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, int len)); 413 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 414 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 415 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 416 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 417 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 418 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 419 static char_u *list2string __ARGS((typval_T *tv)); 420 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); 421 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 422 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 423 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 424 static void dict_unref __ARGS((dict_T *d)); 425 static void dict_free __ARGS((dict_T *d)); 426 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 427 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 428 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 429 static void dictitem_free __ARGS((dictitem_T *item)); 430 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 431 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 432 static long dict_len __ARGS((dict_T *d)); 433 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 434 static char_u *dict2string __ARGS((typval_T *tv)); 435 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 436 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 437 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 438 static char_u *string_quote __ARGS((char_u *str, int function)); 439 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 440 static int find_internal_func __ARGS((char_u *name)); 441 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 442 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)); 443 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)); 444 static void emsg_funcname __ARGS((char *msg, char_u *name)); 445 446 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 447 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 448 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 449 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 450 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 465 #if defined(FEAT_INS_EXPAND) 466 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 468 #endif 469 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 474 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 566 #ifdef vim_mkdir 567 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 568 #endif 569 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 603 #ifdef HAVE_STRFTIME 604 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 605 #endif 606 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 636 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 637 638 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 639 static int get_env_len __ARGS((char_u **arg)); 640 static int get_id_len __ARGS((char_u **arg)); 641 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 642 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 643 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 644 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 645 valid character */ 646 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 647 static int eval_isnamec __ARGS((int c)); 648 static int eval_isnamec1 __ARGS((int c)); 649 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 650 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 651 static typval_T *alloc_tv __ARGS((void)); 652 static typval_T *alloc_string_tv __ARGS((char_u *string)); 653 static void free_tv __ARGS((typval_T *varp)); 654 static void init_tv __ARGS((typval_T *varp)); 655 static long get_tv_number __ARGS((typval_T *varp)); 656 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 657 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 658 static char_u *get_tv_string __ARGS((typval_T *varp)); 659 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 660 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 661 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 662 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 663 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 664 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 665 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 666 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 667 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 668 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 669 static int var_check_ro __ARGS((int flags, char_u *name)); 670 static int tv_check_lock __ARGS((int lock, char_u *name)); 671 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 672 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 673 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 674 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 675 static int eval_fname_script __ARGS((char_u *p)); 676 static int eval_fname_sid __ARGS((char_u *p)); 677 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 678 static ufunc_T *find_func __ARGS((char_u *name)); 679 static int function_exists __ARGS((char_u *name)); 680 static int builtin_function __ARGS((char_u *name)); 681 #ifdef FEAT_PROFILE 682 static void func_do_profile __ARGS((ufunc_T *fp)); 683 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 684 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 685 static int 686 # ifdef __BORLANDC__ 687 _RTLENTRYF 688 # endif 689 prof_total_cmp __ARGS((const void *s1, const void *s2)); 690 static int 691 # ifdef __BORLANDC__ 692 _RTLENTRYF 693 # endif 694 prof_self_cmp __ARGS((const void *s1, const void *s2)); 695 #endif 696 static int script_autoload __ARGS((char_u *name, int reload)); 697 static char_u *autoload_name __ARGS((char_u *name)); 698 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 699 static void func_free __ARGS((ufunc_T *fp)); 700 static void func_unref __ARGS((char_u *name)); 701 static void func_ref __ARGS((char_u *name)); 702 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)); 703 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 704 705 /* Character used as separated in autoload function/variable names. */ 706 #define AUTOLOAD_CHAR '#' 707 708 /* 709 * Initialize the global and v: variables. 710 */ 711 void 712 eval_init() 713 { 714 int i; 715 struct vimvar *p; 716 717 init_var_dict(&globvardict, &globvars_var); 718 init_var_dict(&vimvardict, &vimvars_var); 719 hash_init(&compat_hashtab); 720 hash_init(&func_hashtab); 721 722 for (i = 0; i < VV_LEN; ++i) 723 { 724 p = &vimvars[i]; 725 STRCPY(p->vv_di.di_key, p->vv_name); 726 if (p->vv_flags & VV_RO) 727 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 728 else if (p->vv_flags & VV_RO_SBX) 729 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 730 else 731 p->vv_di.di_flags = DI_FLAGS_FIX; 732 733 /* add to v: scope dict, unless the value is not always available */ 734 if (p->vv_type != VAR_UNKNOWN) 735 hash_add(&vimvarht, p->vv_di.di_key); 736 if (p->vv_flags & VV_COMPAT) 737 /* add to compat scope dict */ 738 hash_add(&compat_hashtab, p->vv_di.di_key); 739 } 740 } 741 742 #if defined(EXITFREE) || defined(PROTO) 743 void 744 eval_clear() 745 { 746 int i; 747 struct vimvar *p; 748 749 for (i = 0; i < VV_LEN; ++i) 750 { 751 p = &vimvars[i]; 752 if (p->vv_di.di_tv.v_type == VAR_STRING) 753 { 754 vim_free(p->vv_di.di_tv.vval.v_string); 755 p->vv_di.di_tv.vval.v_string = NULL; 756 } 757 } 758 hash_clear(&vimvarht); 759 hash_clear(&compat_hashtab); 760 761 /* script-local variables */ 762 for (i = 1; i <= ga_scripts.ga_len; ++i) 763 vars_clear(&SCRIPT_VARS(i)); 764 ga_clear(&ga_scripts); 765 free_scriptnames(); 766 767 /* global variables */ 768 vars_clear(&globvarht); 769 770 /* functions */ 771 free_all_functions(); 772 hash_clear(&func_hashtab); 773 774 /* unreferenced lists and dicts */ 775 (void)garbage_collect(); 776 } 777 #endif 778 779 /* 780 * Return the name of the executed function. 781 */ 782 char_u * 783 func_name(cookie) 784 void *cookie; 785 { 786 return ((funccall_T *)cookie)->func->uf_name; 787 } 788 789 /* 790 * Return the address holding the next breakpoint line for a funccall cookie. 791 */ 792 linenr_T * 793 func_breakpoint(cookie) 794 void *cookie; 795 { 796 return &((funccall_T *)cookie)->breakpoint; 797 } 798 799 /* 800 * Return the address holding the debug tick for a funccall cookie. 801 */ 802 int * 803 func_dbg_tick(cookie) 804 void *cookie; 805 { 806 return &((funccall_T *)cookie)->dbg_tick; 807 } 808 809 /* 810 * Return the nesting level for a funccall cookie. 811 */ 812 int 813 func_level(cookie) 814 void *cookie; 815 { 816 return ((funccall_T *)cookie)->level; 817 } 818 819 /* pointer to funccal for currently active function */ 820 funccall_T *current_funccal = NULL; 821 822 /* 823 * Return TRUE when a function was ended by a ":return" command. 824 */ 825 int 826 current_func_returned() 827 { 828 return current_funccal->returned; 829 } 830 831 832 /* 833 * Set an internal variable to a string value. Creates the variable if it does 834 * not already exist. 835 */ 836 void 837 set_internal_string_var(name, value) 838 char_u *name; 839 char_u *value; 840 { 841 char_u *val; 842 typval_T *tvp; 843 844 val = vim_strsave(value); 845 if (val != NULL) 846 { 847 tvp = alloc_string_tv(val); 848 if (tvp != NULL) 849 { 850 set_var(name, tvp, FALSE); 851 free_tv(tvp); 852 } 853 } 854 } 855 856 static lval_T *redir_lval = NULL; 857 static char_u *redir_endp = NULL; 858 static char_u *redir_varname = NULL; 859 860 /* 861 * Start recording command output to a variable 862 * Returns OK if successfully completed the setup. FAIL otherwise. 863 */ 864 int 865 var_redir_start(name, append) 866 char_u *name; 867 int append; /* append to an existing variable */ 868 { 869 int save_emsg; 870 int err; 871 typval_T tv; 872 873 /* Make sure a valid variable name is specified */ 874 if (!eval_isnamec1(*name)) 875 { 876 EMSG(_(e_invarg)); 877 return FAIL; 878 } 879 880 redir_varname = vim_strsave(name); 881 if (redir_varname == NULL) 882 return FAIL; 883 884 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 885 if (redir_lval == NULL) 886 { 887 var_redir_stop(); 888 return FAIL; 889 } 890 891 /* Parse the variable name (can be a dict or list entry). */ 892 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 893 FNE_CHECK_START); 894 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 895 { 896 if (redir_endp != NULL && *redir_endp != NUL) 897 /* Trailing characters are present after the variable name */ 898 EMSG(_(e_trailing)); 899 else 900 EMSG(_(e_invarg)); 901 var_redir_stop(); 902 return FAIL; 903 } 904 905 /* check if we can write to the variable: set it to or append an empty 906 * string */ 907 save_emsg = did_emsg; 908 did_emsg = FALSE; 909 tv.v_type = VAR_STRING; 910 tv.vval.v_string = (char_u *)""; 911 if (append) 912 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 913 else 914 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 915 err = did_emsg; 916 did_emsg += save_emsg; 917 if (err) 918 { 919 var_redir_stop(); 920 return FAIL; 921 } 922 if (redir_lval->ll_newkey != NULL) 923 { 924 /* Dictionary item was created, don't do it again. */ 925 vim_free(redir_lval->ll_newkey); 926 redir_lval->ll_newkey = NULL; 927 } 928 929 return OK; 930 } 931 932 /* 933 * Append "value[len]" to the variable set by var_redir_start(). 934 */ 935 void 936 var_redir_str(value, len) 937 char_u *value; 938 int len; 939 { 940 char_u *val; 941 typval_T tv; 942 int save_emsg; 943 int err; 944 945 if (redir_lval == NULL) 946 return; 947 948 if (len == -1) 949 /* Append the entire string */ 950 val = vim_strsave(value); 951 else 952 /* Append only the specified number of characters */ 953 val = vim_strnsave(value, len); 954 if (val == NULL) 955 return; 956 957 tv.v_type = VAR_STRING; 958 tv.vval.v_string = val; 959 960 save_emsg = did_emsg; 961 did_emsg = FALSE; 962 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 963 err = did_emsg; 964 did_emsg += save_emsg; 965 if (err) 966 var_redir_stop(); 967 968 vim_free(tv.vval.v_string); 969 } 970 971 /* 972 * Stop redirecting command output to a variable. 973 */ 974 void 975 var_redir_stop() 976 { 977 if (redir_lval != NULL) 978 { 979 clear_lval(redir_lval); 980 vim_free(redir_lval); 981 redir_lval = NULL; 982 } 983 vim_free(redir_varname); 984 redir_varname = NULL; 985 } 986 987 # if defined(FEAT_MBYTE) || defined(PROTO) 988 int 989 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 990 char_u *enc_from; 991 char_u *enc_to; 992 char_u *fname_from; 993 char_u *fname_to; 994 { 995 int err = FALSE; 996 997 set_vim_var_string(VV_CC_FROM, enc_from, -1); 998 set_vim_var_string(VV_CC_TO, enc_to, -1); 999 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1000 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1001 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1002 err = TRUE; 1003 set_vim_var_string(VV_CC_FROM, NULL, -1); 1004 set_vim_var_string(VV_CC_TO, NULL, -1); 1005 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1006 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1007 1008 if (err) 1009 return FAIL; 1010 return OK; 1011 } 1012 # endif 1013 1014 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1015 int 1016 eval_printexpr(fname, args) 1017 char_u *fname; 1018 char_u *args; 1019 { 1020 int err = FALSE; 1021 1022 set_vim_var_string(VV_FNAME_IN, fname, -1); 1023 set_vim_var_string(VV_CMDARG, args, -1); 1024 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1025 err = TRUE; 1026 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1027 set_vim_var_string(VV_CMDARG, NULL, -1); 1028 1029 if (err) 1030 { 1031 mch_remove(fname); 1032 return FAIL; 1033 } 1034 return OK; 1035 } 1036 # endif 1037 1038 # if defined(FEAT_DIFF) || defined(PROTO) 1039 void 1040 eval_diff(origfile, newfile, outfile) 1041 char_u *origfile; 1042 char_u *newfile; 1043 char_u *outfile; 1044 { 1045 int err = FALSE; 1046 1047 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1048 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1049 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1050 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1051 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1052 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1053 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1054 } 1055 1056 void 1057 eval_patch(origfile, difffile, outfile) 1058 char_u *origfile; 1059 char_u *difffile; 1060 char_u *outfile; 1061 { 1062 int err; 1063 1064 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1065 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1066 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1067 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1068 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1069 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1070 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1071 } 1072 # endif 1073 1074 /* 1075 * Top level evaluation function, returning a boolean. 1076 * Sets "error" to TRUE if there was an error. 1077 * Return TRUE or FALSE. 1078 */ 1079 int 1080 eval_to_bool(arg, error, nextcmd, skip) 1081 char_u *arg; 1082 int *error; 1083 char_u **nextcmd; 1084 int skip; /* only parse, don't execute */ 1085 { 1086 typval_T tv; 1087 int retval = FALSE; 1088 1089 if (skip) 1090 ++emsg_skip; 1091 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1092 *error = TRUE; 1093 else 1094 { 1095 *error = FALSE; 1096 if (!skip) 1097 { 1098 retval = (get_tv_number_chk(&tv, error) != 0); 1099 clear_tv(&tv); 1100 } 1101 } 1102 if (skip) 1103 --emsg_skip; 1104 1105 return retval; 1106 } 1107 1108 /* 1109 * Top level evaluation function, returning a string. If "skip" is TRUE, 1110 * only parsing to "nextcmd" is done, without reporting errors. Return 1111 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1112 */ 1113 char_u * 1114 eval_to_string_skip(arg, nextcmd, skip) 1115 char_u *arg; 1116 char_u **nextcmd; 1117 int skip; /* only parse, don't execute */ 1118 { 1119 typval_T tv; 1120 char_u *retval; 1121 1122 if (skip) 1123 ++emsg_skip; 1124 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1125 retval = NULL; 1126 else 1127 { 1128 retval = vim_strsave(get_tv_string(&tv)); 1129 clear_tv(&tv); 1130 } 1131 if (skip) 1132 --emsg_skip; 1133 1134 return retval; 1135 } 1136 1137 /* 1138 * Skip over an expression at "*pp". 1139 * Return FAIL for an error, OK otherwise. 1140 */ 1141 int 1142 skip_expr(pp) 1143 char_u **pp; 1144 { 1145 typval_T rettv; 1146 1147 *pp = skipwhite(*pp); 1148 return eval1(pp, &rettv, FALSE); 1149 } 1150 1151 /* 1152 * Top level evaluation function, returning a string. 1153 * Return pointer to allocated memory, or NULL for failure. 1154 */ 1155 char_u * 1156 eval_to_string(arg, nextcmd) 1157 char_u *arg; 1158 char_u **nextcmd; 1159 { 1160 typval_T tv; 1161 char_u *retval; 1162 1163 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1164 retval = NULL; 1165 else 1166 { 1167 retval = vim_strsave(get_tv_string(&tv)); 1168 clear_tv(&tv); 1169 } 1170 1171 return retval; 1172 } 1173 1174 /* 1175 * Call eval_to_string() with "sandbox" set and not using local variables. 1176 */ 1177 char_u * 1178 eval_to_string_safe(arg, nextcmd) 1179 char_u *arg; 1180 char_u **nextcmd; 1181 { 1182 char_u *retval; 1183 void *save_funccalp; 1184 1185 save_funccalp = save_funccal(); 1186 ++sandbox; 1187 retval = eval_to_string(arg, nextcmd); 1188 --sandbox; 1189 restore_funccal(save_funccalp); 1190 return retval; 1191 } 1192 1193 /* 1194 * Top level evaluation function, returning a number. 1195 * Evaluates "expr" silently. 1196 * Returns -1 for an error. 1197 */ 1198 int 1199 eval_to_number(expr) 1200 char_u *expr; 1201 { 1202 typval_T rettv; 1203 int retval; 1204 char_u *p = skipwhite(expr); 1205 1206 ++emsg_off; 1207 1208 if (eval1(&p, &rettv, TRUE) == FAIL) 1209 retval = -1; 1210 else 1211 { 1212 retval = get_tv_number_chk(&rettv, NULL); 1213 clear_tv(&rettv); 1214 } 1215 --emsg_off; 1216 1217 return retval; 1218 } 1219 1220 /* 1221 * Prepare v: variable "idx" to be used. 1222 * Save the current typeval in "save_tv". 1223 * When not used yet add the variable to the v: hashtable. 1224 */ 1225 static void 1226 prepare_vimvar(idx, save_tv) 1227 int idx; 1228 typval_T *save_tv; 1229 { 1230 *save_tv = vimvars[idx].vv_tv; 1231 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1232 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1233 } 1234 1235 /* 1236 * Restore v: variable "idx" to typeval "save_tv". 1237 * When no longer defined, remove the variable from the v: hashtable. 1238 */ 1239 static void 1240 restore_vimvar(idx, save_tv) 1241 int idx; 1242 typval_T *save_tv; 1243 { 1244 hashitem_T *hi; 1245 1246 clear_tv(&vimvars[idx].vv_tv); 1247 vimvars[idx].vv_tv = *save_tv; 1248 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1249 { 1250 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1251 if (HASHITEM_EMPTY(hi)) 1252 EMSG2(_(e_intern2), "restore_vimvar()"); 1253 else 1254 hash_remove(&vimvarht, hi); 1255 } 1256 } 1257 1258 #if defined(FEAT_SYN_HL) || defined(PROTO) 1259 /* 1260 * Evaluate an expression to a list with suggestions. 1261 * For the "expr:" part of 'spellsuggest'. 1262 */ 1263 list_T * 1264 eval_spell_expr(badword, expr) 1265 char_u *badword; 1266 char_u *expr; 1267 { 1268 typval_T save_val; 1269 typval_T rettv; 1270 list_T *list = NULL; 1271 char_u *p = skipwhite(expr); 1272 1273 /* Set "v:val" to the bad word. */ 1274 prepare_vimvar(VV_VAL, &save_val); 1275 vimvars[VV_VAL].vv_type = VAR_STRING; 1276 vimvars[VV_VAL].vv_str = badword; 1277 if (p_verbose == 0) 1278 ++emsg_off; 1279 1280 if (eval1(&p, &rettv, TRUE) == OK) 1281 { 1282 if (rettv.v_type != VAR_LIST) 1283 clear_tv(&rettv); 1284 else 1285 list = rettv.vval.v_list; 1286 } 1287 1288 if (p_verbose == 0) 1289 --emsg_off; 1290 vimvars[VV_VAL].vv_str = NULL; 1291 restore_vimvar(VV_VAL, &save_val); 1292 1293 return list; 1294 } 1295 1296 /* 1297 * "list" is supposed to contain two items: a word and a number. Return the 1298 * word in "pp" and the number as the return value. 1299 * Return -1 if anything isn't right. 1300 * Used to get the good word and score from the eval_spell_expr() result. 1301 */ 1302 int 1303 get_spellword(list, pp) 1304 list_T *list; 1305 char_u **pp; 1306 { 1307 listitem_T *li; 1308 1309 li = list->lv_first; 1310 if (li == NULL) 1311 return -1; 1312 *pp = get_tv_string(&li->li_tv); 1313 1314 li = li->li_next; 1315 if (li == NULL) 1316 return -1; 1317 return get_tv_number(&li->li_tv); 1318 } 1319 #endif 1320 1321 /* 1322 * Top level evaluation function, 1323 */ 1324 typval_T * 1325 eval_expr(arg, nextcmd) 1326 char_u *arg; 1327 char_u **nextcmd; 1328 { 1329 typval_T *tv; 1330 1331 tv = (typval_T *)alloc(sizeof(typval_T)); 1332 if (!tv) 1333 return NULL; 1334 1335 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1336 { 1337 vim_free(tv); 1338 return NULL; 1339 } 1340 1341 return tv; 1342 } 1343 1344 1345 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1346 /* 1347 * Call some vimL function and return the result in "*rettv". 1348 * Uses argv[argc] for the function arguments. 1349 * Returns OK or FAIL. 1350 */ 1351 static int 1352 call_vim_function(func, argc, argv, safe, rettv) 1353 char_u *func; 1354 int argc; 1355 char_u **argv; 1356 int safe; /* use the sandbox */ 1357 typval_T *rettv; 1358 { 1359 typval_T *argvars; 1360 long n; 1361 int len; 1362 int i; 1363 int doesrange; 1364 void *save_funccalp = NULL; 1365 int ret; 1366 1367 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1368 if (argvars == NULL) 1369 return FAIL; 1370 1371 for (i = 0; i < argc; i++) 1372 { 1373 /* Pass a NULL or empty argument as an empty string */ 1374 if (argv[i] == NULL || *argv[i] == NUL) 1375 { 1376 argvars[i].v_type = VAR_STRING; 1377 argvars[i].vval.v_string = (char_u *)""; 1378 continue; 1379 } 1380 1381 /* Recognize a number argument, the others must be strings. */ 1382 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1383 if (len != 0 && len == (int)STRLEN(argv[i])) 1384 { 1385 argvars[i].v_type = VAR_NUMBER; 1386 argvars[i].vval.v_number = n; 1387 } 1388 else 1389 { 1390 argvars[i].v_type = VAR_STRING; 1391 argvars[i].vval.v_string = argv[i]; 1392 } 1393 } 1394 1395 if (safe) 1396 { 1397 save_funccalp = save_funccal(); 1398 ++sandbox; 1399 } 1400 1401 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1402 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1403 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1404 &doesrange, TRUE, NULL); 1405 if (safe) 1406 { 1407 --sandbox; 1408 restore_funccal(save_funccalp); 1409 } 1410 vim_free(argvars); 1411 1412 if (ret == FAIL) 1413 clear_tv(rettv); 1414 1415 return ret; 1416 } 1417 1418 /* 1419 * Call vimL function "func" and return the result as a string. 1420 * Returns NULL when calling the function fails. 1421 * Uses argv[argc] for the function arguments. 1422 */ 1423 void * 1424 call_func_retstr(func, argc, argv, safe) 1425 char_u *func; 1426 int argc; 1427 char_u **argv; 1428 int safe; /* use the sandbox */ 1429 { 1430 typval_T rettv; 1431 char_u *retval; 1432 1433 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1434 return NULL; 1435 1436 retval = vim_strsave(get_tv_string(&rettv)); 1437 clear_tv(&rettv); 1438 return retval; 1439 } 1440 1441 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1442 /* 1443 * Call vimL function "func" and return the result as a number. 1444 * Returns -1 when calling the function fails. 1445 * Uses argv[argc] for the function arguments. 1446 */ 1447 long 1448 call_func_retnr(func, argc, argv, safe) 1449 char_u *func; 1450 int argc; 1451 char_u **argv; 1452 int safe; /* use the sandbox */ 1453 { 1454 typval_T rettv; 1455 long retval; 1456 1457 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1458 return -1; 1459 1460 retval = get_tv_number_chk(&rettv, NULL); 1461 clear_tv(&rettv); 1462 return retval; 1463 } 1464 #endif 1465 1466 /* 1467 * Call vimL function "func" and return the result as a list 1468 * Uses argv[argc] for the function arguments. 1469 */ 1470 void * 1471 call_func_retlist(func, argc, argv, safe) 1472 char_u *func; 1473 int argc; 1474 char_u **argv; 1475 int safe; /* use the sandbox */ 1476 { 1477 typval_T rettv; 1478 1479 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1480 return NULL; 1481 1482 if (rettv.v_type != VAR_LIST) 1483 { 1484 clear_tv(&rettv); 1485 return NULL; 1486 } 1487 1488 return rettv.vval.v_list; 1489 } 1490 1491 #endif 1492 1493 /* 1494 * Save the current function call pointer, and set it to NULL. 1495 * Used when executing autocommands and for ":source". 1496 */ 1497 void * 1498 save_funccal() 1499 { 1500 funccall_T *fc = current_funccal; 1501 1502 current_funccal = NULL; 1503 return (void *)fc; 1504 } 1505 1506 void 1507 restore_funccal(vfc) 1508 void *vfc; 1509 { 1510 funccall_T *fc = (funccall_T *)vfc; 1511 1512 current_funccal = fc; 1513 } 1514 1515 #if defined(FEAT_PROFILE) || defined(PROTO) 1516 /* 1517 * Prepare profiling for entering a child or something else that is not 1518 * counted for the script/function itself. 1519 * Should always be called in pair with prof_child_exit(). 1520 */ 1521 void 1522 prof_child_enter(tm) 1523 proftime_T *tm; /* place to store waittime */ 1524 { 1525 funccall_T *fc = current_funccal; 1526 1527 if (fc != NULL && fc->func->uf_profiling) 1528 profile_start(&fc->prof_child); 1529 script_prof_save(tm); 1530 } 1531 1532 /* 1533 * Take care of time spent in a child. 1534 * Should always be called after prof_child_enter(). 1535 */ 1536 void 1537 prof_child_exit(tm) 1538 proftime_T *tm; /* where waittime was stored */ 1539 { 1540 funccall_T *fc = current_funccal; 1541 1542 if (fc != NULL && fc->func->uf_profiling) 1543 { 1544 profile_end(&fc->prof_child); 1545 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1546 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1547 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1548 } 1549 script_prof_restore(tm); 1550 } 1551 #endif 1552 1553 1554 #ifdef FEAT_FOLDING 1555 /* 1556 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1557 * it in "*cp". Doesn't give error messages. 1558 */ 1559 int 1560 eval_foldexpr(arg, cp) 1561 char_u *arg; 1562 int *cp; 1563 { 1564 typval_T tv; 1565 int retval; 1566 char_u *s; 1567 1568 ++emsg_off; 1569 ++sandbox; 1570 *cp = NUL; 1571 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1572 retval = 0; 1573 else 1574 { 1575 /* If the result is a number, just return the number. */ 1576 if (tv.v_type == VAR_NUMBER) 1577 retval = tv.vval.v_number; 1578 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1579 retval = 0; 1580 else 1581 { 1582 /* If the result is a string, check if there is a non-digit before 1583 * the number. */ 1584 s = tv.vval.v_string; 1585 if (!VIM_ISDIGIT(*s) && *s != '-') 1586 *cp = *s++; 1587 retval = atol((char *)s); 1588 } 1589 clear_tv(&tv); 1590 } 1591 --emsg_off; 1592 --sandbox; 1593 1594 return retval; 1595 } 1596 #endif 1597 1598 /* 1599 * ":let" list all variable values 1600 * ":let var1 var2" list variable values 1601 * ":let var = expr" assignment command. 1602 * ":let var += expr" assignment command. 1603 * ":let var -= expr" assignment command. 1604 * ":let var .= expr" assignment command. 1605 * ":let [var1, var2] = expr" unpack list. 1606 */ 1607 void 1608 ex_let(eap) 1609 exarg_T *eap; 1610 { 1611 char_u *arg = eap->arg; 1612 char_u *expr = NULL; 1613 typval_T rettv; 1614 int i; 1615 int var_count = 0; 1616 int semicolon = 0; 1617 char_u op[2]; 1618 1619 expr = skip_var_list(arg, &var_count, &semicolon); 1620 if (expr == NULL) 1621 return; 1622 expr = vim_strchr(expr, '='); 1623 if (expr == NULL) 1624 { 1625 /* 1626 * ":let" without "=": list variables 1627 */ 1628 if (*arg == '[') 1629 EMSG(_(e_invarg)); 1630 else if (!ends_excmd(*arg)) 1631 /* ":let var1 var2" */ 1632 arg = list_arg_vars(eap, arg); 1633 else if (!eap->skip) 1634 { 1635 /* ":let" */ 1636 list_glob_vars(); 1637 list_buf_vars(); 1638 list_win_vars(); 1639 list_vim_vars(); 1640 } 1641 eap->nextcmd = check_nextcmd(arg); 1642 } 1643 else 1644 { 1645 op[0] = '='; 1646 op[1] = NUL; 1647 if (expr > arg) 1648 { 1649 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1650 op[0] = expr[-1]; /* +=, -= or .= */ 1651 } 1652 expr = skipwhite(expr + 1); 1653 1654 if (eap->skip) 1655 ++emsg_skip; 1656 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1657 if (eap->skip) 1658 { 1659 if (i != FAIL) 1660 clear_tv(&rettv); 1661 --emsg_skip; 1662 } 1663 else if (i != FAIL) 1664 { 1665 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1666 op); 1667 clear_tv(&rettv); 1668 } 1669 } 1670 } 1671 1672 /* 1673 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1674 * Handles both "var" with any type and "[var, var; var]" with a list type. 1675 * When "nextchars" is not NULL it points to a string with characters that 1676 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1677 * or concatenate. 1678 * Returns OK or FAIL; 1679 */ 1680 static int 1681 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1682 char_u *arg_start; 1683 typval_T *tv; 1684 int copy; /* copy values from "tv", don't move */ 1685 int semicolon; /* from skip_var_list() */ 1686 int var_count; /* from skip_var_list() */ 1687 char_u *nextchars; 1688 { 1689 char_u *arg = arg_start; 1690 list_T *l; 1691 int i; 1692 listitem_T *item; 1693 typval_T ltv; 1694 1695 if (*arg != '[') 1696 { 1697 /* 1698 * ":let var = expr" or ":for var in list" 1699 */ 1700 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1701 return FAIL; 1702 return OK; 1703 } 1704 1705 /* 1706 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1707 */ 1708 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1709 { 1710 EMSG(_(e_listreq)); 1711 return FAIL; 1712 } 1713 1714 i = list_len(l); 1715 if (semicolon == 0 && var_count < i) 1716 { 1717 EMSG(_("E687: Less targets than List items")); 1718 return FAIL; 1719 } 1720 if (var_count - semicolon > i) 1721 { 1722 EMSG(_("E688: More targets than List items")); 1723 return FAIL; 1724 } 1725 1726 item = l->lv_first; 1727 while (*arg != ']') 1728 { 1729 arg = skipwhite(arg + 1); 1730 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1731 item = item->li_next; 1732 if (arg == NULL) 1733 return FAIL; 1734 1735 arg = skipwhite(arg); 1736 if (*arg == ';') 1737 { 1738 /* Put the rest of the list (may be empty) in the var after ';'. 1739 * Create a new list for this. */ 1740 l = list_alloc(); 1741 if (l == NULL) 1742 return FAIL; 1743 while (item != NULL) 1744 { 1745 list_append_tv(l, &item->li_tv); 1746 item = item->li_next; 1747 } 1748 1749 ltv.v_type = VAR_LIST; 1750 ltv.v_lock = 0; 1751 ltv.vval.v_list = l; 1752 l->lv_refcount = 1; 1753 1754 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1755 (char_u *)"]", nextchars); 1756 clear_tv(<v); 1757 if (arg == NULL) 1758 return FAIL; 1759 break; 1760 } 1761 else if (*arg != ',' && *arg != ']') 1762 { 1763 EMSG2(_(e_intern2), "ex_let_vars()"); 1764 return FAIL; 1765 } 1766 } 1767 1768 return OK; 1769 } 1770 1771 /* 1772 * Skip over assignable variable "var" or list of variables "[var, var]". 1773 * Used for ":let varvar = expr" and ":for varvar in expr". 1774 * For "[var, var]" increment "*var_count" for each variable. 1775 * for "[var, var; var]" set "semicolon". 1776 * Return NULL for an error. 1777 */ 1778 static char_u * 1779 skip_var_list(arg, var_count, semicolon) 1780 char_u *arg; 1781 int *var_count; 1782 int *semicolon; 1783 { 1784 char_u *p, *s; 1785 1786 if (*arg == '[') 1787 { 1788 /* "[var, var]": find the matching ']'. */ 1789 p = arg; 1790 for (;;) 1791 { 1792 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1793 s = skip_var_one(p); 1794 if (s == p) 1795 { 1796 EMSG2(_(e_invarg2), p); 1797 return NULL; 1798 } 1799 ++*var_count; 1800 1801 p = skipwhite(s); 1802 if (*p == ']') 1803 break; 1804 else if (*p == ';') 1805 { 1806 if (*semicolon == 1) 1807 { 1808 EMSG(_("Double ; in list of variables")); 1809 return NULL; 1810 } 1811 *semicolon = 1; 1812 } 1813 else if (*p != ',') 1814 { 1815 EMSG2(_(e_invarg2), p); 1816 return NULL; 1817 } 1818 } 1819 return p + 1; 1820 } 1821 else 1822 return skip_var_one(arg); 1823 } 1824 1825 /* 1826 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1827 * l[idx]. 1828 */ 1829 static char_u * 1830 skip_var_one(arg) 1831 char_u *arg; 1832 { 1833 if (*arg == '@' && arg[1] != NUL) 1834 return arg + 2; 1835 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1836 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1837 } 1838 1839 /* 1840 * List variables for hashtab "ht" with prefix "prefix". 1841 * If "empty" is TRUE also list NULL strings as empty strings. 1842 */ 1843 static void 1844 list_hashtable_vars(ht, prefix, empty) 1845 hashtab_T *ht; 1846 char_u *prefix; 1847 int empty; 1848 { 1849 hashitem_T *hi; 1850 dictitem_T *di; 1851 int todo; 1852 1853 todo = ht->ht_used; 1854 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1855 { 1856 if (!HASHITEM_EMPTY(hi)) 1857 { 1858 --todo; 1859 di = HI2DI(hi); 1860 if (empty || di->di_tv.v_type != VAR_STRING 1861 || di->di_tv.vval.v_string != NULL) 1862 list_one_var(di, prefix); 1863 } 1864 } 1865 } 1866 1867 /* 1868 * List global variables. 1869 */ 1870 static void 1871 list_glob_vars() 1872 { 1873 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1874 } 1875 1876 /* 1877 * List buffer variables. 1878 */ 1879 static void 1880 list_buf_vars() 1881 { 1882 char_u numbuf[NUMBUFLEN]; 1883 1884 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1885 1886 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1887 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1888 } 1889 1890 /* 1891 * List window variables. 1892 */ 1893 static void 1894 list_win_vars() 1895 { 1896 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1897 } 1898 1899 /* 1900 * List Vim variables. 1901 */ 1902 static void 1903 list_vim_vars() 1904 { 1905 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1906 } 1907 1908 /* 1909 * List variables in "arg". 1910 */ 1911 static char_u * 1912 list_arg_vars(eap, arg) 1913 exarg_T *eap; 1914 char_u *arg; 1915 { 1916 int error = FALSE; 1917 int len; 1918 char_u *name; 1919 char_u *name_start; 1920 char_u *arg_subsc; 1921 char_u *tofree; 1922 typval_T tv; 1923 1924 while (!ends_excmd(*arg) && !got_int) 1925 { 1926 if (error || eap->skip) 1927 { 1928 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1929 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1930 { 1931 emsg_severe = TRUE; 1932 EMSG(_(e_trailing)); 1933 break; 1934 } 1935 } 1936 else 1937 { 1938 /* get_name_len() takes care of expanding curly braces */ 1939 name_start = name = arg; 1940 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1941 if (len <= 0) 1942 { 1943 /* This is mainly to keep test 49 working: when expanding 1944 * curly braces fails overrule the exception error message. */ 1945 if (len < 0 && !aborting()) 1946 { 1947 emsg_severe = TRUE; 1948 EMSG2(_(e_invarg2), arg); 1949 break; 1950 } 1951 error = TRUE; 1952 } 1953 else 1954 { 1955 if (tofree != NULL) 1956 name = tofree; 1957 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1958 error = TRUE; 1959 else 1960 { 1961 /* handle d.key, l[idx], f(expr) */ 1962 arg_subsc = arg; 1963 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1964 error = TRUE; 1965 else 1966 { 1967 if (arg == arg_subsc && len == 2 && name[1] == ':') 1968 { 1969 switch (*name) 1970 { 1971 case 'g': list_glob_vars(); break; 1972 case 'b': list_buf_vars(); break; 1973 case 'w': list_win_vars(); break; 1974 case 'v': list_vim_vars(); break; 1975 default: 1976 EMSG2(_("E738: Can't list variables for %s"), name); 1977 } 1978 } 1979 else 1980 { 1981 char_u numbuf[NUMBUFLEN]; 1982 char_u *tf; 1983 int c; 1984 char_u *s; 1985 1986 s = echo_string(&tv, &tf, numbuf); 1987 c = *arg; 1988 *arg = NUL; 1989 list_one_var_a((char_u *)"", 1990 arg == arg_subsc ? name : name_start, 1991 tv.v_type, s == NULL ? (char_u *)"" : s); 1992 *arg = c; 1993 vim_free(tf); 1994 } 1995 clear_tv(&tv); 1996 } 1997 } 1998 } 1999 2000 vim_free(tofree); 2001 } 2002 2003 arg = skipwhite(arg); 2004 } 2005 2006 return arg; 2007 } 2008 2009 /* 2010 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2011 * Returns a pointer to the char just after the var name. 2012 * Returns NULL if there is an error. 2013 */ 2014 static char_u * 2015 ex_let_one(arg, tv, copy, endchars, op) 2016 char_u *arg; /* points to variable name */ 2017 typval_T *tv; /* value to assign to variable */ 2018 int copy; /* copy value from "tv" */ 2019 char_u *endchars; /* valid chars after variable name or NULL */ 2020 char_u *op; /* "+", "-", "." or NULL*/ 2021 { 2022 int c1; 2023 char_u *name; 2024 char_u *p; 2025 char_u *arg_end = NULL; 2026 int len; 2027 int opt_flags; 2028 char_u *tofree = NULL; 2029 2030 /* 2031 * ":let $VAR = expr": Set environment variable. 2032 */ 2033 if (*arg == '$') 2034 { 2035 /* Find the end of the name. */ 2036 ++arg; 2037 name = arg; 2038 len = get_env_len(&arg); 2039 if (len == 0) 2040 EMSG2(_(e_invarg2), name - 1); 2041 else 2042 { 2043 if (op != NULL && (*op == '+' || *op == '-')) 2044 EMSG2(_(e_letwrong), op); 2045 else if (endchars != NULL 2046 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2047 EMSG(_(e_letunexp)); 2048 else 2049 { 2050 c1 = name[len]; 2051 name[len] = NUL; 2052 p = get_tv_string_chk(tv); 2053 if (p != NULL && op != NULL && *op == '.') 2054 { 2055 int mustfree = FALSE; 2056 char_u *s = vim_getenv(name, &mustfree); 2057 2058 if (s != NULL) 2059 { 2060 p = tofree = concat_str(s, p); 2061 if (mustfree) 2062 vim_free(s); 2063 } 2064 } 2065 if (p != NULL) 2066 { 2067 vim_setenv(name, p); 2068 if (STRICMP(name, "HOME") == 0) 2069 init_homedir(); 2070 else if (didset_vim && STRICMP(name, "VIM") == 0) 2071 didset_vim = FALSE; 2072 else if (didset_vimruntime 2073 && STRICMP(name, "VIMRUNTIME") == 0) 2074 didset_vimruntime = FALSE; 2075 arg_end = arg; 2076 } 2077 name[len] = c1; 2078 vim_free(tofree); 2079 } 2080 } 2081 } 2082 2083 /* 2084 * ":let &option = expr": Set option value. 2085 * ":let &l:option = expr": Set local option value. 2086 * ":let &g:option = expr": Set global option value. 2087 */ 2088 else if (*arg == '&') 2089 { 2090 /* Find the end of the name. */ 2091 p = find_option_end(&arg, &opt_flags); 2092 if (p == NULL || (endchars != NULL 2093 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2094 EMSG(_(e_letunexp)); 2095 else 2096 { 2097 long n; 2098 int opt_type; 2099 long numval; 2100 char_u *stringval = NULL; 2101 char_u *s; 2102 2103 c1 = *p; 2104 *p = NUL; 2105 2106 n = get_tv_number(tv); 2107 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2108 if (s != NULL && op != NULL && *op != '=') 2109 { 2110 opt_type = get_option_value(arg, &numval, 2111 &stringval, opt_flags); 2112 if ((opt_type == 1 && *op == '.') 2113 || (opt_type == 0 && *op != '.')) 2114 EMSG2(_(e_letwrong), op); 2115 else 2116 { 2117 if (opt_type == 1) /* number */ 2118 { 2119 if (*op == '+') 2120 n = numval + n; 2121 else 2122 n = numval - n; 2123 } 2124 else if (opt_type == 0 && stringval != NULL) /* string */ 2125 { 2126 s = concat_str(stringval, s); 2127 vim_free(stringval); 2128 stringval = s; 2129 } 2130 } 2131 } 2132 if (s != NULL) 2133 { 2134 set_option_value(arg, n, s, opt_flags); 2135 arg_end = p; 2136 } 2137 *p = c1; 2138 vim_free(stringval); 2139 } 2140 } 2141 2142 /* 2143 * ":let @r = expr": Set register contents. 2144 */ 2145 else if (*arg == '@') 2146 { 2147 ++arg; 2148 if (op != NULL && (*op == '+' || *op == '-')) 2149 EMSG2(_(e_letwrong), op); 2150 else if (endchars != NULL 2151 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2152 EMSG(_(e_letunexp)); 2153 else 2154 { 2155 char_u *tofree = NULL; 2156 char_u *s; 2157 2158 p = get_tv_string_chk(tv); 2159 if (p != NULL && op != NULL && *op == '.') 2160 { 2161 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2162 if (s != NULL) 2163 { 2164 p = tofree = concat_str(s, p); 2165 vim_free(s); 2166 } 2167 } 2168 if (p != NULL) 2169 { 2170 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2171 arg_end = arg + 1; 2172 } 2173 vim_free(tofree); 2174 } 2175 } 2176 2177 /* 2178 * ":let var = expr": Set internal variable. 2179 * ":let {expr} = expr": Idem, name made with curly braces 2180 */ 2181 else if (eval_isnamec1(*arg) || *arg == '{') 2182 { 2183 lval_T lv; 2184 2185 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2186 if (p != NULL && lv.ll_name != NULL) 2187 { 2188 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2189 EMSG(_(e_letunexp)); 2190 else 2191 { 2192 set_var_lval(&lv, p, tv, copy, op); 2193 arg_end = p; 2194 } 2195 } 2196 clear_lval(&lv); 2197 } 2198 2199 else 2200 EMSG2(_(e_invarg2), arg); 2201 2202 return arg_end; 2203 } 2204 2205 /* 2206 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2207 */ 2208 static int 2209 check_changedtick(arg) 2210 char_u *arg; 2211 { 2212 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2213 { 2214 EMSG2(_(e_readonlyvar), arg); 2215 return TRUE; 2216 } 2217 return FALSE; 2218 } 2219 2220 /* 2221 * Get an lval: variable, Dict item or List item that can be assigned a value 2222 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2223 * "name.key", "name.key[expr]" etc. 2224 * Indexing only works if "name" is an existing List or Dictionary. 2225 * "name" points to the start of the name. 2226 * If "rettv" is not NULL it points to the value to be assigned. 2227 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2228 * wrong; must end in space or cmd separator. 2229 * 2230 * Returns a pointer to just after the name, including indexes. 2231 * When an evaluation error occurs "lp->ll_name" is NULL; 2232 * Returns NULL for a parsing error. Still need to free items in "lp"! 2233 */ 2234 static char_u * 2235 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2236 char_u *name; 2237 typval_T *rettv; 2238 lval_T *lp; 2239 int unlet; 2240 int skip; 2241 int quiet; /* don't give error messages */ 2242 int fne_flags; /* flags for find_name_end() */ 2243 { 2244 char_u *p; 2245 char_u *expr_start, *expr_end; 2246 int cc; 2247 dictitem_T *v; 2248 typval_T var1; 2249 typval_T var2; 2250 int empty1 = FALSE; 2251 listitem_T *ni; 2252 char_u *key = NULL; 2253 int len; 2254 hashtab_T *ht; 2255 2256 /* Clear everything in "lp". */ 2257 vim_memset(lp, 0, sizeof(lval_T)); 2258 2259 if (skip) 2260 { 2261 /* When skipping just find the end of the name. */ 2262 lp->ll_name = name; 2263 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2264 } 2265 2266 /* Find the end of the name. */ 2267 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2268 if (expr_start != NULL) 2269 { 2270 /* Don't expand the name when we already know there is an error. */ 2271 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2272 && *p != '[' && *p != '.') 2273 { 2274 EMSG(_(e_trailing)); 2275 return NULL; 2276 } 2277 2278 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2279 if (lp->ll_exp_name == NULL) 2280 { 2281 /* Report an invalid expression in braces, unless the 2282 * expression evaluation has been cancelled due to an 2283 * aborting error, an interrupt, or an exception. */ 2284 if (!aborting() && !quiet) 2285 { 2286 emsg_severe = TRUE; 2287 EMSG2(_(e_invarg2), name); 2288 return NULL; 2289 } 2290 } 2291 lp->ll_name = lp->ll_exp_name; 2292 } 2293 else 2294 lp->ll_name = name; 2295 2296 /* Without [idx] or .key we are done. */ 2297 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2298 return p; 2299 2300 cc = *p; 2301 *p = NUL; 2302 v = find_var(lp->ll_name, &ht); 2303 if (v == NULL && !quiet) 2304 EMSG2(_(e_undefvar), lp->ll_name); 2305 *p = cc; 2306 if (v == NULL) 2307 return NULL; 2308 2309 /* 2310 * Loop until no more [idx] or .key is following. 2311 */ 2312 lp->ll_tv = &v->di_tv; 2313 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2314 { 2315 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2316 && !(lp->ll_tv->v_type == VAR_DICT 2317 && lp->ll_tv->vval.v_dict != NULL)) 2318 { 2319 if (!quiet) 2320 EMSG(_("E689: Can only index a List or Dictionary")); 2321 return NULL; 2322 } 2323 if (lp->ll_range) 2324 { 2325 if (!quiet) 2326 EMSG(_("E708: [:] must come last")); 2327 return NULL; 2328 } 2329 2330 len = -1; 2331 if (*p == '.') 2332 { 2333 key = p + 1; 2334 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2335 ; 2336 if (len == 0) 2337 { 2338 if (!quiet) 2339 EMSG(_(e_emptykey)); 2340 return NULL; 2341 } 2342 p = key + len; 2343 } 2344 else 2345 { 2346 /* Get the index [expr] or the first index [expr: ]. */ 2347 p = skipwhite(p + 1); 2348 if (*p == ':') 2349 empty1 = TRUE; 2350 else 2351 { 2352 empty1 = FALSE; 2353 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2354 return NULL; 2355 if (get_tv_string_chk(&var1) == NULL) 2356 { 2357 /* not a number or string */ 2358 clear_tv(&var1); 2359 return NULL; 2360 } 2361 } 2362 2363 /* Optionally get the second index [ :expr]. */ 2364 if (*p == ':') 2365 { 2366 if (lp->ll_tv->v_type == VAR_DICT) 2367 { 2368 if (!quiet) 2369 EMSG(_(e_dictrange)); 2370 if (!empty1) 2371 clear_tv(&var1); 2372 return NULL; 2373 } 2374 if (rettv != NULL && (rettv->v_type != VAR_LIST 2375 || rettv->vval.v_list == NULL)) 2376 { 2377 if (!quiet) 2378 EMSG(_("E709: [:] requires a List value")); 2379 if (!empty1) 2380 clear_tv(&var1); 2381 return NULL; 2382 } 2383 p = skipwhite(p + 1); 2384 if (*p == ']') 2385 lp->ll_empty2 = TRUE; 2386 else 2387 { 2388 lp->ll_empty2 = FALSE; 2389 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2390 { 2391 if (!empty1) 2392 clear_tv(&var1); 2393 return NULL; 2394 } 2395 if (get_tv_string_chk(&var2) == NULL) 2396 { 2397 /* not a number or string */ 2398 if (!empty1) 2399 clear_tv(&var1); 2400 clear_tv(&var2); 2401 return NULL; 2402 } 2403 } 2404 lp->ll_range = TRUE; 2405 } 2406 else 2407 lp->ll_range = FALSE; 2408 2409 if (*p != ']') 2410 { 2411 if (!quiet) 2412 EMSG(_(e_missbrac)); 2413 if (!empty1) 2414 clear_tv(&var1); 2415 if (lp->ll_range && !lp->ll_empty2) 2416 clear_tv(&var2); 2417 return NULL; 2418 } 2419 2420 /* Skip to past ']'. */ 2421 ++p; 2422 } 2423 2424 if (lp->ll_tv->v_type == VAR_DICT) 2425 { 2426 if (len == -1) 2427 { 2428 /* "[key]": get key from "var1" */ 2429 key = get_tv_string(&var1); /* is number or string */ 2430 if (*key == NUL) 2431 { 2432 if (!quiet) 2433 EMSG(_(e_emptykey)); 2434 clear_tv(&var1); 2435 return NULL; 2436 } 2437 } 2438 lp->ll_list = NULL; 2439 lp->ll_dict = lp->ll_tv->vval.v_dict; 2440 lp->ll_di = dict_find(lp->ll_dict, key, len); 2441 if (lp->ll_di == NULL) 2442 { 2443 /* Key does not exist in dict: may need to add it. */ 2444 if (*p == '[' || *p == '.' || unlet) 2445 { 2446 if (!quiet) 2447 EMSG2(_(e_dictkey), key); 2448 if (len == -1) 2449 clear_tv(&var1); 2450 return NULL; 2451 } 2452 if (len == -1) 2453 lp->ll_newkey = vim_strsave(key); 2454 else 2455 lp->ll_newkey = vim_strnsave(key, len); 2456 if (len == -1) 2457 clear_tv(&var1); 2458 if (lp->ll_newkey == NULL) 2459 p = NULL; 2460 break; 2461 } 2462 if (len == -1) 2463 clear_tv(&var1); 2464 lp->ll_tv = &lp->ll_di->di_tv; 2465 } 2466 else 2467 { 2468 /* 2469 * Get the number and item for the only or first index of the List. 2470 */ 2471 if (empty1) 2472 lp->ll_n1 = 0; 2473 else 2474 { 2475 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2476 clear_tv(&var1); 2477 } 2478 lp->ll_dict = NULL; 2479 lp->ll_list = lp->ll_tv->vval.v_list; 2480 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2481 if (lp->ll_li == NULL) 2482 { 2483 if (!quiet) 2484 EMSGN(_(e_listidx), lp->ll_n1); 2485 if (lp->ll_range && !lp->ll_empty2) 2486 clear_tv(&var2); 2487 return NULL; 2488 } 2489 2490 /* 2491 * May need to find the item or absolute index for the second 2492 * index of a range. 2493 * When no index given: "lp->ll_empty2" is TRUE. 2494 * Otherwise "lp->ll_n2" is set to the second index. 2495 */ 2496 if (lp->ll_range && !lp->ll_empty2) 2497 { 2498 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2499 clear_tv(&var2); 2500 if (lp->ll_n2 < 0) 2501 { 2502 ni = list_find(lp->ll_list, lp->ll_n2); 2503 if (ni == NULL) 2504 { 2505 if (!quiet) 2506 EMSGN(_(e_listidx), lp->ll_n2); 2507 return NULL; 2508 } 2509 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2510 } 2511 2512 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2513 if (lp->ll_n1 < 0) 2514 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2515 if (lp->ll_n2 < lp->ll_n1) 2516 { 2517 if (!quiet) 2518 EMSGN(_(e_listidx), lp->ll_n2); 2519 return NULL; 2520 } 2521 } 2522 2523 lp->ll_tv = &lp->ll_li->li_tv; 2524 } 2525 } 2526 2527 return p; 2528 } 2529 2530 /* 2531 * Clear lval "lp" that was filled by get_lval(). 2532 */ 2533 static void 2534 clear_lval(lp) 2535 lval_T *lp; 2536 { 2537 vim_free(lp->ll_exp_name); 2538 vim_free(lp->ll_newkey); 2539 } 2540 2541 /* 2542 * Set a variable that was parsed by get_lval() to "rettv". 2543 * "endp" points to just after the parsed name. 2544 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2545 */ 2546 static void 2547 set_var_lval(lp, endp, rettv, copy, op) 2548 lval_T *lp; 2549 char_u *endp; 2550 typval_T *rettv; 2551 int copy; 2552 char_u *op; 2553 { 2554 int cc; 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 if (list_append_number(lp->ll_list, 0) == FAIL) 2607 { 2608 ri = NULL; 2609 break; 2610 } 2611 } 2612 lp->ll_li = lp->ll_li->li_next; 2613 ++lp->ll_n1; 2614 } 2615 if (ri != NULL) 2616 EMSG(_("E710: List value has more items than target")); 2617 else if (lp->ll_empty2 2618 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2619 : lp->ll_n1 != lp->ll_n2) 2620 EMSG(_("E711: List value has not enough items")); 2621 } 2622 else 2623 { 2624 /* 2625 * Assign to a List or Dictionary item. 2626 */ 2627 if (lp->ll_newkey != NULL) 2628 { 2629 if (op != NULL && *op != '=') 2630 { 2631 EMSG2(_(e_letwrong), op); 2632 return; 2633 } 2634 2635 /* Need to add an item to the Dictionary. */ 2636 di = dictitem_alloc(lp->ll_newkey); 2637 if (di == NULL) 2638 return; 2639 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2640 { 2641 vim_free(di); 2642 return; 2643 } 2644 lp->ll_tv = &di->di_tv; 2645 } 2646 else if (op != NULL && *op != '=') 2647 { 2648 tv_op(lp->ll_tv, rettv, op); 2649 return; 2650 } 2651 else 2652 clear_tv(lp->ll_tv); 2653 2654 /* 2655 * Assign the value to the variable or list item. 2656 */ 2657 if (copy) 2658 copy_tv(rettv, lp->ll_tv); 2659 else 2660 { 2661 *lp->ll_tv = *rettv; 2662 lp->ll_tv->v_lock = 0; 2663 init_tv(rettv); 2664 } 2665 } 2666 } 2667 2668 /* 2669 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2670 * Returns OK or FAIL. 2671 */ 2672 static int 2673 tv_op(tv1, tv2, op) 2674 typval_T *tv1; 2675 typval_T *tv2; 2676 char_u *op; 2677 { 2678 long n; 2679 char_u numbuf[NUMBUFLEN]; 2680 char_u *s; 2681 2682 /* Can't do anything with a Funcref or a Dict on the right. */ 2683 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2684 { 2685 switch (tv1->v_type) 2686 { 2687 case VAR_DICT: 2688 case VAR_FUNC: 2689 break; 2690 2691 case VAR_LIST: 2692 if (*op != '+' || tv2->v_type != VAR_LIST) 2693 break; 2694 /* List += List */ 2695 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2696 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2697 return OK; 2698 2699 case VAR_NUMBER: 2700 case VAR_STRING: 2701 if (tv2->v_type == VAR_LIST) 2702 break; 2703 if (*op == '+' || *op == '-') 2704 { 2705 /* nr += nr or nr -= nr*/ 2706 n = get_tv_number(tv1); 2707 if (*op == '+') 2708 n += get_tv_number(tv2); 2709 else 2710 n -= get_tv_number(tv2); 2711 clear_tv(tv1); 2712 tv1->v_type = VAR_NUMBER; 2713 tv1->vval.v_number = n; 2714 } 2715 else 2716 { 2717 /* str .= str */ 2718 s = get_tv_string(tv1); 2719 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2720 clear_tv(tv1); 2721 tv1->v_type = VAR_STRING; 2722 tv1->vval.v_string = s; 2723 } 2724 return OK; 2725 } 2726 } 2727 2728 EMSG2(_(e_letwrong), op); 2729 return FAIL; 2730 } 2731 2732 /* 2733 * Add a watcher to a list. 2734 */ 2735 static void 2736 list_add_watch(l, lw) 2737 list_T *l; 2738 listwatch_T *lw; 2739 { 2740 lw->lw_next = l->lv_watch; 2741 l->lv_watch = lw; 2742 } 2743 2744 /* 2745 * Remove a watcher from a list. 2746 * No warning when it isn't found... 2747 */ 2748 static void 2749 list_rem_watch(l, lwrem) 2750 list_T *l; 2751 listwatch_T *lwrem; 2752 { 2753 listwatch_T *lw, **lwp; 2754 2755 lwp = &l->lv_watch; 2756 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2757 { 2758 if (lw == lwrem) 2759 { 2760 *lwp = lw->lw_next; 2761 break; 2762 } 2763 lwp = &lw->lw_next; 2764 } 2765 } 2766 2767 /* 2768 * Just before removing an item from a list: advance watchers to the next 2769 * item. 2770 */ 2771 static void 2772 list_fix_watch(l, item) 2773 list_T *l; 2774 listitem_T *item; 2775 { 2776 listwatch_T *lw; 2777 2778 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2779 if (lw->lw_item == item) 2780 lw->lw_item = item->li_next; 2781 } 2782 2783 /* 2784 * Evaluate the expression used in a ":for var in expr" command. 2785 * "arg" points to "var". 2786 * Set "*errp" to TRUE for an error, FALSE otherwise; 2787 * Return a pointer that holds the info. Null when there is an error. 2788 */ 2789 void * 2790 eval_for_line(arg, errp, nextcmdp, skip) 2791 char_u *arg; 2792 int *errp; 2793 char_u **nextcmdp; 2794 int skip; 2795 { 2796 forinfo_T *fi; 2797 char_u *expr; 2798 typval_T tv; 2799 list_T *l; 2800 2801 *errp = TRUE; /* default: there is an error */ 2802 2803 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2804 if (fi == NULL) 2805 return NULL; 2806 2807 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2808 if (expr == NULL) 2809 return fi; 2810 2811 expr = skipwhite(expr); 2812 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2813 { 2814 EMSG(_("E690: Missing \"in\" after :for")); 2815 return fi; 2816 } 2817 2818 if (skip) 2819 ++emsg_skip; 2820 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2821 { 2822 *errp = FALSE; 2823 if (!skip) 2824 { 2825 l = tv.vval.v_list; 2826 if (tv.v_type != VAR_LIST || l == NULL) 2827 { 2828 EMSG(_(e_listreq)); 2829 clear_tv(&tv); 2830 } 2831 else 2832 { 2833 /* No need to increment the refcount, it's already set for the 2834 * list being used in "tv". */ 2835 fi->fi_list = l; 2836 list_add_watch(l, &fi->fi_lw); 2837 fi->fi_lw.lw_item = l->lv_first; 2838 } 2839 } 2840 } 2841 if (skip) 2842 --emsg_skip; 2843 2844 return fi; 2845 } 2846 2847 /* 2848 * Use the first item in a ":for" list. Advance to the next. 2849 * Assign the values to the variable (list). "arg" points to the first one. 2850 * Return TRUE when a valid item was found, FALSE when at end of list or 2851 * something wrong. 2852 */ 2853 int 2854 next_for_item(fi_void, arg) 2855 void *fi_void; 2856 char_u *arg; 2857 { 2858 forinfo_T *fi = (forinfo_T *)fi_void; 2859 int result; 2860 listitem_T *item; 2861 2862 item = fi->fi_lw.lw_item; 2863 if (item == NULL) 2864 result = FALSE; 2865 else 2866 { 2867 fi->fi_lw.lw_item = item->li_next; 2868 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2869 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2870 } 2871 return result; 2872 } 2873 2874 /* 2875 * Free the structure used to store info used by ":for". 2876 */ 2877 void 2878 free_for_info(fi_void) 2879 void *fi_void; 2880 { 2881 forinfo_T *fi = (forinfo_T *)fi_void; 2882 2883 if (fi != NULL && fi->fi_list != NULL) 2884 { 2885 list_rem_watch(fi->fi_list, &fi->fi_lw); 2886 list_unref(fi->fi_list); 2887 } 2888 vim_free(fi); 2889 } 2890 2891 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2892 2893 void 2894 set_context_for_expression(xp, arg, cmdidx) 2895 expand_T *xp; 2896 char_u *arg; 2897 cmdidx_T cmdidx; 2898 { 2899 int got_eq = FALSE; 2900 int c; 2901 char_u *p; 2902 2903 if (cmdidx == CMD_let) 2904 { 2905 xp->xp_context = EXPAND_USER_VARS; 2906 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2907 { 2908 /* ":let var1 var2 ...": find last space. */ 2909 for (p = arg + STRLEN(arg); p >= arg; ) 2910 { 2911 xp->xp_pattern = p; 2912 mb_ptr_back(arg, p); 2913 if (vim_iswhite(*p)) 2914 break; 2915 } 2916 return; 2917 } 2918 } 2919 else 2920 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2921 : EXPAND_EXPRESSION; 2922 while ((xp->xp_pattern = vim_strpbrk(arg, 2923 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2924 { 2925 c = *xp->xp_pattern; 2926 if (c == '&') 2927 { 2928 c = xp->xp_pattern[1]; 2929 if (c == '&') 2930 { 2931 ++xp->xp_pattern; 2932 xp->xp_context = cmdidx != CMD_let || got_eq 2933 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2934 } 2935 else if (c != ' ') 2936 { 2937 xp->xp_context = EXPAND_SETTINGS; 2938 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2939 xp->xp_pattern += 2; 2940 2941 } 2942 } 2943 else if (c == '$') 2944 { 2945 /* environment variable */ 2946 xp->xp_context = EXPAND_ENV_VARS; 2947 } 2948 else if (c == '=') 2949 { 2950 got_eq = TRUE; 2951 xp->xp_context = EXPAND_EXPRESSION; 2952 } 2953 else if (c == '<' 2954 && xp->xp_context == EXPAND_FUNCTIONS 2955 && vim_strchr(xp->xp_pattern, '(') == NULL) 2956 { 2957 /* Function name can start with "<SNR>" */ 2958 break; 2959 } 2960 else if (cmdidx != CMD_let || got_eq) 2961 { 2962 if (c == '"') /* string */ 2963 { 2964 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2965 if (c == '\\' && xp->xp_pattern[1] != NUL) 2966 ++xp->xp_pattern; 2967 xp->xp_context = EXPAND_NOTHING; 2968 } 2969 else if (c == '\'') /* literal string */ 2970 { 2971 /* Trick: '' is like stopping and starting a literal string. */ 2972 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2973 /* skip */ ; 2974 xp->xp_context = EXPAND_NOTHING; 2975 } 2976 else if (c == '|') 2977 { 2978 if (xp->xp_pattern[1] == '|') 2979 { 2980 ++xp->xp_pattern; 2981 xp->xp_context = EXPAND_EXPRESSION; 2982 } 2983 else 2984 xp->xp_context = EXPAND_COMMANDS; 2985 } 2986 else 2987 xp->xp_context = EXPAND_EXPRESSION; 2988 } 2989 else 2990 /* Doesn't look like something valid, expand as an expression 2991 * anyway. */ 2992 xp->xp_context = EXPAND_EXPRESSION; 2993 arg = xp->xp_pattern; 2994 if (*arg != NUL) 2995 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 2996 /* skip */ ; 2997 } 2998 xp->xp_pattern = arg; 2999 } 3000 3001 #endif /* FEAT_CMDL_COMPL */ 3002 3003 /* 3004 * ":1,25call func(arg1, arg2)" function call. 3005 */ 3006 void 3007 ex_call(eap) 3008 exarg_T *eap; 3009 { 3010 char_u *arg = eap->arg; 3011 char_u *startarg; 3012 char_u *name; 3013 char_u *tofree; 3014 int len; 3015 typval_T rettv; 3016 linenr_T lnum; 3017 int doesrange; 3018 int failed = FALSE; 3019 funcdict_T fudi; 3020 3021 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3022 vim_free(fudi.fd_newkey); 3023 if (tofree == NULL) 3024 return; 3025 3026 /* Increase refcount on dictionary, it could get deleted when evaluating 3027 * the arguments. */ 3028 if (fudi.fd_dict != NULL) 3029 ++fudi.fd_dict->dv_refcount; 3030 3031 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3032 len = STRLEN(tofree); 3033 name = deref_func_name(tofree, &len); 3034 3035 /* Skip white space to allow ":call func ()". Not good, but required for 3036 * backward compatibility. */ 3037 startarg = skipwhite(arg); 3038 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3039 3040 if (*startarg != '(') 3041 { 3042 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3043 goto end; 3044 } 3045 3046 /* 3047 * When skipping, evaluate the function once, to find the end of the 3048 * arguments. 3049 * When the function takes a range, this is discovered after the first 3050 * call, and the loop is broken. 3051 */ 3052 if (eap->skip) 3053 { 3054 ++emsg_skip; 3055 lnum = eap->line2; /* do it once, also with an invalid range */ 3056 } 3057 else 3058 lnum = eap->line1; 3059 for ( ; lnum <= eap->line2; ++lnum) 3060 { 3061 if (!eap->skip && eap->addr_count > 0) 3062 { 3063 curwin->w_cursor.lnum = lnum; 3064 curwin->w_cursor.col = 0; 3065 } 3066 arg = startarg; 3067 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3068 eap->line1, eap->line2, &doesrange, 3069 !eap->skip, fudi.fd_dict) == FAIL) 3070 { 3071 failed = TRUE; 3072 break; 3073 } 3074 clear_tv(&rettv); 3075 if (doesrange || eap->skip) 3076 break; 3077 /* Stop when immediately aborting on error, or when an interrupt 3078 * occurred or an exception was thrown but not caught. 3079 * get_func_tv() returned OK, so that the check for trailing 3080 * characters below is executed. */ 3081 if (aborting()) 3082 break; 3083 } 3084 if (eap->skip) 3085 --emsg_skip; 3086 3087 if (!failed) 3088 { 3089 /* Check for trailing illegal characters and a following command. */ 3090 if (!ends_excmd(*arg)) 3091 { 3092 emsg_severe = TRUE; 3093 EMSG(_(e_trailing)); 3094 } 3095 else 3096 eap->nextcmd = check_nextcmd(arg); 3097 } 3098 3099 end: 3100 dict_unref(fudi.fd_dict); 3101 vim_free(tofree); 3102 } 3103 3104 /* 3105 * ":unlet[!] var1 ... " command. 3106 */ 3107 void 3108 ex_unlet(eap) 3109 exarg_T *eap; 3110 { 3111 ex_unletlock(eap, eap->arg, 0); 3112 } 3113 3114 /* 3115 * ":lockvar" and ":unlockvar" commands 3116 */ 3117 void 3118 ex_lockvar(eap) 3119 exarg_T *eap; 3120 { 3121 char_u *arg = eap->arg; 3122 int deep = 2; 3123 3124 if (eap->forceit) 3125 deep = -1; 3126 else if (vim_isdigit(*arg)) 3127 { 3128 deep = getdigits(&arg); 3129 arg = skipwhite(arg); 3130 } 3131 3132 ex_unletlock(eap, arg, deep); 3133 } 3134 3135 /* 3136 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3137 */ 3138 static void 3139 ex_unletlock(eap, argstart, deep) 3140 exarg_T *eap; 3141 char_u *argstart; 3142 int deep; 3143 { 3144 char_u *arg = argstart; 3145 char_u *name_end; 3146 int error = FALSE; 3147 lval_T lv; 3148 3149 do 3150 { 3151 /* Parse the name and find the end. */ 3152 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3153 FNE_CHECK_START); 3154 if (lv.ll_name == NULL) 3155 error = TRUE; /* error but continue parsing */ 3156 if (name_end == NULL || (!vim_iswhite(*name_end) 3157 && !ends_excmd(*name_end))) 3158 { 3159 if (name_end != NULL) 3160 { 3161 emsg_severe = TRUE; 3162 EMSG(_(e_trailing)); 3163 } 3164 if (!(eap->skip || error)) 3165 clear_lval(&lv); 3166 break; 3167 } 3168 3169 if (!error && !eap->skip) 3170 { 3171 if (eap->cmdidx == CMD_unlet) 3172 { 3173 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3174 error = TRUE; 3175 } 3176 else 3177 { 3178 if (do_lock_var(&lv, name_end, deep, 3179 eap->cmdidx == CMD_lockvar) == FAIL) 3180 error = TRUE; 3181 } 3182 } 3183 3184 if (!eap->skip) 3185 clear_lval(&lv); 3186 3187 arg = skipwhite(name_end); 3188 } while (!ends_excmd(*arg)); 3189 3190 eap->nextcmd = check_nextcmd(arg); 3191 } 3192 3193 static int 3194 do_unlet_var(lp, name_end, forceit) 3195 lval_T *lp; 3196 char_u *name_end; 3197 int forceit; 3198 { 3199 int ret = OK; 3200 int cc; 3201 3202 if (lp->ll_tv == NULL) 3203 { 3204 cc = *name_end; 3205 *name_end = NUL; 3206 3207 /* Normal name or expanded name. */ 3208 if (check_changedtick(lp->ll_name)) 3209 ret = FAIL; 3210 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3211 ret = FAIL; 3212 *name_end = cc; 3213 } 3214 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3215 return FAIL; 3216 else if (lp->ll_range) 3217 { 3218 listitem_T *li; 3219 3220 /* Delete a range of List items. */ 3221 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3222 { 3223 li = lp->ll_li->li_next; 3224 listitem_remove(lp->ll_list, lp->ll_li); 3225 lp->ll_li = li; 3226 ++lp->ll_n1; 3227 } 3228 } 3229 else 3230 { 3231 if (lp->ll_list != NULL) 3232 /* unlet a List item. */ 3233 listitem_remove(lp->ll_list, lp->ll_li); 3234 else 3235 /* unlet a Dictionary item. */ 3236 dictitem_remove(lp->ll_dict, lp->ll_di); 3237 } 3238 3239 return ret; 3240 } 3241 3242 /* 3243 * "unlet" a variable. Return OK if it existed, FAIL if not. 3244 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3245 */ 3246 int 3247 do_unlet(name, forceit) 3248 char_u *name; 3249 int forceit; 3250 { 3251 hashtab_T *ht; 3252 hashitem_T *hi; 3253 char_u *varname; 3254 3255 ht = find_var_ht(name, &varname); 3256 if (ht != NULL && *varname != NUL) 3257 { 3258 hi = hash_find(ht, varname); 3259 if (!HASHITEM_EMPTY(hi)) 3260 { 3261 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3262 return FAIL; 3263 delete_var(ht, hi); 3264 return OK; 3265 } 3266 } 3267 if (forceit) 3268 return OK; 3269 EMSG2(_("E108: No such variable: \"%s\""), name); 3270 return FAIL; 3271 } 3272 3273 /* 3274 * Lock or unlock variable indicated by "lp". 3275 * "deep" is the levels to go (-1 for unlimited); 3276 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3277 */ 3278 static int 3279 do_lock_var(lp, name_end, deep, lock) 3280 lval_T *lp; 3281 char_u *name_end; 3282 int deep; 3283 int lock; 3284 { 3285 int ret = OK; 3286 int cc; 3287 dictitem_T *di; 3288 3289 if (deep == 0) /* nothing to do */ 3290 return OK; 3291 3292 if (lp->ll_tv == NULL) 3293 { 3294 cc = *name_end; 3295 *name_end = NUL; 3296 3297 /* Normal name or expanded name. */ 3298 if (check_changedtick(lp->ll_name)) 3299 ret = FAIL; 3300 else 3301 { 3302 di = find_var(lp->ll_name, NULL); 3303 if (di == NULL) 3304 ret = FAIL; 3305 else 3306 { 3307 if (lock) 3308 di->di_flags |= DI_FLAGS_LOCK; 3309 else 3310 di->di_flags &= ~DI_FLAGS_LOCK; 3311 item_lock(&di->di_tv, deep, lock); 3312 } 3313 } 3314 *name_end = cc; 3315 } 3316 else if (lp->ll_range) 3317 { 3318 listitem_T *li = lp->ll_li; 3319 3320 /* (un)lock a range of List items. */ 3321 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3322 { 3323 item_lock(&li->li_tv, deep, lock); 3324 li = li->li_next; 3325 ++lp->ll_n1; 3326 } 3327 } 3328 else if (lp->ll_list != NULL) 3329 /* (un)lock a List item. */ 3330 item_lock(&lp->ll_li->li_tv, deep, lock); 3331 else 3332 /* un(lock) a Dictionary item. */ 3333 item_lock(&lp->ll_di->di_tv, deep, lock); 3334 3335 return ret; 3336 } 3337 3338 /* 3339 * Lock or unlock an item. "deep" is nr of levels to go. 3340 */ 3341 static void 3342 item_lock(tv, deep, lock) 3343 typval_T *tv; 3344 int deep; 3345 int lock; 3346 { 3347 static int recurse = 0; 3348 list_T *l; 3349 listitem_T *li; 3350 dict_T *d; 3351 hashitem_T *hi; 3352 int todo; 3353 3354 if (recurse >= DICT_MAXNEST) 3355 { 3356 EMSG(_("E743: variable nested too deep for (un)lock")); 3357 return; 3358 } 3359 if (deep == 0) 3360 return; 3361 ++recurse; 3362 3363 /* lock/unlock the item itself */ 3364 if (lock) 3365 tv->v_lock |= VAR_LOCKED; 3366 else 3367 tv->v_lock &= ~VAR_LOCKED; 3368 3369 switch (tv->v_type) 3370 { 3371 case VAR_LIST: 3372 if ((l = tv->vval.v_list) != NULL) 3373 { 3374 if (lock) 3375 l->lv_lock |= VAR_LOCKED; 3376 else 3377 l->lv_lock &= ~VAR_LOCKED; 3378 if (deep < 0 || deep > 1) 3379 /* recursive: lock/unlock the items the List contains */ 3380 for (li = l->lv_first; li != NULL; li = li->li_next) 3381 item_lock(&li->li_tv, deep - 1, lock); 3382 } 3383 break; 3384 case VAR_DICT: 3385 if ((d = tv->vval.v_dict) != NULL) 3386 { 3387 if (lock) 3388 d->dv_lock |= VAR_LOCKED; 3389 else 3390 d->dv_lock &= ~VAR_LOCKED; 3391 if (deep < 0 || deep > 1) 3392 { 3393 /* recursive: lock/unlock the items the List contains */ 3394 todo = d->dv_hashtab.ht_used; 3395 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3396 { 3397 if (!HASHITEM_EMPTY(hi)) 3398 { 3399 --todo; 3400 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3401 } 3402 } 3403 } 3404 } 3405 } 3406 --recurse; 3407 } 3408 3409 /* 3410 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3411 * it refers to a List or Dictionary that is locked. 3412 */ 3413 static int 3414 tv_islocked(tv) 3415 typval_T *tv; 3416 { 3417 return (tv->v_lock & VAR_LOCKED) 3418 || (tv->v_type == VAR_LIST 3419 && tv->vval.v_list != NULL 3420 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3421 || (tv->v_type == VAR_DICT 3422 && tv->vval.v_dict != NULL 3423 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3424 } 3425 3426 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3427 /* 3428 * Delete all "menutrans_" variables. 3429 */ 3430 void 3431 del_menutrans_vars() 3432 { 3433 hashitem_T *hi; 3434 int todo; 3435 3436 hash_lock(&globvarht); 3437 todo = globvarht.ht_used; 3438 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3439 { 3440 if (!HASHITEM_EMPTY(hi)) 3441 { 3442 --todo; 3443 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3444 delete_var(&globvarht, hi); 3445 } 3446 } 3447 hash_unlock(&globvarht); 3448 } 3449 #endif 3450 3451 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3452 3453 /* 3454 * Local string buffer for the next two functions to store a variable name 3455 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3456 * get_user_var_name(). 3457 */ 3458 3459 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3460 3461 static char_u *varnamebuf = NULL; 3462 static int varnamebuflen = 0; 3463 3464 /* 3465 * Function to concatenate a prefix and a variable name. 3466 */ 3467 static char_u * 3468 cat_prefix_varname(prefix, name) 3469 int prefix; 3470 char_u *name; 3471 { 3472 int len; 3473 3474 len = (int)STRLEN(name) + 3; 3475 if (len > varnamebuflen) 3476 { 3477 vim_free(varnamebuf); 3478 len += 10; /* some additional space */ 3479 varnamebuf = alloc(len); 3480 if (varnamebuf == NULL) 3481 { 3482 varnamebuflen = 0; 3483 return NULL; 3484 } 3485 varnamebuflen = len; 3486 } 3487 *varnamebuf = prefix; 3488 varnamebuf[1] = ':'; 3489 STRCPY(varnamebuf + 2, name); 3490 return varnamebuf; 3491 } 3492 3493 /* 3494 * Function given to ExpandGeneric() to obtain the list of user defined 3495 * (global/buffer/window/built-in) variable names. 3496 */ 3497 /*ARGSUSED*/ 3498 char_u * 3499 get_user_var_name(xp, idx) 3500 expand_T *xp; 3501 int idx; 3502 { 3503 static long_u gdone; 3504 static long_u bdone; 3505 static long_u wdone; 3506 static int vidx; 3507 static hashitem_T *hi; 3508 hashtab_T *ht; 3509 3510 if (idx == 0) 3511 gdone = bdone = wdone = vidx = 0; 3512 3513 /* Global variables */ 3514 if (gdone < globvarht.ht_used) 3515 { 3516 if (gdone++ == 0) 3517 hi = globvarht.ht_array; 3518 else 3519 ++hi; 3520 while (HASHITEM_EMPTY(hi)) 3521 ++hi; 3522 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3523 return cat_prefix_varname('g', hi->hi_key); 3524 return hi->hi_key; 3525 } 3526 3527 /* b: variables */ 3528 ht = &curbuf->b_vars.dv_hashtab; 3529 if (bdone < ht->ht_used) 3530 { 3531 if (bdone++ == 0) 3532 hi = ht->ht_array; 3533 else 3534 ++hi; 3535 while (HASHITEM_EMPTY(hi)) 3536 ++hi; 3537 return cat_prefix_varname('b', hi->hi_key); 3538 } 3539 if (bdone == ht->ht_used) 3540 { 3541 ++bdone; 3542 return (char_u *)"b:changedtick"; 3543 } 3544 3545 /* w: variables */ 3546 ht = &curwin->w_vars.dv_hashtab; 3547 if (wdone < ht->ht_used) 3548 { 3549 if (wdone++ == 0) 3550 hi = ht->ht_array; 3551 else 3552 ++hi; 3553 while (HASHITEM_EMPTY(hi)) 3554 ++hi; 3555 return cat_prefix_varname('w', hi->hi_key); 3556 } 3557 3558 /* v: variables */ 3559 if (vidx < VV_LEN) 3560 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3561 3562 vim_free(varnamebuf); 3563 varnamebuf = NULL; 3564 varnamebuflen = 0; 3565 return NULL; 3566 } 3567 3568 #endif /* FEAT_CMDL_COMPL */ 3569 3570 /* 3571 * types for expressions. 3572 */ 3573 typedef enum 3574 { 3575 TYPE_UNKNOWN = 0 3576 , TYPE_EQUAL /* == */ 3577 , TYPE_NEQUAL /* != */ 3578 , TYPE_GREATER /* > */ 3579 , TYPE_GEQUAL /* >= */ 3580 , TYPE_SMALLER /* < */ 3581 , TYPE_SEQUAL /* <= */ 3582 , TYPE_MATCH /* =~ */ 3583 , TYPE_NOMATCH /* !~ */ 3584 } exptype_T; 3585 3586 /* 3587 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3588 * executed. The function may return OK, but the rettv will be of type 3589 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3590 */ 3591 3592 /* 3593 * Handle zero level expression. 3594 * This calls eval1() and handles error message and nextcmd. 3595 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3596 * Note: "rettv.v_lock" is not set. 3597 * Return OK or FAIL. 3598 */ 3599 static int 3600 eval0(arg, rettv, nextcmd, evaluate) 3601 char_u *arg; 3602 typval_T *rettv; 3603 char_u **nextcmd; 3604 int evaluate; 3605 { 3606 int ret; 3607 char_u *p; 3608 3609 p = skipwhite(arg); 3610 ret = eval1(&p, rettv, evaluate); 3611 if (ret == FAIL || !ends_excmd(*p)) 3612 { 3613 if (ret != FAIL) 3614 clear_tv(rettv); 3615 /* 3616 * Report the invalid expression unless the expression evaluation has 3617 * been cancelled due to an aborting error, an interrupt, or an 3618 * exception. 3619 */ 3620 if (!aborting()) 3621 EMSG2(_(e_invexpr2), arg); 3622 ret = FAIL; 3623 } 3624 if (nextcmd != NULL) 3625 *nextcmd = check_nextcmd(p); 3626 3627 return ret; 3628 } 3629 3630 /* 3631 * Handle top level expression: 3632 * expr1 ? expr0 : expr0 3633 * 3634 * "arg" must point to the first non-white of the expression. 3635 * "arg" is advanced to the next non-white after the recognized expression. 3636 * 3637 * Note: "rettv.v_lock" is not set. 3638 * 3639 * Return OK or FAIL. 3640 */ 3641 static int 3642 eval1(arg, rettv, evaluate) 3643 char_u **arg; 3644 typval_T *rettv; 3645 int evaluate; 3646 { 3647 int result; 3648 typval_T var2; 3649 3650 /* 3651 * Get the first variable. 3652 */ 3653 if (eval2(arg, rettv, evaluate) == FAIL) 3654 return FAIL; 3655 3656 if ((*arg)[0] == '?') 3657 { 3658 result = FALSE; 3659 if (evaluate) 3660 { 3661 int error = FALSE; 3662 3663 if (get_tv_number_chk(rettv, &error) != 0) 3664 result = TRUE; 3665 clear_tv(rettv); 3666 if (error) 3667 return FAIL; 3668 } 3669 3670 /* 3671 * Get the second variable. 3672 */ 3673 *arg = skipwhite(*arg + 1); 3674 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3675 return FAIL; 3676 3677 /* 3678 * Check for the ":". 3679 */ 3680 if ((*arg)[0] != ':') 3681 { 3682 EMSG(_("E109: Missing ':' after '?'")); 3683 if (evaluate && result) 3684 clear_tv(rettv); 3685 return FAIL; 3686 } 3687 3688 /* 3689 * Get the third variable. 3690 */ 3691 *arg = skipwhite(*arg + 1); 3692 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3693 { 3694 if (evaluate && result) 3695 clear_tv(rettv); 3696 return FAIL; 3697 } 3698 if (evaluate && !result) 3699 *rettv = var2; 3700 } 3701 3702 return OK; 3703 } 3704 3705 /* 3706 * Handle first level expression: 3707 * expr2 || expr2 || expr2 logical OR 3708 * 3709 * "arg" must point to the first non-white of the expression. 3710 * "arg" is advanced to the next non-white after the recognized expression. 3711 * 3712 * Return OK or FAIL. 3713 */ 3714 static int 3715 eval2(arg, rettv, evaluate) 3716 char_u **arg; 3717 typval_T *rettv; 3718 int evaluate; 3719 { 3720 typval_T var2; 3721 long result; 3722 int first; 3723 int error = FALSE; 3724 3725 /* 3726 * Get the first variable. 3727 */ 3728 if (eval3(arg, rettv, evaluate) == FAIL) 3729 return FAIL; 3730 3731 /* 3732 * Repeat until there is no following "||". 3733 */ 3734 first = TRUE; 3735 result = FALSE; 3736 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3737 { 3738 if (evaluate && first) 3739 { 3740 if (get_tv_number_chk(rettv, &error) != 0) 3741 result = TRUE; 3742 clear_tv(rettv); 3743 if (error) 3744 return FAIL; 3745 first = FALSE; 3746 } 3747 3748 /* 3749 * Get the second variable. 3750 */ 3751 *arg = skipwhite(*arg + 2); 3752 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3753 return FAIL; 3754 3755 /* 3756 * Compute the result. 3757 */ 3758 if (evaluate && !result) 3759 { 3760 if (get_tv_number_chk(&var2, &error) != 0) 3761 result = TRUE; 3762 clear_tv(&var2); 3763 if (error) 3764 return FAIL; 3765 } 3766 if (evaluate) 3767 { 3768 rettv->v_type = VAR_NUMBER; 3769 rettv->vval.v_number = result; 3770 } 3771 } 3772 3773 return OK; 3774 } 3775 3776 /* 3777 * Handle second level expression: 3778 * expr3 && expr3 && expr3 logical AND 3779 * 3780 * "arg" must point to the first non-white of the expression. 3781 * "arg" is advanced to the next non-white after the recognized expression. 3782 * 3783 * Return OK or FAIL. 3784 */ 3785 static int 3786 eval3(arg, rettv, evaluate) 3787 char_u **arg; 3788 typval_T *rettv; 3789 int evaluate; 3790 { 3791 typval_T var2; 3792 long result; 3793 int first; 3794 int error = FALSE; 3795 3796 /* 3797 * Get the first variable. 3798 */ 3799 if (eval4(arg, rettv, evaluate) == FAIL) 3800 return FAIL; 3801 3802 /* 3803 * Repeat until there is no following "&&". 3804 */ 3805 first = TRUE; 3806 result = TRUE; 3807 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3808 { 3809 if (evaluate && first) 3810 { 3811 if (get_tv_number_chk(rettv, &error) == 0) 3812 result = FALSE; 3813 clear_tv(rettv); 3814 if (error) 3815 return FAIL; 3816 first = FALSE; 3817 } 3818 3819 /* 3820 * Get the second variable. 3821 */ 3822 *arg = skipwhite(*arg + 2); 3823 if (eval4(arg, &var2, evaluate && result) == FAIL) 3824 return FAIL; 3825 3826 /* 3827 * Compute the result. 3828 */ 3829 if (evaluate && result) 3830 { 3831 if (get_tv_number_chk(&var2, &error) == 0) 3832 result = FALSE; 3833 clear_tv(&var2); 3834 if (error) 3835 return FAIL; 3836 } 3837 if (evaluate) 3838 { 3839 rettv->v_type = VAR_NUMBER; 3840 rettv->vval.v_number = result; 3841 } 3842 } 3843 3844 return OK; 3845 } 3846 3847 /* 3848 * Handle third level expression: 3849 * var1 == var2 3850 * var1 =~ var2 3851 * var1 != var2 3852 * var1 !~ var2 3853 * var1 > var2 3854 * var1 >= var2 3855 * var1 < var2 3856 * var1 <= var2 3857 * var1 is var2 3858 * var1 isnot var2 3859 * 3860 * "arg" must point to the first non-white of the expression. 3861 * "arg" is advanced to the next non-white after the recognized expression. 3862 * 3863 * Return OK or FAIL. 3864 */ 3865 static int 3866 eval4(arg, rettv, evaluate) 3867 char_u **arg; 3868 typval_T *rettv; 3869 int evaluate; 3870 { 3871 typval_T var2; 3872 char_u *p; 3873 int i; 3874 exptype_T type = TYPE_UNKNOWN; 3875 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3876 int len = 2; 3877 long n1, n2; 3878 char_u *s1, *s2; 3879 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3880 regmatch_T regmatch; 3881 int ic; 3882 char_u *save_cpo; 3883 3884 /* 3885 * Get the first variable. 3886 */ 3887 if (eval5(arg, rettv, evaluate) == FAIL) 3888 return FAIL; 3889 3890 p = *arg; 3891 switch (p[0]) 3892 { 3893 case '=': if (p[1] == '=') 3894 type = TYPE_EQUAL; 3895 else if (p[1] == '~') 3896 type = TYPE_MATCH; 3897 break; 3898 case '!': if (p[1] == '=') 3899 type = TYPE_NEQUAL; 3900 else if (p[1] == '~') 3901 type = TYPE_NOMATCH; 3902 break; 3903 case '>': if (p[1] != '=') 3904 { 3905 type = TYPE_GREATER; 3906 len = 1; 3907 } 3908 else 3909 type = TYPE_GEQUAL; 3910 break; 3911 case '<': if (p[1] != '=') 3912 { 3913 type = TYPE_SMALLER; 3914 len = 1; 3915 } 3916 else 3917 type = TYPE_SEQUAL; 3918 break; 3919 case 'i': if (p[1] == 's') 3920 { 3921 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3922 len = 5; 3923 if (!vim_isIDc(p[len])) 3924 { 3925 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3926 type_is = TRUE; 3927 } 3928 } 3929 break; 3930 } 3931 3932 /* 3933 * If there is a comparitive operator, use it. 3934 */ 3935 if (type != TYPE_UNKNOWN) 3936 { 3937 /* extra question mark appended: ignore case */ 3938 if (p[len] == '?') 3939 { 3940 ic = TRUE; 3941 ++len; 3942 } 3943 /* extra '#' appended: match case */ 3944 else if (p[len] == '#') 3945 { 3946 ic = FALSE; 3947 ++len; 3948 } 3949 /* nothing appened: use 'ignorecase' */ 3950 else 3951 ic = p_ic; 3952 3953 /* 3954 * Get the second variable. 3955 */ 3956 *arg = skipwhite(p + len); 3957 if (eval5(arg, &var2, evaluate) == FAIL) 3958 { 3959 clear_tv(rettv); 3960 return FAIL; 3961 } 3962 3963 if (evaluate) 3964 { 3965 if (type_is && rettv->v_type != var2.v_type) 3966 { 3967 /* For "is" a different type always means FALSE, for "notis" 3968 * it means TRUE. */ 3969 n1 = (type == TYPE_NEQUAL); 3970 } 3971 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3972 { 3973 if (type_is) 3974 { 3975 n1 = (rettv->v_type == var2.v_type 3976 && rettv->vval.v_list == var2.vval.v_list); 3977 if (type == TYPE_NEQUAL) 3978 n1 = !n1; 3979 } 3980 else if (rettv->v_type != var2.v_type 3981 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3982 { 3983 if (rettv->v_type != var2.v_type) 3984 EMSG(_("E691: Can only compare List with List")); 3985 else 3986 EMSG(_("E692: Invalid operation for Lists")); 3987 clear_tv(rettv); 3988 clear_tv(&var2); 3989 return FAIL; 3990 } 3991 else 3992 { 3993 /* Compare two Lists for being equal or unequal. */ 3994 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3995 if (type == TYPE_NEQUAL) 3996 n1 = !n1; 3997 } 3998 } 3999 4000 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4001 { 4002 if (type_is) 4003 { 4004 n1 = (rettv->v_type == var2.v_type 4005 && rettv->vval.v_dict == var2.vval.v_dict); 4006 if (type == TYPE_NEQUAL) 4007 n1 = !n1; 4008 } 4009 else if (rettv->v_type != var2.v_type 4010 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4011 { 4012 if (rettv->v_type != var2.v_type) 4013 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4014 else 4015 EMSG(_("E736: Invalid operation for Dictionary")); 4016 clear_tv(rettv); 4017 clear_tv(&var2); 4018 return FAIL; 4019 } 4020 else 4021 { 4022 /* Compare two Dictionaries for being equal or unequal. */ 4023 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4024 if (type == TYPE_NEQUAL) 4025 n1 = !n1; 4026 } 4027 } 4028 4029 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4030 { 4031 if (rettv->v_type != var2.v_type 4032 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4033 { 4034 if (rettv->v_type != var2.v_type) 4035 EMSG(_("E693: Can only compare Funcref with Funcref")); 4036 else 4037 EMSG(_("E694: Invalid operation for Funcrefs")); 4038 clear_tv(rettv); 4039 clear_tv(&var2); 4040 return FAIL; 4041 } 4042 else 4043 { 4044 /* Compare two Funcrefs for being equal or unequal. */ 4045 if (rettv->vval.v_string == NULL 4046 || var2.vval.v_string == NULL) 4047 n1 = FALSE; 4048 else 4049 n1 = STRCMP(rettv->vval.v_string, 4050 var2.vval.v_string) == 0; 4051 if (type == TYPE_NEQUAL) 4052 n1 = !n1; 4053 } 4054 } 4055 4056 /* 4057 * If one of the two variables is a number, compare as a number. 4058 * When using "=~" or "!~", always compare as string. 4059 */ 4060 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4061 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4062 { 4063 n1 = get_tv_number(rettv); 4064 n2 = get_tv_number(&var2); 4065 switch (type) 4066 { 4067 case TYPE_EQUAL: n1 = (n1 == n2); break; 4068 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4069 case TYPE_GREATER: n1 = (n1 > n2); break; 4070 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4071 case TYPE_SMALLER: n1 = (n1 < n2); break; 4072 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4073 case TYPE_UNKNOWN: 4074 case TYPE_MATCH: 4075 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4076 } 4077 } 4078 else 4079 { 4080 s1 = get_tv_string_buf(rettv, buf1); 4081 s2 = get_tv_string_buf(&var2, buf2); 4082 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4083 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4084 else 4085 i = 0; 4086 n1 = FALSE; 4087 switch (type) 4088 { 4089 case TYPE_EQUAL: n1 = (i == 0); break; 4090 case TYPE_NEQUAL: n1 = (i != 0); break; 4091 case TYPE_GREATER: n1 = (i > 0); break; 4092 case TYPE_GEQUAL: n1 = (i >= 0); break; 4093 case TYPE_SMALLER: n1 = (i < 0); break; 4094 case TYPE_SEQUAL: n1 = (i <= 0); break; 4095 4096 case TYPE_MATCH: 4097 case TYPE_NOMATCH: 4098 /* avoid 'l' flag in 'cpoptions' */ 4099 save_cpo = p_cpo; 4100 p_cpo = (char_u *)""; 4101 regmatch.regprog = vim_regcomp(s2, 4102 RE_MAGIC + RE_STRING); 4103 regmatch.rm_ic = ic; 4104 if (regmatch.regprog != NULL) 4105 { 4106 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4107 vim_free(regmatch.regprog); 4108 if (type == TYPE_NOMATCH) 4109 n1 = !n1; 4110 } 4111 p_cpo = save_cpo; 4112 break; 4113 4114 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4115 } 4116 } 4117 clear_tv(rettv); 4118 clear_tv(&var2); 4119 rettv->v_type = VAR_NUMBER; 4120 rettv->vval.v_number = n1; 4121 } 4122 } 4123 4124 return OK; 4125 } 4126 4127 /* 4128 * Handle fourth level expression: 4129 * + number addition 4130 * - number subtraction 4131 * . string concatenation 4132 * 4133 * "arg" must point to the first non-white of the expression. 4134 * "arg" is advanced to the next non-white after the recognized expression. 4135 * 4136 * Return OK or FAIL. 4137 */ 4138 static int 4139 eval5(arg, rettv, evaluate) 4140 char_u **arg; 4141 typval_T *rettv; 4142 int evaluate; 4143 { 4144 typval_T var2; 4145 typval_T var3; 4146 int op; 4147 long n1, n2; 4148 char_u *s1, *s2; 4149 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4150 char_u *p; 4151 4152 /* 4153 * Get the first variable. 4154 */ 4155 if (eval6(arg, rettv, evaluate) == FAIL) 4156 return FAIL; 4157 4158 /* 4159 * Repeat computing, until no '+', '-' or '.' is following. 4160 */ 4161 for (;;) 4162 { 4163 op = **arg; 4164 if (op != '+' && op != '-' && op != '.') 4165 break; 4166 4167 if (op != '+' || rettv->v_type != VAR_LIST) 4168 { 4169 /* For "list + ...", an illegal use of the first operand as 4170 * a number cannot be determined before evaluating the 2nd 4171 * operand: if this is also a list, all is ok. 4172 * For "something . ...", "something - ..." or "non-list + ...", 4173 * we know that the first operand needs to be a string or number 4174 * without evaluating the 2nd operand. So check before to avoid 4175 * side effects after an error. */ 4176 if (evaluate && get_tv_string_chk(rettv) == NULL) 4177 { 4178 clear_tv(rettv); 4179 return FAIL; 4180 } 4181 } 4182 4183 /* 4184 * Get the second variable. 4185 */ 4186 *arg = skipwhite(*arg + 1); 4187 if (eval6(arg, &var2, evaluate) == FAIL) 4188 { 4189 clear_tv(rettv); 4190 return FAIL; 4191 } 4192 4193 if (evaluate) 4194 { 4195 /* 4196 * Compute the result. 4197 */ 4198 if (op == '.') 4199 { 4200 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4201 s2 = get_tv_string_buf_chk(&var2, buf2); 4202 if (s2 == NULL) /* type error ? */ 4203 { 4204 clear_tv(rettv); 4205 clear_tv(&var2); 4206 return FAIL; 4207 } 4208 p = concat_str(s1, s2); 4209 clear_tv(rettv); 4210 rettv->v_type = VAR_STRING; 4211 rettv->vval.v_string = p; 4212 } 4213 else if (op == '+' && rettv->v_type == VAR_LIST 4214 && var2.v_type == VAR_LIST) 4215 { 4216 /* concatenate Lists */ 4217 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4218 &var3) == FAIL) 4219 { 4220 clear_tv(rettv); 4221 clear_tv(&var2); 4222 return FAIL; 4223 } 4224 clear_tv(rettv); 4225 *rettv = var3; 4226 } 4227 else 4228 { 4229 int error = FALSE; 4230 4231 n1 = get_tv_number_chk(rettv, &error); 4232 if (error) 4233 { 4234 /* This can only happen for "list + non-list". 4235 * For "non-list + ..." or "something - ...", we returned 4236 * before evaluating the 2nd operand. */ 4237 clear_tv(rettv); 4238 return FAIL; 4239 } 4240 n2 = get_tv_number_chk(&var2, &error); 4241 if (error) 4242 { 4243 clear_tv(rettv); 4244 clear_tv(&var2); 4245 return FAIL; 4246 } 4247 clear_tv(rettv); 4248 if (op == '+') 4249 n1 = n1 + n2; 4250 else 4251 n1 = n1 - n2; 4252 rettv->v_type = VAR_NUMBER; 4253 rettv->vval.v_number = n1; 4254 } 4255 clear_tv(&var2); 4256 } 4257 } 4258 return OK; 4259 } 4260 4261 /* 4262 * Handle fifth level expression: 4263 * * number multiplication 4264 * / number division 4265 * % number modulo 4266 * 4267 * "arg" must point to the first non-white of the expression. 4268 * "arg" is advanced to the next non-white after the recognized expression. 4269 * 4270 * Return OK or FAIL. 4271 */ 4272 static int 4273 eval6(arg, rettv, evaluate) 4274 char_u **arg; 4275 typval_T *rettv; 4276 int evaluate; 4277 { 4278 typval_T var2; 4279 int op; 4280 long n1, n2; 4281 int error = FALSE; 4282 4283 /* 4284 * Get the first variable. 4285 */ 4286 if (eval7(arg, rettv, evaluate) == FAIL) 4287 return FAIL; 4288 4289 /* 4290 * Repeat computing, until no '*', '/' or '%' is following. 4291 */ 4292 for (;;) 4293 { 4294 op = **arg; 4295 if (op != '*' && op != '/' && op != '%') 4296 break; 4297 4298 if (evaluate) 4299 { 4300 n1 = get_tv_number_chk(rettv, &error); 4301 clear_tv(rettv); 4302 if (error) 4303 return FAIL; 4304 } 4305 else 4306 n1 = 0; 4307 4308 /* 4309 * Get the second variable. 4310 */ 4311 *arg = skipwhite(*arg + 1); 4312 if (eval7(arg, &var2, evaluate) == FAIL) 4313 return FAIL; 4314 4315 if (evaluate) 4316 { 4317 n2 = get_tv_number_chk(&var2, &error); 4318 clear_tv(&var2); 4319 if (error) 4320 return FAIL; 4321 4322 /* 4323 * Compute the result. 4324 */ 4325 if (op == '*') 4326 n1 = n1 * n2; 4327 else if (op == '/') 4328 { 4329 if (n2 == 0) /* give an error message? */ 4330 n1 = 0x7fffffffL; 4331 else 4332 n1 = n1 / n2; 4333 } 4334 else 4335 { 4336 if (n2 == 0) /* give an error message? */ 4337 n1 = 0; 4338 else 4339 n1 = n1 % n2; 4340 } 4341 rettv->v_type = VAR_NUMBER; 4342 rettv->vval.v_number = n1; 4343 } 4344 } 4345 4346 return OK; 4347 } 4348 4349 /* 4350 * Handle sixth level expression: 4351 * number number constant 4352 * "string" string contstant 4353 * 'string' literal string contstant 4354 * &option-name option value 4355 * @r register contents 4356 * identifier variable value 4357 * function() function call 4358 * $VAR environment variable 4359 * (expression) nested expression 4360 * [expr, expr] List 4361 * {key: val, key: val} Dictionary 4362 * 4363 * Also handle: 4364 * ! in front logical NOT 4365 * - in front unary minus 4366 * + in front unary plus (ignored) 4367 * trailing [] subscript in String or List 4368 * trailing .name entry in Dictionary 4369 * 4370 * "arg" must point to the first non-white of the expression. 4371 * "arg" is advanced to the next non-white after the recognized expression. 4372 * 4373 * Return OK or FAIL. 4374 */ 4375 static int 4376 eval7(arg, rettv, evaluate) 4377 char_u **arg; 4378 typval_T *rettv; 4379 int evaluate; 4380 { 4381 long n; 4382 int len; 4383 char_u *s; 4384 int val; 4385 char_u *start_leader, *end_leader; 4386 int ret = OK; 4387 char_u *alias; 4388 4389 /* 4390 * Initialise variable so that clear_tv() can't mistake this for a 4391 * string and free a string that isn't there. 4392 */ 4393 rettv->v_type = VAR_UNKNOWN; 4394 4395 /* 4396 * Skip '!' and '-' characters. They are handled later. 4397 */ 4398 start_leader = *arg; 4399 while (**arg == '!' || **arg == '-' || **arg == '+') 4400 *arg = skipwhite(*arg + 1); 4401 end_leader = *arg; 4402 4403 switch (**arg) 4404 { 4405 /* 4406 * Number constant. 4407 */ 4408 case '0': 4409 case '1': 4410 case '2': 4411 case '3': 4412 case '4': 4413 case '5': 4414 case '6': 4415 case '7': 4416 case '8': 4417 case '9': 4418 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4419 *arg += len; 4420 if (evaluate) 4421 { 4422 rettv->v_type = VAR_NUMBER; 4423 rettv->vval.v_number = n; 4424 } 4425 break; 4426 4427 /* 4428 * String constant: "string". 4429 */ 4430 case '"': ret = get_string_tv(arg, rettv, evaluate); 4431 break; 4432 4433 /* 4434 * Literal string constant: 'str''ing'. 4435 */ 4436 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4437 break; 4438 4439 /* 4440 * List: [expr, expr] 4441 */ 4442 case '[': ret = get_list_tv(arg, rettv, evaluate); 4443 break; 4444 4445 /* 4446 * Dictionary: {key: val, key: val} 4447 */ 4448 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4449 break; 4450 4451 /* 4452 * Option value: &name 4453 */ 4454 case '&': ret = get_option_tv(arg, rettv, evaluate); 4455 break; 4456 4457 /* 4458 * Environment variable: $VAR. 4459 */ 4460 case '$': ret = get_env_tv(arg, rettv, evaluate); 4461 break; 4462 4463 /* 4464 * Register contents: @r. 4465 */ 4466 case '@': ++*arg; 4467 if (evaluate) 4468 { 4469 rettv->v_type = VAR_STRING; 4470 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4471 } 4472 if (**arg != NUL) 4473 ++*arg; 4474 break; 4475 4476 /* 4477 * nested expression: (expression). 4478 */ 4479 case '(': *arg = skipwhite(*arg + 1); 4480 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4481 if (**arg == ')') 4482 ++*arg; 4483 else if (ret == OK) 4484 { 4485 EMSG(_("E110: Missing ')'")); 4486 clear_tv(rettv); 4487 ret = FAIL; 4488 } 4489 break; 4490 4491 default: ret = NOTDONE; 4492 break; 4493 } 4494 4495 if (ret == NOTDONE) 4496 { 4497 /* 4498 * Must be a variable or function name. 4499 * Can also be a curly-braces kind of name: {expr}. 4500 */ 4501 s = *arg; 4502 len = get_name_len(arg, &alias, evaluate, TRUE); 4503 if (alias != NULL) 4504 s = alias; 4505 4506 if (len <= 0) 4507 ret = FAIL; 4508 else 4509 { 4510 if (**arg == '(') /* recursive! */ 4511 { 4512 /* If "s" is the name of a variable of type VAR_FUNC 4513 * use its contents. */ 4514 s = deref_func_name(s, &len); 4515 4516 /* Invoke the function. */ 4517 ret = get_func_tv(s, len, rettv, arg, 4518 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4519 &len, evaluate, NULL); 4520 /* Stop the expression evaluation when immediately 4521 * aborting on error, or when an interrupt occurred or 4522 * an exception was thrown but not caught. */ 4523 if (aborting()) 4524 { 4525 if (ret == OK) 4526 clear_tv(rettv); 4527 ret = FAIL; 4528 } 4529 } 4530 else if (evaluate) 4531 ret = get_var_tv(s, len, rettv, TRUE); 4532 else 4533 ret = OK; 4534 } 4535 4536 if (alias != NULL) 4537 vim_free(alias); 4538 } 4539 4540 *arg = skipwhite(*arg); 4541 4542 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4543 * expr(expr). */ 4544 if (ret == OK) 4545 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4546 4547 /* 4548 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4549 */ 4550 if (ret == OK && evaluate && end_leader > start_leader) 4551 { 4552 int error = FALSE; 4553 4554 val = get_tv_number_chk(rettv, &error); 4555 if (error) 4556 { 4557 clear_tv(rettv); 4558 ret = FAIL; 4559 } 4560 else 4561 { 4562 while (end_leader > start_leader) 4563 { 4564 --end_leader; 4565 if (*end_leader == '!') 4566 val = !val; 4567 else if (*end_leader == '-') 4568 val = -val; 4569 } 4570 clear_tv(rettv); 4571 rettv->v_type = VAR_NUMBER; 4572 rettv->vval.v_number = val; 4573 } 4574 } 4575 4576 return ret; 4577 } 4578 4579 /* 4580 * Evaluate an "[expr]" or "[expr:expr]" index. 4581 * "*arg" points to the '['. 4582 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4583 */ 4584 static int 4585 eval_index(arg, rettv, evaluate, verbose) 4586 char_u **arg; 4587 typval_T *rettv; 4588 int evaluate; 4589 int verbose; /* give error messages */ 4590 { 4591 int empty1 = FALSE, empty2 = FALSE; 4592 typval_T var1, var2; 4593 long n1, n2 = 0; 4594 long len = -1; 4595 int range = FALSE; 4596 char_u *s; 4597 char_u *key = NULL; 4598 4599 if (rettv->v_type == VAR_FUNC) 4600 { 4601 if (verbose) 4602 EMSG(_("E695: Cannot index a Funcref")); 4603 return FAIL; 4604 } 4605 4606 if (**arg == '.') 4607 { 4608 /* 4609 * dict.name 4610 */ 4611 key = *arg + 1; 4612 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4613 ; 4614 if (len == 0) 4615 return FAIL; 4616 *arg = skipwhite(key + len); 4617 } 4618 else 4619 { 4620 /* 4621 * something[idx] 4622 * 4623 * Get the (first) variable from inside the []. 4624 */ 4625 *arg = skipwhite(*arg + 1); 4626 if (**arg == ':') 4627 empty1 = TRUE; 4628 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4629 return FAIL; 4630 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4631 { 4632 /* not a number or string */ 4633 clear_tv(&var1); 4634 return FAIL; 4635 } 4636 4637 /* 4638 * Get the second variable from inside the [:]. 4639 */ 4640 if (**arg == ':') 4641 { 4642 range = TRUE; 4643 *arg = skipwhite(*arg + 1); 4644 if (**arg == ']') 4645 empty2 = TRUE; 4646 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4647 { 4648 if (!empty1) 4649 clear_tv(&var1); 4650 return FAIL; 4651 } 4652 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4653 { 4654 /* not a number or string */ 4655 if (!empty1) 4656 clear_tv(&var1); 4657 clear_tv(&var2); 4658 return FAIL; 4659 } 4660 } 4661 4662 /* Check for the ']'. */ 4663 if (**arg != ']') 4664 { 4665 if (verbose) 4666 EMSG(_(e_missbrac)); 4667 clear_tv(&var1); 4668 if (range) 4669 clear_tv(&var2); 4670 return FAIL; 4671 } 4672 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4673 } 4674 4675 if (evaluate) 4676 { 4677 n1 = 0; 4678 if (!empty1 && rettv->v_type != VAR_DICT) 4679 { 4680 n1 = get_tv_number(&var1); 4681 clear_tv(&var1); 4682 } 4683 if (range) 4684 { 4685 if (empty2) 4686 n2 = -1; 4687 else 4688 { 4689 n2 = get_tv_number(&var2); 4690 clear_tv(&var2); 4691 } 4692 } 4693 4694 switch (rettv->v_type) 4695 { 4696 case VAR_NUMBER: 4697 case VAR_STRING: 4698 s = get_tv_string(rettv); 4699 len = (long)STRLEN(s); 4700 if (range) 4701 { 4702 /* The resulting variable is a substring. If the indexes 4703 * are out of range the result is empty. */ 4704 if (n1 < 0) 4705 { 4706 n1 = len + n1; 4707 if (n1 < 0) 4708 n1 = 0; 4709 } 4710 if (n2 < 0) 4711 n2 = len + n2; 4712 else if (n2 >= len) 4713 n2 = len; 4714 if (n1 >= len || n2 < 0 || n1 > n2) 4715 s = NULL; 4716 else 4717 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4718 } 4719 else 4720 { 4721 /* The resulting variable is a string of a single 4722 * character. If the index is too big or negative the 4723 * result is empty. */ 4724 if (n1 >= len || n1 < 0) 4725 s = NULL; 4726 else 4727 s = vim_strnsave(s + n1, 1); 4728 } 4729 clear_tv(rettv); 4730 rettv->v_type = VAR_STRING; 4731 rettv->vval.v_string = s; 4732 break; 4733 4734 case VAR_LIST: 4735 len = list_len(rettv->vval.v_list); 4736 if (n1 < 0) 4737 n1 = len + n1; 4738 if (!empty1 && (n1 < 0 || n1 >= len)) 4739 { 4740 if (verbose) 4741 EMSGN(_(e_listidx), n1); 4742 return FAIL; 4743 } 4744 if (range) 4745 { 4746 list_T *l; 4747 listitem_T *item; 4748 4749 if (n2 < 0) 4750 n2 = len + n2; 4751 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4752 { 4753 if (verbose) 4754 EMSGN(_(e_listidx), n2); 4755 return FAIL; 4756 } 4757 l = list_alloc(); 4758 if (l == NULL) 4759 return FAIL; 4760 for (item = list_find(rettv->vval.v_list, n1); 4761 n1 <= n2; ++n1) 4762 { 4763 if (list_append_tv(l, &item->li_tv) == FAIL) 4764 { 4765 list_free(l); 4766 return FAIL; 4767 } 4768 item = item->li_next; 4769 } 4770 clear_tv(rettv); 4771 rettv->v_type = VAR_LIST; 4772 rettv->vval.v_list = l; 4773 ++l->lv_refcount; 4774 } 4775 else 4776 { 4777 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4778 &var1); 4779 clear_tv(rettv); 4780 *rettv = var1; 4781 } 4782 break; 4783 4784 case VAR_DICT: 4785 if (range) 4786 { 4787 if (verbose) 4788 EMSG(_(e_dictrange)); 4789 if (len == -1) 4790 clear_tv(&var1); 4791 return FAIL; 4792 } 4793 { 4794 dictitem_T *item; 4795 4796 if (len == -1) 4797 { 4798 key = get_tv_string(&var1); 4799 if (*key == NUL) 4800 { 4801 if (verbose) 4802 EMSG(_(e_emptykey)); 4803 clear_tv(&var1); 4804 return FAIL; 4805 } 4806 } 4807 4808 item = dict_find(rettv->vval.v_dict, key, (int)len); 4809 4810 if (item == NULL && verbose) 4811 EMSG2(_(e_dictkey), key); 4812 if (len == -1) 4813 clear_tv(&var1); 4814 if (item == NULL) 4815 return FAIL; 4816 4817 copy_tv(&item->di_tv, &var1); 4818 clear_tv(rettv); 4819 *rettv = var1; 4820 } 4821 break; 4822 } 4823 } 4824 4825 return OK; 4826 } 4827 4828 /* 4829 * Get an option value. 4830 * "arg" points to the '&' or '+' before the option name. 4831 * "arg" is advanced to character after the option name. 4832 * Return OK or FAIL. 4833 */ 4834 static int 4835 get_option_tv(arg, rettv, evaluate) 4836 char_u **arg; 4837 typval_T *rettv; /* when NULL, only check if option exists */ 4838 int evaluate; 4839 { 4840 char_u *option_end; 4841 long numval; 4842 char_u *stringval; 4843 int opt_type; 4844 int c; 4845 int working = (**arg == '+'); /* has("+option") */ 4846 int ret = OK; 4847 int opt_flags; 4848 4849 /* 4850 * Isolate the option name and find its value. 4851 */ 4852 option_end = find_option_end(arg, &opt_flags); 4853 if (option_end == NULL) 4854 { 4855 if (rettv != NULL) 4856 EMSG2(_("E112: Option name missing: %s"), *arg); 4857 return FAIL; 4858 } 4859 4860 if (!evaluate) 4861 { 4862 *arg = option_end; 4863 return OK; 4864 } 4865 4866 c = *option_end; 4867 *option_end = NUL; 4868 opt_type = get_option_value(*arg, &numval, 4869 rettv == NULL ? NULL : &stringval, opt_flags); 4870 4871 if (opt_type == -3) /* invalid name */ 4872 { 4873 if (rettv != NULL) 4874 EMSG2(_("E113: Unknown option: %s"), *arg); 4875 ret = FAIL; 4876 } 4877 else if (rettv != NULL) 4878 { 4879 if (opt_type == -2) /* hidden string option */ 4880 { 4881 rettv->v_type = VAR_STRING; 4882 rettv->vval.v_string = NULL; 4883 } 4884 else if (opt_type == -1) /* hidden number option */ 4885 { 4886 rettv->v_type = VAR_NUMBER; 4887 rettv->vval.v_number = 0; 4888 } 4889 else if (opt_type == 1) /* number option */ 4890 { 4891 rettv->v_type = VAR_NUMBER; 4892 rettv->vval.v_number = numval; 4893 } 4894 else /* string option */ 4895 { 4896 rettv->v_type = VAR_STRING; 4897 rettv->vval.v_string = stringval; 4898 } 4899 } 4900 else if (working && (opt_type == -2 || opt_type == -1)) 4901 ret = FAIL; 4902 4903 *option_end = c; /* put back for error messages */ 4904 *arg = option_end; 4905 4906 return ret; 4907 } 4908 4909 /* 4910 * Allocate a variable for a string constant. 4911 * Return OK or FAIL. 4912 */ 4913 static int 4914 get_string_tv(arg, rettv, evaluate) 4915 char_u **arg; 4916 typval_T *rettv; 4917 int evaluate; 4918 { 4919 char_u *p; 4920 char_u *name; 4921 int extra = 0; 4922 4923 /* 4924 * Find the end of the string, skipping backslashed characters. 4925 */ 4926 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4927 { 4928 if (*p == '\\' && p[1] != NUL) 4929 { 4930 ++p; 4931 /* A "\<x>" form occupies at least 4 characters, and produces up 4932 * to 6 characters: reserve space for 2 extra */ 4933 if (*p == '<') 4934 extra += 2; 4935 } 4936 } 4937 4938 if (*p != '"') 4939 { 4940 EMSG2(_("E114: Missing quote: %s"), *arg); 4941 return FAIL; 4942 } 4943 4944 /* If only parsing, set *arg and return here */ 4945 if (!evaluate) 4946 { 4947 *arg = p + 1; 4948 return OK; 4949 } 4950 4951 /* 4952 * Copy the string into allocated memory, handling backslashed 4953 * characters. 4954 */ 4955 name = alloc((unsigned)(p - *arg + extra)); 4956 if (name == NULL) 4957 return FAIL; 4958 rettv->v_type = VAR_STRING; 4959 rettv->vval.v_string = name; 4960 4961 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4962 { 4963 if (*p == '\\') 4964 { 4965 switch (*++p) 4966 { 4967 case 'b': *name++ = BS; ++p; break; 4968 case 'e': *name++ = ESC; ++p; break; 4969 case 'f': *name++ = FF; ++p; break; 4970 case 'n': *name++ = NL; ++p; break; 4971 case 'r': *name++ = CAR; ++p; break; 4972 case 't': *name++ = TAB; ++p; break; 4973 4974 case 'X': /* hex: "\x1", "\x12" */ 4975 case 'x': 4976 case 'u': /* Unicode: "\u0023" */ 4977 case 'U': 4978 if (vim_isxdigit(p[1])) 4979 { 4980 int n, nr; 4981 int c = toupper(*p); 4982 4983 if (c == 'X') 4984 n = 2; 4985 else 4986 n = 4; 4987 nr = 0; 4988 while (--n >= 0 && vim_isxdigit(p[1])) 4989 { 4990 ++p; 4991 nr = (nr << 4) + hex2nr(*p); 4992 } 4993 ++p; 4994 #ifdef FEAT_MBYTE 4995 /* For "\u" store the number according to 4996 * 'encoding'. */ 4997 if (c != 'X') 4998 name += (*mb_char2bytes)(nr, name); 4999 else 5000 #endif 5001 *name++ = nr; 5002 } 5003 break; 5004 5005 /* octal: "\1", "\12", "\123" */ 5006 case '0': 5007 case '1': 5008 case '2': 5009 case '3': 5010 case '4': 5011 case '5': 5012 case '6': 5013 case '7': *name = *p++ - '0'; 5014 if (*p >= '0' && *p <= '7') 5015 { 5016 *name = (*name << 3) + *p++ - '0'; 5017 if (*p >= '0' && *p <= '7') 5018 *name = (*name << 3) + *p++ - '0'; 5019 } 5020 ++name; 5021 break; 5022 5023 /* Special key, e.g.: "\<C-W>" */ 5024 case '<': extra = trans_special(&p, name, TRUE); 5025 if (extra != 0) 5026 { 5027 name += extra; 5028 break; 5029 } 5030 /* FALLTHROUGH */ 5031 5032 default: MB_COPY_CHAR(p, name); 5033 break; 5034 } 5035 } 5036 else 5037 MB_COPY_CHAR(p, name); 5038 5039 } 5040 *name = NUL; 5041 *arg = p + 1; 5042 5043 return OK; 5044 } 5045 5046 /* 5047 * Allocate a variable for a 'str''ing' constant. 5048 * Return OK or FAIL. 5049 */ 5050 static int 5051 get_lit_string_tv(arg, rettv, evaluate) 5052 char_u **arg; 5053 typval_T *rettv; 5054 int evaluate; 5055 { 5056 char_u *p; 5057 char_u *str; 5058 int reduce = 0; 5059 5060 /* 5061 * Find the end of the string, skipping ''. 5062 */ 5063 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5064 { 5065 if (*p == '\'') 5066 { 5067 if (p[1] != '\'') 5068 break; 5069 ++reduce; 5070 ++p; 5071 } 5072 } 5073 5074 if (*p != '\'') 5075 { 5076 EMSG2(_("E115: Missing quote: %s"), *arg); 5077 return FAIL; 5078 } 5079 5080 /* If only parsing return after setting "*arg" */ 5081 if (!evaluate) 5082 { 5083 *arg = p + 1; 5084 return OK; 5085 } 5086 5087 /* 5088 * Copy the string into allocated memory, handling '' to ' reduction. 5089 */ 5090 str = alloc((unsigned)((p - *arg) - reduce)); 5091 if (str == NULL) 5092 return FAIL; 5093 rettv->v_type = VAR_STRING; 5094 rettv->vval.v_string = str; 5095 5096 for (p = *arg + 1; *p != NUL; ) 5097 { 5098 if (*p == '\'') 5099 { 5100 if (p[1] != '\'') 5101 break; 5102 ++p; 5103 } 5104 MB_COPY_CHAR(p, str); 5105 } 5106 *str = NUL; 5107 *arg = p + 1; 5108 5109 return OK; 5110 } 5111 5112 /* 5113 * Allocate a variable for a List and fill it from "*arg". 5114 * Return OK or FAIL. 5115 */ 5116 static int 5117 get_list_tv(arg, rettv, evaluate) 5118 char_u **arg; 5119 typval_T *rettv; 5120 int evaluate; 5121 { 5122 list_T *l = NULL; 5123 typval_T tv; 5124 listitem_T *item; 5125 5126 if (evaluate) 5127 { 5128 l = list_alloc(); 5129 if (l == NULL) 5130 return FAIL; 5131 } 5132 5133 *arg = skipwhite(*arg + 1); 5134 while (**arg != ']' && **arg != NUL) 5135 { 5136 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5137 goto failret; 5138 if (evaluate) 5139 { 5140 item = listitem_alloc(); 5141 if (item != NULL) 5142 { 5143 item->li_tv = tv; 5144 item->li_tv.v_lock = 0; 5145 list_append(l, item); 5146 } 5147 else 5148 clear_tv(&tv); 5149 } 5150 5151 if (**arg == ']') 5152 break; 5153 if (**arg != ',') 5154 { 5155 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5156 goto failret; 5157 } 5158 *arg = skipwhite(*arg + 1); 5159 } 5160 5161 if (**arg != ']') 5162 { 5163 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5164 failret: 5165 if (evaluate) 5166 list_free(l); 5167 return FAIL; 5168 } 5169 5170 *arg = skipwhite(*arg + 1); 5171 if (evaluate) 5172 { 5173 rettv->v_type = VAR_LIST; 5174 rettv->vval.v_list = l; 5175 ++l->lv_refcount; 5176 } 5177 5178 return OK; 5179 } 5180 5181 /* 5182 * Allocate an empty header for a list. 5183 * Caller should take care of the reference count. 5184 */ 5185 static list_T * 5186 list_alloc() 5187 { 5188 list_T *l; 5189 5190 l = (list_T *)alloc_clear(sizeof(list_T)); 5191 if (l != NULL) 5192 { 5193 /* Prepend the list to the list of lists for garbage collection. */ 5194 if (first_list != NULL) 5195 first_list->lv_used_prev = l; 5196 l->lv_used_prev = NULL; 5197 l->lv_used_next = first_list; 5198 first_list = l; 5199 } 5200 return l; 5201 } 5202 5203 /* 5204 * Unreference a list: decrement the reference count and free it when it 5205 * becomes zero. 5206 */ 5207 void 5208 list_unref(l) 5209 list_T *l; 5210 { 5211 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5212 list_free(l); 5213 } 5214 5215 /* 5216 * Free a list, including all items it points to. 5217 * Ignores the reference count. 5218 */ 5219 static void 5220 list_free(l) 5221 list_T *l; 5222 { 5223 listitem_T *item; 5224 5225 /* Avoid that recursive reference to the list frees us again. */ 5226 l->lv_refcount = DEL_REFCOUNT; 5227 5228 /* Remove the list from the list of lists for garbage collection. */ 5229 if (l->lv_used_prev == NULL) 5230 first_list = l->lv_used_next; 5231 else 5232 l->lv_used_prev->lv_used_next = l->lv_used_next; 5233 if (l->lv_used_next != NULL) 5234 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5235 5236 for (item = l->lv_first; item != NULL; item = l->lv_first) 5237 { 5238 /* Remove the item before deleting it. */ 5239 l->lv_first = item->li_next; 5240 listitem_free(item); 5241 } 5242 vim_free(l); 5243 } 5244 5245 /* 5246 * Allocate a list item. 5247 */ 5248 static listitem_T * 5249 listitem_alloc() 5250 { 5251 return (listitem_T *)alloc(sizeof(listitem_T)); 5252 } 5253 5254 /* 5255 * Free a list item. Also clears the value. Does not notify watchers. 5256 */ 5257 static void 5258 listitem_free(item) 5259 listitem_T *item; 5260 { 5261 clear_tv(&item->li_tv); 5262 vim_free(item); 5263 } 5264 5265 /* 5266 * Remove a list item from a List and free it. Also clears the value. 5267 */ 5268 static void 5269 listitem_remove(l, item) 5270 list_T *l; 5271 listitem_T *item; 5272 { 5273 list_remove(l, item, item); 5274 listitem_free(item); 5275 } 5276 5277 /* 5278 * Get the number of items in a list. 5279 */ 5280 static long 5281 list_len(l) 5282 list_T *l; 5283 { 5284 if (l == NULL) 5285 return 0L; 5286 return l->lv_len; 5287 } 5288 5289 /* 5290 * Return TRUE when two lists have exactly the same values. 5291 */ 5292 static int 5293 list_equal(l1, l2, ic) 5294 list_T *l1; 5295 list_T *l2; 5296 int ic; /* ignore case for strings */ 5297 { 5298 listitem_T *item1, *item2; 5299 5300 if (list_len(l1) != list_len(l2)) 5301 return FALSE; 5302 5303 for (item1 = l1->lv_first, item2 = l2->lv_first; 5304 item1 != NULL && item2 != NULL; 5305 item1 = item1->li_next, item2 = item2->li_next) 5306 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5307 return FALSE; 5308 return item1 == NULL && item2 == NULL; 5309 } 5310 5311 /* 5312 * Return TRUE when two dictionaries have exactly the same key/values. 5313 */ 5314 static int 5315 dict_equal(d1, d2, ic) 5316 dict_T *d1; 5317 dict_T *d2; 5318 int ic; /* ignore case for strings */ 5319 { 5320 hashitem_T *hi; 5321 dictitem_T *item2; 5322 int todo; 5323 5324 if (dict_len(d1) != dict_len(d2)) 5325 return FALSE; 5326 5327 todo = d1->dv_hashtab.ht_used; 5328 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5329 { 5330 if (!HASHITEM_EMPTY(hi)) 5331 { 5332 item2 = dict_find(d2, hi->hi_key, -1); 5333 if (item2 == NULL) 5334 return FALSE; 5335 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5336 return FALSE; 5337 --todo; 5338 } 5339 } 5340 return TRUE; 5341 } 5342 5343 /* 5344 * Return TRUE if "tv1" and "tv2" have the same value. 5345 * Compares the items just like "==" would compare them, but strings and 5346 * numbers are different. 5347 */ 5348 static int 5349 tv_equal(tv1, tv2, ic) 5350 typval_T *tv1; 5351 typval_T *tv2; 5352 int ic; /* ignore case */ 5353 { 5354 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5355 char_u *s1, *s2; 5356 5357 if (tv1->v_type != tv2->v_type) 5358 return FALSE; 5359 5360 switch (tv1->v_type) 5361 { 5362 case VAR_LIST: 5363 /* recursive! */ 5364 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5365 5366 case VAR_DICT: 5367 /* recursive! */ 5368 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5369 5370 case VAR_FUNC: 5371 return (tv1->vval.v_string != NULL 5372 && tv2->vval.v_string != NULL 5373 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5374 5375 case VAR_NUMBER: 5376 return tv1->vval.v_number == tv2->vval.v_number; 5377 5378 case VAR_STRING: 5379 s1 = get_tv_string_buf(tv1, buf1); 5380 s2 = get_tv_string_buf(tv2, buf2); 5381 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5382 } 5383 5384 EMSG2(_(e_intern2), "tv_equal()"); 5385 return TRUE; 5386 } 5387 5388 /* 5389 * Locate item with index "n" in list "l" and return it. 5390 * A negative index is counted from the end; -1 is the last item. 5391 * Returns NULL when "n" is out of range. 5392 */ 5393 static listitem_T * 5394 list_find(l, n) 5395 list_T *l; 5396 long n; 5397 { 5398 listitem_T *item; 5399 long idx; 5400 5401 if (l == NULL) 5402 return NULL; 5403 5404 /* Negative index is relative to the end. */ 5405 if (n < 0) 5406 n = l->lv_len + n; 5407 5408 /* Check for index out of range. */ 5409 if (n < 0 || n >= l->lv_len) 5410 return NULL; 5411 5412 /* When there is a cached index may start search from there. */ 5413 if (l->lv_idx_item != NULL) 5414 { 5415 if (n < l->lv_idx / 2) 5416 { 5417 /* closest to the start of the list */ 5418 item = l->lv_first; 5419 idx = 0; 5420 } 5421 else if (n > (l->lv_idx + l->lv_len) / 2) 5422 { 5423 /* closest to the end of the list */ 5424 item = l->lv_last; 5425 idx = l->lv_len - 1; 5426 } 5427 else 5428 { 5429 /* closest to the cached index */ 5430 item = l->lv_idx_item; 5431 idx = l->lv_idx; 5432 } 5433 } 5434 else 5435 { 5436 if (n < l->lv_len / 2) 5437 { 5438 /* closest to the start of the list */ 5439 item = l->lv_first; 5440 idx = 0; 5441 } 5442 else 5443 { 5444 /* closest to the end of the list */ 5445 item = l->lv_last; 5446 idx = l->lv_len - 1; 5447 } 5448 } 5449 5450 while (n > idx) 5451 { 5452 /* search forward */ 5453 item = item->li_next; 5454 ++idx; 5455 } 5456 while (n < idx) 5457 { 5458 /* search backward */ 5459 item = item->li_prev; 5460 --idx; 5461 } 5462 5463 /* cache the used index */ 5464 l->lv_idx = idx; 5465 l->lv_idx_item = item; 5466 5467 return item; 5468 } 5469 5470 /* 5471 * Locate "item" list "l" and return its index. 5472 * Returns -1 when "item" is not in the list. 5473 */ 5474 static long 5475 list_idx_of_item(l, item) 5476 list_T *l; 5477 listitem_T *item; 5478 { 5479 long idx = 0; 5480 listitem_T *li; 5481 5482 if (l == NULL) 5483 return -1; 5484 idx = 0; 5485 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5486 ++idx; 5487 if (li == NULL) 5488 return -1; 5489 return idx; 5490 } 5491 5492 /* 5493 * Append item "item" to the end of list "l". 5494 */ 5495 static void 5496 list_append(l, item) 5497 list_T *l; 5498 listitem_T *item; 5499 { 5500 if (l->lv_last == NULL) 5501 { 5502 /* empty list */ 5503 l->lv_first = item; 5504 l->lv_last = item; 5505 item->li_prev = NULL; 5506 } 5507 else 5508 { 5509 l->lv_last->li_next = item; 5510 item->li_prev = l->lv_last; 5511 l->lv_last = item; 5512 } 5513 ++l->lv_len; 5514 item->li_next = NULL; 5515 } 5516 5517 /* 5518 * Append typval_T "tv" to the end of list "l". 5519 * Return FAIL when out of memory. 5520 */ 5521 static int 5522 list_append_tv(l, tv) 5523 list_T *l; 5524 typval_T *tv; 5525 { 5526 listitem_T *li = listitem_alloc(); 5527 5528 if (li == NULL) 5529 return FAIL; 5530 copy_tv(tv, &li->li_tv); 5531 list_append(l, li); 5532 return OK; 5533 } 5534 5535 /* 5536 * Add a dictionary to a list. Used by getqflist(). 5537 * Return FAIL when out of memory. 5538 */ 5539 int 5540 list_append_dict(list, dict) 5541 list_T *list; 5542 dict_T *dict; 5543 { 5544 listitem_T *li = listitem_alloc(); 5545 5546 if (li == NULL) 5547 return FAIL; 5548 li->li_tv.v_type = VAR_DICT; 5549 li->li_tv.v_lock = 0; 5550 li->li_tv.vval.v_dict = dict; 5551 list_append(list, li); 5552 ++dict->dv_refcount; 5553 return OK; 5554 } 5555 5556 /* 5557 * Make a copy of "str" and append it as an item to list "l". 5558 * When "len" >= 0 use "str[len]". 5559 * Returns FAIL when out of memory. 5560 */ 5561 static int 5562 list_append_string(l, str, len) 5563 list_T *l; 5564 char_u *str; 5565 int len; 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 = (len >= 0 ? vim_strnsave(str, len) 5575 : vim_strsave(str))) == NULL) 5576 return FAIL; 5577 return OK; 5578 } 5579 5580 /* 5581 * Append "n" to list "l". 5582 * Returns FAIL when out of memory. 5583 */ 5584 static int 5585 list_append_number(l, n) 5586 list_T *l; 5587 varnumber_T n; 5588 { 5589 listitem_T *li; 5590 5591 li = listitem_alloc(); 5592 if (li == NULL) 5593 return FAIL; 5594 li->li_tv.v_type = VAR_NUMBER; 5595 li->li_tv.v_lock = 0; 5596 li->li_tv.vval.v_number = n; 5597 list_append(l, li); 5598 return OK; 5599 } 5600 5601 /* 5602 * Insert typval_T "tv" in list "l" before "item". 5603 * If "item" is NULL append at the end. 5604 * Return FAIL when out of memory. 5605 */ 5606 static int 5607 list_insert_tv(l, tv, item) 5608 list_T *l; 5609 typval_T *tv; 5610 listitem_T *item; 5611 { 5612 listitem_T *ni = listitem_alloc(); 5613 5614 if (ni == NULL) 5615 return FAIL; 5616 copy_tv(tv, &ni->li_tv); 5617 if (item == NULL) 5618 /* Append new item at end of list. */ 5619 list_append(l, ni); 5620 else 5621 { 5622 /* Insert new item before existing item. */ 5623 ni->li_prev = item->li_prev; 5624 ni->li_next = item; 5625 if (item->li_prev == NULL) 5626 { 5627 l->lv_first = ni; 5628 ++l->lv_idx; 5629 } 5630 else 5631 { 5632 item->li_prev->li_next = ni; 5633 l->lv_idx_item = NULL; 5634 } 5635 item->li_prev = ni; 5636 ++l->lv_len; 5637 } 5638 return OK; 5639 } 5640 5641 /* 5642 * Extend "l1" with "l2". 5643 * If "bef" is NULL append at the end, otherwise insert before this item. 5644 * Returns FAIL when out of memory. 5645 */ 5646 static int 5647 list_extend(l1, l2, bef) 5648 list_T *l1; 5649 list_T *l2; 5650 listitem_T *bef; 5651 { 5652 listitem_T *item; 5653 5654 for (item = l2->lv_first; item != NULL; item = item->li_next) 5655 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5656 return FAIL; 5657 return OK; 5658 } 5659 5660 /* 5661 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5662 * Return FAIL when out of memory. 5663 */ 5664 static int 5665 list_concat(l1, l2, tv) 5666 list_T *l1; 5667 list_T *l2; 5668 typval_T *tv; 5669 { 5670 list_T *l; 5671 5672 /* make a copy of the first list. */ 5673 l = list_copy(l1, FALSE, 0); 5674 if (l == NULL) 5675 return FAIL; 5676 tv->v_type = VAR_LIST; 5677 tv->vval.v_list = l; 5678 5679 /* append all items from the second list */ 5680 return list_extend(l, l2, NULL); 5681 } 5682 5683 /* 5684 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5685 * The refcount of the new list is set to 1. 5686 * See item_copy() for "copyID". 5687 * Returns NULL when out of memory. 5688 */ 5689 static list_T * 5690 list_copy(orig, deep, copyID) 5691 list_T *orig; 5692 int deep; 5693 int copyID; 5694 { 5695 list_T *copy; 5696 listitem_T *item; 5697 listitem_T *ni; 5698 5699 if (orig == NULL) 5700 return NULL; 5701 5702 copy = list_alloc(); 5703 if (copy != NULL) 5704 { 5705 if (copyID != 0) 5706 { 5707 /* Do this before adding the items, because one of the items may 5708 * refer back to this list. */ 5709 orig->lv_copyID = copyID; 5710 orig->lv_copylist = copy; 5711 } 5712 for (item = orig->lv_first; item != NULL && !got_int; 5713 item = item->li_next) 5714 { 5715 ni = listitem_alloc(); 5716 if (ni == NULL) 5717 break; 5718 if (deep) 5719 { 5720 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5721 { 5722 vim_free(ni); 5723 break; 5724 } 5725 } 5726 else 5727 copy_tv(&item->li_tv, &ni->li_tv); 5728 list_append(copy, ni); 5729 } 5730 ++copy->lv_refcount; 5731 if (item != NULL) 5732 { 5733 list_unref(copy); 5734 copy = NULL; 5735 } 5736 } 5737 5738 return copy; 5739 } 5740 5741 /* 5742 * Remove items "item" to "item2" from list "l". 5743 * Does not free the listitem or the value! 5744 */ 5745 static void 5746 list_remove(l, item, item2) 5747 list_T *l; 5748 listitem_T *item; 5749 listitem_T *item2; 5750 { 5751 listitem_T *ip; 5752 5753 /* notify watchers */ 5754 for (ip = item; ip != NULL; ip = ip->li_next) 5755 { 5756 --l->lv_len; 5757 list_fix_watch(l, ip); 5758 if (ip == item2) 5759 break; 5760 } 5761 5762 if (item2->li_next == NULL) 5763 l->lv_last = item->li_prev; 5764 else 5765 item2->li_next->li_prev = item->li_prev; 5766 if (item->li_prev == NULL) 5767 l->lv_first = item2->li_next; 5768 else 5769 item->li_prev->li_next = item2->li_next; 5770 l->lv_idx_item = NULL; 5771 } 5772 5773 /* 5774 * Return an allocated string with the string representation of a list. 5775 * May return NULL. 5776 */ 5777 static char_u * 5778 list2string(tv) 5779 typval_T *tv; 5780 { 5781 garray_T ga; 5782 5783 if (tv->vval.v_list == NULL) 5784 return NULL; 5785 ga_init2(&ga, (int)sizeof(char), 80); 5786 ga_append(&ga, '['); 5787 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5788 { 5789 vim_free(ga.ga_data); 5790 return NULL; 5791 } 5792 ga_append(&ga, ']'); 5793 ga_append(&ga, NUL); 5794 return (char_u *)ga.ga_data; 5795 } 5796 5797 /* 5798 * Join list "l" into a string in "*gap", using separator "sep". 5799 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5800 * Return FAIL or OK. 5801 */ 5802 static int 5803 list_join(gap, l, sep, echo) 5804 garray_T *gap; 5805 list_T *l; 5806 char_u *sep; 5807 int echo; 5808 { 5809 int first = TRUE; 5810 char_u *tofree; 5811 char_u numbuf[NUMBUFLEN]; 5812 listitem_T *item; 5813 char_u *s; 5814 5815 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5816 { 5817 if (first) 5818 first = FALSE; 5819 else 5820 ga_concat(gap, sep); 5821 5822 if (echo) 5823 s = echo_string(&item->li_tv, &tofree, numbuf); 5824 else 5825 s = tv2string(&item->li_tv, &tofree, numbuf); 5826 if (s != NULL) 5827 ga_concat(gap, s); 5828 vim_free(tofree); 5829 if (s == NULL) 5830 return FAIL; 5831 } 5832 return OK; 5833 } 5834 5835 /* 5836 * Garbage collection for lists and dictionaries. 5837 * 5838 * We use reference counts to be able to free most items right away when they 5839 * are no longer used. But for composite items it's possible that it becomes 5840 * unused while the reference count is > 0: When there is a recursive 5841 * reference. Example: 5842 * :let l = [1, 2, 3] 5843 * :let d = {9: l} 5844 * :let l[1] = d 5845 * 5846 * Since this is quite unusual we handle this with garbage collection: every 5847 * once in a while find out which lists and dicts are not referenced from any 5848 * variable. 5849 * 5850 * Here is a good reference text about garbage collection (refers to Python 5851 * but it applies to all reference-counting mechanisms): 5852 * http://python.ca/nas/python/gc/ 5853 */ 5854 5855 /* 5856 * Do garbage collection for lists and dicts. 5857 * Return TRUE if some memory was freed. 5858 */ 5859 int 5860 garbage_collect() 5861 { 5862 dict_T *dd; 5863 list_T *ll; 5864 int copyID = ++current_copyID; 5865 buf_T *buf; 5866 win_T *wp; 5867 int i; 5868 funccall_T *fc; 5869 int did_free = FALSE; 5870 5871 /* 5872 * 1. Go through all accessible variables and mark all lists and dicts 5873 * with copyID. 5874 */ 5875 /* script-local variables */ 5876 for (i = 1; i <= ga_scripts.ga_len; ++i) 5877 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5878 5879 /* buffer-local variables */ 5880 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5881 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5882 5883 /* window-local variables */ 5884 FOR_ALL_WINDOWS(wp) 5885 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5886 5887 /* global variables */ 5888 set_ref_in_ht(&globvarht, copyID); 5889 5890 /* function-local variables */ 5891 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5892 { 5893 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5894 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5895 } 5896 5897 /* 5898 * 2. Go through the list of dicts and free items without the copyID. 5899 */ 5900 for (dd = first_dict; dd != NULL; ) 5901 if (dd->dv_copyID != copyID) 5902 { 5903 dict_free(dd); 5904 did_free = TRUE; 5905 5906 /* restart, next dict may also have been freed */ 5907 dd = first_dict; 5908 } 5909 else 5910 dd = dd->dv_used_next; 5911 5912 /* 5913 * 3. Go through the list of lists and free items without the copyID. 5914 * But don't free a list that has a watcher (used in a for loop), these 5915 * are not referenced anywhere. 5916 */ 5917 for (ll = first_list; ll != NULL; ) 5918 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 5919 { 5920 list_free(ll); 5921 did_free = TRUE; 5922 5923 /* restart, next list may also have been freed */ 5924 ll = first_list; 5925 } 5926 else 5927 ll = ll->lv_used_next; 5928 5929 return did_free; 5930 } 5931 5932 /* 5933 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5934 */ 5935 static void 5936 set_ref_in_ht(ht, copyID) 5937 hashtab_T *ht; 5938 int copyID; 5939 { 5940 int todo; 5941 hashitem_T *hi; 5942 5943 todo = ht->ht_used; 5944 for (hi = ht->ht_array; todo > 0; ++hi) 5945 if (!HASHITEM_EMPTY(hi)) 5946 { 5947 --todo; 5948 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5949 } 5950 } 5951 5952 /* 5953 * Mark all lists and dicts referenced through list "l" with "copyID". 5954 */ 5955 static void 5956 set_ref_in_list(l, copyID) 5957 list_T *l; 5958 int copyID; 5959 { 5960 listitem_T *li; 5961 5962 for (li = l->lv_first; li != NULL; li = li->li_next) 5963 set_ref_in_item(&li->li_tv, copyID); 5964 } 5965 5966 /* 5967 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5968 */ 5969 static void 5970 set_ref_in_item(tv, copyID) 5971 typval_T *tv; 5972 int copyID; 5973 { 5974 dict_T *dd; 5975 list_T *ll; 5976 5977 switch (tv->v_type) 5978 { 5979 case VAR_DICT: 5980 dd = tv->vval.v_dict; 5981 if (dd->dv_copyID != copyID) 5982 { 5983 /* Didn't see this dict yet. */ 5984 dd->dv_copyID = copyID; 5985 set_ref_in_ht(&dd->dv_hashtab, copyID); 5986 } 5987 break; 5988 5989 case VAR_LIST: 5990 ll = tv->vval.v_list; 5991 if (ll->lv_copyID != copyID) 5992 { 5993 /* Didn't see this list yet. */ 5994 ll->lv_copyID = copyID; 5995 set_ref_in_list(ll, copyID); 5996 } 5997 break; 5998 } 5999 return; 6000 } 6001 6002 /* 6003 * Allocate an empty header for a dictionary. 6004 */ 6005 dict_T * 6006 dict_alloc() 6007 { 6008 dict_T *d; 6009 6010 d = (dict_T *)alloc(sizeof(dict_T)); 6011 if (d != NULL) 6012 { 6013 /* Add the list to the hashtable for garbage collection. */ 6014 if (first_dict != NULL) 6015 first_dict->dv_used_prev = d; 6016 d->dv_used_next = first_dict; 6017 d->dv_used_prev = NULL; 6018 6019 hash_init(&d->dv_hashtab); 6020 d->dv_lock = 0; 6021 d->dv_refcount = 0; 6022 d->dv_copyID = 0; 6023 } 6024 return d; 6025 } 6026 6027 /* 6028 * Unreference a Dictionary: decrement the reference count and free it when it 6029 * becomes zero. 6030 */ 6031 static void 6032 dict_unref(d) 6033 dict_T *d; 6034 { 6035 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6036 dict_free(d); 6037 } 6038 6039 /* 6040 * Free a Dictionary, including all items it contains. 6041 * Ignores the reference count. 6042 */ 6043 static void 6044 dict_free(d) 6045 dict_T *d; 6046 { 6047 int todo; 6048 hashitem_T *hi; 6049 dictitem_T *di; 6050 6051 /* Avoid that recursive reference to the dict frees us again. */ 6052 d->dv_refcount = DEL_REFCOUNT; 6053 6054 /* Remove the dict from the list of dicts for garbage collection. */ 6055 if (d->dv_used_prev == NULL) 6056 first_dict = d->dv_used_next; 6057 else 6058 d->dv_used_prev->dv_used_next = d->dv_used_next; 6059 if (d->dv_used_next != NULL) 6060 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6061 6062 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6063 hash_lock(&d->dv_hashtab); 6064 todo = d->dv_hashtab.ht_used; 6065 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6066 { 6067 if (!HASHITEM_EMPTY(hi)) 6068 { 6069 /* Remove the item before deleting it, just in case there is 6070 * something recursive causing trouble. */ 6071 di = HI2DI(hi); 6072 hash_remove(&d->dv_hashtab, hi); 6073 dictitem_free(di); 6074 --todo; 6075 } 6076 } 6077 hash_clear(&d->dv_hashtab); 6078 vim_free(d); 6079 } 6080 6081 /* 6082 * Allocate a Dictionary item. 6083 * The "key" is copied to the new item. 6084 * Note that the value of the item "di_tv" still needs to be initialized! 6085 * Returns NULL when out of memory. 6086 */ 6087 static dictitem_T * 6088 dictitem_alloc(key) 6089 char_u *key; 6090 { 6091 dictitem_T *di; 6092 6093 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6094 if (di != NULL) 6095 { 6096 STRCPY(di->di_key, key); 6097 di->di_flags = 0; 6098 } 6099 return di; 6100 } 6101 6102 /* 6103 * Make a copy of a Dictionary item. 6104 */ 6105 static dictitem_T * 6106 dictitem_copy(org) 6107 dictitem_T *org; 6108 { 6109 dictitem_T *di; 6110 6111 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6112 if (di != NULL) 6113 { 6114 STRCPY(di->di_key, org->di_key); 6115 di->di_flags = 0; 6116 copy_tv(&org->di_tv, &di->di_tv); 6117 } 6118 return di; 6119 } 6120 6121 /* 6122 * Remove item "item" from Dictionary "dict" and free it. 6123 */ 6124 static void 6125 dictitem_remove(dict, item) 6126 dict_T *dict; 6127 dictitem_T *item; 6128 { 6129 hashitem_T *hi; 6130 6131 hi = hash_find(&dict->dv_hashtab, item->di_key); 6132 if (HASHITEM_EMPTY(hi)) 6133 EMSG2(_(e_intern2), "dictitem_remove()"); 6134 else 6135 hash_remove(&dict->dv_hashtab, hi); 6136 dictitem_free(item); 6137 } 6138 6139 /* 6140 * Free a dict item. Also clears the value. 6141 */ 6142 static void 6143 dictitem_free(item) 6144 dictitem_T *item; 6145 { 6146 clear_tv(&item->di_tv); 6147 vim_free(item); 6148 } 6149 6150 /* 6151 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6152 * The refcount of the new dict is set to 1. 6153 * See item_copy() for "copyID". 6154 * Returns NULL when out of memory. 6155 */ 6156 static dict_T * 6157 dict_copy(orig, deep, copyID) 6158 dict_T *orig; 6159 int deep; 6160 int copyID; 6161 { 6162 dict_T *copy; 6163 dictitem_T *di; 6164 int todo; 6165 hashitem_T *hi; 6166 6167 if (orig == NULL) 6168 return NULL; 6169 6170 copy = dict_alloc(); 6171 if (copy != NULL) 6172 { 6173 if (copyID != 0) 6174 { 6175 orig->dv_copyID = copyID; 6176 orig->dv_copydict = copy; 6177 } 6178 todo = orig->dv_hashtab.ht_used; 6179 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6180 { 6181 if (!HASHITEM_EMPTY(hi)) 6182 { 6183 --todo; 6184 6185 di = dictitem_alloc(hi->hi_key); 6186 if (di == NULL) 6187 break; 6188 if (deep) 6189 { 6190 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6191 copyID) == FAIL) 6192 { 6193 vim_free(di); 6194 break; 6195 } 6196 } 6197 else 6198 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6199 if (dict_add(copy, di) == FAIL) 6200 { 6201 dictitem_free(di); 6202 break; 6203 } 6204 } 6205 } 6206 6207 ++copy->dv_refcount; 6208 if (todo > 0) 6209 { 6210 dict_unref(copy); 6211 copy = NULL; 6212 } 6213 } 6214 6215 return copy; 6216 } 6217 6218 /* 6219 * Add item "item" to Dictionary "d". 6220 * Returns FAIL when out of memory and when key already existed. 6221 */ 6222 static int 6223 dict_add(d, item) 6224 dict_T *d; 6225 dictitem_T *item; 6226 { 6227 return hash_add(&d->dv_hashtab, item->di_key); 6228 } 6229 6230 /* 6231 * Add a number or string entry to dictionary "d". 6232 * When "str" is NULL use number "nr", otherwise use "str". 6233 * Returns FAIL when out of memory and when key already exists. 6234 */ 6235 int 6236 dict_add_nr_str(d, key, nr, str) 6237 dict_T *d; 6238 char *key; 6239 long nr; 6240 char_u *str; 6241 { 6242 dictitem_T *item; 6243 6244 item = dictitem_alloc((char_u *)key); 6245 if (item == NULL) 6246 return FAIL; 6247 item->di_tv.v_lock = 0; 6248 if (str == NULL) 6249 { 6250 item->di_tv.v_type = VAR_NUMBER; 6251 item->di_tv.vval.v_number = nr; 6252 } 6253 else 6254 { 6255 item->di_tv.v_type = VAR_STRING; 6256 item->di_tv.vval.v_string = vim_strsave(str); 6257 } 6258 if (dict_add(d, item) == FAIL) 6259 { 6260 dictitem_free(item); 6261 return FAIL; 6262 } 6263 return OK; 6264 } 6265 6266 /* 6267 * Get the number of items in a Dictionary. 6268 */ 6269 static long 6270 dict_len(d) 6271 dict_T *d; 6272 { 6273 if (d == NULL) 6274 return 0L; 6275 return d->dv_hashtab.ht_used; 6276 } 6277 6278 /* 6279 * Find item "key[len]" in Dictionary "d". 6280 * If "len" is negative use strlen(key). 6281 * Returns NULL when not found. 6282 */ 6283 static dictitem_T * 6284 dict_find(d, key, len) 6285 dict_T *d; 6286 char_u *key; 6287 int len; 6288 { 6289 #define AKEYLEN 200 6290 char_u buf[AKEYLEN]; 6291 char_u *akey; 6292 char_u *tofree = NULL; 6293 hashitem_T *hi; 6294 6295 if (len < 0) 6296 akey = key; 6297 else if (len >= AKEYLEN) 6298 { 6299 tofree = akey = vim_strnsave(key, len); 6300 if (akey == NULL) 6301 return NULL; 6302 } 6303 else 6304 { 6305 /* Avoid a malloc/free by using buf[]. */ 6306 vim_strncpy(buf, key, len); 6307 akey = buf; 6308 } 6309 6310 hi = hash_find(&d->dv_hashtab, akey); 6311 vim_free(tofree); 6312 if (HASHITEM_EMPTY(hi)) 6313 return NULL; 6314 return HI2DI(hi); 6315 } 6316 6317 /* 6318 * Get a string item from a dictionary in allocated memory. 6319 * Returns NULL if the entry doesn't exist or out of memory. 6320 */ 6321 char_u * 6322 get_dict_string(d, key) 6323 dict_T *d; 6324 char_u *key; 6325 { 6326 dictitem_T *di; 6327 6328 di = dict_find(d, key, -1); 6329 if (di == NULL) 6330 return NULL; 6331 return vim_strsave(get_tv_string(&di->di_tv)); 6332 } 6333 6334 /* 6335 * Get a number item from a dictionary. 6336 * Returns 0 if the entry doesn't exist or out of memory. 6337 */ 6338 long 6339 get_dict_number(d, key) 6340 dict_T *d; 6341 char_u *key; 6342 { 6343 dictitem_T *di; 6344 6345 di = dict_find(d, key, -1); 6346 if (di == NULL) 6347 return 0; 6348 return get_tv_number(&di->di_tv); 6349 } 6350 6351 /* 6352 * Return an allocated string with the string representation of a Dictionary. 6353 * May return NULL. 6354 */ 6355 static char_u * 6356 dict2string(tv) 6357 typval_T *tv; 6358 { 6359 garray_T ga; 6360 int first = TRUE; 6361 char_u *tofree; 6362 char_u numbuf[NUMBUFLEN]; 6363 hashitem_T *hi; 6364 char_u *s; 6365 dict_T *d; 6366 int todo; 6367 6368 if ((d = tv->vval.v_dict) == NULL) 6369 return NULL; 6370 ga_init2(&ga, (int)sizeof(char), 80); 6371 ga_append(&ga, '{'); 6372 6373 todo = d->dv_hashtab.ht_used; 6374 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6375 { 6376 if (!HASHITEM_EMPTY(hi)) 6377 { 6378 --todo; 6379 6380 if (first) 6381 first = FALSE; 6382 else 6383 ga_concat(&ga, (char_u *)", "); 6384 6385 tofree = string_quote(hi->hi_key, FALSE); 6386 if (tofree != NULL) 6387 { 6388 ga_concat(&ga, tofree); 6389 vim_free(tofree); 6390 } 6391 ga_concat(&ga, (char_u *)": "); 6392 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6393 if (s != NULL) 6394 ga_concat(&ga, s); 6395 vim_free(tofree); 6396 if (s == NULL) 6397 break; 6398 } 6399 } 6400 if (todo > 0) 6401 { 6402 vim_free(ga.ga_data); 6403 return NULL; 6404 } 6405 6406 ga_append(&ga, '}'); 6407 ga_append(&ga, NUL); 6408 return (char_u *)ga.ga_data; 6409 } 6410 6411 /* 6412 * Allocate a variable for a Dictionary and fill it from "*arg". 6413 * Return OK or FAIL. Returns NOTDONE for {expr}. 6414 */ 6415 static int 6416 get_dict_tv(arg, rettv, evaluate) 6417 char_u **arg; 6418 typval_T *rettv; 6419 int evaluate; 6420 { 6421 dict_T *d = NULL; 6422 typval_T tvkey; 6423 typval_T tv; 6424 char_u *key; 6425 dictitem_T *item; 6426 char_u *start = skipwhite(*arg + 1); 6427 char_u buf[NUMBUFLEN]; 6428 6429 /* 6430 * First check if it's not a curly-braces thing: {expr}. 6431 * Must do this without evaluating, otherwise a function may be called 6432 * twice. Unfortunately this means we need to call eval1() twice for the 6433 * first item. 6434 * But {} is an empty Dictionary. 6435 */ 6436 if (*start != '}') 6437 { 6438 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6439 return FAIL; 6440 if (*start == '}') 6441 return NOTDONE; 6442 } 6443 6444 if (evaluate) 6445 { 6446 d = dict_alloc(); 6447 if (d == NULL) 6448 return FAIL; 6449 } 6450 tvkey.v_type = VAR_UNKNOWN; 6451 tv.v_type = VAR_UNKNOWN; 6452 6453 *arg = skipwhite(*arg + 1); 6454 while (**arg != '}' && **arg != NUL) 6455 { 6456 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6457 goto failret; 6458 if (**arg != ':') 6459 { 6460 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6461 clear_tv(&tvkey); 6462 goto failret; 6463 } 6464 key = get_tv_string_buf_chk(&tvkey, buf); 6465 if (key == NULL || *key == NUL) 6466 { 6467 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6468 if (key != NULL) 6469 EMSG(_(e_emptykey)); 6470 clear_tv(&tvkey); 6471 goto failret; 6472 } 6473 6474 *arg = skipwhite(*arg + 1); 6475 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6476 { 6477 clear_tv(&tvkey); 6478 goto failret; 6479 } 6480 if (evaluate) 6481 { 6482 item = dict_find(d, key, -1); 6483 if (item != NULL) 6484 { 6485 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6486 clear_tv(&tvkey); 6487 clear_tv(&tv); 6488 goto failret; 6489 } 6490 item = dictitem_alloc(key); 6491 clear_tv(&tvkey); 6492 if (item != NULL) 6493 { 6494 item->di_tv = tv; 6495 item->di_tv.v_lock = 0; 6496 if (dict_add(d, item) == FAIL) 6497 dictitem_free(item); 6498 } 6499 } 6500 6501 if (**arg == '}') 6502 break; 6503 if (**arg != ',') 6504 { 6505 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6506 goto failret; 6507 } 6508 *arg = skipwhite(*arg + 1); 6509 } 6510 6511 if (**arg != '}') 6512 { 6513 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6514 failret: 6515 if (evaluate) 6516 dict_free(d); 6517 return FAIL; 6518 } 6519 6520 *arg = skipwhite(*arg + 1); 6521 if (evaluate) 6522 { 6523 rettv->v_type = VAR_DICT; 6524 rettv->vval.v_dict = d; 6525 ++d->dv_refcount; 6526 } 6527 6528 return OK; 6529 } 6530 6531 /* 6532 * Return a string with the string representation of a variable. 6533 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6534 * "numbuf" is used for a number. 6535 * Does not put quotes around strings, as ":echo" displays values. 6536 * May return NULL; 6537 */ 6538 static char_u * 6539 echo_string(tv, tofree, numbuf) 6540 typval_T *tv; 6541 char_u **tofree; 6542 char_u *numbuf; 6543 { 6544 static int recurse = 0; 6545 char_u *r = NULL; 6546 6547 if (recurse >= DICT_MAXNEST) 6548 { 6549 EMSG(_("E724: variable nested too deep for displaying")); 6550 *tofree = NULL; 6551 return NULL; 6552 } 6553 ++recurse; 6554 6555 switch (tv->v_type) 6556 { 6557 case VAR_FUNC: 6558 *tofree = NULL; 6559 r = tv->vval.v_string; 6560 break; 6561 case VAR_LIST: 6562 *tofree = list2string(tv); 6563 r = *tofree; 6564 break; 6565 case VAR_DICT: 6566 *tofree = dict2string(tv); 6567 r = *tofree; 6568 break; 6569 case VAR_STRING: 6570 case VAR_NUMBER: 6571 *tofree = NULL; 6572 r = get_tv_string_buf(tv, numbuf); 6573 break; 6574 default: 6575 EMSG2(_(e_intern2), "echo_string()"); 6576 *tofree = NULL; 6577 } 6578 6579 --recurse; 6580 return r; 6581 } 6582 6583 /* 6584 * Return a string with the string representation of a variable. 6585 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6586 * "numbuf" is used for a number. 6587 * Puts quotes around strings, so that they can be parsed back by eval(). 6588 * May return NULL; 6589 */ 6590 static char_u * 6591 tv2string(tv, tofree, numbuf) 6592 typval_T *tv; 6593 char_u **tofree; 6594 char_u *numbuf; 6595 { 6596 switch (tv->v_type) 6597 { 6598 case VAR_FUNC: 6599 *tofree = string_quote(tv->vval.v_string, TRUE); 6600 return *tofree; 6601 case VAR_STRING: 6602 *tofree = string_quote(tv->vval.v_string, FALSE); 6603 return *tofree; 6604 case VAR_NUMBER: 6605 case VAR_LIST: 6606 case VAR_DICT: 6607 break; 6608 default: 6609 EMSG2(_(e_intern2), "tv2string()"); 6610 } 6611 return echo_string(tv, tofree, numbuf); 6612 } 6613 6614 /* 6615 * Return string "str" in ' quotes, doubling ' characters. 6616 * If "str" is NULL an empty string is assumed. 6617 * If "function" is TRUE make it function('string'). 6618 */ 6619 static char_u * 6620 string_quote(str, function) 6621 char_u *str; 6622 int function; 6623 { 6624 unsigned len; 6625 char_u *p, *r, *s; 6626 6627 len = (function ? 13 : 3); 6628 if (str != NULL) 6629 { 6630 len += STRLEN(str); 6631 for (p = str; *p != NUL; mb_ptr_adv(p)) 6632 if (*p == '\'') 6633 ++len; 6634 } 6635 s = r = alloc(len); 6636 if (r != NULL) 6637 { 6638 if (function) 6639 { 6640 STRCPY(r, "function('"); 6641 r += 10; 6642 } 6643 else 6644 *r++ = '\''; 6645 if (str != NULL) 6646 for (p = str; *p != NUL; ) 6647 { 6648 if (*p == '\'') 6649 *r++ = '\''; 6650 MB_COPY_CHAR(p, r); 6651 } 6652 *r++ = '\''; 6653 if (function) 6654 *r++ = ')'; 6655 *r++ = NUL; 6656 } 6657 return s; 6658 } 6659 6660 /* 6661 * Get the value of an environment variable. 6662 * "arg" is pointing to the '$'. It is advanced to after the name. 6663 * If the environment variable was not set, silently assume it is empty. 6664 * Always return OK. 6665 */ 6666 static int 6667 get_env_tv(arg, rettv, evaluate) 6668 char_u **arg; 6669 typval_T *rettv; 6670 int evaluate; 6671 { 6672 char_u *string = NULL; 6673 int len; 6674 int cc; 6675 char_u *name; 6676 int mustfree = FALSE; 6677 6678 ++*arg; 6679 name = *arg; 6680 len = get_env_len(arg); 6681 if (evaluate) 6682 { 6683 if (len != 0) 6684 { 6685 cc = name[len]; 6686 name[len] = NUL; 6687 /* first try vim_getenv(), fast for normal environment vars */ 6688 string = vim_getenv(name, &mustfree); 6689 if (string != NULL && *string != NUL) 6690 { 6691 if (!mustfree) 6692 string = vim_strsave(string); 6693 } 6694 else 6695 { 6696 if (mustfree) 6697 vim_free(string); 6698 6699 /* next try expanding things like $VIM and ${HOME} */ 6700 string = expand_env_save(name - 1); 6701 if (string != NULL && *string == '$') 6702 { 6703 vim_free(string); 6704 string = NULL; 6705 } 6706 } 6707 name[len] = cc; 6708 } 6709 rettv->v_type = VAR_STRING; 6710 rettv->vval.v_string = string; 6711 } 6712 6713 return OK; 6714 } 6715 6716 /* 6717 * Array with names and number of arguments of all internal functions 6718 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6719 */ 6720 static struct fst 6721 { 6722 char *f_name; /* function name */ 6723 char f_min_argc; /* minimal number of arguments */ 6724 char f_max_argc; /* maximal number of arguments */ 6725 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6726 /* implemenation of function */ 6727 } functions[] = 6728 { 6729 {"add", 2, 2, f_add}, 6730 {"append", 2, 2, f_append}, 6731 {"argc", 0, 0, f_argc}, 6732 {"argidx", 0, 0, f_argidx}, 6733 {"argv", 1, 1, f_argv}, 6734 {"browse", 4, 4, f_browse}, 6735 {"browsedir", 2, 2, f_browsedir}, 6736 {"bufexists", 1, 1, f_bufexists}, 6737 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6738 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6739 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6740 {"buflisted", 1, 1, f_buflisted}, 6741 {"bufloaded", 1, 1, f_bufloaded}, 6742 {"bufname", 1, 1, f_bufname}, 6743 {"bufnr", 1, 1, f_bufnr}, 6744 {"bufwinnr", 1, 1, f_bufwinnr}, 6745 {"byte2line", 1, 1, f_byte2line}, 6746 {"byteidx", 2, 2, f_byteidx}, 6747 {"call", 2, 3, f_call}, 6748 {"char2nr", 1, 1, f_char2nr}, 6749 {"cindent", 1, 1, f_cindent}, 6750 {"col", 1, 1, f_col}, 6751 #if defined(FEAT_INS_EXPAND) 6752 {"complete_add", 1, 1, f_complete_add}, 6753 {"complete_check", 0, 0, f_complete_check}, 6754 #endif 6755 {"confirm", 1, 4, f_confirm}, 6756 {"copy", 1, 1, f_copy}, 6757 {"count", 2, 4, f_count}, 6758 {"cscope_connection",0,3, f_cscope_connection}, 6759 {"cursor", 2, 2, f_cursor}, 6760 {"deepcopy", 1, 2, f_deepcopy}, 6761 {"delete", 1, 1, f_delete}, 6762 {"did_filetype", 0, 0, f_did_filetype}, 6763 {"diff_filler", 1, 1, f_diff_filler}, 6764 {"diff_hlID", 2, 2, f_diff_hlID}, 6765 {"empty", 1, 1, f_empty}, 6766 {"escape", 2, 2, f_escape}, 6767 {"eval", 1, 1, f_eval}, 6768 {"eventhandler", 0, 0, f_eventhandler}, 6769 {"executable", 1, 1, f_executable}, 6770 {"exists", 1, 1, f_exists}, 6771 {"expand", 1, 2, f_expand}, 6772 {"extend", 2, 3, f_extend}, 6773 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6774 {"filereadable", 1, 1, f_filereadable}, 6775 {"filewritable", 1, 1, f_filewritable}, 6776 {"filter", 2, 2, f_filter}, 6777 {"finddir", 1, 3, f_finddir}, 6778 {"findfile", 1, 3, f_findfile}, 6779 {"fnamemodify", 2, 2, f_fnamemodify}, 6780 {"foldclosed", 1, 1, f_foldclosed}, 6781 {"foldclosedend", 1, 1, f_foldclosedend}, 6782 {"foldlevel", 1, 1, f_foldlevel}, 6783 {"foldtext", 0, 0, f_foldtext}, 6784 {"foldtextresult", 1, 1, f_foldtextresult}, 6785 {"foreground", 0, 0, f_foreground}, 6786 {"function", 1, 1, f_function}, 6787 {"garbagecollect", 0, 0, f_garbagecollect}, 6788 {"get", 2, 3, f_get}, 6789 {"getbufline", 2, 3, f_getbufline}, 6790 {"getbufvar", 2, 2, f_getbufvar}, 6791 {"getchar", 0, 1, f_getchar}, 6792 {"getcharmod", 0, 0, f_getcharmod}, 6793 {"getcmdline", 0, 0, f_getcmdline}, 6794 {"getcmdpos", 0, 0, f_getcmdpos}, 6795 {"getcmdtype", 0, 0, f_getcmdtype}, 6796 {"getcwd", 0, 0, f_getcwd}, 6797 {"getfontname", 0, 1, f_getfontname}, 6798 {"getfperm", 1, 1, f_getfperm}, 6799 {"getfsize", 1, 1, f_getfsize}, 6800 {"getftime", 1, 1, f_getftime}, 6801 {"getftype", 1, 1, f_getftype}, 6802 {"getline", 1, 2, f_getline}, 6803 {"getqflist", 0, 0, f_getqflist}, 6804 {"getreg", 0, 2, f_getreg}, 6805 {"getregtype", 0, 1, f_getregtype}, 6806 {"getwinposx", 0, 0, f_getwinposx}, 6807 {"getwinposy", 0, 0, f_getwinposy}, 6808 {"getwinvar", 2, 2, f_getwinvar}, 6809 {"glob", 1, 1, f_glob}, 6810 {"globpath", 2, 2, f_globpath}, 6811 {"has", 1, 1, f_has}, 6812 {"has_key", 2, 2, f_has_key}, 6813 {"hasmapto", 1, 2, f_hasmapto}, 6814 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6815 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6816 {"histadd", 2, 2, f_histadd}, 6817 {"histdel", 1, 2, f_histdel}, 6818 {"histget", 1, 2, f_histget}, 6819 {"histnr", 1, 1, f_histnr}, 6820 {"hlID", 1, 1, f_hlID}, 6821 {"hlexists", 1, 1, f_hlexists}, 6822 {"hostname", 0, 0, f_hostname}, 6823 {"iconv", 3, 3, f_iconv}, 6824 {"indent", 1, 1, f_indent}, 6825 {"index", 2, 4, f_index}, 6826 {"input", 1, 3, f_input}, 6827 {"inputdialog", 1, 3, f_inputdialog}, 6828 {"inputlist", 1, 1, f_inputlist}, 6829 {"inputrestore", 0, 0, f_inputrestore}, 6830 {"inputsave", 0, 0, f_inputsave}, 6831 {"inputsecret", 1, 2, f_inputsecret}, 6832 {"insert", 2, 3, f_insert}, 6833 {"isdirectory", 1, 1, f_isdirectory}, 6834 {"islocked", 1, 1, f_islocked}, 6835 {"items", 1, 1, f_items}, 6836 {"join", 1, 2, f_join}, 6837 {"keys", 1, 1, f_keys}, 6838 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6839 {"len", 1, 1, f_len}, 6840 {"libcall", 3, 3, f_libcall}, 6841 {"libcallnr", 3, 3, f_libcallnr}, 6842 {"line", 1, 1, f_line}, 6843 {"line2byte", 1, 1, f_line2byte}, 6844 {"lispindent", 1, 1, f_lispindent}, 6845 {"localtime", 0, 0, f_localtime}, 6846 {"map", 2, 2, f_map}, 6847 {"maparg", 1, 2, f_maparg}, 6848 {"mapcheck", 1, 2, f_mapcheck}, 6849 {"match", 2, 4, f_match}, 6850 {"matchend", 2, 4, f_matchend}, 6851 {"matchlist", 2, 4, f_matchlist}, 6852 {"matchstr", 2, 4, f_matchstr}, 6853 {"max", 1, 1, f_max}, 6854 {"min", 1, 1, f_min}, 6855 #ifdef vim_mkdir 6856 {"mkdir", 1, 3, f_mkdir}, 6857 #endif 6858 {"mode", 0, 0, f_mode}, 6859 {"nextnonblank", 1, 1, f_nextnonblank}, 6860 {"nr2char", 1, 1, f_nr2char}, 6861 {"prevnonblank", 1, 1, f_prevnonblank}, 6862 {"printf", 2, 19, f_printf}, 6863 {"range", 1, 3, f_range}, 6864 {"readfile", 1, 3, f_readfile}, 6865 {"remote_expr", 2, 3, f_remote_expr}, 6866 {"remote_foreground", 1, 1, f_remote_foreground}, 6867 {"remote_peek", 1, 2, f_remote_peek}, 6868 {"remote_read", 1, 1, f_remote_read}, 6869 {"remote_send", 2, 3, f_remote_send}, 6870 {"remove", 2, 3, f_remove}, 6871 {"rename", 2, 2, f_rename}, 6872 {"repeat", 2, 2, f_repeat}, 6873 {"resolve", 1, 1, f_resolve}, 6874 {"reverse", 1, 1, f_reverse}, 6875 {"search", 1, 2, f_search}, 6876 {"searchdecl", 1, 3, f_searchdecl}, 6877 {"searchpair", 3, 5, f_searchpair}, 6878 {"server2client", 2, 2, f_server2client}, 6879 {"serverlist", 0, 0, f_serverlist}, 6880 {"setbufvar", 3, 3, f_setbufvar}, 6881 {"setcmdpos", 1, 1, f_setcmdpos}, 6882 {"setline", 2, 2, f_setline}, 6883 {"setqflist", 1, 2, f_setqflist}, 6884 {"setreg", 2, 3, f_setreg}, 6885 {"setwinvar", 3, 3, f_setwinvar}, 6886 {"simplify", 1, 1, f_simplify}, 6887 {"sort", 1, 2, f_sort}, 6888 {"soundfold", 1, 1, f_soundfold}, 6889 {"spellbadword", 0, 1, f_spellbadword}, 6890 {"spellsuggest", 1, 2, f_spellsuggest}, 6891 {"split", 1, 3, f_split}, 6892 #ifdef HAVE_STRFTIME 6893 {"strftime", 1, 2, f_strftime}, 6894 #endif 6895 {"stridx", 2, 3, f_stridx}, 6896 {"string", 1, 1, f_string}, 6897 {"strlen", 1, 1, f_strlen}, 6898 {"strpart", 2, 3, f_strpart}, 6899 {"strridx", 2, 3, f_strridx}, 6900 {"strtrans", 1, 1, f_strtrans}, 6901 {"submatch", 1, 1, f_submatch}, 6902 {"substitute", 4, 4, f_substitute}, 6903 {"synID", 3, 3, f_synID}, 6904 {"synIDattr", 2, 3, f_synIDattr}, 6905 {"synIDtrans", 1, 1, f_synIDtrans}, 6906 {"system", 1, 2, f_system}, 6907 {"tagfiles", 0, 0, f_tagfiles}, 6908 {"taglist", 1, 1, f_taglist}, 6909 {"tempname", 0, 0, f_tempname}, 6910 {"test", 1, 1, f_test}, 6911 {"tolower", 1, 1, f_tolower}, 6912 {"toupper", 1, 1, f_toupper}, 6913 {"tr", 3, 3, f_tr}, 6914 {"type", 1, 1, f_type}, 6915 {"values", 1, 1, f_values}, 6916 {"virtcol", 1, 1, f_virtcol}, 6917 {"visualmode", 0, 1, f_visualmode}, 6918 {"winbufnr", 1, 1, f_winbufnr}, 6919 {"wincol", 0, 0, f_wincol}, 6920 {"winheight", 1, 1, f_winheight}, 6921 {"winline", 0, 0, f_winline}, 6922 {"winnr", 0, 1, f_winnr}, 6923 {"winrestcmd", 0, 0, f_winrestcmd}, 6924 {"winwidth", 1, 1, f_winwidth}, 6925 {"writefile", 2, 3, f_writefile}, 6926 }; 6927 6928 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6929 6930 /* 6931 * Function given to ExpandGeneric() to obtain the list of internal 6932 * or user defined function names. 6933 */ 6934 char_u * 6935 get_function_name(xp, idx) 6936 expand_T *xp; 6937 int idx; 6938 { 6939 static int intidx = -1; 6940 char_u *name; 6941 6942 if (idx == 0) 6943 intidx = -1; 6944 if (intidx < 0) 6945 { 6946 name = get_user_func_name(xp, idx); 6947 if (name != NULL) 6948 return name; 6949 } 6950 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6951 { 6952 STRCPY(IObuff, functions[intidx].f_name); 6953 STRCAT(IObuff, "("); 6954 if (functions[intidx].f_max_argc == 0) 6955 STRCAT(IObuff, ")"); 6956 return IObuff; 6957 } 6958 6959 return NULL; 6960 } 6961 6962 /* 6963 * Function given to ExpandGeneric() to obtain the list of internal or 6964 * user defined variable or function names. 6965 */ 6966 /*ARGSUSED*/ 6967 char_u * 6968 get_expr_name(xp, idx) 6969 expand_T *xp; 6970 int idx; 6971 { 6972 static int intidx = -1; 6973 char_u *name; 6974 6975 if (idx == 0) 6976 intidx = -1; 6977 if (intidx < 0) 6978 { 6979 name = get_function_name(xp, idx); 6980 if (name != NULL) 6981 return name; 6982 } 6983 return get_user_var_name(xp, ++intidx); 6984 } 6985 6986 #endif /* FEAT_CMDL_COMPL */ 6987 6988 /* 6989 * Find internal function in table above. 6990 * Return index, or -1 if not found 6991 */ 6992 static int 6993 find_internal_func(name) 6994 char_u *name; /* name of the function */ 6995 { 6996 int first = 0; 6997 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 6998 int cmp; 6999 int x; 7000 7001 /* 7002 * Find the function name in the table. Binary search. 7003 */ 7004 while (first <= last) 7005 { 7006 x = first + ((unsigned)(last - first) >> 1); 7007 cmp = STRCMP(name, functions[x].f_name); 7008 if (cmp < 0) 7009 last = x - 1; 7010 else if (cmp > 0) 7011 first = x + 1; 7012 else 7013 return x; 7014 } 7015 return -1; 7016 } 7017 7018 /* 7019 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7020 * name it contains, otherwise return "name". 7021 */ 7022 static char_u * 7023 deref_func_name(name, lenp) 7024 char_u *name; 7025 int *lenp; 7026 { 7027 dictitem_T *v; 7028 int cc; 7029 7030 cc = name[*lenp]; 7031 name[*lenp] = NUL; 7032 v = find_var(name, NULL); 7033 name[*lenp] = cc; 7034 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7035 { 7036 if (v->di_tv.vval.v_string == NULL) 7037 { 7038 *lenp = 0; 7039 return (char_u *)""; /* just in case */ 7040 } 7041 *lenp = STRLEN(v->di_tv.vval.v_string); 7042 return v->di_tv.vval.v_string; 7043 } 7044 7045 return name; 7046 } 7047 7048 /* 7049 * Allocate a variable for the result of a function. 7050 * Return OK or FAIL. 7051 */ 7052 static int 7053 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7054 evaluate, selfdict) 7055 char_u *name; /* name of the function */ 7056 int len; /* length of "name" */ 7057 typval_T *rettv; 7058 char_u **arg; /* argument, pointing to the '(' */ 7059 linenr_T firstline; /* first line of range */ 7060 linenr_T lastline; /* last line of range */ 7061 int *doesrange; /* return: function handled range */ 7062 int evaluate; 7063 dict_T *selfdict; /* Dictionary for "self" */ 7064 { 7065 char_u *argp; 7066 int ret = OK; 7067 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7068 int argcount = 0; /* number of arguments found */ 7069 7070 /* 7071 * Get the arguments. 7072 */ 7073 argp = *arg; 7074 while (argcount < MAX_FUNC_ARGS) 7075 { 7076 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7077 if (*argp == ')' || *argp == ',' || *argp == NUL) 7078 break; 7079 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7080 { 7081 ret = FAIL; 7082 break; 7083 } 7084 ++argcount; 7085 if (*argp != ',') 7086 break; 7087 } 7088 if (*argp == ')') 7089 ++argp; 7090 else 7091 ret = FAIL; 7092 7093 if (ret == OK) 7094 ret = call_func(name, len, rettv, argcount, argvars, 7095 firstline, lastline, doesrange, evaluate, selfdict); 7096 else if (!aborting()) 7097 { 7098 if (argcount == MAX_FUNC_ARGS) 7099 emsg_funcname("E740: Too many arguments for function %s", name); 7100 else 7101 emsg_funcname("E116: Invalid arguments for function %s", name); 7102 } 7103 7104 while (--argcount >= 0) 7105 clear_tv(&argvars[argcount]); 7106 7107 *arg = skipwhite(argp); 7108 return ret; 7109 } 7110 7111 7112 /* 7113 * Call a function with its resolved parameters 7114 * Return OK or FAIL. 7115 */ 7116 static int 7117 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7118 doesrange, evaluate, selfdict) 7119 char_u *name; /* name of the function */ 7120 int len; /* length of "name" */ 7121 typval_T *rettv; /* return value goes here */ 7122 int argcount; /* number of "argvars" */ 7123 typval_T *argvars; /* vars for arguments */ 7124 linenr_T firstline; /* first line of range */ 7125 linenr_T lastline; /* last line of range */ 7126 int *doesrange; /* return: function handled range */ 7127 int evaluate; 7128 dict_T *selfdict; /* Dictionary for "self" */ 7129 { 7130 int ret = FAIL; 7131 #define ERROR_UNKNOWN 0 7132 #define ERROR_TOOMANY 1 7133 #define ERROR_TOOFEW 2 7134 #define ERROR_SCRIPT 3 7135 #define ERROR_DICT 4 7136 #define ERROR_NONE 5 7137 #define ERROR_OTHER 6 7138 int error = ERROR_NONE; 7139 int i; 7140 int llen; 7141 ufunc_T *fp; 7142 int cc; 7143 #define FLEN_FIXED 40 7144 char_u fname_buf[FLEN_FIXED + 1]; 7145 char_u *fname; 7146 7147 /* 7148 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7149 * Change <SNR>123_name() to K_SNR 123_name(). 7150 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7151 */ 7152 cc = name[len]; 7153 name[len] = NUL; 7154 llen = eval_fname_script(name); 7155 if (llen > 0) 7156 { 7157 fname_buf[0] = K_SPECIAL; 7158 fname_buf[1] = KS_EXTRA; 7159 fname_buf[2] = (int)KE_SNR; 7160 i = 3; 7161 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7162 { 7163 if (current_SID <= 0) 7164 error = ERROR_SCRIPT; 7165 else 7166 { 7167 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7168 i = (int)STRLEN(fname_buf); 7169 } 7170 } 7171 if (i + STRLEN(name + llen) < FLEN_FIXED) 7172 { 7173 STRCPY(fname_buf + i, name + llen); 7174 fname = fname_buf; 7175 } 7176 else 7177 { 7178 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7179 if (fname == NULL) 7180 error = ERROR_OTHER; 7181 else 7182 { 7183 mch_memmove(fname, fname_buf, (size_t)i); 7184 STRCPY(fname + i, name + llen); 7185 } 7186 } 7187 } 7188 else 7189 fname = name; 7190 7191 *doesrange = FALSE; 7192 7193 7194 /* execute the function if no errors detected and executing */ 7195 if (evaluate && error == ERROR_NONE) 7196 { 7197 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7198 error = ERROR_UNKNOWN; 7199 7200 if (!builtin_function(fname)) 7201 { 7202 /* 7203 * User defined function. 7204 */ 7205 fp = find_func(fname); 7206 7207 #ifdef FEAT_AUTOCMD 7208 /* Trigger FuncUndefined event, may load the function. */ 7209 if (fp == NULL 7210 && apply_autocmds(EVENT_FUNCUNDEFINED, 7211 fname, fname, TRUE, NULL) 7212 && !aborting()) 7213 { 7214 /* executed an autocommand, search for the function again */ 7215 fp = find_func(fname); 7216 } 7217 #endif 7218 /* Try loading a package. */ 7219 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7220 { 7221 /* loaded a package, search for the function again */ 7222 fp = find_func(fname); 7223 } 7224 7225 if (fp != NULL) 7226 { 7227 if (fp->uf_flags & FC_RANGE) 7228 *doesrange = TRUE; 7229 if (argcount < fp->uf_args.ga_len) 7230 error = ERROR_TOOFEW; 7231 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7232 error = ERROR_TOOMANY; 7233 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7234 error = ERROR_DICT; 7235 else 7236 { 7237 /* 7238 * Call the user function. 7239 * Save and restore search patterns, script variables and 7240 * redo buffer. 7241 */ 7242 save_search_patterns(); 7243 saveRedobuff(); 7244 ++fp->uf_calls; 7245 call_user_func(fp, argcount, argvars, rettv, 7246 firstline, lastline, 7247 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7248 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7249 && fp->uf_refcount <= 0) 7250 /* Function was unreferenced while being used, free it 7251 * now. */ 7252 func_free(fp); 7253 restoreRedobuff(); 7254 restore_search_patterns(); 7255 error = ERROR_NONE; 7256 } 7257 } 7258 } 7259 else 7260 { 7261 /* 7262 * Find the function name in the table, call its implementation. 7263 */ 7264 i = find_internal_func(fname); 7265 if (i >= 0) 7266 { 7267 if (argcount < functions[i].f_min_argc) 7268 error = ERROR_TOOFEW; 7269 else if (argcount > functions[i].f_max_argc) 7270 error = ERROR_TOOMANY; 7271 else 7272 { 7273 argvars[argcount].v_type = VAR_UNKNOWN; 7274 functions[i].f_func(argvars, rettv); 7275 error = ERROR_NONE; 7276 } 7277 } 7278 } 7279 /* 7280 * The function call (or "FuncUndefined" autocommand sequence) might 7281 * have been aborted by an error, an interrupt, or an explicitly thrown 7282 * exception that has not been caught so far. This situation can be 7283 * tested for by calling aborting(). For an error in an internal 7284 * function or for the "E132" error in call_user_func(), however, the 7285 * throw point at which the "force_abort" flag (temporarily reset by 7286 * emsg()) is normally updated has not been reached yet. We need to 7287 * update that flag first to make aborting() reliable. 7288 */ 7289 update_force_abort(); 7290 } 7291 if (error == ERROR_NONE) 7292 ret = OK; 7293 7294 /* 7295 * Report an error unless the argument evaluation or function call has been 7296 * cancelled due to an aborting error, an interrupt, or an exception. 7297 */ 7298 if (!aborting()) 7299 { 7300 switch (error) 7301 { 7302 case ERROR_UNKNOWN: 7303 emsg_funcname("E117: Unknown function: %s", name); 7304 break; 7305 case ERROR_TOOMANY: 7306 emsg_funcname(e_toomanyarg, name); 7307 break; 7308 case ERROR_TOOFEW: 7309 emsg_funcname("E119: Not enough arguments for function: %s", 7310 name); 7311 break; 7312 case ERROR_SCRIPT: 7313 emsg_funcname("E120: Using <SID> not in a script context: %s", 7314 name); 7315 break; 7316 case ERROR_DICT: 7317 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7318 name); 7319 break; 7320 } 7321 } 7322 7323 name[len] = cc; 7324 if (fname != name && fname != fname_buf) 7325 vim_free(fname); 7326 7327 return ret; 7328 } 7329 7330 /* 7331 * Give an error message with a function name. Handle <SNR> things. 7332 */ 7333 static void 7334 emsg_funcname(msg, name) 7335 char *msg; 7336 char_u *name; 7337 { 7338 char_u *p; 7339 7340 if (*name == K_SPECIAL) 7341 p = concat_str((char_u *)"<SNR>", name + 3); 7342 else 7343 p = name; 7344 EMSG2(_(msg), p); 7345 if (p != name) 7346 vim_free(p); 7347 } 7348 7349 /********************************************* 7350 * Implementation of the built-in functions 7351 */ 7352 7353 /* 7354 * "add(list, item)" function 7355 */ 7356 static void 7357 f_add(argvars, rettv) 7358 typval_T *argvars; 7359 typval_T *rettv; 7360 { 7361 list_T *l; 7362 7363 rettv->vval.v_number = 1; /* Default: Failed */ 7364 if (argvars[0].v_type == VAR_LIST) 7365 { 7366 if ((l = argvars[0].vval.v_list) != NULL 7367 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7368 && list_append_tv(l, &argvars[1]) == OK) 7369 copy_tv(&argvars[0], rettv); 7370 } 7371 else 7372 EMSG(_(e_listreq)); 7373 } 7374 7375 /* 7376 * "append(lnum, string/list)" function 7377 */ 7378 static void 7379 f_append(argvars, rettv) 7380 typval_T *argvars; 7381 typval_T *rettv; 7382 { 7383 long lnum; 7384 char_u *line; 7385 list_T *l = NULL; 7386 listitem_T *li = NULL; 7387 typval_T *tv; 7388 long added = 0; 7389 7390 lnum = get_tv_lnum(argvars); 7391 if (lnum >= 0 7392 && lnum <= curbuf->b_ml.ml_line_count 7393 && u_save(lnum, lnum + 1) == OK) 7394 { 7395 if (argvars[1].v_type == VAR_LIST) 7396 { 7397 l = argvars[1].vval.v_list; 7398 if (l == NULL) 7399 return; 7400 li = l->lv_first; 7401 } 7402 rettv->vval.v_number = 0; /* Default: Success */ 7403 for (;;) 7404 { 7405 if (l == NULL) 7406 tv = &argvars[1]; /* append a string */ 7407 else if (li == NULL) 7408 break; /* end of list */ 7409 else 7410 tv = &li->li_tv; /* append item from list */ 7411 line = get_tv_string_chk(tv); 7412 if (line == NULL) /* type error */ 7413 { 7414 rettv->vval.v_number = 1; /* Failed */ 7415 break; 7416 } 7417 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7418 ++added; 7419 if (l == NULL) 7420 break; 7421 li = li->li_next; 7422 } 7423 7424 appended_lines_mark(lnum, added); 7425 if (curwin->w_cursor.lnum > lnum) 7426 curwin->w_cursor.lnum += added; 7427 } 7428 else 7429 rettv->vval.v_number = 1; /* Failed */ 7430 } 7431 7432 /* 7433 * "argc()" function 7434 */ 7435 /* ARGSUSED */ 7436 static void 7437 f_argc(argvars, rettv) 7438 typval_T *argvars; 7439 typval_T *rettv; 7440 { 7441 rettv->vval.v_number = ARGCOUNT; 7442 } 7443 7444 /* 7445 * "argidx()" function 7446 */ 7447 /* ARGSUSED */ 7448 static void 7449 f_argidx(argvars, rettv) 7450 typval_T *argvars; 7451 typval_T *rettv; 7452 { 7453 rettv->vval.v_number = curwin->w_arg_idx; 7454 } 7455 7456 /* 7457 * "argv(nr)" function 7458 */ 7459 static void 7460 f_argv(argvars, rettv) 7461 typval_T *argvars; 7462 typval_T *rettv; 7463 { 7464 int idx; 7465 7466 idx = get_tv_number_chk(&argvars[0], NULL); 7467 if (idx >= 0 && idx < ARGCOUNT) 7468 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7469 else 7470 rettv->vval.v_string = NULL; 7471 rettv->v_type = VAR_STRING; 7472 } 7473 7474 /* 7475 * "browse(save, title, initdir, default)" function 7476 */ 7477 /* ARGSUSED */ 7478 static void 7479 f_browse(argvars, rettv) 7480 typval_T *argvars; 7481 typval_T *rettv; 7482 { 7483 #ifdef FEAT_BROWSE 7484 int save; 7485 char_u *title; 7486 char_u *initdir; 7487 char_u *defname; 7488 char_u buf[NUMBUFLEN]; 7489 char_u buf2[NUMBUFLEN]; 7490 int error = FALSE; 7491 7492 save = get_tv_number_chk(&argvars[0], &error); 7493 title = get_tv_string_chk(&argvars[1]); 7494 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7495 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7496 7497 if (error || title == NULL || initdir == NULL || defname == NULL) 7498 rettv->vval.v_string = NULL; 7499 else 7500 rettv->vval.v_string = 7501 do_browse(save ? BROWSE_SAVE : 0, 7502 title, defname, NULL, initdir, NULL, curbuf); 7503 #else 7504 rettv->vval.v_string = NULL; 7505 #endif 7506 rettv->v_type = VAR_STRING; 7507 } 7508 7509 /* 7510 * "browsedir(title, initdir)" function 7511 */ 7512 /* ARGSUSED */ 7513 static void 7514 f_browsedir(argvars, rettv) 7515 typval_T *argvars; 7516 typval_T *rettv; 7517 { 7518 #ifdef FEAT_BROWSE 7519 char_u *title; 7520 char_u *initdir; 7521 char_u buf[NUMBUFLEN]; 7522 7523 title = get_tv_string_chk(&argvars[0]); 7524 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7525 7526 if (title == NULL || initdir == NULL) 7527 rettv->vval.v_string = NULL; 7528 else 7529 rettv->vval.v_string = do_browse(BROWSE_DIR, 7530 title, NULL, NULL, initdir, NULL, curbuf); 7531 #else 7532 rettv->vval.v_string = NULL; 7533 #endif 7534 rettv->v_type = VAR_STRING; 7535 } 7536 7537 static buf_T *find_buffer __ARGS((typval_T *avar)); 7538 7539 /* 7540 * Find a buffer by number or exact name. 7541 */ 7542 static buf_T * 7543 find_buffer(avar) 7544 typval_T *avar; 7545 { 7546 buf_T *buf = NULL; 7547 7548 if (avar->v_type == VAR_NUMBER) 7549 buf = buflist_findnr((int)avar->vval.v_number); 7550 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7551 { 7552 buf = buflist_findname_exp(avar->vval.v_string); 7553 if (buf == NULL) 7554 { 7555 /* No full path name match, try a match with a URL or a "nofile" 7556 * buffer, these don't use the full path. */ 7557 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7558 if (buf->b_fname != NULL 7559 && (path_with_url(buf->b_fname) 7560 #ifdef FEAT_QUICKFIX 7561 || bt_nofile(buf) 7562 #endif 7563 ) 7564 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7565 break; 7566 } 7567 } 7568 return buf; 7569 } 7570 7571 /* 7572 * "bufexists(expr)" function 7573 */ 7574 static void 7575 f_bufexists(argvars, rettv) 7576 typval_T *argvars; 7577 typval_T *rettv; 7578 { 7579 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7580 } 7581 7582 /* 7583 * "buflisted(expr)" function 7584 */ 7585 static void 7586 f_buflisted(argvars, rettv) 7587 typval_T *argvars; 7588 typval_T *rettv; 7589 { 7590 buf_T *buf; 7591 7592 buf = find_buffer(&argvars[0]); 7593 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7594 } 7595 7596 /* 7597 * "bufloaded(expr)" function 7598 */ 7599 static void 7600 f_bufloaded(argvars, rettv) 7601 typval_T *argvars; 7602 typval_T *rettv; 7603 { 7604 buf_T *buf; 7605 7606 buf = find_buffer(&argvars[0]); 7607 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7608 } 7609 7610 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7611 7612 /* 7613 * Get buffer by number or pattern. 7614 */ 7615 static buf_T * 7616 get_buf_tv(tv) 7617 typval_T *tv; 7618 { 7619 char_u *name = tv->vval.v_string; 7620 int save_magic; 7621 char_u *save_cpo; 7622 buf_T *buf; 7623 7624 if (tv->v_type == VAR_NUMBER) 7625 return buflist_findnr((int)tv->vval.v_number); 7626 if (tv->v_type != VAR_STRING) 7627 return NULL; 7628 if (name == NULL || *name == NUL) 7629 return curbuf; 7630 if (name[0] == '$' && name[1] == NUL) 7631 return lastbuf; 7632 7633 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7634 save_magic = p_magic; 7635 p_magic = TRUE; 7636 save_cpo = p_cpo; 7637 p_cpo = (char_u *)""; 7638 7639 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7640 TRUE, FALSE)); 7641 7642 p_magic = save_magic; 7643 p_cpo = save_cpo; 7644 7645 /* If not found, try expanding the name, like done for bufexists(). */ 7646 if (buf == NULL) 7647 buf = find_buffer(tv); 7648 7649 return buf; 7650 } 7651 7652 /* 7653 * "bufname(expr)" function 7654 */ 7655 static void 7656 f_bufname(argvars, rettv) 7657 typval_T *argvars; 7658 typval_T *rettv; 7659 { 7660 buf_T *buf; 7661 7662 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7663 ++emsg_off; 7664 buf = get_buf_tv(&argvars[0]); 7665 rettv->v_type = VAR_STRING; 7666 if (buf != NULL && buf->b_fname != NULL) 7667 rettv->vval.v_string = vim_strsave(buf->b_fname); 7668 else 7669 rettv->vval.v_string = NULL; 7670 --emsg_off; 7671 } 7672 7673 /* 7674 * "bufnr(expr)" function 7675 */ 7676 static void 7677 f_bufnr(argvars, rettv) 7678 typval_T *argvars; 7679 typval_T *rettv; 7680 { 7681 buf_T *buf; 7682 7683 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7684 ++emsg_off; 7685 buf = get_buf_tv(&argvars[0]); 7686 if (buf != NULL) 7687 rettv->vval.v_number = buf->b_fnum; 7688 else 7689 rettv->vval.v_number = -1; 7690 --emsg_off; 7691 } 7692 7693 /* 7694 * "bufwinnr(nr)" function 7695 */ 7696 static void 7697 f_bufwinnr(argvars, rettv) 7698 typval_T *argvars; 7699 typval_T *rettv; 7700 { 7701 #ifdef FEAT_WINDOWS 7702 win_T *wp; 7703 int winnr = 0; 7704 #endif 7705 buf_T *buf; 7706 7707 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7708 ++emsg_off; 7709 buf = get_buf_tv(&argvars[0]); 7710 #ifdef FEAT_WINDOWS 7711 for (wp = firstwin; wp; wp = wp->w_next) 7712 { 7713 ++winnr; 7714 if (wp->w_buffer == buf) 7715 break; 7716 } 7717 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7718 #else 7719 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7720 #endif 7721 --emsg_off; 7722 } 7723 7724 /* 7725 * "byte2line(byte)" function 7726 */ 7727 /*ARGSUSED*/ 7728 static void 7729 f_byte2line(argvars, rettv) 7730 typval_T *argvars; 7731 typval_T *rettv; 7732 { 7733 #ifndef FEAT_BYTEOFF 7734 rettv->vval.v_number = -1; 7735 #else 7736 long boff = 0; 7737 7738 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7739 if (boff < 0) 7740 rettv->vval.v_number = -1; 7741 else 7742 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7743 (linenr_T)0, &boff); 7744 #endif 7745 } 7746 7747 /* 7748 * "byteidx()" function 7749 */ 7750 /*ARGSUSED*/ 7751 static void 7752 f_byteidx(argvars, rettv) 7753 typval_T *argvars; 7754 typval_T *rettv; 7755 { 7756 #ifdef FEAT_MBYTE 7757 char_u *t; 7758 #endif 7759 char_u *str; 7760 long idx; 7761 7762 str = get_tv_string_chk(&argvars[0]); 7763 idx = get_tv_number_chk(&argvars[1], NULL); 7764 rettv->vval.v_number = -1; 7765 if (str == NULL || idx < 0) 7766 return; 7767 7768 #ifdef FEAT_MBYTE 7769 t = str; 7770 for ( ; idx > 0; idx--) 7771 { 7772 if (*t == NUL) /* EOL reached */ 7773 return; 7774 t += (*mb_ptr2len)(t); 7775 } 7776 rettv->vval.v_number = t - str; 7777 #else 7778 if (idx <= STRLEN(str)) 7779 rettv->vval.v_number = idx; 7780 #endif 7781 } 7782 7783 /* 7784 * "call(func, arglist)" function 7785 */ 7786 static void 7787 f_call(argvars, rettv) 7788 typval_T *argvars; 7789 typval_T *rettv; 7790 { 7791 char_u *func; 7792 typval_T argv[MAX_FUNC_ARGS]; 7793 int argc = 0; 7794 listitem_T *item; 7795 int dummy; 7796 dict_T *selfdict = NULL; 7797 7798 rettv->vval.v_number = 0; 7799 if (argvars[1].v_type != VAR_LIST) 7800 { 7801 EMSG(_(e_listreq)); 7802 return; 7803 } 7804 if (argvars[1].vval.v_list == NULL) 7805 return; 7806 7807 if (argvars[0].v_type == VAR_FUNC) 7808 func = argvars[0].vval.v_string; 7809 else 7810 func = get_tv_string(&argvars[0]); 7811 if (*func == NUL) 7812 return; /* type error or empty name */ 7813 7814 if (argvars[2].v_type != VAR_UNKNOWN) 7815 { 7816 if (argvars[2].v_type != VAR_DICT) 7817 { 7818 EMSG(_(e_dictreq)); 7819 return; 7820 } 7821 selfdict = argvars[2].vval.v_dict; 7822 } 7823 7824 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7825 item = item->li_next) 7826 { 7827 if (argc == MAX_FUNC_ARGS) 7828 { 7829 EMSG(_("E699: Too many arguments")); 7830 break; 7831 } 7832 /* Make a copy of each argument. This is needed to be able to set 7833 * v_lock to VAR_FIXED in the copy without changing the original list. 7834 */ 7835 copy_tv(&item->li_tv, &argv[argc++]); 7836 } 7837 7838 if (item == NULL) 7839 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7840 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7841 &dummy, TRUE, selfdict); 7842 7843 /* Free the arguments. */ 7844 while (argc > 0) 7845 clear_tv(&argv[--argc]); 7846 } 7847 7848 /* 7849 * "char2nr(string)" function 7850 */ 7851 static void 7852 f_char2nr(argvars, rettv) 7853 typval_T *argvars; 7854 typval_T *rettv; 7855 { 7856 #ifdef FEAT_MBYTE 7857 if (has_mbyte) 7858 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7859 else 7860 #endif 7861 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7862 } 7863 7864 /* 7865 * "cindent(lnum)" function 7866 */ 7867 static void 7868 f_cindent(argvars, rettv) 7869 typval_T *argvars; 7870 typval_T *rettv; 7871 { 7872 #ifdef FEAT_CINDENT 7873 pos_T pos; 7874 linenr_T lnum; 7875 7876 pos = curwin->w_cursor; 7877 lnum = get_tv_lnum(argvars); 7878 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7879 { 7880 curwin->w_cursor.lnum = lnum; 7881 rettv->vval.v_number = get_c_indent(); 7882 curwin->w_cursor = pos; 7883 } 7884 else 7885 #endif 7886 rettv->vval.v_number = -1; 7887 } 7888 7889 /* 7890 * "col(string)" function 7891 */ 7892 static void 7893 f_col(argvars, rettv) 7894 typval_T *argvars; 7895 typval_T *rettv; 7896 { 7897 colnr_T col = 0; 7898 pos_T *fp; 7899 7900 fp = var2fpos(&argvars[0], FALSE); 7901 if (fp != NULL) 7902 { 7903 if (fp->col == MAXCOL) 7904 { 7905 /* '> can be MAXCOL, get the length of the line then */ 7906 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7907 col = STRLEN(ml_get(fp->lnum)) + 1; 7908 else 7909 col = MAXCOL; 7910 } 7911 else 7912 { 7913 col = fp->col + 1; 7914 #ifdef FEAT_VIRTUALEDIT 7915 /* col(".") when the cursor is on the NUL at the end of the line 7916 * because of "coladd" can be seen as an extra column. */ 7917 if (virtual_active() && fp == &curwin->w_cursor) 7918 { 7919 char_u *p = ml_get_cursor(); 7920 7921 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7922 curwin->w_virtcol - curwin->w_cursor.coladd)) 7923 { 7924 # ifdef FEAT_MBYTE 7925 int l; 7926 7927 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 7928 col += l; 7929 # else 7930 if (*p != NUL && p[1] == NUL) 7931 ++col; 7932 # endif 7933 } 7934 } 7935 #endif 7936 } 7937 } 7938 rettv->vval.v_number = col; 7939 } 7940 7941 #if defined(FEAT_INS_EXPAND) 7942 /* 7943 * "complete_add()" function 7944 */ 7945 /*ARGSUSED*/ 7946 static void 7947 f_complete_add(argvars, rettv) 7948 typval_T *argvars; 7949 typval_T *rettv; 7950 { 7951 char_u *s; 7952 7953 s = get_tv_string_chk(&argvars[0]); 7954 if (s != NULL) 7955 rettv->vval.v_number = ins_compl_add(s, -1, NULL, FORWARD, 0); 7956 } 7957 7958 /* 7959 * "complete_check()" function 7960 */ 7961 /*ARGSUSED*/ 7962 static void 7963 f_complete_check(argvars, rettv) 7964 typval_T *argvars; 7965 typval_T *rettv; 7966 { 7967 int saved = RedrawingDisabled; 7968 7969 RedrawingDisabled = 0; 7970 ins_compl_check_keys(0); 7971 rettv->vval.v_number = compl_interrupted; 7972 RedrawingDisabled = saved; 7973 } 7974 #endif 7975 7976 /* 7977 * "confirm(message, buttons[, default [, type]])" function 7978 */ 7979 /*ARGSUSED*/ 7980 static void 7981 f_confirm(argvars, rettv) 7982 typval_T *argvars; 7983 typval_T *rettv; 7984 { 7985 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7986 char_u *message; 7987 char_u *buttons = NULL; 7988 char_u buf[NUMBUFLEN]; 7989 char_u buf2[NUMBUFLEN]; 7990 int def = 1; 7991 int type = VIM_GENERIC; 7992 char_u *typestr; 7993 int error = FALSE; 7994 7995 message = get_tv_string_chk(&argvars[0]); 7996 if (message == NULL) 7997 error = TRUE; 7998 if (argvars[1].v_type != VAR_UNKNOWN) 7999 { 8000 buttons = get_tv_string_buf_chk(&argvars[1], buf); 8001 if (buttons == NULL) 8002 error = TRUE; 8003 if (argvars[2].v_type != VAR_UNKNOWN) 8004 { 8005 def = get_tv_number_chk(&argvars[2], &error); 8006 if (argvars[3].v_type != VAR_UNKNOWN) 8007 { 8008 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 8009 if (typestr == NULL) 8010 error = TRUE; 8011 else 8012 { 8013 switch (TOUPPER_ASC(*typestr)) 8014 { 8015 case 'E': type = VIM_ERROR; break; 8016 case 'Q': type = VIM_QUESTION; break; 8017 case 'I': type = VIM_INFO; break; 8018 case 'W': type = VIM_WARNING; break; 8019 case 'G': type = VIM_GENERIC; break; 8020 } 8021 } 8022 } 8023 } 8024 } 8025 8026 if (buttons == NULL || *buttons == NUL) 8027 buttons = (char_u *)_("&Ok"); 8028 8029 if (error) 8030 rettv->vval.v_number = 0; 8031 else 8032 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8033 def, NULL); 8034 #else 8035 rettv->vval.v_number = 0; 8036 #endif 8037 } 8038 8039 /* 8040 * "copy()" function 8041 */ 8042 static void 8043 f_copy(argvars, rettv) 8044 typval_T *argvars; 8045 typval_T *rettv; 8046 { 8047 item_copy(&argvars[0], rettv, FALSE, 0); 8048 } 8049 8050 /* 8051 * "count()" function 8052 */ 8053 static void 8054 f_count(argvars, rettv) 8055 typval_T *argvars; 8056 typval_T *rettv; 8057 { 8058 long n = 0; 8059 int ic = FALSE; 8060 8061 if (argvars[0].v_type == VAR_LIST) 8062 { 8063 listitem_T *li; 8064 list_T *l; 8065 long idx; 8066 8067 if ((l = argvars[0].vval.v_list) != NULL) 8068 { 8069 li = l->lv_first; 8070 if (argvars[2].v_type != VAR_UNKNOWN) 8071 { 8072 int error = FALSE; 8073 8074 ic = get_tv_number_chk(&argvars[2], &error); 8075 if (argvars[3].v_type != VAR_UNKNOWN) 8076 { 8077 idx = get_tv_number_chk(&argvars[3], &error); 8078 if (!error) 8079 { 8080 li = list_find(l, idx); 8081 if (li == NULL) 8082 EMSGN(_(e_listidx), idx); 8083 } 8084 } 8085 if (error) 8086 li = NULL; 8087 } 8088 8089 for ( ; li != NULL; li = li->li_next) 8090 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8091 ++n; 8092 } 8093 } 8094 else if (argvars[0].v_type == VAR_DICT) 8095 { 8096 int todo; 8097 dict_T *d; 8098 hashitem_T *hi; 8099 8100 if ((d = argvars[0].vval.v_dict) != NULL) 8101 { 8102 int error = FALSE; 8103 8104 if (argvars[2].v_type != VAR_UNKNOWN) 8105 { 8106 ic = get_tv_number_chk(&argvars[2], &error); 8107 if (argvars[3].v_type != VAR_UNKNOWN) 8108 EMSG(_(e_invarg)); 8109 } 8110 8111 todo = error ? 0 : d->dv_hashtab.ht_used; 8112 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8113 { 8114 if (!HASHITEM_EMPTY(hi)) 8115 { 8116 --todo; 8117 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8118 ++n; 8119 } 8120 } 8121 } 8122 } 8123 else 8124 EMSG2(_(e_listdictarg), "count()"); 8125 rettv->vval.v_number = n; 8126 } 8127 8128 /* 8129 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8130 * 8131 * Checks the existence of a cscope connection. 8132 */ 8133 /*ARGSUSED*/ 8134 static void 8135 f_cscope_connection(argvars, rettv) 8136 typval_T *argvars; 8137 typval_T *rettv; 8138 { 8139 #ifdef FEAT_CSCOPE 8140 int num = 0; 8141 char_u *dbpath = NULL; 8142 char_u *prepend = NULL; 8143 char_u buf[NUMBUFLEN]; 8144 8145 if (argvars[0].v_type != VAR_UNKNOWN 8146 && argvars[1].v_type != VAR_UNKNOWN) 8147 { 8148 num = (int)get_tv_number(&argvars[0]); 8149 dbpath = get_tv_string(&argvars[1]); 8150 if (argvars[2].v_type != VAR_UNKNOWN) 8151 prepend = get_tv_string_buf(&argvars[2], buf); 8152 } 8153 8154 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8155 #else 8156 rettv->vval.v_number = 0; 8157 #endif 8158 } 8159 8160 /* 8161 * "cursor(lnum, col)" function 8162 * 8163 * Moves the cursor to the specified line and column 8164 */ 8165 /*ARGSUSED*/ 8166 static void 8167 f_cursor(argvars, rettv) 8168 typval_T *argvars; 8169 typval_T *rettv; 8170 { 8171 long line, col; 8172 8173 line = get_tv_lnum(argvars); 8174 col = get_tv_number_chk(&argvars[1], NULL); 8175 if (line < 0 || col < 0) 8176 return; /* type error; errmsg already given */ 8177 if (line > 0) 8178 curwin->w_cursor.lnum = line; 8179 if (col > 0) 8180 curwin->w_cursor.col = col - 1; 8181 #ifdef FEAT_VIRTUALEDIT 8182 curwin->w_cursor.coladd = 0; 8183 #endif 8184 8185 /* Make sure the cursor is in a valid position. */ 8186 check_cursor(); 8187 #ifdef FEAT_MBYTE 8188 /* Correct cursor for multi-byte character. */ 8189 if (has_mbyte) 8190 mb_adjust_cursor(); 8191 #endif 8192 8193 curwin->w_set_curswant = TRUE; 8194 } 8195 8196 /* 8197 * "deepcopy()" function 8198 */ 8199 static void 8200 f_deepcopy(argvars, rettv) 8201 typval_T *argvars; 8202 typval_T *rettv; 8203 { 8204 int noref = 0; 8205 8206 if (argvars[1].v_type != VAR_UNKNOWN) 8207 noref = get_tv_number_chk(&argvars[1], NULL); 8208 if (noref < 0 || noref > 1) 8209 EMSG(_(e_invarg)); 8210 else 8211 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8212 } 8213 8214 /* 8215 * "delete()" function 8216 */ 8217 static void 8218 f_delete(argvars, rettv) 8219 typval_T *argvars; 8220 typval_T *rettv; 8221 { 8222 if (check_restricted() || check_secure()) 8223 rettv->vval.v_number = -1; 8224 else 8225 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8226 } 8227 8228 /* 8229 * "did_filetype()" function 8230 */ 8231 /*ARGSUSED*/ 8232 static void 8233 f_did_filetype(argvars, rettv) 8234 typval_T *argvars; 8235 typval_T *rettv; 8236 { 8237 #ifdef FEAT_AUTOCMD 8238 rettv->vval.v_number = did_filetype; 8239 #else 8240 rettv->vval.v_number = 0; 8241 #endif 8242 } 8243 8244 /* 8245 * "diff_filler()" function 8246 */ 8247 /*ARGSUSED*/ 8248 static void 8249 f_diff_filler(argvars, rettv) 8250 typval_T *argvars; 8251 typval_T *rettv; 8252 { 8253 #ifdef FEAT_DIFF 8254 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8255 #endif 8256 } 8257 8258 /* 8259 * "diff_hlID()" function 8260 */ 8261 /*ARGSUSED*/ 8262 static void 8263 f_diff_hlID(argvars, rettv) 8264 typval_T *argvars; 8265 typval_T *rettv; 8266 { 8267 #ifdef FEAT_DIFF 8268 linenr_T lnum = get_tv_lnum(argvars); 8269 static linenr_T prev_lnum = 0; 8270 static int changedtick = 0; 8271 static int fnum = 0; 8272 static int change_start = 0; 8273 static int change_end = 0; 8274 static hlf_T hlID = 0; 8275 int filler_lines; 8276 int col; 8277 8278 if (lnum < 0) /* ignore type error in {lnum} arg */ 8279 lnum = 0; 8280 if (lnum != prev_lnum 8281 || changedtick != curbuf->b_changedtick 8282 || fnum != curbuf->b_fnum) 8283 { 8284 /* New line, buffer, change: need to get the values. */ 8285 filler_lines = diff_check(curwin, lnum); 8286 if (filler_lines < 0) 8287 { 8288 if (filler_lines == -1) 8289 { 8290 change_start = MAXCOL; 8291 change_end = -1; 8292 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8293 hlID = HLF_ADD; /* added line */ 8294 else 8295 hlID = HLF_CHD; /* changed line */ 8296 } 8297 else 8298 hlID = HLF_ADD; /* added line */ 8299 } 8300 else 8301 hlID = (hlf_T)0; 8302 prev_lnum = lnum; 8303 changedtick = curbuf->b_changedtick; 8304 fnum = curbuf->b_fnum; 8305 } 8306 8307 if (hlID == HLF_CHD || hlID == HLF_TXD) 8308 { 8309 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8310 if (col >= change_start && col <= change_end) 8311 hlID = HLF_TXD; /* changed text */ 8312 else 8313 hlID = HLF_CHD; /* changed line */ 8314 } 8315 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 8316 #endif 8317 } 8318 8319 /* 8320 * "empty({expr})" function 8321 */ 8322 static void 8323 f_empty(argvars, rettv) 8324 typval_T *argvars; 8325 typval_T *rettv; 8326 { 8327 int n; 8328 8329 switch (argvars[0].v_type) 8330 { 8331 case VAR_STRING: 8332 case VAR_FUNC: 8333 n = argvars[0].vval.v_string == NULL 8334 || *argvars[0].vval.v_string == NUL; 8335 break; 8336 case VAR_NUMBER: 8337 n = argvars[0].vval.v_number == 0; 8338 break; 8339 case VAR_LIST: 8340 n = argvars[0].vval.v_list == NULL 8341 || argvars[0].vval.v_list->lv_first == NULL; 8342 break; 8343 case VAR_DICT: 8344 n = argvars[0].vval.v_dict == NULL 8345 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8346 break; 8347 default: 8348 EMSG2(_(e_intern2), "f_empty()"); 8349 n = 0; 8350 } 8351 8352 rettv->vval.v_number = n; 8353 } 8354 8355 /* 8356 * "escape({string}, {chars})" function 8357 */ 8358 static void 8359 f_escape(argvars, rettv) 8360 typval_T *argvars; 8361 typval_T *rettv; 8362 { 8363 char_u buf[NUMBUFLEN]; 8364 8365 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8366 get_tv_string_buf(&argvars[1], buf)); 8367 rettv->v_type = VAR_STRING; 8368 } 8369 8370 /* 8371 * "eval()" function 8372 */ 8373 /*ARGSUSED*/ 8374 static void 8375 f_eval(argvars, rettv) 8376 typval_T *argvars; 8377 typval_T *rettv; 8378 { 8379 char_u *s; 8380 8381 s = get_tv_string_chk(&argvars[0]); 8382 if (s != NULL) 8383 s = skipwhite(s); 8384 8385 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8386 { 8387 rettv->v_type = VAR_NUMBER; 8388 rettv->vval.v_number = 0; 8389 } 8390 else if (*s != NUL) 8391 EMSG(_(e_trailing)); 8392 } 8393 8394 /* 8395 * "eventhandler()" function 8396 */ 8397 /*ARGSUSED*/ 8398 static void 8399 f_eventhandler(argvars, rettv) 8400 typval_T *argvars; 8401 typval_T *rettv; 8402 { 8403 rettv->vval.v_number = vgetc_busy; 8404 } 8405 8406 /* 8407 * "executable()" function 8408 */ 8409 static void 8410 f_executable(argvars, rettv) 8411 typval_T *argvars; 8412 typval_T *rettv; 8413 { 8414 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8415 } 8416 8417 /* 8418 * "exists()" function 8419 */ 8420 static void 8421 f_exists(argvars, rettv) 8422 typval_T *argvars; 8423 typval_T *rettv; 8424 { 8425 char_u *p; 8426 char_u *name; 8427 int n = FALSE; 8428 int len = 0; 8429 8430 p = get_tv_string(&argvars[0]); 8431 if (*p == '$') /* environment variable */ 8432 { 8433 /* first try "normal" environment variables (fast) */ 8434 if (mch_getenv(p + 1) != NULL) 8435 n = TRUE; 8436 else 8437 { 8438 /* try expanding things like $VIM and ${HOME} */ 8439 p = expand_env_save(p); 8440 if (p != NULL && *p != '$') 8441 n = TRUE; 8442 vim_free(p); 8443 } 8444 } 8445 else if (*p == '&' || *p == '+') /* option */ 8446 n = (get_option_tv(&p, NULL, TRUE) == OK); 8447 else if (*p == '*') /* internal or user defined function */ 8448 { 8449 n = function_exists(p + 1); 8450 } 8451 else if (*p == ':') 8452 { 8453 n = cmd_exists(p + 1); 8454 } 8455 else if (*p == '#') 8456 { 8457 #ifdef FEAT_AUTOCMD 8458 name = p + 1; 8459 p = vim_strchr(name, '#'); 8460 if (p != NULL) 8461 n = au_exists(name, p, p + 1); 8462 else 8463 n = au_exists(name, name + STRLEN(name), NULL); 8464 #endif 8465 } 8466 else /* internal variable */ 8467 { 8468 char_u *tofree; 8469 typval_T tv; 8470 8471 /* get_name_len() takes care of expanding curly braces */ 8472 name = p; 8473 len = get_name_len(&p, &tofree, TRUE, FALSE); 8474 if (len > 0) 8475 { 8476 if (tofree != NULL) 8477 name = tofree; 8478 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8479 if (n) 8480 { 8481 /* handle d.key, l[idx], f(expr) */ 8482 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8483 if (n) 8484 clear_tv(&tv); 8485 } 8486 } 8487 8488 vim_free(tofree); 8489 } 8490 8491 rettv->vval.v_number = n; 8492 } 8493 8494 /* 8495 * "expand()" function 8496 */ 8497 static void 8498 f_expand(argvars, rettv) 8499 typval_T *argvars; 8500 typval_T *rettv; 8501 { 8502 char_u *s; 8503 int len; 8504 char_u *errormsg; 8505 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8506 expand_T xpc; 8507 int error = FALSE; 8508 8509 rettv->v_type = VAR_STRING; 8510 s = get_tv_string(&argvars[0]); 8511 if (*s == '%' || *s == '#' || *s == '<') 8512 { 8513 ++emsg_off; 8514 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8515 --emsg_off; 8516 } 8517 else 8518 { 8519 /* When the optional second argument is non-zero, don't remove matches 8520 * for 'suffixes' and 'wildignore' */ 8521 if (argvars[1].v_type != VAR_UNKNOWN 8522 && get_tv_number_chk(&argvars[1], &error)) 8523 flags |= WILD_KEEP_ALL; 8524 if (!error) 8525 { 8526 ExpandInit(&xpc); 8527 xpc.xp_context = EXPAND_FILES; 8528 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8529 ExpandCleanup(&xpc); 8530 } 8531 else 8532 rettv->vval.v_string = NULL; 8533 } 8534 } 8535 8536 /* 8537 * "extend(list, list [, idx])" function 8538 * "extend(dict, dict [, action])" function 8539 */ 8540 static void 8541 f_extend(argvars, rettv) 8542 typval_T *argvars; 8543 typval_T *rettv; 8544 { 8545 rettv->vval.v_number = 0; 8546 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8547 { 8548 list_T *l1, *l2; 8549 listitem_T *item; 8550 long before; 8551 int error = FALSE; 8552 8553 l1 = argvars[0].vval.v_list; 8554 l2 = argvars[1].vval.v_list; 8555 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8556 && l2 != NULL) 8557 { 8558 if (argvars[2].v_type != VAR_UNKNOWN) 8559 { 8560 before = get_tv_number_chk(&argvars[2], &error); 8561 if (error) 8562 return; /* type error; errmsg already given */ 8563 8564 if (before == l1->lv_len) 8565 item = NULL; 8566 else 8567 { 8568 item = list_find(l1, before); 8569 if (item == NULL) 8570 { 8571 EMSGN(_(e_listidx), before); 8572 return; 8573 } 8574 } 8575 } 8576 else 8577 item = NULL; 8578 list_extend(l1, l2, item); 8579 8580 copy_tv(&argvars[0], rettv); 8581 } 8582 } 8583 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8584 { 8585 dict_T *d1, *d2; 8586 dictitem_T *di1; 8587 char_u *action; 8588 int i; 8589 hashitem_T *hi2; 8590 int todo; 8591 8592 d1 = argvars[0].vval.v_dict; 8593 d2 = argvars[1].vval.v_dict; 8594 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8595 && d2 != NULL) 8596 { 8597 /* Check the third argument. */ 8598 if (argvars[2].v_type != VAR_UNKNOWN) 8599 { 8600 static char *(av[]) = {"keep", "force", "error"}; 8601 8602 action = get_tv_string_chk(&argvars[2]); 8603 if (action == NULL) 8604 return; /* type error; errmsg already given */ 8605 for (i = 0; i < 3; ++i) 8606 if (STRCMP(action, av[i]) == 0) 8607 break; 8608 if (i == 3) 8609 { 8610 EMSGN(_(e_invarg2), action); 8611 return; 8612 } 8613 } 8614 else 8615 action = (char_u *)"force"; 8616 8617 /* Go over all entries in the second dict and add them to the 8618 * first dict. */ 8619 todo = d2->dv_hashtab.ht_used; 8620 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8621 { 8622 if (!HASHITEM_EMPTY(hi2)) 8623 { 8624 --todo; 8625 di1 = dict_find(d1, hi2->hi_key, -1); 8626 if (di1 == NULL) 8627 { 8628 di1 = dictitem_copy(HI2DI(hi2)); 8629 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8630 dictitem_free(di1); 8631 } 8632 else if (*action == 'e') 8633 { 8634 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8635 break; 8636 } 8637 else if (*action == 'f') 8638 { 8639 clear_tv(&di1->di_tv); 8640 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8641 } 8642 } 8643 } 8644 8645 copy_tv(&argvars[0], rettv); 8646 } 8647 } 8648 else 8649 EMSG2(_(e_listdictarg), "extend()"); 8650 } 8651 8652 /* 8653 * "filereadable()" function 8654 */ 8655 static void 8656 f_filereadable(argvars, rettv) 8657 typval_T *argvars; 8658 typval_T *rettv; 8659 { 8660 FILE *fd; 8661 char_u *p; 8662 int n; 8663 8664 p = get_tv_string(&argvars[0]); 8665 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8666 { 8667 n = TRUE; 8668 fclose(fd); 8669 } 8670 else 8671 n = FALSE; 8672 8673 rettv->vval.v_number = n; 8674 } 8675 8676 /* 8677 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8678 * rights to write into. 8679 */ 8680 static void 8681 f_filewritable(argvars, rettv) 8682 typval_T *argvars; 8683 typval_T *rettv; 8684 { 8685 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8686 } 8687 8688 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8689 8690 static void 8691 findfilendir(argvars, rettv, dir) 8692 typval_T *argvars; 8693 typval_T *rettv; 8694 int dir; 8695 { 8696 #ifdef FEAT_SEARCHPATH 8697 char_u *fname; 8698 char_u *fresult = NULL; 8699 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8700 char_u *p; 8701 char_u pathbuf[NUMBUFLEN]; 8702 int count = 1; 8703 int first = TRUE; 8704 8705 fname = get_tv_string(&argvars[0]); 8706 8707 if (argvars[1].v_type != VAR_UNKNOWN) 8708 { 8709 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8710 if (p == NULL) 8711 count = -1; /* error */ 8712 else 8713 { 8714 if (*p != NUL) 8715 path = p; 8716 8717 if (argvars[2].v_type != VAR_UNKNOWN) 8718 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8719 } 8720 } 8721 8722 if (*fname != NUL && count >= 0) 8723 { 8724 do 8725 { 8726 vim_free(fresult); 8727 fresult = find_file_in_path_option(first ? fname : NULL, 8728 first ? (int)STRLEN(fname) : 0, 8729 0, first, path, dir, NULL); 8730 first = FALSE; 8731 } while (--count > 0 && fresult != NULL); 8732 } 8733 8734 rettv->vval.v_string = fresult; 8735 #else 8736 rettv->vval.v_string = NULL; 8737 #endif 8738 rettv->v_type = VAR_STRING; 8739 } 8740 8741 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8742 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8743 8744 /* 8745 * Implementation of map() and filter(). 8746 */ 8747 static void 8748 filter_map(argvars, rettv, map) 8749 typval_T *argvars; 8750 typval_T *rettv; 8751 int map; 8752 { 8753 char_u buf[NUMBUFLEN]; 8754 char_u *expr; 8755 listitem_T *li, *nli; 8756 list_T *l = NULL; 8757 dictitem_T *di; 8758 hashtab_T *ht; 8759 hashitem_T *hi; 8760 dict_T *d = NULL; 8761 typval_T save_val; 8762 typval_T save_key; 8763 int rem; 8764 int todo; 8765 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8766 8767 8768 rettv->vval.v_number = 0; 8769 if (argvars[0].v_type == VAR_LIST) 8770 { 8771 if ((l = argvars[0].vval.v_list) == NULL 8772 || (map && tv_check_lock(l->lv_lock, msg))) 8773 return; 8774 } 8775 else if (argvars[0].v_type == VAR_DICT) 8776 { 8777 if ((d = argvars[0].vval.v_dict) == NULL 8778 || (map && tv_check_lock(d->dv_lock, msg))) 8779 return; 8780 } 8781 else 8782 { 8783 EMSG2(_(e_listdictarg), msg); 8784 return; 8785 } 8786 8787 expr = get_tv_string_buf_chk(&argvars[1], buf); 8788 /* On type errors, the preceding call has already displayed an error 8789 * message. Avoid a misleading error message for an empty string that 8790 * was not passed as argument. */ 8791 if (expr != NULL) 8792 { 8793 prepare_vimvar(VV_VAL, &save_val); 8794 expr = skipwhite(expr); 8795 8796 if (argvars[0].v_type == VAR_DICT) 8797 { 8798 prepare_vimvar(VV_KEY, &save_key); 8799 vimvars[VV_KEY].vv_type = VAR_STRING; 8800 8801 ht = &d->dv_hashtab; 8802 hash_lock(ht); 8803 todo = ht->ht_used; 8804 for (hi = ht->ht_array; todo > 0; ++hi) 8805 { 8806 if (!HASHITEM_EMPTY(hi)) 8807 { 8808 --todo; 8809 di = HI2DI(hi); 8810 if (tv_check_lock(di->di_tv.v_lock, msg)) 8811 break; 8812 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8813 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8814 break; 8815 if (!map && rem) 8816 dictitem_remove(d, di); 8817 clear_tv(&vimvars[VV_KEY].vv_tv); 8818 } 8819 } 8820 hash_unlock(ht); 8821 8822 restore_vimvar(VV_KEY, &save_key); 8823 } 8824 else 8825 { 8826 for (li = l->lv_first; li != NULL; li = nli) 8827 { 8828 if (tv_check_lock(li->li_tv.v_lock, msg)) 8829 break; 8830 nli = li->li_next; 8831 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8832 break; 8833 if (!map && rem) 8834 listitem_remove(l, li); 8835 } 8836 } 8837 8838 restore_vimvar(VV_VAL, &save_val); 8839 } 8840 8841 copy_tv(&argvars[0], rettv); 8842 } 8843 8844 static int 8845 filter_map_one(tv, expr, map, remp) 8846 typval_T *tv; 8847 char_u *expr; 8848 int map; 8849 int *remp; 8850 { 8851 typval_T rettv; 8852 char_u *s; 8853 8854 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8855 s = expr; 8856 if (eval1(&s, &rettv, TRUE) == FAIL) 8857 return FAIL; 8858 if (*s != NUL) /* check for trailing chars after expr */ 8859 { 8860 EMSG2(_(e_invexpr2), s); 8861 return FAIL; 8862 } 8863 if (map) 8864 { 8865 /* map(): replace the list item value */ 8866 clear_tv(tv); 8867 rettv.v_lock = 0; 8868 *tv = rettv; 8869 } 8870 else 8871 { 8872 int error = FALSE; 8873 8874 /* filter(): when expr is zero remove the item */ 8875 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8876 clear_tv(&rettv); 8877 /* On type error, nothing has been removed; return FAIL to stop the 8878 * loop. The error message was given by get_tv_number_chk(). */ 8879 if (error) 8880 return FAIL; 8881 } 8882 clear_tv(&vimvars[VV_VAL].vv_tv); 8883 return OK; 8884 } 8885 8886 /* 8887 * "filter()" function 8888 */ 8889 static void 8890 f_filter(argvars, rettv) 8891 typval_T *argvars; 8892 typval_T *rettv; 8893 { 8894 filter_map(argvars, rettv, FALSE); 8895 } 8896 8897 /* 8898 * "finddir({fname}[, {path}[, {count}]])" function 8899 */ 8900 static void 8901 f_finddir(argvars, rettv) 8902 typval_T *argvars; 8903 typval_T *rettv; 8904 { 8905 findfilendir(argvars, rettv, TRUE); 8906 } 8907 8908 /* 8909 * "findfile({fname}[, {path}[, {count}]])" function 8910 */ 8911 static void 8912 f_findfile(argvars, rettv) 8913 typval_T *argvars; 8914 typval_T *rettv; 8915 { 8916 findfilendir(argvars, rettv, FALSE); 8917 } 8918 8919 /* 8920 * "fnamemodify({fname}, {mods})" function 8921 */ 8922 static void 8923 f_fnamemodify(argvars, rettv) 8924 typval_T *argvars; 8925 typval_T *rettv; 8926 { 8927 char_u *fname; 8928 char_u *mods; 8929 int usedlen = 0; 8930 int len; 8931 char_u *fbuf = NULL; 8932 char_u buf[NUMBUFLEN]; 8933 8934 fname = get_tv_string_chk(&argvars[0]); 8935 mods = get_tv_string_buf_chk(&argvars[1], buf); 8936 if (fname == NULL || mods == NULL) 8937 fname = NULL; 8938 else 8939 { 8940 len = (int)STRLEN(fname); 8941 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8942 } 8943 8944 rettv->v_type = VAR_STRING; 8945 if (fname == NULL) 8946 rettv->vval.v_string = NULL; 8947 else 8948 rettv->vval.v_string = vim_strnsave(fname, len); 8949 vim_free(fbuf); 8950 } 8951 8952 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8953 8954 /* 8955 * "foldclosed()" function 8956 */ 8957 static void 8958 foldclosed_both(argvars, rettv, end) 8959 typval_T *argvars; 8960 typval_T *rettv; 8961 int end; 8962 { 8963 #ifdef FEAT_FOLDING 8964 linenr_T lnum; 8965 linenr_T first, last; 8966 8967 lnum = get_tv_lnum(argvars); 8968 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8969 { 8970 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8971 { 8972 if (end) 8973 rettv->vval.v_number = (varnumber_T)last; 8974 else 8975 rettv->vval.v_number = (varnumber_T)first; 8976 return; 8977 } 8978 } 8979 #endif 8980 rettv->vval.v_number = -1; 8981 } 8982 8983 /* 8984 * "foldclosed()" function 8985 */ 8986 static void 8987 f_foldclosed(argvars, rettv) 8988 typval_T *argvars; 8989 typval_T *rettv; 8990 { 8991 foldclosed_both(argvars, rettv, FALSE); 8992 } 8993 8994 /* 8995 * "foldclosedend()" function 8996 */ 8997 static void 8998 f_foldclosedend(argvars, rettv) 8999 typval_T *argvars; 9000 typval_T *rettv; 9001 { 9002 foldclosed_both(argvars, rettv, TRUE); 9003 } 9004 9005 /* 9006 * "foldlevel()" function 9007 */ 9008 static void 9009 f_foldlevel(argvars, rettv) 9010 typval_T *argvars; 9011 typval_T *rettv; 9012 { 9013 #ifdef FEAT_FOLDING 9014 linenr_T lnum; 9015 9016 lnum = get_tv_lnum(argvars); 9017 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9018 rettv->vval.v_number = foldLevel(lnum); 9019 else 9020 #endif 9021 rettv->vval.v_number = 0; 9022 } 9023 9024 /* 9025 * "foldtext()" function 9026 */ 9027 /*ARGSUSED*/ 9028 static void 9029 f_foldtext(argvars, rettv) 9030 typval_T *argvars; 9031 typval_T *rettv; 9032 { 9033 #ifdef FEAT_FOLDING 9034 linenr_T lnum; 9035 char_u *s; 9036 char_u *r; 9037 int len; 9038 char *txt; 9039 #endif 9040 9041 rettv->v_type = VAR_STRING; 9042 rettv->vval.v_string = NULL; 9043 #ifdef FEAT_FOLDING 9044 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9045 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9046 <= curbuf->b_ml.ml_line_count 9047 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9048 { 9049 /* Find first non-empty line in the fold. */ 9050 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9051 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9052 { 9053 if (!linewhite(lnum)) 9054 break; 9055 ++lnum; 9056 } 9057 9058 /* Find interesting text in this line. */ 9059 s = skipwhite(ml_get(lnum)); 9060 /* skip C comment-start */ 9061 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9062 { 9063 s = skipwhite(s + 2); 9064 if (*skipwhite(s) == NUL 9065 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9066 { 9067 s = skipwhite(ml_get(lnum + 1)); 9068 if (*s == '*') 9069 s = skipwhite(s + 1); 9070 } 9071 } 9072 txt = _("+-%s%3ld lines: "); 9073 r = alloc((unsigned)(STRLEN(txt) 9074 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9075 + 20 /* for %3ld */ 9076 + STRLEN(s))); /* concatenated */ 9077 if (r != NULL) 9078 { 9079 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9080 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9081 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9082 len = (int)STRLEN(r); 9083 STRCAT(r, s); 9084 /* remove 'foldmarker' and 'commentstring' */ 9085 foldtext_cleanup(r + len); 9086 rettv->vval.v_string = r; 9087 } 9088 } 9089 #endif 9090 } 9091 9092 /* 9093 * "foldtextresult(lnum)" function 9094 */ 9095 /*ARGSUSED*/ 9096 static void 9097 f_foldtextresult(argvars, rettv) 9098 typval_T *argvars; 9099 typval_T *rettv; 9100 { 9101 #ifdef FEAT_FOLDING 9102 linenr_T lnum; 9103 char_u *text; 9104 char_u buf[51]; 9105 foldinfo_T foldinfo; 9106 int fold_count; 9107 #endif 9108 9109 rettv->v_type = VAR_STRING; 9110 rettv->vval.v_string = NULL; 9111 #ifdef FEAT_FOLDING 9112 lnum = get_tv_lnum(argvars); 9113 /* treat illegal types and illegal string values for {lnum} the same */ 9114 if (lnum < 0) 9115 lnum = 0; 9116 fold_count = foldedCount(curwin, lnum, &foldinfo); 9117 if (fold_count > 0) 9118 { 9119 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9120 &foldinfo, buf); 9121 if (text == buf) 9122 text = vim_strsave(text); 9123 rettv->vval.v_string = text; 9124 } 9125 #endif 9126 } 9127 9128 /* 9129 * "foreground()" function 9130 */ 9131 /*ARGSUSED*/ 9132 static void 9133 f_foreground(argvars, rettv) 9134 typval_T *argvars; 9135 typval_T *rettv; 9136 { 9137 rettv->vval.v_number = 0; 9138 #ifdef FEAT_GUI 9139 if (gui.in_use) 9140 gui_mch_set_foreground(); 9141 #else 9142 # ifdef WIN32 9143 win32_set_foreground(); 9144 # endif 9145 #endif 9146 } 9147 9148 /* 9149 * "function()" function 9150 */ 9151 /*ARGSUSED*/ 9152 static void 9153 f_function(argvars, rettv) 9154 typval_T *argvars; 9155 typval_T *rettv; 9156 { 9157 char_u *s; 9158 9159 rettv->vval.v_number = 0; 9160 s = get_tv_string(&argvars[0]); 9161 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9162 EMSG2(_(e_invarg2), s); 9163 else if (!function_exists(s)) 9164 EMSG2(_("E700: Unknown function: %s"), s); 9165 else 9166 { 9167 rettv->vval.v_string = vim_strsave(s); 9168 rettv->v_type = VAR_FUNC; 9169 } 9170 } 9171 9172 /* 9173 * "garbagecollect()" function 9174 */ 9175 /*ARGSUSED*/ 9176 static void 9177 f_garbagecollect(argvars, rettv) 9178 typval_T *argvars; 9179 typval_T *rettv; 9180 { 9181 garbage_collect(); 9182 } 9183 9184 /* 9185 * "get()" function 9186 */ 9187 static void 9188 f_get(argvars, rettv) 9189 typval_T *argvars; 9190 typval_T *rettv; 9191 { 9192 listitem_T *li; 9193 list_T *l; 9194 dictitem_T *di; 9195 dict_T *d; 9196 typval_T *tv = NULL; 9197 9198 if (argvars[0].v_type == VAR_LIST) 9199 { 9200 if ((l = argvars[0].vval.v_list) != NULL) 9201 { 9202 int error = FALSE; 9203 9204 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9205 if (!error && li != NULL) 9206 tv = &li->li_tv; 9207 } 9208 } 9209 else if (argvars[0].v_type == VAR_DICT) 9210 { 9211 if ((d = argvars[0].vval.v_dict) != NULL) 9212 { 9213 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9214 if (di != NULL) 9215 tv = &di->di_tv; 9216 } 9217 } 9218 else 9219 EMSG2(_(e_listdictarg), "get()"); 9220 9221 if (tv == NULL) 9222 { 9223 if (argvars[2].v_type == VAR_UNKNOWN) 9224 rettv->vval.v_number = 0; 9225 else 9226 copy_tv(&argvars[2], rettv); 9227 } 9228 else 9229 copy_tv(tv, rettv); 9230 } 9231 9232 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9233 9234 /* 9235 * Get line or list of lines from buffer "buf" into "rettv". 9236 * Return a range (from start to end) of lines in rettv from the specified 9237 * buffer. 9238 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9239 */ 9240 static void 9241 get_buffer_lines(buf, start, end, retlist, rettv) 9242 buf_T *buf; 9243 linenr_T start; 9244 linenr_T end; 9245 int retlist; 9246 typval_T *rettv; 9247 { 9248 char_u *p; 9249 list_T *l = NULL; 9250 9251 if (retlist) 9252 { 9253 l = list_alloc(); 9254 if (l == NULL) 9255 return; 9256 9257 rettv->vval.v_list = l; 9258 rettv->v_type = VAR_LIST; 9259 ++l->lv_refcount; 9260 } 9261 else 9262 rettv->vval.v_number = 0; 9263 9264 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9265 return; 9266 9267 if (!retlist) 9268 { 9269 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9270 p = ml_get_buf(buf, start, FALSE); 9271 else 9272 p = (char_u *)""; 9273 9274 rettv->v_type = VAR_STRING; 9275 rettv->vval.v_string = vim_strsave(p); 9276 } 9277 else 9278 { 9279 if (end < start) 9280 return; 9281 9282 if (start < 1) 9283 start = 1; 9284 if (end > buf->b_ml.ml_line_count) 9285 end = buf->b_ml.ml_line_count; 9286 while (start <= end) 9287 if (list_append_string(l, ml_get_buf(buf, start++, FALSE), -1) 9288 == FAIL) 9289 break; 9290 } 9291 } 9292 9293 /* 9294 * "getbufline()" function 9295 */ 9296 static void 9297 f_getbufline(argvars, rettv) 9298 typval_T *argvars; 9299 typval_T *rettv; 9300 { 9301 linenr_T lnum; 9302 linenr_T end; 9303 buf_T *buf; 9304 9305 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9306 ++emsg_off; 9307 buf = get_buf_tv(&argvars[0]); 9308 --emsg_off; 9309 9310 lnum = get_tv_lnum_buf(&argvars[1], buf); 9311 if (argvars[2].v_type == VAR_UNKNOWN) 9312 end = lnum; 9313 else 9314 end = get_tv_lnum_buf(&argvars[2], buf); 9315 9316 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9317 } 9318 9319 /* 9320 * "getbufvar()" function 9321 */ 9322 static void 9323 f_getbufvar(argvars, rettv) 9324 typval_T *argvars; 9325 typval_T *rettv; 9326 { 9327 buf_T *buf; 9328 buf_T *save_curbuf; 9329 char_u *varname; 9330 dictitem_T *v; 9331 9332 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9333 varname = get_tv_string_chk(&argvars[1]); 9334 ++emsg_off; 9335 buf = get_buf_tv(&argvars[0]); 9336 9337 rettv->v_type = VAR_STRING; 9338 rettv->vval.v_string = NULL; 9339 9340 if (buf != NULL && varname != NULL) 9341 { 9342 if (*varname == '&') /* buffer-local-option */ 9343 { 9344 /* set curbuf to be our buf, temporarily */ 9345 save_curbuf = curbuf; 9346 curbuf = buf; 9347 9348 get_option_tv(&varname, rettv, TRUE); 9349 9350 /* restore previous notion of curbuf */ 9351 curbuf = save_curbuf; 9352 } 9353 else 9354 { 9355 if (*varname == NUL) 9356 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9357 * scope prefix before the NUL byte is required by 9358 * find_var_in_ht(). */ 9359 varname = (char_u *)"b:" + 2; 9360 /* look up the variable */ 9361 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9362 if (v != NULL) 9363 copy_tv(&v->di_tv, rettv); 9364 } 9365 } 9366 9367 --emsg_off; 9368 } 9369 9370 /* 9371 * "getchar()" function 9372 */ 9373 static void 9374 f_getchar(argvars, rettv) 9375 typval_T *argvars; 9376 typval_T *rettv; 9377 { 9378 varnumber_T n; 9379 int error = FALSE; 9380 9381 ++no_mapping; 9382 ++allow_keys; 9383 if (argvars[0].v_type == VAR_UNKNOWN) 9384 /* getchar(): blocking wait. */ 9385 n = safe_vgetc(); 9386 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9387 /* getchar(1): only check if char avail */ 9388 n = vpeekc(); 9389 else if (error || vpeekc() == NUL) 9390 /* illegal argument or getchar(0) and no char avail: return zero */ 9391 n = 0; 9392 else 9393 /* getchar(0) and char avail: return char */ 9394 n = safe_vgetc(); 9395 --no_mapping; 9396 --allow_keys; 9397 9398 rettv->vval.v_number = n; 9399 if (IS_SPECIAL(n) || mod_mask != 0) 9400 { 9401 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9402 int i = 0; 9403 9404 /* Turn a special key into three bytes, plus modifier. */ 9405 if (mod_mask != 0) 9406 { 9407 temp[i++] = K_SPECIAL; 9408 temp[i++] = KS_MODIFIER; 9409 temp[i++] = mod_mask; 9410 } 9411 if (IS_SPECIAL(n)) 9412 { 9413 temp[i++] = K_SPECIAL; 9414 temp[i++] = K_SECOND(n); 9415 temp[i++] = K_THIRD(n); 9416 } 9417 #ifdef FEAT_MBYTE 9418 else if (has_mbyte) 9419 i += (*mb_char2bytes)(n, temp + i); 9420 #endif 9421 else 9422 temp[i++] = n; 9423 temp[i++] = NUL; 9424 rettv->v_type = VAR_STRING; 9425 rettv->vval.v_string = vim_strsave(temp); 9426 } 9427 } 9428 9429 /* 9430 * "getcharmod()" function 9431 */ 9432 /*ARGSUSED*/ 9433 static void 9434 f_getcharmod(argvars, rettv) 9435 typval_T *argvars; 9436 typval_T *rettv; 9437 { 9438 rettv->vval.v_number = mod_mask; 9439 } 9440 9441 /* 9442 * "getcmdline()" function 9443 */ 9444 /*ARGSUSED*/ 9445 static void 9446 f_getcmdline(argvars, rettv) 9447 typval_T *argvars; 9448 typval_T *rettv; 9449 { 9450 rettv->v_type = VAR_STRING; 9451 rettv->vval.v_string = get_cmdline_str(); 9452 } 9453 9454 /* 9455 * "getcmdpos()" function 9456 */ 9457 /*ARGSUSED*/ 9458 static void 9459 f_getcmdpos(argvars, rettv) 9460 typval_T *argvars; 9461 typval_T *rettv; 9462 { 9463 rettv->vval.v_number = get_cmdline_pos() + 1; 9464 } 9465 9466 /* 9467 * "getcmdtype()" function 9468 */ 9469 /*ARGSUSED*/ 9470 static void 9471 f_getcmdtype(argvars, rettv) 9472 typval_T *argvars; 9473 typval_T *rettv; 9474 { 9475 rettv->v_type = VAR_STRING; 9476 rettv->vval.v_string = alloc(2); 9477 if (rettv->vval.v_string != NULL) 9478 { 9479 rettv->vval.v_string[0] = get_cmdline_type(); 9480 rettv->vval.v_string[1] = NUL; 9481 } 9482 } 9483 9484 /* 9485 * "getcwd()" function 9486 */ 9487 /*ARGSUSED*/ 9488 static void 9489 f_getcwd(argvars, rettv) 9490 typval_T *argvars; 9491 typval_T *rettv; 9492 { 9493 char_u cwd[MAXPATHL]; 9494 9495 rettv->v_type = VAR_STRING; 9496 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9497 rettv->vval.v_string = NULL; 9498 else 9499 { 9500 rettv->vval.v_string = vim_strsave(cwd); 9501 #ifdef BACKSLASH_IN_FILENAME 9502 if (rettv->vval.v_string != NULL) 9503 slash_adjust(rettv->vval.v_string); 9504 #endif 9505 } 9506 } 9507 9508 /* 9509 * "getfontname()" function 9510 */ 9511 /*ARGSUSED*/ 9512 static void 9513 f_getfontname(argvars, rettv) 9514 typval_T *argvars; 9515 typval_T *rettv; 9516 { 9517 rettv->v_type = VAR_STRING; 9518 rettv->vval.v_string = NULL; 9519 #ifdef FEAT_GUI 9520 if (gui.in_use) 9521 { 9522 GuiFont font; 9523 char_u *name = NULL; 9524 9525 if (argvars[0].v_type == VAR_UNKNOWN) 9526 { 9527 /* Get the "Normal" font. Either the name saved by 9528 * hl_set_font_name() or from the font ID. */ 9529 font = gui.norm_font; 9530 name = hl_get_font_name(); 9531 } 9532 else 9533 { 9534 name = get_tv_string(&argvars[0]); 9535 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9536 return; 9537 font = gui_mch_get_font(name, FALSE); 9538 if (font == NOFONT) 9539 return; /* Invalid font name, return empty string. */ 9540 } 9541 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9542 if (argvars[0].v_type != VAR_UNKNOWN) 9543 gui_mch_free_font(font); 9544 } 9545 #endif 9546 } 9547 9548 /* 9549 * "getfperm({fname})" function 9550 */ 9551 static void 9552 f_getfperm(argvars, rettv) 9553 typval_T *argvars; 9554 typval_T *rettv; 9555 { 9556 char_u *fname; 9557 struct stat st; 9558 char_u *perm = NULL; 9559 char_u flags[] = "rwx"; 9560 int i; 9561 9562 fname = get_tv_string(&argvars[0]); 9563 9564 rettv->v_type = VAR_STRING; 9565 if (mch_stat((char *)fname, &st) >= 0) 9566 { 9567 perm = vim_strsave((char_u *)"---------"); 9568 if (perm != NULL) 9569 { 9570 for (i = 0; i < 9; i++) 9571 { 9572 if (st.st_mode & (1 << (8 - i))) 9573 perm[i] = flags[i % 3]; 9574 } 9575 } 9576 } 9577 rettv->vval.v_string = perm; 9578 } 9579 9580 /* 9581 * "getfsize({fname})" function 9582 */ 9583 static void 9584 f_getfsize(argvars, rettv) 9585 typval_T *argvars; 9586 typval_T *rettv; 9587 { 9588 char_u *fname; 9589 struct stat st; 9590 9591 fname = get_tv_string(&argvars[0]); 9592 9593 rettv->v_type = VAR_NUMBER; 9594 9595 if (mch_stat((char *)fname, &st) >= 0) 9596 { 9597 if (mch_isdir(fname)) 9598 rettv->vval.v_number = 0; 9599 else 9600 rettv->vval.v_number = (varnumber_T)st.st_size; 9601 } 9602 else 9603 rettv->vval.v_number = -1; 9604 } 9605 9606 /* 9607 * "getftime({fname})" function 9608 */ 9609 static void 9610 f_getftime(argvars, rettv) 9611 typval_T *argvars; 9612 typval_T *rettv; 9613 { 9614 char_u *fname; 9615 struct stat st; 9616 9617 fname = get_tv_string(&argvars[0]); 9618 9619 if (mch_stat((char *)fname, &st) >= 0) 9620 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9621 else 9622 rettv->vval.v_number = -1; 9623 } 9624 9625 /* 9626 * "getftype({fname})" function 9627 */ 9628 static void 9629 f_getftype(argvars, rettv) 9630 typval_T *argvars; 9631 typval_T *rettv; 9632 { 9633 char_u *fname; 9634 struct stat st; 9635 char_u *type = NULL; 9636 char *t; 9637 9638 fname = get_tv_string(&argvars[0]); 9639 9640 rettv->v_type = VAR_STRING; 9641 if (mch_lstat((char *)fname, &st) >= 0) 9642 { 9643 #ifdef S_ISREG 9644 if (S_ISREG(st.st_mode)) 9645 t = "file"; 9646 else if (S_ISDIR(st.st_mode)) 9647 t = "dir"; 9648 # ifdef S_ISLNK 9649 else if (S_ISLNK(st.st_mode)) 9650 t = "link"; 9651 # endif 9652 # ifdef S_ISBLK 9653 else if (S_ISBLK(st.st_mode)) 9654 t = "bdev"; 9655 # endif 9656 # ifdef S_ISCHR 9657 else if (S_ISCHR(st.st_mode)) 9658 t = "cdev"; 9659 # endif 9660 # ifdef S_ISFIFO 9661 else if (S_ISFIFO(st.st_mode)) 9662 t = "fifo"; 9663 # endif 9664 # ifdef S_ISSOCK 9665 else if (S_ISSOCK(st.st_mode)) 9666 t = "fifo"; 9667 # endif 9668 else 9669 t = "other"; 9670 #else 9671 # ifdef S_IFMT 9672 switch (st.st_mode & S_IFMT) 9673 { 9674 case S_IFREG: t = "file"; break; 9675 case S_IFDIR: t = "dir"; break; 9676 # ifdef S_IFLNK 9677 case S_IFLNK: t = "link"; break; 9678 # endif 9679 # ifdef S_IFBLK 9680 case S_IFBLK: t = "bdev"; break; 9681 # endif 9682 # ifdef S_IFCHR 9683 case S_IFCHR: t = "cdev"; break; 9684 # endif 9685 # ifdef S_IFIFO 9686 case S_IFIFO: t = "fifo"; break; 9687 # endif 9688 # ifdef S_IFSOCK 9689 case S_IFSOCK: t = "socket"; break; 9690 # endif 9691 default: t = "other"; 9692 } 9693 # else 9694 if (mch_isdir(fname)) 9695 t = "dir"; 9696 else 9697 t = "file"; 9698 # endif 9699 #endif 9700 type = vim_strsave((char_u *)t); 9701 } 9702 rettv->vval.v_string = type; 9703 } 9704 9705 /* 9706 * "getline(lnum, [end])" function 9707 */ 9708 static void 9709 f_getline(argvars, rettv) 9710 typval_T *argvars; 9711 typval_T *rettv; 9712 { 9713 linenr_T lnum; 9714 linenr_T end; 9715 int retlist; 9716 9717 lnum = get_tv_lnum(argvars); 9718 if (argvars[1].v_type == VAR_UNKNOWN) 9719 { 9720 end = 0; 9721 retlist = FALSE; 9722 } 9723 else 9724 { 9725 end = get_tv_lnum(&argvars[1]); 9726 retlist = TRUE; 9727 } 9728 9729 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9730 } 9731 9732 /* 9733 * "getqflist()" function 9734 */ 9735 /*ARGSUSED*/ 9736 static void 9737 f_getqflist(argvars, rettv) 9738 typval_T *argvars; 9739 typval_T *rettv; 9740 { 9741 #ifdef FEAT_QUICKFIX 9742 list_T *l; 9743 #endif 9744 9745 rettv->vval.v_number = FALSE; 9746 #ifdef FEAT_QUICKFIX 9747 l = list_alloc(); 9748 if (l != NULL) 9749 { 9750 rettv->vval.v_list = l; 9751 rettv->v_type = VAR_LIST; 9752 ++l->lv_refcount; 9753 (void)get_errorlist(l); 9754 } 9755 #endif 9756 } 9757 9758 /* 9759 * "getreg()" function 9760 */ 9761 static void 9762 f_getreg(argvars, rettv) 9763 typval_T *argvars; 9764 typval_T *rettv; 9765 { 9766 char_u *strregname; 9767 int regname; 9768 int arg2 = FALSE; 9769 int error = FALSE; 9770 9771 if (argvars[0].v_type != VAR_UNKNOWN) 9772 { 9773 strregname = get_tv_string_chk(&argvars[0]); 9774 error = strregname == NULL; 9775 if (argvars[1].v_type != VAR_UNKNOWN) 9776 arg2 = get_tv_number_chk(&argvars[1], &error); 9777 } 9778 else 9779 strregname = vimvars[VV_REG].vv_str; 9780 regname = (strregname == NULL ? '"' : *strregname); 9781 if (regname == 0) 9782 regname = '"'; 9783 9784 rettv->v_type = VAR_STRING; 9785 rettv->vval.v_string = error ? NULL : 9786 get_reg_contents(regname, TRUE, arg2); 9787 } 9788 9789 /* 9790 * "getregtype()" function 9791 */ 9792 static void 9793 f_getregtype(argvars, rettv) 9794 typval_T *argvars; 9795 typval_T *rettv; 9796 { 9797 char_u *strregname; 9798 int regname; 9799 char_u buf[NUMBUFLEN + 2]; 9800 long reglen = 0; 9801 9802 if (argvars[0].v_type != VAR_UNKNOWN) 9803 { 9804 strregname = get_tv_string_chk(&argvars[0]); 9805 if (strregname == NULL) /* type error; errmsg already given */ 9806 { 9807 rettv->v_type = VAR_STRING; 9808 rettv->vval.v_string = NULL; 9809 return; 9810 } 9811 } 9812 else 9813 /* Default to v:register */ 9814 strregname = vimvars[VV_REG].vv_str; 9815 9816 regname = (strregname == NULL ? '"' : *strregname); 9817 if (regname == 0) 9818 regname = '"'; 9819 9820 buf[0] = NUL; 9821 buf[1] = NUL; 9822 switch (get_reg_type(regname, ®len)) 9823 { 9824 case MLINE: buf[0] = 'V'; break; 9825 case MCHAR: buf[0] = 'v'; break; 9826 #ifdef FEAT_VISUAL 9827 case MBLOCK: 9828 buf[0] = Ctrl_V; 9829 sprintf((char *)buf + 1, "%ld", reglen + 1); 9830 break; 9831 #endif 9832 } 9833 rettv->v_type = VAR_STRING; 9834 rettv->vval.v_string = vim_strsave(buf); 9835 } 9836 9837 /* 9838 * "getwinposx()" function 9839 */ 9840 /*ARGSUSED*/ 9841 static void 9842 f_getwinposx(argvars, rettv) 9843 typval_T *argvars; 9844 typval_T *rettv; 9845 { 9846 rettv->vval.v_number = -1; 9847 #ifdef FEAT_GUI 9848 if (gui.in_use) 9849 { 9850 int x, y; 9851 9852 if (gui_mch_get_winpos(&x, &y) == OK) 9853 rettv->vval.v_number = x; 9854 } 9855 #endif 9856 } 9857 9858 /* 9859 * "getwinposy()" function 9860 */ 9861 /*ARGSUSED*/ 9862 static void 9863 f_getwinposy(argvars, rettv) 9864 typval_T *argvars; 9865 typval_T *rettv; 9866 { 9867 rettv->vval.v_number = -1; 9868 #ifdef FEAT_GUI 9869 if (gui.in_use) 9870 { 9871 int x, y; 9872 9873 if (gui_mch_get_winpos(&x, &y) == OK) 9874 rettv->vval.v_number = y; 9875 } 9876 #endif 9877 } 9878 9879 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9880 9881 static win_T * 9882 find_win_by_nr(vp) 9883 typval_T *vp; 9884 { 9885 #ifdef FEAT_WINDOWS 9886 win_T *wp; 9887 #endif 9888 int nr; 9889 9890 nr = get_tv_number_chk(vp, NULL); 9891 9892 #ifdef FEAT_WINDOWS 9893 if (nr < 0) 9894 return NULL; 9895 if (nr == 0) 9896 return curwin; 9897 9898 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9899 if (--nr <= 0) 9900 break; 9901 return wp; 9902 #else 9903 if (nr == 0 || nr == 1) 9904 return curwin; 9905 return NULL; 9906 #endif 9907 } 9908 9909 /* 9910 * "getwinvar()" function 9911 */ 9912 static void 9913 f_getwinvar(argvars, rettv) 9914 typval_T *argvars; 9915 typval_T *rettv; 9916 { 9917 win_T *win, *oldcurwin; 9918 char_u *varname; 9919 dictitem_T *v; 9920 9921 win = find_win_by_nr(&argvars[0]); 9922 varname = get_tv_string_chk(&argvars[1]); 9923 ++emsg_off; 9924 9925 rettv->v_type = VAR_STRING; 9926 rettv->vval.v_string = NULL; 9927 9928 if (win != NULL && varname != NULL) 9929 { 9930 if (*varname == '&') /* window-local-option */ 9931 { 9932 /* Set curwin to be our win, temporarily. Also set curbuf, so 9933 * that we can get buffer-local options. */ 9934 oldcurwin = curwin; 9935 curwin = win; 9936 curbuf = win->w_buffer; 9937 9938 get_option_tv(&varname, rettv, 1); 9939 9940 /* restore previous notion of curwin */ 9941 curwin = oldcurwin; 9942 curbuf = curwin->w_buffer; 9943 } 9944 else 9945 { 9946 if (*varname == NUL) 9947 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9948 * scope prefix before the NUL byte is required by 9949 * find_var_in_ht(). */ 9950 varname = (char_u *)"w:" + 2; 9951 /* look up the variable */ 9952 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9953 if (v != NULL) 9954 copy_tv(&v->di_tv, rettv); 9955 } 9956 } 9957 9958 --emsg_off; 9959 } 9960 9961 /* 9962 * "glob()" function 9963 */ 9964 static void 9965 f_glob(argvars, rettv) 9966 typval_T *argvars; 9967 typval_T *rettv; 9968 { 9969 expand_T xpc; 9970 9971 ExpandInit(&xpc); 9972 xpc.xp_context = EXPAND_FILES; 9973 rettv->v_type = VAR_STRING; 9974 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9975 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9976 ExpandCleanup(&xpc); 9977 } 9978 9979 /* 9980 * "globpath()" function 9981 */ 9982 static void 9983 f_globpath(argvars, rettv) 9984 typval_T *argvars; 9985 typval_T *rettv; 9986 { 9987 char_u buf1[NUMBUFLEN]; 9988 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9989 9990 rettv->v_type = VAR_STRING; 9991 if (file == NULL) 9992 rettv->vval.v_string = NULL; 9993 else 9994 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9995 } 9996 9997 /* 9998 * "has()" function 9999 */ 10000 static void 10001 f_has(argvars, rettv) 10002 typval_T *argvars; 10003 typval_T *rettv; 10004 { 10005 int i; 10006 char_u *name; 10007 int n = FALSE; 10008 static char *(has_list[]) = 10009 { 10010 #ifdef AMIGA 10011 "amiga", 10012 # ifdef FEAT_ARP 10013 "arp", 10014 # endif 10015 #endif 10016 #ifdef __BEOS__ 10017 "beos", 10018 #endif 10019 #ifdef MSDOS 10020 # ifdef DJGPP 10021 "dos32", 10022 # else 10023 "dos16", 10024 # endif 10025 #endif 10026 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 10027 "mac", 10028 #endif 10029 #if defined(MACOS_X_UNIX) 10030 "macunix", 10031 #endif 10032 #ifdef OS2 10033 "os2", 10034 #endif 10035 #ifdef __QNX__ 10036 "qnx", 10037 #endif 10038 #ifdef RISCOS 10039 "riscos", 10040 #endif 10041 #ifdef UNIX 10042 "unix", 10043 #endif 10044 #ifdef VMS 10045 "vms", 10046 #endif 10047 #ifdef WIN16 10048 "win16", 10049 #endif 10050 #ifdef WIN32 10051 "win32", 10052 #endif 10053 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10054 "win32unix", 10055 #endif 10056 #ifdef WIN64 10057 "win64", 10058 #endif 10059 #ifdef EBCDIC 10060 "ebcdic", 10061 #endif 10062 #ifndef CASE_INSENSITIVE_FILENAME 10063 "fname_case", 10064 #endif 10065 #ifdef FEAT_ARABIC 10066 "arabic", 10067 #endif 10068 #ifdef FEAT_AUTOCMD 10069 "autocmd", 10070 #endif 10071 #ifdef FEAT_BEVAL 10072 "balloon_eval", 10073 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10074 "balloon_multiline", 10075 # endif 10076 #endif 10077 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10078 "builtin_terms", 10079 # ifdef ALL_BUILTIN_TCAPS 10080 "all_builtin_terms", 10081 # endif 10082 #endif 10083 #ifdef FEAT_BYTEOFF 10084 "byte_offset", 10085 #endif 10086 #ifdef FEAT_CINDENT 10087 "cindent", 10088 #endif 10089 #ifdef FEAT_CLIENTSERVER 10090 "clientserver", 10091 #endif 10092 #ifdef FEAT_CLIPBOARD 10093 "clipboard", 10094 #endif 10095 #ifdef FEAT_CMDL_COMPL 10096 "cmdline_compl", 10097 #endif 10098 #ifdef FEAT_CMDHIST 10099 "cmdline_hist", 10100 #endif 10101 #ifdef FEAT_COMMENTS 10102 "comments", 10103 #endif 10104 #ifdef FEAT_CRYPT 10105 "cryptv", 10106 #endif 10107 #ifdef FEAT_CSCOPE 10108 "cscope", 10109 #endif 10110 #ifdef CURSOR_SHAPE 10111 "cursorshape", 10112 #endif 10113 #ifdef DEBUG 10114 "debug", 10115 #endif 10116 #ifdef FEAT_CON_DIALOG 10117 "dialog_con", 10118 #endif 10119 #ifdef FEAT_GUI_DIALOG 10120 "dialog_gui", 10121 #endif 10122 #ifdef FEAT_DIFF 10123 "diff", 10124 #endif 10125 #ifdef FEAT_DIGRAPHS 10126 "digraphs", 10127 #endif 10128 #ifdef FEAT_DND 10129 "dnd", 10130 #endif 10131 #ifdef FEAT_EMACS_TAGS 10132 "emacs_tags", 10133 #endif 10134 "eval", /* always present, of course! */ 10135 #ifdef FEAT_EX_EXTRA 10136 "ex_extra", 10137 #endif 10138 #ifdef FEAT_SEARCH_EXTRA 10139 "extra_search", 10140 #endif 10141 #ifdef FEAT_FKMAP 10142 "farsi", 10143 #endif 10144 #ifdef FEAT_SEARCHPATH 10145 "file_in_path", 10146 #endif 10147 #if defined(UNIX) && !defined(USE_SYSTEM) 10148 "filterpipe", 10149 #endif 10150 #ifdef FEAT_FIND_ID 10151 "find_in_path", 10152 #endif 10153 #ifdef FEAT_FOLDING 10154 "folding", 10155 #endif 10156 #ifdef FEAT_FOOTER 10157 "footer", 10158 #endif 10159 #if !defined(USE_SYSTEM) && defined(UNIX) 10160 "fork", 10161 #endif 10162 #ifdef FEAT_GETTEXT 10163 "gettext", 10164 #endif 10165 #ifdef FEAT_GUI 10166 "gui", 10167 #endif 10168 #ifdef FEAT_GUI_ATHENA 10169 # ifdef FEAT_GUI_NEXTAW 10170 "gui_neXtaw", 10171 # else 10172 "gui_athena", 10173 # endif 10174 #endif 10175 #ifdef FEAT_GUI_KDE 10176 "gui_kde", 10177 #endif 10178 #ifdef FEAT_GUI_GTK 10179 "gui_gtk", 10180 # ifdef HAVE_GTK2 10181 "gui_gtk2", 10182 # endif 10183 #endif 10184 #ifdef FEAT_GUI_MAC 10185 "gui_mac", 10186 #endif 10187 #ifdef FEAT_GUI_MOTIF 10188 "gui_motif", 10189 #endif 10190 #ifdef FEAT_GUI_PHOTON 10191 "gui_photon", 10192 #endif 10193 #ifdef FEAT_GUI_W16 10194 "gui_win16", 10195 #endif 10196 #ifdef FEAT_GUI_W32 10197 "gui_win32", 10198 #endif 10199 #ifdef FEAT_HANGULIN 10200 "hangul_input", 10201 #endif 10202 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10203 "iconv", 10204 #endif 10205 #ifdef FEAT_INS_EXPAND 10206 "insert_expand", 10207 #endif 10208 #ifdef FEAT_JUMPLIST 10209 "jumplist", 10210 #endif 10211 #ifdef FEAT_KEYMAP 10212 "keymap", 10213 #endif 10214 #ifdef FEAT_LANGMAP 10215 "langmap", 10216 #endif 10217 #ifdef FEAT_LIBCALL 10218 "libcall", 10219 #endif 10220 #ifdef FEAT_LINEBREAK 10221 "linebreak", 10222 #endif 10223 #ifdef FEAT_LISP 10224 "lispindent", 10225 #endif 10226 #ifdef FEAT_LISTCMDS 10227 "listcmds", 10228 #endif 10229 #ifdef FEAT_LOCALMAP 10230 "localmap", 10231 #endif 10232 #ifdef FEAT_MENU 10233 "menu", 10234 #endif 10235 #ifdef FEAT_SESSION 10236 "mksession", 10237 #endif 10238 #ifdef FEAT_MODIFY_FNAME 10239 "modify_fname", 10240 #endif 10241 #ifdef FEAT_MOUSE 10242 "mouse", 10243 #endif 10244 #ifdef FEAT_MOUSESHAPE 10245 "mouseshape", 10246 #endif 10247 #if defined(UNIX) || defined(VMS) 10248 # ifdef FEAT_MOUSE_DEC 10249 "mouse_dec", 10250 # endif 10251 # ifdef FEAT_MOUSE_GPM 10252 "mouse_gpm", 10253 # endif 10254 # ifdef FEAT_MOUSE_JSB 10255 "mouse_jsbterm", 10256 # endif 10257 # ifdef FEAT_MOUSE_NET 10258 "mouse_netterm", 10259 # endif 10260 # ifdef FEAT_MOUSE_PTERM 10261 "mouse_pterm", 10262 # endif 10263 # ifdef FEAT_MOUSE_XTERM 10264 "mouse_xterm", 10265 # endif 10266 #endif 10267 #ifdef FEAT_MBYTE 10268 "multi_byte", 10269 #endif 10270 #ifdef FEAT_MBYTE_IME 10271 "multi_byte_ime", 10272 #endif 10273 #ifdef FEAT_MULTI_LANG 10274 "multi_lang", 10275 #endif 10276 #ifdef FEAT_MZSCHEME 10277 #ifndef DYNAMIC_MZSCHEME 10278 "mzscheme", 10279 #endif 10280 #endif 10281 #ifdef FEAT_OLE 10282 "ole", 10283 #endif 10284 #ifdef FEAT_OSFILETYPE 10285 "osfiletype", 10286 #endif 10287 #ifdef FEAT_PATH_EXTRA 10288 "path_extra", 10289 #endif 10290 #ifdef FEAT_PERL 10291 #ifndef DYNAMIC_PERL 10292 "perl", 10293 #endif 10294 #endif 10295 #ifdef FEAT_PYTHON 10296 #ifndef DYNAMIC_PYTHON 10297 "python", 10298 #endif 10299 #endif 10300 #ifdef FEAT_POSTSCRIPT 10301 "postscript", 10302 #endif 10303 #ifdef FEAT_PRINTER 10304 "printer", 10305 #endif 10306 #ifdef FEAT_PROFILE 10307 "profile", 10308 #endif 10309 #ifdef FEAT_QUICKFIX 10310 "quickfix", 10311 #endif 10312 #ifdef FEAT_RIGHTLEFT 10313 "rightleft", 10314 #endif 10315 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10316 "ruby", 10317 #endif 10318 #ifdef FEAT_SCROLLBIND 10319 "scrollbind", 10320 #endif 10321 #ifdef FEAT_CMDL_INFO 10322 "showcmd", 10323 "cmdline_info", 10324 #endif 10325 #ifdef FEAT_SIGNS 10326 "signs", 10327 #endif 10328 #ifdef FEAT_SMARTINDENT 10329 "smartindent", 10330 #endif 10331 #ifdef FEAT_SNIFF 10332 "sniff", 10333 #endif 10334 #ifdef FEAT_STL_OPT 10335 "statusline", 10336 #endif 10337 #ifdef FEAT_SUN_WORKSHOP 10338 "sun_workshop", 10339 #endif 10340 #ifdef FEAT_NETBEANS_INTG 10341 "netbeans_intg", 10342 #endif 10343 #ifdef FEAT_SYN_HL 10344 "spell", 10345 #endif 10346 #ifdef FEAT_SYN_HL 10347 "syntax", 10348 #endif 10349 #if defined(USE_SYSTEM) || !defined(UNIX) 10350 "system", 10351 #endif 10352 #ifdef FEAT_TAG_BINS 10353 "tag_binary", 10354 #endif 10355 #ifdef FEAT_TAG_OLDSTATIC 10356 "tag_old_static", 10357 #endif 10358 #ifdef FEAT_TAG_ANYWHITE 10359 "tag_any_white", 10360 #endif 10361 #ifdef FEAT_TCL 10362 # ifndef DYNAMIC_TCL 10363 "tcl", 10364 # endif 10365 #endif 10366 #ifdef TERMINFO 10367 "terminfo", 10368 #endif 10369 #ifdef FEAT_TERMRESPONSE 10370 "termresponse", 10371 #endif 10372 #ifdef FEAT_TEXTOBJ 10373 "textobjects", 10374 #endif 10375 #ifdef HAVE_TGETENT 10376 "tgetent", 10377 #endif 10378 #ifdef FEAT_TITLE 10379 "title", 10380 #endif 10381 #ifdef FEAT_TOOLBAR 10382 "toolbar", 10383 #endif 10384 #ifdef FEAT_USR_CMDS 10385 "user-commands", /* was accidentally included in 5.4 */ 10386 "user_commands", 10387 #endif 10388 #ifdef FEAT_VIMINFO 10389 "viminfo", 10390 #endif 10391 #ifdef FEAT_VERTSPLIT 10392 "vertsplit", 10393 #endif 10394 #ifdef FEAT_VIRTUALEDIT 10395 "virtualedit", 10396 #endif 10397 #ifdef FEAT_VISUAL 10398 "visual", 10399 #endif 10400 #ifdef FEAT_VISUALEXTRA 10401 "visualextra", 10402 #endif 10403 #ifdef FEAT_VREPLACE 10404 "vreplace", 10405 #endif 10406 #ifdef FEAT_WILDIGN 10407 "wildignore", 10408 #endif 10409 #ifdef FEAT_WILDMENU 10410 "wildmenu", 10411 #endif 10412 #ifdef FEAT_WINDOWS 10413 "windows", 10414 #endif 10415 #ifdef FEAT_WAK 10416 "winaltkeys", 10417 #endif 10418 #ifdef FEAT_WRITEBACKUP 10419 "writebackup", 10420 #endif 10421 #ifdef FEAT_XIM 10422 "xim", 10423 #endif 10424 #ifdef FEAT_XFONTSET 10425 "xfontset", 10426 #endif 10427 #ifdef USE_XSMP 10428 "xsmp", 10429 #endif 10430 #ifdef USE_XSMP_INTERACT 10431 "xsmp_interact", 10432 #endif 10433 #ifdef FEAT_XCLIPBOARD 10434 "xterm_clipboard", 10435 #endif 10436 #ifdef FEAT_XTERM_SAVE 10437 "xterm_save", 10438 #endif 10439 #if defined(UNIX) && defined(FEAT_X11) 10440 "X11", 10441 #endif 10442 NULL 10443 }; 10444 10445 name = get_tv_string(&argvars[0]); 10446 for (i = 0; has_list[i] != NULL; ++i) 10447 if (STRICMP(name, has_list[i]) == 0) 10448 { 10449 n = TRUE; 10450 break; 10451 } 10452 10453 if (n == FALSE) 10454 { 10455 if (STRNICMP(name, "patch", 5) == 0) 10456 n = has_patch(atoi((char *)name + 5)); 10457 else if (STRICMP(name, "vim_starting") == 0) 10458 n = (starting != 0); 10459 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10460 else if (STRICMP(name, "balloon_multiline") == 0) 10461 n = multiline_balloon_available(); 10462 #endif 10463 #ifdef DYNAMIC_TCL 10464 else if (STRICMP(name, "tcl") == 0) 10465 n = tcl_enabled(FALSE); 10466 #endif 10467 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10468 else if (STRICMP(name, "iconv") == 0) 10469 n = iconv_enabled(FALSE); 10470 #endif 10471 #ifdef DYNAMIC_MZSCHEME 10472 else if (STRICMP(name, "mzscheme") == 0) 10473 n = mzscheme_enabled(FALSE); 10474 #endif 10475 #ifdef DYNAMIC_RUBY 10476 else if (STRICMP(name, "ruby") == 0) 10477 n = ruby_enabled(FALSE); 10478 #endif 10479 #ifdef DYNAMIC_PYTHON 10480 else if (STRICMP(name, "python") == 0) 10481 n = python_enabled(FALSE); 10482 #endif 10483 #ifdef DYNAMIC_PERL 10484 else if (STRICMP(name, "perl") == 0) 10485 n = perl_enabled(FALSE); 10486 #endif 10487 #ifdef FEAT_GUI 10488 else if (STRICMP(name, "gui_running") == 0) 10489 n = (gui.in_use || gui.starting); 10490 # ifdef FEAT_GUI_W32 10491 else if (STRICMP(name, "gui_win32s") == 0) 10492 n = gui_is_win32s(); 10493 # endif 10494 # ifdef FEAT_BROWSE 10495 else if (STRICMP(name, "browse") == 0) 10496 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10497 # endif 10498 #endif 10499 #ifdef FEAT_SYN_HL 10500 else if (STRICMP(name, "syntax_items") == 0) 10501 n = syntax_present(curbuf); 10502 #endif 10503 #if defined(WIN3264) 10504 else if (STRICMP(name, "win95") == 0) 10505 n = mch_windows95(); 10506 #endif 10507 #ifdef FEAT_NETBEANS_INTG 10508 else if (STRICMP(name, "netbeans_enabled") == 0) 10509 n = usingNetbeans; 10510 #endif 10511 } 10512 10513 rettv->vval.v_number = n; 10514 } 10515 10516 /* 10517 * "has_key()" function 10518 */ 10519 static void 10520 f_has_key(argvars, rettv) 10521 typval_T *argvars; 10522 typval_T *rettv; 10523 { 10524 rettv->vval.v_number = 0; 10525 if (argvars[0].v_type != VAR_DICT) 10526 { 10527 EMSG(_(e_dictreq)); 10528 return; 10529 } 10530 if (argvars[0].vval.v_dict == NULL) 10531 return; 10532 10533 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10534 get_tv_string(&argvars[1]), -1) != NULL; 10535 } 10536 10537 /* 10538 * "hasmapto()" function 10539 */ 10540 static void 10541 f_hasmapto(argvars, rettv) 10542 typval_T *argvars; 10543 typval_T *rettv; 10544 { 10545 char_u *name; 10546 char_u *mode; 10547 char_u buf[NUMBUFLEN]; 10548 10549 name = get_tv_string(&argvars[0]); 10550 if (argvars[1].v_type == VAR_UNKNOWN) 10551 mode = (char_u *)"nvo"; 10552 else 10553 mode = get_tv_string_buf(&argvars[1], buf); 10554 10555 if (map_to_exists(name, mode)) 10556 rettv->vval.v_number = TRUE; 10557 else 10558 rettv->vval.v_number = FALSE; 10559 } 10560 10561 /* 10562 * "histadd()" function 10563 */ 10564 /*ARGSUSED*/ 10565 static void 10566 f_histadd(argvars, rettv) 10567 typval_T *argvars; 10568 typval_T *rettv; 10569 { 10570 #ifdef FEAT_CMDHIST 10571 int histype; 10572 char_u *str; 10573 char_u buf[NUMBUFLEN]; 10574 #endif 10575 10576 rettv->vval.v_number = FALSE; 10577 if (check_restricted() || check_secure()) 10578 return; 10579 #ifdef FEAT_CMDHIST 10580 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10581 histype = str != NULL ? get_histtype(str) : -1; 10582 if (histype >= 0) 10583 { 10584 str = get_tv_string_buf(&argvars[1], buf); 10585 if (*str != NUL) 10586 { 10587 add_to_history(histype, str, FALSE, NUL); 10588 rettv->vval.v_number = TRUE; 10589 return; 10590 } 10591 } 10592 #endif 10593 } 10594 10595 /* 10596 * "histdel()" function 10597 */ 10598 /*ARGSUSED*/ 10599 static void 10600 f_histdel(argvars, rettv) 10601 typval_T *argvars; 10602 typval_T *rettv; 10603 { 10604 #ifdef FEAT_CMDHIST 10605 int n; 10606 char_u buf[NUMBUFLEN]; 10607 char_u *str; 10608 10609 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10610 if (str == NULL) 10611 n = 0; 10612 else if (argvars[1].v_type == VAR_UNKNOWN) 10613 /* only one argument: clear entire history */ 10614 n = clr_history(get_histtype(str)); 10615 else if (argvars[1].v_type == VAR_NUMBER) 10616 /* index given: remove that entry */ 10617 n = del_history_idx(get_histtype(str), 10618 (int)get_tv_number(&argvars[1])); 10619 else 10620 /* string given: remove all matching entries */ 10621 n = del_history_entry(get_histtype(str), 10622 get_tv_string_buf(&argvars[1], buf)); 10623 rettv->vval.v_number = n; 10624 #else 10625 rettv->vval.v_number = 0; 10626 #endif 10627 } 10628 10629 /* 10630 * "histget()" function 10631 */ 10632 /*ARGSUSED*/ 10633 static void 10634 f_histget(argvars, rettv) 10635 typval_T *argvars; 10636 typval_T *rettv; 10637 { 10638 #ifdef FEAT_CMDHIST 10639 int type; 10640 int idx; 10641 char_u *str; 10642 10643 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10644 if (str == NULL) 10645 rettv->vval.v_string = NULL; 10646 else 10647 { 10648 type = get_histtype(str); 10649 if (argvars[1].v_type == VAR_UNKNOWN) 10650 idx = get_history_idx(type); 10651 else 10652 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10653 /* -1 on type error */ 10654 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10655 } 10656 #else 10657 rettv->vval.v_string = NULL; 10658 #endif 10659 rettv->v_type = VAR_STRING; 10660 } 10661 10662 /* 10663 * "histnr()" function 10664 */ 10665 /*ARGSUSED*/ 10666 static void 10667 f_histnr(argvars, rettv) 10668 typval_T *argvars; 10669 typval_T *rettv; 10670 { 10671 int i; 10672 10673 #ifdef FEAT_CMDHIST 10674 char_u *history = get_tv_string_chk(&argvars[0]); 10675 10676 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10677 if (i >= HIST_CMD && i < HIST_COUNT) 10678 i = get_history_idx(i); 10679 else 10680 #endif 10681 i = -1; 10682 rettv->vval.v_number = i; 10683 } 10684 10685 /* 10686 * "highlightID(name)" function 10687 */ 10688 static void 10689 f_hlID(argvars, rettv) 10690 typval_T *argvars; 10691 typval_T *rettv; 10692 { 10693 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10694 } 10695 10696 /* 10697 * "highlight_exists()" function 10698 */ 10699 static void 10700 f_hlexists(argvars, rettv) 10701 typval_T *argvars; 10702 typval_T *rettv; 10703 { 10704 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10705 } 10706 10707 /* 10708 * "hostname()" function 10709 */ 10710 /*ARGSUSED*/ 10711 static void 10712 f_hostname(argvars, rettv) 10713 typval_T *argvars; 10714 typval_T *rettv; 10715 { 10716 char_u hostname[256]; 10717 10718 mch_get_host_name(hostname, 256); 10719 rettv->v_type = VAR_STRING; 10720 rettv->vval.v_string = vim_strsave(hostname); 10721 } 10722 10723 /* 10724 * iconv() function 10725 */ 10726 /*ARGSUSED*/ 10727 static void 10728 f_iconv(argvars, rettv) 10729 typval_T *argvars; 10730 typval_T *rettv; 10731 { 10732 #ifdef FEAT_MBYTE 10733 char_u buf1[NUMBUFLEN]; 10734 char_u buf2[NUMBUFLEN]; 10735 char_u *from, *to, *str; 10736 vimconv_T vimconv; 10737 #endif 10738 10739 rettv->v_type = VAR_STRING; 10740 rettv->vval.v_string = NULL; 10741 10742 #ifdef FEAT_MBYTE 10743 str = get_tv_string(&argvars[0]); 10744 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10745 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10746 vimconv.vc_type = CONV_NONE; 10747 convert_setup(&vimconv, from, to); 10748 10749 /* If the encodings are equal, no conversion needed. */ 10750 if (vimconv.vc_type == CONV_NONE) 10751 rettv->vval.v_string = vim_strsave(str); 10752 else 10753 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10754 10755 convert_setup(&vimconv, NULL, NULL); 10756 vim_free(from); 10757 vim_free(to); 10758 #endif 10759 } 10760 10761 /* 10762 * "indent()" function 10763 */ 10764 static void 10765 f_indent(argvars, rettv) 10766 typval_T *argvars; 10767 typval_T *rettv; 10768 { 10769 linenr_T lnum; 10770 10771 lnum = get_tv_lnum(argvars); 10772 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10773 rettv->vval.v_number = get_indent_lnum(lnum); 10774 else 10775 rettv->vval.v_number = -1; 10776 } 10777 10778 /* 10779 * "index()" function 10780 */ 10781 static void 10782 f_index(argvars, rettv) 10783 typval_T *argvars; 10784 typval_T *rettv; 10785 { 10786 list_T *l; 10787 listitem_T *item; 10788 long idx = 0; 10789 int ic = FALSE; 10790 10791 rettv->vval.v_number = -1; 10792 if (argvars[0].v_type != VAR_LIST) 10793 { 10794 EMSG(_(e_listreq)); 10795 return; 10796 } 10797 l = argvars[0].vval.v_list; 10798 if (l != NULL) 10799 { 10800 item = l->lv_first; 10801 if (argvars[2].v_type != VAR_UNKNOWN) 10802 { 10803 int error = FALSE; 10804 10805 /* Start at specified item. Use the cached index that list_find() 10806 * sets, so that a negative number also works. */ 10807 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10808 idx = l->lv_idx; 10809 if (argvars[3].v_type != VAR_UNKNOWN) 10810 ic = get_tv_number_chk(&argvars[3], &error); 10811 if (error) 10812 item = NULL; 10813 } 10814 10815 for ( ; item != NULL; item = item->li_next, ++idx) 10816 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10817 { 10818 rettv->vval.v_number = idx; 10819 break; 10820 } 10821 } 10822 } 10823 10824 static int inputsecret_flag = 0; 10825 10826 /* 10827 * "input()" function 10828 * Also handles inputsecret() when inputsecret is set. 10829 */ 10830 static void 10831 f_input(argvars, rettv) 10832 typval_T *argvars; 10833 typval_T *rettv; 10834 { 10835 char_u *prompt = get_tv_string_chk(&argvars[0]); 10836 char_u *p = NULL; 10837 int c; 10838 char_u buf[NUMBUFLEN]; 10839 int cmd_silent_save = cmd_silent; 10840 char_u *defstr = (char_u *)""; 10841 int xp_type = EXPAND_NOTHING; 10842 char_u *xp_arg = NULL; 10843 10844 rettv->v_type = VAR_STRING; 10845 10846 #ifdef NO_CONSOLE_INPUT 10847 /* While starting up, there is no place to enter text. */ 10848 if (no_console_input()) 10849 { 10850 rettv->vval.v_string = NULL; 10851 return; 10852 } 10853 #endif 10854 10855 cmd_silent = FALSE; /* Want to see the prompt. */ 10856 if (prompt != NULL) 10857 { 10858 /* Only the part of the message after the last NL is considered as 10859 * prompt for the command line */ 10860 p = vim_strrchr(prompt, '\n'); 10861 if (p == NULL) 10862 p = prompt; 10863 else 10864 { 10865 ++p; 10866 c = *p; 10867 *p = NUL; 10868 msg_start(); 10869 msg_clr_eos(); 10870 msg_puts_attr(prompt, echo_attr); 10871 msg_didout = FALSE; 10872 msg_starthere(); 10873 *p = c; 10874 } 10875 cmdline_row = msg_row; 10876 10877 if (argvars[1].v_type != VAR_UNKNOWN) 10878 { 10879 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10880 if (defstr != NULL) 10881 stuffReadbuffSpec(defstr); 10882 10883 if (argvars[2].v_type != VAR_UNKNOWN) 10884 { 10885 char_u *xp_name; 10886 int xp_namelen; 10887 long argt; 10888 10889 rettv->vval.v_string = NULL; 10890 10891 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 10892 if (xp_name == NULL) 10893 return; 10894 10895 xp_namelen = STRLEN(xp_name); 10896 10897 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 10898 &xp_arg) == FAIL) 10899 return; 10900 } 10901 } 10902 10903 if (defstr != NULL) 10904 rettv->vval.v_string = 10905 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 10906 xp_type, xp_arg); 10907 10908 vim_free(xp_arg); 10909 10910 /* since the user typed this, no need to wait for return */ 10911 need_wait_return = FALSE; 10912 msg_didout = FALSE; 10913 } 10914 cmd_silent = cmd_silent_save; 10915 } 10916 10917 /* 10918 * "inputdialog()" function 10919 */ 10920 static void 10921 f_inputdialog(argvars, rettv) 10922 typval_T *argvars; 10923 typval_T *rettv; 10924 { 10925 #if defined(FEAT_GUI_TEXTDIALOG) 10926 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10927 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10928 { 10929 char_u *message; 10930 char_u buf[NUMBUFLEN]; 10931 char_u *defstr = (char_u *)""; 10932 10933 message = get_tv_string_chk(&argvars[0]); 10934 if (argvars[1].v_type != VAR_UNKNOWN 10935 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10936 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10937 else 10938 IObuff[0] = NUL; 10939 if (message != NULL && defstr != NULL 10940 && do_dialog(VIM_QUESTION, NULL, message, 10941 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10942 rettv->vval.v_string = vim_strsave(IObuff); 10943 else 10944 { 10945 if (message != NULL && defstr != NULL 10946 && argvars[1].v_type != VAR_UNKNOWN 10947 && argvars[2].v_type != VAR_UNKNOWN) 10948 rettv->vval.v_string = vim_strsave( 10949 get_tv_string_buf(&argvars[2], buf)); 10950 else 10951 rettv->vval.v_string = NULL; 10952 } 10953 rettv->v_type = VAR_STRING; 10954 } 10955 else 10956 #endif 10957 f_input(argvars, rettv); 10958 } 10959 10960 /* 10961 * "inputlist()" function 10962 */ 10963 static void 10964 f_inputlist(argvars, rettv) 10965 typval_T *argvars; 10966 typval_T *rettv; 10967 { 10968 listitem_T *li; 10969 int selected; 10970 int mouse_used; 10971 10972 rettv->vval.v_number = 0; 10973 #ifdef NO_CONSOLE_INPUT 10974 /* While starting up, there is no place to enter text. */ 10975 if (no_console_input()) 10976 return; 10977 #endif 10978 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 10979 { 10980 EMSG2(_(e_listarg), "inputlist()"); 10981 return; 10982 } 10983 10984 msg_start(); 10985 lines_left = Rows; /* avoid more prompt */ 10986 msg_scroll = TRUE; 10987 msg_clr_eos(); 10988 10989 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 10990 { 10991 msg_puts(get_tv_string(&li->li_tv)); 10992 msg_putchar('\n'); 10993 } 10994 10995 /* Ask for choice. */ 10996 selected = prompt_for_number(&mouse_used); 10997 if (mouse_used) 10998 selected -= lines_left; 10999 11000 rettv->vval.v_number = selected; 11001 } 11002 11003 11004 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 11005 11006 /* 11007 * "inputrestore()" function 11008 */ 11009 /*ARGSUSED*/ 11010 static void 11011 f_inputrestore(argvars, rettv) 11012 typval_T *argvars; 11013 typval_T *rettv; 11014 { 11015 if (ga_userinput.ga_len > 0) 11016 { 11017 --ga_userinput.ga_len; 11018 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 11019 + ga_userinput.ga_len); 11020 rettv->vval.v_number = 0; /* OK */ 11021 } 11022 else if (p_verbose > 1) 11023 { 11024 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11025 rettv->vval.v_number = 1; /* Failed */ 11026 } 11027 } 11028 11029 /* 11030 * "inputsave()" function 11031 */ 11032 /*ARGSUSED*/ 11033 static void 11034 f_inputsave(argvars, rettv) 11035 typval_T *argvars; 11036 typval_T *rettv; 11037 { 11038 /* Add an entry to the stack of typehead storage. */ 11039 if (ga_grow(&ga_userinput, 1) == OK) 11040 { 11041 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11042 + ga_userinput.ga_len); 11043 ++ga_userinput.ga_len; 11044 rettv->vval.v_number = 0; /* OK */ 11045 } 11046 else 11047 rettv->vval.v_number = 1; /* Failed */ 11048 } 11049 11050 /* 11051 * "inputsecret()" function 11052 */ 11053 static void 11054 f_inputsecret(argvars, rettv) 11055 typval_T *argvars; 11056 typval_T *rettv; 11057 { 11058 ++cmdline_star; 11059 ++inputsecret_flag; 11060 f_input(argvars, rettv); 11061 --cmdline_star; 11062 --inputsecret_flag; 11063 } 11064 11065 /* 11066 * "insert()" function 11067 */ 11068 static void 11069 f_insert(argvars, rettv) 11070 typval_T *argvars; 11071 typval_T *rettv; 11072 { 11073 long before = 0; 11074 listitem_T *item; 11075 list_T *l; 11076 int error = FALSE; 11077 11078 rettv->vval.v_number = 0; 11079 if (argvars[0].v_type != VAR_LIST) 11080 EMSG2(_(e_listarg), "insert()"); 11081 else if ((l = argvars[0].vval.v_list) != NULL 11082 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11083 { 11084 if (argvars[2].v_type != VAR_UNKNOWN) 11085 before = get_tv_number_chk(&argvars[2], &error); 11086 if (error) 11087 return; /* type error; errmsg already given */ 11088 11089 if (before == l->lv_len) 11090 item = NULL; 11091 else 11092 { 11093 item = list_find(l, before); 11094 if (item == NULL) 11095 { 11096 EMSGN(_(e_listidx), before); 11097 l = NULL; 11098 } 11099 } 11100 if (l != NULL) 11101 { 11102 list_insert_tv(l, &argvars[1], item); 11103 copy_tv(&argvars[0], rettv); 11104 } 11105 } 11106 } 11107 11108 /* 11109 * "isdirectory()" function 11110 */ 11111 static void 11112 f_isdirectory(argvars, rettv) 11113 typval_T *argvars; 11114 typval_T *rettv; 11115 { 11116 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11117 } 11118 11119 /* 11120 * "islocked()" function 11121 */ 11122 static void 11123 f_islocked(argvars, rettv) 11124 typval_T *argvars; 11125 typval_T *rettv; 11126 { 11127 lval_T lv; 11128 char_u *end; 11129 dictitem_T *di; 11130 11131 rettv->vval.v_number = -1; 11132 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11133 FNE_CHECK_START); 11134 if (end != NULL && lv.ll_name != NULL) 11135 { 11136 if (*end != NUL) 11137 EMSG(_(e_trailing)); 11138 else 11139 { 11140 if (lv.ll_tv == NULL) 11141 { 11142 if (check_changedtick(lv.ll_name)) 11143 rettv->vval.v_number = 1; /* always locked */ 11144 else 11145 { 11146 di = find_var(lv.ll_name, NULL); 11147 if (di != NULL) 11148 { 11149 /* Consider a variable locked when: 11150 * 1. the variable itself is locked 11151 * 2. the value of the variable is locked. 11152 * 3. the List or Dict value is locked. 11153 */ 11154 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11155 || tv_islocked(&di->di_tv)); 11156 } 11157 } 11158 } 11159 else if (lv.ll_range) 11160 EMSG(_("E745: Range not allowed")); 11161 else if (lv.ll_newkey != NULL) 11162 EMSG2(_(e_dictkey), lv.ll_newkey); 11163 else if (lv.ll_list != NULL) 11164 /* List item. */ 11165 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11166 else 11167 /* Dictionary item. */ 11168 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11169 } 11170 } 11171 11172 clear_lval(&lv); 11173 } 11174 11175 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11176 11177 /* 11178 * Turn a dict into a list: 11179 * "what" == 0: list of keys 11180 * "what" == 1: list of values 11181 * "what" == 2: list of items 11182 */ 11183 static void 11184 dict_list(argvars, rettv, what) 11185 typval_T *argvars; 11186 typval_T *rettv; 11187 int what; 11188 { 11189 list_T *l; 11190 list_T *l2; 11191 dictitem_T *di; 11192 hashitem_T *hi; 11193 listitem_T *li; 11194 listitem_T *li2; 11195 dict_T *d; 11196 int todo; 11197 11198 rettv->vval.v_number = 0; 11199 if (argvars[0].v_type != VAR_DICT) 11200 { 11201 EMSG(_(e_dictreq)); 11202 return; 11203 } 11204 if ((d = argvars[0].vval.v_dict) == NULL) 11205 return; 11206 11207 l = list_alloc(); 11208 if (l == NULL) 11209 return; 11210 rettv->v_type = VAR_LIST; 11211 rettv->vval.v_list = l; 11212 ++l->lv_refcount; 11213 11214 todo = d->dv_hashtab.ht_used; 11215 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11216 { 11217 if (!HASHITEM_EMPTY(hi)) 11218 { 11219 --todo; 11220 di = HI2DI(hi); 11221 11222 li = listitem_alloc(); 11223 if (li == NULL) 11224 break; 11225 list_append(l, li); 11226 11227 if (what == 0) 11228 { 11229 /* keys() */ 11230 li->li_tv.v_type = VAR_STRING; 11231 li->li_tv.v_lock = 0; 11232 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11233 } 11234 else if (what == 1) 11235 { 11236 /* values() */ 11237 copy_tv(&di->di_tv, &li->li_tv); 11238 } 11239 else 11240 { 11241 /* items() */ 11242 l2 = list_alloc(); 11243 li->li_tv.v_type = VAR_LIST; 11244 li->li_tv.v_lock = 0; 11245 li->li_tv.vval.v_list = l2; 11246 if (l2 == NULL) 11247 break; 11248 ++l2->lv_refcount; 11249 11250 li2 = listitem_alloc(); 11251 if (li2 == NULL) 11252 break; 11253 list_append(l2, li2); 11254 li2->li_tv.v_type = VAR_STRING; 11255 li2->li_tv.v_lock = 0; 11256 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11257 11258 li2 = listitem_alloc(); 11259 if (li2 == NULL) 11260 break; 11261 list_append(l2, li2); 11262 copy_tv(&di->di_tv, &li2->li_tv); 11263 } 11264 } 11265 } 11266 } 11267 11268 /* 11269 * "items(dict)" function 11270 */ 11271 static void 11272 f_items(argvars, rettv) 11273 typval_T *argvars; 11274 typval_T *rettv; 11275 { 11276 dict_list(argvars, rettv, 2); 11277 } 11278 11279 /* 11280 * "join()" function 11281 */ 11282 static void 11283 f_join(argvars, rettv) 11284 typval_T *argvars; 11285 typval_T *rettv; 11286 { 11287 garray_T ga; 11288 char_u *sep; 11289 11290 rettv->vval.v_number = 0; 11291 if (argvars[0].v_type != VAR_LIST) 11292 { 11293 EMSG(_(e_listreq)); 11294 return; 11295 } 11296 if (argvars[0].vval.v_list == NULL) 11297 return; 11298 if (argvars[1].v_type == VAR_UNKNOWN) 11299 sep = (char_u *)" "; 11300 else 11301 sep = get_tv_string_chk(&argvars[1]); 11302 11303 rettv->v_type = VAR_STRING; 11304 11305 if (sep != NULL) 11306 { 11307 ga_init2(&ga, (int)sizeof(char), 80); 11308 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11309 ga_append(&ga, NUL); 11310 rettv->vval.v_string = (char_u *)ga.ga_data; 11311 } 11312 else 11313 rettv->vval.v_string = NULL; 11314 } 11315 11316 /* 11317 * "keys()" function 11318 */ 11319 static void 11320 f_keys(argvars, rettv) 11321 typval_T *argvars; 11322 typval_T *rettv; 11323 { 11324 dict_list(argvars, rettv, 0); 11325 } 11326 11327 /* 11328 * "last_buffer_nr()" function. 11329 */ 11330 /*ARGSUSED*/ 11331 static void 11332 f_last_buffer_nr(argvars, rettv) 11333 typval_T *argvars; 11334 typval_T *rettv; 11335 { 11336 int n = 0; 11337 buf_T *buf; 11338 11339 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11340 if (n < buf->b_fnum) 11341 n = buf->b_fnum; 11342 11343 rettv->vval.v_number = n; 11344 } 11345 11346 /* 11347 * "len()" function 11348 */ 11349 static void 11350 f_len(argvars, rettv) 11351 typval_T *argvars; 11352 typval_T *rettv; 11353 { 11354 switch (argvars[0].v_type) 11355 { 11356 case VAR_STRING: 11357 case VAR_NUMBER: 11358 rettv->vval.v_number = (varnumber_T)STRLEN( 11359 get_tv_string(&argvars[0])); 11360 break; 11361 case VAR_LIST: 11362 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11363 break; 11364 case VAR_DICT: 11365 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11366 break; 11367 default: 11368 EMSG(_("E701: Invalid type for len()")); 11369 break; 11370 } 11371 } 11372 11373 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11374 11375 static void 11376 libcall_common(argvars, rettv, type) 11377 typval_T *argvars; 11378 typval_T *rettv; 11379 int type; 11380 { 11381 #ifdef FEAT_LIBCALL 11382 char_u *string_in; 11383 char_u **string_result; 11384 int nr_result; 11385 #endif 11386 11387 rettv->v_type = type; 11388 if (type == VAR_NUMBER) 11389 rettv->vval.v_number = 0; 11390 else 11391 rettv->vval.v_string = NULL; 11392 11393 if (check_restricted() || check_secure()) 11394 return; 11395 11396 #ifdef FEAT_LIBCALL 11397 /* The first two args must be strings, otherwise its meaningless */ 11398 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11399 { 11400 string_in = NULL; 11401 if (argvars[2].v_type == VAR_STRING) 11402 string_in = argvars[2].vval.v_string; 11403 if (type == VAR_NUMBER) 11404 string_result = NULL; 11405 else 11406 string_result = &rettv->vval.v_string; 11407 if (mch_libcall(argvars[0].vval.v_string, 11408 argvars[1].vval.v_string, 11409 string_in, 11410 argvars[2].vval.v_number, 11411 string_result, 11412 &nr_result) == OK 11413 && type == VAR_NUMBER) 11414 rettv->vval.v_number = nr_result; 11415 } 11416 #endif 11417 } 11418 11419 /* 11420 * "libcall()" function 11421 */ 11422 static void 11423 f_libcall(argvars, rettv) 11424 typval_T *argvars; 11425 typval_T *rettv; 11426 { 11427 libcall_common(argvars, rettv, VAR_STRING); 11428 } 11429 11430 /* 11431 * "libcallnr()" function 11432 */ 11433 static void 11434 f_libcallnr(argvars, rettv) 11435 typval_T *argvars; 11436 typval_T *rettv; 11437 { 11438 libcall_common(argvars, rettv, VAR_NUMBER); 11439 } 11440 11441 /* 11442 * "line(string)" function 11443 */ 11444 static void 11445 f_line(argvars, rettv) 11446 typval_T *argvars; 11447 typval_T *rettv; 11448 { 11449 linenr_T lnum = 0; 11450 pos_T *fp; 11451 11452 fp = var2fpos(&argvars[0], TRUE); 11453 if (fp != NULL) 11454 lnum = fp->lnum; 11455 rettv->vval.v_number = lnum; 11456 } 11457 11458 /* 11459 * "line2byte(lnum)" function 11460 */ 11461 /*ARGSUSED*/ 11462 static void 11463 f_line2byte(argvars, rettv) 11464 typval_T *argvars; 11465 typval_T *rettv; 11466 { 11467 #ifndef FEAT_BYTEOFF 11468 rettv->vval.v_number = -1; 11469 #else 11470 linenr_T lnum; 11471 11472 lnum = get_tv_lnum(argvars); 11473 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11474 rettv->vval.v_number = -1; 11475 else 11476 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11477 if (rettv->vval.v_number >= 0) 11478 ++rettv->vval.v_number; 11479 #endif 11480 } 11481 11482 /* 11483 * "lispindent(lnum)" function 11484 */ 11485 static void 11486 f_lispindent(argvars, rettv) 11487 typval_T *argvars; 11488 typval_T *rettv; 11489 { 11490 #ifdef FEAT_LISP 11491 pos_T pos; 11492 linenr_T lnum; 11493 11494 pos = curwin->w_cursor; 11495 lnum = get_tv_lnum(argvars); 11496 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11497 { 11498 curwin->w_cursor.lnum = lnum; 11499 rettv->vval.v_number = get_lisp_indent(); 11500 curwin->w_cursor = pos; 11501 } 11502 else 11503 #endif 11504 rettv->vval.v_number = -1; 11505 } 11506 11507 /* 11508 * "localtime()" function 11509 */ 11510 /*ARGSUSED*/ 11511 static void 11512 f_localtime(argvars, rettv) 11513 typval_T *argvars; 11514 typval_T *rettv; 11515 { 11516 rettv->vval.v_number = (varnumber_T)time(NULL); 11517 } 11518 11519 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11520 11521 static void 11522 get_maparg(argvars, rettv, exact) 11523 typval_T *argvars; 11524 typval_T *rettv; 11525 int exact; 11526 { 11527 char_u *keys; 11528 char_u *which; 11529 char_u buf[NUMBUFLEN]; 11530 char_u *keys_buf = NULL; 11531 char_u *rhs; 11532 int mode; 11533 garray_T ga; 11534 11535 /* return empty string for failure */ 11536 rettv->v_type = VAR_STRING; 11537 rettv->vval.v_string = NULL; 11538 11539 keys = get_tv_string(&argvars[0]); 11540 if (*keys == NUL) 11541 return; 11542 11543 if (argvars[1].v_type != VAR_UNKNOWN) 11544 which = get_tv_string_buf_chk(&argvars[1], buf); 11545 else 11546 which = (char_u *)""; 11547 if (which == NULL) 11548 return; 11549 11550 mode = get_map_mode(&which, 0); 11551 11552 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11553 rhs = check_map(keys, mode, exact, FALSE); 11554 vim_free(keys_buf); 11555 if (rhs != NULL) 11556 { 11557 ga_init(&ga); 11558 ga.ga_itemsize = 1; 11559 ga.ga_growsize = 40; 11560 11561 while (*rhs != NUL) 11562 ga_concat(&ga, str2special(&rhs, FALSE)); 11563 11564 ga_append(&ga, NUL); 11565 rettv->vval.v_string = (char_u *)ga.ga_data; 11566 } 11567 } 11568 11569 /* 11570 * "map()" function 11571 */ 11572 static void 11573 f_map(argvars, rettv) 11574 typval_T *argvars; 11575 typval_T *rettv; 11576 { 11577 filter_map(argvars, rettv, TRUE); 11578 } 11579 11580 /* 11581 * "maparg()" function 11582 */ 11583 static void 11584 f_maparg(argvars, rettv) 11585 typval_T *argvars; 11586 typval_T *rettv; 11587 { 11588 get_maparg(argvars, rettv, TRUE); 11589 } 11590 11591 /* 11592 * "mapcheck()" function 11593 */ 11594 static void 11595 f_mapcheck(argvars, rettv) 11596 typval_T *argvars; 11597 typval_T *rettv; 11598 { 11599 get_maparg(argvars, rettv, FALSE); 11600 } 11601 11602 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11603 11604 static void 11605 find_some_match(argvars, rettv, type) 11606 typval_T *argvars; 11607 typval_T *rettv; 11608 int type; 11609 { 11610 char_u *str = NULL; 11611 char_u *expr = NULL; 11612 char_u *pat; 11613 regmatch_T regmatch; 11614 char_u patbuf[NUMBUFLEN]; 11615 char_u strbuf[NUMBUFLEN]; 11616 char_u *save_cpo; 11617 long start = 0; 11618 long nth = 1; 11619 int match = 0; 11620 list_T *l = NULL; 11621 listitem_T *li = NULL; 11622 long idx = 0; 11623 char_u *tofree = NULL; 11624 11625 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11626 save_cpo = p_cpo; 11627 p_cpo = (char_u *)""; 11628 11629 rettv->vval.v_number = -1; 11630 if (type == 3) 11631 { 11632 /* return empty list when there are no matches */ 11633 if ((rettv->vval.v_list = list_alloc()) == NULL) 11634 goto theend; 11635 rettv->v_type = VAR_LIST; 11636 ++rettv->vval.v_list->lv_refcount; 11637 } 11638 else if (type == 2) 11639 { 11640 rettv->v_type = VAR_STRING; 11641 rettv->vval.v_string = NULL; 11642 } 11643 11644 if (argvars[0].v_type == VAR_LIST) 11645 { 11646 if ((l = argvars[0].vval.v_list) == NULL) 11647 goto theend; 11648 li = l->lv_first; 11649 } 11650 else 11651 expr = str = get_tv_string(&argvars[0]); 11652 11653 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11654 if (pat == NULL) 11655 goto theend; 11656 11657 if (argvars[2].v_type != VAR_UNKNOWN) 11658 { 11659 int error = FALSE; 11660 11661 start = get_tv_number_chk(&argvars[2], &error); 11662 if (error) 11663 goto theend; 11664 if (l != NULL) 11665 { 11666 li = list_find(l, start); 11667 if (li == NULL) 11668 goto theend; 11669 idx = l->lv_idx; /* use the cached index */ 11670 } 11671 else 11672 { 11673 if (start < 0) 11674 start = 0; 11675 if (start > (long)STRLEN(str)) 11676 goto theend; 11677 str += start; 11678 } 11679 11680 if (argvars[3].v_type != VAR_UNKNOWN) 11681 nth = get_tv_number_chk(&argvars[3], &error); 11682 if (error) 11683 goto theend; 11684 } 11685 11686 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11687 if (regmatch.regprog != NULL) 11688 { 11689 regmatch.rm_ic = p_ic; 11690 11691 for (;;) 11692 { 11693 if (l != NULL) 11694 { 11695 if (li == NULL) 11696 { 11697 match = FALSE; 11698 break; 11699 } 11700 vim_free(tofree); 11701 str = echo_string(&li->li_tv, &tofree, strbuf); 11702 if (str == NULL) 11703 break; 11704 } 11705 11706 match = vim_regexec_nl(®match, str, (colnr_T)0); 11707 11708 if (match && --nth <= 0) 11709 break; 11710 if (l == NULL && !match) 11711 break; 11712 11713 /* Advance to just after the match. */ 11714 if (l != NULL) 11715 { 11716 li = li->li_next; 11717 ++idx; 11718 } 11719 else 11720 { 11721 #ifdef FEAT_MBYTE 11722 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11723 #else 11724 str = regmatch.startp[0] + 1; 11725 #endif 11726 } 11727 } 11728 11729 if (match) 11730 { 11731 if (type == 3) 11732 { 11733 int i; 11734 11735 /* return list with matched string and submatches */ 11736 for (i = 0; i < NSUBEXP; ++i) 11737 { 11738 if (regmatch.endp[i] == NULL) 11739 break; 11740 if (list_append_string(rettv->vval.v_list, 11741 regmatch.startp[i], 11742 (int)(regmatch.endp[i] - regmatch.startp[i])) 11743 == FAIL) 11744 break; 11745 } 11746 } 11747 else if (type == 2) 11748 { 11749 /* return matched string */ 11750 if (l != NULL) 11751 copy_tv(&li->li_tv, rettv); 11752 else 11753 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11754 (int)(regmatch.endp[0] - regmatch.startp[0])); 11755 } 11756 else if (l != NULL) 11757 rettv->vval.v_number = idx; 11758 else 11759 { 11760 if (type != 0) 11761 rettv->vval.v_number = 11762 (varnumber_T)(regmatch.startp[0] - str); 11763 else 11764 rettv->vval.v_number = 11765 (varnumber_T)(regmatch.endp[0] - str); 11766 rettv->vval.v_number += str - expr; 11767 } 11768 } 11769 vim_free(regmatch.regprog); 11770 } 11771 11772 theend: 11773 vim_free(tofree); 11774 p_cpo = save_cpo; 11775 } 11776 11777 /* 11778 * "match()" function 11779 */ 11780 static void 11781 f_match(argvars, rettv) 11782 typval_T *argvars; 11783 typval_T *rettv; 11784 { 11785 find_some_match(argvars, rettv, 1); 11786 } 11787 11788 /* 11789 * "matchend()" function 11790 */ 11791 static void 11792 f_matchend(argvars, rettv) 11793 typval_T *argvars; 11794 typval_T *rettv; 11795 { 11796 find_some_match(argvars, rettv, 0); 11797 } 11798 11799 /* 11800 * "matchlist()" function 11801 */ 11802 static void 11803 f_matchlist(argvars, rettv) 11804 typval_T *argvars; 11805 typval_T *rettv; 11806 { 11807 find_some_match(argvars, rettv, 3); 11808 } 11809 11810 /* 11811 * "matchstr()" function 11812 */ 11813 static void 11814 f_matchstr(argvars, rettv) 11815 typval_T *argvars; 11816 typval_T *rettv; 11817 { 11818 find_some_match(argvars, rettv, 2); 11819 } 11820 11821 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11822 11823 static void 11824 max_min(argvars, rettv, domax) 11825 typval_T *argvars; 11826 typval_T *rettv; 11827 int domax; 11828 { 11829 long n = 0; 11830 long i; 11831 int error = FALSE; 11832 11833 if (argvars[0].v_type == VAR_LIST) 11834 { 11835 list_T *l; 11836 listitem_T *li; 11837 11838 l = argvars[0].vval.v_list; 11839 if (l != NULL) 11840 { 11841 li = l->lv_first; 11842 if (li != NULL) 11843 { 11844 n = get_tv_number_chk(&li->li_tv, &error); 11845 for (;;) 11846 { 11847 li = li->li_next; 11848 if (li == NULL) 11849 break; 11850 i = get_tv_number_chk(&li->li_tv, &error); 11851 if (domax ? i > n : i < n) 11852 n = i; 11853 } 11854 } 11855 } 11856 } 11857 else if (argvars[0].v_type == VAR_DICT) 11858 { 11859 dict_T *d; 11860 int first = TRUE; 11861 hashitem_T *hi; 11862 int todo; 11863 11864 d = argvars[0].vval.v_dict; 11865 if (d != NULL) 11866 { 11867 todo = d->dv_hashtab.ht_used; 11868 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11869 { 11870 if (!HASHITEM_EMPTY(hi)) 11871 { 11872 --todo; 11873 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11874 if (first) 11875 { 11876 n = i; 11877 first = FALSE; 11878 } 11879 else if (domax ? i > n : i < n) 11880 n = i; 11881 } 11882 } 11883 } 11884 } 11885 else 11886 EMSG(_(e_listdictarg)); 11887 rettv->vval.v_number = error ? 0 : n; 11888 } 11889 11890 /* 11891 * "max()" function 11892 */ 11893 static void 11894 f_max(argvars, rettv) 11895 typval_T *argvars; 11896 typval_T *rettv; 11897 { 11898 max_min(argvars, rettv, TRUE); 11899 } 11900 11901 /* 11902 * "min()" function 11903 */ 11904 static void 11905 f_min(argvars, rettv) 11906 typval_T *argvars; 11907 typval_T *rettv; 11908 { 11909 max_min(argvars, rettv, FALSE); 11910 } 11911 11912 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11913 11914 /* 11915 * Create the directory in which "dir" is located, and higher levels when 11916 * needed. 11917 */ 11918 static int 11919 mkdir_recurse(dir, prot) 11920 char_u *dir; 11921 int prot; 11922 { 11923 char_u *p; 11924 char_u *updir; 11925 int r = FAIL; 11926 11927 /* Get end of directory name in "dir". 11928 * We're done when it's "/" or "c:/". */ 11929 p = gettail_sep(dir); 11930 if (p <= get_past_head(dir)) 11931 return OK; 11932 11933 /* If the directory exists we're done. Otherwise: create it.*/ 11934 updir = vim_strnsave(dir, (int)(p - dir)); 11935 if (updir == NULL) 11936 return FAIL; 11937 if (mch_isdir(updir)) 11938 r = OK; 11939 else if (mkdir_recurse(updir, prot) == OK) 11940 r = vim_mkdir_emsg(updir, prot); 11941 vim_free(updir); 11942 return r; 11943 } 11944 11945 #ifdef vim_mkdir 11946 /* 11947 * "mkdir()" function 11948 */ 11949 static void 11950 f_mkdir(argvars, rettv) 11951 typval_T *argvars; 11952 typval_T *rettv; 11953 { 11954 char_u *dir; 11955 char_u buf[NUMBUFLEN]; 11956 int prot = 0755; 11957 11958 rettv->vval.v_number = FAIL; 11959 if (check_restricted() || check_secure()) 11960 return; 11961 11962 dir = get_tv_string_buf(&argvars[0], buf); 11963 if (argvars[1].v_type != VAR_UNKNOWN) 11964 { 11965 if (argvars[2].v_type != VAR_UNKNOWN) 11966 prot = get_tv_number_chk(&argvars[2], NULL); 11967 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11968 mkdir_recurse(dir, prot); 11969 } 11970 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11971 } 11972 #endif 11973 11974 /* 11975 * "mode()" function 11976 */ 11977 /*ARGSUSED*/ 11978 static void 11979 f_mode(argvars, rettv) 11980 typval_T *argvars; 11981 typval_T *rettv; 11982 { 11983 char_u buf[2]; 11984 11985 #ifdef FEAT_VISUAL 11986 if (VIsual_active) 11987 { 11988 if (VIsual_select) 11989 buf[0] = VIsual_mode + 's' - 'v'; 11990 else 11991 buf[0] = VIsual_mode; 11992 } 11993 else 11994 #endif 11995 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11996 buf[0] = 'r'; 11997 else if (State & INSERT) 11998 { 11999 if (State & REPLACE_FLAG) 12000 buf[0] = 'R'; 12001 else 12002 buf[0] = 'i'; 12003 } 12004 else if (State & CMDLINE) 12005 buf[0] = 'c'; 12006 else 12007 buf[0] = 'n'; 12008 12009 buf[1] = NUL; 12010 rettv->vval.v_string = vim_strsave(buf); 12011 rettv->v_type = VAR_STRING; 12012 } 12013 12014 /* 12015 * "nextnonblank()" function 12016 */ 12017 static void 12018 f_nextnonblank(argvars, rettv) 12019 typval_T *argvars; 12020 typval_T *rettv; 12021 { 12022 linenr_T lnum; 12023 12024 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12025 { 12026 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12027 { 12028 lnum = 0; 12029 break; 12030 } 12031 if (*skipwhite(ml_get(lnum)) != NUL) 12032 break; 12033 } 12034 rettv->vval.v_number = lnum; 12035 } 12036 12037 /* 12038 * "nr2char()" function 12039 */ 12040 static void 12041 f_nr2char(argvars, rettv) 12042 typval_T *argvars; 12043 typval_T *rettv; 12044 { 12045 char_u buf[NUMBUFLEN]; 12046 12047 #ifdef FEAT_MBYTE 12048 if (has_mbyte) 12049 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12050 else 12051 #endif 12052 { 12053 buf[0] = (char_u)get_tv_number(&argvars[0]); 12054 buf[1] = NUL; 12055 } 12056 rettv->v_type = VAR_STRING; 12057 rettv->vval.v_string = vim_strsave(buf); 12058 } 12059 12060 /* 12061 * "prevnonblank()" function 12062 */ 12063 static void 12064 f_prevnonblank(argvars, rettv) 12065 typval_T *argvars; 12066 typval_T *rettv; 12067 { 12068 linenr_T lnum; 12069 12070 lnum = get_tv_lnum(argvars); 12071 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12072 lnum = 0; 12073 else 12074 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12075 --lnum; 12076 rettv->vval.v_number = lnum; 12077 } 12078 12079 #ifdef HAVE_STDARG_H 12080 /* This dummy va_list is here because: 12081 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12082 * - locally in the function results in a "used before set" warning 12083 * - using va_start() to initialize it gives "function with fixed args" error */ 12084 static va_list ap; 12085 #endif 12086 12087 /* 12088 * "printf()" function 12089 */ 12090 static void 12091 f_printf(argvars, rettv) 12092 typval_T *argvars; 12093 typval_T *rettv; 12094 { 12095 rettv->v_type = VAR_STRING; 12096 rettv->vval.v_string = NULL; 12097 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12098 { 12099 char_u buf[NUMBUFLEN]; 12100 int len; 12101 char_u *s; 12102 int saved_did_emsg = did_emsg; 12103 char *fmt; 12104 12105 /* Get the required length, allocate the buffer and do it for real. */ 12106 did_emsg = FALSE; 12107 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12108 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12109 if (!did_emsg) 12110 { 12111 s = alloc(len + 1); 12112 if (s != NULL) 12113 { 12114 rettv->vval.v_string = s; 12115 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12116 } 12117 } 12118 did_emsg |= saved_did_emsg; 12119 } 12120 #endif 12121 } 12122 12123 /* 12124 * "range()" function 12125 */ 12126 static void 12127 f_range(argvars, rettv) 12128 typval_T *argvars; 12129 typval_T *rettv; 12130 { 12131 long start; 12132 long end; 12133 long stride = 1; 12134 long i; 12135 list_T *l; 12136 int error = FALSE; 12137 12138 start = get_tv_number_chk(&argvars[0], &error); 12139 if (argvars[1].v_type == VAR_UNKNOWN) 12140 { 12141 end = start - 1; 12142 start = 0; 12143 } 12144 else 12145 { 12146 end = get_tv_number_chk(&argvars[1], &error); 12147 if (argvars[2].v_type != VAR_UNKNOWN) 12148 stride = get_tv_number_chk(&argvars[2], &error); 12149 } 12150 12151 rettv->vval.v_number = 0; 12152 if (error) 12153 return; /* type error; errmsg already given */ 12154 if (stride == 0) 12155 EMSG(_("E726: Stride is zero")); 12156 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12157 EMSG(_("E727: Start past end")); 12158 else 12159 { 12160 l = list_alloc(); 12161 if (l != NULL) 12162 { 12163 rettv->v_type = VAR_LIST; 12164 rettv->vval.v_list = l; 12165 ++l->lv_refcount; 12166 12167 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12168 if (list_append_number(l, (varnumber_T)i) == FAIL) 12169 break; 12170 } 12171 } 12172 } 12173 12174 /* 12175 * "readfile()" function 12176 */ 12177 static void 12178 f_readfile(argvars, rettv) 12179 typval_T *argvars; 12180 typval_T *rettv; 12181 { 12182 int binary = FALSE; 12183 char_u *fname; 12184 FILE *fd; 12185 list_T *l; 12186 listitem_T *li; 12187 #define FREAD_SIZE 200 /* optimized for text lines */ 12188 char_u buf[FREAD_SIZE]; 12189 int readlen; /* size of last fread() */ 12190 int buflen; /* nr of valid chars in buf[] */ 12191 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12192 int tolist; /* first byte in buf[] still to be put in list */ 12193 int chop; /* how many CR to chop off */ 12194 char_u *prev = NULL; /* previously read bytes, if any */ 12195 int prevlen = 0; /* length of "prev" if not NULL */ 12196 char_u *s; 12197 int len; 12198 long maxline = MAXLNUM; 12199 long cnt = 0; 12200 12201 if (argvars[1].v_type != VAR_UNKNOWN) 12202 { 12203 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12204 binary = TRUE; 12205 if (argvars[2].v_type != VAR_UNKNOWN) 12206 maxline = get_tv_number(&argvars[2]); 12207 } 12208 12209 l = list_alloc(); 12210 if (l == NULL) 12211 return; 12212 rettv->v_type = VAR_LIST; 12213 rettv->vval.v_list = l; 12214 l->lv_refcount = 1; 12215 12216 /* Always open the file in binary mode, library functions have a mind of 12217 * their own about CR-LF conversion. */ 12218 fname = get_tv_string(&argvars[0]); 12219 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12220 { 12221 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12222 return; 12223 } 12224 12225 filtd = 0; 12226 while (cnt < maxline || maxline < 0) 12227 { 12228 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12229 buflen = filtd + readlen; 12230 tolist = 0; 12231 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12232 { 12233 if (buf[filtd] == '\n' || readlen <= 0) 12234 { 12235 /* Only when in binary mode add an empty list item when the 12236 * last line ends in a '\n'. */ 12237 if (!binary && readlen == 0 && filtd == 0) 12238 break; 12239 12240 /* Found end-of-line or end-of-file: add a text line to the 12241 * list. */ 12242 chop = 0; 12243 if (!binary) 12244 while (filtd - chop - 1 >= tolist 12245 && buf[filtd - chop - 1] == '\r') 12246 ++chop; 12247 len = filtd - tolist - chop; 12248 if (prev == NULL) 12249 s = vim_strnsave(buf + tolist, len); 12250 else 12251 { 12252 s = alloc((unsigned)(prevlen + len + 1)); 12253 if (s != NULL) 12254 { 12255 mch_memmove(s, prev, prevlen); 12256 vim_free(prev); 12257 prev = NULL; 12258 mch_memmove(s + prevlen, buf + tolist, len); 12259 s[prevlen + len] = NUL; 12260 } 12261 } 12262 tolist = filtd + 1; 12263 12264 li = listitem_alloc(); 12265 if (li == NULL) 12266 { 12267 vim_free(s); 12268 break; 12269 } 12270 li->li_tv.v_type = VAR_STRING; 12271 li->li_tv.v_lock = 0; 12272 li->li_tv.vval.v_string = s; 12273 list_append(l, li); 12274 12275 if (++cnt >= maxline && maxline >= 0) 12276 break; 12277 if (readlen <= 0) 12278 break; 12279 } 12280 else if (buf[filtd] == NUL) 12281 buf[filtd] = '\n'; 12282 } 12283 if (readlen <= 0) 12284 break; 12285 12286 if (tolist == 0) 12287 { 12288 /* "buf" is full, need to move text to an allocated buffer */ 12289 if (prev == NULL) 12290 { 12291 prev = vim_strnsave(buf, buflen); 12292 prevlen = buflen; 12293 } 12294 else 12295 { 12296 s = alloc((unsigned)(prevlen + buflen)); 12297 if (s != NULL) 12298 { 12299 mch_memmove(s, prev, prevlen); 12300 mch_memmove(s + prevlen, buf, buflen); 12301 vim_free(prev); 12302 prev = s; 12303 prevlen += buflen; 12304 } 12305 } 12306 filtd = 0; 12307 } 12308 else 12309 { 12310 mch_memmove(buf, buf + tolist, buflen - tolist); 12311 filtd -= tolist; 12312 } 12313 } 12314 12315 /* 12316 * For a negative line count use only the lines at the end of the file, 12317 * free the rest. 12318 */ 12319 if (maxline < 0) 12320 while (cnt > -maxline) 12321 { 12322 listitem_remove(l, l->lv_first); 12323 --cnt; 12324 } 12325 12326 vim_free(prev); 12327 fclose(fd); 12328 } 12329 12330 12331 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12332 static void make_connection __ARGS((void)); 12333 static int check_connection __ARGS((void)); 12334 12335 static void 12336 make_connection() 12337 { 12338 if (X_DISPLAY == NULL 12339 # ifdef FEAT_GUI 12340 && !gui.in_use 12341 # endif 12342 ) 12343 { 12344 x_force_connect = TRUE; 12345 setup_term_clip(); 12346 x_force_connect = FALSE; 12347 } 12348 } 12349 12350 static int 12351 check_connection() 12352 { 12353 make_connection(); 12354 if (X_DISPLAY == NULL) 12355 { 12356 EMSG(_("E240: No connection to Vim server")); 12357 return FAIL; 12358 } 12359 return OK; 12360 } 12361 #endif 12362 12363 #ifdef FEAT_CLIENTSERVER 12364 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12365 12366 static void 12367 remote_common(argvars, rettv, expr) 12368 typval_T *argvars; 12369 typval_T *rettv; 12370 int expr; 12371 { 12372 char_u *server_name; 12373 char_u *keys; 12374 char_u *r = NULL; 12375 char_u buf[NUMBUFLEN]; 12376 # ifdef WIN32 12377 HWND w; 12378 # else 12379 Window w; 12380 # endif 12381 12382 if (check_restricted() || check_secure()) 12383 return; 12384 12385 # ifdef FEAT_X11 12386 if (check_connection() == FAIL) 12387 return; 12388 # endif 12389 12390 server_name = get_tv_string_chk(&argvars[0]); 12391 if (server_name == NULL) 12392 return; /* type error; errmsg already given */ 12393 keys = get_tv_string_buf(&argvars[1], buf); 12394 # ifdef WIN32 12395 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12396 # else 12397 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12398 < 0) 12399 # endif 12400 { 12401 if (r != NULL) 12402 EMSG(r); /* sending worked but evaluation failed */ 12403 else 12404 EMSG2(_("E241: Unable to send to %s"), server_name); 12405 return; 12406 } 12407 12408 rettv->vval.v_string = r; 12409 12410 if (argvars[2].v_type != VAR_UNKNOWN) 12411 { 12412 dictitem_T v; 12413 char_u str[30]; 12414 char_u *idvar; 12415 12416 sprintf((char *)str, "0x%x", (unsigned int)w); 12417 v.di_tv.v_type = VAR_STRING; 12418 v.di_tv.vval.v_string = vim_strsave(str); 12419 idvar = get_tv_string_chk(&argvars[2]); 12420 if (idvar != NULL) 12421 set_var(idvar, &v.di_tv, FALSE); 12422 vim_free(v.di_tv.vval.v_string); 12423 } 12424 } 12425 #endif 12426 12427 /* 12428 * "remote_expr()" function 12429 */ 12430 /*ARGSUSED*/ 12431 static void 12432 f_remote_expr(argvars, rettv) 12433 typval_T *argvars; 12434 typval_T *rettv; 12435 { 12436 rettv->v_type = VAR_STRING; 12437 rettv->vval.v_string = NULL; 12438 #ifdef FEAT_CLIENTSERVER 12439 remote_common(argvars, rettv, TRUE); 12440 #endif 12441 } 12442 12443 /* 12444 * "remote_foreground()" function 12445 */ 12446 /*ARGSUSED*/ 12447 static void 12448 f_remote_foreground(argvars, rettv) 12449 typval_T *argvars; 12450 typval_T *rettv; 12451 { 12452 rettv->vval.v_number = 0; 12453 #ifdef FEAT_CLIENTSERVER 12454 # ifdef WIN32 12455 /* On Win32 it's done in this application. */ 12456 { 12457 char_u *server_name = get_tv_string_chk(&argvars[0]); 12458 12459 if (server_name != NULL) 12460 serverForeground(server_name); 12461 } 12462 # else 12463 /* Send a foreground() expression to the server. */ 12464 argvars[1].v_type = VAR_STRING; 12465 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12466 argvars[2].v_type = VAR_UNKNOWN; 12467 remote_common(argvars, rettv, TRUE); 12468 vim_free(argvars[1].vval.v_string); 12469 # endif 12470 #endif 12471 } 12472 12473 /*ARGSUSED*/ 12474 static void 12475 f_remote_peek(argvars, rettv) 12476 typval_T *argvars; 12477 typval_T *rettv; 12478 { 12479 #ifdef FEAT_CLIENTSERVER 12480 dictitem_T v; 12481 char_u *s = NULL; 12482 # ifdef WIN32 12483 int n = 0; 12484 # endif 12485 char_u *serverid; 12486 12487 if (check_restricted() || check_secure()) 12488 { 12489 rettv->vval.v_number = -1; 12490 return; 12491 } 12492 serverid = get_tv_string_chk(&argvars[0]); 12493 if (serverid == NULL) 12494 { 12495 rettv->vval.v_number = -1; 12496 return; /* type error; errmsg already given */ 12497 } 12498 # ifdef WIN32 12499 sscanf(serverid, "%x", &n); 12500 if (n == 0) 12501 rettv->vval.v_number = -1; 12502 else 12503 { 12504 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12505 rettv->vval.v_number = (s != NULL); 12506 } 12507 # else 12508 rettv->vval.v_number = 0; 12509 if (check_connection() == FAIL) 12510 return; 12511 12512 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12513 serverStrToWin(serverid), &s); 12514 # endif 12515 12516 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12517 { 12518 char_u *retvar; 12519 12520 v.di_tv.v_type = VAR_STRING; 12521 v.di_tv.vval.v_string = vim_strsave(s); 12522 retvar = get_tv_string_chk(&argvars[1]); 12523 if (retvar != NULL) 12524 set_var(retvar, &v.di_tv, FALSE); 12525 vim_free(v.di_tv.vval.v_string); 12526 } 12527 #else 12528 rettv->vval.v_number = -1; 12529 #endif 12530 } 12531 12532 /*ARGSUSED*/ 12533 static void 12534 f_remote_read(argvars, rettv) 12535 typval_T *argvars; 12536 typval_T *rettv; 12537 { 12538 char_u *r = NULL; 12539 12540 #ifdef FEAT_CLIENTSERVER 12541 char_u *serverid = get_tv_string_chk(&argvars[0]); 12542 12543 if (serverid != NULL && !check_restricted() && !check_secure()) 12544 { 12545 # ifdef WIN32 12546 /* The server's HWND is encoded in the 'id' parameter */ 12547 int n = 0; 12548 12549 sscanf(serverid, "%x", &n); 12550 if (n != 0) 12551 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12552 if (r == NULL) 12553 # else 12554 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12555 serverStrToWin(serverid), &r, FALSE) < 0) 12556 # endif 12557 EMSG(_("E277: Unable to read a server reply")); 12558 } 12559 #endif 12560 rettv->v_type = VAR_STRING; 12561 rettv->vval.v_string = r; 12562 } 12563 12564 /* 12565 * "remote_send()" function 12566 */ 12567 /*ARGSUSED*/ 12568 static void 12569 f_remote_send(argvars, rettv) 12570 typval_T *argvars; 12571 typval_T *rettv; 12572 { 12573 rettv->v_type = VAR_STRING; 12574 rettv->vval.v_string = NULL; 12575 #ifdef FEAT_CLIENTSERVER 12576 remote_common(argvars, rettv, FALSE); 12577 #endif 12578 } 12579 12580 /* 12581 * "remove()" function 12582 */ 12583 static void 12584 f_remove(argvars, rettv) 12585 typval_T *argvars; 12586 typval_T *rettv; 12587 { 12588 list_T *l; 12589 listitem_T *item, *item2; 12590 listitem_T *li; 12591 long idx; 12592 long end; 12593 char_u *key; 12594 dict_T *d; 12595 dictitem_T *di; 12596 12597 rettv->vval.v_number = 0; 12598 if (argvars[0].v_type == VAR_DICT) 12599 { 12600 if (argvars[2].v_type != VAR_UNKNOWN) 12601 EMSG2(_(e_toomanyarg), "remove()"); 12602 else if ((d = argvars[0].vval.v_dict) != NULL 12603 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12604 { 12605 key = get_tv_string_chk(&argvars[1]); 12606 if (key != NULL) 12607 { 12608 di = dict_find(d, key, -1); 12609 if (di == NULL) 12610 EMSG2(_(e_dictkey), key); 12611 else 12612 { 12613 *rettv = di->di_tv; 12614 init_tv(&di->di_tv); 12615 dictitem_remove(d, di); 12616 } 12617 } 12618 } 12619 } 12620 else if (argvars[0].v_type != VAR_LIST) 12621 EMSG2(_(e_listdictarg), "remove()"); 12622 else if ((l = argvars[0].vval.v_list) != NULL 12623 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12624 { 12625 int error = FALSE; 12626 12627 idx = get_tv_number_chk(&argvars[1], &error); 12628 if (error) 12629 ; /* type error: do nothing, errmsg already given */ 12630 else if ((item = list_find(l, idx)) == NULL) 12631 EMSGN(_(e_listidx), idx); 12632 else 12633 { 12634 if (argvars[2].v_type == VAR_UNKNOWN) 12635 { 12636 /* Remove one item, return its value. */ 12637 list_remove(l, item, item); 12638 *rettv = item->li_tv; 12639 vim_free(item); 12640 } 12641 else 12642 { 12643 /* Remove range of items, return list with values. */ 12644 end = get_tv_number_chk(&argvars[2], &error); 12645 if (error) 12646 ; /* type error: do nothing */ 12647 else if ((item2 = list_find(l, end)) == NULL) 12648 EMSGN(_(e_listidx), end); 12649 else 12650 { 12651 int cnt = 0; 12652 12653 for (li = item; li != NULL; li = li->li_next) 12654 { 12655 ++cnt; 12656 if (li == item2) 12657 break; 12658 } 12659 if (li == NULL) /* didn't find "item2" after "item" */ 12660 EMSG(_(e_invrange)); 12661 else 12662 { 12663 list_remove(l, item, item2); 12664 l = list_alloc(); 12665 if (l != NULL) 12666 { 12667 rettv->v_type = VAR_LIST; 12668 rettv->vval.v_list = l; 12669 l->lv_first = item; 12670 l->lv_last = item2; 12671 l->lv_refcount = 1; 12672 item->li_prev = NULL; 12673 item2->li_next = NULL; 12674 l->lv_len = cnt; 12675 } 12676 } 12677 } 12678 } 12679 } 12680 } 12681 } 12682 12683 /* 12684 * "rename({from}, {to})" function 12685 */ 12686 static void 12687 f_rename(argvars, rettv) 12688 typval_T *argvars; 12689 typval_T *rettv; 12690 { 12691 char_u buf[NUMBUFLEN]; 12692 12693 if (check_restricted() || check_secure()) 12694 rettv->vval.v_number = -1; 12695 else 12696 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12697 get_tv_string_buf(&argvars[1], buf)); 12698 } 12699 12700 /* 12701 * "repeat()" function 12702 */ 12703 /*ARGSUSED*/ 12704 static void 12705 f_repeat(argvars, rettv) 12706 typval_T *argvars; 12707 typval_T *rettv; 12708 { 12709 char_u *p; 12710 int n; 12711 int slen; 12712 int len; 12713 char_u *r; 12714 int i; 12715 list_T *l; 12716 12717 n = get_tv_number(&argvars[1]); 12718 if (argvars[0].v_type == VAR_LIST) 12719 { 12720 l = list_alloc(); 12721 if (l != NULL && argvars[0].vval.v_list != NULL) 12722 { 12723 l->lv_refcount = 1; 12724 while (n-- > 0) 12725 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12726 break; 12727 } 12728 rettv->v_type = VAR_LIST; 12729 rettv->vval.v_list = l; 12730 } 12731 else 12732 { 12733 p = get_tv_string(&argvars[0]); 12734 rettv->v_type = VAR_STRING; 12735 rettv->vval.v_string = NULL; 12736 12737 slen = (int)STRLEN(p); 12738 len = slen * n; 12739 if (len <= 0) 12740 return; 12741 12742 r = alloc(len + 1); 12743 if (r != NULL) 12744 { 12745 for (i = 0; i < n; i++) 12746 mch_memmove(r + i * slen, p, (size_t)slen); 12747 r[len] = NUL; 12748 } 12749 12750 rettv->vval.v_string = r; 12751 } 12752 } 12753 12754 /* 12755 * "resolve()" function 12756 */ 12757 static void 12758 f_resolve(argvars, rettv) 12759 typval_T *argvars; 12760 typval_T *rettv; 12761 { 12762 char_u *p; 12763 12764 p = get_tv_string(&argvars[0]); 12765 #ifdef FEAT_SHORTCUT 12766 { 12767 char_u *v = NULL; 12768 12769 v = mch_resolve_shortcut(p); 12770 if (v != NULL) 12771 rettv->vval.v_string = v; 12772 else 12773 rettv->vval.v_string = vim_strsave(p); 12774 } 12775 #else 12776 # ifdef HAVE_READLINK 12777 { 12778 char_u buf[MAXPATHL + 1]; 12779 char_u *cpy; 12780 int len; 12781 char_u *remain = NULL; 12782 char_u *q; 12783 int is_relative_to_current = FALSE; 12784 int has_trailing_pathsep = FALSE; 12785 int limit = 100; 12786 12787 p = vim_strsave(p); 12788 12789 if (p[0] == '.' && (vim_ispathsep(p[1]) 12790 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12791 is_relative_to_current = TRUE; 12792 12793 len = STRLEN(p); 12794 if (len > 0 && after_pathsep(p, p + len)) 12795 has_trailing_pathsep = TRUE; 12796 12797 q = getnextcomp(p); 12798 if (*q != NUL) 12799 { 12800 /* Separate the first path component in "p", and keep the 12801 * remainder (beginning with the path separator). */ 12802 remain = vim_strsave(q - 1); 12803 q[-1] = NUL; 12804 } 12805 12806 for (;;) 12807 { 12808 for (;;) 12809 { 12810 len = readlink((char *)p, (char *)buf, MAXPATHL); 12811 if (len <= 0) 12812 break; 12813 buf[len] = NUL; 12814 12815 if (limit-- == 0) 12816 { 12817 vim_free(p); 12818 vim_free(remain); 12819 EMSG(_("E655: Too many symbolic links (cycle?)")); 12820 rettv->vval.v_string = NULL; 12821 goto fail; 12822 } 12823 12824 /* Ensure that the result will have a trailing path separator 12825 * if the argument has one. */ 12826 if (remain == NULL && has_trailing_pathsep) 12827 add_pathsep(buf); 12828 12829 /* Separate the first path component in the link value and 12830 * concatenate the remainders. */ 12831 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12832 if (*q != NUL) 12833 { 12834 if (remain == NULL) 12835 remain = vim_strsave(q - 1); 12836 else 12837 { 12838 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12839 if (cpy != NULL) 12840 { 12841 STRCAT(cpy, remain); 12842 vim_free(remain); 12843 remain = cpy; 12844 } 12845 } 12846 q[-1] = NUL; 12847 } 12848 12849 q = gettail(p); 12850 if (q > p && *q == NUL) 12851 { 12852 /* Ignore trailing path separator. */ 12853 q[-1] = NUL; 12854 q = gettail(p); 12855 } 12856 if (q > p && !mch_isFullName(buf)) 12857 { 12858 /* symlink is relative to directory of argument */ 12859 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12860 if (cpy != NULL) 12861 { 12862 STRCPY(cpy, p); 12863 STRCPY(gettail(cpy), buf); 12864 vim_free(p); 12865 p = cpy; 12866 } 12867 } 12868 else 12869 { 12870 vim_free(p); 12871 p = vim_strsave(buf); 12872 } 12873 } 12874 12875 if (remain == NULL) 12876 break; 12877 12878 /* Append the first path component of "remain" to "p". */ 12879 q = getnextcomp(remain + 1); 12880 len = q - remain - (*q != NUL); 12881 cpy = vim_strnsave(p, STRLEN(p) + len); 12882 if (cpy != NULL) 12883 { 12884 STRNCAT(cpy, remain, len); 12885 vim_free(p); 12886 p = cpy; 12887 } 12888 /* Shorten "remain". */ 12889 if (*q != NUL) 12890 STRCPY(remain, q - 1); 12891 else 12892 { 12893 vim_free(remain); 12894 remain = NULL; 12895 } 12896 } 12897 12898 /* If the result is a relative path name, make it explicitly relative to 12899 * the current directory if and only if the argument had this form. */ 12900 if (!vim_ispathsep(*p)) 12901 { 12902 if (is_relative_to_current 12903 && *p != NUL 12904 && !(p[0] == '.' 12905 && (p[1] == NUL 12906 || vim_ispathsep(p[1]) 12907 || (p[1] == '.' 12908 && (p[2] == NUL 12909 || vim_ispathsep(p[2])))))) 12910 { 12911 /* Prepend "./". */ 12912 cpy = concat_str((char_u *)"./", p); 12913 if (cpy != NULL) 12914 { 12915 vim_free(p); 12916 p = cpy; 12917 } 12918 } 12919 else if (!is_relative_to_current) 12920 { 12921 /* Strip leading "./". */ 12922 q = p; 12923 while (q[0] == '.' && vim_ispathsep(q[1])) 12924 q += 2; 12925 if (q > p) 12926 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12927 } 12928 } 12929 12930 /* Ensure that the result will have no trailing path separator 12931 * if the argument had none. But keep "/" or "//". */ 12932 if (!has_trailing_pathsep) 12933 { 12934 q = p + STRLEN(p); 12935 if (after_pathsep(p, q)) 12936 *gettail_sep(p) = NUL; 12937 } 12938 12939 rettv->vval.v_string = p; 12940 } 12941 # else 12942 rettv->vval.v_string = vim_strsave(p); 12943 # endif 12944 #endif 12945 12946 simplify_filename(rettv->vval.v_string); 12947 12948 #ifdef HAVE_READLINK 12949 fail: 12950 #endif 12951 rettv->v_type = VAR_STRING; 12952 } 12953 12954 /* 12955 * "reverse({list})" function 12956 */ 12957 static void 12958 f_reverse(argvars, rettv) 12959 typval_T *argvars; 12960 typval_T *rettv; 12961 { 12962 list_T *l; 12963 listitem_T *li, *ni; 12964 12965 rettv->vval.v_number = 0; 12966 if (argvars[0].v_type != VAR_LIST) 12967 EMSG2(_(e_listarg), "reverse()"); 12968 else if ((l = argvars[0].vval.v_list) != NULL 12969 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12970 { 12971 li = l->lv_last; 12972 l->lv_first = l->lv_last = NULL; 12973 l->lv_len = 0; 12974 while (li != NULL) 12975 { 12976 ni = li->li_prev; 12977 list_append(l, li); 12978 li = ni; 12979 } 12980 rettv->vval.v_list = l; 12981 rettv->v_type = VAR_LIST; 12982 ++l->lv_refcount; 12983 } 12984 } 12985 12986 #define SP_NOMOVE 1 /* don't move cursor */ 12987 #define SP_REPEAT 2 /* repeat to find outer pair */ 12988 #define SP_RETCOUNT 4 /* return matchcount */ 12989 #define SP_SETPCMARK 8 /* set previous context mark */ 12990 12991 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12992 12993 /* 12994 * Get flags for a search function. 12995 * Possibly sets "p_ws". 12996 * Returns BACKWARD, FORWARD or zero (for an error). 12997 */ 12998 static int 12999 get_search_arg(varp, flagsp) 13000 typval_T *varp; 13001 int *flagsp; 13002 { 13003 int dir = FORWARD; 13004 char_u *flags; 13005 char_u nbuf[NUMBUFLEN]; 13006 int mask; 13007 13008 if (varp->v_type != VAR_UNKNOWN) 13009 { 13010 flags = get_tv_string_buf_chk(varp, nbuf); 13011 if (flags == NULL) 13012 return 0; /* type error; errmsg already given */ 13013 while (*flags != NUL) 13014 { 13015 switch (*flags) 13016 { 13017 case 'b': dir = BACKWARD; break; 13018 case 'w': p_ws = TRUE; break; 13019 case 'W': p_ws = FALSE; break; 13020 default: mask = 0; 13021 if (flagsp != NULL) 13022 switch (*flags) 13023 { 13024 case 'n': mask = SP_NOMOVE; break; 13025 case 'r': mask = SP_REPEAT; break; 13026 case 'm': mask = SP_RETCOUNT; break; 13027 case 's': mask = SP_SETPCMARK; break; 13028 } 13029 if (mask == 0) 13030 { 13031 EMSG2(_(e_invarg2), flags); 13032 dir = 0; 13033 } 13034 else 13035 *flagsp |= mask; 13036 } 13037 if (dir == 0) 13038 break; 13039 ++flags; 13040 } 13041 } 13042 return dir; 13043 } 13044 13045 /* 13046 * "search()" function 13047 */ 13048 static void 13049 f_search(argvars, rettv) 13050 typval_T *argvars; 13051 typval_T *rettv; 13052 { 13053 char_u *pat; 13054 pos_T pos; 13055 pos_T save_cursor; 13056 int save_p_ws = p_ws; 13057 int dir; 13058 int flags = 0; 13059 13060 rettv->vval.v_number = 0; /* default: FAIL */ 13061 13062 pat = get_tv_string(&argvars[0]); 13063 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 13064 if (dir == 0) 13065 goto theend; 13066 /* 13067 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 13068 * Check to make sure only those flags are set. 13069 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13070 * flags cannot be set. Check for that condition also. 13071 */ 13072 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 13073 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13074 { 13075 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13076 goto theend; 13077 } 13078 13079 pos = save_cursor = curwin->w_cursor; 13080 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 13081 SEARCH_KEEP, RE_SEARCH) != FAIL) 13082 { 13083 rettv->vval.v_number = pos.lnum; 13084 if (flags & SP_SETPCMARK) 13085 setpcmark(); 13086 curwin->w_cursor = pos; 13087 /* "/$" will put the cursor after the end of the line, may need to 13088 * correct that here */ 13089 check_cursor(); 13090 } 13091 13092 /* If 'n' flag is used: restore cursor position. */ 13093 if (flags & SP_NOMOVE) 13094 curwin->w_cursor = save_cursor; 13095 theend: 13096 p_ws = save_p_ws; 13097 } 13098 13099 /* 13100 * "searchdecl()" function 13101 */ 13102 static void 13103 f_searchdecl(argvars, rettv) 13104 typval_T *argvars; 13105 typval_T *rettv; 13106 { 13107 int locally = 1; 13108 int thisblock = 0; 13109 int error = FALSE; 13110 char_u *name; 13111 13112 rettv->vval.v_number = 1; /* default: FAIL */ 13113 13114 name = get_tv_string_chk(&argvars[0]); 13115 if (argvars[1].v_type != VAR_UNKNOWN) 13116 { 13117 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13118 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13119 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13120 } 13121 if (!error && name != NULL) 13122 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13123 locally, thisblock, SEARCH_KEEP) == FAIL; 13124 } 13125 13126 /* 13127 * "searchpair()" function 13128 */ 13129 static void 13130 f_searchpair(argvars, rettv) 13131 typval_T *argvars; 13132 typval_T *rettv; 13133 { 13134 char_u *spat, *mpat, *epat; 13135 char_u *skip; 13136 int save_p_ws = p_ws; 13137 int dir; 13138 int flags = 0; 13139 char_u nbuf1[NUMBUFLEN]; 13140 char_u nbuf2[NUMBUFLEN]; 13141 char_u nbuf3[NUMBUFLEN]; 13142 13143 rettv->vval.v_number = 0; /* default: FAIL */ 13144 13145 /* Get the three pattern arguments: start, middle, end. */ 13146 spat = get_tv_string_chk(&argvars[0]); 13147 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13148 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13149 if (spat == NULL || mpat == NULL || epat == NULL) 13150 goto theend; /* type error */ 13151 13152 /* Handle the optional fourth argument: flags */ 13153 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13154 if (dir == 0) 13155 goto theend; 13156 /* 13157 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13158 */ 13159 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13160 { 13161 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13162 goto theend; 13163 } 13164 13165 /* Optional fifth argument: skip expresion */ 13166 if (argvars[3].v_type == VAR_UNKNOWN 13167 || argvars[4].v_type == VAR_UNKNOWN) 13168 skip = (char_u *)""; 13169 else 13170 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13171 if (skip == NULL) 13172 goto theend; /* type error */ 13173 13174 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13175 13176 theend: 13177 p_ws = save_p_ws; 13178 } 13179 13180 /* 13181 * Search for a start/middle/end thing. 13182 * Used by searchpair(), see its documentation for the details. 13183 * Returns 0 or -1 for no match, 13184 */ 13185 long 13186 do_searchpair(spat, mpat, epat, dir, skip, flags) 13187 char_u *spat; /* start pattern */ 13188 char_u *mpat; /* middle pattern */ 13189 char_u *epat; /* end pattern */ 13190 int dir; /* BACKWARD or FORWARD */ 13191 char_u *skip; /* skip expression */ 13192 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13193 { 13194 char_u *save_cpo; 13195 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13196 long retval = 0; 13197 pos_T pos; 13198 pos_T firstpos; 13199 pos_T foundpos; 13200 pos_T save_cursor; 13201 pos_T save_pos; 13202 int n; 13203 int r; 13204 int nest = 1; 13205 int err; 13206 13207 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13208 save_cpo = p_cpo; 13209 p_cpo = (char_u *)""; 13210 13211 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13212 * start/middle/end (pat3, for the top pair). */ 13213 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13214 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13215 if (pat2 == NULL || pat3 == NULL) 13216 goto theend; 13217 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13218 if (*mpat == NUL) 13219 STRCPY(pat3, pat2); 13220 else 13221 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13222 spat, epat, mpat); 13223 13224 save_cursor = curwin->w_cursor; 13225 pos = curwin->w_cursor; 13226 firstpos.lnum = 0; 13227 foundpos.lnum = 0; 13228 pat = pat3; 13229 for (;;) 13230 { 13231 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13232 SEARCH_KEEP, RE_SEARCH); 13233 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13234 /* didn't find it or found the first match again: FAIL */ 13235 break; 13236 13237 if (firstpos.lnum == 0) 13238 firstpos = pos; 13239 if (equalpos(pos, foundpos)) 13240 { 13241 /* Found the same position again. Can happen with a pattern that 13242 * has "\zs" at the end and searching backwards. Advance one 13243 * character and try again. */ 13244 if (dir == BACKWARD) 13245 decl(&pos); 13246 else 13247 incl(&pos); 13248 } 13249 foundpos = pos; 13250 13251 /* If the skip pattern matches, ignore this match. */ 13252 if (*skip != NUL) 13253 { 13254 save_pos = curwin->w_cursor; 13255 curwin->w_cursor = pos; 13256 r = eval_to_bool(skip, &err, NULL, FALSE); 13257 curwin->w_cursor = save_pos; 13258 if (err) 13259 { 13260 /* Evaluating {skip} caused an error, break here. */ 13261 curwin->w_cursor = save_cursor; 13262 retval = -1; 13263 break; 13264 } 13265 if (r) 13266 continue; 13267 } 13268 13269 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13270 { 13271 /* Found end when searching backwards or start when searching 13272 * forward: nested pair. */ 13273 ++nest; 13274 pat = pat2; /* nested, don't search for middle */ 13275 } 13276 else 13277 { 13278 /* Found end when searching forward or start when searching 13279 * backward: end of (nested) pair; or found middle in outer pair. */ 13280 if (--nest == 1) 13281 pat = pat3; /* outer level, search for middle */ 13282 } 13283 13284 if (nest == 0) 13285 { 13286 /* Found the match: return matchcount or line number. */ 13287 if (flags & SP_RETCOUNT) 13288 ++retval; 13289 else 13290 retval = pos.lnum; 13291 if (flags & SP_SETPCMARK) 13292 setpcmark(); 13293 curwin->w_cursor = pos; 13294 if (!(flags & SP_REPEAT)) 13295 break; 13296 nest = 1; /* search for next unmatched */ 13297 } 13298 } 13299 13300 /* If 'n' flag is used or search failed: restore cursor position. */ 13301 if ((flags & SP_NOMOVE) || retval == 0) 13302 curwin->w_cursor = save_cursor; 13303 13304 theend: 13305 vim_free(pat2); 13306 vim_free(pat3); 13307 p_cpo = save_cpo; 13308 13309 return retval; 13310 } 13311 13312 /*ARGSUSED*/ 13313 static void 13314 f_server2client(argvars, rettv) 13315 typval_T *argvars; 13316 typval_T *rettv; 13317 { 13318 #ifdef FEAT_CLIENTSERVER 13319 char_u buf[NUMBUFLEN]; 13320 char_u *server = get_tv_string_chk(&argvars[0]); 13321 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13322 13323 rettv->vval.v_number = -1; 13324 if (server == NULL || reply == NULL) 13325 return; 13326 if (check_restricted() || check_secure()) 13327 return; 13328 # ifdef FEAT_X11 13329 if (check_connection() == FAIL) 13330 return; 13331 # endif 13332 13333 if (serverSendReply(server, reply) < 0) 13334 { 13335 EMSG(_("E258: Unable to send to client")); 13336 return; 13337 } 13338 rettv->vval.v_number = 0; 13339 #else 13340 rettv->vval.v_number = -1; 13341 #endif 13342 } 13343 13344 /*ARGSUSED*/ 13345 static void 13346 f_serverlist(argvars, rettv) 13347 typval_T *argvars; 13348 typval_T *rettv; 13349 { 13350 char_u *r = NULL; 13351 13352 #ifdef FEAT_CLIENTSERVER 13353 # ifdef WIN32 13354 r = serverGetVimNames(); 13355 # else 13356 make_connection(); 13357 if (X_DISPLAY != NULL) 13358 r = serverGetVimNames(X_DISPLAY); 13359 # endif 13360 #endif 13361 rettv->v_type = VAR_STRING; 13362 rettv->vval.v_string = r; 13363 } 13364 13365 /* 13366 * "setbufvar()" function 13367 */ 13368 /*ARGSUSED*/ 13369 static void 13370 f_setbufvar(argvars, rettv) 13371 typval_T *argvars; 13372 typval_T *rettv; 13373 { 13374 buf_T *buf; 13375 #ifdef FEAT_AUTOCMD 13376 aco_save_T aco; 13377 #else 13378 buf_T *save_curbuf; 13379 #endif 13380 char_u *varname, *bufvarname; 13381 typval_T *varp; 13382 char_u nbuf[NUMBUFLEN]; 13383 13384 rettv->vval.v_number = 0; 13385 13386 if (check_restricted() || check_secure()) 13387 return; 13388 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13389 varname = get_tv_string_chk(&argvars[1]); 13390 buf = get_buf_tv(&argvars[0]); 13391 varp = &argvars[2]; 13392 13393 if (buf != NULL && varname != NULL && varp != NULL) 13394 { 13395 /* set curbuf to be our buf, temporarily */ 13396 #ifdef FEAT_AUTOCMD 13397 aucmd_prepbuf(&aco, buf); 13398 #else 13399 save_curbuf = curbuf; 13400 curbuf = buf; 13401 #endif 13402 13403 if (*varname == '&') 13404 { 13405 long numval; 13406 char_u *strval; 13407 int error = FALSE; 13408 13409 ++varname; 13410 numval = get_tv_number_chk(varp, &error); 13411 strval = get_tv_string_buf_chk(varp, nbuf); 13412 if (!error && strval != NULL) 13413 set_option_value(varname, numval, strval, OPT_LOCAL); 13414 } 13415 else 13416 { 13417 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13418 if (bufvarname != NULL) 13419 { 13420 STRCPY(bufvarname, "b:"); 13421 STRCPY(bufvarname + 2, varname); 13422 set_var(bufvarname, varp, TRUE); 13423 vim_free(bufvarname); 13424 } 13425 } 13426 13427 /* reset notion of buffer */ 13428 #ifdef FEAT_AUTOCMD 13429 aucmd_restbuf(&aco); 13430 #else 13431 curbuf = save_curbuf; 13432 #endif 13433 } 13434 } 13435 13436 /* 13437 * "setcmdpos()" function 13438 */ 13439 static void 13440 f_setcmdpos(argvars, rettv) 13441 typval_T *argvars; 13442 typval_T *rettv; 13443 { 13444 int pos = (int)get_tv_number(&argvars[0]) - 1; 13445 13446 if (pos >= 0) 13447 rettv->vval.v_number = set_cmdline_pos(pos); 13448 } 13449 13450 /* 13451 * "setline()" function 13452 */ 13453 static void 13454 f_setline(argvars, rettv) 13455 typval_T *argvars; 13456 typval_T *rettv; 13457 { 13458 linenr_T lnum; 13459 char_u *line = NULL; 13460 list_T *l = NULL; 13461 listitem_T *li = NULL; 13462 long added = 0; 13463 linenr_T lcount = curbuf->b_ml.ml_line_count; 13464 13465 lnum = get_tv_lnum(&argvars[0]); 13466 if (argvars[1].v_type == VAR_LIST) 13467 { 13468 l = argvars[1].vval.v_list; 13469 li = l->lv_first; 13470 } 13471 else 13472 line = get_tv_string_chk(&argvars[1]); 13473 13474 rettv->vval.v_number = 0; /* OK */ 13475 for (;;) 13476 { 13477 if (l != NULL) 13478 { 13479 /* list argument, get next string */ 13480 if (li == NULL) 13481 break; 13482 line = get_tv_string_chk(&li->li_tv); 13483 li = li->li_next; 13484 } 13485 13486 rettv->vval.v_number = 1; /* FAIL */ 13487 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13488 break; 13489 if (lnum <= curbuf->b_ml.ml_line_count) 13490 { 13491 /* existing line, replace it */ 13492 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13493 { 13494 changed_bytes(lnum, 0); 13495 check_cursor_col(); 13496 rettv->vval.v_number = 0; /* OK */ 13497 } 13498 } 13499 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13500 { 13501 /* lnum is one past the last line, append the line */ 13502 ++added; 13503 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13504 rettv->vval.v_number = 0; /* OK */ 13505 } 13506 13507 if (l == NULL) /* only one string argument */ 13508 break; 13509 ++lnum; 13510 } 13511 13512 if (added > 0) 13513 appended_lines_mark(lcount, added); 13514 } 13515 13516 /* 13517 * "setqflist()" function 13518 */ 13519 /*ARGSUSED*/ 13520 static void 13521 f_setqflist(argvars, rettv) 13522 typval_T *argvars; 13523 typval_T *rettv; 13524 { 13525 char_u *act; 13526 int action = ' '; 13527 13528 rettv->vval.v_number = -1; 13529 13530 #ifdef FEAT_QUICKFIX 13531 if (argvars[0].v_type != VAR_LIST) 13532 EMSG(_(e_listreq)); 13533 else 13534 { 13535 list_T *l = argvars[0].vval.v_list; 13536 13537 if (argvars[1].v_type == VAR_STRING) 13538 { 13539 act = get_tv_string_chk(&argvars[1]); 13540 if (act == NULL) 13541 return; /* type error; errmsg already given */ 13542 if (*act == 'a' || *act == 'r') 13543 action = *act; 13544 } 13545 13546 if (l != NULL && set_errorlist(l, action) == OK) 13547 rettv->vval.v_number = 0; 13548 } 13549 #endif 13550 } 13551 13552 /* 13553 * "setreg()" function 13554 */ 13555 static void 13556 f_setreg(argvars, rettv) 13557 typval_T *argvars; 13558 typval_T *rettv; 13559 { 13560 int regname; 13561 char_u *strregname; 13562 char_u *stropt; 13563 char_u *strval; 13564 int append; 13565 char_u yank_type; 13566 long block_len; 13567 13568 block_len = -1; 13569 yank_type = MAUTO; 13570 append = FALSE; 13571 13572 strregname = get_tv_string_chk(argvars); 13573 rettv->vval.v_number = 1; /* FAIL is default */ 13574 13575 if (strregname == NULL) 13576 return; /* type error; errmsg already given */ 13577 regname = *strregname; 13578 if (regname == 0 || regname == '@') 13579 regname = '"'; 13580 else if (regname == '=') 13581 return; 13582 13583 if (argvars[2].v_type != VAR_UNKNOWN) 13584 { 13585 stropt = get_tv_string_chk(&argvars[2]); 13586 if (stropt == NULL) 13587 return; /* type error */ 13588 for (; *stropt != NUL; ++stropt) 13589 switch (*stropt) 13590 { 13591 case 'a': case 'A': /* append */ 13592 append = TRUE; 13593 break; 13594 case 'v': case 'c': /* character-wise selection */ 13595 yank_type = MCHAR; 13596 break; 13597 case 'V': case 'l': /* line-wise selection */ 13598 yank_type = MLINE; 13599 break; 13600 #ifdef FEAT_VISUAL 13601 case 'b': case Ctrl_V: /* block-wise selection */ 13602 yank_type = MBLOCK; 13603 if (VIM_ISDIGIT(stropt[1])) 13604 { 13605 ++stropt; 13606 block_len = getdigits(&stropt) - 1; 13607 --stropt; 13608 } 13609 break; 13610 #endif 13611 } 13612 } 13613 13614 strval = get_tv_string_chk(&argvars[1]); 13615 if (strval != NULL) 13616 write_reg_contents_ex(regname, strval, -1, 13617 append, yank_type, block_len); 13618 rettv->vval.v_number = 0; 13619 } 13620 13621 13622 /* 13623 * "setwinvar(expr)" function 13624 */ 13625 /*ARGSUSED*/ 13626 static void 13627 f_setwinvar(argvars, rettv) 13628 typval_T *argvars; 13629 typval_T *rettv; 13630 { 13631 win_T *win; 13632 #ifdef FEAT_WINDOWS 13633 win_T *save_curwin; 13634 #endif 13635 char_u *varname, *winvarname; 13636 typval_T *varp; 13637 char_u nbuf[NUMBUFLEN]; 13638 13639 rettv->vval.v_number = 0; 13640 13641 if (check_restricted() || check_secure()) 13642 return; 13643 win = find_win_by_nr(&argvars[0]); 13644 varname = get_tv_string_chk(&argvars[1]); 13645 varp = &argvars[2]; 13646 13647 if (win != NULL && varname != NULL && varp != NULL) 13648 { 13649 #ifdef FEAT_WINDOWS 13650 /* set curwin to be our win, temporarily */ 13651 save_curwin = curwin; 13652 curwin = win; 13653 curbuf = curwin->w_buffer; 13654 #endif 13655 13656 if (*varname == '&') 13657 { 13658 long numval; 13659 char_u *strval; 13660 int error = FALSE; 13661 13662 ++varname; 13663 numval = get_tv_number_chk(varp, &error); 13664 strval = get_tv_string_buf_chk(varp, nbuf); 13665 if (!error && strval != NULL) 13666 set_option_value(varname, numval, strval, OPT_LOCAL); 13667 } 13668 else 13669 { 13670 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13671 if (winvarname != NULL) 13672 { 13673 STRCPY(winvarname, "w:"); 13674 STRCPY(winvarname + 2, varname); 13675 set_var(winvarname, varp, TRUE); 13676 vim_free(winvarname); 13677 } 13678 } 13679 13680 #ifdef FEAT_WINDOWS 13681 /* Restore current window, if it's still valid (autocomands can make 13682 * it invalid). */ 13683 if (win_valid(save_curwin)) 13684 { 13685 curwin = save_curwin; 13686 curbuf = curwin->w_buffer; 13687 } 13688 #endif 13689 } 13690 } 13691 13692 /* 13693 * "simplify()" function 13694 */ 13695 static void 13696 f_simplify(argvars, rettv) 13697 typval_T *argvars; 13698 typval_T *rettv; 13699 { 13700 char_u *p; 13701 13702 p = get_tv_string(&argvars[0]); 13703 rettv->vval.v_string = vim_strsave(p); 13704 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13705 rettv->v_type = VAR_STRING; 13706 } 13707 13708 static int 13709 #ifdef __BORLANDC__ 13710 _RTLENTRYF 13711 #endif 13712 item_compare __ARGS((const void *s1, const void *s2)); 13713 static int 13714 #ifdef __BORLANDC__ 13715 _RTLENTRYF 13716 #endif 13717 item_compare2 __ARGS((const void *s1, const void *s2)); 13718 13719 static int item_compare_ic; 13720 static char_u *item_compare_func; 13721 static int item_compare_func_err; 13722 #define ITEM_COMPARE_FAIL 999 13723 13724 /* 13725 * Compare functions for f_sort() below. 13726 */ 13727 static int 13728 #ifdef __BORLANDC__ 13729 _RTLENTRYF 13730 #endif 13731 item_compare(s1, s2) 13732 const void *s1; 13733 const void *s2; 13734 { 13735 char_u *p1, *p2; 13736 char_u *tofree1, *tofree2; 13737 int res; 13738 char_u numbuf1[NUMBUFLEN]; 13739 char_u numbuf2[NUMBUFLEN]; 13740 13741 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13742 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13743 if (item_compare_ic) 13744 res = STRICMP(p1, p2); 13745 else 13746 res = STRCMP(p1, p2); 13747 vim_free(tofree1); 13748 vim_free(tofree2); 13749 return res; 13750 } 13751 13752 static int 13753 #ifdef __BORLANDC__ 13754 _RTLENTRYF 13755 #endif 13756 item_compare2(s1, s2) 13757 const void *s1; 13758 const void *s2; 13759 { 13760 int res; 13761 typval_T rettv; 13762 typval_T argv[2]; 13763 int dummy; 13764 13765 /* shortcut after failure in previous call; compare all items equal */ 13766 if (item_compare_func_err) 13767 return 0; 13768 13769 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13770 * in the copy without changing the original list items. */ 13771 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13772 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13773 13774 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13775 res = call_func(item_compare_func, STRLEN(item_compare_func), 13776 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13777 clear_tv(&argv[0]); 13778 clear_tv(&argv[1]); 13779 13780 if (res == FAIL) 13781 res = ITEM_COMPARE_FAIL; 13782 else 13783 /* return value has wrong type */ 13784 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13785 if (item_compare_func_err) 13786 res = ITEM_COMPARE_FAIL; 13787 clear_tv(&rettv); 13788 return res; 13789 } 13790 13791 /* 13792 * "sort({list})" function 13793 */ 13794 static void 13795 f_sort(argvars, rettv) 13796 typval_T *argvars; 13797 typval_T *rettv; 13798 { 13799 list_T *l; 13800 listitem_T *li; 13801 listitem_T **ptrs; 13802 long len; 13803 long i; 13804 13805 rettv->vval.v_number = 0; 13806 if (argvars[0].v_type != VAR_LIST) 13807 EMSG2(_(e_listarg), "sort()"); 13808 else 13809 { 13810 l = argvars[0].vval.v_list; 13811 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13812 return; 13813 rettv->vval.v_list = l; 13814 rettv->v_type = VAR_LIST; 13815 ++l->lv_refcount; 13816 13817 len = list_len(l); 13818 if (len <= 1) 13819 return; /* short list sorts pretty quickly */ 13820 13821 item_compare_ic = FALSE; 13822 item_compare_func = NULL; 13823 if (argvars[1].v_type != VAR_UNKNOWN) 13824 { 13825 if (argvars[1].v_type == VAR_FUNC) 13826 item_compare_func = argvars[1].vval.v_string; 13827 else 13828 { 13829 int error = FALSE; 13830 13831 i = get_tv_number_chk(&argvars[1], &error); 13832 if (error) 13833 return; /* type error; errmsg already given */ 13834 if (i == 1) 13835 item_compare_ic = TRUE; 13836 else 13837 item_compare_func = get_tv_string(&argvars[1]); 13838 } 13839 } 13840 13841 /* Make an array with each entry pointing to an item in the List. */ 13842 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13843 if (ptrs == NULL) 13844 return; 13845 i = 0; 13846 for (li = l->lv_first; li != NULL; li = li->li_next) 13847 ptrs[i++] = li; 13848 13849 item_compare_func_err = FALSE; 13850 /* test the compare function */ 13851 if (item_compare_func != NULL 13852 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13853 == ITEM_COMPARE_FAIL) 13854 EMSG(_("E702: Sort compare function failed")); 13855 else 13856 { 13857 /* Sort the array with item pointers. */ 13858 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13859 item_compare_func == NULL ? item_compare : item_compare2); 13860 13861 if (!item_compare_func_err) 13862 { 13863 /* Clear the List and append the items in the sorted order. */ 13864 l->lv_first = l->lv_last = NULL; 13865 l->lv_len = 0; 13866 for (i = 0; i < len; ++i) 13867 list_append(l, ptrs[i]); 13868 } 13869 } 13870 13871 vim_free(ptrs); 13872 } 13873 } 13874 13875 /* 13876 * "soundfold({word})" function 13877 */ 13878 static void 13879 f_soundfold(argvars, rettv) 13880 typval_T *argvars; 13881 typval_T *rettv; 13882 { 13883 char_u *s; 13884 13885 rettv->v_type = VAR_STRING; 13886 s = get_tv_string(&argvars[0]); 13887 #ifdef FEAT_SYN_HL 13888 rettv->vval.v_string = eval_soundfold(s); 13889 #else 13890 rettv->vval.v_string = vim_strsave(s); 13891 #endif 13892 } 13893 13894 /* 13895 * "spellbadword()" function 13896 */ 13897 /* ARGSUSED */ 13898 static void 13899 f_spellbadword(argvars, rettv) 13900 typval_T *argvars; 13901 typval_T *rettv; 13902 { 13903 char_u *word = (char_u *)""; 13904 #ifdef FEAT_SYN_HL 13905 int len = 0; 13906 hlf_T attr = HLF_COUNT; 13907 list_T *l; 13908 #endif 13909 13910 l = list_alloc(); 13911 if (l == NULL) 13912 return; 13913 rettv->v_type = VAR_LIST; 13914 rettv->vval.v_list = l; 13915 ++l->lv_refcount; 13916 13917 #ifdef FEAT_SYN_HL 13918 if (argvars[0].v_type == VAR_UNKNOWN) 13919 { 13920 /* Find the start and length of the badly spelled word. */ 13921 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 13922 if (len != 0) 13923 word = ml_get_cursor(); 13924 } 13925 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13926 { 13927 char_u *str = get_tv_string_chk(&argvars[0]); 13928 int capcol = -1; 13929 13930 if (str != NULL) 13931 { 13932 /* Check the argument for spelling. */ 13933 while (*str != NUL) 13934 { 13935 len = spell_check(curwin, str, &attr, &capcol); 13936 if (attr != HLF_COUNT) 13937 { 13938 word = str; 13939 break; 13940 } 13941 str += len; 13942 } 13943 } 13944 } 13945 #endif 13946 13947 list_append_string(l, word, len); 13948 list_append_string(l, (char_u *)( 13949 attr == HLF_SPB ? "bad" : 13950 attr == HLF_SPR ? "rare" : 13951 attr == HLF_SPL ? "local" : 13952 attr == HLF_SPC ? "caps" : 13953 ""), -1); 13954 } 13955 13956 /* 13957 * "spellsuggest()" function 13958 */ 13959 static void 13960 f_spellsuggest(argvars, rettv) 13961 typval_T *argvars; 13962 typval_T *rettv; 13963 { 13964 char_u *str; 13965 int maxcount; 13966 garray_T ga; 13967 list_T *l; 13968 listitem_T *li; 13969 int i; 13970 13971 l = list_alloc(); 13972 if (l == NULL) 13973 return; 13974 rettv->v_type = VAR_LIST; 13975 rettv->vval.v_list = l; 13976 ++l->lv_refcount; 13977 13978 #ifdef FEAT_SYN_HL 13979 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13980 { 13981 str = get_tv_string(&argvars[0]); 13982 if (argvars[1].v_type != VAR_UNKNOWN) 13983 { 13984 maxcount = get_tv_number(&argvars[1]); 13985 if (maxcount <= 0) 13986 return; 13987 } 13988 else 13989 maxcount = 25; 13990 13991 spell_suggest_list(&ga, str, maxcount, FALSE); 13992 13993 for (i = 0; i < ga.ga_len; ++i) 13994 { 13995 str = ((char_u **)ga.ga_data)[i]; 13996 13997 li = listitem_alloc(); 13998 if (li == NULL) 13999 vim_free(str); 14000 else 14001 { 14002 li->li_tv.v_type = VAR_STRING; 14003 li->li_tv.v_lock = 0; 14004 li->li_tv.vval.v_string = str; 14005 list_append(l, li); 14006 } 14007 } 14008 ga_clear(&ga); 14009 } 14010 #endif 14011 } 14012 14013 static void 14014 f_split(argvars, rettv) 14015 typval_T *argvars; 14016 typval_T *rettv; 14017 { 14018 char_u *str; 14019 char_u *end; 14020 char_u *pat = NULL; 14021 regmatch_T regmatch; 14022 char_u patbuf[NUMBUFLEN]; 14023 char_u *save_cpo; 14024 int match; 14025 list_T *l; 14026 colnr_T col = 0; 14027 int keepempty = FALSE; 14028 int typeerr = FALSE; 14029 14030 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14031 save_cpo = p_cpo; 14032 p_cpo = (char_u *)""; 14033 14034 str = get_tv_string(&argvars[0]); 14035 if (argvars[1].v_type != VAR_UNKNOWN) 14036 { 14037 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14038 if (pat == NULL) 14039 typeerr = TRUE; 14040 if (argvars[2].v_type != VAR_UNKNOWN) 14041 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 14042 } 14043 if (pat == NULL || *pat == NUL) 14044 pat = (char_u *)"[\\x01- ]\\+"; 14045 14046 l = list_alloc(); 14047 if (l == NULL) 14048 return; 14049 rettv->v_type = VAR_LIST; 14050 rettv->vval.v_list = l; 14051 ++l->lv_refcount; 14052 if (typeerr) 14053 return; 14054 14055 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14056 if (regmatch.regprog != NULL) 14057 { 14058 regmatch.rm_ic = FALSE; 14059 while (*str != NUL || keepempty) 14060 { 14061 if (*str == NUL) 14062 match = FALSE; /* empty item at the end */ 14063 else 14064 match = vim_regexec_nl(®match, str, col); 14065 if (match) 14066 end = regmatch.startp[0]; 14067 else 14068 end = str + STRLEN(str); 14069 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 14070 && match && end < regmatch.endp[0])) 14071 { 14072 if (list_append_string(l, str, (int)(end - str)) == FAIL) 14073 break; 14074 } 14075 if (!match) 14076 break; 14077 /* Advance to just after the match. */ 14078 if (regmatch.endp[0] > str) 14079 col = 0; 14080 else 14081 { 14082 /* Don't get stuck at the same match. */ 14083 #ifdef FEAT_MBYTE 14084 col = (*mb_ptr2len)(regmatch.endp[0]); 14085 #else 14086 col = 1; 14087 #endif 14088 } 14089 str = regmatch.endp[0]; 14090 } 14091 14092 vim_free(regmatch.regprog); 14093 } 14094 14095 p_cpo = save_cpo; 14096 } 14097 14098 #ifdef HAVE_STRFTIME 14099 /* 14100 * "strftime({format}[, {time}])" function 14101 */ 14102 static void 14103 f_strftime(argvars, rettv) 14104 typval_T *argvars; 14105 typval_T *rettv; 14106 { 14107 char_u result_buf[256]; 14108 struct tm *curtime; 14109 time_t seconds; 14110 char_u *p; 14111 14112 rettv->v_type = VAR_STRING; 14113 14114 p = get_tv_string(&argvars[0]); 14115 if (argvars[1].v_type == VAR_UNKNOWN) 14116 seconds = time(NULL); 14117 else 14118 seconds = (time_t)get_tv_number(&argvars[1]); 14119 curtime = localtime(&seconds); 14120 /* MSVC returns NULL for an invalid value of seconds. */ 14121 if (curtime == NULL) 14122 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 14123 else 14124 { 14125 # ifdef FEAT_MBYTE 14126 vimconv_T conv; 14127 char_u *enc; 14128 14129 conv.vc_type = CONV_NONE; 14130 enc = enc_locale(); 14131 convert_setup(&conv, p_enc, enc); 14132 if (conv.vc_type != CONV_NONE) 14133 p = string_convert(&conv, p, NULL); 14134 # endif 14135 if (p != NULL) 14136 (void)strftime((char *)result_buf, sizeof(result_buf), 14137 (char *)p, curtime); 14138 else 14139 result_buf[0] = NUL; 14140 14141 # ifdef FEAT_MBYTE 14142 if (conv.vc_type != CONV_NONE) 14143 vim_free(p); 14144 convert_setup(&conv, enc, p_enc); 14145 if (conv.vc_type != CONV_NONE) 14146 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 14147 else 14148 # endif 14149 rettv->vval.v_string = vim_strsave(result_buf); 14150 14151 # ifdef FEAT_MBYTE 14152 /* Release conversion descriptors */ 14153 convert_setup(&conv, NULL, NULL); 14154 vim_free(enc); 14155 # endif 14156 } 14157 } 14158 #endif 14159 14160 /* 14161 * "stridx()" function 14162 */ 14163 static void 14164 f_stridx(argvars, rettv) 14165 typval_T *argvars; 14166 typval_T *rettv; 14167 { 14168 char_u buf[NUMBUFLEN]; 14169 char_u *needle; 14170 char_u *haystack; 14171 char_u *save_haystack; 14172 char_u *pos; 14173 int start_idx; 14174 14175 needle = get_tv_string_chk(&argvars[1]); 14176 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 14177 rettv->vval.v_number = -1; 14178 if (needle == NULL || haystack == NULL) 14179 return; /* type error; errmsg already given */ 14180 14181 if (argvars[2].v_type != VAR_UNKNOWN) 14182 { 14183 int error = FALSE; 14184 14185 start_idx = get_tv_number_chk(&argvars[2], &error); 14186 if (error || start_idx >= (int)STRLEN(haystack)) 14187 return; 14188 if (start_idx >= 0) 14189 haystack += start_idx; 14190 } 14191 14192 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14193 if (pos != NULL) 14194 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14195 } 14196 14197 /* 14198 * "string()" function 14199 */ 14200 static void 14201 f_string(argvars, rettv) 14202 typval_T *argvars; 14203 typval_T *rettv; 14204 { 14205 char_u *tofree; 14206 char_u numbuf[NUMBUFLEN]; 14207 14208 rettv->v_type = VAR_STRING; 14209 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14210 if (tofree == NULL) 14211 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14212 } 14213 14214 /* 14215 * "strlen()" function 14216 */ 14217 static void 14218 f_strlen(argvars, rettv) 14219 typval_T *argvars; 14220 typval_T *rettv; 14221 { 14222 rettv->vval.v_number = (varnumber_T)(STRLEN( 14223 get_tv_string(&argvars[0]))); 14224 } 14225 14226 /* 14227 * "strpart()" function 14228 */ 14229 static void 14230 f_strpart(argvars, rettv) 14231 typval_T *argvars; 14232 typval_T *rettv; 14233 { 14234 char_u *p; 14235 int n; 14236 int len; 14237 int slen; 14238 int error = FALSE; 14239 14240 p = get_tv_string(&argvars[0]); 14241 slen = (int)STRLEN(p); 14242 14243 n = get_tv_number_chk(&argvars[1], &error); 14244 if (error) 14245 len = 0; 14246 else if (argvars[2].v_type != VAR_UNKNOWN) 14247 len = get_tv_number(&argvars[2]); 14248 else 14249 len = slen - n; /* default len: all bytes that are available. */ 14250 14251 /* 14252 * Only return the overlap between the specified part and the actual 14253 * string. 14254 */ 14255 if (n < 0) 14256 { 14257 len += n; 14258 n = 0; 14259 } 14260 else if (n > slen) 14261 n = slen; 14262 if (len < 0) 14263 len = 0; 14264 else if (n + len > slen) 14265 len = slen - n; 14266 14267 rettv->v_type = VAR_STRING; 14268 rettv->vval.v_string = vim_strnsave(p + n, len); 14269 } 14270 14271 /* 14272 * "strridx()" function 14273 */ 14274 static void 14275 f_strridx(argvars, rettv) 14276 typval_T *argvars; 14277 typval_T *rettv; 14278 { 14279 char_u buf[NUMBUFLEN]; 14280 char_u *needle; 14281 char_u *haystack; 14282 char_u *rest; 14283 char_u *lastmatch = NULL; 14284 int haystack_len, end_idx; 14285 14286 needle = get_tv_string_chk(&argvars[1]); 14287 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14288 haystack_len = STRLEN(haystack); 14289 14290 rettv->vval.v_number = -1; 14291 if (needle == NULL || haystack == NULL) 14292 return; /* type error; errmsg already given */ 14293 if (argvars[2].v_type != VAR_UNKNOWN) 14294 { 14295 /* Third argument: upper limit for index */ 14296 end_idx = get_tv_number_chk(&argvars[2], NULL); 14297 if (end_idx < 0) 14298 return; /* can never find a match */ 14299 } 14300 else 14301 end_idx = haystack_len; 14302 14303 if (*needle == NUL) 14304 { 14305 /* Empty string matches past the end. */ 14306 lastmatch = haystack + end_idx; 14307 } 14308 else 14309 { 14310 for (rest = haystack; *rest != '\0'; ++rest) 14311 { 14312 rest = (char_u *)strstr((char *)rest, (char *)needle); 14313 if (rest == NULL || rest > haystack + end_idx) 14314 break; 14315 lastmatch = rest; 14316 } 14317 } 14318 14319 if (lastmatch == NULL) 14320 rettv->vval.v_number = -1; 14321 else 14322 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14323 } 14324 14325 /* 14326 * "strtrans()" function 14327 */ 14328 static void 14329 f_strtrans(argvars, rettv) 14330 typval_T *argvars; 14331 typval_T *rettv; 14332 { 14333 rettv->v_type = VAR_STRING; 14334 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14335 } 14336 14337 /* 14338 * "submatch()" function 14339 */ 14340 static void 14341 f_submatch(argvars, rettv) 14342 typval_T *argvars; 14343 typval_T *rettv; 14344 { 14345 rettv->v_type = VAR_STRING; 14346 rettv->vval.v_string = 14347 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14348 } 14349 14350 /* 14351 * "substitute()" function 14352 */ 14353 static void 14354 f_substitute(argvars, rettv) 14355 typval_T *argvars; 14356 typval_T *rettv; 14357 { 14358 char_u patbuf[NUMBUFLEN]; 14359 char_u subbuf[NUMBUFLEN]; 14360 char_u flagsbuf[NUMBUFLEN]; 14361 14362 char_u *str = get_tv_string_chk(&argvars[0]); 14363 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14364 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14365 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14366 14367 rettv->v_type = VAR_STRING; 14368 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14369 rettv->vval.v_string = NULL; 14370 else 14371 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14372 } 14373 14374 /* 14375 * "synID(lnum, col, trans)" function 14376 */ 14377 /*ARGSUSED*/ 14378 static void 14379 f_synID(argvars, rettv) 14380 typval_T *argvars; 14381 typval_T *rettv; 14382 { 14383 int id = 0; 14384 #ifdef FEAT_SYN_HL 14385 long lnum; 14386 long col; 14387 int trans; 14388 int transerr = FALSE; 14389 14390 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14391 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14392 trans = get_tv_number_chk(&argvars[2], &transerr); 14393 14394 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14395 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14396 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14397 #endif 14398 14399 rettv->vval.v_number = id; 14400 } 14401 14402 /* 14403 * "synIDattr(id, what [, mode])" function 14404 */ 14405 /*ARGSUSED*/ 14406 static void 14407 f_synIDattr(argvars, rettv) 14408 typval_T *argvars; 14409 typval_T *rettv; 14410 { 14411 char_u *p = NULL; 14412 #ifdef FEAT_SYN_HL 14413 int id; 14414 char_u *what; 14415 char_u *mode; 14416 char_u modebuf[NUMBUFLEN]; 14417 int modec; 14418 14419 id = get_tv_number(&argvars[0]); 14420 what = get_tv_string(&argvars[1]); 14421 if (argvars[2].v_type != VAR_UNKNOWN) 14422 { 14423 mode = get_tv_string_buf(&argvars[2], modebuf); 14424 modec = TOLOWER_ASC(mode[0]); 14425 if (modec != 't' && modec != 'c' 14426 #ifdef FEAT_GUI 14427 && modec != 'g' 14428 #endif 14429 ) 14430 modec = 0; /* replace invalid with current */ 14431 } 14432 else 14433 { 14434 #ifdef FEAT_GUI 14435 if (gui.in_use) 14436 modec = 'g'; 14437 else 14438 #endif 14439 if (t_colors > 1) 14440 modec = 'c'; 14441 else 14442 modec = 't'; 14443 } 14444 14445 14446 switch (TOLOWER_ASC(what[0])) 14447 { 14448 case 'b': 14449 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14450 p = highlight_color(id, what, modec); 14451 else /* bold */ 14452 p = highlight_has_attr(id, HL_BOLD, modec); 14453 break; 14454 14455 case 'f': /* fg[#] */ 14456 p = highlight_color(id, what, modec); 14457 break; 14458 14459 case 'i': 14460 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14461 p = highlight_has_attr(id, HL_INVERSE, modec); 14462 else /* italic */ 14463 p = highlight_has_attr(id, HL_ITALIC, modec); 14464 break; 14465 14466 case 'n': /* name */ 14467 p = get_highlight_name(NULL, id - 1); 14468 break; 14469 14470 case 'r': /* reverse */ 14471 p = highlight_has_attr(id, HL_INVERSE, modec); 14472 break; 14473 14474 case 's': /* standout */ 14475 p = highlight_has_attr(id, HL_STANDOUT, modec); 14476 break; 14477 14478 case 'u': 14479 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14480 /* underline */ 14481 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14482 else 14483 /* undercurl */ 14484 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14485 break; 14486 } 14487 14488 if (p != NULL) 14489 p = vim_strsave(p); 14490 #endif 14491 rettv->v_type = VAR_STRING; 14492 rettv->vval.v_string = p; 14493 } 14494 14495 /* 14496 * "synIDtrans(id)" function 14497 */ 14498 /*ARGSUSED*/ 14499 static void 14500 f_synIDtrans(argvars, rettv) 14501 typval_T *argvars; 14502 typval_T *rettv; 14503 { 14504 int id; 14505 14506 #ifdef FEAT_SYN_HL 14507 id = get_tv_number(&argvars[0]); 14508 14509 if (id > 0) 14510 id = syn_get_final_id(id); 14511 else 14512 #endif 14513 id = 0; 14514 14515 rettv->vval.v_number = id; 14516 } 14517 14518 /* 14519 * "system()" function 14520 */ 14521 static void 14522 f_system(argvars, rettv) 14523 typval_T *argvars; 14524 typval_T *rettv; 14525 { 14526 char_u *res = NULL; 14527 char_u *p; 14528 char_u *infile = NULL; 14529 char_u buf[NUMBUFLEN]; 14530 int err = FALSE; 14531 FILE *fd; 14532 14533 if (argvars[1].v_type != VAR_UNKNOWN) 14534 { 14535 /* 14536 * Write the string to a temp file, to be used for input of the shell 14537 * command. 14538 */ 14539 if ((infile = vim_tempname('i')) == NULL) 14540 { 14541 EMSG(_(e_notmp)); 14542 return; 14543 } 14544 14545 fd = mch_fopen((char *)infile, WRITEBIN); 14546 if (fd == NULL) 14547 { 14548 EMSG2(_(e_notopen), infile); 14549 goto done; 14550 } 14551 p = get_tv_string_buf_chk(&argvars[1], buf); 14552 if (p == NULL) 14553 goto done; /* type error; errmsg already given */ 14554 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14555 err = TRUE; 14556 if (fclose(fd) != 0) 14557 err = TRUE; 14558 if (err) 14559 { 14560 EMSG(_("E677: Error writing temp file")); 14561 goto done; 14562 } 14563 } 14564 14565 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14566 14567 #ifdef USE_CR 14568 /* translate <CR> into <NL> */ 14569 if (res != NULL) 14570 { 14571 char_u *s; 14572 14573 for (s = res; *s; ++s) 14574 { 14575 if (*s == CAR) 14576 *s = NL; 14577 } 14578 } 14579 #else 14580 # ifdef USE_CRNL 14581 /* translate <CR><NL> into <NL> */ 14582 if (res != NULL) 14583 { 14584 char_u *s, *d; 14585 14586 d = res; 14587 for (s = res; *s; ++s) 14588 { 14589 if (s[0] == CAR && s[1] == NL) 14590 ++s; 14591 *d++ = *s; 14592 } 14593 *d = NUL; 14594 } 14595 # endif 14596 #endif 14597 14598 done: 14599 if (infile != NULL) 14600 { 14601 mch_remove(infile); 14602 vim_free(infile); 14603 } 14604 rettv->v_type = VAR_STRING; 14605 rettv->vval.v_string = res; 14606 } 14607 14608 /* 14609 * "tagfiles()" function 14610 */ 14611 /*ARGSUSED*/ 14612 static void 14613 f_tagfiles(argvars, rettv) 14614 typval_T *argvars; 14615 typval_T *rettv; 14616 { 14617 char_u fname[MAXPATHL + 1]; 14618 list_T *l; 14619 14620 l = list_alloc(); 14621 if (l == NULL) 14622 { 14623 rettv->vval.v_number = 0; 14624 return; 14625 } 14626 rettv->vval.v_list = l; 14627 rettv->v_type = VAR_LIST; 14628 ++l->lv_refcount; 14629 14630 get_tagfname(TRUE, NULL); 14631 for (;;) 14632 if (get_tagfname(FALSE, fname) == FAIL 14633 || list_append_string(l, fname, -1) == FAIL) 14634 break; 14635 } 14636 14637 /* 14638 * "taglist()" function 14639 */ 14640 static void 14641 f_taglist(argvars, rettv) 14642 typval_T *argvars; 14643 typval_T *rettv; 14644 { 14645 char_u *tag_pattern; 14646 list_T *l; 14647 14648 tag_pattern = get_tv_string(&argvars[0]); 14649 14650 rettv->vval.v_number = FALSE; 14651 if (*tag_pattern == NUL) 14652 return; 14653 14654 l = list_alloc(); 14655 if (l != NULL) 14656 { 14657 if (get_tags(l, tag_pattern) != FAIL) 14658 { 14659 rettv->vval.v_list = l; 14660 rettv->v_type = VAR_LIST; 14661 ++l->lv_refcount; 14662 } 14663 else 14664 list_free(l); 14665 } 14666 } 14667 14668 /* 14669 * "tempname()" function 14670 */ 14671 /*ARGSUSED*/ 14672 static void 14673 f_tempname(argvars, rettv) 14674 typval_T *argvars; 14675 typval_T *rettv; 14676 { 14677 static int x = 'A'; 14678 14679 rettv->v_type = VAR_STRING; 14680 rettv->vval.v_string = vim_tempname(x); 14681 14682 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14683 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14684 do 14685 { 14686 if (x == 'Z') 14687 x = '0'; 14688 else if (x == '9') 14689 x = 'A'; 14690 else 14691 { 14692 #ifdef EBCDIC 14693 if (x == 'I') 14694 x = 'J'; 14695 else if (x == 'R') 14696 x = 'S'; 14697 else 14698 #endif 14699 ++x; 14700 } 14701 } while (x == 'I' || x == 'O'); 14702 } 14703 14704 /* 14705 * "test(list)" function: Just checking the walls... 14706 */ 14707 /*ARGSUSED*/ 14708 static void 14709 f_test(argvars, rettv) 14710 typval_T *argvars; 14711 typval_T *rettv; 14712 { 14713 /* Used for unit testing. Change the code below to your liking. */ 14714 #if 0 14715 listitem_T *li; 14716 list_T *l; 14717 char_u *bad, *good; 14718 14719 if (argvars[0].v_type != VAR_LIST) 14720 return; 14721 l = argvars[0].vval.v_list; 14722 if (l == NULL) 14723 return; 14724 li = l->lv_first; 14725 if (li == NULL) 14726 return; 14727 bad = get_tv_string(&li->li_tv); 14728 li = li->li_next; 14729 if (li == NULL) 14730 return; 14731 good = get_tv_string(&li->li_tv); 14732 rettv->vval.v_number = test_edit_score(bad, good); 14733 #endif 14734 } 14735 14736 /* 14737 * "tolower(string)" function 14738 */ 14739 static void 14740 f_tolower(argvars, rettv) 14741 typval_T *argvars; 14742 typval_T *rettv; 14743 { 14744 char_u *p; 14745 14746 p = vim_strsave(get_tv_string(&argvars[0])); 14747 rettv->v_type = VAR_STRING; 14748 rettv->vval.v_string = p; 14749 14750 if (p != NULL) 14751 while (*p != NUL) 14752 { 14753 #ifdef FEAT_MBYTE 14754 int l; 14755 14756 if (enc_utf8) 14757 { 14758 int c, lc; 14759 14760 c = utf_ptr2char(p); 14761 lc = utf_tolower(c); 14762 l = utf_ptr2len(p); 14763 /* TODO: reallocate string when byte count changes. */ 14764 if (utf_char2len(lc) == l) 14765 utf_char2bytes(lc, p); 14766 p += l; 14767 } 14768 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14769 p += l; /* skip multi-byte character */ 14770 else 14771 #endif 14772 { 14773 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14774 ++p; 14775 } 14776 } 14777 } 14778 14779 /* 14780 * "toupper(string)" function 14781 */ 14782 static void 14783 f_toupper(argvars, rettv) 14784 typval_T *argvars; 14785 typval_T *rettv; 14786 { 14787 rettv->v_type = VAR_STRING; 14788 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14789 } 14790 14791 /* 14792 * "tr(string, fromstr, tostr)" function 14793 */ 14794 static void 14795 f_tr(argvars, rettv) 14796 typval_T *argvars; 14797 typval_T *rettv; 14798 { 14799 char_u *instr; 14800 char_u *fromstr; 14801 char_u *tostr; 14802 char_u *p; 14803 #ifdef FEAT_MBYTE 14804 int inlen; 14805 int fromlen; 14806 int tolen; 14807 int idx; 14808 char_u *cpstr; 14809 int cplen; 14810 int first = TRUE; 14811 #endif 14812 char_u buf[NUMBUFLEN]; 14813 char_u buf2[NUMBUFLEN]; 14814 garray_T ga; 14815 14816 instr = get_tv_string(&argvars[0]); 14817 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14818 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14819 14820 /* Default return value: empty string. */ 14821 rettv->v_type = VAR_STRING; 14822 rettv->vval.v_string = NULL; 14823 if (fromstr == NULL || tostr == NULL) 14824 return; /* type error; errmsg already given */ 14825 ga_init2(&ga, (int)sizeof(char), 80); 14826 14827 #ifdef FEAT_MBYTE 14828 if (!has_mbyte) 14829 #endif 14830 /* not multi-byte: fromstr and tostr must be the same length */ 14831 if (STRLEN(fromstr) != STRLEN(tostr)) 14832 { 14833 #ifdef FEAT_MBYTE 14834 error: 14835 #endif 14836 EMSG2(_(e_invarg2), fromstr); 14837 ga_clear(&ga); 14838 return; 14839 } 14840 14841 /* fromstr and tostr have to contain the same number of chars */ 14842 while (*instr != NUL) 14843 { 14844 #ifdef FEAT_MBYTE 14845 if (has_mbyte) 14846 { 14847 inlen = (*mb_ptr2len)(instr); 14848 cpstr = instr; 14849 cplen = inlen; 14850 idx = 0; 14851 for (p = fromstr; *p != NUL; p += fromlen) 14852 { 14853 fromlen = (*mb_ptr2len)(p); 14854 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14855 { 14856 for (p = tostr; *p != NUL; p += tolen) 14857 { 14858 tolen = (*mb_ptr2len)(p); 14859 if (idx-- == 0) 14860 { 14861 cplen = tolen; 14862 cpstr = p; 14863 break; 14864 } 14865 } 14866 if (*p == NUL) /* tostr is shorter than fromstr */ 14867 goto error; 14868 break; 14869 } 14870 ++idx; 14871 } 14872 14873 if (first && cpstr == instr) 14874 { 14875 /* Check that fromstr and tostr have the same number of 14876 * (multi-byte) characters. Done only once when a character 14877 * of instr doesn't appear in fromstr. */ 14878 first = FALSE; 14879 for (p = tostr; *p != NUL; p += tolen) 14880 { 14881 tolen = (*mb_ptr2len)(p); 14882 --idx; 14883 } 14884 if (idx != 0) 14885 goto error; 14886 } 14887 14888 ga_grow(&ga, cplen); 14889 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14890 ga.ga_len += cplen; 14891 14892 instr += inlen; 14893 } 14894 else 14895 #endif 14896 { 14897 /* When not using multi-byte chars we can do it faster. */ 14898 p = vim_strchr(fromstr, *instr); 14899 if (p != NULL) 14900 ga_append(&ga, tostr[p - fromstr]); 14901 else 14902 ga_append(&ga, *instr); 14903 ++instr; 14904 } 14905 } 14906 14907 rettv->vval.v_string = ga.ga_data; 14908 } 14909 14910 /* 14911 * "type(expr)" function 14912 */ 14913 static void 14914 f_type(argvars, rettv) 14915 typval_T *argvars; 14916 typval_T *rettv; 14917 { 14918 int n; 14919 14920 switch (argvars[0].v_type) 14921 { 14922 case VAR_NUMBER: n = 0; break; 14923 case VAR_STRING: n = 1; break; 14924 case VAR_FUNC: n = 2; break; 14925 case VAR_LIST: n = 3; break; 14926 case VAR_DICT: n = 4; break; 14927 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14928 } 14929 rettv->vval.v_number = n; 14930 } 14931 14932 /* 14933 * "values(dict)" function 14934 */ 14935 static void 14936 f_values(argvars, rettv) 14937 typval_T *argvars; 14938 typval_T *rettv; 14939 { 14940 dict_list(argvars, rettv, 1); 14941 } 14942 14943 /* 14944 * "virtcol(string)" function 14945 */ 14946 static void 14947 f_virtcol(argvars, rettv) 14948 typval_T *argvars; 14949 typval_T *rettv; 14950 { 14951 colnr_T vcol = 0; 14952 pos_T *fp; 14953 14954 fp = var2fpos(&argvars[0], FALSE); 14955 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14956 { 14957 getvvcol(curwin, fp, NULL, NULL, &vcol); 14958 ++vcol; 14959 } 14960 14961 rettv->vval.v_number = vcol; 14962 } 14963 14964 /* 14965 * "visualmode()" function 14966 */ 14967 /*ARGSUSED*/ 14968 static void 14969 f_visualmode(argvars, rettv) 14970 typval_T *argvars; 14971 typval_T *rettv; 14972 { 14973 #ifdef FEAT_VISUAL 14974 char_u str[2]; 14975 14976 rettv->v_type = VAR_STRING; 14977 str[0] = curbuf->b_visual_mode_eval; 14978 str[1] = NUL; 14979 rettv->vval.v_string = vim_strsave(str); 14980 14981 /* A non-zero number or non-empty string argument: reset mode. */ 14982 if ((argvars[0].v_type == VAR_NUMBER 14983 && argvars[0].vval.v_number != 0) 14984 || (argvars[0].v_type == VAR_STRING 14985 && *get_tv_string(&argvars[0]) != NUL)) 14986 curbuf->b_visual_mode_eval = NUL; 14987 #else 14988 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14989 #endif 14990 } 14991 14992 /* 14993 * "winbufnr(nr)" function 14994 */ 14995 static void 14996 f_winbufnr(argvars, rettv) 14997 typval_T *argvars; 14998 typval_T *rettv; 14999 { 15000 win_T *wp; 15001 15002 wp = find_win_by_nr(&argvars[0]); 15003 if (wp == NULL) 15004 rettv->vval.v_number = -1; 15005 else 15006 rettv->vval.v_number = wp->w_buffer->b_fnum; 15007 } 15008 15009 /* 15010 * "wincol()" function 15011 */ 15012 /*ARGSUSED*/ 15013 static void 15014 f_wincol(argvars, rettv) 15015 typval_T *argvars; 15016 typval_T *rettv; 15017 { 15018 validate_cursor(); 15019 rettv->vval.v_number = curwin->w_wcol + 1; 15020 } 15021 15022 /* 15023 * "winheight(nr)" function 15024 */ 15025 static void 15026 f_winheight(argvars, rettv) 15027 typval_T *argvars; 15028 typval_T *rettv; 15029 { 15030 win_T *wp; 15031 15032 wp = find_win_by_nr(&argvars[0]); 15033 if (wp == NULL) 15034 rettv->vval.v_number = -1; 15035 else 15036 rettv->vval.v_number = wp->w_height; 15037 } 15038 15039 /* 15040 * "winline()" function 15041 */ 15042 /*ARGSUSED*/ 15043 static void 15044 f_winline(argvars, rettv) 15045 typval_T *argvars; 15046 typval_T *rettv; 15047 { 15048 validate_cursor(); 15049 rettv->vval.v_number = curwin->w_wrow + 1; 15050 } 15051 15052 /* 15053 * "winnr()" function 15054 */ 15055 /* ARGSUSED */ 15056 static void 15057 f_winnr(argvars, rettv) 15058 typval_T *argvars; 15059 typval_T *rettv; 15060 { 15061 int nr = 1; 15062 #ifdef FEAT_WINDOWS 15063 win_T *wp; 15064 win_T *twin = curwin; 15065 char_u *arg; 15066 15067 if (argvars[0].v_type != VAR_UNKNOWN) 15068 { 15069 arg = get_tv_string_chk(&argvars[0]); 15070 if (arg == NULL) 15071 nr = 0; /* type error; errmsg already given */ 15072 else if (STRCMP(arg, "$") == 0) 15073 twin = lastwin; 15074 else if (STRCMP(arg, "#") == 0) 15075 { 15076 twin = prevwin; 15077 if (prevwin == NULL) 15078 nr = 0; 15079 } 15080 else 15081 { 15082 EMSG2(_(e_invexpr2), arg); 15083 nr = 0; 15084 } 15085 } 15086 15087 if (nr > 0) 15088 for (wp = firstwin; wp != twin; wp = wp->w_next) 15089 ++nr; 15090 #endif 15091 rettv->vval.v_number = nr; 15092 } 15093 15094 /* 15095 * "winrestcmd()" function 15096 */ 15097 /* ARGSUSED */ 15098 static void 15099 f_winrestcmd(argvars, rettv) 15100 typval_T *argvars; 15101 typval_T *rettv; 15102 { 15103 #ifdef FEAT_WINDOWS 15104 win_T *wp; 15105 int winnr = 1; 15106 garray_T ga; 15107 char_u buf[50]; 15108 15109 ga_init2(&ga, (int)sizeof(char), 70); 15110 for (wp = firstwin; wp != NULL; wp = wp->w_next) 15111 { 15112 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 15113 ga_concat(&ga, buf); 15114 # ifdef FEAT_VERTSPLIT 15115 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 15116 ga_concat(&ga, buf); 15117 # endif 15118 ++winnr; 15119 } 15120 ga_append(&ga, NUL); 15121 15122 rettv->vval.v_string = ga.ga_data; 15123 #else 15124 rettv->vval.v_string = NULL; 15125 #endif 15126 rettv->v_type = VAR_STRING; 15127 } 15128 15129 /* 15130 * "winwidth(nr)" function 15131 */ 15132 static void 15133 f_winwidth(argvars, rettv) 15134 typval_T *argvars; 15135 typval_T *rettv; 15136 { 15137 win_T *wp; 15138 15139 wp = find_win_by_nr(&argvars[0]); 15140 if (wp == NULL) 15141 rettv->vval.v_number = -1; 15142 else 15143 #ifdef FEAT_VERTSPLIT 15144 rettv->vval.v_number = wp->w_width; 15145 #else 15146 rettv->vval.v_number = Columns; 15147 #endif 15148 } 15149 15150 /* 15151 * "writefile()" function 15152 */ 15153 static void 15154 f_writefile(argvars, rettv) 15155 typval_T *argvars; 15156 typval_T *rettv; 15157 { 15158 int binary = FALSE; 15159 char_u *fname; 15160 FILE *fd; 15161 listitem_T *li; 15162 char_u *s; 15163 int ret = 0; 15164 int c; 15165 15166 if (argvars[0].v_type != VAR_LIST) 15167 { 15168 EMSG2(_(e_listarg), "writefile()"); 15169 return; 15170 } 15171 if (argvars[0].vval.v_list == NULL) 15172 return; 15173 15174 if (argvars[2].v_type != VAR_UNKNOWN 15175 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 15176 binary = TRUE; 15177 15178 /* Always open the file in binary mode, library functions have a mind of 15179 * their own about CR-LF conversion. */ 15180 fname = get_tv_string(&argvars[1]); 15181 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 15182 { 15183 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 15184 ret = -1; 15185 } 15186 else 15187 { 15188 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 15189 li = li->li_next) 15190 { 15191 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 15192 { 15193 if (*s == '\n') 15194 c = putc(NUL, fd); 15195 else 15196 c = putc(*s, fd); 15197 if (c == EOF) 15198 { 15199 ret = -1; 15200 break; 15201 } 15202 } 15203 if (!binary || li->li_next != NULL) 15204 if (putc('\n', fd) == EOF) 15205 { 15206 ret = -1; 15207 break; 15208 } 15209 if (ret < 0) 15210 { 15211 EMSG(_(e_write)); 15212 break; 15213 } 15214 } 15215 fclose(fd); 15216 } 15217 15218 rettv->vval.v_number = ret; 15219 } 15220 15221 /* 15222 * Translate a String variable into a position. 15223 */ 15224 static pos_T * 15225 var2fpos(varp, lnum) 15226 typval_T *varp; 15227 int lnum; /* TRUE when $ is last line */ 15228 { 15229 char_u *name; 15230 static pos_T pos; 15231 pos_T *pp; 15232 15233 name = get_tv_string_chk(varp); 15234 if (name == NULL) 15235 return NULL; 15236 if (name[0] == '.') /* cursor */ 15237 return &curwin->w_cursor; 15238 if (name[0] == '\'') /* mark */ 15239 { 15240 pp = getmark(name[1], FALSE); 15241 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15242 return NULL; 15243 return pp; 15244 } 15245 if (name[0] == '$') /* last column or line */ 15246 { 15247 if (lnum) 15248 { 15249 pos.lnum = curbuf->b_ml.ml_line_count; 15250 pos.col = 0; 15251 } 15252 else 15253 { 15254 pos.lnum = curwin->w_cursor.lnum; 15255 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15256 } 15257 return &pos; 15258 } 15259 return NULL; 15260 } 15261 15262 /* 15263 * Get the length of an environment variable name. 15264 * Advance "arg" to the first character after the name. 15265 * Return 0 for error. 15266 */ 15267 static int 15268 get_env_len(arg) 15269 char_u **arg; 15270 { 15271 char_u *p; 15272 int len; 15273 15274 for (p = *arg; vim_isIDc(*p); ++p) 15275 ; 15276 if (p == *arg) /* no name found */ 15277 return 0; 15278 15279 len = (int)(p - *arg); 15280 *arg = p; 15281 return len; 15282 } 15283 15284 /* 15285 * Get the length of the name of a function or internal variable. 15286 * "arg" is advanced to the first non-white character after the name. 15287 * Return 0 if something is wrong. 15288 */ 15289 static int 15290 get_id_len(arg) 15291 char_u **arg; 15292 { 15293 char_u *p; 15294 int len; 15295 15296 /* Find the end of the name. */ 15297 for (p = *arg; eval_isnamec(*p); ++p) 15298 ; 15299 if (p == *arg) /* no name found */ 15300 return 0; 15301 15302 len = (int)(p - *arg); 15303 *arg = skipwhite(p); 15304 15305 return len; 15306 } 15307 15308 /* 15309 * Get the length of the name of a variable or function. 15310 * Only the name is recognized, does not handle ".key" or "[idx]". 15311 * "arg" is advanced to the first non-white character after the name. 15312 * Return -1 if curly braces expansion failed. 15313 * Return 0 if something else is wrong. 15314 * If the name contains 'magic' {}'s, expand them and return the 15315 * expanded name in an allocated string via 'alias' - caller must free. 15316 */ 15317 static int 15318 get_name_len(arg, alias, evaluate, verbose) 15319 char_u **arg; 15320 char_u **alias; 15321 int evaluate; 15322 int verbose; 15323 { 15324 int len; 15325 char_u *p; 15326 char_u *expr_start; 15327 char_u *expr_end; 15328 15329 *alias = NULL; /* default to no alias */ 15330 15331 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15332 && (*arg)[2] == (int)KE_SNR) 15333 { 15334 /* hard coded <SNR>, already translated */ 15335 *arg += 3; 15336 return get_id_len(arg) + 3; 15337 } 15338 len = eval_fname_script(*arg); 15339 if (len > 0) 15340 { 15341 /* literal "<SID>", "s:" or "<SNR>" */ 15342 *arg += len; 15343 } 15344 15345 /* 15346 * Find the end of the name; check for {} construction. 15347 */ 15348 p = find_name_end(*arg, &expr_start, &expr_end, 15349 len > 0 ? 0 : FNE_CHECK_START); 15350 if (expr_start != NULL) 15351 { 15352 char_u *temp_string; 15353 15354 if (!evaluate) 15355 { 15356 len += (int)(p - *arg); 15357 *arg = skipwhite(p); 15358 return len; 15359 } 15360 15361 /* 15362 * Include any <SID> etc in the expanded string: 15363 * Thus the -len here. 15364 */ 15365 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15366 if (temp_string == NULL) 15367 return -1; 15368 *alias = temp_string; 15369 *arg = skipwhite(p); 15370 return (int)STRLEN(temp_string); 15371 } 15372 15373 len += get_id_len(arg); 15374 if (len == 0 && verbose) 15375 EMSG2(_(e_invexpr2), *arg); 15376 15377 return len; 15378 } 15379 15380 /* 15381 * Find the end of a variable or function name, taking care of magic braces. 15382 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15383 * start and end of the first magic braces item. 15384 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15385 * Return a pointer to just after the name. Equal to "arg" if there is no 15386 * valid name. 15387 */ 15388 static char_u * 15389 find_name_end(arg, expr_start, expr_end, flags) 15390 char_u *arg; 15391 char_u **expr_start; 15392 char_u **expr_end; 15393 int flags; 15394 { 15395 int mb_nest = 0; 15396 int br_nest = 0; 15397 char_u *p; 15398 15399 if (expr_start != NULL) 15400 { 15401 *expr_start = NULL; 15402 *expr_end = NULL; 15403 } 15404 15405 /* Quick check for valid starting character. */ 15406 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15407 return arg; 15408 15409 for (p = arg; *p != NUL 15410 && (eval_isnamec(*p) 15411 || *p == '{' 15412 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15413 || mb_nest != 0 15414 || br_nest != 0); mb_ptr_adv(p)) 15415 { 15416 if (*p == '\'') 15417 { 15418 /* skip over 'string' to avoid counting [ and ] inside it. */ 15419 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15420 ; 15421 if (*p == NUL) 15422 break; 15423 } 15424 else if (*p == '"') 15425 { 15426 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15427 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15428 if (*p == '\\' && p[1] != NUL) 15429 ++p; 15430 if (*p == NUL) 15431 break; 15432 } 15433 15434 if (mb_nest == 0) 15435 { 15436 if (*p == '[') 15437 ++br_nest; 15438 else if (*p == ']') 15439 --br_nest; 15440 } 15441 15442 if (br_nest == 0) 15443 { 15444 if (*p == '{') 15445 { 15446 mb_nest++; 15447 if (expr_start != NULL && *expr_start == NULL) 15448 *expr_start = p; 15449 } 15450 else if (*p == '}') 15451 { 15452 mb_nest--; 15453 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15454 *expr_end = p; 15455 } 15456 } 15457 } 15458 15459 return p; 15460 } 15461 15462 /* 15463 * Expands out the 'magic' {}'s in a variable/function name. 15464 * Note that this can call itself recursively, to deal with 15465 * constructs like foo{bar}{baz}{bam} 15466 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15467 * "in_start" ^ 15468 * "expr_start" ^ 15469 * "expr_end" ^ 15470 * "in_end" ^ 15471 * 15472 * Returns a new allocated string, which the caller must free. 15473 * Returns NULL for failure. 15474 */ 15475 static char_u * 15476 make_expanded_name(in_start, expr_start, expr_end, in_end) 15477 char_u *in_start; 15478 char_u *expr_start; 15479 char_u *expr_end; 15480 char_u *in_end; 15481 { 15482 char_u c1; 15483 char_u *retval = NULL; 15484 char_u *temp_result; 15485 char_u *nextcmd = NULL; 15486 15487 if (expr_end == NULL || in_end == NULL) 15488 return NULL; 15489 *expr_start = NUL; 15490 *expr_end = NUL; 15491 c1 = *in_end; 15492 *in_end = NUL; 15493 15494 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15495 if (temp_result != NULL && nextcmd == NULL) 15496 { 15497 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15498 + (in_end - expr_end) + 1)); 15499 if (retval != NULL) 15500 { 15501 STRCPY(retval, in_start); 15502 STRCAT(retval, temp_result); 15503 STRCAT(retval, expr_end + 1); 15504 } 15505 } 15506 vim_free(temp_result); 15507 15508 *in_end = c1; /* put char back for error messages */ 15509 *expr_start = '{'; 15510 *expr_end = '}'; 15511 15512 if (retval != NULL) 15513 { 15514 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15515 if (expr_start != NULL) 15516 { 15517 /* Further expansion! */ 15518 temp_result = make_expanded_name(retval, expr_start, 15519 expr_end, temp_result); 15520 vim_free(retval); 15521 retval = temp_result; 15522 } 15523 } 15524 15525 return retval; 15526 } 15527 15528 /* 15529 * Return TRUE if character "c" can be used in a variable or function name. 15530 * Does not include '{' or '}' for magic braces. 15531 */ 15532 static int 15533 eval_isnamec(c) 15534 int c; 15535 { 15536 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15537 } 15538 15539 /* 15540 * Return TRUE if character "c" can be used as the first character in a 15541 * variable or function name (excluding '{' and '}'). 15542 */ 15543 static int 15544 eval_isnamec1(c) 15545 int c; 15546 { 15547 return (ASCII_ISALPHA(c) || c == '_'); 15548 } 15549 15550 /* 15551 * Set number v: variable to "val". 15552 */ 15553 void 15554 set_vim_var_nr(idx, val) 15555 int idx; 15556 long val; 15557 { 15558 vimvars[idx].vv_nr = val; 15559 } 15560 15561 /* 15562 * Get number v: variable value. 15563 */ 15564 long 15565 get_vim_var_nr(idx) 15566 int idx; 15567 { 15568 return vimvars[idx].vv_nr; 15569 } 15570 15571 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15572 /* 15573 * Get string v: variable value. Uses a static buffer, can only be used once. 15574 */ 15575 char_u * 15576 get_vim_var_str(idx) 15577 int idx; 15578 { 15579 return get_tv_string(&vimvars[idx].vv_tv); 15580 } 15581 #endif 15582 15583 /* 15584 * Set v:count, v:count1 and v:prevcount. 15585 */ 15586 void 15587 set_vcount(count, count1) 15588 long count; 15589 long count1; 15590 { 15591 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15592 vimvars[VV_COUNT].vv_nr = count; 15593 vimvars[VV_COUNT1].vv_nr = count1; 15594 } 15595 15596 /* 15597 * Set string v: variable to a copy of "val". 15598 */ 15599 void 15600 set_vim_var_string(idx, val, len) 15601 int idx; 15602 char_u *val; 15603 int len; /* length of "val" to use or -1 (whole string) */ 15604 { 15605 /* Need to do this (at least) once, since we can't initialize a union. 15606 * Will always be invoked when "v:progname" is set. */ 15607 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15608 15609 vim_free(vimvars[idx].vv_str); 15610 if (val == NULL) 15611 vimvars[idx].vv_str = NULL; 15612 else if (len == -1) 15613 vimvars[idx].vv_str = vim_strsave(val); 15614 else 15615 vimvars[idx].vv_str = vim_strnsave(val, len); 15616 } 15617 15618 /* 15619 * Set v:register if needed. 15620 */ 15621 void 15622 set_reg_var(c) 15623 int c; 15624 { 15625 char_u regname; 15626 15627 if (c == 0 || c == ' ') 15628 regname = '"'; 15629 else 15630 regname = c; 15631 /* Avoid free/alloc when the value is already right. */ 15632 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15633 set_vim_var_string(VV_REG, ®name, 1); 15634 } 15635 15636 /* 15637 * Get or set v:exception. If "oldval" == NULL, return the current value. 15638 * Otherwise, restore the value to "oldval" and return NULL. 15639 * Must always be called in pairs to save and restore v:exception! Does not 15640 * take care of memory allocations. 15641 */ 15642 char_u * 15643 v_exception(oldval) 15644 char_u *oldval; 15645 { 15646 if (oldval == NULL) 15647 return vimvars[VV_EXCEPTION].vv_str; 15648 15649 vimvars[VV_EXCEPTION].vv_str = oldval; 15650 return NULL; 15651 } 15652 15653 /* 15654 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15655 * Otherwise, restore the value to "oldval" and return NULL. 15656 * Must always be called in pairs to save and restore v:throwpoint! Does not 15657 * take care of memory allocations. 15658 */ 15659 char_u * 15660 v_throwpoint(oldval) 15661 char_u *oldval; 15662 { 15663 if (oldval == NULL) 15664 return vimvars[VV_THROWPOINT].vv_str; 15665 15666 vimvars[VV_THROWPOINT].vv_str = oldval; 15667 return NULL; 15668 } 15669 15670 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15671 /* 15672 * Set v:cmdarg. 15673 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15674 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15675 * Must always be called in pairs! 15676 */ 15677 char_u * 15678 set_cmdarg(eap, oldarg) 15679 exarg_T *eap; 15680 char_u *oldarg; 15681 { 15682 char_u *oldval; 15683 char_u *newval; 15684 unsigned len; 15685 15686 oldval = vimvars[VV_CMDARG].vv_str; 15687 if (eap == NULL) 15688 { 15689 vim_free(oldval); 15690 vimvars[VV_CMDARG].vv_str = oldarg; 15691 return NULL; 15692 } 15693 15694 if (eap->force_bin == FORCE_BIN) 15695 len = 6; 15696 else if (eap->force_bin == FORCE_NOBIN) 15697 len = 8; 15698 else 15699 len = 0; 15700 if (eap->force_ff != 0) 15701 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15702 # ifdef FEAT_MBYTE 15703 if (eap->force_enc != 0) 15704 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15705 # endif 15706 15707 newval = alloc(len + 1); 15708 if (newval == NULL) 15709 return NULL; 15710 15711 if (eap->force_bin == FORCE_BIN) 15712 sprintf((char *)newval, " ++bin"); 15713 else if (eap->force_bin == FORCE_NOBIN) 15714 sprintf((char *)newval, " ++nobin"); 15715 else 15716 *newval = NUL; 15717 if (eap->force_ff != 0) 15718 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15719 eap->cmd + eap->force_ff); 15720 # ifdef FEAT_MBYTE 15721 if (eap->force_enc != 0) 15722 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15723 eap->cmd + eap->force_enc); 15724 # endif 15725 vimvars[VV_CMDARG].vv_str = newval; 15726 return oldval; 15727 } 15728 #endif 15729 15730 /* 15731 * Get the value of internal variable "name". 15732 * Return OK or FAIL. 15733 */ 15734 static int 15735 get_var_tv(name, len, rettv, verbose) 15736 char_u *name; 15737 int len; /* length of "name" */ 15738 typval_T *rettv; /* NULL when only checking existence */ 15739 int verbose; /* may give error message */ 15740 { 15741 int ret = OK; 15742 typval_T *tv = NULL; 15743 typval_T atv; 15744 dictitem_T *v; 15745 int cc; 15746 15747 /* truncate the name, so that we can use strcmp() */ 15748 cc = name[len]; 15749 name[len] = NUL; 15750 15751 /* 15752 * Check for "b:changedtick". 15753 */ 15754 if (STRCMP(name, "b:changedtick") == 0) 15755 { 15756 atv.v_type = VAR_NUMBER; 15757 atv.vval.v_number = curbuf->b_changedtick; 15758 tv = &atv; 15759 } 15760 15761 /* 15762 * Check for user-defined variables. 15763 */ 15764 else 15765 { 15766 v = find_var(name, NULL); 15767 if (v != NULL) 15768 tv = &v->di_tv; 15769 } 15770 15771 if (tv == NULL) 15772 { 15773 if (rettv != NULL && verbose) 15774 EMSG2(_(e_undefvar), name); 15775 ret = FAIL; 15776 } 15777 else if (rettv != NULL) 15778 copy_tv(tv, rettv); 15779 15780 name[len] = cc; 15781 15782 return ret; 15783 } 15784 15785 /* 15786 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15787 * Also handle function call with Funcref variable: func(expr) 15788 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15789 */ 15790 static int 15791 handle_subscript(arg, rettv, evaluate, verbose) 15792 char_u **arg; 15793 typval_T *rettv; 15794 int evaluate; /* do more than finding the end */ 15795 int verbose; /* give error messages */ 15796 { 15797 int ret = OK; 15798 dict_T *selfdict = NULL; 15799 char_u *s; 15800 int len; 15801 typval_T functv; 15802 15803 while (ret == OK 15804 && (**arg == '[' 15805 || (**arg == '.' && rettv->v_type == VAR_DICT) 15806 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15807 && !vim_iswhite(*(*arg - 1))) 15808 { 15809 if (**arg == '(') 15810 { 15811 /* need to copy the funcref so that we can clear rettv */ 15812 functv = *rettv; 15813 rettv->v_type = VAR_UNKNOWN; 15814 15815 /* Invoke the function. Recursive! */ 15816 s = functv.vval.v_string; 15817 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15818 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15819 &len, evaluate, selfdict); 15820 15821 /* Clear the funcref afterwards, so that deleting it while 15822 * evaluating the arguments is possible (see test55). */ 15823 clear_tv(&functv); 15824 15825 /* Stop the expression evaluation when immediately aborting on 15826 * error, or when an interrupt occurred or an exception was thrown 15827 * but not caught. */ 15828 if (aborting()) 15829 { 15830 if (ret == OK) 15831 clear_tv(rettv); 15832 ret = FAIL; 15833 } 15834 dict_unref(selfdict); 15835 selfdict = NULL; 15836 } 15837 else /* **arg == '[' || **arg == '.' */ 15838 { 15839 dict_unref(selfdict); 15840 if (rettv->v_type == VAR_DICT) 15841 { 15842 selfdict = rettv->vval.v_dict; 15843 if (selfdict != NULL) 15844 ++selfdict->dv_refcount; 15845 } 15846 else 15847 selfdict = NULL; 15848 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15849 { 15850 clear_tv(rettv); 15851 ret = FAIL; 15852 } 15853 } 15854 } 15855 dict_unref(selfdict); 15856 return ret; 15857 } 15858 15859 /* 15860 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15861 * value). 15862 */ 15863 static typval_T * 15864 alloc_tv() 15865 { 15866 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15867 } 15868 15869 /* 15870 * Allocate memory for a variable type-value, and assign a string to it. 15871 * The string "s" must have been allocated, it is consumed. 15872 * Return NULL for out of memory, the variable otherwise. 15873 */ 15874 static typval_T * 15875 alloc_string_tv(s) 15876 char_u *s; 15877 { 15878 typval_T *rettv; 15879 15880 rettv = alloc_tv(); 15881 if (rettv != NULL) 15882 { 15883 rettv->v_type = VAR_STRING; 15884 rettv->vval.v_string = s; 15885 } 15886 else 15887 vim_free(s); 15888 return rettv; 15889 } 15890 15891 /* 15892 * Free the memory for a variable type-value. 15893 */ 15894 static void 15895 free_tv(varp) 15896 typval_T *varp; 15897 { 15898 if (varp != NULL) 15899 { 15900 switch (varp->v_type) 15901 { 15902 case VAR_FUNC: 15903 func_unref(varp->vval.v_string); 15904 /*FALLTHROUGH*/ 15905 case VAR_STRING: 15906 vim_free(varp->vval.v_string); 15907 break; 15908 case VAR_LIST: 15909 list_unref(varp->vval.v_list); 15910 break; 15911 case VAR_DICT: 15912 dict_unref(varp->vval.v_dict); 15913 break; 15914 case VAR_NUMBER: 15915 case VAR_UNKNOWN: 15916 break; 15917 default: 15918 EMSG2(_(e_intern2), "free_tv()"); 15919 break; 15920 } 15921 vim_free(varp); 15922 } 15923 } 15924 15925 /* 15926 * Free the memory for a variable value and set the value to NULL or 0. 15927 */ 15928 void 15929 clear_tv(varp) 15930 typval_T *varp; 15931 { 15932 if (varp != NULL) 15933 { 15934 switch (varp->v_type) 15935 { 15936 case VAR_FUNC: 15937 func_unref(varp->vval.v_string); 15938 /*FALLTHROUGH*/ 15939 case VAR_STRING: 15940 vim_free(varp->vval.v_string); 15941 varp->vval.v_string = NULL; 15942 break; 15943 case VAR_LIST: 15944 list_unref(varp->vval.v_list); 15945 varp->vval.v_list = NULL; 15946 break; 15947 case VAR_DICT: 15948 dict_unref(varp->vval.v_dict); 15949 varp->vval.v_dict = NULL; 15950 break; 15951 case VAR_NUMBER: 15952 varp->vval.v_number = 0; 15953 break; 15954 case VAR_UNKNOWN: 15955 break; 15956 default: 15957 EMSG2(_(e_intern2), "clear_tv()"); 15958 } 15959 varp->v_lock = 0; 15960 } 15961 } 15962 15963 /* 15964 * Set the value of a variable to NULL without freeing items. 15965 */ 15966 static void 15967 init_tv(varp) 15968 typval_T *varp; 15969 { 15970 if (varp != NULL) 15971 vim_memset(varp, 0, sizeof(typval_T)); 15972 } 15973 15974 /* 15975 * Get the number value of a variable. 15976 * If it is a String variable, uses vim_str2nr(). 15977 * For incompatible types, return 0. 15978 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15979 * caller of incompatible types: it sets *denote to TRUE if "denote" 15980 * is not NULL or returns -1 otherwise. 15981 */ 15982 static long 15983 get_tv_number(varp) 15984 typval_T *varp; 15985 { 15986 int error = FALSE; 15987 15988 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15989 } 15990 15991 long 15992 get_tv_number_chk(varp, denote) 15993 typval_T *varp; 15994 int *denote; 15995 { 15996 long n = 0L; 15997 15998 switch (varp->v_type) 15999 { 16000 case VAR_NUMBER: 16001 return (long)(varp->vval.v_number); 16002 case VAR_FUNC: 16003 EMSG(_("E703: Using a Funcref as a number")); 16004 break; 16005 case VAR_STRING: 16006 if (varp->vval.v_string != NULL) 16007 vim_str2nr(varp->vval.v_string, NULL, NULL, 16008 TRUE, TRUE, &n, NULL); 16009 return n; 16010 case VAR_LIST: 16011 EMSG(_("E745: Using a List as a number")); 16012 break; 16013 case VAR_DICT: 16014 EMSG(_("E728: Using a Dictionary as a number")); 16015 break; 16016 default: 16017 EMSG2(_(e_intern2), "get_tv_number()"); 16018 break; 16019 } 16020 if (denote == NULL) /* useful for values that must be unsigned */ 16021 n = -1; 16022 else 16023 *denote = TRUE; 16024 return n; 16025 } 16026 16027 /* 16028 * Get the lnum from the first argument. 16029 * Also accepts ".", "$", etc., but that only works for the current buffer. 16030 * Returns -1 on error. 16031 */ 16032 static linenr_T 16033 get_tv_lnum(argvars) 16034 typval_T *argvars; 16035 { 16036 typval_T rettv; 16037 linenr_T lnum; 16038 16039 lnum = get_tv_number_chk(&argvars[0], NULL); 16040 if (lnum == 0) /* no valid number, try using line() */ 16041 { 16042 rettv.v_type = VAR_NUMBER; 16043 f_line(argvars, &rettv); 16044 lnum = rettv.vval.v_number; 16045 clear_tv(&rettv); 16046 } 16047 return lnum; 16048 } 16049 16050 /* 16051 * Get the lnum from the first argument. 16052 * Also accepts "$", then "buf" is used. 16053 * Returns 0 on error. 16054 */ 16055 static linenr_T 16056 get_tv_lnum_buf(argvars, buf) 16057 typval_T *argvars; 16058 buf_T *buf; 16059 { 16060 if (argvars[0].v_type == VAR_STRING 16061 && argvars[0].vval.v_string != NULL 16062 && argvars[0].vval.v_string[0] == '$' 16063 && buf != NULL) 16064 return buf->b_ml.ml_line_count; 16065 return get_tv_number_chk(&argvars[0], NULL); 16066 } 16067 16068 /* 16069 * Get the string value of a variable. 16070 * If it is a Number variable, the number is converted into a string. 16071 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 16072 * get_tv_string_buf() uses a given buffer. 16073 * If the String variable has never been set, return an empty string. 16074 * Never returns NULL; 16075 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 16076 * NULL on error. 16077 */ 16078 static char_u * 16079 get_tv_string(varp) 16080 typval_T *varp; 16081 { 16082 static char_u mybuf[NUMBUFLEN]; 16083 16084 return get_tv_string_buf(varp, mybuf); 16085 } 16086 16087 static char_u * 16088 get_tv_string_buf(varp, buf) 16089 typval_T *varp; 16090 char_u *buf; 16091 { 16092 char_u *res = get_tv_string_buf_chk(varp, buf); 16093 16094 return res != NULL ? res : (char_u *)""; 16095 } 16096 16097 char_u * 16098 get_tv_string_chk(varp) 16099 typval_T *varp; 16100 { 16101 static char_u mybuf[NUMBUFLEN]; 16102 16103 return get_tv_string_buf_chk(varp, mybuf); 16104 } 16105 16106 static char_u * 16107 get_tv_string_buf_chk(varp, buf) 16108 typval_T *varp; 16109 char_u *buf; 16110 { 16111 switch (varp->v_type) 16112 { 16113 case VAR_NUMBER: 16114 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 16115 return buf; 16116 case VAR_FUNC: 16117 EMSG(_("E729: using Funcref as a String")); 16118 break; 16119 case VAR_LIST: 16120 EMSG(_("E730: using List as a String")); 16121 break; 16122 case VAR_DICT: 16123 EMSG(_("E731: using Dictionary as a String")); 16124 break; 16125 case VAR_STRING: 16126 if (varp->vval.v_string != NULL) 16127 return varp->vval.v_string; 16128 return (char_u *)""; 16129 default: 16130 EMSG2(_(e_intern2), "get_tv_string_buf()"); 16131 break; 16132 } 16133 return NULL; 16134 } 16135 16136 /* 16137 * Find variable "name" in the list of variables. 16138 * Return a pointer to it if found, NULL if not found. 16139 * Careful: "a:0" variables don't have a name. 16140 * When "htp" is not NULL we are writing to the variable, set "htp" to the 16141 * hashtab_T used. 16142 */ 16143 static dictitem_T * 16144 find_var(name, htp) 16145 char_u *name; 16146 hashtab_T **htp; 16147 { 16148 char_u *varname; 16149 hashtab_T *ht; 16150 16151 ht = find_var_ht(name, &varname); 16152 if (htp != NULL) 16153 *htp = ht; 16154 if (ht == NULL) 16155 return NULL; 16156 return find_var_in_ht(ht, varname, htp != NULL); 16157 } 16158 16159 /* 16160 * Find variable "varname" in hashtab "ht". 16161 * Returns NULL if not found. 16162 */ 16163 static dictitem_T * 16164 find_var_in_ht(ht, varname, writing) 16165 hashtab_T *ht; 16166 char_u *varname; 16167 int writing; 16168 { 16169 hashitem_T *hi; 16170 16171 if (*varname == NUL) 16172 { 16173 /* Must be something like "s:", otherwise "ht" would be NULL. */ 16174 switch (varname[-2]) 16175 { 16176 case 's': return &SCRIPT_SV(current_SID).sv_var; 16177 case 'g': return &globvars_var; 16178 case 'v': return &vimvars_var; 16179 case 'b': return &curbuf->b_bufvar; 16180 case 'w': return &curwin->w_winvar; 16181 case 'l': return current_funccal == NULL 16182 ? NULL : ¤t_funccal->l_vars_var; 16183 case 'a': return current_funccal == NULL 16184 ? NULL : ¤t_funccal->l_avars_var; 16185 } 16186 return NULL; 16187 } 16188 16189 hi = hash_find(ht, varname); 16190 if (HASHITEM_EMPTY(hi)) 16191 { 16192 /* For global variables we may try auto-loading the script. If it 16193 * worked find the variable again. Don't auto-load a script if it was 16194 * loaded already, otherwise it would be loaded every time when 16195 * checking if a function name is a Funcref variable. */ 16196 if (ht == &globvarht && !writing 16197 && script_autoload(varname, FALSE) && !aborting()) 16198 hi = hash_find(ht, varname); 16199 if (HASHITEM_EMPTY(hi)) 16200 return NULL; 16201 } 16202 return HI2DI(hi); 16203 } 16204 16205 /* 16206 * Find the hashtab used for a variable name. 16207 * Set "varname" to the start of name without ':'. 16208 */ 16209 static hashtab_T * 16210 find_var_ht(name, varname) 16211 char_u *name; 16212 char_u **varname; 16213 { 16214 hashitem_T *hi; 16215 16216 if (name[1] != ':') 16217 { 16218 /* The name must not start with a colon or #. */ 16219 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16220 return NULL; 16221 *varname = name; 16222 16223 /* "version" is "v:version" in all scopes */ 16224 hi = hash_find(&compat_hashtab, name); 16225 if (!HASHITEM_EMPTY(hi)) 16226 return &compat_hashtab; 16227 16228 if (current_funccal == NULL) 16229 return &globvarht; /* global variable */ 16230 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16231 } 16232 *varname = name + 2; 16233 if (*name == 'g') /* global variable */ 16234 return &globvarht; 16235 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16236 */ 16237 if (vim_strchr(name + 2, ':') != NULL 16238 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16239 return NULL; 16240 if (*name == 'b') /* buffer variable */ 16241 return &curbuf->b_vars.dv_hashtab; 16242 if (*name == 'w') /* window variable */ 16243 return &curwin->w_vars.dv_hashtab; 16244 if (*name == 'v') /* v: variable */ 16245 return &vimvarht; 16246 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16247 return ¤t_funccal->l_avars.dv_hashtab; 16248 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16249 return ¤t_funccal->l_vars.dv_hashtab; 16250 if (*name == 's' /* script variable */ 16251 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16252 return &SCRIPT_VARS(current_SID); 16253 return NULL; 16254 } 16255 16256 /* 16257 * Get the string value of a (global/local) variable. 16258 * Returns NULL when it doesn't exist. 16259 */ 16260 char_u * 16261 get_var_value(name) 16262 char_u *name; 16263 { 16264 dictitem_T *v; 16265 16266 v = find_var(name, NULL); 16267 if (v == NULL) 16268 return NULL; 16269 return get_tv_string(&v->di_tv); 16270 } 16271 16272 /* 16273 * Allocate a new hashtab for a sourced script. It will be used while 16274 * sourcing this script and when executing functions defined in the script. 16275 */ 16276 void 16277 new_script_vars(id) 16278 scid_T id; 16279 { 16280 int i; 16281 hashtab_T *ht; 16282 scriptvar_T *sv; 16283 16284 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16285 { 16286 /* Re-allocating ga_data means that an ht_array pointing to 16287 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16288 * at its init value. Also reset "v_dict", it's always the same. */ 16289 for (i = 1; i <= ga_scripts.ga_len; ++i) 16290 { 16291 ht = &SCRIPT_VARS(i); 16292 if (ht->ht_mask == HT_INIT_SIZE - 1) 16293 ht->ht_array = ht->ht_smallarray; 16294 sv = &SCRIPT_SV(i); 16295 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16296 } 16297 16298 while (ga_scripts.ga_len < id) 16299 { 16300 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16301 init_var_dict(&sv->sv_dict, &sv->sv_var); 16302 ++ga_scripts.ga_len; 16303 } 16304 } 16305 } 16306 16307 /* 16308 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16309 * point to it. 16310 */ 16311 void 16312 init_var_dict(dict, dict_var) 16313 dict_T *dict; 16314 dictitem_T *dict_var; 16315 { 16316 hash_init(&dict->dv_hashtab); 16317 dict->dv_refcount = 99999; 16318 dict_var->di_tv.vval.v_dict = dict; 16319 dict_var->di_tv.v_type = VAR_DICT; 16320 dict_var->di_tv.v_lock = VAR_FIXED; 16321 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16322 dict_var->di_key[0] = NUL; 16323 } 16324 16325 /* 16326 * Clean up a list of internal variables. 16327 * Frees all allocated variables and the value they contain. 16328 * Clears hashtab "ht", does not free it. 16329 */ 16330 void 16331 vars_clear(ht) 16332 hashtab_T *ht; 16333 { 16334 vars_clear_ext(ht, TRUE); 16335 } 16336 16337 /* 16338 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16339 */ 16340 static void 16341 vars_clear_ext(ht, free_val) 16342 hashtab_T *ht; 16343 int free_val; 16344 { 16345 int todo; 16346 hashitem_T *hi; 16347 dictitem_T *v; 16348 16349 hash_lock(ht); 16350 todo = ht->ht_used; 16351 for (hi = ht->ht_array; todo > 0; ++hi) 16352 { 16353 if (!HASHITEM_EMPTY(hi)) 16354 { 16355 --todo; 16356 16357 /* Free the variable. Don't remove it from the hashtab, 16358 * ht_array might change then. hash_clear() takes care of it 16359 * later. */ 16360 v = HI2DI(hi); 16361 if (free_val) 16362 clear_tv(&v->di_tv); 16363 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16364 vim_free(v); 16365 } 16366 } 16367 hash_clear(ht); 16368 ht->ht_used = 0; 16369 } 16370 16371 /* 16372 * Delete a variable from hashtab "ht" at item "hi". 16373 * Clear the variable value and free the dictitem. 16374 */ 16375 static void 16376 delete_var(ht, hi) 16377 hashtab_T *ht; 16378 hashitem_T *hi; 16379 { 16380 dictitem_T *di = HI2DI(hi); 16381 16382 hash_remove(ht, hi); 16383 clear_tv(&di->di_tv); 16384 vim_free(di); 16385 } 16386 16387 /* 16388 * List the value of one internal variable. 16389 */ 16390 static void 16391 list_one_var(v, prefix) 16392 dictitem_T *v; 16393 char_u *prefix; 16394 { 16395 char_u *tofree; 16396 char_u *s; 16397 char_u numbuf[NUMBUFLEN]; 16398 16399 s = echo_string(&v->di_tv, &tofree, numbuf); 16400 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16401 s == NULL ? (char_u *)"" : s); 16402 vim_free(tofree); 16403 } 16404 16405 static void 16406 list_one_var_a(prefix, name, type, string) 16407 char_u *prefix; 16408 char_u *name; 16409 int type; 16410 char_u *string; 16411 { 16412 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16413 if (name != NULL) /* "a:" vars don't have a name stored */ 16414 msg_puts(name); 16415 msg_putchar(' '); 16416 msg_advance(22); 16417 if (type == VAR_NUMBER) 16418 msg_putchar('#'); 16419 else if (type == VAR_FUNC) 16420 msg_putchar('*'); 16421 else if (type == VAR_LIST) 16422 { 16423 msg_putchar('['); 16424 if (*string == '[') 16425 ++string; 16426 } 16427 else if (type == VAR_DICT) 16428 { 16429 msg_putchar('{'); 16430 if (*string == '{') 16431 ++string; 16432 } 16433 else 16434 msg_putchar(' '); 16435 16436 msg_outtrans(string); 16437 16438 if (type == VAR_FUNC) 16439 msg_puts((char_u *)"()"); 16440 } 16441 16442 /* 16443 * Set variable "name" to value in "tv". 16444 * If the variable already exists, the value is updated. 16445 * Otherwise the variable is created. 16446 */ 16447 static void 16448 set_var(name, tv, copy) 16449 char_u *name; 16450 typval_T *tv; 16451 int copy; /* make copy of value in "tv" */ 16452 { 16453 dictitem_T *v; 16454 char_u *varname; 16455 hashtab_T *ht; 16456 char_u *p; 16457 16458 if (tv->v_type == VAR_FUNC) 16459 { 16460 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16461 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16462 ? name[2] : name[0])) 16463 { 16464 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16465 return; 16466 } 16467 if (function_exists(name)) 16468 { 16469 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16470 name); 16471 return; 16472 } 16473 } 16474 16475 ht = find_var_ht(name, &varname); 16476 if (ht == NULL || *varname == NUL) 16477 { 16478 EMSG2(_(e_illvar), name); 16479 return; 16480 } 16481 16482 v = find_var_in_ht(ht, varname, TRUE); 16483 if (v != NULL) 16484 { 16485 /* existing variable, need to clear the value */ 16486 if (var_check_ro(v->di_flags, name) 16487 || tv_check_lock(v->di_tv.v_lock, name)) 16488 return; 16489 if (v->di_tv.v_type != tv->v_type 16490 && !((v->di_tv.v_type == VAR_STRING 16491 || v->di_tv.v_type == VAR_NUMBER) 16492 && (tv->v_type == VAR_STRING 16493 || tv->v_type == VAR_NUMBER))) 16494 { 16495 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16496 return; 16497 } 16498 16499 /* 16500 * Handle setting internal v: variables separately: we don't change 16501 * the type. 16502 */ 16503 if (ht == &vimvarht) 16504 { 16505 if (v->di_tv.v_type == VAR_STRING) 16506 { 16507 vim_free(v->di_tv.vval.v_string); 16508 if (copy || tv->v_type != VAR_STRING) 16509 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16510 else 16511 { 16512 /* Take over the string to avoid an extra alloc/free. */ 16513 v->di_tv.vval.v_string = tv->vval.v_string; 16514 tv->vval.v_string = NULL; 16515 } 16516 } 16517 else if (v->di_tv.v_type != VAR_NUMBER) 16518 EMSG2(_(e_intern2), "set_var()"); 16519 else 16520 v->di_tv.vval.v_number = get_tv_number(tv); 16521 return; 16522 } 16523 16524 clear_tv(&v->di_tv); 16525 } 16526 else /* add a new variable */ 16527 { 16528 /* Make sure the variable name is valid. */ 16529 for (p = varname; *p != NUL; ++p) 16530 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16531 { 16532 EMSG2(_(e_illvar), varname); 16533 return; 16534 } 16535 16536 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16537 + STRLEN(varname))); 16538 if (v == NULL) 16539 return; 16540 STRCPY(v->di_key, varname); 16541 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16542 { 16543 vim_free(v); 16544 return; 16545 } 16546 v->di_flags = 0; 16547 } 16548 16549 if (copy || tv->v_type == VAR_NUMBER) 16550 copy_tv(tv, &v->di_tv); 16551 else 16552 { 16553 v->di_tv = *tv; 16554 v->di_tv.v_lock = 0; 16555 init_tv(tv); 16556 } 16557 } 16558 16559 /* 16560 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16561 * Also give an error message. 16562 */ 16563 static int 16564 var_check_ro(flags, name) 16565 int flags; 16566 char_u *name; 16567 { 16568 if (flags & DI_FLAGS_RO) 16569 { 16570 EMSG2(_(e_readonlyvar), name); 16571 return TRUE; 16572 } 16573 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16574 { 16575 EMSG2(_(e_readonlysbx), name); 16576 return TRUE; 16577 } 16578 return FALSE; 16579 } 16580 16581 /* 16582 * Return TRUE if typeval "tv" is set to be locked (immutable). 16583 * Also give an error message, using "name". 16584 */ 16585 static int 16586 tv_check_lock(lock, name) 16587 int lock; 16588 char_u *name; 16589 { 16590 if (lock & VAR_LOCKED) 16591 { 16592 EMSG2(_("E741: Value is locked: %s"), 16593 name == NULL ? (char_u *)_("Unknown") : name); 16594 return TRUE; 16595 } 16596 if (lock & VAR_FIXED) 16597 { 16598 EMSG2(_("E742: Cannot change value of %s"), 16599 name == NULL ? (char_u *)_("Unknown") : name); 16600 return TRUE; 16601 } 16602 return FALSE; 16603 } 16604 16605 /* 16606 * Copy the values from typval_T "from" to typval_T "to". 16607 * When needed allocates string or increases reference count. 16608 * Does not make a copy of a list or dict but copies the reference! 16609 */ 16610 static void 16611 copy_tv(from, to) 16612 typval_T *from; 16613 typval_T *to; 16614 { 16615 to->v_type = from->v_type; 16616 to->v_lock = 0; 16617 switch (from->v_type) 16618 { 16619 case VAR_NUMBER: 16620 to->vval.v_number = from->vval.v_number; 16621 break; 16622 case VAR_STRING: 16623 case VAR_FUNC: 16624 if (from->vval.v_string == NULL) 16625 to->vval.v_string = NULL; 16626 else 16627 { 16628 to->vval.v_string = vim_strsave(from->vval.v_string); 16629 if (from->v_type == VAR_FUNC) 16630 func_ref(to->vval.v_string); 16631 } 16632 break; 16633 case VAR_LIST: 16634 if (from->vval.v_list == NULL) 16635 to->vval.v_list = NULL; 16636 else 16637 { 16638 to->vval.v_list = from->vval.v_list; 16639 ++to->vval.v_list->lv_refcount; 16640 } 16641 break; 16642 case VAR_DICT: 16643 if (from->vval.v_dict == NULL) 16644 to->vval.v_dict = NULL; 16645 else 16646 { 16647 to->vval.v_dict = from->vval.v_dict; 16648 ++to->vval.v_dict->dv_refcount; 16649 } 16650 break; 16651 default: 16652 EMSG2(_(e_intern2), "copy_tv()"); 16653 break; 16654 } 16655 } 16656 16657 /* 16658 * Make a copy of an item. 16659 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16660 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16661 * reference to an already copied list/dict can be used. 16662 * Returns FAIL or OK. 16663 */ 16664 static int 16665 item_copy(from, to, deep, copyID) 16666 typval_T *from; 16667 typval_T *to; 16668 int deep; 16669 int copyID; 16670 { 16671 static int recurse = 0; 16672 int ret = OK; 16673 16674 if (recurse >= DICT_MAXNEST) 16675 { 16676 EMSG(_("E698: variable nested too deep for making a copy")); 16677 return FAIL; 16678 } 16679 ++recurse; 16680 16681 switch (from->v_type) 16682 { 16683 case VAR_NUMBER: 16684 case VAR_STRING: 16685 case VAR_FUNC: 16686 copy_tv(from, to); 16687 break; 16688 case VAR_LIST: 16689 to->v_type = VAR_LIST; 16690 to->v_lock = 0; 16691 if (from->vval.v_list == NULL) 16692 to->vval.v_list = NULL; 16693 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16694 { 16695 /* use the copy made earlier */ 16696 to->vval.v_list = from->vval.v_list->lv_copylist; 16697 ++to->vval.v_list->lv_refcount; 16698 } 16699 else 16700 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16701 if (to->vval.v_list == NULL) 16702 ret = FAIL; 16703 break; 16704 case VAR_DICT: 16705 to->v_type = VAR_DICT; 16706 to->v_lock = 0; 16707 if (from->vval.v_dict == NULL) 16708 to->vval.v_dict = NULL; 16709 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16710 { 16711 /* use the copy made earlier */ 16712 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16713 ++to->vval.v_dict->dv_refcount; 16714 } 16715 else 16716 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16717 if (to->vval.v_dict == NULL) 16718 ret = FAIL; 16719 break; 16720 default: 16721 EMSG2(_(e_intern2), "item_copy()"); 16722 ret = FAIL; 16723 } 16724 --recurse; 16725 return ret; 16726 } 16727 16728 /* 16729 * ":echo expr1 ..." print each argument separated with a space, add a 16730 * newline at the end. 16731 * ":echon expr1 ..." print each argument plain. 16732 */ 16733 void 16734 ex_echo(eap) 16735 exarg_T *eap; 16736 { 16737 char_u *arg = eap->arg; 16738 typval_T rettv; 16739 char_u *tofree; 16740 char_u *p; 16741 int needclr = TRUE; 16742 int atstart = TRUE; 16743 char_u numbuf[NUMBUFLEN]; 16744 16745 if (eap->skip) 16746 ++emsg_skip; 16747 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16748 { 16749 p = arg; 16750 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16751 { 16752 /* 16753 * Report the invalid expression unless the expression evaluation 16754 * has been cancelled due to an aborting error, an interrupt, or an 16755 * exception. 16756 */ 16757 if (!aborting()) 16758 EMSG2(_(e_invexpr2), p); 16759 break; 16760 } 16761 if (!eap->skip) 16762 { 16763 if (atstart) 16764 { 16765 atstart = FALSE; 16766 /* Call msg_start() after eval1(), evaluating the expression 16767 * may cause a message to appear. */ 16768 if (eap->cmdidx == CMD_echo) 16769 msg_start(); 16770 } 16771 else if (eap->cmdidx == CMD_echo) 16772 msg_puts_attr((char_u *)" ", echo_attr); 16773 p = echo_string(&rettv, &tofree, numbuf); 16774 if (p != NULL) 16775 for ( ; *p != NUL && !got_int; ++p) 16776 { 16777 if (*p == '\n' || *p == '\r' || *p == TAB) 16778 { 16779 if (*p != TAB && needclr) 16780 { 16781 /* remove any text still there from the command */ 16782 msg_clr_eos(); 16783 needclr = FALSE; 16784 } 16785 msg_putchar_attr(*p, echo_attr); 16786 } 16787 else 16788 { 16789 #ifdef FEAT_MBYTE 16790 if (has_mbyte) 16791 { 16792 int i = (*mb_ptr2len)(p); 16793 16794 (void)msg_outtrans_len_attr(p, i, echo_attr); 16795 p += i - 1; 16796 } 16797 else 16798 #endif 16799 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16800 } 16801 } 16802 vim_free(tofree); 16803 } 16804 clear_tv(&rettv); 16805 arg = skipwhite(arg); 16806 } 16807 eap->nextcmd = check_nextcmd(arg); 16808 16809 if (eap->skip) 16810 --emsg_skip; 16811 else 16812 { 16813 /* remove text that may still be there from the command */ 16814 if (needclr) 16815 msg_clr_eos(); 16816 if (eap->cmdidx == CMD_echo) 16817 msg_end(); 16818 } 16819 } 16820 16821 /* 16822 * ":echohl {name}". 16823 */ 16824 void 16825 ex_echohl(eap) 16826 exarg_T *eap; 16827 { 16828 int id; 16829 16830 id = syn_name2id(eap->arg); 16831 if (id == 0) 16832 echo_attr = 0; 16833 else 16834 echo_attr = syn_id2attr(id); 16835 } 16836 16837 /* 16838 * ":execute expr1 ..." execute the result of an expression. 16839 * ":echomsg expr1 ..." Print a message 16840 * ":echoerr expr1 ..." Print an error 16841 * Each gets spaces around each argument and a newline at the end for 16842 * echo commands 16843 */ 16844 void 16845 ex_execute(eap) 16846 exarg_T *eap; 16847 { 16848 char_u *arg = eap->arg; 16849 typval_T rettv; 16850 int ret = OK; 16851 char_u *p; 16852 garray_T ga; 16853 int len; 16854 int save_did_emsg; 16855 16856 ga_init2(&ga, 1, 80); 16857 16858 if (eap->skip) 16859 ++emsg_skip; 16860 while (*arg != NUL && *arg != '|' && *arg != '\n') 16861 { 16862 p = arg; 16863 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16864 { 16865 /* 16866 * Report the invalid expression unless the expression evaluation 16867 * has been cancelled due to an aborting error, an interrupt, or an 16868 * exception. 16869 */ 16870 if (!aborting()) 16871 EMSG2(_(e_invexpr2), p); 16872 ret = FAIL; 16873 break; 16874 } 16875 16876 if (!eap->skip) 16877 { 16878 p = get_tv_string(&rettv); 16879 len = (int)STRLEN(p); 16880 if (ga_grow(&ga, len + 2) == FAIL) 16881 { 16882 clear_tv(&rettv); 16883 ret = FAIL; 16884 break; 16885 } 16886 if (ga.ga_len) 16887 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16888 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16889 ga.ga_len += len; 16890 } 16891 16892 clear_tv(&rettv); 16893 arg = skipwhite(arg); 16894 } 16895 16896 if (ret != FAIL && ga.ga_data != NULL) 16897 { 16898 if (eap->cmdidx == CMD_echomsg) 16899 MSG_ATTR(ga.ga_data, echo_attr); 16900 else if (eap->cmdidx == CMD_echoerr) 16901 { 16902 /* We don't want to abort following commands, restore did_emsg. */ 16903 save_did_emsg = did_emsg; 16904 EMSG((char_u *)ga.ga_data); 16905 if (!force_abort) 16906 did_emsg = save_did_emsg; 16907 } 16908 else if (eap->cmdidx == CMD_execute) 16909 do_cmdline((char_u *)ga.ga_data, 16910 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16911 } 16912 16913 ga_clear(&ga); 16914 16915 if (eap->skip) 16916 --emsg_skip; 16917 16918 eap->nextcmd = check_nextcmd(arg); 16919 } 16920 16921 /* 16922 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16923 * "arg" points to the "&" or '+' when called, to "option" when returning. 16924 * Returns NULL when no option name found. Otherwise pointer to the char 16925 * after the option name. 16926 */ 16927 static char_u * 16928 find_option_end(arg, opt_flags) 16929 char_u **arg; 16930 int *opt_flags; 16931 { 16932 char_u *p = *arg; 16933 16934 ++p; 16935 if (*p == 'g' && p[1] == ':') 16936 { 16937 *opt_flags = OPT_GLOBAL; 16938 p += 2; 16939 } 16940 else if (*p == 'l' && p[1] == ':') 16941 { 16942 *opt_flags = OPT_LOCAL; 16943 p += 2; 16944 } 16945 else 16946 *opt_flags = 0; 16947 16948 if (!ASCII_ISALPHA(*p)) 16949 return NULL; 16950 *arg = p; 16951 16952 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16953 p += 4; /* termcap option */ 16954 else 16955 while (ASCII_ISALPHA(*p)) 16956 ++p; 16957 return p; 16958 } 16959 16960 /* 16961 * ":function" 16962 */ 16963 void 16964 ex_function(eap) 16965 exarg_T *eap; 16966 { 16967 char_u *theline; 16968 int j; 16969 int c; 16970 int saved_did_emsg; 16971 char_u *name = NULL; 16972 char_u *p; 16973 char_u *arg; 16974 garray_T newargs; 16975 garray_T newlines; 16976 int varargs = FALSE; 16977 int mustend = FALSE; 16978 int flags = 0; 16979 ufunc_T *fp; 16980 int indent; 16981 int nesting; 16982 char_u *skip_until = NULL; 16983 dictitem_T *v; 16984 funcdict_T fudi; 16985 static int func_nr = 0; /* number for nameless function */ 16986 int paren; 16987 hashtab_T *ht; 16988 int todo; 16989 hashitem_T *hi; 16990 16991 /* 16992 * ":function" without argument: list functions. 16993 */ 16994 if (ends_excmd(*eap->arg)) 16995 { 16996 if (!eap->skip) 16997 { 16998 todo = func_hashtab.ht_used; 16999 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17000 { 17001 if (!HASHITEM_EMPTY(hi)) 17002 { 17003 --todo; 17004 fp = HI2UF(hi); 17005 if (!isdigit(*fp->uf_name)) 17006 list_func_head(fp, FALSE); 17007 } 17008 } 17009 } 17010 eap->nextcmd = check_nextcmd(eap->arg); 17011 return; 17012 } 17013 17014 /* 17015 * ":function /pat": list functions matching pattern. 17016 */ 17017 if (*eap->arg == '/') 17018 { 17019 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 17020 if (!eap->skip) 17021 { 17022 regmatch_T regmatch; 17023 17024 c = *p; 17025 *p = NUL; 17026 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 17027 *p = c; 17028 if (regmatch.regprog != NULL) 17029 { 17030 regmatch.rm_ic = p_ic; 17031 17032 todo = func_hashtab.ht_used; 17033 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17034 { 17035 if (!HASHITEM_EMPTY(hi)) 17036 { 17037 --todo; 17038 fp = HI2UF(hi); 17039 if (!isdigit(*fp->uf_name) 17040 && vim_regexec(®match, fp->uf_name, 0)) 17041 list_func_head(fp, FALSE); 17042 } 17043 } 17044 } 17045 } 17046 if (*p == '/') 17047 ++p; 17048 eap->nextcmd = check_nextcmd(p); 17049 return; 17050 } 17051 17052 /* 17053 * Get the function name. There are these situations: 17054 * func normal function name 17055 * "name" == func, "fudi.fd_dict" == NULL 17056 * dict.func new dictionary entry 17057 * "name" == NULL, "fudi.fd_dict" set, 17058 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 17059 * dict.func existing dict entry with a Funcref 17060 * "name" == func, "fudi.fd_dict" set, 17061 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17062 * dict.func existing dict entry that's not a Funcref 17063 * "name" == NULL, "fudi.fd_dict" set, 17064 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17065 */ 17066 p = eap->arg; 17067 name = trans_function_name(&p, eap->skip, 0, &fudi); 17068 paren = (vim_strchr(p, '(') != NULL); 17069 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 17070 { 17071 /* 17072 * Return on an invalid expression in braces, unless the expression 17073 * evaluation has been cancelled due to an aborting error, an 17074 * interrupt, or an exception. 17075 */ 17076 if (!aborting()) 17077 { 17078 if (!eap->skip && fudi.fd_newkey != NULL) 17079 EMSG2(_(e_dictkey), fudi.fd_newkey); 17080 vim_free(fudi.fd_newkey); 17081 return; 17082 } 17083 else 17084 eap->skip = TRUE; 17085 } 17086 /* An error in a function call during evaluation of an expression in magic 17087 * braces should not cause the function not to be defined. */ 17088 saved_did_emsg = did_emsg; 17089 did_emsg = FALSE; 17090 17091 /* 17092 * ":function func" with only function name: list function. 17093 */ 17094 if (!paren) 17095 { 17096 if (!ends_excmd(*skipwhite(p))) 17097 { 17098 EMSG(_(e_trailing)); 17099 goto ret_free; 17100 } 17101 eap->nextcmd = check_nextcmd(p); 17102 if (eap->nextcmd != NULL) 17103 *p = NUL; 17104 if (!eap->skip && !got_int) 17105 { 17106 fp = find_func(name); 17107 if (fp != NULL) 17108 { 17109 list_func_head(fp, TRUE); 17110 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 17111 { 17112 msg_putchar('\n'); 17113 msg_outnum((long)(j + 1)); 17114 if (j < 9) 17115 msg_putchar(' '); 17116 if (j < 99) 17117 msg_putchar(' '); 17118 msg_prt_line(FUNCLINE(fp, j), FALSE); 17119 out_flush(); /* show a line at a time */ 17120 ui_breakcheck(); 17121 } 17122 if (!got_int) 17123 { 17124 msg_putchar('\n'); 17125 msg_puts((char_u *)" endfunction"); 17126 } 17127 } 17128 else 17129 emsg_funcname("E123: Undefined function: %s", name); 17130 } 17131 goto ret_free; 17132 } 17133 17134 /* 17135 * ":function name(arg1, arg2)" Define function. 17136 */ 17137 p = skipwhite(p); 17138 if (*p != '(') 17139 { 17140 if (!eap->skip) 17141 { 17142 EMSG2(_("E124: Missing '(': %s"), eap->arg); 17143 goto ret_free; 17144 } 17145 /* attempt to continue by skipping some text */ 17146 if (vim_strchr(p, '(') != NULL) 17147 p = vim_strchr(p, '('); 17148 } 17149 p = skipwhite(p + 1); 17150 17151 ga_init2(&newargs, (int)sizeof(char_u *), 3); 17152 ga_init2(&newlines, (int)sizeof(char_u *), 3); 17153 17154 if (!eap->skip) 17155 { 17156 /* Check the name of the function. */ 17157 if (name != NULL) 17158 arg = name; 17159 else 17160 arg = fudi.fd_newkey; 17161 if (arg != NULL) 17162 { 17163 if (*arg == K_SPECIAL) 17164 j = 3; 17165 else 17166 j = 0; 17167 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 17168 : eval_isnamec(arg[j]))) 17169 ++j; 17170 if (arg[j] != NUL) 17171 emsg_funcname(_(e_invarg2), arg); 17172 } 17173 } 17174 17175 /* 17176 * Isolate the arguments: "arg1, arg2, ...)" 17177 */ 17178 while (*p != ')') 17179 { 17180 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 17181 { 17182 varargs = TRUE; 17183 p += 3; 17184 mustend = TRUE; 17185 } 17186 else 17187 { 17188 arg = p; 17189 while (ASCII_ISALNUM(*p) || *p == '_') 17190 ++p; 17191 if (arg == p || isdigit(*arg) 17192 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 17193 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 17194 { 17195 if (!eap->skip) 17196 EMSG2(_("E125: Illegal argument: %s"), arg); 17197 break; 17198 } 17199 if (ga_grow(&newargs, 1) == FAIL) 17200 goto erret; 17201 c = *p; 17202 *p = NUL; 17203 arg = vim_strsave(arg); 17204 if (arg == NULL) 17205 goto erret; 17206 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 17207 *p = c; 17208 newargs.ga_len++; 17209 if (*p == ',') 17210 ++p; 17211 else 17212 mustend = TRUE; 17213 } 17214 p = skipwhite(p); 17215 if (mustend && *p != ')') 17216 { 17217 if (!eap->skip) 17218 EMSG2(_(e_invarg2), eap->arg); 17219 break; 17220 } 17221 } 17222 ++p; /* skip the ')' */ 17223 17224 /* find extra arguments "range", "dict" and "abort" */ 17225 for (;;) 17226 { 17227 p = skipwhite(p); 17228 if (STRNCMP(p, "range", 5) == 0) 17229 { 17230 flags |= FC_RANGE; 17231 p += 5; 17232 } 17233 else if (STRNCMP(p, "dict", 4) == 0) 17234 { 17235 flags |= FC_DICT; 17236 p += 4; 17237 } 17238 else if (STRNCMP(p, "abort", 5) == 0) 17239 { 17240 flags |= FC_ABORT; 17241 p += 5; 17242 } 17243 else 17244 break; 17245 } 17246 17247 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 17248 EMSG(_(e_trailing)); 17249 17250 /* 17251 * Read the body of the function, until ":endfunction" is found. 17252 */ 17253 if (KeyTyped) 17254 { 17255 /* Check if the function already exists, don't let the user type the 17256 * whole function before telling him it doesn't work! For a script we 17257 * need to skip the body to be able to find what follows. */ 17258 if (!eap->skip && !eap->forceit) 17259 { 17260 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 17261 EMSG(_(e_funcdict)); 17262 else if (name != NULL && find_func(name) != NULL) 17263 emsg_funcname(e_funcexts, name); 17264 } 17265 17266 if (!eap->skip && did_emsg) 17267 goto erret; 17268 17269 msg_putchar('\n'); /* don't overwrite the function name */ 17270 cmdline_row = msg_row; 17271 } 17272 17273 indent = 2; 17274 nesting = 0; 17275 for (;;) 17276 { 17277 msg_scroll = TRUE; 17278 need_wait_return = FALSE; 17279 if (eap->getline == NULL) 17280 theline = getcmdline(':', 0L, indent); 17281 else 17282 theline = eap->getline(':', eap->cookie, indent); 17283 if (KeyTyped) 17284 lines_left = Rows - 1; 17285 if (theline == NULL) 17286 { 17287 EMSG(_("E126: Missing :endfunction")); 17288 goto erret; 17289 } 17290 17291 if (skip_until != NULL) 17292 { 17293 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17294 * don't check for ":endfunc". */ 17295 if (STRCMP(theline, skip_until) == 0) 17296 { 17297 vim_free(skip_until); 17298 skip_until = NULL; 17299 } 17300 } 17301 else 17302 { 17303 /* skip ':' and blanks*/ 17304 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17305 ; 17306 17307 /* Check for "endfunction". */ 17308 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17309 { 17310 vim_free(theline); 17311 break; 17312 } 17313 17314 /* Increase indent inside "if", "while", "for" and "try", decrease 17315 * at "end". */ 17316 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17317 indent -= 2; 17318 else if (STRNCMP(p, "if", 2) == 0 17319 || STRNCMP(p, "wh", 2) == 0 17320 || STRNCMP(p, "for", 3) == 0 17321 || STRNCMP(p, "try", 3) == 0) 17322 indent += 2; 17323 17324 /* Check for defining a function inside this function. */ 17325 if (checkforcmd(&p, "function", 2)) 17326 { 17327 if (*p == '!') 17328 p = skipwhite(p + 1); 17329 p += eval_fname_script(p); 17330 if (ASCII_ISALPHA(*p)) 17331 { 17332 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17333 if (*skipwhite(p) == '(') 17334 { 17335 ++nesting; 17336 indent += 2; 17337 } 17338 } 17339 } 17340 17341 /* Check for ":append" or ":insert". */ 17342 p = skip_range(p, NULL); 17343 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17344 || (p[0] == 'i' 17345 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17346 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17347 skip_until = vim_strsave((char_u *)"."); 17348 17349 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17350 arg = skipwhite(skiptowhite(p)); 17351 if (arg[0] == '<' && arg[1] =='<' 17352 && ((p[0] == 'p' && p[1] == 'y' 17353 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17354 || (p[0] == 'p' && p[1] == 'e' 17355 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17356 || (p[0] == 't' && p[1] == 'c' 17357 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17358 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17359 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17360 || (p[0] == 'm' && p[1] == 'z' 17361 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17362 )) 17363 { 17364 /* ":python <<" continues until a dot, like ":append" */ 17365 p = skipwhite(arg + 2); 17366 if (*p == NUL) 17367 skip_until = vim_strsave((char_u *)"."); 17368 else 17369 skip_until = vim_strsave(p); 17370 } 17371 } 17372 17373 /* Add the line to the function. */ 17374 if (ga_grow(&newlines, 1) == FAIL) 17375 { 17376 vim_free(theline); 17377 goto erret; 17378 } 17379 17380 /* Copy the line to newly allocated memory. get_one_sourceline() 17381 * allocates 250 bytes per line, this saves 80% on average. The cost 17382 * is an extra alloc/free. */ 17383 p = vim_strsave(theline); 17384 if (p != NULL) 17385 { 17386 vim_free(theline); 17387 theline = p; 17388 } 17389 17390 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17391 newlines.ga_len++; 17392 } 17393 17394 /* Don't define the function when skipping commands or when an error was 17395 * detected. */ 17396 if (eap->skip || did_emsg) 17397 goto erret; 17398 17399 /* 17400 * If there are no errors, add the function 17401 */ 17402 if (fudi.fd_dict == NULL) 17403 { 17404 v = find_var(name, &ht); 17405 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17406 { 17407 emsg_funcname("E707: Function name conflicts with variable: %s", 17408 name); 17409 goto erret; 17410 } 17411 17412 fp = find_func(name); 17413 if (fp != NULL) 17414 { 17415 if (!eap->forceit) 17416 { 17417 emsg_funcname(e_funcexts, name); 17418 goto erret; 17419 } 17420 if (fp->uf_calls > 0) 17421 { 17422 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17423 name); 17424 goto erret; 17425 } 17426 /* redefine existing function */ 17427 ga_clear_strings(&(fp->uf_args)); 17428 ga_clear_strings(&(fp->uf_lines)); 17429 vim_free(name); 17430 name = NULL; 17431 } 17432 } 17433 else 17434 { 17435 char numbuf[20]; 17436 17437 fp = NULL; 17438 if (fudi.fd_newkey == NULL && !eap->forceit) 17439 { 17440 EMSG(_(e_funcdict)); 17441 goto erret; 17442 } 17443 if (fudi.fd_di == NULL) 17444 { 17445 /* Can't add a function to a locked dictionary */ 17446 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17447 goto erret; 17448 } 17449 /* Can't change an existing function if it is locked */ 17450 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17451 goto erret; 17452 17453 /* Give the function a sequential number. Can only be used with a 17454 * Funcref! */ 17455 vim_free(name); 17456 sprintf(numbuf, "%d", ++func_nr); 17457 name = vim_strsave((char_u *)numbuf); 17458 if (name == NULL) 17459 goto erret; 17460 } 17461 17462 if (fp == NULL) 17463 { 17464 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17465 { 17466 int slen, plen; 17467 char_u *scriptname; 17468 17469 /* Check that the autoload name matches the script name. */ 17470 j = FAIL; 17471 if (sourcing_name != NULL) 17472 { 17473 scriptname = autoload_name(name); 17474 if (scriptname != NULL) 17475 { 17476 p = vim_strchr(scriptname, '/'); 17477 plen = STRLEN(p); 17478 slen = STRLEN(sourcing_name); 17479 if (slen > plen && fnamecmp(p, 17480 sourcing_name + slen - plen) == 0) 17481 j = OK; 17482 vim_free(scriptname); 17483 } 17484 } 17485 if (j == FAIL) 17486 { 17487 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17488 goto erret; 17489 } 17490 } 17491 17492 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17493 if (fp == NULL) 17494 goto erret; 17495 17496 if (fudi.fd_dict != NULL) 17497 { 17498 if (fudi.fd_di == NULL) 17499 { 17500 /* add new dict entry */ 17501 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17502 if (fudi.fd_di == NULL) 17503 { 17504 vim_free(fp); 17505 goto erret; 17506 } 17507 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17508 { 17509 vim_free(fudi.fd_di); 17510 goto erret; 17511 } 17512 } 17513 else 17514 /* overwrite existing dict entry */ 17515 clear_tv(&fudi.fd_di->di_tv); 17516 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17517 fudi.fd_di->di_tv.v_lock = 0; 17518 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17519 fp->uf_refcount = 1; 17520 } 17521 17522 /* insert the new function in the function list */ 17523 STRCPY(fp->uf_name, name); 17524 hash_add(&func_hashtab, UF2HIKEY(fp)); 17525 } 17526 fp->uf_args = newargs; 17527 fp->uf_lines = newlines; 17528 #ifdef FEAT_PROFILE 17529 fp->uf_tml_count = NULL; 17530 fp->uf_tml_total = NULL; 17531 fp->uf_tml_self = NULL; 17532 fp->uf_profiling = FALSE; 17533 if (prof_def_func()) 17534 func_do_profile(fp); 17535 #endif 17536 fp->uf_varargs = varargs; 17537 fp->uf_flags = flags; 17538 fp->uf_calls = 0; 17539 fp->uf_script_ID = current_SID; 17540 goto ret_free; 17541 17542 erret: 17543 ga_clear_strings(&newargs); 17544 ga_clear_strings(&newlines); 17545 ret_free: 17546 vim_free(skip_until); 17547 vim_free(fudi.fd_newkey); 17548 vim_free(name); 17549 did_emsg |= saved_did_emsg; 17550 } 17551 17552 /* 17553 * Get a function name, translating "<SID>" and "<SNR>". 17554 * Also handles a Funcref in a List or Dictionary. 17555 * Returns the function name in allocated memory, or NULL for failure. 17556 * flags: 17557 * TFN_INT: internal function name OK 17558 * TFN_QUIET: be quiet 17559 * Advances "pp" to just after the function name (if no error). 17560 */ 17561 static char_u * 17562 trans_function_name(pp, skip, flags, fdp) 17563 char_u **pp; 17564 int skip; /* only find the end, don't evaluate */ 17565 int flags; 17566 funcdict_T *fdp; /* return: info about dictionary used */ 17567 { 17568 char_u *name = NULL; 17569 char_u *start; 17570 char_u *end; 17571 int lead; 17572 char_u sid_buf[20]; 17573 int len; 17574 lval_T lv; 17575 17576 if (fdp != NULL) 17577 vim_memset(fdp, 0, sizeof(funcdict_T)); 17578 start = *pp; 17579 17580 /* Check for hard coded <SNR>: already translated function ID (from a user 17581 * command). */ 17582 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17583 && (*pp)[2] == (int)KE_SNR) 17584 { 17585 *pp += 3; 17586 len = get_id_len(pp) + 3; 17587 return vim_strnsave(start, len); 17588 } 17589 17590 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17591 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17592 lead = eval_fname_script(start); 17593 if (lead > 2) 17594 start += lead; 17595 17596 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17597 lead > 2 ? 0 : FNE_CHECK_START); 17598 if (end == start) 17599 { 17600 if (!skip) 17601 EMSG(_("E129: Function name required")); 17602 goto theend; 17603 } 17604 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17605 { 17606 /* 17607 * Report an invalid expression in braces, unless the expression 17608 * evaluation has been cancelled due to an aborting error, an 17609 * interrupt, or an exception. 17610 */ 17611 if (!aborting()) 17612 { 17613 if (end != NULL) 17614 EMSG2(_(e_invarg2), start); 17615 } 17616 else 17617 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17618 goto theend; 17619 } 17620 17621 if (lv.ll_tv != NULL) 17622 { 17623 if (fdp != NULL) 17624 { 17625 fdp->fd_dict = lv.ll_dict; 17626 fdp->fd_newkey = lv.ll_newkey; 17627 lv.ll_newkey = NULL; 17628 fdp->fd_di = lv.ll_di; 17629 } 17630 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17631 { 17632 name = vim_strsave(lv.ll_tv->vval.v_string); 17633 *pp = end; 17634 } 17635 else 17636 { 17637 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17638 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17639 EMSG(_(e_funcref)); 17640 else 17641 *pp = end; 17642 name = NULL; 17643 } 17644 goto theend; 17645 } 17646 17647 if (lv.ll_name == NULL) 17648 { 17649 /* Error found, but continue after the function name. */ 17650 *pp = end; 17651 goto theend; 17652 } 17653 17654 if (lv.ll_exp_name != NULL) 17655 len = STRLEN(lv.ll_exp_name); 17656 else 17657 { 17658 if (lead == 2) /* skip over "s:" */ 17659 lv.ll_name += 2; 17660 len = (int)(end - lv.ll_name); 17661 } 17662 17663 /* 17664 * Copy the function name to allocated memory. 17665 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17666 * Accept <SNR>123_name() outside a script. 17667 */ 17668 if (skip) 17669 lead = 0; /* do nothing */ 17670 else if (lead > 0) 17671 { 17672 lead = 3; 17673 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17674 { 17675 if (current_SID <= 0) 17676 { 17677 EMSG(_(e_usingsid)); 17678 goto theend; 17679 } 17680 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17681 lead += (int)STRLEN(sid_buf); 17682 } 17683 } 17684 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17685 { 17686 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17687 goto theend; 17688 } 17689 name = alloc((unsigned)(len + lead + 1)); 17690 if (name != NULL) 17691 { 17692 if (lead > 0) 17693 { 17694 name[0] = K_SPECIAL; 17695 name[1] = KS_EXTRA; 17696 name[2] = (int)KE_SNR; 17697 if (lead > 3) /* If it's "<SID>" */ 17698 STRCPY(name + 3, sid_buf); 17699 } 17700 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17701 name[len + lead] = NUL; 17702 } 17703 *pp = end; 17704 17705 theend: 17706 clear_lval(&lv); 17707 return name; 17708 } 17709 17710 /* 17711 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17712 * Return 2 if "p" starts with "s:". 17713 * Return 0 otherwise. 17714 */ 17715 static int 17716 eval_fname_script(p) 17717 char_u *p; 17718 { 17719 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17720 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17721 return 5; 17722 if (p[0] == 's' && p[1] == ':') 17723 return 2; 17724 return 0; 17725 } 17726 17727 /* 17728 * Return TRUE if "p" starts with "<SID>" or "s:". 17729 * Only works if eval_fname_script() returned non-zero for "p"! 17730 */ 17731 static int 17732 eval_fname_sid(p) 17733 char_u *p; 17734 { 17735 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17736 } 17737 17738 /* 17739 * List the head of the function: "name(arg1, arg2)". 17740 */ 17741 static void 17742 list_func_head(fp, indent) 17743 ufunc_T *fp; 17744 int indent; 17745 { 17746 int j; 17747 17748 msg_start(); 17749 if (indent) 17750 MSG_PUTS(" "); 17751 MSG_PUTS("function "); 17752 if (fp->uf_name[0] == K_SPECIAL) 17753 { 17754 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17755 msg_puts(fp->uf_name + 3); 17756 } 17757 else 17758 msg_puts(fp->uf_name); 17759 msg_putchar('('); 17760 for (j = 0; j < fp->uf_args.ga_len; ++j) 17761 { 17762 if (j) 17763 MSG_PUTS(", "); 17764 msg_puts(FUNCARG(fp, j)); 17765 } 17766 if (fp->uf_varargs) 17767 { 17768 if (j) 17769 MSG_PUTS(", "); 17770 MSG_PUTS("..."); 17771 } 17772 msg_putchar(')'); 17773 msg_clr_eos(); 17774 if (p_verbose > 0) 17775 last_set_msg(fp->uf_script_ID); 17776 } 17777 17778 /* 17779 * Find a function by name, return pointer to it in ufuncs. 17780 * Return NULL for unknown function. 17781 */ 17782 static ufunc_T * 17783 find_func(name) 17784 char_u *name; 17785 { 17786 hashitem_T *hi; 17787 17788 hi = hash_find(&func_hashtab, name); 17789 if (!HASHITEM_EMPTY(hi)) 17790 return HI2UF(hi); 17791 return NULL; 17792 } 17793 17794 #if defined(EXITFREE) || defined(PROTO) 17795 void 17796 free_all_functions() 17797 { 17798 hashitem_T *hi; 17799 17800 /* Need to start all over every time, because func_free() may change the 17801 * hash table. */ 17802 while (func_hashtab.ht_used > 0) 17803 for (hi = func_hashtab.ht_array; ; ++hi) 17804 if (!HASHITEM_EMPTY(hi)) 17805 { 17806 func_free(HI2UF(hi)); 17807 break; 17808 } 17809 } 17810 #endif 17811 17812 /* 17813 * Return TRUE if a function "name" exists. 17814 */ 17815 static int 17816 function_exists(name) 17817 char_u *name; 17818 { 17819 char_u *p = name; 17820 int n = FALSE; 17821 17822 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17823 if (p != NULL) 17824 { 17825 if (builtin_function(p)) 17826 n = (find_internal_func(p) >= 0); 17827 else 17828 n = (find_func(p) != NULL); 17829 vim_free(p); 17830 } 17831 return n; 17832 } 17833 17834 /* 17835 * Return TRUE if "name" looks like a builtin function name: starts with a 17836 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17837 */ 17838 static int 17839 builtin_function(name) 17840 char_u *name; 17841 { 17842 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17843 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17844 } 17845 17846 #if defined(FEAT_PROFILE) || defined(PROTO) 17847 /* 17848 * Start profiling function "fp". 17849 */ 17850 static void 17851 func_do_profile(fp) 17852 ufunc_T *fp; 17853 { 17854 fp->uf_tm_count = 0; 17855 profile_zero(&fp->uf_tm_self); 17856 profile_zero(&fp->uf_tm_total); 17857 if (fp->uf_tml_count == NULL) 17858 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17859 (sizeof(int) * fp->uf_lines.ga_len)); 17860 if (fp->uf_tml_total == NULL) 17861 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17862 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17863 if (fp->uf_tml_self == NULL) 17864 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17865 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17866 fp->uf_tml_idx = -1; 17867 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17868 || fp->uf_tml_self == NULL) 17869 return; /* out of memory */ 17870 17871 fp->uf_profiling = TRUE; 17872 } 17873 17874 /* 17875 * Dump the profiling results for all functions in file "fd". 17876 */ 17877 void 17878 func_dump_profile(fd) 17879 FILE *fd; 17880 { 17881 hashitem_T *hi; 17882 int todo; 17883 ufunc_T *fp; 17884 int i; 17885 ufunc_T **sorttab; 17886 int st_len = 0; 17887 17888 todo = func_hashtab.ht_used; 17889 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17890 17891 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17892 { 17893 if (!HASHITEM_EMPTY(hi)) 17894 { 17895 --todo; 17896 fp = HI2UF(hi); 17897 if (fp->uf_profiling) 17898 { 17899 if (sorttab != NULL) 17900 sorttab[st_len++] = fp; 17901 17902 if (fp->uf_name[0] == K_SPECIAL) 17903 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17904 else 17905 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17906 if (fp->uf_tm_count == 1) 17907 fprintf(fd, "Called 1 time\n"); 17908 else 17909 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17910 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17911 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17912 fprintf(fd, "\n"); 17913 fprintf(fd, "count total (s) self (s)\n"); 17914 17915 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17916 { 17917 prof_func_line(fd, fp->uf_tml_count[i], 17918 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17919 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17920 } 17921 fprintf(fd, "\n"); 17922 } 17923 } 17924 } 17925 17926 if (sorttab != NULL && st_len > 0) 17927 { 17928 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17929 prof_total_cmp); 17930 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17931 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17932 prof_self_cmp); 17933 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17934 } 17935 } 17936 17937 static void 17938 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17939 FILE *fd; 17940 ufunc_T **sorttab; 17941 int st_len; 17942 char *title; 17943 int prefer_self; /* when equal print only self time */ 17944 { 17945 int i; 17946 ufunc_T *fp; 17947 17948 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17949 fprintf(fd, "count total (s) self (s) function\n"); 17950 for (i = 0; i < 20 && i < st_len; ++i) 17951 { 17952 fp = sorttab[i]; 17953 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17954 prefer_self); 17955 if (fp->uf_name[0] == K_SPECIAL) 17956 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17957 else 17958 fprintf(fd, " %s()\n", fp->uf_name); 17959 } 17960 fprintf(fd, "\n"); 17961 } 17962 17963 /* 17964 * Print the count and times for one function or function line. 17965 */ 17966 static void 17967 prof_func_line(fd, count, total, self, prefer_self) 17968 FILE *fd; 17969 int count; 17970 proftime_T *total; 17971 proftime_T *self; 17972 int prefer_self; /* when equal print only self time */ 17973 { 17974 if (count > 0) 17975 { 17976 fprintf(fd, "%5d ", count); 17977 if (prefer_self && profile_equal(total, self)) 17978 fprintf(fd, " "); 17979 else 17980 fprintf(fd, "%s ", profile_msg(total)); 17981 if (!prefer_self && profile_equal(total, self)) 17982 fprintf(fd, " "); 17983 else 17984 fprintf(fd, "%s ", profile_msg(self)); 17985 } 17986 else 17987 fprintf(fd, " "); 17988 } 17989 17990 /* 17991 * Compare function for total time sorting. 17992 */ 17993 static int 17994 #ifdef __BORLANDC__ 17995 _RTLENTRYF 17996 #endif 17997 prof_total_cmp(s1, s2) 17998 const void *s1; 17999 const void *s2; 18000 { 18001 ufunc_T *p1, *p2; 18002 18003 p1 = *(ufunc_T **)s1; 18004 p2 = *(ufunc_T **)s2; 18005 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 18006 } 18007 18008 /* 18009 * Compare function for self time sorting. 18010 */ 18011 static int 18012 #ifdef __BORLANDC__ 18013 _RTLENTRYF 18014 #endif 18015 prof_self_cmp(s1, s2) 18016 const void *s1; 18017 const void *s2; 18018 { 18019 ufunc_T *p1, *p2; 18020 18021 p1 = *(ufunc_T **)s1; 18022 p2 = *(ufunc_T **)s2; 18023 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 18024 } 18025 18026 #endif 18027 18028 /* The names of packages that once were loaded is remembered. */ 18029 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 18030 18031 /* 18032 * If "name" has a package name try autoloading the script for it. 18033 * Return TRUE if a package was loaded. 18034 */ 18035 static int 18036 script_autoload(name, reload) 18037 char_u *name; 18038 int reload; /* load script again when already loaded */ 18039 { 18040 char_u *p; 18041 char_u *scriptname, *tofree; 18042 int ret = FALSE; 18043 int i; 18044 18045 /* If there is no '#' after name[0] there is no package name. */ 18046 p = vim_strchr(name, AUTOLOAD_CHAR); 18047 if (p == NULL || p == name) 18048 return FALSE; 18049 18050 tofree = scriptname = autoload_name(name); 18051 18052 /* Find the name in the list of previously loaded package names. Skip 18053 * "autoload/", it's always the same. */ 18054 for (i = 0; i < ga_loaded.ga_len; ++i) 18055 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 18056 break; 18057 if (!reload && i < ga_loaded.ga_len) 18058 ret = FALSE; /* was loaded already */ 18059 else 18060 { 18061 /* Remember the name if it wasn't loaded already. */ 18062 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 18063 { 18064 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 18065 tofree = NULL; 18066 } 18067 18068 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 18069 if (source_runtime(scriptname, FALSE) == OK) 18070 ret = TRUE; 18071 } 18072 18073 vim_free(tofree); 18074 return ret; 18075 } 18076 18077 /* 18078 * Return the autoload script name for a function or variable name. 18079 * Returns NULL when out of memory. 18080 */ 18081 static char_u * 18082 autoload_name(name) 18083 char_u *name; 18084 { 18085 char_u *p; 18086 char_u *scriptname; 18087 18088 /* Get the script file name: replace '#' with '/', append ".vim". */ 18089 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 18090 if (scriptname == NULL) 18091 return FALSE; 18092 STRCPY(scriptname, "autoload/"); 18093 STRCAT(scriptname, name); 18094 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 18095 STRCAT(scriptname, ".vim"); 18096 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 18097 *p = '/'; 18098 return scriptname; 18099 } 18100 18101 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 18102 18103 /* 18104 * Function given to ExpandGeneric() to obtain the list of user defined 18105 * function names. 18106 */ 18107 char_u * 18108 get_user_func_name(xp, idx) 18109 expand_T *xp; 18110 int idx; 18111 { 18112 static long_u done; 18113 static hashitem_T *hi; 18114 ufunc_T *fp; 18115 18116 if (idx == 0) 18117 { 18118 done = 0; 18119 hi = func_hashtab.ht_array; 18120 } 18121 if (done < func_hashtab.ht_used) 18122 { 18123 if (done++ > 0) 18124 ++hi; 18125 while (HASHITEM_EMPTY(hi)) 18126 ++hi; 18127 fp = HI2UF(hi); 18128 18129 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 18130 return fp->uf_name; /* prevents overflow */ 18131 18132 cat_func_name(IObuff, fp); 18133 if (xp->xp_context != EXPAND_USER_FUNC) 18134 { 18135 STRCAT(IObuff, "("); 18136 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 18137 STRCAT(IObuff, ")"); 18138 } 18139 return IObuff; 18140 } 18141 return NULL; 18142 } 18143 18144 #endif /* FEAT_CMDL_COMPL */ 18145 18146 /* 18147 * Copy the function name of "fp" to buffer "buf". 18148 * "buf" must be able to hold the function name plus three bytes. 18149 * Takes care of script-local function names. 18150 */ 18151 static void 18152 cat_func_name(buf, fp) 18153 char_u *buf; 18154 ufunc_T *fp; 18155 { 18156 if (fp->uf_name[0] == K_SPECIAL) 18157 { 18158 STRCPY(buf, "<SNR>"); 18159 STRCAT(buf, fp->uf_name + 3); 18160 } 18161 else 18162 STRCPY(buf, fp->uf_name); 18163 } 18164 18165 /* 18166 * ":delfunction {name}" 18167 */ 18168 void 18169 ex_delfunction(eap) 18170 exarg_T *eap; 18171 { 18172 ufunc_T *fp = NULL; 18173 char_u *p; 18174 char_u *name; 18175 funcdict_T fudi; 18176 18177 p = eap->arg; 18178 name = trans_function_name(&p, eap->skip, 0, &fudi); 18179 vim_free(fudi.fd_newkey); 18180 if (name == NULL) 18181 { 18182 if (fudi.fd_dict != NULL && !eap->skip) 18183 EMSG(_(e_funcref)); 18184 return; 18185 } 18186 if (!ends_excmd(*skipwhite(p))) 18187 { 18188 vim_free(name); 18189 EMSG(_(e_trailing)); 18190 return; 18191 } 18192 eap->nextcmd = check_nextcmd(p); 18193 if (eap->nextcmd != NULL) 18194 *p = NUL; 18195 18196 if (!eap->skip) 18197 fp = find_func(name); 18198 vim_free(name); 18199 18200 if (!eap->skip) 18201 { 18202 if (fp == NULL) 18203 { 18204 EMSG2(_(e_nofunc), eap->arg); 18205 return; 18206 } 18207 if (fp->uf_calls > 0) 18208 { 18209 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 18210 return; 18211 } 18212 18213 if (fudi.fd_dict != NULL) 18214 { 18215 /* Delete the dict item that refers to the function, it will 18216 * invoke func_unref() and possibly delete the function. */ 18217 dictitem_remove(fudi.fd_dict, fudi.fd_di); 18218 } 18219 else 18220 func_free(fp); 18221 } 18222 } 18223 18224 /* 18225 * Free a function and remove it from the list of functions. 18226 */ 18227 static void 18228 func_free(fp) 18229 ufunc_T *fp; 18230 { 18231 hashitem_T *hi; 18232 18233 /* clear this function */ 18234 ga_clear_strings(&(fp->uf_args)); 18235 ga_clear_strings(&(fp->uf_lines)); 18236 #ifdef FEAT_PROFILE 18237 vim_free(fp->uf_tml_count); 18238 vim_free(fp->uf_tml_total); 18239 vim_free(fp->uf_tml_self); 18240 #endif 18241 18242 /* remove the function from the function hashtable */ 18243 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 18244 if (HASHITEM_EMPTY(hi)) 18245 EMSG2(_(e_intern2), "func_free()"); 18246 else 18247 hash_remove(&func_hashtab, hi); 18248 18249 vim_free(fp); 18250 } 18251 18252 /* 18253 * Unreference a Function: decrement the reference count and free it when it 18254 * becomes zero. Only for numbered functions. 18255 */ 18256 static void 18257 func_unref(name) 18258 char_u *name; 18259 { 18260 ufunc_T *fp; 18261 18262 if (name != NULL && isdigit(*name)) 18263 { 18264 fp = find_func(name); 18265 if (fp == NULL) 18266 EMSG2(_(e_intern2), "func_unref()"); 18267 else if (--fp->uf_refcount <= 0) 18268 { 18269 /* Only delete it when it's not being used. Otherwise it's done 18270 * when "uf_calls" becomes zero. */ 18271 if (fp->uf_calls == 0) 18272 func_free(fp); 18273 } 18274 } 18275 } 18276 18277 /* 18278 * Count a reference to a Function. 18279 */ 18280 static void 18281 func_ref(name) 18282 char_u *name; 18283 { 18284 ufunc_T *fp; 18285 18286 if (name != NULL && isdigit(*name)) 18287 { 18288 fp = find_func(name); 18289 if (fp == NULL) 18290 EMSG2(_(e_intern2), "func_ref()"); 18291 else 18292 ++fp->uf_refcount; 18293 } 18294 } 18295 18296 /* 18297 * Call a user function. 18298 */ 18299 static void 18300 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18301 ufunc_T *fp; /* pointer to function */ 18302 int argcount; /* nr of args */ 18303 typval_T *argvars; /* arguments */ 18304 typval_T *rettv; /* return value */ 18305 linenr_T firstline; /* first line of range */ 18306 linenr_T lastline; /* last line of range */ 18307 dict_T *selfdict; /* Dictionary for "self" */ 18308 { 18309 char_u *save_sourcing_name; 18310 linenr_T save_sourcing_lnum; 18311 scid_T save_current_SID; 18312 funccall_T fc; 18313 int save_did_emsg; 18314 static int depth = 0; 18315 dictitem_T *v; 18316 int fixvar_idx = 0; /* index in fixvar[] */ 18317 int i; 18318 int ai; 18319 char_u numbuf[NUMBUFLEN]; 18320 char_u *name; 18321 #ifdef FEAT_PROFILE 18322 proftime_T wait_start; 18323 #endif 18324 18325 /* If depth of calling is getting too high, don't execute the function */ 18326 if (depth >= p_mfd) 18327 { 18328 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18329 rettv->v_type = VAR_NUMBER; 18330 rettv->vval.v_number = -1; 18331 return; 18332 } 18333 ++depth; 18334 18335 line_breakcheck(); /* check for CTRL-C hit */ 18336 18337 fc.caller = current_funccal; 18338 current_funccal = &fc; 18339 fc.func = fp; 18340 fc.rettv = rettv; 18341 rettv->vval.v_number = 0; 18342 fc.linenr = 0; 18343 fc.returned = FALSE; 18344 fc.level = ex_nesting_level; 18345 /* Check if this function has a breakpoint. */ 18346 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18347 fc.dbg_tick = debug_tick; 18348 18349 /* 18350 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18351 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18352 * each argument variable and saves a lot of time. 18353 */ 18354 /* 18355 * Init l: variables. 18356 */ 18357 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18358 if (selfdict != NULL) 18359 { 18360 /* Set l:self to "selfdict". */ 18361 v = &fc.fixvar[fixvar_idx++].var; 18362 STRCPY(v->di_key, "self"); 18363 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18364 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18365 v->di_tv.v_type = VAR_DICT; 18366 v->di_tv.v_lock = 0; 18367 v->di_tv.vval.v_dict = selfdict; 18368 ++selfdict->dv_refcount; 18369 } 18370 18371 /* 18372 * Init a: variables. 18373 * Set a:0 to "argcount". 18374 * Set a:000 to a list with room for the "..." arguments. 18375 */ 18376 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18377 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18378 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18379 v = &fc.fixvar[fixvar_idx++].var; 18380 STRCPY(v->di_key, "000"); 18381 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18382 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18383 v->di_tv.v_type = VAR_LIST; 18384 v->di_tv.v_lock = VAR_FIXED; 18385 v->di_tv.vval.v_list = &fc.l_varlist; 18386 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18387 fc.l_varlist.lv_refcount = 99999; 18388 18389 /* 18390 * Set a:firstline to "firstline" and a:lastline to "lastline". 18391 * Set a:name to named arguments. 18392 * Set a:N to the "..." arguments. 18393 */ 18394 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18395 (varnumber_T)firstline); 18396 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18397 (varnumber_T)lastline); 18398 for (i = 0; i < argcount; ++i) 18399 { 18400 ai = i - fp->uf_args.ga_len; 18401 if (ai < 0) 18402 /* named argument a:name */ 18403 name = FUNCARG(fp, i); 18404 else 18405 { 18406 /* "..." argument a:1, a:2, etc. */ 18407 sprintf((char *)numbuf, "%d", ai + 1); 18408 name = numbuf; 18409 } 18410 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18411 { 18412 v = &fc.fixvar[fixvar_idx++].var; 18413 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18414 } 18415 else 18416 { 18417 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18418 + STRLEN(name))); 18419 if (v == NULL) 18420 break; 18421 v->di_flags = DI_FLAGS_RO; 18422 } 18423 STRCPY(v->di_key, name); 18424 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18425 18426 /* Note: the values are copied directly to avoid alloc/free. 18427 * "argvars" must have VAR_FIXED for v_lock. */ 18428 v->di_tv = argvars[i]; 18429 v->di_tv.v_lock = VAR_FIXED; 18430 18431 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18432 { 18433 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18434 fc.l_listitems[ai].li_tv = argvars[i]; 18435 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18436 } 18437 } 18438 18439 /* Don't redraw while executing the function. */ 18440 ++RedrawingDisabled; 18441 save_sourcing_name = sourcing_name; 18442 save_sourcing_lnum = sourcing_lnum; 18443 sourcing_lnum = 1; 18444 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18445 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18446 if (sourcing_name != NULL) 18447 { 18448 if (save_sourcing_name != NULL 18449 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18450 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18451 else 18452 STRCPY(sourcing_name, "function "); 18453 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18454 18455 if (p_verbose >= 12) 18456 { 18457 ++no_wait_return; 18458 verbose_enter_scroll(); 18459 18460 smsg((char_u *)_("calling %s"), sourcing_name); 18461 if (p_verbose >= 14) 18462 { 18463 char_u buf[MSG_BUF_LEN]; 18464 char_u numbuf[NUMBUFLEN]; 18465 char_u *tofree; 18466 18467 msg_puts((char_u *)"("); 18468 for (i = 0; i < argcount; ++i) 18469 { 18470 if (i > 0) 18471 msg_puts((char_u *)", "); 18472 if (argvars[i].v_type == VAR_NUMBER) 18473 msg_outnum((long)argvars[i].vval.v_number); 18474 else 18475 { 18476 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18477 buf, MSG_BUF_CLEN); 18478 msg_puts(buf); 18479 vim_free(tofree); 18480 } 18481 } 18482 msg_puts((char_u *)")"); 18483 } 18484 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18485 18486 verbose_leave_scroll(); 18487 --no_wait_return; 18488 } 18489 } 18490 #ifdef FEAT_PROFILE 18491 if (do_profiling) 18492 { 18493 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18494 func_do_profile(fp); 18495 if (fp->uf_profiling 18496 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18497 { 18498 ++fp->uf_tm_count; 18499 profile_start(&fp->uf_tm_start); 18500 profile_zero(&fp->uf_tm_children); 18501 } 18502 script_prof_save(&wait_start); 18503 } 18504 #endif 18505 18506 save_current_SID = current_SID; 18507 current_SID = fp->uf_script_ID; 18508 save_did_emsg = did_emsg; 18509 did_emsg = FALSE; 18510 18511 /* call do_cmdline() to execute the lines */ 18512 do_cmdline(NULL, get_func_line, (void *)&fc, 18513 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18514 18515 --RedrawingDisabled; 18516 18517 /* when the function was aborted because of an error, return -1 */ 18518 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18519 { 18520 clear_tv(rettv); 18521 rettv->v_type = VAR_NUMBER; 18522 rettv->vval.v_number = -1; 18523 } 18524 18525 #ifdef FEAT_PROFILE 18526 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18527 { 18528 profile_end(&fp->uf_tm_start); 18529 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18530 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18531 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18532 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18533 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18534 { 18535 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18536 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18537 } 18538 } 18539 #endif 18540 18541 /* when being verbose, mention the return value */ 18542 if (p_verbose >= 12) 18543 { 18544 ++no_wait_return; 18545 verbose_enter_scroll(); 18546 18547 if (aborting()) 18548 smsg((char_u *)_("%s aborted"), sourcing_name); 18549 else if (fc.rettv->v_type == VAR_NUMBER) 18550 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18551 (long)fc.rettv->vval.v_number); 18552 else 18553 { 18554 char_u buf[MSG_BUF_LEN]; 18555 char_u numbuf[NUMBUFLEN]; 18556 char_u *tofree; 18557 18558 /* The value may be very long. Skip the middle part, so that we 18559 * have some idea how it starts and ends. smsg() would always 18560 * truncate it at the end. */ 18561 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18562 buf, MSG_BUF_CLEN); 18563 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18564 vim_free(tofree); 18565 } 18566 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18567 18568 verbose_leave_scroll(); 18569 --no_wait_return; 18570 } 18571 18572 vim_free(sourcing_name); 18573 sourcing_name = save_sourcing_name; 18574 sourcing_lnum = save_sourcing_lnum; 18575 current_SID = save_current_SID; 18576 #ifdef FEAT_PROFILE 18577 if (do_profiling) 18578 script_prof_restore(&wait_start); 18579 #endif 18580 18581 if (p_verbose >= 12 && sourcing_name != NULL) 18582 { 18583 ++no_wait_return; 18584 verbose_enter_scroll(); 18585 18586 smsg((char_u *)_("continuing in %s"), sourcing_name); 18587 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18588 18589 verbose_leave_scroll(); 18590 --no_wait_return; 18591 } 18592 18593 did_emsg |= save_did_emsg; 18594 current_funccal = fc.caller; 18595 18596 /* The a: variables typevals were not alloced, only free the allocated 18597 * variables. */ 18598 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18599 18600 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18601 --depth; 18602 } 18603 18604 /* 18605 * Add a number variable "name" to dict "dp" with value "nr". 18606 */ 18607 static void 18608 add_nr_var(dp, v, name, nr) 18609 dict_T *dp; 18610 dictitem_T *v; 18611 char *name; 18612 varnumber_T nr; 18613 { 18614 STRCPY(v->di_key, name); 18615 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18616 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18617 v->di_tv.v_type = VAR_NUMBER; 18618 v->di_tv.v_lock = VAR_FIXED; 18619 v->di_tv.vval.v_number = nr; 18620 } 18621 18622 /* 18623 * ":return [expr]" 18624 */ 18625 void 18626 ex_return(eap) 18627 exarg_T *eap; 18628 { 18629 char_u *arg = eap->arg; 18630 typval_T rettv; 18631 int returning = FALSE; 18632 18633 if (current_funccal == NULL) 18634 { 18635 EMSG(_("E133: :return not inside a function")); 18636 return; 18637 } 18638 18639 if (eap->skip) 18640 ++emsg_skip; 18641 18642 eap->nextcmd = NULL; 18643 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18644 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18645 { 18646 if (!eap->skip) 18647 returning = do_return(eap, FALSE, TRUE, &rettv); 18648 else 18649 clear_tv(&rettv); 18650 } 18651 /* It's safer to return also on error. */ 18652 else if (!eap->skip) 18653 { 18654 /* 18655 * Return unless the expression evaluation has been cancelled due to an 18656 * aborting error, an interrupt, or an exception. 18657 */ 18658 if (!aborting()) 18659 returning = do_return(eap, FALSE, TRUE, NULL); 18660 } 18661 18662 /* When skipping or the return gets pending, advance to the next command 18663 * in this line (!returning). Otherwise, ignore the rest of the line. 18664 * Following lines will be ignored by get_func_line(). */ 18665 if (returning) 18666 eap->nextcmd = NULL; 18667 else if (eap->nextcmd == NULL) /* no argument */ 18668 eap->nextcmd = check_nextcmd(arg); 18669 18670 if (eap->skip) 18671 --emsg_skip; 18672 } 18673 18674 /* 18675 * Return from a function. Possibly makes the return pending. Also called 18676 * for a pending return at the ":endtry" or after returning from an extra 18677 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18678 * when called due to a ":return" command. "rettv" may point to a typval_T 18679 * with the return rettv. Returns TRUE when the return can be carried out, 18680 * FALSE when the return gets pending. 18681 */ 18682 int 18683 do_return(eap, reanimate, is_cmd, rettv) 18684 exarg_T *eap; 18685 int reanimate; 18686 int is_cmd; 18687 void *rettv; 18688 { 18689 int idx; 18690 struct condstack *cstack = eap->cstack; 18691 18692 if (reanimate) 18693 /* Undo the return. */ 18694 current_funccal->returned = FALSE; 18695 18696 /* 18697 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18698 * not in its finally clause (which then is to be executed next) is found. 18699 * In this case, make the ":return" pending for execution at the ":endtry". 18700 * Otherwise, return normally. 18701 */ 18702 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18703 if (idx >= 0) 18704 { 18705 cstack->cs_pending[idx] = CSTP_RETURN; 18706 18707 if (!is_cmd && !reanimate) 18708 /* A pending return again gets pending. "rettv" points to an 18709 * allocated variable with the rettv of the original ":return"'s 18710 * argument if present or is NULL else. */ 18711 cstack->cs_rettv[idx] = rettv; 18712 else 18713 { 18714 /* When undoing a return in order to make it pending, get the stored 18715 * return rettv. */ 18716 if (reanimate) 18717 rettv = current_funccal->rettv; 18718 18719 if (rettv != NULL) 18720 { 18721 /* Store the value of the pending return. */ 18722 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18723 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18724 else 18725 EMSG(_(e_outofmem)); 18726 } 18727 else 18728 cstack->cs_rettv[idx] = NULL; 18729 18730 if (reanimate) 18731 { 18732 /* The pending return value could be overwritten by a ":return" 18733 * without argument in a finally clause; reset the default 18734 * return value. */ 18735 current_funccal->rettv->v_type = VAR_NUMBER; 18736 current_funccal->rettv->vval.v_number = 0; 18737 } 18738 } 18739 report_make_pending(CSTP_RETURN, rettv); 18740 } 18741 else 18742 { 18743 current_funccal->returned = TRUE; 18744 18745 /* If the return is carried out now, store the return value. For 18746 * a return immediately after reanimation, the value is already 18747 * there. */ 18748 if (!reanimate && rettv != NULL) 18749 { 18750 clear_tv(current_funccal->rettv); 18751 *current_funccal->rettv = *(typval_T *)rettv; 18752 if (!is_cmd) 18753 vim_free(rettv); 18754 } 18755 } 18756 18757 return idx < 0; 18758 } 18759 18760 /* 18761 * Free the variable with a pending return value. 18762 */ 18763 void 18764 discard_pending_return(rettv) 18765 void *rettv; 18766 { 18767 free_tv((typval_T *)rettv); 18768 } 18769 18770 /* 18771 * Generate a return command for producing the value of "rettv". The result 18772 * is an allocated string. Used by report_pending() for verbose messages. 18773 */ 18774 char_u * 18775 get_return_cmd(rettv) 18776 void *rettv; 18777 { 18778 char_u *s = NULL; 18779 char_u *tofree = NULL; 18780 char_u numbuf[NUMBUFLEN]; 18781 18782 if (rettv != NULL) 18783 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18784 if (s == NULL) 18785 s = (char_u *)""; 18786 18787 STRCPY(IObuff, ":return "); 18788 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18789 if (STRLEN(s) + 8 >= IOSIZE) 18790 STRCPY(IObuff + IOSIZE - 4, "..."); 18791 vim_free(tofree); 18792 return vim_strsave(IObuff); 18793 } 18794 18795 /* 18796 * Get next function line. 18797 * Called by do_cmdline() to get the next line. 18798 * Returns allocated string, or NULL for end of function. 18799 */ 18800 /* ARGSUSED */ 18801 char_u * 18802 get_func_line(c, cookie, indent) 18803 int c; /* not used */ 18804 void *cookie; 18805 int indent; /* not used */ 18806 { 18807 funccall_T *fcp = (funccall_T *)cookie; 18808 ufunc_T *fp = fcp->func; 18809 char_u *retval; 18810 garray_T *gap; /* growarray with function lines */ 18811 18812 /* If breakpoints have been added/deleted need to check for it. */ 18813 if (fcp->dbg_tick != debug_tick) 18814 { 18815 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18816 sourcing_lnum); 18817 fcp->dbg_tick = debug_tick; 18818 } 18819 #ifdef FEAT_PROFILE 18820 if (do_profiling) 18821 func_line_end(cookie); 18822 #endif 18823 18824 gap = &fp->uf_lines; 18825 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18826 retval = NULL; 18827 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18828 retval = NULL; 18829 else 18830 { 18831 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18832 sourcing_lnum = fcp->linenr; 18833 #ifdef FEAT_PROFILE 18834 if (do_profiling) 18835 func_line_start(cookie); 18836 #endif 18837 } 18838 18839 /* Did we encounter a breakpoint? */ 18840 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18841 { 18842 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18843 /* Find next breakpoint. */ 18844 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18845 sourcing_lnum); 18846 fcp->dbg_tick = debug_tick; 18847 } 18848 18849 return retval; 18850 } 18851 18852 #if defined(FEAT_PROFILE) || defined(PROTO) 18853 /* 18854 * Called when starting to read a function line. 18855 * "sourcing_lnum" must be correct! 18856 * When skipping lines it may not actually be executed, but we won't find out 18857 * until later and we need to store the time now. 18858 */ 18859 void 18860 func_line_start(cookie) 18861 void *cookie; 18862 { 18863 funccall_T *fcp = (funccall_T *)cookie; 18864 ufunc_T *fp = fcp->func; 18865 18866 if (fp->uf_profiling && sourcing_lnum >= 1 18867 && sourcing_lnum <= fp->uf_lines.ga_len) 18868 { 18869 fp->uf_tml_idx = sourcing_lnum - 1; 18870 fp->uf_tml_execed = FALSE; 18871 profile_start(&fp->uf_tml_start); 18872 profile_zero(&fp->uf_tml_children); 18873 profile_get_wait(&fp->uf_tml_wait); 18874 } 18875 } 18876 18877 /* 18878 * Called when actually executing a function line. 18879 */ 18880 void 18881 func_line_exec(cookie) 18882 void *cookie; 18883 { 18884 funccall_T *fcp = (funccall_T *)cookie; 18885 ufunc_T *fp = fcp->func; 18886 18887 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18888 fp->uf_tml_execed = TRUE; 18889 } 18890 18891 /* 18892 * Called when done with a function line. 18893 */ 18894 void 18895 func_line_end(cookie) 18896 void *cookie; 18897 { 18898 funccall_T *fcp = (funccall_T *)cookie; 18899 ufunc_T *fp = fcp->func; 18900 18901 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18902 { 18903 if (fp->uf_tml_execed) 18904 { 18905 ++fp->uf_tml_count[fp->uf_tml_idx]; 18906 profile_end(&fp->uf_tml_start); 18907 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18908 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18909 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18910 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18911 } 18912 fp->uf_tml_idx = -1; 18913 } 18914 } 18915 #endif 18916 18917 /* 18918 * Return TRUE if the currently active function should be ended, because a 18919 * return was encountered or an error occured. Used inside a ":while". 18920 */ 18921 int 18922 func_has_ended(cookie) 18923 void *cookie; 18924 { 18925 funccall_T *fcp = (funccall_T *)cookie; 18926 18927 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18928 * an error inside a try conditional. */ 18929 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18930 || fcp->returned); 18931 } 18932 18933 /* 18934 * return TRUE if cookie indicates a function which "abort"s on errors. 18935 */ 18936 int 18937 func_has_abort(cookie) 18938 void *cookie; 18939 { 18940 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18941 } 18942 18943 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18944 typedef enum 18945 { 18946 VAR_FLAVOUR_DEFAULT, 18947 VAR_FLAVOUR_SESSION, 18948 VAR_FLAVOUR_VIMINFO 18949 } var_flavour_T; 18950 18951 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18952 18953 static var_flavour_T 18954 var_flavour(varname) 18955 char_u *varname; 18956 { 18957 char_u *p = varname; 18958 18959 if (ASCII_ISUPPER(*p)) 18960 { 18961 while (*(++p)) 18962 if (ASCII_ISLOWER(*p)) 18963 return VAR_FLAVOUR_SESSION; 18964 return VAR_FLAVOUR_VIMINFO; 18965 } 18966 else 18967 return VAR_FLAVOUR_DEFAULT; 18968 } 18969 #endif 18970 18971 #if defined(FEAT_VIMINFO) || defined(PROTO) 18972 /* 18973 * Restore global vars that start with a capital from the viminfo file 18974 */ 18975 int 18976 read_viminfo_varlist(virp, writing) 18977 vir_T *virp; 18978 int writing; 18979 { 18980 char_u *tab; 18981 int is_string = FALSE; 18982 typval_T tv; 18983 18984 if (!writing && (find_viminfo_parameter('!') != NULL)) 18985 { 18986 tab = vim_strchr(virp->vir_line + 1, '\t'); 18987 if (tab != NULL) 18988 { 18989 *tab++ = '\0'; /* isolate the variable name */ 18990 if (*tab == 'S') /* string var */ 18991 is_string = TRUE; 18992 18993 tab = vim_strchr(tab, '\t'); 18994 if (tab != NULL) 18995 { 18996 if (is_string) 18997 { 18998 tv.v_type = VAR_STRING; 18999 tv.vval.v_string = viminfo_readstring(virp, 19000 (int)(tab - virp->vir_line + 1), TRUE); 19001 } 19002 else 19003 { 19004 tv.v_type = VAR_NUMBER; 19005 tv.vval.v_number = atol((char *)tab + 1); 19006 } 19007 set_var(virp->vir_line + 1, &tv, FALSE); 19008 if (is_string) 19009 vim_free(tv.vval.v_string); 19010 } 19011 } 19012 } 19013 19014 return viminfo_readline(virp); 19015 } 19016 19017 /* 19018 * Write global vars that start with a capital to the viminfo file 19019 */ 19020 void 19021 write_viminfo_varlist(fp) 19022 FILE *fp; 19023 { 19024 hashitem_T *hi; 19025 dictitem_T *this_var; 19026 int todo; 19027 char *s; 19028 char_u *p; 19029 char_u *tofree; 19030 char_u numbuf[NUMBUFLEN]; 19031 19032 if (find_viminfo_parameter('!') == NULL) 19033 return; 19034 19035 fprintf(fp, _("\n# global variables:\n")); 19036 19037 todo = globvarht.ht_used; 19038 for (hi = globvarht.ht_array; todo > 0; ++hi) 19039 { 19040 if (!HASHITEM_EMPTY(hi)) 19041 { 19042 --todo; 19043 this_var = HI2DI(hi); 19044 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 19045 { 19046 switch (this_var->di_tv.v_type) 19047 { 19048 case VAR_STRING: s = "STR"; break; 19049 case VAR_NUMBER: s = "NUM"; break; 19050 default: continue; 19051 } 19052 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 19053 p = echo_string(&this_var->di_tv, &tofree, numbuf); 19054 if (p != NULL) 19055 viminfo_writestring(fp, p); 19056 vim_free(tofree); 19057 } 19058 } 19059 } 19060 } 19061 #endif 19062 19063 #if defined(FEAT_SESSION) || defined(PROTO) 19064 int 19065 store_session_globals(fd) 19066 FILE *fd; 19067 { 19068 hashitem_T *hi; 19069 dictitem_T *this_var; 19070 int todo; 19071 char_u *p, *t; 19072 19073 todo = globvarht.ht_used; 19074 for (hi = globvarht.ht_array; todo > 0; ++hi) 19075 { 19076 if (!HASHITEM_EMPTY(hi)) 19077 { 19078 --todo; 19079 this_var = HI2DI(hi); 19080 if ((this_var->di_tv.v_type == VAR_NUMBER 19081 || this_var->di_tv.v_type == VAR_STRING) 19082 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 19083 { 19084 /* Escape special characters with a backslash. Turn a LF and 19085 * CR into \n and \r. */ 19086 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 19087 (char_u *)"\\\"\n\r"); 19088 if (p == NULL) /* out of memory */ 19089 break; 19090 for (t = p; *t != NUL; ++t) 19091 if (*t == '\n') 19092 *t = 'n'; 19093 else if (*t == '\r') 19094 *t = 'r'; 19095 if ((fprintf(fd, "let %s = %c%s%c", 19096 this_var->di_key, 19097 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19098 : ' ', 19099 p, 19100 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19101 : ' ') < 0) 19102 || put_eol(fd) == FAIL) 19103 { 19104 vim_free(p); 19105 return FAIL; 19106 } 19107 vim_free(p); 19108 } 19109 } 19110 } 19111 return OK; 19112 } 19113 #endif 19114 19115 /* 19116 * Display script name where an item was last set. 19117 * Should only be invoked when 'verbose' is non-zero. 19118 */ 19119 void 19120 last_set_msg(scriptID) 19121 scid_T scriptID; 19122 { 19123 char_u *p; 19124 19125 if (scriptID != 0) 19126 { 19127 p = home_replace_save(NULL, get_scriptname(scriptID)); 19128 if (p != NULL) 19129 { 19130 verbose_enter(); 19131 MSG_PUTS(_("\n\tLast set from ")); 19132 MSG_PUTS(p); 19133 vim_free(p); 19134 verbose_leave(); 19135 } 19136 } 19137 } 19138 19139 #endif /* FEAT_EVAL */ 19140 19141 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 19142 19143 19144 #ifdef WIN3264 19145 /* 19146 * Functions for ":8" filename modifier: get 8.3 version of a filename. 19147 */ 19148 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19149 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 19150 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19151 19152 /* 19153 * Get the short pathname of a file. 19154 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 19155 */ 19156 static int 19157 get_short_pathname(fnamep, bufp, fnamelen) 19158 char_u **fnamep; 19159 char_u **bufp; 19160 int *fnamelen; 19161 { 19162 int l,len; 19163 char_u *newbuf; 19164 19165 len = *fnamelen; 19166 19167 l = GetShortPathName(*fnamep, *fnamep, len); 19168 if (l > len - 1) 19169 { 19170 /* If that doesn't work (not enough space), then save the string 19171 * and try again with a new buffer big enough 19172 */ 19173 newbuf = vim_strnsave(*fnamep, l); 19174 if (newbuf == NULL) 19175 return 0; 19176 19177 vim_free(*bufp); 19178 *fnamep = *bufp = newbuf; 19179 19180 l = GetShortPathName(*fnamep,*fnamep,l+1); 19181 19182 /* Really should always succeed, as the buffer is big enough */ 19183 } 19184 19185 *fnamelen = l; 19186 return 1; 19187 } 19188 19189 /* 19190 * Create a short path name. Returns the length of the buffer it needs. 19191 * Doesn't copy over the end of the buffer passed in. 19192 */ 19193 static int 19194 shortpath_for_invalid_fname(fname, bufp, fnamelen) 19195 char_u **fname; 19196 char_u **bufp; 19197 int *fnamelen; 19198 { 19199 char_u *s, *p, *pbuf2, *pbuf3; 19200 char_u ch; 19201 int len, len2, plen, slen; 19202 19203 /* Make a copy */ 19204 len2 = *fnamelen; 19205 pbuf2 = vim_strnsave(*fname, len2); 19206 pbuf3 = NULL; 19207 19208 s = pbuf2 + len2 - 1; /* Find the end */ 19209 slen = 1; 19210 plen = len2; 19211 19212 if (after_pathsep(pbuf2, s + 1)) 19213 { 19214 --s; 19215 ++slen; 19216 --plen; 19217 } 19218 19219 do 19220 { 19221 /* Go back one path-seperator */ 19222 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 19223 { 19224 --s; 19225 ++slen; 19226 --plen; 19227 } 19228 if (s <= pbuf2) 19229 break; 19230 19231 /* Remeber the character that is about to be blatted */ 19232 ch = *s; 19233 *s = 0; /* get_short_pathname requires a null-terminated string */ 19234 19235 /* Try it in situ */ 19236 p = pbuf2; 19237 if (!get_short_pathname(&p, &pbuf3, &plen)) 19238 { 19239 vim_free(pbuf2); 19240 return -1; 19241 } 19242 *s = ch; /* Preserve the string */ 19243 } while (plen == 0); 19244 19245 if (plen > 0) 19246 { 19247 /* Remeber the length of the new string. */ 19248 *fnamelen = len = plen + slen; 19249 vim_free(*bufp); 19250 if (len > len2) 19251 { 19252 /* If there's not enough space in the currently allocated string, 19253 * then copy it to a buffer big enough. 19254 */ 19255 *fname= *bufp = vim_strnsave(p, len); 19256 if (*fname == NULL) 19257 return -1; 19258 } 19259 else 19260 { 19261 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 19262 *fname = *bufp = pbuf2; 19263 if (p != pbuf2) 19264 strncpy(*fname, p, plen); 19265 pbuf2 = NULL; 19266 } 19267 /* Concat the next bit */ 19268 strncpy(*fname + plen, s, slen); 19269 (*fname)[len] = '\0'; 19270 } 19271 vim_free(pbuf3); 19272 vim_free(pbuf2); 19273 return 0; 19274 } 19275 19276 /* 19277 * Get a pathname for a partial path. 19278 */ 19279 static int 19280 shortpath_for_partial(fnamep, bufp, fnamelen) 19281 char_u **fnamep; 19282 char_u **bufp; 19283 int *fnamelen; 19284 { 19285 int sepcount, len, tflen; 19286 char_u *p; 19287 char_u *pbuf, *tfname; 19288 int hasTilde; 19289 19290 /* Count up the path seperators from the RHS.. so we know which part 19291 * of the path to return. 19292 */ 19293 sepcount = 0; 19294 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19295 if (vim_ispathsep(*p)) 19296 ++sepcount; 19297 19298 /* Need full path first (use expand_env() to remove a "~/") */ 19299 hasTilde = (**fnamep == '~'); 19300 if (hasTilde) 19301 pbuf = tfname = expand_env_save(*fnamep); 19302 else 19303 pbuf = tfname = FullName_save(*fnamep, FALSE); 19304 19305 len = tflen = STRLEN(tfname); 19306 19307 if (!get_short_pathname(&tfname, &pbuf, &len)) 19308 return -1; 19309 19310 if (len == 0) 19311 { 19312 /* Don't have a valid filename, so shorten the rest of the 19313 * path if we can. This CAN give us invalid 8.3 filenames, but 19314 * there's not a lot of point in guessing what it might be. 19315 */ 19316 len = tflen; 19317 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19318 return -1; 19319 } 19320 19321 /* Count the paths backward to find the beginning of the desired string. */ 19322 for (p = tfname + len - 1; p >= tfname; --p) 19323 { 19324 #ifdef FEAT_MBYTE 19325 if (has_mbyte) 19326 p -= mb_head_off(tfname, p); 19327 #endif 19328 if (vim_ispathsep(*p)) 19329 { 19330 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19331 break; 19332 else 19333 sepcount --; 19334 } 19335 } 19336 if (hasTilde) 19337 { 19338 --p; 19339 if (p >= tfname) 19340 *p = '~'; 19341 else 19342 return -1; 19343 } 19344 else 19345 ++p; 19346 19347 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19348 vim_free(*bufp); 19349 *fnamelen = (int)STRLEN(p); 19350 *bufp = pbuf; 19351 *fnamep = p; 19352 19353 return 0; 19354 } 19355 #endif /* WIN3264 */ 19356 19357 /* 19358 * Adjust a filename, according to a string of modifiers. 19359 * *fnamep must be NUL terminated when called. When returning, the length is 19360 * determined by *fnamelen. 19361 * Returns valid flags. 19362 * When there is an error, *fnamep is set to NULL. 19363 */ 19364 int 19365 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19366 char_u *src; /* string with modifiers */ 19367 int *usedlen; /* characters after src that are used */ 19368 char_u **fnamep; /* file name so far */ 19369 char_u **bufp; /* buffer for allocated file name or NULL */ 19370 int *fnamelen; /* length of fnamep */ 19371 { 19372 int valid = 0; 19373 char_u *tail; 19374 char_u *s, *p, *pbuf; 19375 char_u dirname[MAXPATHL]; 19376 int c; 19377 int has_fullname = 0; 19378 #ifdef WIN3264 19379 int has_shortname = 0; 19380 #endif 19381 19382 repeat: 19383 /* ":p" - full path/file_name */ 19384 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19385 { 19386 has_fullname = 1; 19387 19388 valid |= VALID_PATH; 19389 *usedlen += 2; 19390 19391 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19392 if ((*fnamep)[0] == '~' 19393 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19394 && ((*fnamep)[1] == '/' 19395 # ifdef BACKSLASH_IN_FILENAME 19396 || (*fnamep)[1] == '\\' 19397 # endif 19398 || (*fnamep)[1] == NUL) 19399 19400 #endif 19401 ) 19402 { 19403 *fnamep = expand_env_save(*fnamep); 19404 vim_free(*bufp); /* free any allocated file name */ 19405 *bufp = *fnamep; 19406 if (*fnamep == NULL) 19407 return -1; 19408 } 19409 19410 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19411 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19412 { 19413 if (vim_ispathsep(*p) 19414 && p[1] == '.' 19415 && (p[2] == NUL 19416 || vim_ispathsep(p[2]) 19417 || (p[2] == '.' 19418 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19419 break; 19420 } 19421 19422 /* FullName_save() is slow, don't use it when not needed. */ 19423 if (*p != NUL || !vim_isAbsName(*fnamep)) 19424 { 19425 *fnamep = FullName_save(*fnamep, *p != NUL); 19426 vim_free(*bufp); /* free any allocated file name */ 19427 *bufp = *fnamep; 19428 if (*fnamep == NULL) 19429 return -1; 19430 } 19431 19432 /* Append a path separator to a directory. */ 19433 if (mch_isdir(*fnamep)) 19434 { 19435 /* Make room for one or two extra characters. */ 19436 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19437 vim_free(*bufp); /* free any allocated file name */ 19438 *bufp = *fnamep; 19439 if (*fnamep == NULL) 19440 return -1; 19441 add_pathsep(*fnamep); 19442 } 19443 } 19444 19445 /* ":." - path relative to the current directory */ 19446 /* ":~" - path relative to the home directory */ 19447 /* ":8" - shortname path - postponed till after */ 19448 while (src[*usedlen] == ':' 19449 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19450 { 19451 *usedlen += 2; 19452 if (c == '8') 19453 { 19454 #ifdef WIN3264 19455 has_shortname = 1; /* Postpone this. */ 19456 #endif 19457 continue; 19458 } 19459 pbuf = NULL; 19460 /* Need full path first (use expand_env() to remove a "~/") */ 19461 if (!has_fullname) 19462 { 19463 if (c == '.' && **fnamep == '~') 19464 p = pbuf = expand_env_save(*fnamep); 19465 else 19466 p = pbuf = FullName_save(*fnamep, FALSE); 19467 } 19468 else 19469 p = *fnamep; 19470 19471 has_fullname = 0; 19472 19473 if (p != NULL) 19474 { 19475 if (c == '.') 19476 { 19477 mch_dirname(dirname, MAXPATHL); 19478 s = shorten_fname(p, dirname); 19479 if (s != NULL) 19480 { 19481 *fnamep = s; 19482 if (pbuf != NULL) 19483 { 19484 vim_free(*bufp); /* free any allocated file name */ 19485 *bufp = pbuf; 19486 pbuf = NULL; 19487 } 19488 } 19489 } 19490 else 19491 { 19492 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19493 /* Only replace it when it starts with '~' */ 19494 if (*dirname == '~') 19495 { 19496 s = vim_strsave(dirname); 19497 if (s != NULL) 19498 { 19499 *fnamep = s; 19500 vim_free(*bufp); 19501 *bufp = s; 19502 } 19503 } 19504 } 19505 vim_free(pbuf); 19506 } 19507 } 19508 19509 tail = gettail(*fnamep); 19510 *fnamelen = (int)STRLEN(*fnamep); 19511 19512 /* ":h" - head, remove "/file_name", can be repeated */ 19513 /* Don't remove the first "/" or "c:\" */ 19514 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19515 { 19516 valid |= VALID_HEAD; 19517 *usedlen += 2; 19518 s = get_past_head(*fnamep); 19519 while (tail > s && after_pathsep(s, tail)) 19520 --tail; 19521 *fnamelen = (int)(tail - *fnamep); 19522 #ifdef VMS 19523 if (*fnamelen > 0) 19524 *fnamelen += 1; /* the path separator is part of the path */ 19525 #endif 19526 while (tail > s && !after_pathsep(s, tail)) 19527 mb_ptr_back(*fnamep, tail); 19528 } 19529 19530 /* ":8" - shortname */ 19531 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19532 { 19533 *usedlen += 2; 19534 #ifdef WIN3264 19535 has_shortname = 1; 19536 #endif 19537 } 19538 19539 #ifdef WIN3264 19540 /* Check shortname after we have done 'heads' and before we do 'tails' 19541 */ 19542 if (has_shortname) 19543 { 19544 pbuf = NULL; 19545 /* Copy the string if it is shortened by :h */ 19546 if (*fnamelen < (int)STRLEN(*fnamep)) 19547 { 19548 p = vim_strnsave(*fnamep, *fnamelen); 19549 if (p == 0) 19550 return -1; 19551 vim_free(*bufp); 19552 *bufp = *fnamep = p; 19553 } 19554 19555 /* Split into two implementations - makes it easier. First is where 19556 * there isn't a full name already, second is where there is. 19557 */ 19558 if (!has_fullname && !vim_isAbsName(*fnamep)) 19559 { 19560 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19561 return -1; 19562 } 19563 else 19564 { 19565 int l; 19566 19567 /* Simple case, already have the full-name 19568 * Nearly always shorter, so try first time. */ 19569 l = *fnamelen; 19570 if (!get_short_pathname(fnamep, bufp, &l)) 19571 return -1; 19572 19573 if (l == 0) 19574 { 19575 /* Couldn't find the filename.. search the paths. 19576 */ 19577 l = *fnamelen; 19578 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19579 return -1; 19580 } 19581 *fnamelen = l; 19582 } 19583 } 19584 #endif /* WIN3264 */ 19585 19586 /* ":t" - tail, just the basename */ 19587 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19588 { 19589 *usedlen += 2; 19590 *fnamelen -= (int)(tail - *fnamep); 19591 *fnamep = tail; 19592 } 19593 19594 /* ":e" - extension, can be repeated */ 19595 /* ":r" - root, without extension, can be repeated */ 19596 while (src[*usedlen] == ':' 19597 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19598 { 19599 /* find a '.' in the tail: 19600 * - for second :e: before the current fname 19601 * - otherwise: The last '.' 19602 */ 19603 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19604 s = *fnamep - 2; 19605 else 19606 s = *fnamep + *fnamelen - 1; 19607 for ( ; s > tail; --s) 19608 if (s[0] == '.') 19609 break; 19610 if (src[*usedlen + 1] == 'e') /* :e */ 19611 { 19612 if (s > tail) 19613 { 19614 *fnamelen += (int)(*fnamep - (s + 1)); 19615 *fnamep = s + 1; 19616 #ifdef VMS 19617 /* cut version from the extension */ 19618 s = *fnamep + *fnamelen - 1; 19619 for ( ; s > *fnamep; --s) 19620 if (s[0] == ';') 19621 break; 19622 if (s > *fnamep) 19623 *fnamelen = s - *fnamep; 19624 #endif 19625 } 19626 else if (*fnamep <= tail) 19627 *fnamelen = 0; 19628 } 19629 else /* :r */ 19630 { 19631 if (s > tail) /* remove one extension */ 19632 *fnamelen = (int)(s - *fnamep); 19633 } 19634 *usedlen += 2; 19635 } 19636 19637 /* ":s?pat?foo?" - substitute */ 19638 /* ":gs?pat?foo?" - global substitute */ 19639 if (src[*usedlen] == ':' 19640 && (src[*usedlen + 1] == 's' 19641 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19642 { 19643 char_u *str; 19644 char_u *pat; 19645 char_u *sub; 19646 int sep; 19647 char_u *flags; 19648 int didit = FALSE; 19649 19650 flags = (char_u *)""; 19651 s = src + *usedlen + 2; 19652 if (src[*usedlen + 1] == 'g') 19653 { 19654 flags = (char_u *)"g"; 19655 ++s; 19656 } 19657 19658 sep = *s++; 19659 if (sep) 19660 { 19661 /* find end of pattern */ 19662 p = vim_strchr(s, sep); 19663 if (p != NULL) 19664 { 19665 pat = vim_strnsave(s, (int)(p - s)); 19666 if (pat != NULL) 19667 { 19668 s = p + 1; 19669 /* find end of substitution */ 19670 p = vim_strchr(s, sep); 19671 if (p != NULL) 19672 { 19673 sub = vim_strnsave(s, (int)(p - s)); 19674 str = vim_strnsave(*fnamep, *fnamelen); 19675 if (sub != NULL && str != NULL) 19676 { 19677 *usedlen = (int)(p + 1 - src); 19678 s = do_string_sub(str, pat, sub, flags); 19679 if (s != NULL) 19680 { 19681 *fnamep = s; 19682 *fnamelen = (int)STRLEN(s); 19683 vim_free(*bufp); 19684 *bufp = s; 19685 didit = TRUE; 19686 } 19687 } 19688 vim_free(sub); 19689 vim_free(str); 19690 } 19691 vim_free(pat); 19692 } 19693 } 19694 /* after using ":s", repeat all the modifiers */ 19695 if (didit) 19696 goto repeat; 19697 } 19698 } 19699 19700 return valid; 19701 } 19702 19703 /* 19704 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19705 * "flags" can be "g" to do a global substitute. 19706 * Returns an allocated string, NULL for error. 19707 */ 19708 char_u * 19709 do_string_sub(str, pat, sub, flags) 19710 char_u *str; 19711 char_u *pat; 19712 char_u *sub; 19713 char_u *flags; 19714 { 19715 int sublen; 19716 regmatch_T regmatch; 19717 int i; 19718 int do_all; 19719 char_u *tail; 19720 garray_T ga; 19721 char_u *ret; 19722 char_u *save_cpo; 19723 19724 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19725 save_cpo = p_cpo; 19726 p_cpo = (char_u *)""; 19727 19728 ga_init2(&ga, 1, 200); 19729 19730 do_all = (flags[0] == 'g'); 19731 19732 regmatch.rm_ic = p_ic; 19733 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19734 if (regmatch.regprog != NULL) 19735 { 19736 tail = str; 19737 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19738 { 19739 /* 19740 * Get some space for a temporary buffer to do the substitution 19741 * into. It will contain: 19742 * - The text up to where the match is. 19743 * - The substituted text. 19744 * - The text after the match. 19745 */ 19746 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19747 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19748 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19749 { 19750 ga_clear(&ga); 19751 break; 19752 } 19753 19754 /* copy the text up to where the match is */ 19755 i = (int)(regmatch.startp[0] - tail); 19756 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19757 /* add the substituted text */ 19758 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19759 + ga.ga_len + i, TRUE, TRUE, FALSE); 19760 ga.ga_len += i + sublen - 1; 19761 /* avoid getting stuck on a match with an empty string */ 19762 if (tail == regmatch.endp[0]) 19763 { 19764 if (*tail == NUL) 19765 break; 19766 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19767 ++ga.ga_len; 19768 } 19769 else 19770 { 19771 tail = regmatch.endp[0]; 19772 if (*tail == NUL) 19773 break; 19774 } 19775 if (!do_all) 19776 break; 19777 } 19778 19779 if (ga.ga_data != NULL) 19780 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19781 19782 vim_free(regmatch.regprog); 19783 } 19784 19785 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19786 ga_clear(&ga); 19787 p_cpo = save_cpo; 19788 19789 return ret; 19790 } 19791 19792 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19793