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_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 413 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 414 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 415 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 416 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 417 static char_u *list2string __ARGS((typval_T *tv)); 418 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); 419 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 420 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 421 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 422 static void dict_unref __ARGS((dict_T *d)); 423 static void dict_free __ARGS((dict_T *d)); 424 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 425 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 426 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 427 static void dictitem_free __ARGS((dictitem_T *item)); 428 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 429 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 430 static long dict_len __ARGS((dict_T *d)); 431 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 432 static char_u *dict2string __ARGS((typval_T *tv)); 433 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 434 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 435 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 436 static char_u *string_quote __ARGS((char_u *str, int function)); 437 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 438 static int find_internal_func __ARGS((char_u *name)); 439 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 440 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)); 441 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)); 442 static void emsg_funcname __ARGS((char *msg, char_u *name)); 443 444 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 445 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 446 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 447 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 448 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 449 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 450 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 463 #if defined(FEAT_INS_EXPAND) 464 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 466 #endif 467 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 468 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 469 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 472 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 562 #ifdef vim_mkdir 563 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 564 #endif 565 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 598 #ifdef HAVE_STRFTIME 599 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 600 #endif 601 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 630 631 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 632 static int get_env_len __ARGS((char_u **arg)); 633 static int get_id_len __ARGS((char_u **arg)); 634 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 635 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 636 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 637 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 638 valid character */ 639 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 640 static int eval_isnamec __ARGS((int c)); 641 static int eval_isnamec1 __ARGS((int c)); 642 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 643 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 644 static typval_T *alloc_tv __ARGS((void)); 645 static typval_T *alloc_string_tv __ARGS((char_u *string)); 646 static void free_tv __ARGS((typval_T *varp)); 647 static void init_tv __ARGS((typval_T *varp)); 648 static long get_tv_number __ARGS((typval_T *varp)); 649 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 650 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 651 static char_u *get_tv_string __ARGS((typval_T *varp)); 652 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 653 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 654 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 655 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 656 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 657 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 658 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 659 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 660 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 661 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 662 static int var_check_ro __ARGS((int flags, char_u *name)); 663 static int tv_check_lock __ARGS((int lock, char_u *name)); 664 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 665 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 666 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 667 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 668 static int eval_fname_script __ARGS((char_u *p)); 669 static int eval_fname_sid __ARGS((char_u *p)); 670 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 671 static ufunc_T *find_func __ARGS((char_u *name)); 672 static int function_exists __ARGS((char_u *name)); 673 static int builtin_function __ARGS((char_u *name)); 674 #ifdef FEAT_PROFILE 675 static void func_do_profile __ARGS((ufunc_T *fp)); 676 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 677 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 678 static int 679 # ifdef __BORLANDC__ 680 _RTLENTRYF 681 # endif 682 prof_total_cmp __ARGS((const void *s1, const void *s2)); 683 static int 684 # ifdef __BORLANDC__ 685 _RTLENTRYF 686 # endif 687 prof_self_cmp __ARGS((const void *s1, const void *s2)); 688 #endif 689 static int script_autoload __ARGS((char_u *name, int reload)); 690 static char_u *autoload_name __ARGS((char_u *name)); 691 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 692 static void func_free __ARGS((ufunc_T *fp)); 693 static void func_unref __ARGS((char_u *name)); 694 static void func_ref __ARGS((char_u *name)); 695 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)); 696 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 697 698 /* Character used as separated in autoload function/variable names. */ 699 #define AUTOLOAD_CHAR '#' 700 701 /* 702 * Initialize the global and v: variables. 703 */ 704 void 705 eval_init() 706 { 707 int i; 708 struct vimvar *p; 709 710 init_var_dict(&globvardict, &globvars_var); 711 init_var_dict(&vimvardict, &vimvars_var); 712 hash_init(&compat_hashtab); 713 hash_init(&func_hashtab); 714 715 for (i = 0; i < VV_LEN; ++i) 716 { 717 p = &vimvars[i]; 718 STRCPY(p->vv_di.di_key, p->vv_name); 719 if (p->vv_flags & VV_RO) 720 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 721 else if (p->vv_flags & VV_RO_SBX) 722 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 723 else 724 p->vv_di.di_flags = DI_FLAGS_FIX; 725 726 /* add to v: scope dict, unless the value is not always available */ 727 if (p->vv_type != VAR_UNKNOWN) 728 hash_add(&vimvarht, p->vv_di.di_key); 729 if (p->vv_flags & VV_COMPAT) 730 /* add to compat scope dict */ 731 hash_add(&compat_hashtab, p->vv_di.di_key); 732 } 733 } 734 735 #if defined(EXITFREE) || defined(PROTO) 736 void 737 eval_clear() 738 { 739 int i; 740 struct vimvar *p; 741 742 for (i = 0; i < VV_LEN; ++i) 743 { 744 p = &vimvars[i]; 745 if (p->vv_di.di_tv.v_type == VAR_STRING) 746 { 747 vim_free(p->vv_di.di_tv.vval.v_string); 748 p->vv_di.di_tv.vval.v_string = NULL; 749 } 750 } 751 hash_clear(&vimvarht); 752 hash_clear(&compat_hashtab); 753 754 /* script-local variables */ 755 for (i = 1; i <= ga_scripts.ga_len; ++i) 756 vars_clear(&SCRIPT_VARS(i)); 757 ga_clear(&ga_scripts); 758 free_scriptnames(); 759 760 /* global variables */ 761 vars_clear(&globvarht); 762 763 /* functions */ 764 free_all_functions(); 765 hash_clear(&func_hashtab); 766 767 /* unreferenced lists and dicts */ 768 (void)garbage_collect(); 769 } 770 #endif 771 772 /* 773 * Return the name of the executed function. 774 */ 775 char_u * 776 func_name(cookie) 777 void *cookie; 778 { 779 return ((funccall_T *)cookie)->func->uf_name; 780 } 781 782 /* 783 * Return the address holding the next breakpoint line for a funccall cookie. 784 */ 785 linenr_T * 786 func_breakpoint(cookie) 787 void *cookie; 788 { 789 return &((funccall_T *)cookie)->breakpoint; 790 } 791 792 /* 793 * Return the address holding the debug tick for a funccall cookie. 794 */ 795 int * 796 func_dbg_tick(cookie) 797 void *cookie; 798 { 799 return &((funccall_T *)cookie)->dbg_tick; 800 } 801 802 /* 803 * Return the nesting level for a funccall cookie. 804 */ 805 int 806 func_level(cookie) 807 void *cookie; 808 { 809 return ((funccall_T *)cookie)->level; 810 } 811 812 /* pointer to funccal for currently active function */ 813 funccall_T *current_funccal = NULL; 814 815 /* 816 * Return TRUE when a function was ended by a ":return" command. 817 */ 818 int 819 current_func_returned() 820 { 821 return current_funccal->returned; 822 } 823 824 825 /* 826 * Set an internal variable to a string value. Creates the variable if it does 827 * not already exist. 828 */ 829 void 830 set_internal_string_var(name, value) 831 char_u *name; 832 char_u *value; 833 { 834 char_u *val; 835 typval_T *tvp; 836 837 val = vim_strsave(value); 838 if (val != NULL) 839 { 840 tvp = alloc_string_tv(val); 841 if (tvp != NULL) 842 { 843 set_var(name, tvp, FALSE); 844 free_tv(tvp); 845 } 846 } 847 } 848 849 static lval_T *redir_lval = NULL; 850 static char_u *redir_endp = NULL; 851 static char_u *redir_varname = NULL; 852 853 /* 854 * Start recording command output to a variable 855 * Returns OK if successfully completed the setup. FAIL otherwise. 856 */ 857 int 858 var_redir_start(name, append) 859 char_u *name; 860 int append; /* append to an existing variable */ 861 { 862 int save_emsg; 863 int err; 864 typval_T tv; 865 866 /* Make sure a valid variable name is specified */ 867 if (!eval_isnamec1(*name)) 868 { 869 EMSG(_(e_invarg)); 870 return FAIL; 871 } 872 873 redir_varname = vim_strsave(name); 874 if (redir_varname == NULL) 875 return FAIL; 876 877 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 878 if (redir_lval == NULL) 879 { 880 var_redir_stop(); 881 return FAIL; 882 } 883 884 /* Parse the variable name (can be a dict or list entry). */ 885 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 886 FNE_CHECK_START); 887 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 888 { 889 if (redir_endp != NULL && *redir_endp != NUL) 890 /* Trailing characters are present after the variable name */ 891 EMSG(_(e_trailing)); 892 else 893 EMSG(_(e_invarg)); 894 var_redir_stop(); 895 return FAIL; 896 } 897 898 /* check if we can write to the variable: set it to or append an empty 899 * string */ 900 save_emsg = did_emsg; 901 did_emsg = FALSE; 902 tv.v_type = VAR_STRING; 903 tv.vval.v_string = (char_u *)""; 904 if (append) 905 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 906 else 907 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 908 err = did_emsg; 909 did_emsg += save_emsg; 910 if (err) 911 { 912 var_redir_stop(); 913 return FAIL; 914 } 915 if (redir_lval->ll_newkey != NULL) 916 { 917 /* Dictionary item was created, don't do it again. */ 918 vim_free(redir_lval->ll_newkey); 919 redir_lval->ll_newkey = NULL; 920 } 921 922 return OK; 923 } 924 925 /* 926 * Append "value[len]" to the variable set by var_redir_start(). 927 */ 928 void 929 var_redir_str(value, len) 930 char_u *value; 931 int len; 932 { 933 char_u *val; 934 typval_T tv; 935 int save_emsg; 936 int err; 937 938 if (redir_lval == NULL) 939 return; 940 941 if (len == -1) 942 /* Append the entire string */ 943 val = vim_strsave(value); 944 else 945 /* Append only the specified number of characters */ 946 val = vim_strnsave(value, len); 947 if (val == NULL) 948 return; 949 950 tv.v_type = VAR_STRING; 951 tv.vval.v_string = val; 952 953 save_emsg = did_emsg; 954 did_emsg = FALSE; 955 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 956 err = did_emsg; 957 did_emsg += save_emsg; 958 if (err) 959 var_redir_stop(); 960 961 vim_free(tv.vval.v_string); 962 } 963 964 /* 965 * Stop redirecting command output to a variable. 966 */ 967 void 968 var_redir_stop() 969 { 970 if (redir_lval != NULL) 971 { 972 clear_lval(redir_lval); 973 vim_free(redir_lval); 974 redir_lval = NULL; 975 } 976 vim_free(redir_varname); 977 redir_varname = NULL; 978 } 979 980 # if defined(FEAT_MBYTE) || defined(PROTO) 981 int 982 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 983 char_u *enc_from; 984 char_u *enc_to; 985 char_u *fname_from; 986 char_u *fname_to; 987 { 988 int err = FALSE; 989 990 set_vim_var_string(VV_CC_FROM, enc_from, -1); 991 set_vim_var_string(VV_CC_TO, enc_to, -1); 992 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 993 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 994 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 995 err = TRUE; 996 set_vim_var_string(VV_CC_FROM, NULL, -1); 997 set_vim_var_string(VV_CC_TO, NULL, -1); 998 set_vim_var_string(VV_FNAME_IN, NULL, -1); 999 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1000 1001 if (err) 1002 return FAIL; 1003 return OK; 1004 } 1005 # endif 1006 1007 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1008 int 1009 eval_printexpr(fname, args) 1010 char_u *fname; 1011 char_u *args; 1012 { 1013 int err = FALSE; 1014 1015 set_vim_var_string(VV_FNAME_IN, fname, -1); 1016 set_vim_var_string(VV_CMDARG, args, -1); 1017 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1018 err = TRUE; 1019 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1020 set_vim_var_string(VV_CMDARG, NULL, -1); 1021 1022 if (err) 1023 { 1024 mch_remove(fname); 1025 return FAIL; 1026 } 1027 return OK; 1028 } 1029 # endif 1030 1031 # if defined(FEAT_DIFF) || defined(PROTO) 1032 void 1033 eval_diff(origfile, newfile, outfile) 1034 char_u *origfile; 1035 char_u *newfile; 1036 char_u *outfile; 1037 { 1038 int err = FALSE; 1039 1040 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1041 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1042 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1043 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1044 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1045 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1046 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1047 } 1048 1049 void 1050 eval_patch(origfile, difffile, outfile) 1051 char_u *origfile; 1052 char_u *difffile; 1053 char_u *outfile; 1054 { 1055 int err; 1056 1057 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1058 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1059 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1060 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1061 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1062 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1063 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1064 } 1065 # endif 1066 1067 /* 1068 * Top level evaluation function, returning a boolean. 1069 * Sets "error" to TRUE if there was an error. 1070 * Return TRUE or FALSE. 1071 */ 1072 int 1073 eval_to_bool(arg, error, nextcmd, skip) 1074 char_u *arg; 1075 int *error; 1076 char_u **nextcmd; 1077 int skip; /* only parse, don't execute */ 1078 { 1079 typval_T tv; 1080 int retval = FALSE; 1081 1082 if (skip) 1083 ++emsg_skip; 1084 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1085 *error = TRUE; 1086 else 1087 { 1088 *error = FALSE; 1089 if (!skip) 1090 { 1091 retval = (get_tv_number_chk(&tv, error) != 0); 1092 clear_tv(&tv); 1093 } 1094 } 1095 if (skip) 1096 --emsg_skip; 1097 1098 return retval; 1099 } 1100 1101 /* 1102 * Top level evaluation function, returning a string. If "skip" is TRUE, 1103 * only parsing to "nextcmd" is done, without reporting errors. Return 1104 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1105 */ 1106 char_u * 1107 eval_to_string_skip(arg, nextcmd, skip) 1108 char_u *arg; 1109 char_u **nextcmd; 1110 int skip; /* only parse, don't execute */ 1111 { 1112 typval_T tv; 1113 char_u *retval; 1114 1115 if (skip) 1116 ++emsg_skip; 1117 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1118 retval = NULL; 1119 else 1120 { 1121 retval = vim_strsave(get_tv_string(&tv)); 1122 clear_tv(&tv); 1123 } 1124 if (skip) 1125 --emsg_skip; 1126 1127 return retval; 1128 } 1129 1130 /* 1131 * Skip over an expression at "*pp". 1132 * Return FAIL for an error, OK otherwise. 1133 */ 1134 int 1135 skip_expr(pp) 1136 char_u **pp; 1137 { 1138 typval_T rettv; 1139 1140 *pp = skipwhite(*pp); 1141 return eval1(pp, &rettv, FALSE); 1142 } 1143 1144 /* 1145 * Top level evaluation function, returning a string. 1146 * Return pointer to allocated memory, or NULL for failure. 1147 */ 1148 char_u * 1149 eval_to_string(arg, nextcmd) 1150 char_u *arg; 1151 char_u **nextcmd; 1152 { 1153 typval_T tv; 1154 char_u *retval; 1155 1156 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1157 retval = NULL; 1158 else 1159 { 1160 retval = vim_strsave(get_tv_string(&tv)); 1161 clear_tv(&tv); 1162 } 1163 1164 return retval; 1165 } 1166 1167 /* 1168 * Call eval_to_string() with "sandbox" set and not using local variables. 1169 */ 1170 char_u * 1171 eval_to_string_safe(arg, nextcmd) 1172 char_u *arg; 1173 char_u **nextcmd; 1174 { 1175 char_u *retval; 1176 void *save_funccalp; 1177 1178 save_funccalp = save_funccal(); 1179 ++sandbox; 1180 retval = eval_to_string(arg, nextcmd); 1181 --sandbox; 1182 restore_funccal(save_funccalp); 1183 return retval; 1184 } 1185 1186 /* 1187 * Top level evaluation function, returning a number. 1188 * Evaluates "expr" silently. 1189 * Returns -1 for an error. 1190 */ 1191 int 1192 eval_to_number(expr) 1193 char_u *expr; 1194 { 1195 typval_T rettv; 1196 int retval; 1197 char_u *p = skipwhite(expr); 1198 1199 ++emsg_off; 1200 1201 if (eval1(&p, &rettv, TRUE) == FAIL) 1202 retval = -1; 1203 else 1204 { 1205 retval = get_tv_number_chk(&rettv, NULL); 1206 clear_tv(&rettv); 1207 } 1208 --emsg_off; 1209 1210 return retval; 1211 } 1212 1213 /* 1214 * Prepare v: variable "idx" to be used. 1215 * Save the current typeval in "save_tv". 1216 * When not used yet add the variable to the v: hashtable. 1217 */ 1218 static void 1219 prepare_vimvar(idx, save_tv) 1220 int idx; 1221 typval_T *save_tv; 1222 { 1223 *save_tv = vimvars[idx].vv_tv; 1224 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1225 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1226 } 1227 1228 /* 1229 * Restore v: variable "idx" to typeval "save_tv". 1230 * When no longer defined, remove the variable from the v: hashtable. 1231 */ 1232 static void 1233 restore_vimvar(idx, save_tv) 1234 int idx; 1235 typval_T *save_tv; 1236 { 1237 hashitem_T *hi; 1238 1239 clear_tv(&vimvars[idx].vv_tv); 1240 vimvars[idx].vv_tv = *save_tv; 1241 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1242 { 1243 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1244 if (HASHITEM_EMPTY(hi)) 1245 EMSG2(_(e_intern2), "restore_vimvar()"); 1246 else 1247 hash_remove(&vimvarht, hi); 1248 } 1249 } 1250 1251 #if defined(FEAT_SYN_HL) || defined(PROTO) 1252 /* 1253 * Evaluate an expression to a list with suggestions. 1254 * For the "expr:" part of 'spellsuggest'. 1255 */ 1256 list_T * 1257 eval_spell_expr(badword, expr) 1258 char_u *badword; 1259 char_u *expr; 1260 { 1261 typval_T save_val; 1262 typval_T rettv; 1263 list_T *list = NULL; 1264 char_u *p = skipwhite(expr); 1265 1266 /* Set "v:val" to the bad word. */ 1267 prepare_vimvar(VV_VAL, &save_val); 1268 vimvars[VV_VAL].vv_type = VAR_STRING; 1269 vimvars[VV_VAL].vv_str = badword; 1270 if (p_verbose == 0) 1271 ++emsg_off; 1272 1273 if (eval1(&p, &rettv, TRUE) == OK) 1274 { 1275 if (rettv.v_type != VAR_LIST) 1276 clear_tv(&rettv); 1277 else 1278 list = rettv.vval.v_list; 1279 } 1280 1281 if (p_verbose == 0) 1282 --emsg_off; 1283 vimvars[VV_VAL].vv_str = NULL; 1284 restore_vimvar(VV_VAL, &save_val); 1285 1286 return list; 1287 } 1288 1289 /* 1290 * "list" is supposed to contain two items: a word and a number. Return the 1291 * word in "pp" and the number as the return value. 1292 * Return -1 if anything isn't right. 1293 * Used to get the good word and score from the eval_spell_expr() result. 1294 */ 1295 int 1296 get_spellword(list, pp) 1297 list_T *list; 1298 char_u **pp; 1299 { 1300 listitem_T *li; 1301 1302 li = list->lv_first; 1303 if (li == NULL) 1304 return -1; 1305 *pp = get_tv_string(&li->li_tv); 1306 1307 li = li->li_next; 1308 if (li == NULL) 1309 return -1; 1310 return get_tv_number(&li->li_tv); 1311 } 1312 #endif 1313 1314 /* 1315 * Top level evaluation function, 1316 */ 1317 typval_T * 1318 eval_expr(arg, nextcmd) 1319 char_u *arg; 1320 char_u **nextcmd; 1321 { 1322 typval_T *tv; 1323 1324 tv = (typval_T *)alloc(sizeof(typval_T)); 1325 if (!tv) 1326 return NULL; 1327 1328 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1329 { 1330 vim_free(tv); 1331 return NULL; 1332 } 1333 1334 return tv; 1335 } 1336 1337 1338 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1339 /* 1340 * Call some vimL function and return the result in "*rettv". 1341 * Uses argv[argc] for the function arguments. 1342 * Returns OK or FAIL. 1343 */ 1344 static int 1345 call_vim_function(func, argc, argv, safe, rettv) 1346 char_u *func; 1347 int argc; 1348 char_u **argv; 1349 int safe; /* use the sandbox */ 1350 typval_T *rettv; 1351 { 1352 typval_T *argvars; 1353 long n; 1354 int len; 1355 int i; 1356 int doesrange; 1357 void *save_funccalp = NULL; 1358 int ret; 1359 1360 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1361 if (argvars == NULL) 1362 return FAIL; 1363 1364 for (i = 0; i < argc; i++) 1365 { 1366 /* Pass a NULL or empty argument as an empty string */ 1367 if (argv[i] == NULL || *argv[i] == NUL) 1368 { 1369 argvars[i].v_type = VAR_STRING; 1370 argvars[i].vval.v_string = (char_u *)""; 1371 continue; 1372 } 1373 1374 /* Recognize a number argument, the others must be strings. */ 1375 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1376 if (len != 0 && len == (int)STRLEN(argv[i])) 1377 { 1378 argvars[i].v_type = VAR_NUMBER; 1379 argvars[i].vval.v_number = n; 1380 } 1381 else 1382 { 1383 argvars[i].v_type = VAR_STRING; 1384 argvars[i].vval.v_string = argv[i]; 1385 } 1386 } 1387 1388 if (safe) 1389 { 1390 save_funccalp = save_funccal(); 1391 ++sandbox; 1392 } 1393 1394 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1395 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1396 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1397 &doesrange, TRUE, NULL); 1398 if (safe) 1399 { 1400 --sandbox; 1401 restore_funccal(save_funccalp); 1402 } 1403 vim_free(argvars); 1404 1405 if (ret == FAIL) 1406 clear_tv(rettv); 1407 1408 return ret; 1409 } 1410 1411 /* 1412 * Call vimL function "func" and return the result as a string. 1413 * Returns NULL when calling the function fails. 1414 * Uses argv[argc] for the function arguments. 1415 */ 1416 void * 1417 call_func_retstr(func, argc, argv, safe) 1418 char_u *func; 1419 int argc; 1420 char_u **argv; 1421 int safe; /* use the sandbox */ 1422 { 1423 typval_T rettv; 1424 char_u *retval; 1425 1426 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1427 return NULL; 1428 1429 retval = vim_strsave(get_tv_string(&rettv)); 1430 clear_tv(&rettv); 1431 return retval; 1432 } 1433 1434 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1435 /* 1436 * Call vimL function "func" and return the result as a number. 1437 * Returns -1 when calling the function fails. 1438 * Uses argv[argc] for the function arguments. 1439 */ 1440 long 1441 call_func_retnr(func, argc, argv, safe) 1442 char_u *func; 1443 int argc; 1444 char_u **argv; 1445 int safe; /* use the sandbox */ 1446 { 1447 typval_T rettv; 1448 long retval; 1449 1450 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1451 return -1; 1452 1453 retval = get_tv_number_chk(&rettv, NULL); 1454 clear_tv(&rettv); 1455 return retval; 1456 } 1457 #endif 1458 1459 /* 1460 * Call vimL function "func" and return the result as a list 1461 * Uses argv[argc] for the function arguments. 1462 */ 1463 void * 1464 call_func_retlist(func, argc, argv, safe) 1465 char_u *func; 1466 int argc; 1467 char_u **argv; 1468 int safe; /* use the sandbox */ 1469 { 1470 typval_T rettv; 1471 1472 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1473 return NULL; 1474 1475 if (rettv.v_type != VAR_LIST) 1476 { 1477 clear_tv(&rettv); 1478 return NULL; 1479 } 1480 1481 return rettv.vval.v_list; 1482 } 1483 1484 #endif 1485 1486 /* 1487 * Save the current function call pointer, and set it to NULL. 1488 * Used when executing autocommands and for ":source". 1489 */ 1490 void * 1491 save_funccal() 1492 { 1493 funccall_T *fc = current_funccal; 1494 1495 current_funccal = NULL; 1496 return (void *)fc; 1497 } 1498 1499 void 1500 restore_funccal(vfc) 1501 void *vfc; 1502 { 1503 funccall_T *fc = (funccall_T *)vfc; 1504 1505 current_funccal = fc; 1506 } 1507 1508 #if defined(FEAT_PROFILE) || defined(PROTO) 1509 /* 1510 * Prepare profiling for entering a child or something else that is not 1511 * counted for the script/function itself. 1512 * Should always be called in pair with prof_child_exit(). 1513 */ 1514 void 1515 prof_child_enter(tm) 1516 proftime_T *tm; /* place to store waittime */ 1517 { 1518 funccall_T *fc = current_funccal; 1519 1520 if (fc != NULL && fc->func->uf_profiling) 1521 profile_start(&fc->prof_child); 1522 script_prof_save(tm); 1523 } 1524 1525 /* 1526 * Take care of time spent in a child. 1527 * Should always be called after prof_child_enter(). 1528 */ 1529 void 1530 prof_child_exit(tm) 1531 proftime_T *tm; /* where waittime was stored */ 1532 { 1533 funccall_T *fc = current_funccal; 1534 1535 if (fc != NULL && fc->func->uf_profiling) 1536 { 1537 profile_end(&fc->prof_child); 1538 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1539 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1540 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1541 } 1542 script_prof_restore(tm); 1543 } 1544 #endif 1545 1546 1547 #ifdef FEAT_FOLDING 1548 /* 1549 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1550 * it in "*cp". Doesn't give error messages. 1551 */ 1552 int 1553 eval_foldexpr(arg, cp) 1554 char_u *arg; 1555 int *cp; 1556 { 1557 typval_T tv; 1558 int retval; 1559 char_u *s; 1560 1561 ++emsg_off; 1562 ++sandbox; 1563 *cp = NUL; 1564 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1565 retval = 0; 1566 else 1567 { 1568 /* If the result is a number, just return the number. */ 1569 if (tv.v_type == VAR_NUMBER) 1570 retval = tv.vval.v_number; 1571 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1572 retval = 0; 1573 else 1574 { 1575 /* If the result is a string, check if there is a non-digit before 1576 * the number. */ 1577 s = tv.vval.v_string; 1578 if (!VIM_ISDIGIT(*s) && *s != '-') 1579 *cp = *s++; 1580 retval = atol((char *)s); 1581 } 1582 clear_tv(&tv); 1583 } 1584 --emsg_off; 1585 --sandbox; 1586 1587 return retval; 1588 } 1589 #endif 1590 1591 /* 1592 * ":let" list all variable values 1593 * ":let var1 var2" list variable values 1594 * ":let var = expr" assignment command. 1595 * ":let var += expr" assignment command. 1596 * ":let var -= expr" assignment command. 1597 * ":let var .= expr" assignment command. 1598 * ":let [var1, var2] = expr" unpack list. 1599 */ 1600 void 1601 ex_let(eap) 1602 exarg_T *eap; 1603 { 1604 char_u *arg = eap->arg; 1605 char_u *expr = NULL; 1606 typval_T rettv; 1607 int i; 1608 int var_count = 0; 1609 int semicolon = 0; 1610 char_u op[2]; 1611 1612 expr = skip_var_list(arg, &var_count, &semicolon); 1613 if (expr == NULL) 1614 return; 1615 expr = vim_strchr(expr, '='); 1616 if (expr == NULL) 1617 { 1618 /* 1619 * ":let" without "=": list variables 1620 */ 1621 if (*arg == '[') 1622 EMSG(_(e_invarg)); 1623 else if (!ends_excmd(*arg)) 1624 /* ":let var1 var2" */ 1625 arg = list_arg_vars(eap, arg); 1626 else if (!eap->skip) 1627 { 1628 /* ":let" */ 1629 list_glob_vars(); 1630 list_buf_vars(); 1631 list_win_vars(); 1632 list_vim_vars(); 1633 } 1634 eap->nextcmd = check_nextcmd(arg); 1635 } 1636 else 1637 { 1638 op[0] = '='; 1639 op[1] = NUL; 1640 if (expr > arg) 1641 { 1642 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1643 op[0] = expr[-1]; /* +=, -= or .= */ 1644 } 1645 expr = skipwhite(expr + 1); 1646 1647 if (eap->skip) 1648 ++emsg_skip; 1649 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1650 if (eap->skip) 1651 { 1652 if (i != FAIL) 1653 clear_tv(&rettv); 1654 --emsg_skip; 1655 } 1656 else if (i != FAIL) 1657 { 1658 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1659 op); 1660 clear_tv(&rettv); 1661 } 1662 } 1663 } 1664 1665 /* 1666 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1667 * Handles both "var" with any type and "[var, var; var]" with a list type. 1668 * When "nextchars" is not NULL it points to a string with characters that 1669 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1670 * or concatenate. 1671 * Returns OK or FAIL; 1672 */ 1673 static int 1674 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1675 char_u *arg_start; 1676 typval_T *tv; 1677 int copy; /* copy values from "tv", don't move */ 1678 int semicolon; /* from skip_var_list() */ 1679 int var_count; /* from skip_var_list() */ 1680 char_u *nextchars; 1681 { 1682 char_u *arg = arg_start; 1683 list_T *l; 1684 int i; 1685 listitem_T *item; 1686 typval_T ltv; 1687 1688 if (*arg != '[') 1689 { 1690 /* 1691 * ":let var = expr" or ":for var in list" 1692 */ 1693 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1694 return FAIL; 1695 return OK; 1696 } 1697 1698 /* 1699 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1700 */ 1701 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1702 { 1703 EMSG(_(e_listreq)); 1704 return FAIL; 1705 } 1706 1707 i = list_len(l); 1708 if (semicolon == 0 && var_count < i) 1709 { 1710 EMSG(_("E687: Less targets than List items")); 1711 return FAIL; 1712 } 1713 if (var_count - semicolon > i) 1714 { 1715 EMSG(_("E688: More targets than List items")); 1716 return FAIL; 1717 } 1718 1719 item = l->lv_first; 1720 while (*arg != ']') 1721 { 1722 arg = skipwhite(arg + 1); 1723 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1724 item = item->li_next; 1725 if (arg == NULL) 1726 return FAIL; 1727 1728 arg = skipwhite(arg); 1729 if (*arg == ';') 1730 { 1731 /* Put the rest of the list (may be empty) in the var after ';'. 1732 * Create a new list for this. */ 1733 l = list_alloc(); 1734 if (l == NULL) 1735 return FAIL; 1736 while (item != NULL) 1737 { 1738 list_append_tv(l, &item->li_tv); 1739 item = item->li_next; 1740 } 1741 1742 ltv.v_type = VAR_LIST; 1743 ltv.v_lock = 0; 1744 ltv.vval.v_list = l; 1745 l->lv_refcount = 1; 1746 1747 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1748 (char_u *)"]", nextchars); 1749 clear_tv(<v); 1750 if (arg == NULL) 1751 return FAIL; 1752 break; 1753 } 1754 else if (*arg != ',' && *arg != ']') 1755 { 1756 EMSG2(_(e_intern2), "ex_let_vars()"); 1757 return FAIL; 1758 } 1759 } 1760 1761 return OK; 1762 } 1763 1764 /* 1765 * Skip over assignable variable "var" or list of variables "[var, var]". 1766 * Used for ":let varvar = expr" and ":for varvar in expr". 1767 * For "[var, var]" increment "*var_count" for each variable. 1768 * for "[var, var; var]" set "semicolon". 1769 * Return NULL for an error. 1770 */ 1771 static char_u * 1772 skip_var_list(arg, var_count, semicolon) 1773 char_u *arg; 1774 int *var_count; 1775 int *semicolon; 1776 { 1777 char_u *p, *s; 1778 1779 if (*arg == '[') 1780 { 1781 /* "[var, var]": find the matching ']'. */ 1782 p = arg; 1783 for (;;) 1784 { 1785 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1786 s = skip_var_one(p); 1787 if (s == p) 1788 { 1789 EMSG2(_(e_invarg2), p); 1790 return NULL; 1791 } 1792 ++*var_count; 1793 1794 p = skipwhite(s); 1795 if (*p == ']') 1796 break; 1797 else if (*p == ';') 1798 { 1799 if (*semicolon == 1) 1800 { 1801 EMSG(_("Double ; in list of variables")); 1802 return NULL; 1803 } 1804 *semicolon = 1; 1805 } 1806 else if (*p != ',') 1807 { 1808 EMSG2(_(e_invarg2), p); 1809 return NULL; 1810 } 1811 } 1812 return p + 1; 1813 } 1814 else 1815 return skip_var_one(arg); 1816 } 1817 1818 /* 1819 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1820 * l[idx]. 1821 */ 1822 static char_u * 1823 skip_var_one(arg) 1824 char_u *arg; 1825 { 1826 if (*arg == '@' && arg[1] != NUL) 1827 return arg + 2; 1828 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1829 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1830 } 1831 1832 /* 1833 * List variables for hashtab "ht" with prefix "prefix". 1834 * If "empty" is TRUE also list NULL strings as empty strings. 1835 */ 1836 static void 1837 list_hashtable_vars(ht, prefix, empty) 1838 hashtab_T *ht; 1839 char_u *prefix; 1840 int empty; 1841 { 1842 hashitem_T *hi; 1843 dictitem_T *di; 1844 int todo; 1845 1846 todo = ht->ht_used; 1847 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1848 { 1849 if (!HASHITEM_EMPTY(hi)) 1850 { 1851 --todo; 1852 di = HI2DI(hi); 1853 if (empty || di->di_tv.v_type != VAR_STRING 1854 || di->di_tv.vval.v_string != NULL) 1855 list_one_var(di, prefix); 1856 } 1857 } 1858 } 1859 1860 /* 1861 * List global variables. 1862 */ 1863 static void 1864 list_glob_vars() 1865 { 1866 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1867 } 1868 1869 /* 1870 * List buffer variables. 1871 */ 1872 static void 1873 list_buf_vars() 1874 { 1875 char_u numbuf[NUMBUFLEN]; 1876 1877 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1878 1879 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1880 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1881 } 1882 1883 /* 1884 * List window variables. 1885 */ 1886 static void 1887 list_win_vars() 1888 { 1889 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1890 } 1891 1892 /* 1893 * List Vim variables. 1894 */ 1895 static void 1896 list_vim_vars() 1897 { 1898 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1899 } 1900 1901 /* 1902 * List variables in "arg". 1903 */ 1904 static char_u * 1905 list_arg_vars(eap, arg) 1906 exarg_T *eap; 1907 char_u *arg; 1908 { 1909 int error = FALSE; 1910 int len; 1911 char_u *name; 1912 char_u *name_start; 1913 char_u *arg_subsc; 1914 char_u *tofree; 1915 typval_T tv; 1916 1917 while (!ends_excmd(*arg) && !got_int) 1918 { 1919 if (error || eap->skip) 1920 { 1921 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1922 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1923 { 1924 emsg_severe = TRUE; 1925 EMSG(_(e_trailing)); 1926 break; 1927 } 1928 } 1929 else 1930 { 1931 /* get_name_len() takes care of expanding curly braces */ 1932 name_start = name = arg; 1933 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1934 if (len <= 0) 1935 { 1936 /* This is mainly to keep test 49 working: when expanding 1937 * curly braces fails overrule the exception error message. */ 1938 if (len < 0 && !aborting()) 1939 { 1940 emsg_severe = TRUE; 1941 EMSG2(_(e_invarg2), arg); 1942 break; 1943 } 1944 error = TRUE; 1945 } 1946 else 1947 { 1948 if (tofree != NULL) 1949 name = tofree; 1950 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1951 error = TRUE; 1952 else 1953 { 1954 /* handle d.key, l[idx], f(expr) */ 1955 arg_subsc = arg; 1956 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1957 error = TRUE; 1958 else 1959 { 1960 if (arg == arg_subsc && len == 2 && name[1] == ':') 1961 { 1962 switch (*name) 1963 { 1964 case 'g': list_glob_vars(); break; 1965 case 'b': list_buf_vars(); break; 1966 case 'w': list_win_vars(); break; 1967 case 'v': list_vim_vars(); break; 1968 default: 1969 EMSG2(_("E738: Can't list variables for %s"), name); 1970 } 1971 } 1972 else 1973 { 1974 char_u numbuf[NUMBUFLEN]; 1975 char_u *tf; 1976 int c; 1977 char_u *s; 1978 1979 s = echo_string(&tv, &tf, numbuf); 1980 c = *arg; 1981 *arg = NUL; 1982 list_one_var_a((char_u *)"", 1983 arg == arg_subsc ? name : name_start, 1984 tv.v_type, s == NULL ? (char_u *)"" : s); 1985 *arg = c; 1986 vim_free(tf); 1987 } 1988 clear_tv(&tv); 1989 } 1990 } 1991 } 1992 1993 vim_free(tofree); 1994 } 1995 1996 arg = skipwhite(arg); 1997 } 1998 1999 return arg; 2000 } 2001 2002 /* 2003 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2004 * Returns a pointer to the char just after the var name. 2005 * Returns NULL if there is an error. 2006 */ 2007 static char_u * 2008 ex_let_one(arg, tv, copy, endchars, op) 2009 char_u *arg; /* points to variable name */ 2010 typval_T *tv; /* value to assign to variable */ 2011 int copy; /* copy value from "tv" */ 2012 char_u *endchars; /* valid chars after variable name or NULL */ 2013 char_u *op; /* "+", "-", "." or NULL*/ 2014 { 2015 int c1; 2016 char_u *name; 2017 char_u *p; 2018 char_u *arg_end = NULL; 2019 int len; 2020 int opt_flags; 2021 char_u *tofree = NULL; 2022 2023 /* 2024 * ":let $VAR = expr": Set environment variable. 2025 */ 2026 if (*arg == '$') 2027 { 2028 /* Find the end of the name. */ 2029 ++arg; 2030 name = arg; 2031 len = get_env_len(&arg); 2032 if (len == 0) 2033 EMSG2(_(e_invarg2), name - 1); 2034 else 2035 { 2036 if (op != NULL && (*op == '+' || *op == '-')) 2037 EMSG2(_(e_letwrong), op); 2038 else if (endchars != NULL 2039 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2040 EMSG(_(e_letunexp)); 2041 else 2042 { 2043 c1 = name[len]; 2044 name[len] = NUL; 2045 p = get_tv_string_chk(tv); 2046 if (p != NULL && op != NULL && *op == '.') 2047 { 2048 int mustfree = FALSE; 2049 char_u *s = vim_getenv(name, &mustfree); 2050 2051 if (s != NULL) 2052 { 2053 p = tofree = concat_str(s, p); 2054 if (mustfree) 2055 vim_free(s); 2056 } 2057 } 2058 if (p != NULL) 2059 { 2060 vim_setenv(name, p); 2061 if (STRICMP(name, "HOME") == 0) 2062 init_homedir(); 2063 else if (didset_vim && STRICMP(name, "VIM") == 0) 2064 didset_vim = FALSE; 2065 else if (didset_vimruntime 2066 && STRICMP(name, "VIMRUNTIME") == 0) 2067 didset_vimruntime = FALSE; 2068 arg_end = arg; 2069 } 2070 name[len] = c1; 2071 vim_free(tofree); 2072 } 2073 } 2074 } 2075 2076 /* 2077 * ":let &option = expr": Set option value. 2078 * ":let &l:option = expr": Set local option value. 2079 * ":let &g:option = expr": Set global option value. 2080 */ 2081 else if (*arg == '&') 2082 { 2083 /* Find the end of the name. */ 2084 p = find_option_end(&arg, &opt_flags); 2085 if (p == NULL || (endchars != NULL 2086 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2087 EMSG(_(e_letunexp)); 2088 else 2089 { 2090 long n; 2091 int opt_type; 2092 long numval; 2093 char_u *stringval = NULL; 2094 char_u *s; 2095 2096 c1 = *p; 2097 *p = NUL; 2098 2099 n = get_tv_number(tv); 2100 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2101 if (s != NULL && op != NULL && *op != '=') 2102 { 2103 opt_type = get_option_value(arg, &numval, 2104 &stringval, opt_flags); 2105 if ((opt_type == 1 && *op == '.') 2106 || (opt_type == 0 && *op != '.')) 2107 EMSG2(_(e_letwrong), op); 2108 else 2109 { 2110 if (opt_type == 1) /* number */ 2111 { 2112 if (*op == '+') 2113 n = numval + n; 2114 else 2115 n = numval - n; 2116 } 2117 else if (opt_type == 0 && stringval != NULL) /* string */ 2118 { 2119 s = concat_str(stringval, s); 2120 vim_free(stringval); 2121 stringval = s; 2122 } 2123 } 2124 } 2125 if (s != NULL) 2126 { 2127 set_option_value(arg, n, s, opt_flags); 2128 arg_end = p; 2129 } 2130 *p = c1; 2131 vim_free(stringval); 2132 } 2133 } 2134 2135 /* 2136 * ":let @r = expr": Set register contents. 2137 */ 2138 else if (*arg == '@') 2139 { 2140 ++arg; 2141 if (op != NULL && (*op == '+' || *op == '-')) 2142 EMSG2(_(e_letwrong), op); 2143 else if (endchars != NULL 2144 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2145 EMSG(_(e_letunexp)); 2146 else 2147 { 2148 char_u *tofree = NULL; 2149 char_u *s; 2150 2151 p = get_tv_string_chk(tv); 2152 if (p != NULL && op != NULL && *op == '.') 2153 { 2154 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2155 if (s != NULL) 2156 { 2157 p = tofree = concat_str(s, p); 2158 vim_free(s); 2159 } 2160 } 2161 if (p != NULL) 2162 { 2163 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2164 arg_end = arg + 1; 2165 } 2166 vim_free(tofree); 2167 } 2168 } 2169 2170 /* 2171 * ":let var = expr": Set internal variable. 2172 * ":let {expr} = expr": Idem, name made with curly braces 2173 */ 2174 else if (eval_isnamec1(*arg) || *arg == '{') 2175 { 2176 lval_T lv; 2177 2178 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2179 if (p != NULL && lv.ll_name != NULL) 2180 { 2181 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2182 EMSG(_(e_letunexp)); 2183 else 2184 { 2185 set_var_lval(&lv, p, tv, copy, op); 2186 arg_end = p; 2187 } 2188 } 2189 clear_lval(&lv); 2190 } 2191 2192 else 2193 EMSG2(_(e_invarg2), arg); 2194 2195 return arg_end; 2196 } 2197 2198 /* 2199 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2200 */ 2201 static int 2202 check_changedtick(arg) 2203 char_u *arg; 2204 { 2205 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2206 { 2207 EMSG2(_(e_readonlyvar), arg); 2208 return TRUE; 2209 } 2210 return FALSE; 2211 } 2212 2213 /* 2214 * Get an lval: variable, Dict item or List item that can be assigned a value 2215 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2216 * "name.key", "name.key[expr]" etc. 2217 * Indexing only works if "name" is an existing List or Dictionary. 2218 * "name" points to the start of the name. 2219 * If "rettv" is not NULL it points to the value to be assigned. 2220 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2221 * wrong; must end in space or cmd separator. 2222 * 2223 * Returns a pointer to just after the name, including indexes. 2224 * When an evaluation error occurs "lp->ll_name" is NULL; 2225 * Returns NULL for a parsing error. Still need to free items in "lp"! 2226 */ 2227 static char_u * 2228 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2229 char_u *name; 2230 typval_T *rettv; 2231 lval_T *lp; 2232 int unlet; 2233 int skip; 2234 int quiet; /* don't give error messages */ 2235 int fne_flags; /* flags for find_name_end() */ 2236 { 2237 char_u *p; 2238 char_u *expr_start, *expr_end; 2239 int cc; 2240 dictitem_T *v; 2241 typval_T var1; 2242 typval_T var2; 2243 int empty1 = FALSE; 2244 listitem_T *ni; 2245 char_u *key = NULL; 2246 int len; 2247 hashtab_T *ht; 2248 2249 /* Clear everything in "lp". */ 2250 vim_memset(lp, 0, sizeof(lval_T)); 2251 2252 if (skip) 2253 { 2254 /* When skipping just find the end of the name. */ 2255 lp->ll_name = name; 2256 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2257 } 2258 2259 /* Find the end of the name. */ 2260 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2261 if (expr_start != NULL) 2262 { 2263 /* Don't expand the name when we already know there is an error. */ 2264 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2265 && *p != '[' && *p != '.') 2266 { 2267 EMSG(_(e_trailing)); 2268 return NULL; 2269 } 2270 2271 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2272 if (lp->ll_exp_name == NULL) 2273 { 2274 /* Report an invalid expression in braces, unless the 2275 * expression evaluation has been cancelled due to an 2276 * aborting error, an interrupt, or an exception. */ 2277 if (!aborting() && !quiet) 2278 { 2279 emsg_severe = TRUE; 2280 EMSG2(_(e_invarg2), name); 2281 return NULL; 2282 } 2283 } 2284 lp->ll_name = lp->ll_exp_name; 2285 } 2286 else 2287 lp->ll_name = name; 2288 2289 /* Without [idx] or .key we are done. */ 2290 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2291 return p; 2292 2293 cc = *p; 2294 *p = NUL; 2295 v = find_var(lp->ll_name, &ht); 2296 if (v == NULL && !quiet) 2297 EMSG2(_(e_undefvar), lp->ll_name); 2298 *p = cc; 2299 if (v == NULL) 2300 return NULL; 2301 2302 /* 2303 * Loop until no more [idx] or .key is following. 2304 */ 2305 lp->ll_tv = &v->di_tv; 2306 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2307 { 2308 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2309 && !(lp->ll_tv->v_type == VAR_DICT 2310 && lp->ll_tv->vval.v_dict != NULL)) 2311 { 2312 if (!quiet) 2313 EMSG(_("E689: Can only index a List or Dictionary")); 2314 return NULL; 2315 } 2316 if (lp->ll_range) 2317 { 2318 if (!quiet) 2319 EMSG(_("E708: [:] must come last")); 2320 return NULL; 2321 } 2322 2323 len = -1; 2324 if (*p == '.') 2325 { 2326 key = p + 1; 2327 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2328 ; 2329 if (len == 0) 2330 { 2331 if (!quiet) 2332 EMSG(_(e_emptykey)); 2333 return NULL; 2334 } 2335 p = key + len; 2336 } 2337 else 2338 { 2339 /* Get the index [expr] or the first index [expr: ]. */ 2340 p = skipwhite(p + 1); 2341 if (*p == ':') 2342 empty1 = TRUE; 2343 else 2344 { 2345 empty1 = FALSE; 2346 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2347 return NULL; 2348 if (get_tv_string_chk(&var1) == NULL) 2349 { 2350 /* not a number or string */ 2351 clear_tv(&var1); 2352 return NULL; 2353 } 2354 } 2355 2356 /* Optionally get the second index [ :expr]. */ 2357 if (*p == ':') 2358 { 2359 if (lp->ll_tv->v_type == VAR_DICT) 2360 { 2361 if (!quiet) 2362 EMSG(_(e_dictrange)); 2363 if (!empty1) 2364 clear_tv(&var1); 2365 return NULL; 2366 } 2367 if (rettv != NULL && (rettv->v_type != VAR_LIST 2368 || rettv->vval.v_list == NULL)) 2369 { 2370 if (!quiet) 2371 EMSG(_("E709: [:] requires a List value")); 2372 if (!empty1) 2373 clear_tv(&var1); 2374 return NULL; 2375 } 2376 p = skipwhite(p + 1); 2377 if (*p == ']') 2378 lp->ll_empty2 = TRUE; 2379 else 2380 { 2381 lp->ll_empty2 = FALSE; 2382 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2383 { 2384 if (!empty1) 2385 clear_tv(&var1); 2386 return NULL; 2387 } 2388 if (get_tv_string_chk(&var2) == NULL) 2389 { 2390 /* not a number or string */ 2391 if (!empty1) 2392 clear_tv(&var1); 2393 clear_tv(&var2); 2394 return NULL; 2395 } 2396 } 2397 lp->ll_range = TRUE; 2398 } 2399 else 2400 lp->ll_range = FALSE; 2401 2402 if (*p != ']') 2403 { 2404 if (!quiet) 2405 EMSG(_(e_missbrac)); 2406 if (!empty1) 2407 clear_tv(&var1); 2408 if (lp->ll_range && !lp->ll_empty2) 2409 clear_tv(&var2); 2410 return NULL; 2411 } 2412 2413 /* Skip to past ']'. */ 2414 ++p; 2415 } 2416 2417 if (lp->ll_tv->v_type == VAR_DICT) 2418 { 2419 if (len == -1) 2420 { 2421 /* "[key]": get key from "var1" */ 2422 key = get_tv_string(&var1); /* is number or string */ 2423 if (*key == NUL) 2424 { 2425 if (!quiet) 2426 EMSG(_(e_emptykey)); 2427 clear_tv(&var1); 2428 return NULL; 2429 } 2430 } 2431 lp->ll_list = NULL; 2432 lp->ll_dict = lp->ll_tv->vval.v_dict; 2433 lp->ll_di = dict_find(lp->ll_dict, key, len); 2434 if (lp->ll_di == NULL) 2435 { 2436 /* Key does not exist in dict: may need to add it. */ 2437 if (*p == '[' || *p == '.' || unlet) 2438 { 2439 if (!quiet) 2440 EMSG2(_(e_dictkey), key); 2441 if (len == -1) 2442 clear_tv(&var1); 2443 return NULL; 2444 } 2445 if (len == -1) 2446 lp->ll_newkey = vim_strsave(key); 2447 else 2448 lp->ll_newkey = vim_strnsave(key, len); 2449 if (len == -1) 2450 clear_tv(&var1); 2451 if (lp->ll_newkey == NULL) 2452 p = NULL; 2453 break; 2454 } 2455 if (len == -1) 2456 clear_tv(&var1); 2457 lp->ll_tv = &lp->ll_di->di_tv; 2458 } 2459 else 2460 { 2461 /* 2462 * Get the number and item for the only or first index of the List. 2463 */ 2464 if (empty1) 2465 lp->ll_n1 = 0; 2466 else 2467 { 2468 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2469 clear_tv(&var1); 2470 } 2471 lp->ll_dict = NULL; 2472 lp->ll_list = lp->ll_tv->vval.v_list; 2473 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2474 if (lp->ll_li == NULL) 2475 { 2476 if (!quiet) 2477 EMSGN(_(e_listidx), lp->ll_n1); 2478 if (lp->ll_range && !lp->ll_empty2) 2479 clear_tv(&var2); 2480 return NULL; 2481 } 2482 2483 /* 2484 * May need to find the item or absolute index for the second 2485 * index of a range. 2486 * When no index given: "lp->ll_empty2" is TRUE. 2487 * Otherwise "lp->ll_n2" is set to the second index. 2488 */ 2489 if (lp->ll_range && !lp->ll_empty2) 2490 { 2491 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2492 clear_tv(&var2); 2493 if (lp->ll_n2 < 0) 2494 { 2495 ni = list_find(lp->ll_list, lp->ll_n2); 2496 if (ni == NULL) 2497 { 2498 if (!quiet) 2499 EMSGN(_(e_listidx), lp->ll_n2); 2500 return NULL; 2501 } 2502 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2503 } 2504 2505 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2506 if (lp->ll_n1 < 0) 2507 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2508 if (lp->ll_n2 < lp->ll_n1) 2509 { 2510 if (!quiet) 2511 EMSGN(_(e_listidx), lp->ll_n2); 2512 return NULL; 2513 } 2514 } 2515 2516 lp->ll_tv = &lp->ll_li->li_tv; 2517 } 2518 } 2519 2520 return p; 2521 } 2522 2523 /* 2524 * Clear lval "lp" that was filled by get_lval(). 2525 */ 2526 static void 2527 clear_lval(lp) 2528 lval_T *lp; 2529 { 2530 vim_free(lp->ll_exp_name); 2531 vim_free(lp->ll_newkey); 2532 } 2533 2534 /* 2535 * Set a variable that was parsed by get_lval() to "rettv". 2536 * "endp" points to just after the parsed name. 2537 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2538 */ 2539 static void 2540 set_var_lval(lp, endp, rettv, copy, op) 2541 lval_T *lp; 2542 char_u *endp; 2543 typval_T *rettv; 2544 int copy; 2545 char_u *op; 2546 { 2547 int cc; 2548 listitem_T *ni; 2549 listitem_T *ri; 2550 dictitem_T *di; 2551 2552 if (lp->ll_tv == NULL) 2553 { 2554 if (!check_changedtick(lp->ll_name)) 2555 { 2556 cc = *endp; 2557 *endp = NUL; 2558 if (op != NULL && *op != '=') 2559 { 2560 typval_T tv; 2561 2562 /* handle +=, -= and .= */ 2563 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2564 &tv, TRUE) == OK) 2565 { 2566 if (tv_op(&tv, rettv, op) == OK) 2567 set_var(lp->ll_name, &tv, FALSE); 2568 clear_tv(&tv); 2569 } 2570 } 2571 else 2572 set_var(lp->ll_name, rettv, copy); 2573 *endp = cc; 2574 } 2575 } 2576 else if (tv_check_lock(lp->ll_newkey == NULL 2577 ? lp->ll_tv->v_lock 2578 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2579 ; 2580 else if (lp->ll_range) 2581 { 2582 /* 2583 * Assign the List values to the list items. 2584 */ 2585 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2586 { 2587 if (op != NULL && *op != '=') 2588 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2589 else 2590 { 2591 clear_tv(&lp->ll_li->li_tv); 2592 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2593 } 2594 ri = ri->li_next; 2595 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2596 break; 2597 if (lp->ll_li->li_next == NULL) 2598 { 2599 /* Need to add an empty item. */ 2600 ni = listitem_alloc(); 2601 if (ni == NULL) 2602 { 2603 ri = NULL; 2604 break; 2605 } 2606 ni->li_tv.v_type = VAR_NUMBER; 2607 ni->li_tv.v_lock = 0; 2608 ni->li_tv.vval.v_number = 0; 2609 list_append(lp->ll_list, ni); 2610 } 2611 lp->ll_li = lp->ll_li->li_next; 2612 ++lp->ll_n1; 2613 } 2614 if (ri != NULL) 2615 EMSG(_("E710: List value has more items than target")); 2616 else if (lp->ll_empty2 2617 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2618 : lp->ll_n1 != lp->ll_n2) 2619 EMSG(_("E711: List value has not enough items")); 2620 } 2621 else 2622 { 2623 /* 2624 * Assign to a List or Dictionary item. 2625 */ 2626 if (lp->ll_newkey != NULL) 2627 { 2628 if (op != NULL && *op != '=') 2629 { 2630 EMSG2(_(e_letwrong), op); 2631 return; 2632 } 2633 2634 /* Need to add an item to the Dictionary. */ 2635 di = dictitem_alloc(lp->ll_newkey); 2636 if (di == NULL) 2637 return; 2638 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2639 { 2640 vim_free(di); 2641 return; 2642 } 2643 lp->ll_tv = &di->di_tv; 2644 } 2645 else if (op != NULL && *op != '=') 2646 { 2647 tv_op(lp->ll_tv, rettv, op); 2648 return; 2649 } 2650 else 2651 clear_tv(lp->ll_tv); 2652 2653 /* 2654 * Assign the value to the variable or list item. 2655 */ 2656 if (copy) 2657 copy_tv(rettv, lp->ll_tv); 2658 else 2659 { 2660 *lp->ll_tv = *rettv; 2661 lp->ll_tv->v_lock = 0; 2662 init_tv(rettv); 2663 } 2664 } 2665 } 2666 2667 /* 2668 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2669 * Returns OK or FAIL. 2670 */ 2671 static int 2672 tv_op(tv1, tv2, op) 2673 typval_T *tv1; 2674 typval_T *tv2; 2675 char_u *op; 2676 { 2677 long n; 2678 char_u numbuf[NUMBUFLEN]; 2679 char_u *s; 2680 2681 /* Can't do anything with a Funcref or a Dict on the right. */ 2682 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2683 { 2684 switch (tv1->v_type) 2685 { 2686 case VAR_DICT: 2687 case VAR_FUNC: 2688 break; 2689 2690 case VAR_LIST: 2691 if (*op != '+' || tv2->v_type != VAR_LIST) 2692 break; 2693 /* List += List */ 2694 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2695 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2696 return OK; 2697 2698 case VAR_NUMBER: 2699 case VAR_STRING: 2700 if (tv2->v_type == VAR_LIST) 2701 break; 2702 if (*op == '+' || *op == '-') 2703 { 2704 /* nr += nr or nr -= nr*/ 2705 n = get_tv_number(tv1); 2706 if (*op == '+') 2707 n += get_tv_number(tv2); 2708 else 2709 n -= get_tv_number(tv2); 2710 clear_tv(tv1); 2711 tv1->v_type = VAR_NUMBER; 2712 tv1->vval.v_number = n; 2713 } 2714 else 2715 { 2716 /* str .= str */ 2717 s = get_tv_string(tv1); 2718 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2719 clear_tv(tv1); 2720 tv1->v_type = VAR_STRING; 2721 tv1->vval.v_string = s; 2722 } 2723 return OK; 2724 } 2725 } 2726 2727 EMSG2(_(e_letwrong), op); 2728 return FAIL; 2729 } 2730 2731 /* 2732 * Add a watcher to a list. 2733 */ 2734 static void 2735 list_add_watch(l, lw) 2736 list_T *l; 2737 listwatch_T *lw; 2738 { 2739 lw->lw_next = l->lv_watch; 2740 l->lv_watch = lw; 2741 } 2742 2743 /* 2744 * Remove a watcher from a list. 2745 * No warning when it isn't found... 2746 */ 2747 static void 2748 list_rem_watch(l, lwrem) 2749 list_T *l; 2750 listwatch_T *lwrem; 2751 { 2752 listwatch_T *lw, **lwp; 2753 2754 lwp = &l->lv_watch; 2755 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2756 { 2757 if (lw == lwrem) 2758 { 2759 *lwp = lw->lw_next; 2760 break; 2761 } 2762 lwp = &lw->lw_next; 2763 } 2764 } 2765 2766 /* 2767 * Just before removing an item from a list: advance watchers to the next 2768 * item. 2769 */ 2770 static void 2771 list_fix_watch(l, item) 2772 list_T *l; 2773 listitem_T *item; 2774 { 2775 listwatch_T *lw; 2776 2777 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2778 if (lw->lw_item == item) 2779 lw->lw_item = item->li_next; 2780 } 2781 2782 /* 2783 * Evaluate the expression used in a ":for var in expr" command. 2784 * "arg" points to "var". 2785 * Set "*errp" to TRUE for an error, FALSE otherwise; 2786 * Return a pointer that holds the info. Null when there is an error. 2787 */ 2788 void * 2789 eval_for_line(arg, errp, nextcmdp, skip) 2790 char_u *arg; 2791 int *errp; 2792 char_u **nextcmdp; 2793 int skip; 2794 { 2795 forinfo_T *fi; 2796 char_u *expr; 2797 typval_T tv; 2798 list_T *l; 2799 2800 *errp = TRUE; /* default: there is an error */ 2801 2802 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2803 if (fi == NULL) 2804 return NULL; 2805 2806 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2807 if (expr == NULL) 2808 return fi; 2809 2810 expr = skipwhite(expr); 2811 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2812 { 2813 EMSG(_("E690: Missing \"in\" after :for")); 2814 return fi; 2815 } 2816 2817 if (skip) 2818 ++emsg_skip; 2819 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2820 { 2821 *errp = FALSE; 2822 if (!skip) 2823 { 2824 l = tv.vval.v_list; 2825 if (tv.v_type != VAR_LIST || l == NULL) 2826 { 2827 EMSG(_(e_listreq)); 2828 clear_tv(&tv); 2829 } 2830 else 2831 { 2832 fi->fi_list = l; 2833 list_add_watch(l, &fi->fi_lw); 2834 fi->fi_lw.lw_item = l->lv_first; 2835 } 2836 } 2837 } 2838 if (skip) 2839 --emsg_skip; 2840 2841 return fi; 2842 } 2843 2844 /* 2845 * Use the first item in a ":for" list. Advance to the next. 2846 * Assign the values to the variable (list). "arg" points to the first one. 2847 * Return TRUE when a valid item was found, FALSE when at end of list or 2848 * something wrong. 2849 */ 2850 int 2851 next_for_item(fi_void, arg) 2852 void *fi_void; 2853 char_u *arg; 2854 { 2855 forinfo_T *fi = (forinfo_T *)fi_void; 2856 int result; 2857 listitem_T *item; 2858 2859 item = fi->fi_lw.lw_item; 2860 if (item == NULL) 2861 result = FALSE; 2862 else 2863 { 2864 fi->fi_lw.lw_item = item->li_next; 2865 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2866 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2867 } 2868 return result; 2869 } 2870 2871 /* 2872 * Free the structure used to store info used by ":for". 2873 */ 2874 void 2875 free_for_info(fi_void) 2876 void *fi_void; 2877 { 2878 forinfo_T *fi = (forinfo_T *)fi_void; 2879 2880 if (fi != NULL && fi->fi_list != NULL) 2881 { 2882 list_rem_watch(fi->fi_list, &fi->fi_lw); 2883 list_unref(fi->fi_list); 2884 } 2885 vim_free(fi); 2886 } 2887 2888 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2889 2890 void 2891 set_context_for_expression(xp, arg, cmdidx) 2892 expand_T *xp; 2893 char_u *arg; 2894 cmdidx_T cmdidx; 2895 { 2896 int got_eq = FALSE; 2897 int c; 2898 char_u *p; 2899 2900 if (cmdidx == CMD_let) 2901 { 2902 xp->xp_context = EXPAND_USER_VARS; 2903 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2904 { 2905 /* ":let var1 var2 ...": find last space. */ 2906 for (p = arg + STRLEN(arg); p >= arg; ) 2907 { 2908 xp->xp_pattern = p; 2909 mb_ptr_back(arg, p); 2910 if (vim_iswhite(*p)) 2911 break; 2912 } 2913 return; 2914 } 2915 } 2916 else 2917 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2918 : EXPAND_EXPRESSION; 2919 while ((xp->xp_pattern = vim_strpbrk(arg, 2920 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2921 { 2922 c = *xp->xp_pattern; 2923 if (c == '&') 2924 { 2925 c = xp->xp_pattern[1]; 2926 if (c == '&') 2927 { 2928 ++xp->xp_pattern; 2929 xp->xp_context = cmdidx != CMD_let || got_eq 2930 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2931 } 2932 else if (c != ' ') 2933 { 2934 xp->xp_context = EXPAND_SETTINGS; 2935 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2936 xp->xp_pattern += 2; 2937 2938 } 2939 } 2940 else if (c == '$') 2941 { 2942 /* environment variable */ 2943 xp->xp_context = EXPAND_ENV_VARS; 2944 } 2945 else if (c == '=') 2946 { 2947 got_eq = TRUE; 2948 xp->xp_context = EXPAND_EXPRESSION; 2949 } 2950 else if (c == '<' 2951 && xp->xp_context == EXPAND_FUNCTIONS 2952 && vim_strchr(xp->xp_pattern, '(') == NULL) 2953 { 2954 /* Function name can start with "<SNR>" */ 2955 break; 2956 } 2957 else if (cmdidx != CMD_let || got_eq) 2958 { 2959 if (c == '"') /* string */ 2960 { 2961 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2962 if (c == '\\' && xp->xp_pattern[1] != NUL) 2963 ++xp->xp_pattern; 2964 xp->xp_context = EXPAND_NOTHING; 2965 } 2966 else if (c == '\'') /* literal string */ 2967 { 2968 /* Trick: '' is like stopping and starting a literal string. */ 2969 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2970 /* skip */ ; 2971 xp->xp_context = EXPAND_NOTHING; 2972 } 2973 else if (c == '|') 2974 { 2975 if (xp->xp_pattern[1] == '|') 2976 { 2977 ++xp->xp_pattern; 2978 xp->xp_context = EXPAND_EXPRESSION; 2979 } 2980 else 2981 xp->xp_context = EXPAND_COMMANDS; 2982 } 2983 else 2984 xp->xp_context = EXPAND_EXPRESSION; 2985 } 2986 else 2987 /* Doesn't look like something valid, expand as an expression 2988 * anyway. */ 2989 xp->xp_context = EXPAND_EXPRESSION; 2990 arg = xp->xp_pattern; 2991 if (*arg != NUL) 2992 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 2993 /* skip */ ; 2994 } 2995 xp->xp_pattern = arg; 2996 } 2997 2998 #endif /* FEAT_CMDL_COMPL */ 2999 3000 /* 3001 * ":1,25call func(arg1, arg2)" function call. 3002 */ 3003 void 3004 ex_call(eap) 3005 exarg_T *eap; 3006 { 3007 char_u *arg = eap->arg; 3008 char_u *startarg; 3009 char_u *name; 3010 char_u *tofree; 3011 int len; 3012 typval_T rettv; 3013 linenr_T lnum; 3014 int doesrange; 3015 int failed = FALSE; 3016 funcdict_T fudi; 3017 3018 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3019 vim_free(fudi.fd_newkey); 3020 if (tofree == NULL) 3021 return; 3022 3023 /* Increase refcount on dictionary, it could get deleted when evaluating 3024 * the arguments. */ 3025 if (fudi.fd_dict != NULL) 3026 ++fudi.fd_dict->dv_refcount; 3027 3028 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3029 len = STRLEN(tofree); 3030 name = deref_func_name(tofree, &len); 3031 3032 /* Skip white space to allow ":call func ()". Not good, but required for 3033 * backward compatibility. */ 3034 startarg = skipwhite(arg); 3035 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3036 3037 if (*startarg != '(') 3038 { 3039 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3040 goto end; 3041 } 3042 3043 /* 3044 * When skipping, evaluate the function once, to find the end of the 3045 * arguments. 3046 * When the function takes a range, this is discovered after the first 3047 * call, and the loop is broken. 3048 */ 3049 if (eap->skip) 3050 { 3051 ++emsg_skip; 3052 lnum = eap->line2; /* do it once, also with an invalid range */ 3053 } 3054 else 3055 lnum = eap->line1; 3056 for ( ; lnum <= eap->line2; ++lnum) 3057 { 3058 if (!eap->skip && eap->addr_count > 0) 3059 { 3060 curwin->w_cursor.lnum = lnum; 3061 curwin->w_cursor.col = 0; 3062 } 3063 arg = startarg; 3064 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3065 eap->line1, eap->line2, &doesrange, 3066 !eap->skip, fudi.fd_dict) == FAIL) 3067 { 3068 failed = TRUE; 3069 break; 3070 } 3071 clear_tv(&rettv); 3072 if (doesrange || eap->skip) 3073 break; 3074 /* Stop when immediately aborting on error, or when an interrupt 3075 * occurred or an exception was thrown but not caught. 3076 * get_func_tv() returned OK, so that the check for trailing 3077 * characters below is executed. */ 3078 if (aborting()) 3079 break; 3080 } 3081 if (eap->skip) 3082 --emsg_skip; 3083 3084 if (!failed) 3085 { 3086 /* Check for trailing illegal characters and a following command. */ 3087 if (!ends_excmd(*arg)) 3088 { 3089 emsg_severe = TRUE; 3090 EMSG(_(e_trailing)); 3091 } 3092 else 3093 eap->nextcmd = check_nextcmd(arg); 3094 } 3095 3096 end: 3097 dict_unref(fudi.fd_dict); 3098 vim_free(tofree); 3099 } 3100 3101 /* 3102 * ":unlet[!] var1 ... " command. 3103 */ 3104 void 3105 ex_unlet(eap) 3106 exarg_T *eap; 3107 { 3108 ex_unletlock(eap, eap->arg, 0); 3109 } 3110 3111 /* 3112 * ":lockvar" and ":unlockvar" commands 3113 */ 3114 void 3115 ex_lockvar(eap) 3116 exarg_T *eap; 3117 { 3118 char_u *arg = eap->arg; 3119 int deep = 2; 3120 3121 if (eap->forceit) 3122 deep = -1; 3123 else if (vim_isdigit(*arg)) 3124 { 3125 deep = getdigits(&arg); 3126 arg = skipwhite(arg); 3127 } 3128 3129 ex_unletlock(eap, arg, deep); 3130 } 3131 3132 /* 3133 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3134 */ 3135 static void 3136 ex_unletlock(eap, argstart, deep) 3137 exarg_T *eap; 3138 char_u *argstart; 3139 int deep; 3140 { 3141 char_u *arg = argstart; 3142 char_u *name_end; 3143 int error = FALSE; 3144 lval_T lv; 3145 3146 do 3147 { 3148 /* Parse the name and find the end. */ 3149 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3150 FNE_CHECK_START); 3151 if (lv.ll_name == NULL) 3152 error = TRUE; /* error but continue parsing */ 3153 if (name_end == NULL || (!vim_iswhite(*name_end) 3154 && !ends_excmd(*name_end))) 3155 { 3156 if (name_end != NULL) 3157 { 3158 emsg_severe = TRUE; 3159 EMSG(_(e_trailing)); 3160 } 3161 if (!(eap->skip || error)) 3162 clear_lval(&lv); 3163 break; 3164 } 3165 3166 if (!error && !eap->skip) 3167 { 3168 if (eap->cmdidx == CMD_unlet) 3169 { 3170 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3171 error = TRUE; 3172 } 3173 else 3174 { 3175 if (do_lock_var(&lv, name_end, deep, 3176 eap->cmdidx == CMD_lockvar) == FAIL) 3177 error = TRUE; 3178 } 3179 } 3180 3181 if (!eap->skip) 3182 clear_lval(&lv); 3183 3184 arg = skipwhite(name_end); 3185 } while (!ends_excmd(*arg)); 3186 3187 eap->nextcmd = check_nextcmd(arg); 3188 } 3189 3190 static int 3191 do_unlet_var(lp, name_end, forceit) 3192 lval_T *lp; 3193 char_u *name_end; 3194 int forceit; 3195 { 3196 int ret = OK; 3197 int cc; 3198 3199 if (lp->ll_tv == NULL) 3200 { 3201 cc = *name_end; 3202 *name_end = NUL; 3203 3204 /* Normal name or expanded name. */ 3205 if (check_changedtick(lp->ll_name)) 3206 ret = FAIL; 3207 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3208 ret = FAIL; 3209 *name_end = cc; 3210 } 3211 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3212 return FAIL; 3213 else if (lp->ll_range) 3214 { 3215 listitem_T *li; 3216 3217 /* Delete a range of List items. */ 3218 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3219 { 3220 li = lp->ll_li->li_next; 3221 listitem_remove(lp->ll_list, lp->ll_li); 3222 lp->ll_li = li; 3223 ++lp->ll_n1; 3224 } 3225 } 3226 else 3227 { 3228 if (lp->ll_list != NULL) 3229 /* unlet a List item. */ 3230 listitem_remove(lp->ll_list, lp->ll_li); 3231 else 3232 /* unlet a Dictionary item. */ 3233 dictitem_remove(lp->ll_dict, lp->ll_di); 3234 } 3235 3236 return ret; 3237 } 3238 3239 /* 3240 * "unlet" a variable. Return OK if it existed, FAIL if not. 3241 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3242 */ 3243 int 3244 do_unlet(name, forceit) 3245 char_u *name; 3246 int forceit; 3247 { 3248 hashtab_T *ht; 3249 hashitem_T *hi; 3250 char_u *varname; 3251 3252 ht = find_var_ht(name, &varname); 3253 if (ht != NULL && *varname != NUL) 3254 { 3255 hi = hash_find(ht, varname); 3256 if (!HASHITEM_EMPTY(hi)) 3257 { 3258 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3259 return FAIL; 3260 delete_var(ht, hi); 3261 return OK; 3262 } 3263 } 3264 if (forceit) 3265 return OK; 3266 EMSG2(_("E108: No such variable: \"%s\""), name); 3267 return FAIL; 3268 } 3269 3270 /* 3271 * Lock or unlock variable indicated by "lp". 3272 * "deep" is the levels to go (-1 for unlimited); 3273 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3274 */ 3275 static int 3276 do_lock_var(lp, name_end, deep, lock) 3277 lval_T *lp; 3278 char_u *name_end; 3279 int deep; 3280 int lock; 3281 { 3282 int ret = OK; 3283 int cc; 3284 dictitem_T *di; 3285 3286 if (deep == 0) /* nothing to do */ 3287 return OK; 3288 3289 if (lp->ll_tv == NULL) 3290 { 3291 cc = *name_end; 3292 *name_end = NUL; 3293 3294 /* Normal name or expanded name. */ 3295 if (check_changedtick(lp->ll_name)) 3296 ret = FAIL; 3297 else 3298 { 3299 di = find_var(lp->ll_name, NULL); 3300 if (di == NULL) 3301 ret = FAIL; 3302 else 3303 { 3304 if (lock) 3305 di->di_flags |= DI_FLAGS_LOCK; 3306 else 3307 di->di_flags &= ~DI_FLAGS_LOCK; 3308 item_lock(&di->di_tv, deep, lock); 3309 } 3310 } 3311 *name_end = cc; 3312 } 3313 else if (lp->ll_range) 3314 { 3315 listitem_T *li = lp->ll_li; 3316 3317 /* (un)lock a range of List items. */ 3318 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3319 { 3320 item_lock(&li->li_tv, deep, lock); 3321 li = li->li_next; 3322 ++lp->ll_n1; 3323 } 3324 } 3325 else if (lp->ll_list != NULL) 3326 /* (un)lock a List item. */ 3327 item_lock(&lp->ll_li->li_tv, deep, lock); 3328 else 3329 /* un(lock) a Dictionary item. */ 3330 item_lock(&lp->ll_di->di_tv, deep, lock); 3331 3332 return ret; 3333 } 3334 3335 /* 3336 * Lock or unlock an item. "deep" is nr of levels to go. 3337 */ 3338 static void 3339 item_lock(tv, deep, lock) 3340 typval_T *tv; 3341 int deep; 3342 int lock; 3343 { 3344 static int recurse = 0; 3345 list_T *l; 3346 listitem_T *li; 3347 dict_T *d; 3348 hashitem_T *hi; 3349 int todo; 3350 3351 if (recurse >= DICT_MAXNEST) 3352 { 3353 EMSG(_("E743: variable nested too deep for (un)lock")); 3354 return; 3355 } 3356 if (deep == 0) 3357 return; 3358 ++recurse; 3359 3360 /* lock/unlock the item itself */ 3361 if (lock) 3362 tv->v_lock |= VAR_LOCKED; 3363 else 3364 tv->v_lock &= ~VAR_LOCKED; 3365 3366 switch (tv->v_type) 3367 { 3368 case VAR_LIST: 3369 if ((l = tv->vval.v_list) != NULL) 3370 { 3371 if (lock) 3372 l->lv_lock |= VAR_LOCKED; 3373 else 3374 l->lv_lock &= ~VAR_LOCKED; 3375 if (deep < 0 || deep > 1) 3376 /* recursive: lock/unlock the items the List contains */ 3377 for (li = l->lv_first; li != NULL; li = li->li_next) 3378 item_lock(&li->li_tv, deep - 1, lock); 3379 } 3380 break; 3381 case VAR_DICT: 3382 if ((d = tv->vval.v_dict) != NULL) 3383 { 3384 if (lock) 3385 d->dv_lock |= VAR_LOCKED; 3386 else 3387 d->dv_lock &= ~VAR_LOCKED; 3388 if (deep < 0 || deep > 1) 3389 { 3390 /* recursive: lock/unlock the items the List contains */ 3391 todo = d->dv_hashtab.ht_used; 3392 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3393 { 3394 if (!HASHITEM_EMPTY(hi)) 3395 { 3396 --todo; 3397 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3398 } 3399 } 3400 } 3401 } 3402 } 3403 --recurse; 3404 } 3405 3406 /* 3407 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3408 * it refers to a List or Dictionary that is locked. 3409 */ 3410 static int 3411 tv_islocked(tv) 3412 typval_T *tv; 3413 { 3414 return (tv->v_lock & VAR_LOCKED) 3415 || (tv->v_type == VAR_LIST 3416 && tv->vval.v_list != NULL 3417 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3418 || (tv->v_type == VAR_DICT 3419 && tv->vval.v_dict != NULL 3420 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3421 } 3422 3423 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3424 /* 3425 * Delete all "menutrans_" variables. 3426 */ 3427 void 3428 del_menutrans_vars() 3429 { 3430 hashitem_T *hi; 3431 int todo; 3432 3433 hash_lock(&globvarht); 3434 todo = globvarht.ht_used; 3435 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3436 { 3437 if (!HASHITEM_EMPTY(hi)) 3438 { 3439 --todo; 3440 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3441 delete_var(&globvarht, hi); 3442 } 3443 } 3444 hash_unlock(&globvarht); 3445 } 3446 #endif 3447 3448 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3449 3450 /* 3451 * Local string buffer for the next two functions to store a variable name 3452 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3453 * get_user_var_name(). 3454 */ 3455 3456 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3457 3458 static char_u *varnamebuf = NULL; 3459 static int varnamebuflen = 0; 3460 3461 /* 3462 * Function to concatenate a prefix and a variable name. 3463 */ 3464 static char_u * 3465 cat_prefix_varname(prefix, name) 3466 int prefix; 3467 char_u *name; 3468 { 3469 int len; 3470 3471 len = (int)STRLEN(name) + 3; 3472 if (len > varnamebuflen) 3473 { 3474 vim_free(varnamebuf); 3475 len += 10; /* some additional space */ 3476 varnamebuf = alloc(len); 3477 if (varnamebuf == NULL) 3478 { 3479 varnamebuflen = 0; 3480 return NULL; 3481 } 3482 varnamebuflen = len; 3483 } 3484 *varnamebuf = prefix; 3485 varnamebuf[1] = ':'; 3486 STRCPY(varnamebuf + 2, name); 3487 return varnamebuf; 3488 } 3489 3490 /* 3491 * Function given to ExpandGeneric() to obtain the list of user defined 3492 * (global/buffer/window/built-in) variable names. 3493 */ 3494 /*ARGSUSED*/ 3495 char_u * 3496 get_user_var_name(xp, idx) 3497 expand_T *xp; 3498 int idx; 3499 { 3500 static long_u gdone; 3501 static long_u bdone; 3502 static long_u wdone; 3503 static int vidx; 3504 static hashitem_T *hi; 3505 hashtab_T *ht; 3506 3507 if (idx == 0) 3508 gdone = bdone = wdone = vidx = 0; 3509 3510 /* Global variables */ 3511 if (gdone < globvarht.ht_used) 3512 { 3513 if (gdone++ == 0) 3514 hi = globvarht.ht_array; 3515 else 3516 ++hi; 3517 while (HASHITEM_EMPTY(hi)) 3518 ++hi; 3519 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3520 return cat_prefix_varname('g', hi->hi_key); 3521 return hi->hi_key; 3522 } 3523 3524 /* b: variables */ 3525 ht = &curbuf->b_vars.dv_hashtab; 3526 if (bdone < ht->ht_used) 3527 { 3528 if (bdone++ == 0) 3529 hi = ht->ht_array; 3530 else 3531 ++hi; 3532 while (HASHITEM_EMPTY(hi)) 3533 ++hi; 3534 return cat_prefix_varname('b', hi->hi_key); 3535 } 3536 if (bdone == ht->ht_used) 3537 { 3538 ++bdone; 3539 return (char_u *)"b:changedtick"; 3540 } 3541 3542 /* w: variables */ 3543 ht = &curwin->w_vars.dv_hashtab; 3544 if (wdone < ht->ht_used) 3545 { 3546 if (wdone++ == 0) 3547 hi = ht->ht_array; 3548 else 3549 ++hi; 3550 while (HASHITEM_EMPTY(hi)) 3551 ++hi; 3552 return cat_prefix_varname('w', hi->hi_key); 3553 } 3554 3555 /* v: variables */ 3556 if (vidx < VV_LEN) 3557 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3558 3559 vim_free(varnamebuf); 3560 varnamebuf = NULL; 3561 varnamebuflen = 0; 3562 return NULL; 3563 } 3564 3565 #endif /* FEAT_CMDL_COMPL */ 3566 3567 /* 3568 * types for expressions. 3569 */ 3570 typedef enum 3571 { 3572 TYPE_UNKNOWN = 0 3573 , TYPE_EQUAL /* == */ 3574 , TYPE_NEQUAL /* != */ 3575 , TYPE_GREATER /* > */ 3576 , TYPE_GEQUAL /* >= */ 3577 , TYPE_SMALLER /* < */ 3578 , TYPE_SEQUAL /* <= */ 3579 , TYPE_MATCH /* =~ */ 3580 , TYPE_NOMATCH /* !~ */ 3581 } exptype_T; 3582 3583 /* 3584 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3585 * executed. The function may return OK, but the rettv will be of type 3586 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3587 */ 3588 3589 /* 3590 * Handle zero level expression. 3591 * This calls eval1() and handles error message and nextcmd. 3592 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3593 * Return OK or FAIL. 3594 */ 3595 static int 3596 eval0(arg, rettv, nextcmd, evaluate) 3597 char_u *arg; 3598 typval_T *rettv; 3599 char_u **nextcmd; 3600 int evaluate; 3601 { 3602 int ret; 3603 char_u *p; 3604 3605 p = skipwhite(arg); 3606 ret = eval1(&p, rettv, evaluate); 3607 if (ret == FAIL || !ends_excmd(*p)) 3608 { 3609 if (ret != FAIL) 3610 clear_tv(rettv); 3611 /* 3612 * Report the invalid expression unless the expression evaluation has 3613 * been cancelled due to an aborting error, an interrupt, or an 3614 * exception. 3615 */ 3616 if (!aborting()) 3617 EMSG2(_(e_invexpr2), arg); 3618 ret = FAIL; 3619 } 3620 if (nextcmd != NULL) 3621 *nextcmd = check_nextcmd(p); 3622 3623 return ret; 3624 } 3625 3626 /* 3627 * Handle top level expression: 3628 * expr1 ? expr0 : expr0 3629 * 3630 * "arg" must point to the first non-white of the expression. 3631 * "arg" is advanced to the next non-white after the recognized expression. 3632 * 3633 * Return OK or FAIL. 3634 */ 3635 static int 3636 eval1(arg, rettv, evaluate) 3637 char_u **arg; 3638 typval_T *rettv; 3639 int evaluate; 3640 { 3641 int result; 3642 typval_T var2; 3643 3644 /* 3645 * Get the first variable. 3646 */ 3647 if (eval2(arg, rettv, evaluate) == FAIL) 3648 return FAIL; 3649 3650 if ((*arg)[0] == '?') 3651 { 3652 result = FALSE; 3653 if (evaluate) 3654 { 3655 int error = FALSE; 3656 3657 if (get_tv_number_chk(rettv, &error) != 0) 3658 result = TRUE; 3659 clear_tv(rettv); 3660 if (error) 3661 return FAIL; 3662 } 3663 3664 /* 3665 * Get the second variable. 3666 */ 3667 *arg = skipwhite(*arg + 1); 3668 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3669 return FAIL; 3670 3671 /* 3672 * Check for the ":". 3673 */ 3674 if ((*arg)[0] != ':') 3675 { 3676 EMSG(_("E109: Missing ':' after '?'")); 3677 if (evaluate && result) 3678 clear_tv(rettv); 3679 return FAIL; 3680 } 3681 3682 /* 3683 * Get the third variable. 3684 */ 3685 *arg = skipwhite(*arg + 1); 3686 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3687 { 3688 if (evaluate && result) 3689 clear_tv(rettv); 3690 return FAIL; 3691 } 3692 if (evaluate && !result) 3693 *rettv = var2; 3694 } 3695 3696 return OK; 3697 } 3698 3699 /* 3700 * Handle first level expression: 3701 * expr2 || expr2 || expr2 logical OR 3702 * 3703 * "arg" must point to the first non-white of the expression. 3704 * "arg" is advanced to the next non-white after the recognized expression. 3705 * 3706 * Return OK or FAIL. 3707 */ 3708 static int 3709 eval2(arg, rettv, evaluate) 3710 char_u **arg; 3711 typval_T *rettv; 3712 int evaluate; 3713 { 3714 typval_T var2; 3715 long result; 3716 int first; 3717 int error = FALSE; 3718 3719 /* 3720 * Get the first variable. 3721 */ 3722 if (eval3(arg, rettv, evaluate) == FAIL) 3723 return FAIL; 3724 3725 /* 3726 * Repeat until there is no following "||". 3727 */ 3728 first = TRUE; 3729 result = FALSE; 3730 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3731 { 3732 if (evaluate && first) 3733 { 3734 if (get_tv_number_chk(rettv, &error) != 0) 3735 result = TRUE; 3736 clear_tv(rettv); 3737 if (error) 3738 return FAIL; 3739 first = FALSE; 3740 } 3741 3742 /* 3743 * Get the second variable. 3744 */ 3745 *arg = skipwhite(*arg + 2); 3746 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3747 return FAIL; 3748 3749 /* 3750 * Compute the result. 3751 */ 3752 if (evaluate && !result) 3753 { 3754 if (get_tv_number_chk(&var2, &error) != 0) 3755 result = TRUE; 3756 clear_tv(&var2); 3757 if (error) 3758 return FAIL; 3759 } 3760 if (evaluate) 3761 { 3762 rettv->v_type = VAR_NUMBER; 3763 rettv->vval.v_number = result; 3764 } 3765 } 3766 3767 return OK; 3768 } 3769 3770 /* 3771 * Handle second level expression: 3772 * expr3 && expr3 && expr3 logical AND 3773 * 3774 * "arg" must point to the first non-white of the expression. 3775 * "arg" is advanced to the next non-white after the recognized expression. 3776 * 3777 * Return OK or FAIL. 3778 */ 3779 static int 3780 eval3(arg, rettv, evaluate) 3781 char_u **arg; 3782 typval_T *rettv; 3783 int evaluate; 3784 { 3785 typval_T var2; 3786 long result; 3787 int first; 3788 int error = FALSE; 3789 3790 /* 3791 * Get the first variable. 3792 */ 3793 if (eval4(arg, rettv, evaluate) == FAIL) 3794 return FAIL; 3795 3796 /* 3797 * Repeat until there is no following "&&". 3798 */ 3799 first = TRUE; 3800 result = TRUE; 3801 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3802 { 3803 if (evaluate && first) 3804 { 3805 if (get_tv_number_chk(rettv, &error) == 0) 3806 result = FALSE; 3807 clear_tv(rettv); 3808 if (error) 3809 return FAIL; 3810 first = FALSE; 3811 } 3812 3813 /* 3814 * Get the second variable. 3815 */ 3816 *arg = skipwhite(*arg + 2); 3817 if (eval4(arg, &var2, evaluate && result) == FAIL) 3818 return FAIL; 3819 3820 /* 3821 * Compute the result. 3822 */ 3823 if (evaluate && result) 3824 { 3825 if (get_tv_number_chk(&var2, &error) == 0) 3826 result = FALSE; 3827 clear_tv(&var2); 3828 if (error) 3829 return FAIL; 3830 } 3831 if (evaluate) 3832 { 3833 rettv->v_type = VAR_NUMBER; 3834 rettv->vval.v_number = result; 3835 } 3836 } 3837 3838 return OK; 3839 } 3840 3841 /* 3842 * Handle third level expression: 3843 * var1 == var2 3844 * var1 =~ var2 3845 * var1 != var2 3846 * var1 !~ var2 3847 * var1 > var2 3848 * var1 >= var2 3849 * var1 < var2 3850 * var1 <= var2 3851 * var1 is var2 3852 * var1 isnot var2 3853 * 3854 * "arg" must point to the first non-white of the expression. 3855 * "arg" is advanced to the next non-white after the recognized expression. 3856 * 3857 * Return OK or FAIL. 3858 */ 3859 static int 3860 eval4(arg, rettv, evaluate) 3861 char_u **arg; 3862 typval_T *rettv; 3863 int evaluate; 3864 { 3865 typval_T var2; 3866 char_u *p; 3867 int i; 3868 exptype_T type = TYPE_UNKNOWN; 3869 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3870 int len = 2; 3871 long n1, n2; 3872 char_u *s1, *s2; 3873 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3874 regmatch_T regmatch; 3875 int ic; 3876 char_u *save_cpo; 3877 3878 /* 3879 * Get the first variable. 3880 */ 3881 if (eval5(arg, rettv, evaluate) == FAIL) 3882 return FAIL; 3883 3884 p = *arg; 3885 switch (p[0]) 3886 { 3887 case '=': if (p[1] == '=') 3888 type = TYPE_EQUAL; 3889 else if (p[1] == '~') 3890 type = TYPE_MATCH; 3891 break; 3892 case '!': if (p[1] == '=') 3893 type = TYPE_NEQUAL; 3894 else if (p[1] == '~') 3895 type = TYPE_NOMATCH; 3896 break; 3897 case '>': if (p[1] != '=') 3898 { 3899 type = TYPE_GREATER; 3900 len = 1; 3901 } 3902 else 3903 type = TYPE_GEQUAL; 3904 break; 3905 case '<': if (p[1] != '=') 3906 { 3907 type = TYPE_SMALLER; 3908 len = 1; 3909 } 3910 else 3911 type = TYPE_SEQUAL; 3912 break; 3913 case 'i': if (p[1] == 's') 3914 { 3915 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3916 len = 5; 3917 if (!vim_isIDc(p[len])) 3918 { 3919 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3920 type_is = TRUE; 3921 } 3922 } 3923 break; 3924 } 3925 3926 /* 3927 * If there is a comparitive operator, use it. 3928 */ 3929 if (type != TYPE_UNKNOWN) 3930 { 3931 /* extra question mark appended: ignore case */ 3932 if (p[len] == '?') 3933 { 3934 ic = TRUE; 3935 ++len; 3936 } 3937 /* extra '#' appended: match case */ 3938 else if (p[len] == '#') 3939 { 3940 ic = FALSE; 3941 ++len; 3942 } 3943 /* nothing appened: use 'ignorecase' */ 3944 else 3945 ic = p_ic; 3946 3947 /* 3948 * Get the second variable. 3949 */ 3950 *arg = skipwhite(p + len); 3951 if (eval5(arg, &var2, evaluate) == FAIL) 3952 { 3953 clear_tv(rettv); 3954 return FAIL; 3955 } 3956 3957 if (evaluate) 3958 { 3959 if (type_is && rettv->v_type != var2.v_type) 3960 { 3961 /* For "is" a different type always means FALSE, for "notis" 3962 * it means TRUE. */ 3963 n1 = (type == TYPE_NEQUAL); 3964 } 3965 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3966 { 3967 if (type_is) 3968 { 3969 n1 = (rettv->v_type == var2.v_type 3970 && rettv->vval.v_list == var2.vval.v_list); 3971 if (type == TYPE_NEQUAL) 3972 n1 = !n1; 3973 } 3974 else if (rettv->v_type != var2.v_type 3975 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3976 { 3977 if (rettv->v_type != var2.v_type) 3978 EMSG(_("E691: Can only compare List with List")); 3979 else 3980 EMSG(_("E692: Invalid operation for Lists")); 3981 clear_tv(rettv); 3982 clear_tv(&var2); 3983 return FAIL; 3984 } 3985 else 3986 { 3987 /* Compare two Lists for being equal or unequal. */ 3988 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3989 if (type == TYPE_NEQUAL) 3990 n1 = !n1; 3991 } 3992 } 3993 3994 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 3995 { 3996 if (type_is) 3997 { 3998 n1 = (rettv->v_type == var2.v_type 3999 && rettv->vval.v_dict == var2.vval.v_dict); 4000 if (type == TYPE_NEQUAL) 4001 n1 = !n1; 4002 } 4003 else if (rettv->v_type != var2.v_type 4004 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4005 { 4006 if (rettv->v_type != var2.v_type) 4007 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4008 else 4009 EMSG(_("E736: Invalid operation for Dictionary")); 4010 clear_tv(rettv); 4011 clear_tv(&var2); 4012 return FAIL; 4013 } 4014 else 4015 { 4016 /* Compare two Dictionaries for being equal or unequal. */ 4017 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4018 if (type == TYPE_NEQUAL) 4019 n1 = !n1; 4020 } 4021 } 4022 4023 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4024 { 4025 if (rettv->v_type != var2.v_type 4026 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4027 { 4028 if (rettv->v_type != var2.v_type) 4029 EMSG(_("E693: Can only compare Funcref with Funcref")); 4030 else 4031 EMSG(_("E694: Invalid operation for Funcrefs")); 4032 clear_tv(rettv); 4033 clear_tv(&var2); 4034 return FAIL; 4035 } 4036 else 4037 { 4038 /* Compare two Funcrefs for being equal or unequal. */ 4039 if (rettv->vval.v_string == NULL 4040 || var2.vval.v_string == NULL) 4041 n1 = FALSE; 4042 else 4043 n1 = STRCMP(rettv->vval.v_string, 4044 var2.vval.v_string) == 0; 4045 if (type == TYPE_NEQUAL) 4046 n1 = !n1; 4047 } 4048 } 4049 4050 /* 4051 * If one of the two variables is a number, compare as a number. 4052 * When using "=~" or "!~", always compare as string. 4053 */ 4054 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4055 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4056 { 4057 n1 = get_tv_number(rettv); 4058 n2 = get_tv_number(&var2); 4059 switch (type) 4060 { 4061 case TYPE_EQUAL: n1 = (n1 == n2); break; 4062 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4063 case TYPE_GREATER: n1 = (n1 > n2); break; 4064 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4065 case TYPE_SMALLER: n1 = (n1 < n2); break; 4066 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4067 case TYPE_UNKNOWN: 4068 case TYPE_MATCH: 4069 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4070 } 4071 } 4072 else 4073 { 4074 s1 = get_tv_string_buf(rettv, buf1); 4075 s2 = get_tv_string_buf(&var2, buf2); 4076 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4077 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4078 else 4079 i = 0; 4080 n1 = FALSE; 4081 switch (type) 4082 { 4083 case TYPE_EQUAL: n1 = (i == 0); break; 4084 case TYPE_NEQUAL: n1 = (i != 0); break; 4085 case TYPE_GREATER: n1 = (i > 0); break; 4086 case TYPE_GEQUAL: n1 = (i >= 0); break; 4087 case TYPE_SMALLER: n1 = (i < 0); break; 4088 case TYPE_SEQUAL: n1 = (i <= 0); break; 4089 4090 case TYPE_MATCH: 4091 case TYPE_NOMATCH: 4092 /* avoid 'l' flag in 'cpoptions' */ 4093 save_cpo = p_cpo; 4094 p_cpo = (char_u *)""; 4095 regmatch.regprog = vim_regcomp(s2, 4096 RE_MAGIC + RE_STRING); 4097 regmatch.rm_ic = ic; 4098 if (regmatch.regprog != NULL) 4099 { 4100 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4101 vim_free(regmatch.regprog); 4102 if (type == TYPE_NOMATCH) 4103 n1 = !n1; 4104 } 4105 p_cpo = save_cpo; 4106 break; 4107 4108 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4109 } 4110 } 4111 clear_tv(rettv); 4112 clear_tv(&var2); 4113 rettv->v_type = VAR_NUMBER; 4114 rettv->vval.v_number = n1; 4115 } 4116 } 4117 4118 return OK; 4119 } 4120 4121 /* 4122 * Handle fourth level expression: 4123 * + number addition 4124 * - number subtraction 4125 * . string concatenation 4126 * 4127 * "arg" must point to the first non-white of the expression. 4128 * "arg" is advanced to the next non-white after the recognized expression. 4129 * 4130 * Return OK or FAIL. 4131 */ 4132 static int 4133 eval5(arg, rettv, evaluate) 4134 char_u **arg; 4135 typval_T *rettv; 4136 int evaluate; 4137 { 4138 typval_T var2; 4139 typval_T var3; 4140 int op; 4141 long n1, n2; 4142 char_u *s1, *s2; 4143 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4144 char_u *p; 4145 4146 /* 4147 * Get the first variable. 4148 */ 4149 if (eval6(arg, rettv, evaluate) == FAIL) 4150 return FAIL; 4151 4152 /* 4153 * Repeat computing, until no '+', '-' or '.' is following. 4154 */ 4155 for (;;) 4156 { 4157 op = **arg; 4158 if (op != '+' && op != '-' && op != '.') 4159 break; 4160 4161 if (op != '+' || rettv->v_type != VAR_LIST) 4162 { 4163 /* For "list + ...", an illegal use of the first operand as 4164 * a number cannot be determined before evaluating the 2nd 4165 * operand: if this is also a list, all is ok. 4166 * For "something . ...", "something - ..." or "non-list + ...", 4167 * we know that the first operand needs to be a string or number 4168 * without evaluating the 2nd operand. So check before to avoid 4169 * side effects after an error. */ 4170 if (evaluate && get_tv_string_chk(rettv) == NULL) 4171 { 4172 clear_tv(rettv); 4173 return FAIL; 4174 } 4175 } 4176 4177 /* 4178 * Get the second variable. 4179 */ 4180 *arg = skipwhite(*arg + 1); 4181 if (eval6(arg, &var2, evaluate) == FAIL) 4182 { 4183 clear_tv(rettv); 4184 return FAIL; 4185 } 4186 4187 if (evaluate) 4188 { 4189 /* 4190 * Compute the result. 4191 */ 4192 if (op == '.') 4193 { 4194 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4195 s2 = get_tv_string_buf_chk(&var2, buf2); 4196 if (s2 == NULL) /* type error ? */ 4197 { 4198 clear_tv(rettv); 4199 clear_tv(&var2); 4200 return FAIL; 4201 } 4202 p = concat_str(s1, s2); 4203 clear_tv(rettv); 4204 rettv->v_type = VAR_STRING; 4205 rettv->vval.v_string = p; 4206 } 4207 else if (op == '+' && rettv->v_type == VAR_LIST 4208 && var2.v_type == VAR_LIST) 4209 { 4210 /* concatenate Lists */ 4211 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4212 &var3) == FAIL) 4213 { 4214 clear_tv(rettv); 4215 clear_tv(&var2); 4216 return FAIL; 4217 } 4218 clear_tv(rettv); 4219 *rettv = var3; 4220 } 4221 else 4222 { 4223 int error = FALSE; 4224 4225 n1 = get_tv_number_chk(rettv, &error); 4226 if (error) 4227 { 4228 /* This can only happen for "list + non-list". 4229 * For "non-list + ..." or "something - ...", we returned 4230 * before evaluating the 2nd operand. */ 4231 clear_tv(rettv); 4232 return FAIL; 4233 } 4234 n2 = get_tv_number_chk(&var2, &error); 4235 if (error) 4236 { 4237 clear_tv(rettv); 4238 clear_tv(&var2); 4239 return FAIL; 4240 } 4241 clear_tv(rettv); 4242 if (op == '+') 4243 n1 = n1 + n2; 4244 else 4245 n1 = n1 - n2; 4246 rettv->v_type = VAR_NUMBER; 4247 rettv->vval.v_number = n1; 4248 } 4249 clear_tv(&var2); 4250 } 4251 } 4252 return OK; 4253 } 4254 4255 /* 4256 * Handle fifth level expression: 4257 * * number multiplication 4258 * / number division 4259 * % number modulo 4260 * 4261 * "arg" must point to the first non-white of the expression. 4262 * "arg" is advanced to the next non-white after the recognized expression. 4263 * 4264 * Return OK or FAIL. 4265 */ 4266 static int 4267 eval6(arg, rettv, evaluate) 4268 char_u **arg; 4269 typval_T *rettv; 4270 int evaluate; 4271 { 4272 typval_T var2; 4273 int op; 4274 long n1, n2; 4275 int error = FALSE; 4276 4277 /* 4278 * Get the first variable. 4279 */ 4280 if (eval7(arg, rettv, evaluate) == FAIL) 4281 return FAIL; 4282 4283 /* 4284 * Repeat computing, until no '*', '/' or '%' is following. 4285 */ 4286 for (;;) 4287 { 4288 op = **arg; 4289 if (op != '*' && op != '/' && op != '%') 4290 break; 4291 4292 if (evaluate) 4293 { 4294 n1 = get_tv_number_chk(rettv, &error); 4295 clear_tv(rettv); 4296 if (error) 4297 return FAIL; 4298 } 4299 else 4300 n1 = 0; 4301 4302 /* 4303 * Get the second variable. 4304 */ 4305 *arg = skipwhite(*arg + 1); 4306 if (eval7(arg, &var2, evaluate) == FAIL) 4307 return FAIL; 4308 4309 if (evaluate) 4310 { 4311 n2 = get_tv_number_chk(&var2, &error); 4312 clear_tv(&var2); 4313 if (error) 4314 return FAIL; 4315 4316 /* 4317 * Compute the result. 4318 */ 4319 if (op == '*') 4320 n1 = n1 * n2; 4321 else if (op == '/') 4322 { 4323 if (n2 == 0) /* give an error message? */ 4324 n1 = 0x7fffffffL; 4325 else 4326 n1 = n1 / n2; 4327 } 4328 else 4329 { 4330 if (n2 == 0) /* give an error message? */ 4331 n1 = 0; 4332 else 4333 n1 = n1 % n2; 4334 } 4335 rettv->v_type = VAR_NUMBER; 4336 rettv->vval.v_number = n1; 4337 } 4338 } 4339 4340 return OK; 4341 } 4342 4343 /* 4344 * Handle sixth level expression: 4345 * number number constant 4346 * "string" string contstant 4347 * 'string' literal string contstant 4348 * &option-name option value 4349 * @r register contents 4350 * identifier variable value 4351 * function() function call 4352 * $VAR environment variable 4353 * (expression) nested expression 4354 * [expr, expr] List 4355 * {key: val, key: val} Dictionary 4356 * 4357 * Also handle: 4358 * ! in front logical NOT 4359 * - in front unary minus 4360 * + in front unary plus (ignored) 4361 * trailing [] subscript in String or List 4362 * trailing .name entry in Dictionary 4363 * 4364 * "arg" must point to the first non-white of the expression. 4365 * "arg" is advanced to the next non-white after the recognized expression. 4366 * 4367 * Return OK or FAIL. 4368 */ 4369 static int 4370 eval7(arg, rettv, evaluate) 4371 char_u **arg; 4372 typval_T *rettv; 4373 int evaluate; 4374 { 4375 long n; 4376 int len; 4377 char_u *s; 4378 int val; 4379 char_u *start_leader, *end_leader; 4380 int ret = OK; 4381 char_u *alias; 4382 4383 /* 4384 * Initialise variable so that clear_tv() can't mistake this for a 4385 * string and free a string that isn't there. 4386 */ 4387 rettv->v_type = VAR_UNKNOWN; 4388 4389 /* 4390 * Skip '!' and '-' characters. They are handled later. 4391 */ 4392 start_leader = *arg; 4393 while (**arg == '!' || **arg == '-' || **arg == '+') 4394 *arg = skipwhite(*arg + 1); 4395 end_leader = *arg; 4396 4397 switch (**arg) 4398 { 4399 /* 4400 * Number constant. 4401 */ 4402 case '0': 4403 case '1': 4404 case '2': 4405 case '3': 4406 case '4': 4407 case '5': 4408 case '6': 4409 case '7': 4410 case '8': 4411 case '9': 4412 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4413 *arg += len; 4414 if (evaluate) 4415 { 4416 rettv->v_type = VAR_NUMBER; 4417 rettv->vval.v_number = n; 4418 } 4419 break; 4420 4421 /* 4422 * String constant: "string". 4423 */ 4424 case '"': ret = get_string_tv(arg, rettv, evaluate); 4425 break; 4426 4427 /* 4428 * Literal string constant: 'str''ing'. 4429 */ 4430 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4431 break; 4432 4433 /* 4434 * List: [expr, expr] 4435 */ 4436 case '[': ret = get_list_tv(arg, rettv, evaluate); 4437 break; 4438 4439 /* 4440 * Dictionary: {key: val, key: val} 4441 */ 4442 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4443 break; 4444 4445 /* 4446 * Option value: &name 4447 */ 4448 case '&': ret = get_option_tv(arg, rettv, evaluate); 4449 break; 4450 4451 /* 4452 * Environment variable: $VAR. 4453 */ 4454 case '$': ret = get_env_tv(arg, rettv, evaluate); 4455 break; 4456 4457 /* 4458 * Register contents: @r. 4459 */ 4460 case '@': ++*arg; 4461 if (evaluate) 4462 { 4463 rettv->v_type = VAR_STRING; 4464 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4465 } 4466 if (**arg != NUL) 4467 ++*arg; 4468 break; 4469 4470 /* 4471 * nested expression: (expression). 4472 */ 4473 case '(': *arg = skipwhite(*arg + 1); 4474 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4475 if (**arg == ')') 4476 ++*arg; 4477 else if (ret == OK) 4478 { 4479 EMSG(_("E110: Missing ')'")); 4480 clear_tv(rettv); 4481 ret = FAIL; 4482 } 4483 break; 4484 4485 default: ret = NOTDONE; 4486 break; 4487 } 4488 4489 if (ret == NOTDONE) 4490 { 4491 /* 4492 * Must be a variable or function name. 4493 * Can also be a curly-braces kind of name: {expr}. 4494 */ 4495 s = *arg; 4496 len = get_name_len(arg, &alias, evaluate, TRUE); 4497 if (alias != NULL) 4498 s = alias; 4499 4500 if (len <= 0) 4501 ret = FAIL; 4502 else 4503 { 4504 if (**arg == '(') /* recursive! */ 4505 { 4506 /* If "s" is the name of a variable of type VAR_FUNC 4507 * use its contents. */ 4508 s = deref_func_name(s, &len); 4509 4510 /* Invoke the function. */ 4511 ret = get_func_tv(s, len, rettv, arg, 4512 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4513 &len, evaluate, NULL); 4514 /* Stop the expression evaluation when immediately 4515 * aborting on error, or when an interrupt occurred or 4516 * an exception was thrown but not caught. */ 4517 if (aborting()) 4518 { 4519 if (ret == OK) 4520 clear_tv(rettv); 4521 ret = FAIL; 4522 } 4523 } 4524 else if (evaluate) 4525 ret = get_var_tv(s, len, rettv, TRUE); 4526 else 4527 ret = OK; 4528 } 4529 4530 if (alias != NULL) 4531 vim_free(alias); 4532 } 4533 4534 *arg = skipwhite(*arg); 4535 4536 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4537 * expr(expr). */ 4538 if (ret == OK) 4539 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4540 4541 /* 4542 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4543 */ 4544 if (ret == OK && evaluate && end_leader > start_leader) 4545 { 4546 int error = FALSE; 4547 4548 val = get_tv_number_chk(rettv, &error); 4549 if (error) 4550 { 4551 clear_tv(rettv); 4552 ret = FAIL; 4553 } 4554 else 4555 { 4556 while (end_leader > start_leader) 4557 { 4558 --end_leader; 4559 if (*end_leader == '!') 4560 val = !val; 4561 else if (*end_leader == '-') 4562 val = -val; 4563 } 4564 clear_tv(rettv); 4565 rettv->v_type = VAR_NUMBER; 4566 rettv->vval.v_number = val; 4567 } 4568 } 4569 4570 return ret; 4571 } 4572 4573 /* 4574 * Evaluate an "[expr]" or "[expr:expr]" index. 4575 * "*arg" points to the '['. 4576 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4577 */ 4578 static int 4579 eval_index(arg, rettv, evaluate, verbose) 4580 char_u **arg; 4581 typval_T *rettv; 4582 int evaluate; 4583 int verbose; /* give error messages */ 4584 { 4585 int empty1 = FALSE, empty2 = FALSE; 4586 typval_T var1, var2; 4587 long n1, n2 = 0; 4588 long len = -1; 4589 int range = FALSE; 4590 char_u *s; 4591 char_u *key = NULL; 4592 4593 if (rettv->v_type == VAR_FUNC) 4594 { 4595 if (verbose) 4596 EMSG(_("E695: Cannot index a Funcref")); 4597 return FAIL; 4598 } 4599 4600 if (**arg == '.') 4601 { 4602 /* 4603 * dict.name 4604 */ 4605 key = *arg + 1; 4606 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4607 ; 4608 if (len == 0) 4609 return FAIL; 4610 *arg = skipwhite(key + len); 4611 } 4612 else 4613 { 4614 /* 4615 * something[idx] 4616 * 4617 * Get the (first) variable from inside the []. 4618 */ 4619 *arg = skipwhite(*arg + 1); 4620 if (**arg == ':') 4621 empty1 = TRUE; 4622 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4623 return FAIL; 4624 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4625 { 4626 /* not a number or string */ 4627 clear_tv(&var1); 4628 return FAIL; 4629 } 4630 4631 /* 4632 * Get the second variable from inside the [:]. 4633 */ 4634 if (**arg == ':') 4635 { 4636 range = TRUE; 4637 *arg = skipwhite(*arg + 1); 4638 if (**arg == ']') 4639 empty2 = TRUE; 4640 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4641 { 4642 if (!empty1) 4643 clear_tv(&var1); 4644 return FAIL; 4645 } 4646 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4647 { 4648 /* not a number or string */ 4649 if (!empty1) 4650 clear_tv(&var1); 4651 clear_tv(&var2); 4652 return FAIL; 4653 } 4654 } 4655 4656 /* Check for the ']'. */ 4657 if (**arg != ']') 4658 { 4659 if (verbose) 4660 EMSG(_(e_missbrac)); 4661 clear_tv(&var1); 4662 if (range) 4663 clear_tv(&var2); 4664 return FAIL; 4665 } 4666 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4667 } 4668 4669 if (evaluate) 4670 { 4671 n1 = 0; 4672 if (!empty1 && rettv->v_type != VAR_DICT) 4673 { 4674 n1 = get_tv_number(&var1); 4675 clear_tv(&var1); 4676 } 4677 if (range) 4678 { 4679 if (empty2) 4680 n2 = -1; 4681 else 4682 { 4683 n2 = get_tv_number(&var2); 4684 clear_tv(&var2); 4685 } 4686 } 4687 4688 switch (rettv->v_type) 4689 { 4690 case VAR_NUMBER: 4691 case VAR_STRING: 4692 s = get_tv_string(rettv); 4693 len = (long)STRLEN(s); 4694 if (range) 4695 { 4696 /* The resulting variable is a substring. If the indexes 4697 * are out of range the result is empty. */ 4698 if (n1 < 0) 4699 { 4700 n1 = len + n1; 4701 if (n1 < 0) 4702 n1 = 0; 4703 } 4704 if (n2 < 0) 4705 n2 = len + n2; 4706 else if (n2 >= len) 4707 n2 = len; 4708 if (n1 >= len || n2 < 0 || n1 > n2) 4709 s = NULL; 4710 else 4711 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4712 } 4713 else 4714 { 4715 /* The resulting variable is a string of a single 4716 * character. If the index is too big or negative the 4717 * result is empty. */ 4718 if (n1 >= len || n1 < 0) 4719 s = NULL; 4720 else 4721 s = vim_strnsave(s + n1, 1); 4722 } 4723 clear_tv(rettv); 4724 rettv->v_type = VAR_STRING; 4725 rettv->vval.v_string = s; 4726 break; 4727 4728 case VAR_LIST: 4729 len = list_len(rettv->vval.v_list); 4730 if (n1 < 0) 4731 n1 = len + n1; 4732 if (!empty1 && (n1 < 0 || n1 >= len)) 4733 { 4734 if (verbose) 4735 EMSGN(_(e_listidx), n1); 4736 return FAIL; 4737 } 4738 if (range) 4739 { 4740 list_T *l; 4741 listitem_T *item; 4742 4743 if (n2 < 0) 4744 n2 = len + n2; 4745 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4746 { 4747 if (verbose) 4748 EMSGN(_(e_listidx), n2); 4749 return FAIL; 4750 } 4751 l = list_alloc(); 4752 if (l == NULL) 4753 return FAIL; 4754 for (item = list_find(rettv->vval.v_list, n1); 4755 n1 <= n2; ++n1) 4756 { 4757 if (list_append_tv(l, &item->li_tv) == FAIL) 4758 { 4759 list_free(l); 4760 return FAIL; 4761 } 4762 item = item->li_next; 4763 } 4764 clear_tv(rettv); 4765 rettv->v_type = VAR_LIST; 4766 rettv->vval.v_list = l; 4767 ++l->lv_refcount; 4768 } 4769 else 4770 { 4771 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4772 &var1); 4773 clear_tv(rettv); 4774 *rettv = var1; 4775 } 4776 break; 4777 4778 case VAR_DICT: 4779 if (range) 4780 { 4781 if (verbose) 4782 EMSG(_(e_dictrange)); 4783 if (len == -1) 4784 clear_tv(&var1); 4785 return FAIL; 4786 } 4787 { 4788 dictitem_T *item; 4789 4790 if (len == -1) 4791 { 4792 key = get_tv_string(&var1); 4793 if (*key == NUL) 4794 { 4795 if (verbose) 4796 EMSG(_(e_emptykey)); 4797 clear_tv(&var1); 4798 return FAIL; 4799 } 4800 } 4801 4802 item = dict_find(rettv->vval.v_dict, key, (int)len); 4803 4804 if (item == NULL && verbose) 4805 EMSG2(_(e_dictkey), key); 4806 if (len == -1) 4807 clear_tv(&var1); 4808 if (item == NULL) 4809 return FAIL; 4810 4811 copy_tv(&item->di_tv, &var1); 4812 clear_tv(rettv); 4813 *rettv = var1; 4814 } 4815 break; 4816 } 4817 } 4818 4819 return OK; 4820 } 4821 4822 /* 4823 * Get an option value. 4824 * "arg" points to the '&' or '+' before the option name. 4825 * "arg" is advanced to character after the option name. 4826 * Return OK or FAIL. 4827 */ 4828 static int 4829 get_option_tv(arg, rettv, evaluate) 4830 char_u **arg; 4831 typval_T *rettv; /* when NULL, only check if option exists */ 4832 int evaluate; 4833 { 4834 char_u *option_end; 4835 long numval; 4836 char_u *stringval; 4837 int opt_type; 4838 int c; 4839 int working = (**arg == '+'); /* has("+option") */ 4840 int ret = OK; 4841 int opt_flags; 4842 4843 /* 4844 * Isolate the option name and find its value. 4845 */ 4846 option_end = find_option_end(arg, &opt_flags); 4847 if (option_end == NULL) 4848 { 4849 if (rettv != NULL) 4850 EMSG2(_("E112: Option name missing: %s"), *arg); 4851 return FAIL; 4852 } 4853 4854 if (!evaluate) 4855 { 4856 *arg = option_end; 4857 return OK; 4858 } 4859 4860 c = *option_end; 4861 *option_end = NUL; 4862 opt_type = get_option_value(*arg, &numval, 4863 rettv == NULL ? NULL : &stringval, opt_flags); 4864 4865 if (opt_type == -3) /* invalid name */ 4866 { 4867 if (rettv != NULL) 4868 EMSG2(_("E113: Unknown option: %s"), *arg); 4869 ret = FAIL; 4870 } 4871 else if (rettv != NULL) 4872 { 4873 if (opt_type == -2) /* hidden string option */ 4874 { 4875 rettv->v_type = VAR_STRING; 4876 rettv->vval.v_string = NULL; 4877 } 4878 else if (opt_type == -1) /* hidden number option */ 4879 { 4880 rettv->v_type = VAR_NUMBER; 4881 rettv->vval.v_number = 0; 4882 } 4883 else if (opt_type == 1) /* number option */ 4884 { 4885 rettv->v_type = VAR_NUMBER; 4886 rettv->vval.v_number = numval; 4887 } 4888 else /* string option */ 4889 { 4890 rettv->v_type = VAR_STRING; 4891 rettv->vval.v_string = stringval; 4892 } 4893 } 4894 else if (working && (opt_type == -2 || opt_type == -1)) 4895 ret = FAIL; 4896 4897 *option_end = c; /* put back for error messages */ 4898 *arg = option_end; 4899 4900 return ret; 4901 } 4902 4903 /* 4904 * Allocate a variable for a string constant. 4905 * Return OK or FAIL. 4906 */ 4907 static int 4908 get_string_tv(arg, rettv, evaluate) 4909 char_u **arg; 4910 typval_T *rettv; 4911 int evaluate; 4912 { 4913 char_u *p; 4914 char_u *name; 4915 int extra = 0; 4916 4917 /* 4918 * Find the end of the string, skipping backslashed characters. 4919 */ 4920 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4921 { 4922 if (*p == '\\' && p[1] != NUL) 4923 { 4924 ++p; 4925 /* A "\<x>" form occupies at least 4 characters, and produces up 4926 * to 6 characters: reserve space for 2 extra */ 4927 if (*p == '<') 4928 extra += 2; 4929 } 4930 } 4931 4932 if (*p != '"') 4933 { 4934 EMSG2(_("E114: Missing quote: %s"), *arg); 4935 return FAIL; 4936 } 4937 4938 /* If only parsing, set *arg and return here */ 4939 if (!evaluate) 4940 { 4941 *arg = p + 1; 4942 return OK; 4943 } 4944 4945 /* 4946 * Copy the string into allocated memory, handling backslashed 4947 * characters. 4948 */ 4949 name = alloc((unsigned)(p - *arg + extra)); 4950 if (name == NULL) 4951 return FAIL; 4952 rettv->v_type = VAR_STRING; 4953 rettv->vval.v_string = name; 4954 4955 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4956 { 4957 if (*p == '\\') 4958 { 4959 switch (*++p) 4960 { 4961 case 'b': *name++ = BS; ++p; break; 4962 case 'e': *name++ = ESC; ++p; break; 4963 case 'f': *name++ = FF; ++p; break; 4964 case 'n': *name++ = NL; ++p; break; 4965 case 'r': *name++ = CAR; ++p; break; 4966 case 't': *name++ = TAB; ++p; break; 4967 4968 case 'X': /* hex: "\x1", "\x12" */ 4969 case 'x': 4970 case 'u': /* Unicode: "\u0023" */ 4971 case 'U': 4972 if (vim_isxdigit(p[1])) 4973 { 4974 int n, nr; 4975 int c = toupper(*p); 4976 4977 if (c == 'X') 4978 n = 2; 4979 else 4980 n = 4; 4981 nr = 0; 4982 while (--n >= 0 && vim_isxdigit(p[1])) 4983 { 4984 ++p; 4985 nr = (nr << 4) + hex2nr(*p); 4986 } 4987 ++p; 4988 #ifdef FEAT_MBYTE 4989 /* For "\u" store the number according to 4990 * 'encoding'. */ 4991 if (c != 'X') 4992 name += (*mb_char2bytes)(nr, name); 4993 else 4994 #endif 4995 *name++ = nr; 4996 } 4997 break; 4998 4999 /* octal: "\1", "\12", "\123" */ 5000 case '0': 5001 case '1': 5002 case '2': 5003 case '3': 5004 case '4': 5005 case '5': 5006 case '6': 5007 case '7': *name = *p++ - '0'; 5008 if (*p >= '0' && *p <= '7') 5009 { 5010 *name = (*name << 3) + *p++ - '0'; 5011 if (*p >= '0' && *p <= '7') 5012 *name = (*name << 3) + *p++ - '0'; 5013 } 5014 ++name; 5015 break; 5016 5017 /* Special key, e.g.: "\<C-W>" */ 5018 case '<': extra = trans_special(&p, name, TRUE); 5019 if (extra != 0) 5020 { 5021 name += extra; 5022 break; 5023 } 5024 /* FALLTHROUGH */ 5025 5026 default: MB_COPY_CHAR(p, name); 5027 break; 5028 } 5029 } 5030 else 5031 MB_COPY_CHAR(p, name); 5032 5033 } 5034 *name = NUL; 5035 *arg = p + 1; 5036 5037 return OK; 5038 } 5039 5040 /* 5041 * Allocate a variable for a 'str''ing' constant. 5042 * Return OK or FAIL. 5043 */ 5044 static int 5045 get_lit_string_tv(arg, rettv, evaluate) 5046 char_u **arg; 5047 typval_T *rettv; 5048 int evaluate; 5049 { 5050 char_u *p; 5051 char_u *str; 5052 int reduce = 0; 5053 5054 /* 5055 * Find the end of the string, skipping ''. 5056 */ 5057 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5058 { 5059 if (*p == '\'') 5060 { 5061 if (p[1] != '\'') 5062 break; 5063 ++reduce; 5064 ++p; 5065 } 5066 } 5067 5068 if (*p != '\'') 5069 { 5070 EMSG2(_("E115: Missing quote: %s"), *arg); 5071 return FAIL; 5072 } 5073 5074 /* If only parsing return after setting "*arg" */ 5075 if (!evaluate) 5076 { 5077 *arg = p + 1; 5078 return OK; 5079 } 5080 5081 /* 5082 * Copy the string into allocated memory, handling '' to ' reduction. 5083 */ 5084 str = alloc((unsigned)((p - *arg) - reduce)); 5085 if (str == NULL) 5086 return FAIL; 5087 rettv->v_type = VAR_STRING; 5088 rettv->vval.v_string = str; 5089 5090 for (p = *arg + 1; *p != NUL; ) 5091 { 5092 if (*p == '\'') 5093 { 5094 if (p[1] != '\'') 5095 break; 5096 ++p; 5097 } 5098 MB_COPY_CHAR(p, str); 5099 } 5100 *str = NUL; 5101 *arg = p + 1; 5102 5103 return OK; 5104 } 5105 5106 /* 5107 * Allocate a variable for a List and fill it from "*arg". 5108 * Return OK or FAIL. 5109 */ 5110 static int 5111 get_list_tv(arg, rettv, evaluate) 5112 char_u **arg; 5113 typval_T *rettv; 5114 int evaluate; 5115 { 5116 list_T *l = NULL; 5117 typval_T tv; 5118 listitem_T *item; 5119 5120 if (evaluate) 5121 { 5122 l = list_alloc(); 5123 if (l == NULL) 5124 return FAIL; 5125 } 5126 5127 *arg = skipwhite(*arg + 1); 5128 while (**arg != ']' && **arg != NUL) 5129 { 5130 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5131 goto failret; 5132 if (evaluate) 5133 { 5134 item = listitem_alloc(); 5135 if (item != NULL) 5136 { 5137 item->li_tv = tv; 5138 item->li_tv.v_lock = 0; 5139 list_append(l, item); 5140 } 5141 else 5142 clear_tv(&tv); 5143 } 5144 5145 if (**arg == ']') 5146 break; 5147 if (**arg != ',') 5148 { 5149 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5150 goto failret; 5151 } 5152 *arg = skipwhite(*arg + 1); 5153 } 5154 5155 if (**arg != ']') 5156 { 5157 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5158 failret: 5159 if (evaluate) 5160 list_free(l); 5161 return FAIL; 5162 } 5163 5164 *arg = skipwhite(*arg + 1); 5165 if (evaluate) 5166 { 5167 rettv->v_type = VAR_LIST; 5168 rettv->vval.v_list = l; 5169 ++l->lv_refcount; 5170 } 5171 5172 return OK; 5173 } 5174 5175 /* 5176 * Allocate an empty header for a list. 5177 */ 5178 static list_T * 5179 list_alloc() 5180 { 5181 list_T *l; 5182 5183 l = (list_T *)alloc_clear(sizeof(list_T)); 5184 if (l != NULL) 5185 { 5186 /* Prepend the list to the list of lists for garbage collection. */ 5187 if (first_list != NULL) 5188 first_list->lv_used_prev = l; 5189 l->lv_used_prev = NULL; 5190 l->lv_used_next = first_list; 5191 first_list = l; 5192 } 5193 return l; 5194 } 5195 5196 /* 5197 * Unreference a list: decrement the reference count and free it when it 5198 * becomes zero. 5199 */ 5200 void 5201 list_unref(l) 5202 list_T *l; 5203 { 5204 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5205 list_free(l); 5206 } 5207 5208 /* 5209 * Free a list, including all items it points to. 5210 * Ignores the reference count. 5211 */ 5212 static void 5213 list_free(l) 5214 list_T *l; 5215 { 5216 listitem_T *item; 5217 5218 /* Avoid that recursive reference to the list frees us again. */ 5219 l->lv_refcount = DEL_REFCOUNT; 5220 5221 /* Remove the list from the list of lists for garbage collection. */ 5222 if (l->lv_used_prev == NULL) 5223 first_list = l->lv_used_next; 5224 else 5225 l->lv_used_prev->lv_used_next = l->lv_used_next; 5226 if (l->lv_used_next != NULL) 5227 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5228 5229 for (item = l->lv_first; item != NULL; item = l->lv_first) 5230 { 5231 /* Remove the item before deleting it. */ 5232 l->lv_first = item->li_next; 5233 listitem_free(item); 5234 } 5235 vim_free(l); 5236 } 5237 5238 /* 5239 * Allocate a list item. 5240 */ 5241 static listitem_T * 5242 listitem_alloc() 5243 { 5244 return (listitem_T *)alloc(sizeof(listitem_T)); 5245 } 5246 5247 /* 5248 * Free a list item. Also clears the value. Does not notify watchers. 5249 */ 5250 static void 5251 listitem_free(item) 5252 listitem_T *item; 5253 { 5254 clear_tv(&item->li_tv); 5255 vim_free(item); 5256 } 5257 5258 /* 5259 * Remove a list item from a List and free it. Also clears the value. 5260 */ 5261 static void 5262 listitem_remove(l, item) 5263 list_T *l; 5264 listitem_T *item; 5265 { 5266 list_remove(l, item, item); 5267 listitem_free(item); 5268 } 5269 5270 /* 5271 * Get the number of items in a list. 5272 */ 5273 static long 5274 list_len(l) 5275 list_T *l; 5276 { 5277 if (l == NULL) 5278 return 0L; 5279 return l->lv_len; 5280 } 5281 5282 /* 5283 * Return TRUE when two lists have exactly the same values. 5284 */ 5285 static int 5286 list_equal(l1, l2, ic) 5287 list_T *l1; 5288 list_T *l2; 5289 int ic; /* ignore case for strings */ 5290 { 5291 listitem_T *item1, *item2; 5292 5293 if (list_len(l1) != list_len(l2)) 5294 return FALSE; 5295 5296 for (item1 = l1->lv_first, item2 = l2->lv_first; 5297 item1 != NULL && item2 != NULL; 5298 item1 = item1->li_next, item2 = item2->li_next) 5299 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5300 return FALSE; 5301 return item1 == NULL && item2 == NULL; 5302 } 5303 5304 /* 5305 * Return TRUE when two dictionaries have exactly the same key/values. 5306 */ 5307 static int 5308 dict_equal(d1, d2, ic) 5309 dict_T *d1; 5310 dict_T *d2; 5311 int ic; /* ignore case for strings */ 5312 { 5313 hashitem_T *hi; 5314 dictitem_T *item2; 5315 int todo; 5316 5317 if (dict_len(d1) != dict_len(d2)) 5318 return FALSE; 5319 5320 todo = d1->dv_hashtab.ht_used; 5321 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5322 { 5323 if (!HASHITEM_EMPTY(hi)) 5324 { 5325 item2 = dict_find(d2, hi->hi_key, -1); 5326 if (item2 == NULL) 5327 return FALSE; 5328 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5329 return FALSE; 5330 --todo; 5331 } 5332 } 5333 return TRUE; 5334 } 5335 5336 /* 5337 * Return TRUE if "tv1" and "tv2" have the same value. 5338 * Compares the items just like "==" would compare them, but strings and 5339 * numbers are different. 5340 */ 5341 static int 5342 tv_equal(tv1, tv2, ic) 5343 typval_T *tv1; 5344 typval_T *tv2; 5345 int ic; /* ignore case */ 5346 { 5347 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5348 char_u *s1, *s2; 5349 5350 if (tv1->v_type != tv2->v_type) 5351 return FALSE; 5352 5353 switch (tv1->v_type) 5354 { 5355 case VAR_LIST: 5356 /* recursive! */ 5357 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5358 5359 case VAR_DICT: 5360 /* recursive! */ 5361 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5362 5363 case VAR_FUNC: 5364 return (tv1->vval.v_string != NULL 5365 && tv2->vval.v_string != NULL 5366 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5367 5368 case VAR_NUMBER: 5369 return tv1->vval.v_number == tv2->vval.v_number; 5370 5371 case VAR_STRING: 5372 s1 = get_tv_string_buf(tv1, buf1); 5373 s2 = get_tv_string_buf(tv2, buf2); 5374 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5375 } 5376 5377 EMSG2(_(e_intern2), "tv_equal()"); 5378 return TRUE; 5379 } 5380 5381 /* 5382 * Locate item with index "n" in list "l" and return it. 5383 * A negative index is counted from the end; -1 is the last item. 5384 * Returns NULL when "n" is out of range. 5385 */ 5386 static listitem_T * 5387 list_find(l, n) 5388 list_T *l; 5389 long n; 5390 { 5391 listitem_T *item; 5392 long idx; 5393 5394 if (l == NULL) 5395 return NULL; 5396 5397 /* Negative index is relative to the end. */ 5398 if (n < 0) 5399 n = l->lv_len + n; 5400 5401 /* Check for index out of range. */ 5402 if (n < 0 || n >= l->lv_len) 5403 return NULL; 5404 5405 /* When there is a cached index may start search from there. */ 5406 if (l->lv_idx_item != NULL) 5407 { 5408 if (n < l->lv_idx / 2) 5409 { 5410 /* closest to the start of the list */ 5411 item = l->lv_first; 5412 idx = 0; 5413 } 5414 else if (n > (l->lv_idx + l->lv_len) / 2) 5415 { 5416 /* closest to the end of the list */ 5417 item = l->lv_last; 5418 idx = l->lv_len - 1; 5419 } 5420 else 5421 { 5422 /* closest to the cached index */ 5423 item = l->lv_idx_item; 5424 idx = l->lv_idx; 5425 } 5426 } 5427 else 5428 { 5429 if (n < l->lv_len / 2) 5430 { 5431 /* closest to the start of the list */ 5432 item = l->lv_first; 5433 idx = 0; 5434 } 5435 else 5436 { 5437 /* closest to the end of the list */ 5438 item = l->lv_last; 5439 idx = l->lv_len - 1; 5440 } 5441 } 5442 5443 while (n > idx) 5444 { 5445 /* search forward */ 5446 item = item->li_next; 5447 ++idx; 5448 } 5449 while (n < idx) 5450 { 5451 /* search backward */ 5452 item = item->li_prev; 5453 --idx; 5454 } 5455 5456 /* cache the used index */ 5457 l->lv_idx = idx; 5458 l->lv_idx_item = item; 5459 5460 return item; 5461 } 5462 5463 /* 5464 * Locate "item" list "l" and return its index. 5465 * Returns -1 when "item" is not in the list. 5466 */ 5467 static long 5468 list_idx_of_item(l, item) 5469 list_T *l; 5470 listitem_T *item; 5471 { 5472 long idx = 0; 5473 listitem_T *li; 5474 5475 if (l == NULL) 5476 return -1; 5477 idx = 0; 5478 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5479 ++idx; 5480 if (li == NULL) 5481 return -1; 5482 return idx; 5483 } 5484 5485 /* 5486 * Append item "item" to the end of list "l". 5487 */ 5488 static void 5489 list_append(l, item) 5490 list_T *l; 5491 listitem_T *item; 5492 { 5493 if (l->lv_last == NULL) 5494 { 5495 /* empty list */ 5496 l->lv_first = item; 5497 l->lv_last = item; 5498 item->li_prev = NULL; 5499 } 5500 else 5501 { 5502 l->lv_last->li_next = item; 5503 item->li_prev = l->lv_last; 5504 l->lv_last = item; 5505 } 5506 ++l->lv_len; 5507 item->li_next = NULL; 5508 } 5509 5510 /* 5511 * Append typval_T "tv" to the end of list "l". 5512 * Return FAIL when out of memory. 5513 */ 5514 static int 5515 list_append_tv(l, tv) 5516 list_T *l; 5517 typval_T *tv; 5518 { 5519 listitem_T *li = listitem_alloc(); 5520 5521 if (li == NULL) 5522 return FAIL; 5523 copy_tv(tv, &li->li_tv); 5524 list_append(l, li); 5525 return OK; 5526 } 5527 5528 /* 5529 * Add a dictionary to a list. Used by getqflist(). 5530 * Return FAIL when out of memory. 5531 */ 5532 int 5533 list_append_dict(list, dict) 5534 list_T *list; 5535 dict_T *dict; 5536 { 5537 listitem_T *li = listitem_alloc(); 5538 5539 if (li == NULL) 5540 return FAIL; 5541 li->li_tv.v_type = VAR_DICT; 5542 li->li_tv.v_lock = 0; 5543 li->li_tv.vval.v_dict = dict; 5544 list_append(list, li); 5545 ++dict->dv_refcount; 5546 return OK; 5547 } 5548 5549 /* 5550 * Insert typval_T "tv" in list "l" before "item". 5551 * If "item" is NULL append at the end. 5552 * Return FAIL when out of memory. 5553 */ 5554 static int 5555 list_insert_tv(l, tv, item) 5556 list_T *l; 5557 typval_T *tv; 5558 listitem_T *item; 5559 { 5560 listitem_T *ni = listitem_alloc(); 5561 5562 if (ni == NULL) 5563 return FAIL; 5564 copy_tv(tv, &ni->li_tv); 5565 if (item == NULL) 5566 /* Append new item at end of list. */ 5567 list_append(l, ni); 5568 else 5569 { 5570 /* Insert new item before existing item. */ 5571 ni->li_prev = item->li_prev; 5572 ni->li_next = item; 5573 if (item->li_prev == NULL) 5574 { 5575 l->lv_first = ni; 5576 ++l->lv_idx; 5577 } 5578 else 5579 { 5580 item->li_prev->li_next = ni; 5581 l->lv_idx_item = NULL; 5582 } 5583 item->li_prev = ni; 5584 ++l->lv_len; 5585 } 5586 return OK; 5587 } 5588 5589 /* 5590 * Extend "l1" with "l2". 5591 * If "bef" is NULL append at the end, otherwise insert before this item. 5592 * Returns FAIL when out of memory. 5593 */ 5594 static int 5595 list_extend(l1, l2, bef) 5596 list_T *l1; 5597 list_T *l2; 5598 listitem_T *bef; 5599 { 5600 listitem_T *item; 5601 5602 for (item = l2->lv_first; item != NULL; item = item->li_next) 5603 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5604 return FAIL; 5605 return OK; 5606 } 5607 5608 /* 5609 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5610 * Return FAIL when out of memory. 5611 */ 5612 static int 5613 list_concat(l1, l2, tv) 5614 list_T *l1; 5615 list_T *l2; 5616 typval_T *tv; 5617 { 5618 list_T *l; 5619 5620 /* make a copy of the first list. */ 5621 l = list_copy(l1, FALSE, 0); 5622 if (l == NULL) 5623 return FAIL; 5624 tv->v_type = VAR_LIST; 5625 tv->vval.v_list = l; 5626 5627 /* append all items from the second list */ 5628 return list_extend(l, l2, NULL); 5629 } 5630 5631 /* 5632 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5633 * The refcount of the new list is set to 1. 5634 * See item_copy() for "copyID". 5635 * Returns NULL when out of memory. 5636 */ 5637 static list_T * 5638 list_copy(orig, deep, copyID) 5639 list_T *orig; 5640 int deep; 5641 int copyID; 5642 { 5643 list_T *copy; 5644 listitem_T *item; 5645 listitem_T *ni; 5646 5647 if (orig == NULL) 5648 return NULL; 5649 5650 copy = list_alloc(); 5651 if (copy != NULL) 5652 { 5653 if (copyID != 0) 5654 { 5655 /* Do this before adding the items, because one of the items may 5656 * refer back to this list. */ 5657 orig->lv_copyID = copyID; 5658 orig->lv_copylist = copy; 5659 } 5660 for (item = orig->lv_first; item != NULL && !got_int; 5661 item = item->li_next) 5662 { 5663 ni = listitem_alloc(); 5664 if (ni == NULL) 5665 break; 5666 if (deep) 5667 { 5668 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5669 { 5670 vim_free(ni); 5671 break; 5672 } 5673 } 5674 else 5675 copy_tv(&item->li_tv, &ni->li_tv); 5676 list_append(copy, ni); 5677 } 5678 ++copy->lv_refcount; 5679 if (item != NULL) 5680 { 5681 list_unref(copy); 5682 copy = NULL; 5683 } 5684 } 5685 5686 return copy; 5687 } 5688 5689 /* 5690 * Remove items "item" to "item2" from list "l". 5691 * Does not free the listitem or the value! 5692 */ 5693 static void 5694 list_remove(l, item, item2) 5695 list_T *l; 5696 listitem_T *item; 5697 listitem_T *item2; 5698 { 5699 listitem_T *ip; 5700 5701 /* notify watchers */ 5702 for (ip = item; ip != NULL; ip = ip->li_next) 5703 { 5704 --l->lv_len; 5705 list_fix_watch(l, ip); 5706 if (ip == item2) 5707 break; 5708 } 5709 5710 if (item2->li_next == NULL) 5711 l->lv_last = item->li_prev; 5712 else 5713 item2->li_next->li_prev = item->li_prev; 5714 if (item->li_prev == NULL) 5715 l->lv_first = item2->li_next; 5716 else 5717 item->li_prev->li_next = item2->li_next; 5718 l->lv_idx_item = NULL; 5719 } 5720 5721 /* 5722 * Return an allocated string with the string representation of a list. 5723 * May return NULL. 5724 */ 5725 static char_u * 5726 list2string(tv) 5727 typval_T *tv; 5728 { 5729 garray_T ga; 5730 5731 if (tv->vval.v_list == NULL) 5732 return NULL; 5733 ga_init2(&ga, (int)sizeof(char), 80); 5734 ga_append(&ga, '['); 5735 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5736 { 5737 vim_free(ga.ga_data); 5738 return NULL; 5739 } 5740 ga_append(&ga, ']'); 5741 ga_append(&ga, NUL); 5742 return (char_u *)ga.ga_data; 5743 } 5744 5745 /* 5746 * Join list "l" into a string in "*gap", using separator "sep". 5747 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5748 * Return FAIL or OK. 5749 */ 5750 static int 5751 list_join(gap, l, sep, echo) 5752 garray_T *gap; 5753 list_T *l; 5754 char_u *sep; 5755 int echo; 5756 { 5757 int first = TRUE; 5758 char_u *tofree; 5759 char_u numbuf[NUMBUFLEN]; 5760 listitem_T *item; 5761 char_u *s; 5762 5763 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5764 { 5765 if (first) 5766 first = FALSE; 5767 else 5768 ga_concat(gap, sep); 5769 5770 if (echo) 5771 s = echo_string(&item->li_tv, &tofree, numbuf); 5772 else 5773 s = tv2string(&item->li_tv, &tofree, numbuf); 5774 if (s != NULL) 5775 ga_concat(gap, s); 5776 vim_free(tofree); 5777 if (s == NULL) 5778 return FAIL; 5779 } 5780 return OK; 5781 } 5782 5783 /* 5784 * Garbage collection for lists and dictionaries. 5785 * 5786 * We use reference counts to be able to free most items right away when they 5787 * are no longer used. But for composite items it's possible that it becomes 5788 * unused while the reference count is > 0: When there is a recursive 5789 * reference. Example: 5790 * :let l = [1, 2, 3] 5791 * :let d = {9: l} 5792 * :let l[1] = d 5793 * 5794 * Since this is quite unusual we handle this with garbage collection: every 5795 * once in a while find out which lists and dicts are not referenced from any 5796 * variable. 5797 * 5798 * Here is a good reference text about garbage collection (refers to Python 5799 * but it applies to all reference-counting mechanisms): 5800 * http://python.ca/nas/python/gc/ 5801 */ 5802 5803 /* 5804 * Do garbage collection for lists and dicts. 5805 * Return TRUE if some memory was freed. 5806 */ 5807 int 5808 garbage_collect() 5809 { 5810 dict_T *dd; 5811 list_T *ll; 5812 int copyID = ++current_copyID; 5813 buf_T *buf; 5814 win_T *wp; 5815 int i; 5816 funccall_T *fc; 5817 int did_free = FALSE; 5818 5819 /* 5820 * 1. Go through all accessible variables and mark all lists and dicts 5821 * with copyID. 5822 */ 5823 /* script-local variables */ 5824 for (i = 1; i <= ga_scripts.ga_len; ++i) 5825 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5826 5827 /* buffer-local variables */ 5828 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5829 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5830 5831 /* window-local variables */ 5832 FOR_ALL_WINDOWS(wp) 5833 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5834 5835 /* global variables */ 5836 set_ref_in_ht(&globvarht, copyID); 5837 5838 /* function-local variables */ 5839 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5840 { 5841 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5842 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5843 } 5844 5845 /* 5846 * 2. Go through the list of dicts and free items without the copyID. 5847 */ 5848 for (dd = first_dict; dd != NULL; ) 5849 if (dd->dv_copyID != copyID) 5850 { 5851 dict_free(dd); 5852 did_free = TRUE; 5853 5854 /* restart, next dict may also have been freed */ 5855 dd = first_dict; 5856 } 5857 else 5858 dd = dd->dv_used_next; 5859 5860 /* 5861 * 3. Go through the list of lists and free items without the copyID. 5862 */ 5863 for (ll = first_list; ll != NULL; ) 5864 if (ll->lv_copyID != copyID) 5865 { 5866 list_free(ll); 5867 did_free = TRUE; 5868 5869 /* restart, next dict may also have been freed */ 5870 ll = first_list; 5871 } 5872 else 5873 ll = ll->lv_used_next; 5874 5875 return did_free; 5876 } 5877 5878 /* 5879 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5880 */ 5881 static void 5882 set_ref_in_ht(ht, copyID) 5883 hashtab_T *ht; 5884 int copyID; 5885 { 5886 int todo; 5887 hashitem_T *hi; 5888 5889 todo = ht->ht_used; 5890 for (hi = ht->ht_array; todo > 0; ++hi) 5891 if (!HASHITEM_EMPTY(hi)) 5892 { 5893 --todo; 5894 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5895 } 5896 } 5897 5898 /* 5899 * Mark all lists and dicts referenced through list "l" with "copyID". 5900 */ 5901 static void 5902 set_ref_in_list(l, copyID) 5903 list_T *l; 5904 int copyID; 5905 { 5906 listitem_T *li; 5907 5908 for (li = l->lv_first; li != NULL; li = li->li_next) 5909 set_ref_in_item(&li->li_tv, copyID); 5910 } 5911 5912 /* 5913 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5914 */ 5915 static void 5916 set_ref_in_item(tv, copyID) 5917 typval_T *tv; 5918 int copyID; 5919 { 5920 dict_T *dd; 5921 list_T *ll; 5922 5923 switch (tv->v_type) 5924 { 5925 case VAR_DICT: 5926 dd = tv->vval.v_dict; 5927 if (dd->dv_copyID != copyID) 5928 { 5929 /* Didn't see this dict yet. */ 5930 dd->dv_copyID = copyID; 5931 set_ref_in_ht(&dd->dv_hashtab, copyID); 5932 } 5933 break; 5934 5935 case VAR_LIST: 5936 ll = tv->vval.v_list; 5937 if (ll->lv_copyID != copyID) 5938 { 5939 /* Didn't see this list yet. */ 5940 ll->lv_copyID = copyID; 5941 set_ref_in_list(ll, copyID); 5942 } 5943 break; 5944 } 5945 return; 5946 } 5947 5948 /* 5949 * Allocate an empty header for a dictionary. 5950 */ 5951 dict_T * 5952 dict_alloc() 5953 { 5954 dict_T *d; 5955 5956 d = (dict_T *)alloc(sizeof(dict_T)); 5957 if (d != NULL) 5958 { 5959 /* Add the list to the hashtable for garbage collection. */ 5960 if (first_dict != NULL) 5961 first_dict->dv_used_prev = d; 5962 d->dv_used_next = first_dict; 5963 d->dv_used_prev = NULL; 5964 5965 hash_init(&d->dv_hashtab); 5966 d->dv_lock = 0; 5967 d->dv_refcount = 0; 5968 d->dv_copyID = 0; 5969 } 5970 return d; 5971 } 5972 5973 /* 5974 * Unreference a Dictionary: decrement the reference count and free it when it 5975 * becomes zero. 5976 */ 5977 static void 5978 dict_unref(d) 5979 dict_T *d; 5980 { 5981 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 5982 dict_free(d); 5983 } 5984 5985 /* 5986 * Free a Dictionary, including all items it contains. 5987 * Ignores the reference count. 5988 */ 5989 static void 5990 dict_free(d) 5991 dict_T *d; 5992 { 5993 int todo; 5994 hashitem_T *hi; 5995 dictitem_T *di; 5996 5997 /* Avoid that recursive reference to the dict frees us again. */ 5998 d->dv_refcount = DEL_REFCOUNT; 5999 6000 /* Remove the dict from the list of dicts for garbage collection. */ 6001 if (d->dv_used_prev == NULL) 6002 first_dict = d->dv_used_next; 6003 else 6004 d->dv_used_prev->dv_used_next = d->dv_used_next; 6005 if (d->dv_used_next != NULL) 6006 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6007 6008 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6009 hash_lock(&d->dv_hashtab); 6010 todo = d->dv_hashtab.ht_used; 6011 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6012 { 6013 if (!HASHITEM_EMPTY(hi)) 6014 { 6015 /* Remove the item before deleting it, just in case there is 6016 * something recursive causing trouble. */ 6017 di = HI2DI(hi); 6018 hash_remove(&d->dv_hashtab, hi); 6019 dictitem_free(di); 6020 --todo; 6021 } 6022 } 6023 hash_clear(&d->dv_hashtab); 6024 vim_free(d); 6025 } 6026 6027 /* 6028 * Allocate a Dictionary item. 6029 * The "key" is copied to the new item. 6030 * Note that the value of the item "di_tv" still needs to be initialized! 6031 * Returns NULL when out of memory. 6032 */ 6033 static dictitem_T * 6034 dictitem_alloc(key) 6035 char_u *key; 6036 { 6037 dictitem_T *di; 6038 6039 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6040 if (di != NULL) 6041 { 6042 STRCPY(di->di_key, key); 6043 di->di_flags = 0; 6044 } 6045 return di; 6046 } 6047 6048 /* 6049 * Make a copy of a Dictionary item. 6050 */ 6051 static dictitem_T * 6052 dictitem_copy(org) 6053 dictitem_T *org; 6054 { 6055 dictitem_T *di; 6056 6057 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6058 if (di != NULL) 6059 { 6060 STRCPY(di->di_key, org->di_key); 6061 di->di_flags = 0; 6062 copy_tv(&org->di_tv, &di->di_tv); 6063 } 6064 return di; 6065 } 6066 6067 /* 6068 * Remove item "item" from Dictionary "dict" and free it. 6069 */ 6070 static void 6071 dictitem_remove(dict, item) 6072 dict_T *dict; 6073 dictitem_T *item; 6074 { 6075 hashitem_T *hi; 6076 6077 hi = hash_find(&dict->dv_hashtab, item->di_key); 6078 if (HASHITEM_EMPTY(hi)) 6079 EMSG2(_(e_intern2), "dictitem_remove()"); 6080 else 6081 hash_remove(&dict->dv_hashtab, hi); 6082 dictitem_free(item); 6083 } 6084 6085 /* 6086 * Free a dict item. Also clears the value. 6087 */ 6088 static void 6089 dictitem_free(item) 6090 dictitem_T *item; 6091 { 6092 clear_tv(&item->di_tv); 6093 vim_free(item); 6094 } 6095 6096 /* 6097 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6098 * The refcount of the new dict is set to 1. 6099 * See item_copy() for "copyID". 6100 * Returns NULL when out of memory. 6101 */ 6102 static dict_T * 6103 dict_copy(orig, deep, copyID) 6104 dict_T *orig; 6105 int deep; 6106 int copyID; 6107 { 6108 dict_T *copy; 6109 dictitem_T *di; 6110 int todo; 6111 hashitem_T *hi; 6112 6113 if (orig == NULL) 6114 return NULL; 6115 6116 copy = dict_alloc(); 6117 if (copy != NULL) 6118 { 6119 if (copyID != 0) 6120 { 6121 orig->dv_copyID = copyID; 6122 orig->dv_copydict = copy; 6123 } 6124 todo = orig->dv_hashtab.ht_used; 6125 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6126 { 6127 if (!HASHITEM_EMPTY(hi)) 6128 { 6129 --todo; 6130 6131 di = dictitem_alloc(hi->hi_key); 6132 if (di == NULL) 6133 break; 6134 if (deep) 6135 { 6136 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6137 copyID) == FAIL) 6138 { 6139 vim_free(di); 6140 break; 6141 } 6142 } 6143 else 6144 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6145 if (dict_add(copy, di) == FAIL) 6146 { 6147 dictitem_free(di); 6148 break; 6149 } 6150 } 6151 } 6152 6153 ++copy->dv_refcount; 6154 if (todo > 0) 6155 { 6156 dict_unref(copy); 6157 copy = NULL; 6158 } 6159 } 6160 6161 return copy; 6162 } 6163 6164 /* 6165 * Add item "item" to Dictionary "d". 6166 * Returns FAIL when out of memory and when key already existed. 6167 */ 6168 static int 6169 dict_add(d, item) 6170 dict_T *d; 6171 dictitem_T *item; 6172 { 6173 return hash_add(&d->dv_hashtab, item->di_key); 6174 } 6175 6176 /* 6177 * Add a number or string entry to dictionary "d". 6178 * When "str" is NULL use number "nr", otherwise use "str". 6179 * Returns FAIL when out of memory and when key already exists. 6180 */ 6181 int 6182 dict_add_nr_str(d, key, nr, str) 6183 dict_T *d; 6184 char *key; 6185 long nr; 6186 char_u *str; 6187 { 6188 dictitem_T *item; 6189 6190 item = dictitem_alloc((char_u *)key); 6191 if (item == NULL) 6192 return FAIL; 6193 item->di_tv.v_lock = 0; 6194 if (str == NULL) 6195 { 6196 item->di_tv.v_type = VAR_NUMBER; 6197 item->di_tv.vval.v_number = nr; 6198 } 6199 else 6200 { 6201 item->di_tv.v_type = VAR_STRING; 6202 item->di_tv.vval.v_string = vim_strsave(str); 6203 } 6204 if (dict_add(d, item) == FAIL) 6205 { 6206 dictitem_free(item); 6207 return FAIL; 6208 } 6209 return OK; 6210 } 6211 6212 /* 6213 * Get the number of items in a Dictionary. 6214 */ 6215 static long 6216 dict_len(d) 6217 dict_T *d; 6218 { 6219 if (d == NULL) 6220 return 0L; 6221 return d->dv_hashtab.ht_used; 6222 } 6223 6224 /* 6225 * Find item "key[len]" in Dictionary "d". 6226 * If "len" is negative use strlen(key). 6227 * Returns NULL when not found. 6228 */ 6229 static dictitem_T * 6230 dict_find(d, key, len) 6231 dict_T *d; 6232 char_u *key; 6233 int len; 6234 { 6235 #define AKEYLEN 200 6236 char_u buf[AKEYLEN]; 6237 char_u *akey; 6238 char_u *tofree = NULL; 6239 hashitem_T *hi; 6240 6241 if (len < 0) 6242 akey = key; 6243 else if (len >= AKEYLEN) 6244 { 6245 tofree = akey = vim_strnsave(key, len); 6246 if (akey == NULL) 6247 return NULL; 6248 } 6249 else 6250 { 6251 /* Avoid a malloc/free by using buf[]. */ 6252 vim_strncpy(buf, key, len); 6253 akey = buf; 6254 } 6255 6256 hi = hash_find(&d->dv_hashtab, akey); 6257 vim_free(tofree); 6258 if (HASHITEM_EMPTY(hi)) 6259 return NULL; 6260 return HI2DI(hi); 6261 } 6262 6263 /* 6264 * Get a string item from a dictionary in allocated memory. 6265 * Returns NULL if the entry doesn't exist or out of memory. 6266 */ 6267 char_u * 6268 get_dict_string(d, key) 6269 dict_T *d; 6270 char_u *key; 6271 { 6272 dictitem_T *di; 6273 6274 di = dict_find(d, key, -1); 6275 if (di == NULL) 6276 return NULL; 6277 return vim_strsave(get_tv_string(&di->di_tv)); 6278 } 6279 6280 /* 6281 * Get a number item from a dictionary. 6282 * Returns 0 if the entry doesn't exist or out of memory. 6283 */ 6284 long 6285 get_dict_number(d, key) 6286 dict_T *d; 6287 char_u *key; 6288 { 6289 dictitem_T *di; 6290 6291 di = dict_find(d, key, -1); 6292 if (di == NULL) 6293 return 0; 6294 return get_tv_number(&di->di_tv); 6295 } 6296 6297 /* 6298 * Return an allocated string with the string representation of a Dictionary. 6299 * May return NULL. 6300 */ 6301 static char_u * 6302 dict2string(tv) 6303 typval_T *tv; 6304 { 6305 garray_T ga; 6306 int first = TRUE; 6307 char_u *tofree; 6308 char_u numbuf[NUMBUFLEN]; 6309 hashitem_T *hi; 6310 char_u *s; 6311 dict_T *d; 6312 int todo; 6313 6314 if ((d = tv->vval.v_dict) == NULL) 6315 return NULL; 6316 ga_init2(&ga, (int)sizeof(char), 80); 6317 ga_append(&ga, '{'); 6318 6319 todo = d->dv_hashtab.ht_used; 6320 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6321 { 6322 if (!HASHITEM_EMPTY(hi)) 6323 { 6324 --todo; 6325 6326 if (first) 6327 first = FALSE; 6328 else 6329 ga_concat(&ga, (char_u *)", "); 6330 6331 tofree = string_quote(hi->hi_key, FALSE); 6332 if (tofree != NULL) 6333 { 6334 ga_concat(&ga, tofree); 6335 vim_free(tofree); 6336 } 6337 ga_concat(&ga, (char_u *)": "); 6338 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6339 if (s != NULL) 6340 ga_concat(&ga, s); 6341 vim_free(tofree); 6342 if (s == NULL) 6343 break; 6344 } 6345 } 6346 if (todo > 0) 6347 { 6348 vim_free(ga.ga_data); 6349 return NULL; 6350 } 6351 6352 ga_append(&ga, '}'); 6353 ga_append(&ga, NUL); 6354 return (char_u *)ga.ga_data; 6355 } 6356 6357 /* 6358 * Allocate a variable for a Dictionary and fill it from "*arg". 6359 * Return OK or FAIL. Returns NOTDONE for {expr}. 6360 */ 6361 static int 6362 get_dict_tv(arg, rettv, evaluate) 6363 char_u **arg; 6364 typval_T *rettv; 6365 int evaluate; 6366 { 6367 dict_T *d = NULL; 6368 typval_T tvkey; 6369 typval_T tv; 6370 char_u *key; 6371 dictitem_T *item; 6372 char_u *start = skipwhite(*arg + 1); 6373 char_u buf[NUMBUFLEN]; 6374 6375 /* 6376 * First check if it's not a curly-braces thing: {expr}. 6377 * Must do this without evaluating, otherwise a function may be called 6378 * twice. Unfortunately this means we need to call eval1() twice for the 6379 * first item. 6380 * But {} is an empty Dictionary. 6381 */ 6382 if (*start != '}') 6383 { 6384 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6385 return FAIL; 6386 if (*start == '}') 6387 return NOTDONE; 6388 } 6389 6390 if (evaluate) 6391 { 6392 d = dict_alloc(); 6393 if (d == NULL) 6394 return FAIL; 6395 } 6396 tvkey.v_type = VAR_UNKNOWN; 6397 tv.v_type = VAR_UNKNOWN; 6398 6399 *arg = skipwhite(*arg + 1); 6400 while (**arg != '}' && **arg != NUL) 6401 { 6402 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6403 goto failret; 6404 if (**arg != ':') 6405 { 6406 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6407 clear_tv(&tvkey); 6408 goto failret; 6409 } 6410 key = get_tv_string_buf_chk(&tvkey, buf); 6411 if (key == NULL || *key == NUL) 6412 { 6413 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6414 if (key != NULL) 6415 EMSG(_(e_emptykey)); 6416 clear_tv(&tvkey); 6417 goto failret; 6418 } 6419 6420 *arg = skipwhite(*arg + 1); 6421 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6422 { 6423 clear_tv(&tvkey); 6424 goto failret; 6425 } 6426 if (evaluate) 6427 { 6428 item = dict_find(d, key, -1); 6429 if (item != NULL) 6430 { 6431 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6432 clear_tv(&tvkey); 6433 clear_tv(&tv); 6434 goto failret; 6435 } 6436 item = dictitem_alloc(key); 6437 clear_tv(&tvkey); 6438 if (item != NULL) 6439 { 6440 item->di_tv = tv; 6441 item->di_tv.v_lock = 0; 6442 if (dict_add(d, item) == FAIL) 6443 dictitem_free(item); 6444 } 6445 } 6446 6447 if (**arg == '}') 6448 break; 6449 if (**arg != ',') 6450 { 6451 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6452 goto failret; 6453 } 6454 *arg = skipwhite(*arg + 1); 6455 } 6456 6457 if (**arg != '}') 6458 { 6459 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6460 failret: 6461 if (evaluate) 6462 dict_free(d); 6463 return FAIL; 6464 } 6465 6466 *arg = skipwhite(*arg + 1); 6467 if (evaluate) 6468 { 6469 rettv->v_type = VAR_DICT; 6470 rettv->vval.v_dict = d; 6471 ++d->dv_refcount; 6472 } 6473 6474 return OK; 6475 } 6476 6477 /* 6478 * Return a string with the string representation of a variable. 6479 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6480 * "numbuf" is used for a number. 6481 * Does not put quotes around strings, as ":echo" displays values. 6482 * May return NULL; 6483 */ 6484 static char_u * 6485 echo_string(tv, tofree, numbuf) 6486 typval_T *tv; 6487 char_u **tofree; 6488 char_u *numbuf; 6489 { 6490 static int recurse = 0; 6491 char_u *r = NULL; 6492 6493 if (recurse >= DICT_MAXNEST) 6494 { 6495 EMSG(_("E724: variable nested too deep for displaying")); 6496 *tofree = NULL; 6497 return NULL; 6498 } 6499 ++recurse; 6500 6501 switch (tv->v_type) 6502 { 6503 case VAR_FUNC: 6504 *tofree = NULL; 6505 r = tv->vval.v_string; 6506 break; 6507 case VAR_LIST: 6508 *tofree = list2string(tv); 6509 r = *tofree; 6510 break; 6511 case VAR_DICT: 6512 *tofree = dict2string(tv); 6513 r = *tofree; 6514 break; 6515 case VAR_STRING: 6516 case VAR_NUMBER: 6517 *tofree = NULL; 6518 r = get_tv_string_buf(tv, numbuf); 6519 break; 6520 default: 6521 EMSG2(_(e_intern2), "echo_string()"); 6522 *tofree = NULL; 6523 } 6524 6525 --recurse; 6526 return r; 6527 } 6528 6529 /* 6530 * Return a string with the string representation of a variable. 6531 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6532 * "numbuf" is used for a number. 6533 * Puts quotes around strings, so that they can be parsed back by eval(). 6534 * May return NULL; 6535 */ 6536 static char_u * 6537 tv2string(tv, tofree, numbuf) 6538 typval_T *tv; 6539 char_u **tofree; 6540 char_u *numbuf; 6541 { 6542 switch (tv->v_type) 6543 { 6544 case VAR_FUNC: 6545 *tofree = string_quote(tv->vval.v_string, TRUE); 6546 return *tofree; 6547 case VAR_STRING: 6548 *tofree = string_quote(tv->vval.v_string, FALSE); 6549 return *tofree; 6550 case VAR_NUMBER: 6551 case VAR_LIST: 6552 case VAR_DICT: 6553 break; 6554 default: 6555 EMSG2(_(e_intern2), "tv2string()"); 6556 } 6557 return echo_string(tv, tofree, numbuf); 6558 } 6559 6560 /* 6561 * Return string "str" in ' quotes, doubling ' characters. 6562 * If "str" is NULL an empty string is assumed. 6563 * If "function" is TRUE make it function('string'). 6564 */ 6565 static char_u * 6566 string_quote(str, function) 6567 char_u *str; 6568 int function; 6569 { 6570 unsigned len; 6571 char_u *p, *r, *s; 6572 6573 len = (function ? 13 : 3); 6574 if (str != NULL) 6575 { 6576 len += STRLEN(str); 6577 for (p = str; *p != NUL; mb_ptr_adv(p)) 6578 if (*p == '\'') 6579 ++len; 6580 } 6581 s = r = alloc(len); 6582 if (r != NULL) 6583 { 6584 if (function) 6585 { 6586 STRCPY(r, "function('"); 6587 r += 10; 6588 } 6589 else 6590 *r++ = '\''; 6591 if (str != NULL) 6592 for (p = str; *p != NUL; ) 6593 { 6594 if (*p == '\'') 6595 *r++ = '\''; 6596 MB_COPY_CHAR(p, r); 6597 } 6598 *r++ = '\''; 6599 if (function) 6600 *r++ = ')'; 6601 *r++ = NUL; 6602 } 6603 return s; 6604 } 6605 6606 /* 6607 * Get the value of an environment variable. 6608 * "arg" is pointing to the '$'. It is advanced to after the name. 6609 * If the environment variable was not set, silently assume it is empty. 6610 * Always return OK. 6611 */ 6612 static int 6613 get_env_tv(arg, rettv, evaluate) 6614 char_u **arg; 6615 typval_T *rettv; 6616 int evaluate; 6617 { 6618 char_u *string = NULL; 6619 int len; 6620 int cc; 6621 char_u *name; 6622 int mustfree = FALSE; 6623 6624 ++*arg; 6625 name = *arg; 6626 len = get_env_len(arg); 6627 if (evaluate) 6628 { 6629 if (len != 0) 6630 { 6631 cc = name[len]; 6632 name[len] = NUL; 6633 /* first try vim_getenv(), fast for normal environment vars */ 6634 string = vim_getenv(name, &mustfree); 6635 if (string != NULL && *string != NUL) 6636 { 6637 if (!mustfree) 6638 string = vim_strsave(string); 6639 } 6640 else 6641 { 6642 if (mustfree) 6643 vim_free(string); 6644 6645 /* next try expanding things like $VIM and ${HOME} */ 6646 string = expand_env_save(name - 1); 6647 if (string != NULL && *string == '$') 6648 { 6649 vim_free(string); 6650 string = NULL; 6651 } 6652 } 6653 name[len] = cc; 6654 } 6655 rettv->v_type = VAR_STRING; 6656 rettv->vval.v_string = string; 6657 } 6658 6659 return OK; 6660 } 6661 6662 /* 6663 * Array with names and number of arguments of all internal functions 6664 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6665 */ 6666 static struct fst 6667 { 6668 char *f_name; /* function name */ 6669 char f_min_argc; /* minimal number of arguments */ 6670 char f_max_argc; /* maximal number of arguments */ 6671 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6672 /* implemenation of function */ 6673 } functions[] = 6674 { 6675 {"add", 2, 2, f_add}, 6676 {"append", 2, 2, f_append}, 6677 {"argc", 0, 0, f_argc}, 6678 {"argidx", 0, 0, f_argidx}, 6679 {"argv", 1, 1, f_argv}, 6680 {"browse", 4, 4, f_browse}, 6681 {"browsedir", 2, 2, f_browsedir}, 6682 {"bufexists", 1, 1, f_bufexists}, 6683 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6684 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6685 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6686 {"buflisted", 1, 1, f_buflisted}, 6687 {"bufloaded", 1, 1, f_bufloaded}, 6688 {"bufname", 1, 1, f_bufname}, 6689 {"bufnr", 1, 1, f_bufnr}, 6690 {"bufwinnr", 1, 1, f_bufwinnr}, 6691 {"byte2line", 1, 1, f_byte2line}, 6692 {"byteidx", 2, 2, f_byteidx}, 6693 {"call", 2, 3, f_call}, 6694 {"char2nr", 1, 1, f_char2nr}, 6695 {"cindent", 1, 1, f_cindent}, 6696 {"col", 1, 1, f_col}, 6697 #if defined(FEAT_INS_EXPAND) 6698 {"complete_add", 1, 1, f_complete_add}, 6699 {"complete_check", 0, 0, f_complete_check}, 6700 #endif 6701 {"confirm", 1, 4, f_confirm}, 6702 {"copy", 1, 1, f_copy}, 6703 {"count", 2, 4, f_count}, 6704 {"cscope_connection",0,3, f_cscope_connection}, 6705 {"cursor", 2, 2, f_cursor}, 6706 {"deepcopy", 1, 2, f_deepcopy}, 6707 {"delete", 1, 1, f_delete}, 6708 {"did_filetype", 0, 0, f_did_filetype}, 6709 {"diff_filler", 1, 1, f_diff_filler}, 6710 {"diff_hlID", 2, 2, f_diff_hlID}, 6711 {"empty", 1, 1, f_empty}, 6712 {"escape", 2, 2, f_escape}, 6713 {"eval", 1, 1, f_eval}, 6714 {"eventhandler", 0, 0, f_eventhandler}, 6715 {"executable", 1, 1, f_executable}, 6716 {"exists", 1, 1, f_exists}, 6717 {"expand", 1, 2, f_expand}, 6718 {"extend", 2, 3, f_extend}, 6719 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6720 {"filereadable", 1, 1, f_filereadable}, 6721 {"filewritable", 1, 1, f_filewritable}, 6722 {"filter", 2, 2, f_filter}, 6723 {"finddir", 1, 3, f_finddir}, 6724 {"findfile", 1, 3, f_findfile}, 6725 {"fnamemodify", 2, 2, f_fnamemodify}, 6726 {"foldclosed", 1, 1, f_foldclosed}, 6727 {"foldclosedend", 1, 1, f_foldclosedend}, 6728 {"foldlevel", 1, 1, f_foldlevel}, 6729 {"foldtext", 0, 0, f_foldtext}, 6730 {"foldtextresult", 1, 1, f_foldtextresult}, 6731 {"foreground", 0, 0, f_foreground}, 6732 {"function", 1, 1, f_function}, 6733 {"garbagecollect", 0, 0, f_garbagecollect}, 6734 {"get", 2, 3, f_get}, 6735 {"getbufline", 2, 3, f_getbufline}, 6736 {"getbufvar", 2, 2, f_getbufvar}, 6737 {"getchar", 0, 1, f_getchar}, 6738 {"getcharmod", 0, 0, f_getcharmod}, 6739 {"getcmdline", 0, 0, f_getcmdline}, 6740 {"getcmdpos", 0, 0, f_getcmdpos}, 6741 {"getcwd", 0, 0, f_getcwd}, 6742 {"getfontname", 0, 1, f_getfontname}, 6743 {"getfperm", 1, 1, f_getfperm}, 6744 {"getfsize", 1, 1, f_getfsize}, 6745 {"getftime", 1, 1, f_getftime}, 6746 {"getftype", 1, 1, f_getftype}, 6747 {"getline", 1, 2, f_getline}, 6748 {"getqflist", 0, 0, f_getqflist}, 6749 {"getreg", 0, 2, f_getreg}, 6750 {"getregtype", 0, 1, f_getregtype}, 6751 {"getwinposx", 0, 0, f_getwinposx}, 6752 {"getwinposy", 0, 0, f_getwinposy}, 6753 {"getwinvar", 2, 2, f_getwinvar}, 6754 {"glob", 1, 1, f_glob}, 6755 {"globpath", 2, 2, f_globpath}, 6756 {"has", 1, 1, f_has}, 6757 {"has_key", 2, 2, f_has_key}, 6758 {"hasmapto", 1, 2, f_hasmapto}, 6759 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6760 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6761 {"histadd", 2, 2, f_histadd}, 6762 {"histdel", 1, 2, f_histdel}, 6763 {"histget", 1, 2, f_histget}, 6764 {"histnr", 1, 1, f_histnr}, 6765 {"hlID", 1, 1, f_hlID}, 6766 {"hlexists", 1, 1, f_hlexists}, 6767 {"hostname", 0, 0, f_hostname}, 6768 {"iconv", 3, 3, f_iconv}, 6769 {"indent", 1, 1, f_indent}, 6770 {"index", 2, 4, f_index}, 6771 {"input", 1, 2, f_input}, 6772 {"inputdialog", 1, 3, f_inputdialog}, 6773 {"inputrestore", 0, 0, f_inputrestore}, 6774 {"inputsave", 0, 0, f_inputsave}, 6775 {"inputsecret", 1, 2, f_inputsecret}, 6776 {"insert", 2, 3, f_insert}, 6777 {"isdirectory", 1, 1, f_isdirectory}, 6778 {"islocked", 1, 1, f_islocked}, 6779 {"items", 1, 1, f_items}, 6780 {"join", 1, 2, f_join}, 6781 {"keys", 1, 1, f_keys}, 6782 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6783 {"len", 1, 1, f_len}, 6784 {"libcall", 3, 3, f_libcall}, 6785 {"libcallnr", 3, 3, f_libcallnr}, 6786 {"line", 1, 1, f_line}, 6787 {"line2byte", 1, 1, f_line2byte}, 6788 {"lispindent", 1, 1, f_lispindent}, 6789 {"localtime", 0, 0, f_localtime}, 6790 {"map", 2, 2, f_map}, 6791 {"maparg", 1, 2, f_maparg}, 6792 {"mapcheck", 1, 2, f_mapcheck}, 6793 {"match", 2, 4, f_match}, 6794 {"matchend", 2, 4, f_matchend}, 6795 {"matchlist", 2, 4, f_matchlist}, 6796 {"matchstr", 2, 4, f_matchstr}, 6797 {"max", 1, 1, f_max}, 6798 {"min", 1, 1, f_min}, 6799 #ifdef vim_mkdir 6800 {"mkdir", 1, 3, f_mkdir}, 6801 #endif 6802 {"mode", 0, 0, f_mode}, 6803 {"nextnonblank", 1, 1, f_nextnonblank}, 6804 {"nr2char", 1, 1, f_nr2char}, 6805 {"prevnonblank", 1, 1, f_prevnonblank}, 6806 {"printf", 2, 19, f_printf}, 6807 {"range", 1, 3, f_range}, 6808 {"readfile", 1, 3, f_readfile}, 6809 {"remote_expr", 2, 3, f_remote_expr}, 6810 {"remote_foreground", 1, 1, f_remote_foreground}, 6811 {"remote_peek", 1, 2, f_remote_peek}, 6812 {"remote_read", 1, 1, f_remote_read}, 6813 {"remote_send", 2, 3, f_remote_send}, 6814 {"remove", 2, 3, f_remove}, 6815 {"rename", 2, 2, f_rename}, 6816 {"repeat", 2, 2, f_repeat}, 6817 {"resolve", 1, 1, f_resolve}, 6818 {"reverse", 1, 1, f_reverse}, 6819 {"search", 1, 2, f_search}, 6820 {"searchpair", 3, 5, f_searchpair}, 6821 {"server2client", 2, 2, f_server2client}, 6822 {"serverlist", 0, 0, f_serverlist}, 6823 {"setbufvar", 3, 3, f_setbufvar}, 6824 {"setcmdpos", 1, 1, f_setcmdpos}, 6825 {"setline", 2, 2, f_setline}, 6826 {"setqflist", 1, 2, f_setqflist}, 6827 {"setreg", 2, 3, f_setreg}, 6828 {"setwinvar", 3, 3, f_setwinvar}, 6829 {"simplify", 1, 1, f_simplify}, 6830 {"sort", 1, 2, f_sort}, 6831 {"soundfold", 1, 1, f_soundfold}, 6832 {"spellbadword", 0, 0, f_spellbadword}, 6833 {"spellsuggest", 1, 2, f_spellsuggest}, 6834 {"split", 1, 3, f_split}, 6835 #ifdef HAVE_STRFTIME 6836 {"strftime", 1, 2, f_strftime}, 6837 #endif 6838 {"stridx", 2, 3, f_stridx}, 6839 {"string", 1, 1, f_string}, 6840 {"strlen", 1, 1, f_strlen}, 6841 {"strpart", 2, 3, f_strpart}, 6842 {"strridx", 2, 3, f_strridx}, 6843 {"strtrans", 1, 1, f_strtrans}, 6844 {"submatch", 1, 1, f_submatch}, 6845 {"substitute", 4, 4, f_substitute}, 6846 {"synID", 3, 3, f_synID}, 6847 {"synIDattr", 2, 3, f_synIDattr}, 6848 {"synIDtrans", 1, 1, f_synIDtrans}, 6849 {"system", 1, 2, f_system}, 6850 {"taglist", 1, 1, f_taglist}, 6851 {"tempname", 0, 0, f_tempname}, 6852 {"tolower", 1, 1, f_tolower}, 6853 {"toupper", 1, 1, f_toupper}, 6854 {"tr", 3, 3, f_tr}, 6855 {"type", 1, 1, f_type}, 6856 {"values", 1, 1, f_values}, 6857 {"virtcol", 1, 1, f_virtcol}, 6858 {"visualmode", 0, 1, f_visualmode}, 6859 {"winbufnr", 1, 1, f_winbufnr}, 6860 {"wincol", 0, 0, f_wincol}, 6861 {"winheight", 1, 1, f_winheight}, 6862 {"winline", 0, 0, f_winline}, 6863 {"winnr", 0, 1, f_winnr}, 6864 {"winrestcmd", 0, 0, f_winrestcmd}, 6865 {"winwidth", 1, 1, f_winwidth}, 6866 {"writefile", 2, 3, f_writefile}, 6867 }; 6868 6869 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6870 6871 /* 6872 * Function given to ExpandGeneric() to obtain the list of internal 6873 * or user defined function names. 6874 */ 6875 char_u * 6876 get_function_name(xp, idx) 6877 expand_T *xp; 6878 int idx; 6879 { 6880 static int intidx = -1; 6881 char_u *name; 6882 6883 if (idx == 0) 6884 intidx = -1; 6885 if (intidx < 0) 6886 { 6887 name = get_user_func_name(xp, idx); 6888 if (name != NULL) 6889 return name; 6890 } 6891 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6892 { 6893 STRCPY(IObuff, functions[intidx].f_name); 6894 STRCAT(IObuff, "("); 6895 if (functions[intidx].f_max_argc == 0) 6896 STRCAT(IObuff, ")"); 6897 return IObuff; 6898 } 6899 6900 return NULL; 6901 } 6902 6903 /* 6904 * Function given to ExpandGeneric() to obtain the list of internal or 6905 * user defined variable or function names. 6906 */ 6907 /*ARGSUSED*/ 6908 char_u * 6909 get_expr_name(xp, idx) 6910 expand_T *xp; 6911 int idx; 6912 { 6913 static int intidx = -1; 6914 char_u *name; 6915 6916 if (idx == 0) 6917 intidx = -1; 6918 if (intidx < 0) 6919 { 6920 name = get_function_name(xp, idx); 6921 if (name != NULL) 6922 return name; 6923 } 6924 return get_user_var_name(xp, ++intidx); 6925 } 6926 6927 #endif /* FEAT_CMDL_COMPL */ 6928 6929 /* 6930 * Find internal function in table above. 6931 * Return index, or -1 if not found 6932 */ 6933 static int 6934 find_internal_func(name) 6935 char_u *name; /* name of the function */ 6936 { 6937 int first = 0; 6938 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 6939 int cmp; 6940 int x; 6941 6942 /* 6943 * Find the function name in the table. Binary search. 6944 */ 6945 while (first <= last) 6946 { 6947 x = first + ((unsigned)(last - first) >> 1); 6948 cmp = STRCMP(name, functions[x].f_name); 6949 if (cmp < 0) 6950 last = x - 1; 6951 else if (cmp > 0) 6952 first = x + 1; 6953 else 6954 return x; 6955 } 6956 return -1; 6957 } 6958 6959 /* 6960 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 6961 * name it contains, otherwise return "name". 6962 */ 6963 static char_u * 6964 deref_func_name(name, lenp) 6965 char_u *name; 6966 int *lenp; 6967 { 6968 dictitem_T *v; 6969 int cc; 6970 6971 cc = name[*lenp]; 6972 name[*lenp] = NUL; 6973 v = find_var(name, NULL); 6974 name[*lenp] = cc; 6975 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 6976 { 6977 if (v->di_tv.vval.v_string == NULL) 6978 { 6979 *lenp = 0; 6980 return (char_u *)""; /* just in case */ 6981 } 6982 *lenp = STRLEN(v->di_tv.vval.v_string); 6983 return v->di_tv.vval.v_string; 6984 } 6985 6986 return name; 6987 } 6988 6989 /* 6990 * Allocate a variable for the result of a function. 6991 * Return OK or FAIL. 6992 */ 6993 static int 6994 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 6995 evaluate, selfdict) 6996 char_u *name; /* name of the function */ 6997 int len; /* length of "name" */ 6998 typval_T *rettv; 6999 char_u **arg; /* argument, pointing to the '(' */ 7000 linenr_T firstline; /* first line of range */ 7001 linenr_T lastline; /* last line of range */ 7002 int *doesrange; /* return: function handled range */ 7003 int evaluate; 7004 dict_T *selfdict; /* Dictionary for "self" */ 7005 { 7006 char_u *argp; 7007 int ret = OK; 7008 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7009 int argcount = 0; /* number of arguments found */ 7010 7011 /* 7012 * Get the arguments. 7013 */ 7014 argp = *arg; 7015 while (argcount < MAX_FUNC_ARGS) 7016 { 7017 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7018 if (*argp == ')' || *argp == ',' || *argp == NUL) 7019 break; 7020 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7021 { 7022 ret = FAIL; 7023 break; 7024 } 7025 ++argcount; 7026 if (*argp != ',') 7027 break; 7028 } 7029 if (*argp == ')') 7030 ++argp; 7031 else 7032 ret = FAIL; 7033 7034 if (ret == OK) 7035 ret = call_func(name, len, rettv, argcount, argvars, 7036 firstline, lastline, doesrange, evaluate, selfdict); 7037 else if (!aborting()) 7038 { 7039 if (argcount == MAX_FUNC_ARGS) 7040 emsg_funcname("E740: Too many arguments for function %s", name); 7041 else 7042 emsg_funcname("E116: Invalid arguments for function %s", name); 7043 } 7044 7045 while (--argcount >= 0) 7046 clear_tv(&argvars[argcount]); 7047 7048 *arg = skipwhite(argp); 7049 return ret; 7050 } 7051 7052 7053 /* 7054 * Call a function with its resolved parameters 7055 * Return OK or FAIL. 7056 */ 7057 static int 7058 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7059 doesrange, evaluate, selfdict) 7060 char_u *name; /* name of the function */ 7061 int len; /* length of "name" */ 7062 typval_T *rettv; /* return value goes here */ 7063 int argcount; /* number of "argvars" */ 7064 typval_T *argvars; /* vars for arguments */ 7065 linenr_T firstline; /* first line of range */ 7066 linenr_T lastline; /* last line of range */ 7067 int *doesrange; /* return: function handled range */ 7068 int evaluate; 7069 dict_T *selfdict; /* Dictionary for "self" */ 7070 { 7071 int ret = FAIL; 7072 #define ERROR_UNKNOWN 0 7073 #define ERROR_TOOMANY 1 7074 #define ERROR_TOOFEW 2 7075 #define ERROR_SCRIPT 3 7076 #define ERROR_DICT 4 7077 #define ERROR_NONE 5 7078 #define ERROR_OTHER 6 7079 int error = ERROR_NONE; 7080 int i; 7081 int llen; 7082 ufunc_T *fp; 7083 int cc; 7084 #define FLEN_FIXED 40 7085 char_u fname_buf[FLEN_FIXED + 1]; 7086 char_u *fname; 7087 7088 /* 7089 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7090 * Change <SNR>123_name() to K_SNR 123_name(). 7091 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7092 */ 7093 cc = name[len]; 7094 name[len] = NUL; 7095 llen = eval_fname_script(name); 7096 if (llen > 0) 7097 { 7098 fname_buf[0] = K_SPECIAL; 7099 fname_buf[1] = KS_EXTRA; 7100 fname_buf[2] = (int)KE_SNR; 7101 i = 3; 7102 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7103 { 7104 if (current_SID <= 0) 7105 error = ERROR_SCRIPT; 7106 else 7107 { 7108 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7109 i = (int)STRLEN(fname_buf); 7110 } 7111 } 7112 if (i + STRLEN(name + llen) < FLEN_FIXED) 7113 { 7114 STRCPY(fname_buf + i, name + llen); 7115 fname = fname_buf; 7116 } 7117 else 7118 { 7119 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7120 if (fname == NULL) 7121 error = ERROR_OTHER; 7122 else 7123 { 7124 mch_memmove(fname, fname_buf, (size_t)i); 7125 STRCPY(fname + i, name + llen); 7126 } 7127 } 7128 } 7129 else 7130 fname = name; 7131 7132 *doesrange = FALSE; 7133 7134 7135 /* execute the function if no errors detected and executing */ 7136 if (evaluate && error == ERROR_NONE) 7137 { 7138 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7139 error = ERROR_UNKNOWN; 7140 7141 if (!builtin_function(fname)) 7142 { 7143 /* 7144 * User defined function. 7145 */ 7146 fp = find_func(fname); 7147 7148 #ifdef FEAT_AUTOCMD 7149 /* Trigger FuncUndefined event, may load the function. */ 7150 if (fp == NULL 7151 && apply_autocmds(EVENT_FUNCUNDEFINED, 7152 fname, fname, TRUE, NULL) 7153 && !aborting()) 7154 { 7155 /* executed an autocommand, search for the function again */ 7156 fp = find_func(fname); 7157 } 7158 #endif 7159 /* Try loading a package. */ 7160 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7161 { 7162 /* loaded a package, search for the function again */ 7163 fp = find_func(fname); 7164 } 7165 7166 if (fp != NULL) 7167 { 7168 if (fp->uf_flags & FC_RANGE) 7169 *doesrange = TRUE; 7170 if (argcount < fp->uf_args.ga_len) 7171 error = ERROR_TOOFEW; 7172 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7173 error = ERROR_TOOMANY; 7174 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7175 error = ERROR_DICT; 7176 else 7177 { 7178 /* 7179 * Call the user function. 7180 * Save and restore search patterns, script variables and 7181 * redo buffer. 7182 */ 7183 save_search_patterns(); 7184 saveRedobuff(); 7185 ++fp->uf_calls; 7186 call_user_func(fp, argcount, argvars, rettv, 7187 firstline, lastline, 7188 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7189 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7190 && fp->uf_refcount <= 0) 7191 /* Function was unreferenced while being used, free it 7192 * now. */ 7193 func_free(fp); 7194 restoreRedobuff(); 7195 restore_search_patterns(); 7196 error = ERROR_NONE; 7197 } 7198 } 7199 } 7200 else 7201 { 7202 /* 7203 * Find the function name in the table, call its implementation. 7204 */ 7205 i = find_internal_func(fname); 7206 if (i >= 0) 7207 { 7208 if (argcount < functions[i].f_min_argc) 7209 error = ERROR_TOOFEW; 7210 else if (argcount > functions[i].f_max_argc) 7211 error = ERROR_TOOMANY; 7212 else 7213 { 7214 argvars[argcount].v_type = VAR_UNKNOWN; 7215 functions[i].f_func(argvars, rettv); 7216 error = ERROR_NONE; 7217 } 7218 } 7219 } 7220 /* 7221 * The function call (or "FuncUndefined" autocommand sequence) might 7222 * have been aborted by an error, an interrupt, or an explicitly thrown 7223 * exception that has not been caught so far. This situation can be 7224 * tested for by calling aborting(). For an error in an internal 7225 * function or for the "E132" error in call_user_func(), however, the 7226 * throw point at which the "force_abort" flag (temporarily reset by 7227 * emsg()) is normally updated has not been reached yet. We need to 7228 * update that flag first to make aborting() reliable. 7229 */ 7230 update_force_abort(); 7231 } 7232 if (error == ERROR_NONE) 7233 ret = OK; 7234 7235 /* 7236 * Report an error unless the argument evaluation or function call has been 7237 * cancelled due to an aborting error, an interrupt, or an exception. 7238 */ 7239 if (!aborting()) 7240 { 7241 switch (error) 7242 { 7243 case ERROR_UNKNOWN: 7244 emsg_funcname("E117: Unknown function: %s", name); 7245 break; 7246 case ERROR_TOOMANY: 7247 emsg_funcname(e_toomanyarg, name); 7248 break; 7249 case ERROR_TOOFEW: 7250 emsg_funcname("E119: Not enough arguments for function: %s", 7251 name); 7252 break; 7253 case ERROR_SCRIPT: 7254 emsg_funcname("E120: Using <SID> not in a script context: %s", 7255 name); 7256 break; 7257 case ERROR_DICT: 7258 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7259 name); 7260 break; 7261 } 7262 } 7263 7264 name[len] = cc; 7265 if (fname != name && fname != fname_buf) 7266 vim_free(fname); 7267 7268 return ret; 7269 } 7270 7271 /* 7272 * Give an error message with a function name. Handle <SNR> things. 7273 */ 7274 static void 7275 emsg_funcname(msg, name) 7276 char *msg; 7277 char_u *name; 7278 { 7279 char_u *p; 7280 7281 if (*name == K_SPECIAL) 7282 p = concat_str((char_u *)"<SNR>", name + 3); 7283 else 7284 p = name; 7285 EMSG2(_(msg), p); 7286 if (p != name) 7287 vim_free(p); 7288 } 7289 7290 /********************************************* 7291 * Implementation of the built-in functions 7292 */ 7293 7294 /* 7295 * "add(list, item)" function 7296 */ 7297 static void 7298 f_add(argvars, rettv) 7299 typval_T *argvars; 7300 typval_T *rettv; 7301 { 7302 list_T *l; 7303 7304 rettv->vval.v_number = 1; /* Default: Failed */ 7305 if (argvars[0].v_type == VAR_LIST) 7306 { 7307 if ((l = argvars[0].vval.v_list) != NULL 7308 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7309 && list_append_tv(l, &argvars[1]) == OK) 7310 copy_tv(&argvars[0], rettv); 7311 } 7312 else 7313 EMSG(_(e_listreq)); 7314 } 7315 7316 /* 7317 * "append(lnum, string/list)" function 7318 */ 7319 static void 7320 f_append(argvars, rettv) 7321 typval_T *argvars; 7322 typval_T *rettv; 7323 { 7324 long lnum; 7325 char_u *line; 7326 list_T *l = NULL; 7327 listitem_T *li = NULL; 7328 typval_T *tv; 7329 long added = 0; 7330 7331 lnum = get_tv_lnum(argvars); 7332 if (lnum >= 0 7333 && lnum <= curbuf->b_ml.ml_line_count 7334 && u_save(lnum, lnum + 1) == OK) 7335 { 7336 if (argvars[1].v_type == VAR_LIST) 7337 { 7338 l = argvars[1].vval.v_list; 7339 if (l == NULL) 7340 return; 7341 li = l->lv_first; 7342 } 7343 rettv->vval.v_number = 0; /* Default: Success */ 7344 for (;;) 7345 { 7346 if (l == NULL) 7347 tv = &argvars[1]; /* append a string */ 7348 else if (li == NULL) 7349 break; /* end of list */ 7350 else 7351 tv = &li->li_tv; /* append item from list */ 7352 line = get_tv_string_chk(tv); 7353 if (line == NULL) /* type error */ 7354 { 7355 rettv->vval.v_number = 1; /* Failed */ 7356 break; 7357 } 7358 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7359 ++added; 7360 if (l == NULL) 7361 break; 7362 li = li->li_next; 7363 } 7364 7365 appended_lines_mark(lnum, added); 7366 if (curwin->w_cursor.lnum > lnum) 7367 curwin->w_cursor.lnum += added; 7368 } 7369 else 7370 rettv->vval.v_number = 1; /* Failed */ 7371 } 7372 7373 /* 7374 * "argc()" function 7375 */ 7376 /* ARGSUSED */ 7377 static void 7378 f_argc(argvars, rettv) 7379 typval_T *argvars; 7380 typval_T *rettv; 7381 { 7382 rettv->vval.v_number = ARGCOUNT; 7383 } 7384 7385 /* 7386 * "argidx()" function 7387 */ 7388 /* ARGSUSED */ 7389 static void 7390 f_argidx(argvars, rettv) 7391 typval_T *argvars; 7392 typval_T *rettv; 7393 { 7394 rettv->vval.v_number = curwin->w_arg_idx; 7395 } 7396 7397 /* 7398 * "argv(nr)" function 7399 */ 7400 static void 7401 f_argv(argvars, rettv) 7402 typval_T *argvars; 7403 typval_T *rettv; 7404 { 7405 int idx; 7406 7407 idx = get_tv_number_chk(&argvars[0], NULL); 7408 if (idx >= 0 && idx < ARGCOUNT) 7409 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7410 else 7411 rettv->vval.v_string = NULL; 7412 rettv->v_type = VAR_STRING; 7413 } 7414 7415 /* 7416 * "browse(save, title, initdir, default)" function 7417 */ 7418 /* ARGSUSED */ 7419 static void 7420 f_browse(argvars, rettv) 7421 typval_T *argvars; 7422 typval_T *rettv; 7423 { 7424 #ifdef FEAT_BROWSE 7425 int save; 7426 char_u *title; 7427 char_u *initdir; 7428 char_u *defname; 7429 char_u buf[NUMBUFLEN]; 7430 char_u buf2[NUMBUFLEN]; 7431 int error = FALSE; 7432 7433 save = get_tv_number_chk(&argvars[0], &error); 7434 title = get_tv_string_chk(&argvars[1]); 7435 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7436 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7437 7438 if (error || title == NULL || initdir == NULL || defname == NULL) 7439 rettv->vval.v_string = NULL; 7440 else 7441 rettv->vval.v_string = 7442 do_browse(save ? BROWSE_SAVE : 0, 7443 title, defname, NULL, initdir, NULL, curbuf); 7444 #else 7445 rettv->vval.v_string = NULL; 7446 #endif 7447 rettv->v_type = VAR_STRING; 7448 } 7449 7450 /* 7451 * "browsedir(title, initdir)" function 7452 */ 7453 /* ARGSUSED */ 7454 static void 7455 f_browsedir(argvars, rettv) 7456 typval_T *argvars; 7457 typval_T *rettv; 7458 { 7459 #ifdef FEAT_BROWSE 7460 char_u *title; 7461 char_u *initdir; 7462 char_u buf[NUMBUFLEN]; 7463 7464 title = get_tv_string_chk(&argvars[0]); 7465 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7466 7467 if (title == NULL || initdir == NULL) 7468 rettv->vval.v_string = NULL; 7469 else 7470 rettv->vval.v_string = do_browse(BROWSE_DIR, 7471 title, NULL, NULL, initdir, NULL, curbuf); 7472 #else 7473 rettv->vval.v_string = NULL; 7474 #endif 7475 rettv->v_type = VAR_STRING; 7476 } 7477 7478 static buf_T *find_buffer __ARGS((typval_T *avar)); 7479 7480 /* 7481 * Find a buffer by number or exact name. 7482 */ 7483 static buf_T * 7484 find_buffer(avar) 7485 typval_T *avar; 7486 { 7487 buf_T *buf = NULL; 7488 7489 if (avar->v_type == VAR_NUMBER) 7490 buf = buflist_findnr((int)avar->vval.v_number); 7491 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7492 { 7493 buf = buflist_findname_exp(avar->vval.v_string); 7494 if (buf == NULL) 7495 { 7496 /* No full path name match, try a match with a URL or a "nofile" 7497 * buffer, these don't use the full path. */ 7498 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7499 if (buf->b_fname != NULL 7500 && (path_with_url(buf->b_fname) 7501 #ifdef FEAT_QUICKFIX 7502 || bt_nofile(buf) 7503 #endif 7504 ) 7505 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7506 break; 7507 } 7508 } 7509 return buf; 7510 } 7511 7512 /* 7513 * "bufexists(expr)" function 7514 */ 7515 static void 7516 f_bufexists(argvars, rettv) 7517 typval_T *argvars; 7518 typval_T *rettv; 7519 { 7520 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7521 } 7522 7523 /* 7524 * "buflisted(expr)" function 7525 */ 7526 static void 7527 f_buflisted(argvars, rettv) 7528 typval_T *argvars; 7529 typval_T *rettv; 7530 { 7531 buf_T *buf; 7532 7533 buf = find_buffer(&argvars[0]); 7534 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7535 } 7536 7537 /* 7538 * "bufloaded(expr)" function 7539 */ 7540 static void 7541 f_bufloaded(argvars, rettv) 7542 typval_T *argvars; 7543 typval_T *rettv; 7544 { 7545 buf_T *buf; 7546 7547 buf = find_buffer(&argvars[0]); 7548 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7549 } 7550 7551 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7552 7553 /* 7554 * Get buffer by number or pattern. 7555 */ 7556 static buf_T * 7557 get_buf_tv(tv) 7558 typval_T *tv; 7559 { 7560 char_u *name = tv->vval.v_string; 7561 int save_magic; 7562 char_u *save_cpo; 7563 buf_T *buf; 7564 7565 if (tv->v_type == VAR_NUMBER) 7566 return buflist_findnr((int)tv->vval.v_number); 7567 if (tv->v_type != VAR_STRING) 7568 return NULL; 7569 if (name == NULL || *name == NUL) 7570 return curbuf; 7571 if (name[0] == '$' && name[1] == NUL) 7572 return lastbuf; 7573 7574 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7575 save_magic = p_magic; 7576 p_magic = TRUE; 7577 save_cpo = p_cpo; 7578 p_cpo = (char_u *)""; 7579 7580 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7581 TRUE, FALSE)); 7582 7583 p_magic = save_magic; 7584 p_cpo = save_cpo; 7585 7586 /* If not found, try expanding the name, like done for bufexists(). */ 7587 if (buf == NULL) 7588 buf = find_buffer(tv); 7589 7590 return buf; 7591 } 7592 7593 /* 7594 * "bufname(expr)" function 7595 */ 7596 static void 7597 f_bufname(argvars, rettv) 7598 typval_T *argvars; 7599 typval_T *rettv; 7600 { 7601 buf_T *buf; 7602 7603 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7604 ++emsg_off; 7605 buf = get_buf_tv(&argvars[0]); 7606 rettv->v_type = VAR_STRING; 7607 if (buf != NULL && buf->b_fname != NULL) 7608 rettv->vval.v_string = vim_strsave(buf->b_fname); 7609 else 7610 rettv->vval.v_string = NULL; 7611 --emsg_off; 7612 } 7613 7614 /* 7615 * "bufnr(expr)" function 7616 */ 7617 static void 7618 f_bufnr(argvars, rettv) 7619 typval_T *argvars; 7620 typval_T *rettv; 7621 { 7622 buf_T *buf; 7623 7624 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7625 ++emsg_off; 7626 buf = get_buf_tv(&argvars[0]); 7627 if (buf != NULL) 7628 rettv->vval.v_number = buf->b_fnum; 7629 else 7630 rettv->vval.v_number = -1; 7631 --emsg_off; 7632 } 7633 7634 /* 7635 * "bufwinnr(nr)" function 7636 */ 7637 static void 7638 f_bufwinnr(argvars, rettv) 7639 typval_T *argvars; 7640 typval_T *rettv; 7641 { 7642 #ifdef FEAT_WINDOWS 7643 win_T *wp; 7644 int winnr = 0; 7645 #endif 7646 buf_T *buf; 7647 7648 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7649 ++emsg_off; 7650 buf = get_buf_tv(&argvars[0]); 7651 #ifdef FEAT_WINDOWS 7652 for (wp = firstwin; wp; wp = wp->w_next) 7653 { 7654 ++winnr; 7655 if (wp->w_buffer == buf) 7656 break; 7657 } 7658 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7659 #else 7660 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7661 #endif 7662 --emsg_off; 7663 } 7664 7665 /* 7666 * "byte2line(byte)" function 7667 */ 7668 /*ARGSUSED*/ 7669 static void 7670 f_byte2line(argvars, rettv) 7671 typval_T *argvars; 7672 typval_T *rettv; 7673 { 7674 #ifndef FEAT_BYTEOFF 7675 rettv->vval.v_number = -1; 7676 #else 7677 long boff = 0; 7678 7679 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7680 if (boff < 0) 7681 rettv->vval.v_number = -1; 7682 else 7683 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7684 (linenr_T)0, &boff); 7685 #endif 7686 } 7687 7688 /* 7689 * "byteidx()" function 7690 */ 7691 /*ARGSUSED*/ 7692 static void 7693 f_byteidx(argvars, rettv) 7694 typval_T *argvars; 7695 typval_T *rettv; 7696 { 7697 #ifdef FEAT_MBYTE 7698 char_u *t; 7699 #endif 7700 char_u *str; 7701 long idx; 7702 7703 str = get_tv_string_chk(&argvars[0]); 7704 idx = get_tv_number_chk(&argvars[1], NULL); 7705 rettv->vval.v_number = -1; 7706 if (str == NULL || idx < 0) 7707 return; 7708 7709 #ifdef FEAT_MBYTE 7710 t = str; 7711 for ( ; idx > 0; idx--) 7712 { 7713 if (*t == NUL) /* EOL reached */ 7714 return; 7715 t += (*mb_ptr2len)(t); 7716 } 7717 rettv->vval.v_number = t - str; 7718 #else 7719 if (idx <= STRLEN(str)) 7720 rettv->vval.v_number = idx; 7721 #endif 7722 } 7723 7724 /* 7725 * "call(func, arglist)" function 7726 */ 7727 static void 7728 f_call(argvars, rettv) 7729 typval_T *argvars; 7730 typval_T *rettv; 7731 { 7732 char_u *func; 7733 typval_T argv[MAX_FUNC_ARGS]; 7734 int argc = 0; 7735 listitem_T *item; 7736 int dummy; 7737 dict_T *selfdict = NULL; 7738 7739 rettv->vval.v_number = 0; 7740 if (argvars[1].v_type != VAR_LIST) 7741 { 7742 EMSG(_(e_listreq)); 7743 return; 7744 } 7745 if (argvars[1].vval.v_list == NULL) 7746 return; 7747 7748 if (argvars[0].v_type == VAR_FUNC) 7749 func = argvars[0].vval.v_string; 7750 else 7751 func = get_tv_string(&argvars[0]); 7752 if (*func == NUL) 7753 return; /* type error or empty name */ 7754 7755 if (argvars[2].v_type != VAR_UNKNOWN) 7756 { 7757 if (argvars[2].v_type != VAR_DICT) 7758 { 7759 EMSG(_(e_dictreq)); 7760 return; 7761 } 7762 selfdict = argvars[2].vval.v_dict; 7763 } 7764 7765 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7766 item = item->li_next) 7767 { 7768 if (argc == MAX_FUNC_ARGS) 7769 { 7770 EMSG(_("E699: Too many arguments")); 7771 break; 7772 } 7773 /* Make a copy of each argument. This is needed to be able to set 7774 * v_lock to VAR_FIXED in the copy without changing the original list. 7775 */ 7776 copy_tv(&item->li_tv, &argv[argc++]); 7777 } 7778 7779 if (item == NULL) 7780 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7781 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7782 &dummy, TRUE, selfdict); 7783 7784 /* Free the arguments. */ 7785 while (argc > 0) 7786 clear_tv(&argv[--argc]); 7787 } 7788 7789 /* 7790 * "char2nr(string)" function 7791 */ 7792 static void 7793 f_char2nr(argvars, rettv) 7794 typval_T *argvars; 7795 typval_T *rettv; 7796 { 7797 #ifdef FEAT_MBYTE 7798 if (has_mbyte) 7799 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7800 else 7801 #endif 7802 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7803 } 7804 7805 /* 7806 * "cindent(lnum)" function 7807 */ 7808 static void 7809 f_cindent(argvars, rettv) 7810 typval_T *argvars; 7811 typval_T *rettv; 7812 { 7813 #ifdef FEAT_CINDENT 7814 pos_T pos; 7815 linenr_T lnum; 7816 7817 pos = curwin->w_cursor; 7818 lnum = get_tv_lnum(argvars); 7819 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7820 { 7821 curwin->w_cursor.lnum = lnum; 7822 rettv->vval.v_number = get_c_indent(); 7823 curwin->w_cursor = pos; 7824 } 7825 else 7826 #endif 7827 rettv->vval.v_number = -1; 7828 } 7829 7830 /* 7831 * "col(string)" function 7832 */ 7833 static void 7834 f_col(argvars, rettv) 7835 typval_T *argvars; 7836 typval_T *rettv; 7837 { 7838 colnr_T col = 0; 7839 pos_T *fp; 7840 7841 fp = var2fpos(&argvars[0], FALSE); 7842 if (fp != NULL) 7843 { 7844 if (fp->col == MAXCOL) 7845 { 7846 /* '> can be MAXCOL, get the length of the line then */ 7847 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7848 col = STRLEN(ml_get(fp->lnum)) + 1; 7849 else 7850 col = MAXCOL; 7851 } 7852 else 7853 { 7854 col = fp->col + 1; 7855 #ifdef FEAT_VIRTUALEDIT 7856 /* col(".") when the cursor is on the NUL at the end of the line 7857 * because of "coladd" can be seen as an extra column. */ 7858 if (virtual_active() && fp == &curwin->w_cursor) 7859 { 7860 char_u *p = ml_get_cursor(); 7861 7862 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7863 curwin->w_virtcol - curwin->w_cursor.coladd)) 7864 { 7865 # ifdef FEAT_MBYTE 7866 int l; 7867 7868 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 7869 col += l; 7870 # else 7871 if (*p != NUL && p[1] == NUL) 7872 ++col; 7873 # endif 7874 } 7875 } 7876 #endif 7877 } 7878 } 7879 rettv->vval.v_number = col; 7880 } 7881 7882 #if defined(FEAT_INS_EXPAND) 7883 /* 7884 * "complete_add()" function 7885 */ 7886 /*ARGSUSED*/ 7887 static void 7888 f_complete_add(argvars, rettv) 7889 typval_T *argvars; 7890 typval_T *rettv; 7891 { 7892 char_u *s; 7893 7894 s = get_tv_string_chk(&argvars[0]); 7895 if (s != NULL) 7896 rettv->vval.v_number = ins_compl_add(s, -1, NULL, FORWARD, 0); 7897 } 7898 7899 /* 7900 * "complete_check()" function 7901 */ 7902 /*ARGSUSED*/ 7903 static void 7904 f_complete_check(argvars, rettv) 7905 typval_T *argvars; 7906 typval_T *rettv; 7907 { 7908 int saved = RedrawingDisabled; 7909 7910 RedrawingDisabled = 0; 7911 ins_compl_check_keys(0); 7912 rettv->vval.v_number = compl_interrupted; 7913 RedrawingDisabled = saved; 7914 } 7915 #endif 7916 7917 /* 7918 * "confirm(message, buttons[, default [, type]])" function 7919 */ 7920 /*ARGSUSED*/ 7921 static void 7922 f_confirm(argvars, rettv) 7923 typval_T *argvars; 7924 typval_T *rettv; 7925 { 7926 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7927 char_u *message; 7928 char_u *buttons = NULL; 7929 char_u buf[NUMBUFLEN]; 7930 char_u buf2[NUMBUFLEN]; 7931 int def = 1; 7932 int type = VIM_GENERIC; 7933 char_u *typestr; 7934 int error = FALSE; 7935 7936 message = get_tv_string_chk(&argvars[0]); 7937 if (message == NULL) 7938 error = TRUE; 7939 if (argvars[1].v_type != VAR_UNKNOWN) 7940 { 7941 buttons = get_tv_string_buf_chk(&argvars[1], buf); 7942 if (buttons == NULL) 7943 error = TRUE; 7944 if (argvars[2].v_type != VAR_UNKNOWN) 7945 { 7946 def = get_tv_number_chk(&argvars[2], &error); 7947 if (argvars[3].v_type != VAR_UNKNOWN) 7948 { 7949 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 7950 if (typestr == NULL) 7951 error = TRUE; 7952 else 7953 { 7954 switch (TOUPPER_ASC(*typestr)) 7955 { 7956 case 'E': type = VIM_ERROR; break; 7957 case 'Q': type = VIM_QUESTION; break; 7958 case 'I': type = VIM_INFO; break; 7959 case 'W': type = VIM_WARNING; break; 7960 case 'G': type = VIM_GENERIC; break; 7961 } 7962 } 7963 } 7964 } 7965 } 7966 7967 if (buttons == NULL || *buttons == NUL) 7968 buttons = (char_u *)_("&Ok"); 7969 7970 if (error) 7971 rettv->vval.v_number = 0; 7972 else 7973 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 7974 def, NULL); 7975 #else 7976 rettv->vval.v_number = 0; 7977 #endif 7978 } 7979 7980 /* 7981 * "copy()" function 7982 */ 7983 static void 7984 f_copy(argvars, rettv) 7985 typval_T *argvars; 7986 typval_T *rettv; 7987 { 7988 item_copy(&argvars[0], rettv, FALSE, 0); 7989 } 7990 7991 /* 7992 * "count()" function 7993 */ 7994 static void 7995 f_count(argvars, rettv) 7996 typval_T *argvars; 7997 typval_T *rettv; 7998 { 7999 long n = 0; 8000 int ic = FALSE; 8001 8002 if (argvars[0].v_type == VAR_LIST) 8003 { 8004 listitem_T *li; 8005 list_T *l; 8006 long idx; 8007 8008 if ((l = argvars[0].vval.v_list) != NULL) 8009 { 8010 li = l->lv_first; 8011 if (argvars[2].v_type != VAR_UNKNOWN) 8012 { 8013 int error = FALSE; 8014 8015 ic = get_tv_number_chk(&argvars[2], &error); 8016 if (argvars[3].v_type != VAR_UNKNOWN) 8017 { 8018 idx = get_tv_number_chk(&argvars[3], &error); 8019 if (!error) 8020 { 8021 li = list_find(l, idx); 8022 if (li == NULL) 8023 EMSGN(_(e_listidx), idx); 8024 } 8025 } 8026 if (error) 8027 li = NULL; 8028 } 8029 8030 for ( ; li != NULL; li = li->li_next) 8031 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8032 ++n; 8033 } 8034 } 8035 else if (argvars[0].v_type == VAR_DICT) 8036 { 8037 int todo; 8038 dict_T *d; 8039 hashitem_T *hi; 8040 8041 if ((d = argvars[0].vval.v_dict) != NULL) 8042 { 8043 int error = FALSE; 8044 8045 if (argvars[2].v_type != VAR_UNKNOWN) 8046 { 8047 ic = get_tv_number_chk(&argvars[2], &error); 8048 if (argvars[3].v_type != VAR_UNKNOWN) 8049 EMSG(_(e_invarg)); 8050 } 8051 8052 todo = error ? 0 : d->dv_hashtab.ht_used; 8053 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8054 { 8055 if (!HASHITEM_EMPTY(hi)) 8056 { 8057 --todo; 8058 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8059 ++n; 8060 } 8061 } 8062 } 8063 } 8064 else 8065 EMSG2(_(e_listdictarg), "count()"); 8066 rettv->vval.v_number = n; 8067 } 8068 8069 /* 8070 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8071 * 8072 * Checks the existence of a cscope connection. 8073 */ 8074 /*ARGSUSED*/ 8075 static void 8076 f_cscope_connection(argvars, rettv) 8077 typval_T *argvars; 8078 typval_T *rettv; 8079 { 8080 #ifdef FEAT_CSCOPE 8081 int num = 0; 8082 char_u *dbpath = NULL; 8083 char_u *prepend = NULL; 8084 char_u buf[NUMBUFLEN]; 8085 8086 if (argvars[0].v_type != VAR_UNKNOWN 8087 && argvars[1].v_type != VAR_UNKNOWN) 8088 { 8089 num = (int)get_tv_number(&argvars[0]); 8090 dbpath = get_tv_string(&argvars[1]); 8091 if (argvars[2].v_type != VAR_UNKNOWN) 8092 prepend = get_tv_string_buf(&argvars[2], buf); 8093 } 8094 8095 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8096 #else 8097 rettv->vval.v_number = 0; 8098 #endif 8099 } 8100 8101 /* 8102 * "cursor(lnum, col)" function 8103 * 8104 * Moves the cursor to the specified line and column 8105 */ 8106 /*ARGSUSED*/ 8107 static void 8108 f_cursor(argvars, rettv) 8109 typval_T *argvars; 8110 typval_T *rettv; 8111 { 8112 long line, col; 8113 8114 line = get_tv_lnum(argvars); 8115 col = get_tv_number_chk(&argvars[1], NULL); 8116 if (line < 0 || col < 0) 8117 return; /* type error; errmsg already given */ 8118 if (line > 0) 8119 curwin->w_cursor.lnum = line; 8120 if (col > 0) 8121 curwin->w_cursor.col = col - 1; 8122 #ifdef FEAT_VIRTUALEDIT 8123 curwin->w_cursor.coladd = 0; 8124 #endif 8125 8126 /* Make sure the cursor is in a valid position. */ 8127 check_cursor(); 8128 #ifdef FEAT_MBYTE 8129 /* Correct cursor for multi-byte character. */ 8130 if (has_mbyte) 8131 mb_adjust_cursor(); 8132 #endif 8133 8134 curwin->w_set_curswant = TRUE; 8135 } 8136 8137 /* 8138 * "deepcopy()" function 8139 */ 8140 static void 8141 f_deepcopy(argvars, rettv) 8142 typval_T *argvars; 8143 typval_T *rettv; 8144 { 8145 int noref = 0; 8146 8147 if (argvars[1].v_type != VAR_UNKNOWN) 8148 noref = get_tv_number_chk(&argvars[1], NULL); 8149 if (noref < 0 || noref > 1) 8150 EMSG(_(e_invarg)); 8151 else 8152 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8153 } 8154 8155 /* 8156 * "delete()" function 8157 */ 8158 static void 8159 f_delete(argvars, rettv) 8160 typval_T *argvars; 8161 typval_T *rettv; 8162 { 8163 if (check_restricted() || check_secure()) 8164 rettv->vval.v_number = -1; 8165 else 8166 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8167 } 8168 8169 /* 8170 * "did_filetype()" function 8171 */ 8172 /*ARGSUSED*/ 8173 static void 8174 f_did_filetype(argvars, rettv) 8175 typval_T *argvars; 8176 typval_T *rettv; 8177 { 8178 #ifdef FEAT_AUTOCMD 8179 rettv->vval.v_number = did_filetype; 8180 #else 8181 rettv->vval.v_number = 0; 8182 #endif 8183 } 8184 8185 /* 8186 * "diff_filler()" function 8187 */ 8188 /*ARGSUSED*/ 8189 static void 8190 f_diff_filler(argvars, rettv) 8191 typval_T *argvars; 8192 typval_T *rettv; 8193 { 8194 #ifdef FEAT_DIFF 8195 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8196 #endif 8197 } 8198 8199 /* 8200 * "diff_hlID()" function 8201 */ 8202 /*ARGSUSED*/ 8203 static void 8204 f_diff_hlID(argvars, rettv) 8205 typval_T *argvars; 8206 typval_T *rettv; 8207 { 8208 #ifdef FEAT_DIFF 8209 linenr_T lnum = get_tv_lnum(argvars); 8210 static linenr_T prev_lnum = 0; 8211 static int changedtick = 0; 8212 static int fnum = 0; 8213 static int change_start = 0; 8214 static int change_end = 0; 8215 static enum hlf_value hlID = 0; 8216 int filler_lines; 8217 int col; 8218 8219 if (lnum < 0) /* ignore type error in {lnum} arg */ 8220 lnum = 0; 8221 if (lnum != prev_lnum 8222 || changedtick != curbuf->b_changedtick 8223 || fnum != curbuf->b_fnum) 8224 { 8225 /* New line, buffer, change: need to get the values. */ 8226 filler_lines = diff_check(curwin, lnum); 8227 if (filler_lines < 0) 8228 { 8229 if (filler_lines == -1) 8230 { 8231 change_start = MAXCOL; 8232 change_end = -1; 8233 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8234 hlID = HLF_ADD; /* added line */ 8235 else 8236 hlID = HLF_CHD; /* changed line */ 8237 } 8238 else 8239 hlID = HLF_ADD; /* added line */ 8240 } 8241 else 8242 hlID = (enum hlf_value)0; 8243 prev_lnum = lnum; 8244 changedtick = curbuf->b_changedtick; 8245 fnum = curbuf->b_fnum; 8246 } 8247 8248 if (hlID == HLF_CHD || hlID == HLF_TXD) 8249 { 8250 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8251 if (col >= change_start && col <= change_end) 8252 hlID = HLF_TXD; /* changed text */ 8253 else 8254 hlID = HLF_CHD; /* changed line */ 8255 } 8256 rettv->vval.v_number = hlID == (enum hlf_value)0 ? 0 : (int)hlID; 8257 #endif 8258 } 8259 8260 /* 8261 * "empty({expr})" function 8262 */ 8263 static void 8264 f_empty(argvars, rettv) 8265 typval_T *argvars; 8266 typval_T *rettv; 8267 { 8268 int n; 8269 8270 switch (argvars[0].v_type) 8271 { 8272 case VAR_STRING: 8273 case VAR_FUNC: 8274 n = argvars[0].vval.v_string == NULL 8275 || *argvars[0].vval.v_string == NUL; 8276 break; 8277 case VAR_NUMBER: 8278 n = argvars[0].vval.v_number == 0; 8279 break; 8280 case VAR_LIST: 8281 n = argvars[0].vval.v_list == NULL 8282 || argvars[0].vval.v_list->lv_first == NULL; 8283 break; 8284 case VAR_DICT: 8285 n = argvars[0].vval.v_dict == NULL 8286 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8287 break; 8288 default: 8289 EMSG2(_(e_intern2), "f_empty()"); 8290 n = 0; 8291 } 8292 8293 rettv->vval.v_number = n; 8294 } 8295 8296 /* 8297 * "escape({string}, {chars})" function 8298 */ 8299 static void 8300 f_escape(argvars, rettv) 8301 typval_T *argvars; 8302 typval_T *rettv; 8303 { 8304 char_u buf[NUMBUFLEN]; 8305 8306 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8307 get_tv_string_buf(&argvars[1], buf)); 8308 rettv->v_type = VAR_STRING; 8309 } 8310 8311 /* 8312 * "eval()" function 8313 */ 8314 /*ARGSUSED*/ 8315 static void 8316 f_eval(argvars, rettv) 8317 typval_T *argvars; 8318 typval_T *rettv; 8319 { 8320 char_u *s; 8321 8322 s = get_tv_string_chk(&argvars[0]); 8323 if (s != NULL) 8324 s = skipwhite(s); 8325 8326 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8327 { 8328 rettv->v_type = VAR_NUMBER; 8329 rettv->vval.v_number = 0; 8330 } 8331 else if (*s != NUL) 8332 EMSG(_(e_trailing)); 8333 } 8334 8335 /* 8336 * "eventhandler()" function 8337 */ 8338 /*ARGSUSED*/ 8339 static void 8340 f_eventhandler(argvars, rettv) 8341 typval_T *argvars; 8342 typval_T *rettv; 8343 { 8344 rettv->vval.v_number = vgetc_busy; 8345 } 8346 8347 /* 8348 * "executable()" function 8349 */ 8350 static void 8351 f_executable(argvars, rettv) 8352 typval_T *argvars; 8353 typval_T *rettv; 8354 { 8355 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8356 } 8357 8358 /* 8359 * "exists()" function 8360 */ 8361 static void 8362 f_exists(argvars, rettv) 8363 typval_T *argvars; 8364 typval_T *rettv; 8365 { 8366 char_u *p; 8367 char_u *name; 8368 int n = FALSE; 8369 int len = 0; 8370 8371 p = get_tv_string(&argvars[0]); 8372 if (*p == '$') /* environment variable */ 8373 { 8374 /* first try "normal" environment variables (fast) */ 8375 if (mch_getenv(p + 1) != NULL) 8376 n = TRUE; 8377 else 8378 { 8379 /* try expanding things like $VIM and ${HOME} */ 8380 p = expand_env_save(p); 8381 if (p != NULL && *p != '$') 8382 n = TRUE; 8383 vim_free(p); 8384 } 8385 } 8386 else if (*p == '&' || *p == '+') /* option */ 8387 n = (get_option_tv(&p, NULL, TRUE) == OK); 8388 else if (*p == '*') /* internal or user defined function */ 8389 { 8390 n = function_exists(p + 1); 8391 } 8392 else if (*p == ':') 8393 { 8394 n = cmd_exists(p + 1); 8395 } 8396 else if (*p == '#') 8397 { 8398 #ifdef FEAT_AUTOCMD 8399 name = p + 1; 8400 p = vim_strchr(name, '#'); 8401 if (p != NULL) 8402 n = au_exists(name, p, p + 1); 8403 else 8404 n = au_exists(name, name + STRLEN(name), NULL); 8405 #endif 8406 } 8407 else /* internal variable */ 8408 { 8409 char_u *tofree; 8410 typval_T tv; 8411 8412 /* get_name_len() takes care of expanding curly braces */ 8413 name = p; 8414 len = get_name_len(&p, &tofree, TRUE, FALSE); 8415 if (len > 0) 8416 { 8417 if (tofree != NULL) 8418 name = tofree; 8419 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8420 if (n) 8421 { 8422 /* handle d.key, l[idx], f(expr) */ 8423 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8424 if (n) 8425 clear_tv(&tv); 8426 } 8427 } 8428 8429 vim_free(tofree); 8430 } 8431 8432 rettv->vval.v_number = n; 8433 } 8434 8435 /* 8436 * "expand()" function 8437 */ 8438 static void 8439 f_expand(argvars, rettv) 8440 typval_T *argvars; 8441 typval_T *rettv; 8442 { 8443 char_u *s; 8444 int len; 8445 char_u *errormsg; 8446 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8447 expand_T xpc; 8448 int error = FALSE; 8449 8450 rettv->v_type = VAR_STRING; 8451 s = get_tv_string(&argvars[0]); 8452 if (*s == '%' || *s == '#' || *s == '<') 8453 { 8454 ++emsg_off; 8455 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8456 --emsg_off; 8457 } 8458 else 8459 { 8460 /* When the optional second argument is non-zero, don't remove matches 8461 * for 'suffixes' and 'wildignore' */ 8462 if (argvars[1].v_type != VAR_UNKNOWN 8463 && get_tv_number_chk(&argvars[1], &error)) 8464 flags |= WILD_KEEP_ALL; 8465 if (!error) 8466 { 8467 ExpandInit(&xpc); 8468 xpc.xp_context = EXPAND_FILES; 8469 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8470 ExpandCleanup(&xpc); 8471 } 8472 else 8473 rettv->vval.v_string = NULL; 8474 } 8475 } 8476 8477 /* 8478 * "extend(list, list [, idx])" function 8479 * "extend(dict, dict [, action])" function 8480 */ 8481 static void 8482 f_extend(argvars, rettv) 8483 typval_T *argvars; 8484 typval_T *rettv; 8485 { 8486 rettv->vval.v_number = 0; 8487 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8488 { 8489 list_T *l1, *l2; 8490 listitem_T *item; 8491 long before; 8492 int error = FALSE; 8493 8494 l1 = argvars[0].vval.v_list; 8495 l2 = argvars[1].vval.v_list; 8496 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8497 && l2 != NULL) 8498 { 8499 if (argvars[2].v_type != VAR_UNKNOWN) 8500 { 8501 before = get_tv_number_chk(&argvars[2], &error); 8502 if (error) 8503 return; /* type error; errmsg already given */ 8504 8505 if (before == l1->lv_len) 8506 item = NULL; 8507 else 8508 { 8509 item = list_find(l1, before); 8510 if (item == NULL) 8511 { 8512 EMSGN(_(e_listidx), before); 8513 return; 8514 } 8515 } 8516 } 8517 else 8518 item = NULL; 8519 list_extend(l1, l2, item); 8520 8521 copy_tv(&argvars[0], rettv); 8522 } 8523 } 8524 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8525 { 8526 dict_T *d1, *d2; 8527 dictitem_T *di1; 8528 char_u *action; 8529 int i; 8530 hashitem_T *hi2; 8531 int todo; 8532 8533 d1 = argvars[0].vval.v_dict; 8534 d2 = argvars[1].vval.v_dict; 8535 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8536 && d2 != NULL) 8537 { 8538 /* Check the third argument. */ 8539 if (argvars[2].v_type != VAR_UNKNOWN) 8540 { 8541 static char *(av[]) = {"keep", "force", "error"}; 8542 8543 action = get_tv_string_chk(&argvars[2]); 8544 if (action == NULL) 8545 return; /* type error; errmsg already given */ 8546 for (i = 0; i < 3; ++i) 8547 if (STRCMP(action, av[i]) == 0) 8548 break; 8549 if (i == 3) 8550 { 8551 EMSGN(_(e_invarg2), action); 8552 return; 8553 } 8554 } 8555 else 8556 action = (char_u *)"force"; 8557 8558 /* Go over all entries in the second dict and add them to the 8559 * first dict. */ 8560 todo = d2->dv_hashtab.ht_used; 8561 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8562 { 8563 if (!HASHITEM_EMPTY(hi2)) 8564 { 8565 --todo; 8566 di1 = dict_find(d1, hi2->hi_key, -1); 8567 if (di1 == NULL) 8568 { 8569 di1 = dictitem_copy(HI2DI(hi2)); 8570 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8571 dictitem_free(di1); 8572 } 8573 else if (*action == 'e') 8574 { 8575 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8576 break; 8577 } 8578 else if (*action == 'f') 8579 { 8580 clear_tv(&di1->di_tv); 8581 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8582 } 8583 } 8584 } 8585 8586 copy_tv(&argvars[0], rettv); 8587 } 8588 } 8589 else 8590 EMSG2(_(e_listdictarg), "extend()"); 8591 } 8592 8593 /* 8594 * "filereadable()" function 8595 */ 8596 static void 8597 f_filereadable(argvars, rettv) 8598 typval_T *argvars; 8599 typval_T *rettv; 8600 { 8601 FILE *fd; 8602 char_u *p; 8603 int n; 8604 8605 p = get_tv_string(&argvars[0]); 8606 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8607 { 8608 n = TRUE; 8609 fclose(fd); 8610 } 8611 else 8612 n = FALSE; 8613 8614 rettv->vval.v_number = n; 8615 } 8616 8617 /* 8618 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8619 * rights to write into. 8620 */ 8621 static void 8622 f_filewritable(argvars, rettv) 8623 typval_T *argvars; 8624 typval_T *rettv; 8625 { 8626 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8627 } 8628 8629 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8630 8631 static void 8632 findfilendir(argvars, rettv, dir) 8633 typval_T *argvars; 8634 typval_T *rettv; 8635 int dir; 8636 { 8637 #ifdef FEAT_SEARCHPATH 8638 char_u *fname; 8639 char_u *fresult = NULL; 8640 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8641 char_u *p; 8642 char_u pathbuf[NUMBUFLEN]; 8643 int count = 1; 8644 int first = TRUE; 8645 8646 fname = get_tv_string(&argvars[0]); 8647 8648 if (argvars[1].v_type != VAR_UNKNOWN) 8649 { 8650 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8651 if (p == NULL) 8652 count = -1; /* error */ 8653 else 8654 { 8655 if (*p != NUL) 8656 path = p; 8657 8658 if (argvars[2].v_type != VAR_UNKNOWN) 8659 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8660 } 8661 } 8662 8663 if (*fname != NUL && count >= 0) 8664 { 8665 do 8666 { 8667 vim_free(fresult); 8668 fresult = find_file_in_path_option(first ? fname : NULL, 8669 first ? (int)STRLEN(fname) : 0, 8670 0, first, path, dir, NULL); 8671 first = FALSE; 8672 } while (--count > 0 && fresult != NULL); 8673 } 8674 8675 rettv->vval.v_string = fresult; 8676 #else 8677 rettv->vval.v_string = NULL; 8678 #endif 8679 rettv->v_type = VAR_STRING; 8680 } 8681 8682 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8683 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8684 8685 /* 8686 * Implementation of map() and filter(). 8687 */ 8688 static void 8689 filter_map(argvars, rettv, map) 8690 typval_T *argvars; 8691 typval_T *rettv; 8692 int map; 8693 { 8694 char_u buf[NUMBUFLEN]; 8695 char_u *expr; 8696 listitem_T *li, *nli; 8697 list_T *l = NULL; 8698 dictitem_T *di; 8699 hashtab_T *ht; 8700 hashitem_T *hi; 8701 dict_T *d = NULL; 8702 typval_T save_val; 8703 typval_T save_key; 8704 int rem; 8705 int todo; 8706 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8707 8708 8709 rettv->vval.v_number = 0; 8710 if (argvars[0].v_type == VAR_LIST) 8711 { 8712 if ((l = argvars[0].vval.v_list) == NULL 8713 || (map && tv_check_lock(l->lv_lock, msg))) 8714 return; 8715 } 8716 else if (argvars[0].v_type == VAR_DICT) 8717 { 8718 if ((d = argvars[0].vval.v_dict) == NULL 8719 || (map && tv_check_lock(d->dv_lock, msg))) 8720 return; 8721 } 8722 else 8723 { 8724 EMSG2(_(e_listdictarg), msg); 8725 return; 8726 } 8727 8728 expr = get_tv_string_buf_chk(&argvars[1], buf); 8729 /* On type errors, the preceding call has already displayed an error 8730 * message. Avoid a misleading error message for an empty string that 8731 * was not passed as argument. */ 8732 if (expr != NULL) 8733 { 8734 prepare_vimvar(VV_VAL, &save_val); 8735 expr = skipwhite(expr); 8736 8737 if (argvars[0].v_type == VAR_DICT) 8738 { 8739 prepare_vimvar(VV_KEY, &save_key); 8740 vimvars[VV_KEY].vv_type = VAR_STRING; 8741 8742 ht = &d->dv_hashtab; 8743 hash_lock(ht); 8744 todo = ht->ht_used; 8745 for (hi = ht->ht_array; todo > 0; ++hi) 8746 { 8747 if (!HASHITEM_EMPTY(hi)) 8748 { 8749 --todo; 8750 di = HI2DI(hi); 8751 if (tv_check_lock(di->di_tv.v_lock, msg)) 8752 break; 8753 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8754 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8755 break; 8756 if (!map && rem) 8757 dictitem_remove(d, di); 8758 clear_tv(&vimvars[VV_KEY].vv_tv); 8759 } 8760 } 8761 hash_unlock(ht); 8762 8763 restore_vimvar(VV_KEY, &save_key); 8764 } 8765 else 8766 { 8767 for (li = l->lv_first; li != NULL; li = nli) 8768 { 8769 if (tv_check_lock(li->li_tv.v_lock, msg)) 8770 break; 8771 nli = li->li_next; 8772 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8773 break; 8774 if (!map && rem) 8775 listitem_remove(l, li); 8776 } 8777 } 8778 8779 restore_vimvar(VV_VAL, &save_val); 8780 } 8781 8782 copy_tv(&argvars[0], rettv); 8783 } 8784 8785 static int 8786 filter_map_one(tv, expr, map, remp) 8787 typval_T *tv; 8788 char_u *expr; 8789 int map; 8790 int *remp; 8791 { 8792 typval_T rettv; 8793 char_u *s; 8794 8795 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8796 s = expr; 8797 if (eval1(&s, &rettv, TRUE) == FAIL) 8798 return FAIL; 8799 if (*s != NUL) /* check for trailing chars after expr */ 8800 { 8801 EMSG2(_(e_invexpr2), s); 8802 return FAIL; 8803 } 8804 if (map) 8805 { 8806 /* map(): replace the list item value */ 8807 clear_tv(tv); 8808 *tv = rettv; 8809 } 8810 else 8811 { 8812 int error = FALSE; 8813 8814 /* filter(): when expr is zero remove the item */ 8815 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8816 clear_tv(&rettv); 8817 /* On type error, nothing has been removed; return FAIL to stop the 8818 * loop. The error message was given by get_tv_number_chk(). */ 8819 if (error) 8820 return FAIL; 8821 } 8822 clear_tv(&vimvars[VV_VAL].vv_tv); 8823 return OK; 8824 } 8825 8826 /* 8827 * "filter()" function 8828 */ 8829 static void 8830 f_filter(argvars, rettv) 8831 typval_T *argvars; 8832 typval_T *rettv; 8833 { 8834 filter_map(argvars, rettv, FALSE); 8835 } 8836 8837 /* 8838 * "finddir({fname}[, {path}[, {count}]])" function 8839 */ 8840 static void 8841 f_finddir(argvars, rettv) 8842 typval_T *argvars; 8843 typval_T *rettv; 8844 { 8845 findfilendir(argvars, rettv, TRUE); 8846 } 8847 8848 /* 8849 * "findfile({fname}[, {path}[, {count}]])" function 8850 */ 8851 static void 8852 f_findfile(argvars, rettv) 8853 typval_T *argvars; 8854 typval_T *rettv; 8855 { 8856 findfilendir(argvars, rettv, FALSE); 8857 } 8858 8859 /* 8860 * "fnamemodify({fname}, {mods})" function 8861 */ 8862 static void 8863 f_fnamemodify(argvars, rettv) 8864 typval_T *argvars; 8865 typval_T *rettv; 8866 { 8867 char_u *fname; 8868 char_u *mods; 8869 int usedlen = 0; 8870 int len; 8871 char_u *fbuf = NULL; 8872 char_u buf[NUMBUFLEN]; 8873 8874 fname = get_tv_string_chk(&argvars[0]); 8875 mods = get_tv_string_buf_chk(&argvars[1], buf); 8876 if (fname == NULL || mods == NULL) 8877 fname = NULL; 8878 else 8879 { 8880 len = (int)STRLEN(fname); 8881 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8882 } 8883 8884 rettv->v_type = VAR_STRING; 8885 if (fname == NULL) 8886 rettv->vval.v_string = NULL; 8887 else 8888 rettv->vval.v_string = vim_strnsave(fname, len); 8889 vim_free(fbuf); 8890 } 8891 8892 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8893 8894 /* 8895 * "foldclosed()" function 8896 */ 8897 static void 8898 foldclosed_both(argvars, rettv, end) 8899 typval_T *argvars; 8900 typval_T *rettv; 8901 int end; 8902 { 8903 #ifdef FEAT_FOLDING 8904 linenr_T lnum; 8905 linenr_T first, last; 8906 8907 lnum = get_tv_lnum(argvars); 8908 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8909 { 8910 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8911 { 8912 if (end) 8913 rettv->vval.v_number = (varnumber_T)last; 8914 else 8915 rettv->vval.v_number = (varnumber_T)first; 8916 return; 8917 } 8918 } 8919 #endif 8920 rettv->vval.v_number = -1; 8921 } 8922 8923 /* 8924 * "foldclosed()" function 8925 */ 8926 static void 8927 f_foldclosed(argvars, rettv) 8928 typval_T *argvars; 8929 typval_T *rettv; 8930 { 8931 foldclosed_both(argvars, rettv, FALSE); 8932 } 8933 8934 /* 8935 * "foldclosedend()" function 8936 */ 8937 static void 8938 f_foldclosedend(argvars, rettv) 8939 typval_T *argvars; 8940 typval_T *rettv; 8941 { 8942 foldclosed_both(argvars, rettv, TRUE); 8943 } 8944 8945 /* 8946 * "foldlevel()" function 8947 */ 8948 static void 8949 f_foldlevel(argvars, rettv) 8950 typval_T *argvars; 8951 typval_T *rettv; 8952 { 8953 #ifdef FEAT_FOLDING 8954 linenr_T lnum; 8955 8956 lnum = get_tv_lnum(argvars); 8957 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8958 rettv->vval.v_number = foldLevel(lnum); 8959 else 8960 #endif 8961 rettv->vval.v_number = 0; 8962 } 8963 8964 /* 8965 * "foldtext()" function 8966 */ 8967 /*ARGSUSED*/ 8968 static void 8969 f_foldtext(argvars, rettv) 8970 typval_T *argvars; 8971 typval_T *rettv; 8972 { 8973 #ifdef FEAT_FOLDING 8974 linenr_T lnum; 8975 char_u *s; 8976 char_u *r; 8977 int len; 8978 char *txt; 8979 #endif 8980 8981 rettv->v_type = VAR_STRING; 8982 rettv->vval.v_string = NULL; 8983 #ifdef FEAT_FOLDING 8984 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 8985 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 8986 <= curbuf->b_ml.ml_line_count 8987 && vimvars[VV_FOLDDASHES].vv_str != NULL) 8988 { 8989 /* Find first non-empty line in the fold. */ 8990 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 8991 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 8992 { 8993 if (!linewhite(lnum)) 8994 break; 8995 ++lnum; 8996 } 8997 8998 /* Find interesting text in this line. */ 8999 s = skipwhite(ml_get(lnum)); 9000 /* skip C comment-start */ 9001 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9002 { 9003 s = skipwhite(s + 2); 9004 if (*skipwhite(s) == NUL 9005 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9006 { 9007 s = skipwhite(ml_get(lnum + 1)); 9008 if (*s == '*') 9009 s = skipwhite(s + 1); 9010 } 9011 } 9012 txt = _("+-%s%3ld lines: "); 9013 r = alloc((unsigned)(STRLEN(txt) 9014 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9015 + 20 /* for %3ld */ 9016 + STRLEN(s))); /* concatenated */ 9017 if (r != NULL) 9018 { 9019 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9020 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9021 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9022 len = (int)STRLEN(r); 9023 STRCAT(r, s); 9024 /* remove 'foldmarker' and 'commentstring' */ 9025 foldtext_cleanup(r + len); 9026 rettv->vval.v_string = r; 9027 } 9028 } 9029 #endif 9030 } 9031 9032 /* 9033 * "foldtextresult(lnum)" function 9034 */ 9035 /*ARGSUSED*/ 9036 static void 9037 f_foldtextresult(argvars, rettv) 9038 typval_T *argvars; 9039 typval_T *rettv; 9040 { 9041 #ifdef FEAT_FOLDING 9042 linenr_T lnum; 9043 char_u *text; 9044 char_u buf[51]; 9045 foldinfo_T foldinfo; 9046 int fold_count; 9047 #endif 9048 9049 rettv->v_type = VAR_STRING; 9050 rettv->vval.v_string = NULL; 9051 #ifdef FEAT_FOLDING 9052 lnum = get_tv_lnum(argvars); 9053 /* treat illegal types and illegal string values for {lnum} the same */ 9054 if (lnum < 0) 9055 lnum = 0; 9056 fold_count = foldedCount(curwin, lnum, &foldinfo); 9057 if (fold_count > 0) 9058 { 9059 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9060 &foldinfo, buf); 9061 if (text == buf) 9062 text = vim_strsave(text); 9063 rettv->vval.v_string = text; 9064 } 9065 #endif 9066 } 9067 9068 /* 9069 * "foreground()" function 9070 */ 9071 /*ARGSUSED*/ 9072 static void 9073 f_foreground(argvars, rettv) 9074 typval_T *argvars; 9075 typval_T *rettv; 9076 { 9077 rettv->vval.v_number = 0; 9078 #ifdef FEAT_GUI 9079 if (gui.in_use) 9080 gui_mch_set_foreground(); 9081 #else 9082 # ifdef WIN32 9083 win32_set_foreground(); 9084 # endif 9085 #endif 9086 } 9087 9088 /* 9089 * "function()" function 9090 */ 9091 /*ARGSUSED*/ 9092 static void 9093 f_function(argvars, rettv) 9094 typval_T *argvars; 9095 typval_T *rettv; 9096 { 9097 char_u *s; 9098 9099 rettv->vval.v_number = 0; 9100 s = get_tv_string(&argvars[0]); 9101 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9102 EMSG2(_(e_invarg2), s); 9103 else if (!function_exists(s)) 9104 EMSG2(_("E700: Unknown function: %s"), s); 9105 else 9106 { 9107 rettv->vval.v_string = vim_strsave(s); 9108 rettv->v_type = VAR_FUNC; 9109 } 9110 } 9111 9112 /* 9113 * "garbagecollect()" function 9114 */ 9115 /*ARGSUSED*/ 9116 static void 9117 f_garbagecollect(argvars, rettv) 9118 typval_T *argvars; 9119 typval_T *rettv; 9120 { 9121 garbage_collect(); 9122 } 9123 9124 /* 9125 * "get()" function 9126 */ 9127 static void 9128 f_get(argvars, rettv) 9129 typval_T *argvars; 9130 typval_T *rettv; 9131 { 9132 listitem_T *li; 9133 list_T *l; 9134 dictitem_T *di; 9135 dict_T *d; 9136 typval_T *tv = NULL; 9137 9138 if (argvars[0].v_type == VAR_LIST) 9139 { 9140 if ((l = argvars[0].vval.v_list) != NULL) 9141 { 9142 int error = FALSE; 9143 9144 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9145 if (!error && li != NULL) 9146 tv = &li->li_tv; 9147 } 9148 } 9149 else if (argvars[0].v_type == VAR_DICT) 9150 { 9151 if ((d = argvars[0].vval.v_dict) != NULL) 9152 { 9153 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9154 if (di != NULL) 9155 tv = &di->di_tv; 9156 } 9157 } 9158 else 9159 EMSG2(_(e_listdictarg), "get()"); 9160 9161 if (tv == NULL) 9162 { 9163 if (argvars[2].v_type == VAR_UNKNOWN) 9164 rettv->vval.v_number = 0; 9165 else 9166 copy_tv(&argvars[2], rettv); 9167 } 9168 else 9169 copy_tv(tv, rettv); 9170 } 9171 9172 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9173 9174 /* 9175 * Get line or list of lines from buffer "buf" into "rettv". 9176 * Return a range (from start to end) of lines in rettv from the specified 9177 * buffer. 9178 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9179 */ 9180 static void 9181 get_buffer_lines(buf, start, end, retlist, rettv) 9182 buf_T *buf; 9183 linenr_T start; 9184 linenr_T end; 9185 int retlist; 9186 typval_T *rettv; 9187 { 9188 char_u *p; 9189 list_T *l = NULL; 9190 listitem_T *li; 9191 9192 if (retlist) 9193 { 9194 l = list_alloc(); 9195 if (l == NULL) 9196 return; 9197 9198 rettv->vval.v_list = l; 9199 rettv->v_type = VAR_LIST; 9200 ++l->lv_refcount; 9201 } 9202 else 9203 rettv->vval.v_number = 0; 9204 9205 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9206 return; 9207 9208 if (!retlist) 9209 { 9210 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9211 p = ml_get_buf(buf, start, FALSE); 9212 else 9213 p = (char_u *)""; 9214 9215 rettv->v_type = VAR_STRING; 9216 rettv->vval.v_string = vim_strsave(p); 9217 } 9218 else 9219 { 9220 if (end < start) 9221 return; 9222 9223 if (start < 1) 9224 start = 1; 9225 if (end > buf->b_ml.ml_line_count) 9226 end = buf->b_ml.ml_line_count; 9227 while (start <= end) 9228 { 9229 li = listitem_alloc(); 9230 if (li == NULL) 9231 break; 9232 list_append(l, li); 9233 li->li_tv.v_type = VAR_STRING; 9234 li->li_tv.v_lock = 0; 9235 li->li_tv.vval.v_string = 9236 vim_strsave(ml_get_buf(buf, start++, FALSE)); 9237 } 9238 } 9239 } 9240 9241 /* 9242 * "getbufline()" function 9243 */ 9244 static void 9245 f_getbufline(argvars, rettv) 9246 typval_T *argvars; 9247 typval_T *rettv; 9248 { 9249 linenr_T lnum; 9250 linenr_T end; 9251 buf_T *buf; 9252 9253 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9254 ++emsg_off; 9255 buf = get_buf_tv(&argvars[0]); 9256 --emsg_off; 9257 9258 lnum = get_tv_lnum_buf(&argvars[1], buf); 9259 if (argvars[2].v_type == VAR_UNKNOWN) 9260 end = lnum; 9261 else 9262 end = get_tv_lnum_buf(&argvars[2], buf); 9263 9264 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9265 } 9266 9267 /* 9268 * "getbufvar()" function 9269 */ 9270 static void 9271 f_getbufvar(argvars, rettv) 9272 typval_T *argvars; 9273 typval_T *rettv; 9274 { 9275 buf_T *buf; 9276 buf_T *save_curbuf; 9277 char_u *varname; 9278 dictitem_T *v; 9279 9280 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9281 varname = get_tv_string_chk(&argvars[1]); 9282 ++emsg_off; 9283 buf = get_buf_tv(&argvars[0]); 9284 9285 rettv->v_type = VAR_STRING; 9286 rettv->vval.v_string = NULL; 9287 9288 if (buf != NULL && varname != NULL) 9289 { 9290 if (*varname == '&') /* buffer-local-option */ 9291 { 9292 /* set curbuf to be our buf, temporarily */ 9293 save_curbuf = curbuf; 9294 curbuf = buf; 9295 9296 get_option_tv(&varname, rettv, TRUE); 9297 9298 /* restore previous notion of curbuf */ 9299 curbuf = save_curbuf; 9300 } 9301 else 9302 { 9303 if (*varname == NUL) 9304 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9305 * scope prefix before the NUL byte is required by 9306 * find_var_in_ht(). */ 9307 varname = (char_u *)"b:" + 2; 9308 /* look up the variable */ 9309 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9310 if (v != NULL) 9311 copy_tv(&v->di_tv, rettv); 9312 } 9313 } 9314 9315 --emsg_off; 9316 } 9317 9318 /* 9319 * "getchar()" function 9320 */ 9321 static void 9322 f_getchar(argvars, rettv) 9323 typval_T *argvars; 9324 typval_T *rettv; 9325 { 9326 varnumber_T n; 9327 int error = FALSE; 9328 9329 ++no_mapping; 9330 ++allow_keys; 9331 if (argvars[0].v_type == VAR_UNKNOWN) 9332 /* getchar(): blocking wait. */ 9333 n = safe_vgetc(); 9334 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9335 /* getchar(1): only check if char avail */ 9336 n = vpeekc(); 9337 else if (error || vpeekc() == NUL) 9338 /* illegal argument or getchar(0) and no char avail: return zero */ 9339 n = 0; 9340 else 9341 /* getchar(0) and char avail: return char */ 9342 n = safe_vgetc(); 9343 --no_mapping; 9344 --allow_keys; 9345 9346 rettv->vval.v_number = n; 9347 if (IS_SPECIAL(n) || mod_mask != 0) 9348 { 9349 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9350 int i = 0; 9351 9352 /* Turn a special key into three bytes, plus modifier. */ 9353 if (mod_mask != 0) 9354 { 9355 temp[i++] = K_SPECIAL; 9356 temp[i++] = KS_MODIFIER; 9357 temp[i++] = mod_mask; 9358 } 9359 if (IS_SPECIAL(n)) 9360 { 9361 temp[i++] = K_SPECIAL; 9362 temp[i++] = K_SECOND(n); 9363 temp[i++] = K_THIRD(n); 9364 } 9365 #ifdef FEAT_MBYTE 9366 else if (has_mbyte) 9367 i += (*mb_char2bytes)(n, temp + i); 9368 #endif 9369 else 9370 temp[i++] = n; 9371 temp[i++] = NUL; 9372 rettv->v_type = VAR_STRING; 9373 rettv->vval.v_string = vim_strsave(temp); 9374 } 9375 } 9376 9377 /* 9378 * "getcharmod()" function 9379 */ 9380 /*ARGSUSED*/ 9381 static void 9382 f_getcharmod(argvars, rettv) 9383 typval_T *argvars; 9384 typval_T *rettv; 9385 { 9386 rettv->vval.v_number = mod_mask; 9387 } 9388 9389 /* 9390 * "getcmdline()" function 9391 */ 9392 /*ARGSUSED*/ 9393 static void 9394 f_getcmdline(argvars, rettv) 9395 typval_T *argvars; 9396 typval_T *rettv; 9397 { 9398 rettv->v_type = VAR_STRING; 9399 rettv->vval.v_string = get_cmdline_str(); 9400 } 9401 9402 /* 9403 * "getcmdpos()" function 9404 */ 9405 /*ARGSUSED*/ 9406 static void 9407 f_getcmdpos(argvars, rettv) 9408 typval_T *argvars; 9409 typval_T *rettv; 9410 { 9411 rettv->vval.v_number = get_cmdline_pos() + 1; 9412 } 9413 9414 /* 9415 * "getcwd()" function 9416 */ 9417 /*ARGSUSED*/ 9418 static void 9419 f_getcwd(argvars, rettv) 9420 typval_T *argvars; 9421 typval_T *rettv; 9422 { 9423 char_u cwd[MAXPATHL]; 9424 9425 rettv->v_type = VAR_STRING; 9426 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9427 rettv->vval.v_string = NULL; 9428 else 9429 { 9430 rettv->vval.v_string = vim_strsave(cwd); 9431 #ifdef BACKSLASH_IN_FILENAME 9432 if (rettv->vval.v_string != NULL) 9433 slash_adjust(rettv->vval.v_string); 9434 #endif 9435 } 9436 } 9437 9438 /* 9439 * "getfontname()" function 9440 */ 9441 /*ARGSUSED*/ 9442 static void 9443 f_getfontname(argvars, rettv) 9444 typval_T *argvars; 9445 typval_T *rettv; 9446 { 9447 rettv->v_type = VAR_STRING; 9448 rettv->vval.v_string = NULL; 9449 #ifdef FEAT_GUI 9450 if (gui.in_use) 9451 { 9452 GuiFont font; 9453 char_u *name = NULL; 9454 9455 if (argvars[0].v_type == VAR_UNKNOWN) 9456 { 9457 /* Get the "Normal" font. Either the name saved by 9458 * hl_set_font_name() or from the font ID. */ 9459 font = gui.norm_font; 9460 name = hl_get_font_name(); 9461 } 9462 else 9463 { 9464 name = get_tv_string(&argvars[0]); 9465 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9466 return; 9467 font = gui_mch_get_font(name, FALSE); 9468 if (font == NOFONT) 9469 return; /* Invalid font name, return empty string. */ 9470 } 9471 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9472 if (argvars[0].v_type != VAR_UNKNOWN) 9473 gui_mch_free_font(font); 9474 } 9475 #endif 9476 } 9477 9478 /* 9479 * "getfperm({fname})" function 9480 */ 9481 static void 9482 f_getfperm(argvars, rettv) 9483 typval_T *argvars; 9484 typval_T *rettv; 9485 { 9486 char_u *fname; 9487 struct stat st; 9488 char_u *perm = NULL; 9489 char_u flags[] = "rwx"; 9490 int i; 9491 9492 fname = get_tv_string(&argvars[0]); 9493 9494 rettv->v_type = VAR_STRING; 9495 if (mch_stat((char *)fname, &st) >= 0) 9496 { 9497 perm = vim_strsave((char_u *)"---------"); 9498 if (perm != NULL) 9499 { 9500 for (i = 0; i < 9; i++) 9501 { 9502 if (st.st_mode & (1 << (8 - i))) 9503 perm[i] = flags[i % 3]; 9504 } 9505 } 9506 } 9507 rettv->vval.v_string = perm; 9508 } 9509 9510 /* 9511 * "getfsize({fname})" function 9512 */ 9513 static void 9514 f_getfsize(argvars, rettv) 9515 typval_T *argvars; 9516 typval_T *rettv; 9517 { 9518 char_u *fname; 9519 struct stat st; 9520 9521 fname = get_tv_string(&argvars[0]); 9522 9523 rettv->v_type = VAR_NUMBER; 9524 9525 if (mch_stat((char *)fname, &st) >= 0) 9526 { 9527 if (mch_isdir(fname)) 9528 rettv->vval.v_number = 0; 9529 else 9530 rettv->vval.v_number = (varnumber_T)st.st_size; 9531 } 9532 else 9533 rettv->vval.v_number = -1; 9534 } 9535 9536 /* 9537 * "getftime({fname})" function 9538 */ 9539 static void 9540 f_getftime(argvars, rettv) 9541 typval_T *argvars; 9542 typval_T *rettv; 9543 { 9544 char_u *fname; 9545 struct stat st; 9546 9547 fname = get_tv_string(&argvars[0]); 9548 9549 if (mch_stat((char *)fname, &st) >= 0) 9550 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9551 else 9552 rettv->vval.v_number = -1; 9553 } 9554 9555 /* 9556 * "getftype({fname})" function 9557 */ 9558 static void 9559 f_getftype(argvars, rettv) 9560 typval_T *argvars; 9561 typval_T *rettv; 9562 { 9563 char_u *fname; 9564 struct stat st; 9565 char_u *type = NULL; 9566 char *t; 9567 9568 fname = get_tv_string(&argvars[0]); 9569 9570 rettv->v_type = VAR_STRING; 9571 if (mch_lstat((char *)fname, &st) >= 0) 9572 { 9573 #ifdef S_ISREG 9574 if (S_ISREG(st.st_mode)) 9575 t = "file"; 9576 else if (S_ISDIR(st.st_mode)) 9577 t = "dir"; 9578 # ifdef S_ISLNK 9579 else if (S_ISLNK(st.st_mode)) 9580 t = "link"; 9581 # endif 9582 # ifdef S_ISBLK 9583 else if (S_ISBLK(st.st_mode)) 9584 t = "bdev"; 9585 # endif 9586 # ifdef S_ISCHR 9587 else if (S_ISCHR(st.st_mode)) 9588 t = "cdev"; 9589 # endif 9590 # ifdef S_ISFIFO 9591 else if (S_ISFIFO(st.st_mode)) 9592 t = "fifo"; 9593 # endif 9594 # ifdef S_ISSOCK 9595 else if (S_ISSOCK(st.st_mode)) 9596 t = "fifo"; 9597 # endif 9598 else 9599 t = "other"; 9600 #else 9601 # ifdef S_IFMT 9602 switch (st.st_mode & S_IFMT) 9603 { 9604 case S_IFREG: t = "file"; break; 9605 case S_IFDIR: t = "dir"; break; 9606 # ifdef S_IFLNK 9607 case S_IFLNK: t = "link"; break; 9608 # endif 9609 # ifdef S_IFBLK 9610 case S_IFBLK: t = "bdev"; break; 9611 # endif 9612 # ifdef S_IFCHR 9613 case S_IFCHR: t = "cdev"; break; 9614 # endif 9615 # ifdef S_IFIFO 9616 case S_IFIFO: t = "fifo"; break; 9617 # endif 9618 # ifdef S_IFSOCK 9619 case S_IFSOCK: t = "socket"; break; 9620 # endif 9621 default: t = "other"; 9622 } 9623 # else 9624 if (mch_isdir(fname)) 9625 t = "dir"; 9626 else 9627 t = "file"; 9628 # endif 9629 #endif 9630 type = vim_strsave((char_u *)t); 9631 } 9632 rettv->vval.v_string = type; 9633 } 9634 9635 /* 9636 * "getline(lnum, [end])" function 9637 */ 9638 static void 9639 f_getline(argvars, rettv) 9640 typval_T *argvars; 9641 typval_T *rettv; 9642 { 9643 linenr_T lnum; 9644 linenr_T end; 9645 int retlist; 9646 9647 lnum = get_tv_lnum(argvars); 9648 if (argvars[1].v_type == VAR_UNKNOWN) 9649 { 9650 end = 0; 9651 retlist = FALSE; 9652 } 9653 else 9654 { 9655 end = get_tv_lnum(&argvars[1]); 9656 retlist = TRUE; 9657 } 9658 9659 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9660 } 9661 9662 /* 9663 * "getqflist()" function 9664 */ 9665 /*ARGSUSED*/ 9666 static void 9667 f_getqflist(argvars, rettv) 9668 typval_T *argvars; 9669 typval_T *rettv; 9670 { 9671 #ifdef FEAT_QUICKFIX 9672 list_T *l; 9673 #endif 9674 9675 rettv->vval.v_number = FALSE; 9676 #ifdef FEAT_QUICKFIX 9677 l = list_alloc(); 9678 if (l != NULL) 9679 { 9680 if (get_errorlist(l) != FAIL) 9681 { 9682 rettv->vval.v_list = l; 9683 rettv->v_type = VAR_LIST; 9684 ++l->lv_refcount; 9685 } 9686 else 9687 list_free(l); 9688 } 9689 #endif 9690 } 9691 9692 /* 9693 * "getreg()" function 9694 */ 9695 static void 9696 f_getreg(argvars, rettv) 9697 typval_T *argvars; 9698 typval_T *rettv; 9699 { 9700 char_u *strregname; 9701 int regname; 9702 int arg2 = FALSE; 9703 int error = FALSE; 9704 9705 if (argvars[0].v_type != VAR_UNKNOWN) 9706 { 9707 strregname = get_tv_string_chk(&argvars[0]); 9708 error = strregname == NULL; 9709 if (argvars[1].v_type != VAR_UNKNOWN) 9710 arg2 = get_tv_number_chk(&argvars[1], &error); 9711 } 9712 else 9713 strregname = vimvars[VV_REG].vv_str; 9714 regname = (strregname == NULL ? '"' : *strregname); 9715 if (regname == 0) 9716 regname = '"'; 9717 9718 rettv->v_type = VAR_STRING; 9719 rettv->vval.v_string = error ? NULL : 9720 get_reg_contents(regname, TRUE, arg2); 9721 } 9722 9723 /* 9724 * "getregtype()" function 9725 */ 9726 static void 9727 f_getregtype(argvars, rettv) 9728 typval_T *argvars; 9729 typval_T *rettv; 9730 { 9731 char_u *strregname; 9732 int regname; 9733 char_u buf[NUMBUFLEN + 2]; 9734 long reglen = 0; 9735 9736 if (argvars[0].v_type != VAR_UNKNOWN) 9737 { 9738 strregname = get_tv_string_chk(&argvars[0]); 9739 if (strregname == NULL) /* type error; errmsg already given */ 9740 { 9741 rettv->v_type = VAR_STRING; 9742 rettv->vval.v_string = NULL; 9743 return; 9744 } 9745 } 9746 else 9747 /* Default to v:register */ 9748 strregname = vimvars[VV_REG].vv_str; 9749 9750 regname = (strregname == NULL ? '"' : *strregname); 9751 if (regname == 0) 9752 regname = '"'; 9753 9754 buf[0] = NUL; 9755 buf[1] = NUL; 9756 switch (get_reg_type(regname, ®len)) 9757 { 9758 case MLINE: buf[0] = 'V'; break; 9759 case MCHAR: buf[0] = 'v'; break; 9760 #ifdef FEAT_VISUAL 9761 case MBLOCK: 9762 buf[0] = Ctrl_V; 9763 sprintf((char *)buf + 1, "%ld", reglen + 1); 9764 break; 9765 #endif 9766 } 9767 rettv->v_type = VAR_STRING; 9768 rettv->vval.v_string = vim_strsave(buf); 9769 } 9770 9771 /* 9772 * "getwinposx()" function 9773 */ 9774 /*ARGSUSED*/ 9775 static void 9776 f_getwinposx(argvars, rettv) 9777 typval_T *argvars; 9778 typval_T *rettv; 9779 { 9780 rettv->vval.v_number = -1; 9781 #ifdef FEAT_GUI 9782 if (gui.in_use) 9783 { 9784 int x, y; 9785 9786 if (gui_mch_get_winpos(&x, &y) == OK) 9787 rettv->vval.v_number = x; 9788 } 9789 #endif 9790 } 9791 9792 /* 9793 * "getwinposy()" function 9794 */ 9795 /*ARGSUSED*/ 9796 static void 9797 f_getwinposy(argvars, rettv) 9798 typval_T *argvars; 9799 typval_T *rettv; 9800 { 9801 rettv->vval.v_number = -1; 9802 #ifdef FEAT_GUI 9803 if (gui.in_use) 9804 { 9805 int x, y; 9806 9807 if (gui_mch_get_winpos(&x, &y) == OK) 9808 rettv->vval.v_number = y; 9809 } 9810 #endif 9811 } 9812 9813 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9814 9815 static win_T * 9816 find_win_by_nr(vp) 9817 typval_T *vp; 9818 { 9819 #ifdef FEAT_WINDOWS 9820 win_T *wp; 9821 #endif 9822 int nr; 9823 9824 nr = get_tv_number_chk(vp, NULL); 9825 9826 #ifdef FEAT_WINDOWS 9827 if (nr < 0) 9828 return NULL; 9829 if (nr == 0) 9830 return curwin; 9831 9832 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9833 if (--nr <= 0) 9834 break; 9835 return wp; 9836 #else 9837 if (nr == 0 || nr == 1) 9838 return curwin; 9839 return NULL; 9840 #endif 9841 } 9842 9843 /* 9844 * "getwinvar()" function 9845 */ 9846 static void 9847 f_getwinvar(argvars, rettv) 9848 typval_T *argvars; 9849 typval_T *rettv; 9850 { 9851 win_T *win, *oldcurwin; 9852 char_u *varname; 9853 dictitem_T *v; 9854 9855 win = find_win_by_nr(&argvars[0]); 9856 varname = get_tv_string_chk(&argvars[1]); 9857 ++emsg_off; 9858 9859 rettv->v_type = VAR_STRING; 9860 rettv->vval.v_string = NULL; 9861 9862 if (win != NULL && varname != NULL) 9863 { 9864 if (*varname == '&') /* window-local-option */ 9865 { 9866 /* Set curwin to be our win, temporarily. Also set curbuf, so 9867 * that we can get buffer-local options. */ 9868 oldcurwin = curwin; 9869 curwin = win; 9870 curbuf = win->w_buffer; 9871 9872 get_option_tv(&varname, rettv, 1); 9873 9874 /* restore previous notion of curwin */ 9875 curwin = oldcurwin; 9876 curbuf = curwin->w_buffer; 9877 } 9878 else 9879 { 9880 if (*varname == NUL) 9881 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9882 * scope prefix before the NUL byte is required by 9883 * find_var_in_ht(). */ 9884 varname = (char_u *)"w:" + 2; 9885 /* look up the variable */ 9886 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9887 if (v != NULL) 9888 copy_tv(&v->di_tv, rettv); 9889 } 9890 } 9891 9892 --emsg_off; 9893 } 9894 9895 /* 9896 * "glob()" function 9897 */ 9898 static void 9899 f_glob(argvars, rettv) 9900 typval_T *argvars; 9901 typval_T *rettv; 9902 { 9903 expand_T xpc; 9904 9905 ExpandInit(&xpc); 9906 xpc.xp_context = EXPAND_FILES; 9907 rettv->v_type = VAR_STRING; 9908 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9909 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9910 ExpandCleanup(&xpc); 9911 } 9912 9913 /* 9914 * "globpath()" function 9915 */ 9916 static void 9917 f_globpath(argvars, rettv) 9918 typval_T *argvars; 9919 typval_T *rettv; 9920 { 9921 char_u buf1[NUMBUFLEN]; 9922 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9923 9924 rettv->v_type = VAR_STRING; 9925 if (file == NULL) 9926 rettv->vval.v_string = NULL; 9927 else 9928 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9929 } 9930 9931 /* 9932 * "has()" function 9933 */ 9934 static void 9935 f_has(argvars, rettv) 9936 typval_T *argvars; 9937 typval_T *rettv; 9938 { 9939 int i; 9940 char_u *name; 9941 int n = FALSE; 9942 static char *(has_list[]) = 9943 { 9944 #ifdef AMIGA 9945 "amiga", 9946 # ifdef FEAT_ARP 9947 "arp", 9948 # endif 9949 #endif 9950 #ifdef __BEOS__ 9951 "beos", 9952 #endif 9953 #ifdef MSDOS 9954 # ifdef DJGPP 9955 "dos32", 9956 # else 9957 "dos16", 9958 # endif 9959 #endif 9960 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 9961 "mac", 9962 #endif 9963 #if defined(MACOS_X_UNIX) 9964 "macunix", 9965 #endif 9966 #ifdef OS2 9967 "os2", 9968 #endif 9969 #ifdef __QNX__ 9970 "qnx", 9971 #endif 9972 #ifdef RISCOS 9973 "riscos", 9974 #endif 9975 #ifdef UNIX 9976 "unix", 9977 #endif 9978 #ifdef VMS 9979 "vms", 9980 #endif 9981 #ifdef WIN16 9982 "win16", 9983 #endif 9984 #ifdef WIN32 9985 "win32", 9986 #endif 9987 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 9988 "win32unix", 9989 #endif 9990 #ifdef WIN64 9991 "win64", 9992 #endif 9993 #ifdef EBCDIC 9994 "ebcdic", 9995 #endif 9996 #ifndef CASE_INSENSITIVE_FILENAME 9997 "fname_case", 9998 #endif 9999 #ifdef FEAT_ARABIC 10000 "arabic", 10001 #endif 10002 #ifdef FEAT_AUTOCMD 10003 "autocmd", 10004 #endif 10005 #ifdef FEAT_BEVAL 10006 "balloon_eval", 10007 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10008 "balloon_multiline", 10009 # endif 10010 #endif 10011 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10012 "builtin_terms", 10013 # ifdef ALL_BUILTIN_TCAPS 10014 "all_builtin_terms", 10015 # endif 10016 #endif 10017 #ifdef FEAT_BYTEOFF 10018 "byte_offset", 10019 #endif 10020 #ifdef FEAT_CINDENT 10021 "cindent", 10022 #endif 10023 #ifdef FEAT_CLIENTSERVER 10024 "clientserver", 10025 #endif 10026 #ifdef FEAT_CLIPBOARD 10027 "clipboard", 10028 #endif 10029 #ifdef FEAT_CMDL_COMPL 10030 "cmdline_compl", 10031 #endif 10032 #ifdef FEAT_CMDHIST 10033 "cmdline_hist", 10034 #endif 10035 #ifdef FEAT_COMMENTS 10036 "comments", 10037 #endif 10038 #ifdef FEAT_CRYPT 10039 "cryptv", 10040 #endif 10041 #ifdef FEAT_CSCOPE 10042 "cscope", 10043 #endif 10044 #ifdef DEBUG 10045 "debug", 10046 #endif 10047 #ifdef FEAT_CON_DIALOG 10048 "dialog_con", 10049 #endif 10050 #ifdef FEAT_GUI_DIALOG 10051 "dialog_gui", 10052 #endif 10053 #ifdef FEAT_DIFF 10054 "diff", 10055 #endif 10056 #ifdef FEAT_DIGRAPHS 10057 "digraphs", 10058 #endif 10059 #ifdef FEAT_DND 10060 "dnd", 10061 #endif 10062 #ifdef FEAT_EMACS_TAGS 10063 "emacs_tags", 10064 #endif 10065 "eval", /* always present, of course! */ 10066 #ifdef FEAT_EX_EXTRA 10067 "ex_extra", 10068 #endif 10069 #ifdef FEAT_SEARCH_EXTRA 10070 "extra_search", 10071 #endif 10072 #ifdef FEAT_FKMAP 10073 "farsi", 10074 #endif 10075 #ifdef FEAT_SEARCHPATH 10076 "file_in_path", 10077 #endif 10078 #if defined(UNIX) && !defined(USE_SYSTEM) 10079 "filterpipe", 10080 #endif 10081 #ifdef FEAT_FIND_ID 10082 "find_in_path", 10083 #endif 10084 #ifdef FEAT_FOLDING 10085 "folding", 10086 #endif 10087 #ifdef FEAT_FOOTER 10088 "footer", 10089 #endif 10090 #if !defined(USE_SYSTEM) && defined(UNIX) 10091 "fork", 10092 #endif 10093 #ifdef FEAT_GETTEXT 10094 "gettext", 10095 #endif 10096 #ifdef FEAT_GUI 10097 "gui", 10098 #endif 10099 #ifdef FEAT_GUI_ATHENA 10100 # ifdef FEAT_GUI_NEXTAW 10101 "gui_neXtaw", 10102 # else 10103 "gui_athena", 10104 # endif 10105 #endif 10106 #ifdef FEAT_GUI_KDE 10107 "gui_kde", 10108 #endif 10109 #ifdef FEAT_GUI_GTK 10110 "gui_gtk", 10111 # ifdef HAVE_GTK2 10112 "gui_gtk2", 10113 # endif 10114 #endif 10115 #ifdef FEAT_GUI_MAC 10116 "gui_mac", 10117 #endif 10118 #ifdef FEAT_GUI_MOTIF 10119 "gui_motif", 10120 #endif 10121 #ifdef FEAT_GUI_PHOTON 10122 "gui_photon", 10123 #endif 10124 #ifdef FEAT_GUI_W16 10125 "gui_win16", 10126 #endif 10127 #ifdef FEAT_GUI_W32 10128 "gui_win32", 10129 #endif 10130 #ifdef FEAT_HANGULIN 10131 "hangul_input", 10132 #endif 10133 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10134 "iconv", 10135 #endif 10136 #ifdef FEAT_INS_EXPAND 10137 "insert_expand", 10138 #endif 10139 #ifdef FEAT_JUMPLIST 10140 "jumplist", 10141 #endif 10142 #ifdef FEAT_KEYMAP 10143 "keymap", 10144 #endif 10145 #ifdef FEAT_LANGMAP 10146 "langmap", 10147 #endif 10148 #ifdef FEAT_LIBCALL 10149 "libcall", 10150 #endif 10151 #ifdef FEAT_LINEBREAK 10152 "linebreak", 10153 #endif 10154 #ifdef FEAT_LISP 10155 "lispindent", 10156 #endif 10157 #ifdef FEAT_LISTCMDS 10158 "listcmds", 10159 #endif 10160 #ifdef FEAT_LOCALMAP 10161 "localmap", 10162 #endif 10163 #ifdef FEAT_MENU 10164 "menu", 10165 #endif 10166 #ifdef FEAT_SESSION 10167 "mksession", 10168 #endif 10169 #ifdef FEAT_MODIFY_FNAME 10170 "modify_fname", 10171 #endif 10172 #ifdef FEAT_MOUSE 10173 "mouse", 10174 #endif 10175 #ifdef FEAT_MOUSESHAPE 10176 "mouseshape", 10177 #endif 10178 #if defined(UNIX) || defined(VMS) 10179 # ifdef FEAT_MOUSE_DEC 10180 "mouse_dec", 10181 # endif 10182 # ifdef FEAT_MOUSE_GPM 10183 "mouse_gpm", 10184 # endif 10185 # ifdef FEAT_MOUSE_JSB 10186 "mouse_jsbterm", 10187 # endif 10188 # ifdef FEAT_MOUSE_NET 10189 "mouse_netterm", 10190 # endif 10191 # ifdef FEAT_MOUSE_PTERM 10192 "mouse_pterm", 10193 # endif 10194 # ifdef FEAT_MOUSE_XTERM 10195 "mouse_xterm", 10196 # endif 10197 #endif 10198 #ifdef FEAT_MBYTE 10199 "multi_byte", 10200 #endif 10201 #ifdef FEAT_MBYTE_IME 10202 "multi_byte_ime", 10203 #endif 10204 #ifdef FEAT_MULTI_LANG 10205 "multi_lang", 10206 #endif 10207 #ifdef FEAT_MZSCHEME 10208 #ifndef DYNAMIC_MZSCHEME 10209 "mzscheme", 10210 #endif 10211 #endif 10212 #ifdef FEAT_OLE 10213 "ole", 10214 #endif 10215 #ifdef FEAT_OSFILETYPE 10216 "osfiletype", 10217 #endif 10218 #ifdef FEAT_PATH_EXTRA 10219 "path_extra", 10220 #endif 10221 #ifdef FEAT_PERL 10222 #ifndef DYNAMIC_PERL 10223 "perl", 10224 #endif 10225 #endif 10226 #ifdef FEAT_PYTHON 10227 #ifndef DYNAMIC_PYTHON 10228 "python", 10229 #endif 10230 #endif 10231 #ifdef FEAT_POSTSCRIPT 10232 "postscript", 10233 #endif 10234 #ifdef FEAT_PRINTER 10235 "printer", 10236 #endif 10237 #ifdef FEAT_PROFILE 10238 "profile", 10239 #endif 10240 #ifdef FEAT_QUICKFIX 10241 "quickfix", 10242 #endif 10243 #ifdef FEAT_RIGHTLEFT 10244 "rightleft", 10245 #endif 10246 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10247 "ruby", 10248 #endif 10249 #ifdef FEAT_SCROLLBIND 10250 "scrollbind", 10251 #endif 10252 #ifdef FEAT_CMDL_INFO 10253 "showcmd", 10254 "cmdline_info", 10255 #endif 10256 #ifdef FEAT_SIGNS 10257 "signs", 10258 #endif 10259 #ifdef FEAT_SMARTINDENT 10260 "smartindent", 10261 #endif 10262 #ifdef FEAT_SNIFF 10263 "sniff", 10264 #endif 10265 #ifdef FEAT_STL_OPT 10266 "statusline", 10267 #endif 10268 #ifdef FEAT_SUN_WORKSHOP 10269 "sun_workshop", 10270 #endif 10271 #ifdef FEAT_NETBEANS_INTG 10272 "netbeans_intg", 10273 #endif 10274 #ifdef FEAT_SYN_HL 10275 "spell", 10276 #endif 10277 #ifdef FEAT_SYN_HL 10278 "syntax", 10279 #endif 10280 #if defined(USE_SYSTEM) || !defined(UNIX) 10281 "system", 10282 #endif 10283 #ifdef FEAT_TAG_BINS 10284 "tag_binary", 10285 #endif 10286 #ifdef FEAT_TAG_OLDSTATIC 10287 "tag_old_static", 10288 #endif 10289 #ifdef FEAT_TAG_ANYWHITE 10290 "tag_any_white", 10291 #endif 10292 #ifdef FEAT_TCL 10293 # ifndef DYNAMIC_TCL 10294 "tcl", 10295 # endif 10296 #endif 10297 #ifdef TERMINFO 10298 "terminfo", 10299 #endif 10300 #ifdef FEAT_TERMRESPONSE 10301 "termresponse", 10302 #endif 10303 #ifdef FEAT_TEXTOBJ 10304 "textobjects", 10305 #endif 10306 #ifdef HAVE_TGETENT 10307 "tgetent", 10308 #endif 10309 #ifdef FEAT_TITLE 10310 "title", 10311 #endif 10312 #ifdef FEAT_TOOLBAR 10313 "toolbar", 10314 #endif 10315 #ifdef FEAT_USR_CMDS 10316 "user-commands", /* was accidentally included in 5.4 */ 10317 "user_commands", 10318 #endif 10319 #ifdef FEAT_VIMINFO 10320 "viminfo", 10321 #endif 10322 #ifdef FEAT_VERTSPLIT 10323 "vertsplit", 10324 #endif 10325 #ifdef FEAT_VIRTUALEDIT 10326 "virtualedit", 10327 #endif 10328 #ifdef FEAT_VISUAL 10329 "visual", 10330 #endif 10331 #ifdef FEAT_VISUALEXTRA 10332 "visualextra", 10333 #endif 10334 #ifdef FEAT_VREPLACE 10335 "vreplace", 10336 #endif 10337 #ifdef FEAT_WILDIGN 10338 "wildignore", 10339 #endif 10340 #ifdef FEAT_WILDMENU 10341 "wildmenu", 10342 #endif 10343 #ifdef FEAT_WINDOWS 10344 "windows", 10345 #endif 10346 #ifdef FEAT_WAK 10347 "winaltkeys", 10348 #endif 10349 #ifdef FEAT_WRITEBACKUP 10350 "writebackup", 10351 #endif 10352 #ifdef FEAT_XIM 10353 "xim", 10354 #endif 10355 #ifdef FEAT_XFONTSET 10356 "xfontset", 10357 #endif 10358 #ifdef USE_XSMP 10359 "xsmp", 10360 #endif 10361 #ifdef USE_XSMP_INTERACT 10362 "xsmp_interact", 10363 #endif 10364 #ifdef FEAT_XCLIPBOARD 10365 "xterm_clipboard", 10366 #endif 10367 #ifdef FEAT_XTERM_SAVE 10368 "xterm_save", 10369 #endif 10370 #if defined(UNIX) && defined(FEAT_X11) 10371 "X11", 10372 #endif 10373 NULL 10374 }; 10375 10376 name = get_tv_string(&argvars[0]); 10377 for (i = 0; has_list[i] != NULL; ++i) 10378 if (STRICMP(name, has_list[i]) == 0) 10379 { 10380 n = TRUE; 10381 break; 10382 } 10383 10384 if (n == FALSE) 10385 { 10386 if (STRNICMP(name, "patch", 5) == 0) 10387 n = has_patch(atoi((char *)name + 5)); 10388 else if (STRICMP(name, "vim_starting") == 0) 10389 n = (starting != 0); 10390 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10391 else if (STRICMP(name, "balloon_multiline") == 0) 10392 n = multiline_balloon_available(); 10393 #endif 10394 #ifdef DYNAMIC_TCL 10395 else if (STRICMP(name, "tcl") == 0) 10396 n = tcl_enabled(FALSE); 10397 #endif 10398 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10399 else if (STRICMP(name, "iconv") == 0) 10400 n = iconv_enabled(FALSE); 10401 #endif 10402 #ifdef DYNAMIC_MZSCHEME 10403 else if (STRICMP(name, "mzscheme") == 0) 10404 n = mzscheme_enabled(FALSE); 10405 #endif 10406 #ifdef DYNAMIC_RUBY 10407 else if (STRICMP(name, "ruby") == 0) 10408 n = ruby_enabled(FALSE); 10409 #endif 10410 #ifdef DYNAMIC_PYTHON 10411 else if (STRICMP(name, "python") == 0) 10412 n = python_enabled(FALSE); 10413 #endif 10414 #ifdef DYNAMIC_PERL 10415 else if (STRICMP(name, "perl") == 0) 10416 n = perl_enabled(FALSE); 10417 #endif 10418 #ifdef FEAT_GUI 10419 else if (STRICMP(name, "gui_running") == 0) 10420 n = (gui.in_use || gui.starting); 10421 # ifdef FEAT_GUI_W32 10422 else if (STRICMP(name, "gui_win32s") == 0) 10423 n = gui_is_win32s(); 10424 # endif 10425 # ifdef FEAT_BROWSE 10426 else if (STRICMP(name, "browse") == 0) 10427 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10428 # endif 10429 #endif 10430 #ifdef FEAT_SYN_HL 10431 else if (STRICMP(name, "syntax_items") == 0) 10432 n = syntax_present(curbuf); 10433 #endif 10434 #if defined(WIN3264) 10435 else if (STRICMP(name, "win95") == 0) 10436 n = mch_windows95(); 10437 #endif 10438 #ifdef FEAT_NETBEANS_INTG 10439 else if (STRICMP(name, "netbeans_enabled") == 0) 10440 n = usingNetbeans; 10441 #endif 10442 } 10443 10444 rettv->vval.v_number = n; 10445 } 10446 10447 /* 10448 * "has_key()" function 10449 */ 10450 static void 10451 f_has_key(argvars, rettv) 10452 typval_T *argvars; 10453 typval_T *rettv; 10454 { 10455 rettv->vval.v_number = 0; 10456 if (argvars[0].v_type != VAR_DICT) 10457 { 10458 EMSG(_(e_dictreq)); 10459 return; 10460 } 10461 if (argvars[0].vval.v_dict == NULL) 10462 return; 10463 10464 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10465 get_tv_string(&argvars[1]), -1) != NULL; 10466 } 10467 10468 /* 10469 * "hasmapto()" function 10470 */ 10471 static void 10472 f_hasmapto(argvars, rettv) 10473 typval_T *argvars; 10474 typval_T *rettv; 10475 { 10476 char_u *name; 10477 char_u *mode; 10478 char_u buf[NUMBUFLEN]; 10479 10480 name = get_tv_string(&argvars[0]); 10481 if (argvars[1].v_type == VAR_UNKNOWN) 10482 mode = (char_u *)"nvo"; 10483 else 10484 mode = get_tv_string_buf(&argvars[1], buf); 10485 10486 if (map_to_exists(name, mode)) 10487 rettv->vval.v_number = TRUE; 10488 else 10489 rettv->vval.v_number = FALSE; 10490 } 10491 10492 /* 10493 * "histadd()" function 10494 */ 10495 /*ARGSUSED*/ 10496 static void 10497 f_histadd(argvars, rettv) 10498 typval_T *argvars; 10499 typval_T *rettv; 10500 { 10501 #ifdef FEAT_CMDHIST 10502 int histype; 10503 char_u *str; 10504 char_u buf[NUMBUFLEN]; 10505 #endif 10506 10507 rettv->vval.v_number = FALSE; 10508 if (check_restricted() || check_secure()) 10509 return; 10510 #ifdef FEAT_CMDHIST 10511 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10512 histype = str != NULL ? get_histtype(str) : -1; 10513 if (histype >= 0) 10514 { 10515 str = get_tv_string_buf(&argvars[1], buf); 10516 if (*str != NUL) 10517 { 10518 add_to_history(histype, str, FALSE, NUL); 10519 rettv->vval.v_number = TRUE; 10520 return; 10521 } 10522 } 10523 #endif 10524 } 10525 10526 /* 10527 * "histdel()" function 10528 */ 10529 /*ARGSUSED*/ 10530 static void 10531 f_histdel(argvars, rettv) 10532 typval_T *argvars; 10533 typval_T *rettv; 10534 { 10535 #ifdef FEAT_CMDHIST 10536 int n; 10537 char_u buf[NUMBUFLEN]; 10538 char_u *str; 10539 10540 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10541 if (str == NULL) 10542 n = 0; 10543 else if (argvars[1].v_type == VAR_UNKNOWN) 10544 /* only one argument: clear entire history */ 10545 n = clr_history(get_histtype(str)); 10546 else if (argvars[1].v_type == VAR_NUMBER) 10547 /* index given: remove that entry */ 10548 n = del_history_idx(get_histtype(str), 10549 (int)get_tv_number(&argvars[1])); 10550 else 10551 /* string given: remove all matching entries */ 10552 n = del_history_entry(get_histtype(str), 10553 get_tv_string_buf(&argvars[1], buf)); 10554 rettv->vval.v_number = n; 10555 #else 10556 rettv->vval.v_number = 0; 10557 #endif 10558 } 10559 10560 /* 10561 * "histget()" function 10562 */ 10563 /*ARGSUSED*/ 10564 static void 10565 f_histget(argvars, rettv) 10566 typval_T *argvars; 10567 typval_T *rettv; 10568 { 10569 #ifdef FEAT_CMDHIST 10570 int type; 10571 int idx; 10572 char_u *str; 10573 10574 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10575 if (str == NULL) 10576 rettv->vval.v_string = NULL; 10577 else 10578 { 10579 type = get_histtype(str); 10580 if (argvars[1].v_type == VAR_UNKNOWN) 10581 idx = get_history_idx(type); 10582 else 10583 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10584 /* -1 on type error */ 10585 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10586 } 10587 #else 10588 rettv->vval.v_string = NULL; 10589 #endif 10590 rettv->v_type = VAR_STRING; 10591 } 10592 10593 /* 10594 * "histnr()" function 10595 */ 10596 /*ARGSUSED*/ 10597 static void 10598 f_histnr(argvars, rettv) 10599 typval_T *argvars; 10600 typval_T *rettv; 10601 { 10602 int i; 10603 10604 #ifdef FEAT_CMDHIST 10605 char_u *history = get_tv_string_chk(&argvars[0]); 10606 10607 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10608 if (i >= HIST_CMD && i < HIST_COUNT) 10609 i = get_history_idx(i); 10610 else 10611 #endif 10612 i = -1; 10613 rettv->vval.v_number = i; 10614 } 10615 10616 /* 10617 * "highlightID(name)" function 10618 */ 10619 static void 10620 f_hlID(argvars, rettv) 10621 typval_T *argvars; 10622 typval_T *rettv; 10623 { 10624 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10625 } 10626 10627 /* 10628 * "highlight_exists()" function 10629 */ 10630 static void 10631 f_hlexists(argvars, rettv) 10632 typval_T *argvars; 10633 typval_T *rettv; 10634 { 10635 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10636 } 10637 10638 /* 10639 * "hostname()" function 10640 */ 10641 /*ARGSUSED*/ 10642 static void 10643 f_hostname(argvars, rettv) 10644 typval_T *argvars; 10645 typval_T *rettv; 10646 { 10647 char_u hostname[256]; 10648 10649 mch_get_host_name(hostname, 256); 10650 rettv->v_type = VAR_STRING; 10651 rettv->vval.v_string = vim_strsave(hostname); 10652 } 10653 10654 /* 10655 * iconv() function 10656 */ 10657 /*ARGSUSED*/ 10658 static void 10659 f_iconv(argvars, rettv) 10660 typval_T *argvars; 10661 typval_T *rettv; 10662 { 10663 #ifdef FEAT_MBYTE 10664 char_u buf1[NUMBUFLEN]; 10665 char_u buf2[NUMBUFLEN]; 10666 char_u *from, *to, *str; 10667 vimconv_T vimconv; 10668 #endif 10669 10670 rettv->v_type = VAR_STRING; 10671 rettv->vval.v_string = NULL; 10672 10673 #ifdef FEAT_MBYTE 10674 str = get_tv_string(&argvars[0]); 10675 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10676 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10677 vimconv.vc_type = CONV_NONE; 10678 convert_setup(&vimconv, from, to); 10679 10680 /* If the encodings are equal, no conversion needed. */ 10681 if (vimconv.vc_type == CONV_NONE) 10682 rettv->vval.v_string = vim_strsave(str); 10683 else 10684 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10685 10686 convert_setup(&vimconv, NULL, NULL); 10687 vim_free(from); 10688 vim_free(to); 10689 #endif 10690 } 10691 10692 /* 10693 * "indent()" function 10694 */ 10695 static void 10696 f_indent(argvars, rettv) 10697 typval_T *argvars; 10698 typval_T *rettv; 10699 { 10700 linenr_T lnum; 10701 10702 lnum = get_tv_lnum(argvars); 10703 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10704 rettv->vval.v_number = get_indent_lnum(lnum); 10705 else 10706 rettv->vval.v_number = -1; 10707 } 10708 10709 /* 10710 * "index()" function 10711 */ 10712 static void 10713 f_index(argvars, rettv) 10714 typval_T *argvars; 10715 typval_T *rettv; 10716 { 10717 list_T *l; 10718 listitem_T *item; 10719 long idx = 0; 10720 int ic = FALSE; 10721 10722 rettv->vval.v_number = -1; 10723 if (argvars[0].v_type != VAR_LIST) 10724 { 10725 EMSG(_(e_listreq)); 10726 return; 10727 } 10728 l = argvars[0].vval.v_list; 10729 if (l != NULL) 10730 { 10731 item = l->lv_first; 10732 if (argvars[2].v_type != VAR_UNKNOWN) 10733 { 10734 int error = FALSE; 10735 10736 /* Start at specified item. Use the cached index that list_find() 10737 * sets, so that a negative number also works. */ 10738 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10739 idx = l->lv_idx; 10740 if (argvars[3].v_type != VAR_UNKNOWN) 10741 ic = get_tv_number_chk(&argvars[3], &error); 10742 if (error) 10743 item = NULL; 10744 } 10745 10746 for ( ; item != NULL; item = item->li_next, ++idx) 10747 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10748 { 10749 rettv->vval.v_number = idx; 10750 break; 10751 } 10752 } 10753 } 10754 10755 static int inputsecret_flag = 0; 10756 10757 /* 10758 * "input()" function 10759 * Also handles inputsecret() when inputsecret is set. 10760 */ 10761 static void 10762 f_input(argvars, rettv) 10763 typval_T *argvars; 10764 typval_T *rettv; 10765 { 10766 char_u *prompt = get_tv_string_chk(&argvars[0]); 10767 char_u *p = NULL; 10768 int c; 10769 char_u buf[NUMBUFLEN]; 10770 int cmd_silent_save = cmd_silent; 10771 char_u *defstr = (char_u *)""; 10772 10773 rettv->v_type = VAR_STRING; 10774 10775 #ifdef NO_CONSOLE_INPUT 10776 /* While starting up, there is no place to enter text. */ 10777 if (no_console_input()) 10778 { 10779 rettv->vval.v_string = NULL; 10780 return; 10781 } 10782 #endif 10783 10784 cmd_silent = FALSE; /* Want to see the prompt. */ 10785 if (prompt != NULL) 10786 { 10787 /* Only the part of the message after the last NL is considered as 10788 * prompt for the command line */ 10789 p = vim_strrchr(prompt, '\n'); 10790 if (p == NULL) 10791 p = prompt; 10792 else 10793 { 10794 ++p; 10795 c = *p; 10796 *p = NUL; 10797 msg_start(); 10798 msg_clr_eos(); 10799 msg_puts_attr(prompt, echo_attr); 10800 msg_didout = FALSE; 10801 msg_starthere(); 10802 *p = c; 10803 } 10804 cmdline_row = msg_row; 10805 10806 if (argvars[1].v_type != VAR_UNKNOWN) 10807 { 10808 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10809 if (defstr != NULL) 10810 stuffReadbuffSpec(defstr); 10811 } 10812 10813 if (defstr != NULL) 10814 rettv->vval.v_string = 10815 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr); 10816 10817 /* since the user typed this, no need to wait for return */ 10818 need_wait_return = FALSE; 10819 msg_didout = FALSE; 10820 } 10821 cmd_silent = cmd_silent_save; 10822 } 10823 10824 /* 10825 * "inputdialog()" function 10826 */ 10827 static void 10828 f_inputdialog(argvars, rettv) 10829 typval_T *argvars; 10830 typval_T *rettv; 10831 { 10832 #if defined(FEAT_GUI_TEXTDIALOG) 10833 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10834 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10835 { 10836 char_u *message; 10837 char_u buf[NUMBUFLEN]; 10838 char_u *defstr = (char_u *)""; 10839 10840 message = get_tv_string_chk(&argvars[0]); 10841 if (argvars[1].v_type != VAR_UNKNOWN 10842 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10843 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10844 else 10845 IObuff[0] = NUL; 10846 if (message != NULL && defstr != NULL 10847 && do_dialog(VIM_QUESTION, NULL, message, 10848 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10849 rettv->vval.v_string = vim_strsave(IObuff); 10850 else 10851 { 10852 if (message != NULL && defstr != NULL 10853 && argvars[1].v_type != VAR_UNKNOWN 10854 && argvars[2].v_type != VAR_UNKNOWN) 10855 rettv->vval.v_string = vim_strsave( 10856 get_tv_string_buf(&argvars[2], buf)); 10857 else 10858 rettv->vval.v_string = NULL; 10859 } 10860 rettv->v_type = VAR_STRING; 10861 } 10862 else 10863 #endif 10864 f_input(argvars, rettv); 10865 } 10866 10867 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 10868 10869 /* 10870 * "inputrestore()" function 10871 */ 10872 /*ARGSUSED*/ 10873 static void 10874 f_inputrestore(argvars, rettv) 10875 typval_T *argvars; 10876 typval_T *rettv; 10877 { 10878 if (ga_userinput.ga_len > 0) 10879 { 10880 --ga_userinput.ga_len; 10881 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 10882 + ga_userinput.ga_len); 10883 rettv->vval.v_number = 0; /* OK */ 10884 } 10885 else if (p_verbose > 1) 10886 { 10887 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 10888 rettv->vval.v_number = 1; /* Failed */ 10889 } 10890 } 10891 10892 /* 10893 * "inputsave()" function 10894 */ 10895 /*ARGSUSED*/ 10896 static void 10897 f_inputsave(argvars, rettv) 10898 typval_T *argvars; 10899 typval_T *rettv; 10900 { 10901 /* Add an entry to the stack of typehead storage. */ 10902 if (ga_grow(&ga_userinput, 1) == OK) 10903 { 10904 save_typeahead((tasave_T *)(ga_userinput.ga_data) 10905 + ga_userinput.ga_len); 10906 ++ga_userinput.ga_len; 10907 rettv->vval.v_number = 0; /* OK */ 10908 } 10909 else 10910 rettv->vval.v_number = 1; /* Failed */ 10911 } 10912 10913 /* 10914 * "inputsecret()" function 10915 */ 10916 static void 10917 f_inputsecret(argvars, rettv) 10918 typval_T *argvars; 10919 typval_T *rettv; 10920 { 10921 ++cmdline_star; 10922 ++inputsecret_flag; 10923 f_input(argvars, rettv); 10924 --cmdline_star; 10925 --inputsecret_flag; 10926 } 10927 10928 /* 10929 * "insert()" function 10930 */ 10931 static void 10932 f_insert(argvars, rettv) 10933 typval_T *argvars; 10934 typval_T *rettv; 10935 { 10936 long before = 0; 10937 listitem_T *item; 10938 list_T *l; 10939 int error = FALSE; 10940 10941 rettv->vval.v_number = 0; 10942 if (argvars[0].v_type != VAR_LIST) 10943 EMSG2(_(e_listarg), "insert()"); 10944 else if ((l = argvars[0].vval.v_list) != NULL 10945 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 10946 { 10947 if (argvars[2].v_type != VAR_UNKNOWN) 10948 before = get_tv_number_chk(&argvars[2], &error); 10949 if (error) 10950 return; /* type error; errmsg already given */ 10951 10952 if (before == l->lv_len) 10953 item = NULL; 10954 else 10955 { 10956 item = list_find(l, before); 10957 if (item == NULL) 10958 { 10959 EMSGN(_(e_listidx), before); 10960 l = NULL; 10961 } 10962 } 10963 if (l != NULL) 10964 { 10965 list_insert_tv(l, &argvars[1], item); 10966 copy_tv(&argvars[0], rettv); 10967 } 10968 } 10969 } 10970 10971 /* 10972 * "isdirectory()" function 10973 */ 10974 static void 10975 f_isdirectory(argvars, rettv) 10976 typval_T *argvars; 10977 typval_T *rettv; 10978 { 10979 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 10980 } 10981 10982 /* 10983 * "islocked()" function 10984 */ 10985 static void 10986 f_islocked(argvars, rettv) 10987 typval_T *argvars; 10988 typval_T *rettv; 10989 { 10990 lval_T lv; 10991 char_u *end; 10992 dictitem_T *di; 10993 10994 rettv->vval.v_number = -1; 10995 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 10996 FNE_CHECK_START); 10997 if (end != NULL && lv.ll_name != NULL) 10998 { 10999 if (*end != NUL) 11000 EMSG(_(e_trailing)); 11001 else 11002 { 11003 if (lv.ll_tv == NULL) 11004 { 11005 if (check_changedtick(lv.ll_name)) 11006 rettv->vval.v_number = 1; /* always locked */ 11007 else 11008 { 11009 di = find_var(lv.ll_name, NULL); 11010 if (di != NULL) 11011 { 11012 /* Consider a variable locked when: 11013 * 1. the variable itself is locked 11014 * 2. the value of the variable is locked. 11015 * 3. the List or Dict value is locked. 11016 */ 11017 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11018 || tv_islocked(&di->di_tv)); 11019 } 11020 } 11021 } 11022 else if (lv.ll_range) 11023 EMSG(_("E745: Range not allowed")); 11024 else if (lv.ll_newkey != NULL) 11025 EMSG2(_(e_dictkey), lv.ll_newkey); 11026 else if (lv.ll_list != NULL) 11027 /* List item. */ 11028 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11029 else 11030 /* Dictionary item. */ 11031 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11032 } 11033 } 11034 11035 clear_lval(&lv); 11036 } 11037 11038 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11039 11040 /* 11041 * Turn a dict into a list: 11042 * "what" == 0: list of keys 11043 * "what" == 1: list of values 11044 * "what" == 2: list of items 11045 */ 11046 static void 11047 dict_list(argvars, rettv, what) 11048 typval_T *argvars; 11049 typval_T *rettv; 11050 int what; 11051 { 11052 list_T *l; 11053 list_T *l2; 11054 dictitem_T *di; 11055 hashitem_T *hi; 11056 listitem_T *li; 11057 listitem_T *li2; 11058 dict_T *d; 11059 int todo; 11060 11061 rettv->vval.v_number = 0; 11062 if (argvars[0].v_type != VAR_DICT) 11063 { 11064 EMSG(_(e_dictreq)); 11065 return; 11066 } 11067 if ((d = argvars[0].vval.v_dict) == NULL) 11068 return; 11069 11070 l = list_alloc(); 11071 if (l == NULL) 11072 return; 11073 rettv->v_type = VAR_LIST; 11074 rettv->vval.v_list = l; 11075 ++l->lv_refcount; 11076 11077 todo = d->dv_hashtab.ht_used; 11078 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11079 { 11080 if (!HASHITEM_EMPTY(hi)) 11081 { 11082 --todo; 11083 di = HI2DI(hi); 11084 11085 li = listitem_alloc(); 11086 if (li == NULL) 11087 break; 11088 list_append(l, li); 11089 11090 if (what == 0) 11091 { 11092 /* keys() */ 11093 li->li_tv.v_type = VAR_STRING; 11094 li->li_tv.v_lock = 0; 11095 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11096 } 11097 else if (what == 1) 11098 { 11099 /* values() */ 11100 copy_tv(&di->di_tv, &li->li_tv); 11101 } 11102 else 11103 { 11104 /* items() */ 11105 l2 = list_alloc(); 11106 li->li_tv.v_type = VAR_LIST; 11107 li->li_tv.v_lock = 0; 11108 li->li_tv.vval.v_list = l2; 11109 if (l2 == NULL) 11110 break; 11111 ++l2->lv_refcount; 11112 11113 li2 = listitem_alloc(); 11114 if (li2 == NULL) 11115 break; 11116 list_append(l2, li2); 11117 li2->li_tv.v_type = VAR_STRING; 11118 li2->li_tv.v_lock = 0; 11119 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11120 11121 li2 = listitem_alloc(); 11122 if (li2 == NULL) 11123 break; 11124 list_append(l2, li2); 11125 copy_tv(&di->di_tv, &li2->li_tv); 11126 } 11127 } 11128 } 11129 } 11130 11131 /* 11132 * "items(dict)" function 11133 */ 11134 static void 11135 f_items(argvars, rettv) 11136 typval_T *argvars; 11137 typval_T *rettv; 11138 { 11139 dict_list(argvars, rettv, 2); 11140 } 11141 11142 /* 11143 * "join()" function 11144 */ 11145 static void 11146 f_join(argvars, rettv) 11147 typval_T *argvars; 11148 typval_T *rettv; 11149 { 11150 garray_T ga; 11151 char_u *sep; 11152 11153 rettv->vval.v_number = 0; 11154 if (argvars[0].v_type != VAR_LIST) 11155 { 11156 EMSG(_(e_listreq)); 11157 return; 11158 } 11159 if (argvars[0].vval.v_list == NULL) 11160 return; 11161 if (argvars[1].v_type == VAR_UNKNOWN) 11162 sep = (char_u *)" "; 11163 else 11164 sep = get_tv_string_chk(&argvars[1]); 11165 11166 rettv->v_type = VAR_STRING; 11167 11168 if (sep != NULL) 11169 { 11170 ga_init2(&ga, (int)sizeof(char), 80); 11171 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11172 ga_append(&ga, NUL); 11173 rettv->vval.v_string = (char_u *)ga.ga_data; 11174 } 11175 else 11176 rettv->vval.v_string = NULL; 11177 } 11178 11179 /* 11180 * "keys()" function 11181 */ 11182 static void 11183 f_keys(argvars, rettv) 11184 typval_T *argvars; 11185 typval_T *rettv; 11186 { 11187 dict_list(argvars, rettv, 0); 11188 } 11189 11190 /* 11191 * "last_buffer_nr()" function. 11192 */ 11193 /*ARGSUSED*/ 11194 static void 11195 f_last_buffer_nr(argvars, rettv) 11196 typval_T *argvars; 11197 typval_T *rettv; 11198 { 11199 int n = 0; 11200 buf_T *buf; 11201 11202 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11203 if (n < buf->b_fnum) 11204 n = buf->b_fnum; 11205 11206 rettv->vval.v_number = n; 11207 } 11208 11209 /* 11210 * "len()" function 11211 */ 11212 static void 11213 f_len(argvars, rettv) 11214 typval_T *argvars; 11215 typval_T *rettv; 11216 { 11217 switch (argvars[0].v_type) 11218 { 11219 case VAR_STRING: 11220 case VAR_NUMBER: 11221 rettv->vval.v_number = (varnumber_T)STRLEN( 11222 get_tv_string(&argvars[0])); 11223 break; 11224 case VAR_LIST: 11225 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11226 break; 11227 case VAR_DICT: 11228 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11229 break; 11230 default: 11231 EMSG(_("E701: Invalid type for len()")); 11232 break; 11233 } 11234 } 11235 11236 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11237 11238 static void 11239 libcall_common(argvars, rettv, type) 11240 typval_T *argvars; 11241 typval_T *rettv; 11242 int type; 11243 { 11244 #ifdef FEAT_LIBCALL 11245 char_u *string_in; 11246 char_u **string_result; 11247 int nr_result; 11248 #endif 11249 11250 rettv->v_type = type; 11251 if (type == VAR_NUMBER) 11252 rettv->vval.v_number = 0; 11253 else 11254 rettv->vval.v_string = NULL; 11255 11256 if (check_restricted() || check_secure()) 11257 return; 11258 11259 #ifdef FEAT_LIBCALL 11260 /* The first two args must be strings, otherwise its meaningless */ 11261 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11262 { 11263 string_in = NULL; 11264 if (argvars[2].v_type == VAR_STRING) 11265 string_in = argvars[2].vval.v_string; 11266 if (type == VAR_NUMBER) 11267 string_result = NULL; 11268 else 11269 string_result = &rettv->vval.v_string; 11270 if (mch_libcall(argvars[0].vval.v_string, 11271 argvars[1].vval.v_string, 11272 string_in, 11273 argvars[2].vval.v_number, 11274 string_result, 11275 &nr_result) == OK 11276 && type == VAR_NUMBER) 11277 rettv->vval.v_number = nr_result; 11278 } 11279 #endif 11280 } 11281 11282 /* 11283 * "libcall()" function 11284 */ 11285 static void 11286 f_libcall(argvars, rettv) 11287 typval_T *argvars; 11288 typval_T *rettv; 11289 { 11290 libcall_common(argvars, rettv, VAR_STRING); 11291 } 11292 11293 /* 11294 * "libcallnr()" function 11295 */ 11296 static void 11297 f_libcallnr(argvars, rettv) 11298 typval_T *argvars; 11299 typval_T *rettv; 11300 { 11301 libcall_common(argvars, rettv, VAR_NUMBER); 11302 } 11303 11304 /* 11305 * "line(string)" function 11306 */ 11307 static void 11308 f_line(argvars, rettv) 11309 typval_T *argvars; 11310 typval_T *rettv; 11311 { 11312 linenr_T lnum = 0; 11313 pos_T *fp; 11314 11315 fp = var2fpos(&argvars[0], TRUE); 11316 if (fp != NULL) 11317 lnum = fp->lnum; 11318 rettv->vval.v_number = lnum; 11319 } 11320 11321 /* 11322 * "line2byte(lnum)" function 11323 */ 11324 /*ARGSUSED*/ 11325 static void 11326 f_line2byte(argvars, rettv) 11327 typval_T *argvars; 11328 typval_T *rettv; 11329 { 11330 #ifndef FEAT_BYTEOFF 11331 rettv->vval.v_number = -1; 11332 #else 11333 linenr_T lnum; 11334 11335 lnum = get_tv_lnum(argvars); 11336 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11337 rettv->vval.v_number = -1; 11338 else 11339 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11340 if (rettv->vval.v_number >= 0) 11341 ++rettv->vval.v_number; 11342 #endif 11343 } 11344 11345 /* 11346 * "lispindent(lnum)" function 11347 */ 11348 static void 11349 f_lispindent(argvars, rettv) 11350 typval_T *argvars; 11351 typval_T *rettv; 11352 { 11353 #ifdef FEAT_LISP 11354 pos_T pos; 11355 linenr_T lnum; 11356 11357 pos = curwin->w_cursor; 11358 lnum = get_tv_lnum(argvars); 11359 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11360 { 11361 curwin->w_cursor.lnum = lnum; 11362 rettv->vval.v_number = get_lisp_indent(); 11363 curwin->w_cursor = pos; 11364 } 11365 else 11366 #endif 11367 rettv->vval.v_number = -1; 11368 } 11369 11370 /* 11371 * "localtime()" function 11372 */ 11373 /*ARGSUSED*/ 11374 static void 11375 f_localtime(argvars, rettv) 11376 typval_T *argvars; 11377 typval_T *rettv; 11378 { 11379 rettv->vval.v_number = (varnumber_T)time(NULL); 11380 } 11381 11382 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11383 11384 static void 11385 get_maparg(argvars, rettv, exact) 11386 typval_T *argvars; 11387 typval_T *rettv; 11388 int exact; 11389 { 11390 char_u *keys; 11391 char_u *which; 11392 char_u buf[NUMBUFLEN]; 11393 char_u *keys_buf = NULL; 11394 char_u *rhs; 11395 int mode; 11396 garray_T ga; 11397 11398 /* return empty string for failure */ 11399 rettv->v_type = VAR_STRING; 11400 rettv->vval.v_string = NULL; 11401 11402 keys = get_tv_string(&argvars[0]); 11403 if (*keys == NUL) 11404 return; 11405 11406 if (argvars[1].v_type != VAR_UNKNOWN) 11407 which = get_tv_string_buf_chk(&argvars[1], buf); 11408 else 11409 which = (char_u *)""; 11410 if (which == NULL) 11411 return; 11412 11413 mode = get_map_mode(&which, 0); 11414 11415 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11416 rhs = check_map(keys, mode, exact, FALSE); 11417 vim_free(keys_buf); 11418 if (rhs != NULL) 11419 { 11420 ga_init(&ga); 11421 ga.ga_itemsize = 1; 11422 ga.ga_growsize = 40; 11423 11424 while (*rhs != NUL) 11425 ga_concat(&ga, str2special(&rhs, FALSE)); 11426 11427 ga_append(&ga, NUL); 11428 rettv->vval.v_string = (char_u *)ga.ga_data; 11429 } 11430 } 11431 11432 /* 11433 * "map()" function 11434 */ 11435 static void 11436 f_map(argvars, rettv) 11437 typval_T *argvars; 11438 typval_T *rettv; 11439 { 11440 filter_map(argvars, rettv, TRUE); 11441 } 11442 11443 /* 11444 * "maparg()" function 11445 */ 11446 static void 11447 f_maparg(argvars, rettv) 11448 typval_T *argvars; 11449 typval_T *rettv; 11450 { 11451 get_maparg(argvars, rettv, TRUE); 11452 } 11453 11454 /* 11455 * "mapcheck()" function 11456 */ 11457 static void 11458 f_mapcheck(argvars, rettv) 11459 typval_T *argvars; 11460 typval_T *rettv; 11461 { 11462 get_maparg(argvars, rettv, FALSE); 11463 } 11464 11465 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11466 11467 static void 11468 find_some_match(argvars, rettv, type) 11469 typval_T *argvars; 11470 typval_T *rettv; 11471 int type; 11472 { 11473 char_u *str = NULL; 11474 char_u *expr = NULL; 11475 char_u *pat; 11476 regmatch_T regmatch; 11477 char_u patbuf[NUMBUFLEN]; 11478 char_u strbuf[NUMBUFLEN]; 11479 char_u *save_cpo; 11480 long start = 0; 11481 long nth = 1; 11482 int match = 0; 11483 list_T *l = NULL; 11484 listitem_T *li = NULL; 11485 long idx = 0; 11486 char_u *tofree = NULL; 11487 11488 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11489 save_cpo = p_cpo; 11490 p_cpo = (char_u *)""; 11491 11492 rettv->vval.v_number = -1; 11493 if (type == 3) 11494 { 11495 /* return empty list when there are no matches */ 11496 if ((rettv->vval.v_list = list_alloc()) == NULL) 11497 goto theend; 11498 rettv->v_type = VAR_LIST; 11499 ++rettv->vval.v_list->lv_refcount; 11500 } 11501 else if (type == 2) 11502 { 11503 rettv->v_type = VAR_STRING; 11504 rettv->vval.v_string = NULL; 11505 } 11506 11507 if (argvars[0].v_type == VAR_LIST) 11508 { 11509 if ((l = argvars[0].vval.v_list) == NULL) 11510 goto theend; 11511 li = l->lv_first; 11512 } 11513 else 11514 expr = str = get_tv_string(&argvars[0]); 11515 11516 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11517 if (pat == NULL) 11518 goto theend; 11519 11520 if (argvars[2].v_type != VAR_UNKNOWN) 11521 { 11522 int error = FALSE; 11523 11524 start = get_tv_number_chk(&argvars[2], &error); 11525 if (error) 11526 goto theend; 11527 if (l != NULL) 11528 { 11529 li = list_find(l, start); 11530 if (li == NULL) 11531 goto theend; 11532 idx = l->lv_idx; /* use the cached index */ 11533 } 11534 else 11535 { 11536 if (start < 0) 11537 start = 0; 11538 if (start > (long)STRLEN(str)) 11539 goto theend; 11540 str += start; 11541 } 11542 11543 if (argvars[3].v_type != VAR_UNKNOWN) 11544 nth = get_tv_number_chk(&argvars[3], &error); 11545 if (error) 11546 goto theend; 11547 } 11548 11549 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11550 if (regmatch.regprog != NULL) 11551 { 11552 regmatch.rm_ic = p_ic; 11553 11554 for (;;) 11555 { 11556 if (l != NULL) 11557 { 11558 if (li == NULL) 11559 { 11560 match = FALSE; 11561 break; 11562 } 11563 vim_free(tofree); 11564 str = echo_string(&li->li_tv, &tofree, strbuf); 11565 if (str == NULL) 11566 break; 11567 } 11568 11569 match = vim_regexec_nl(®match, str, (colnr_T)0); 11570 11571 if (match && --nth <= 0) 11572 break; 11573 if (l == NULL && !match) 11574 break; 11575 11576 /* Advance to just after the match. */ 11577 if (l != NULL) 11578 { 11579 li = li->li_next; 11580 ++idx; 11581 } 11582 else 11583 { 11584 #ifdef FEAT_MBYTE 11585 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11586 #else 11587 str = regmatch.startp[0] + 1; 11588 #endif 11589 } 11590 } 11591 11592 if (match) 11593 { 11594 if (type == 3) 11595 { 11596 int i; 11597 11598 /* return list with matched string and submatches */ 11599 for (i = 0; i < NSUBEXP; ++i) 11600 { 11601 if (regmatch.endp[i] == NULL) 11602 break; 11603 li = listitem_alloc(); 11604 if (li == NULL) 11605 break; 11606 li->li_tv.v_type = VAR_STRING; 11607 li->li_tv.v_lock = 0; 11608 li->li_tv.vval.v_string = vim_strnsave(regmatch.startp[i], 11609 (int)(regmatch.endp[i] - regmatch.startp[i])); 11610 list_append(rettv->vval.v_list, li); 11611 } 11612 } 11613 else if (type == 2) 11614 { 11615 /* return matched string */ 11616 if (l != NULL) 11617 copy_tv(&li->li_tv, rettv); 11618 else 11619 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11620 (int)(regmatch.endp[0] - regmatch.startp[0])); 11621 } 11622 else if (l != NULL) 11623 rettv->vval.v_number = idx; 11624 else 11625 { 11626 if (type != 0) 11627 rettv->vval.v_number = 11628 (varnumber_T)(regmatch.startp[0] - str); 11629 else 11630 rettv->vval.v_number = 11631 (varnumber_T)(regmatch.endp[0] - str); 11632 rettv->vval.v_number += str - expr; 11633 } 11634 } 11635 vim_free(regmatch.regprog); 11636 } 11637 11638 theend: 11639 vim_free(tofree); 11640 p_cpo = save_cpo; 11641 } 11642 11643 /* 11644 * "match()" function 11645 */ 11646 static void 11647 f_match(argvars, rettv) 11648 typval_T *argvars; 11649 typval_T *rettv; 11650 { 11651 find_some_match(argvars, rettv, 1); 11652 } 11653 11654 /* 11655 * "matchend()" function 11656 */ 11657 static void 11658 f_matchend(argvars, rettv) 11659 typval_T *argvars; 11660 typval_T *rettv; 11661 { 11662 find_some_match(argvars, rettv, 0); 11663 } 11664 11665 /* 11666 * "matchlist()" function 11667 */ 11668 static void 11669 f_matchlist(argvars, rettv) 11670 typval_T *argvars; 11671 typval_T *rettv; 11672 { 11673 find_some_match(argvars, rettv, 3); 11674 } 11675 11676 /* 11677 * "matchstr()" function 11678 */ 11679 static void 11680 f_matchstr(argvars, rettv) 11681 typval_T *argvars; 11682 typval_T *rettv; 11683 { 11684 find_some_match(argvars, rettv, 2); 11685 } 11686 11687 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11688 11689 static void 11690 max_min(argvars, rettv, domax) 11691 typval_T *argvars; 11692 typval_T *rettv; 11693 int domax; 11694 { 11695 long n = 0; 11696 long i; 11697 int error = FALSE; 11698 11699 if (argvars[0].v_type == VAR_LIST) 11700 { 11701 list_T *l; 11702 listitem_T *li; 11703 11704 l = argvars[0].vval.v_list; 11705 if (l != NULL) 11706 { 11707 li = l->lv_first; 11708 if (li != NULL) 11709 { 11710 n = get_tv_number_chk(&li->li_tv, &error); 11711 for (;;) 11712 { 11713 li = li->li_next; 11714 if (li == NULL) 11715 break; 11716 i = get_tv_number_chk(&li->li_tv, &error); 11717 if (domax ? i > n : i < n) 11718 n = i; 11719 } 11720 } 11721 } 11722 } 11723 else if (argvars[0].v_type == VAR_DICT) 11724 { 11725 dict_T *d; 11726 int first = TRUE; 11727 hashitem_T *hi; 11728 int todo; 11729 11730 d = argvars[0].vval.v_dict; 11731 if (d != NULL) 11732 { 11733 todo = d->dv_hashtab.ht_used; 11734 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11735 { 11736 if (!HASHITEM_EMPTY(hi)) 11737 { 11738 --todo; 11739 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11740 if (first) 11741 { 11742 n = i; 11743 first = FALSE; 11744 } 11745 else if (domax ? i > n : i < n) 11746 n = i; 11747 } 11748 } 11749 } 11750 } 11751 else 11752 EMSG(_(e_listdictarg)); 11753 rettv->vval.v_number = error ? 0 : n; 11754 } 11755 11756 /* 11757 * "max()" function 11758 */ 11759 static void 11760 f_max(argvars, rettv) 11761 typval_T *argvars; 11762 typval_T *rettv; 11763 { 11764 max_min(argvars, rettv, TRUE); 11765 } 11766 11767 /* 11768 * "min()" function 11769 */ 11770 static void 11771 f_min(argvars, rettv) 11772 typval_T *argvars; 11773 typval_T *rettv; 11774 { 11775 max_min(argvars, rettv, FALSE); 11776 } 11777 11778 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11779 11780 /* 11781 * Create the directory in which "dir" is located, and higher levels when 11782 * needed. 11783 */ 11784 static int 11785 mkdir_recurse(dir, prot) 11786 char_u *dir; 11787 int prot; 11788 { 11789 char_u *p; 11790 char_u *updir; 11791 int r = FAIL; 11792 11793 /* Get end of directory name in "dir". 11794 * We're done when it's "/" or "c:/". */ 11795 p = gettail_sep(dir); 11796 if (p <= get_past_head(dir)) 11797 return OK; 11798 11799 /* If the directory exists we're done. Otherwise: create it.*/ 11800 updir = vim_strnsave(dir, (int)(p - dir)); 11801 if (updir == NULL) 11802 return FAIL; 11803 if (mch_isdir(updir)) 11804 r = OK; 11805 else if (mkdir_recurse(updir, prot) == OK) 11806 r = vim_mkdir_emsg(updir, prot); 11807 vim_free(updir); 11808 return r; 11809 } 11810 11811 #ifdef vim_mkdir 11812 /* 11813 * "mkdir()" function 11814 */ 11815 static void 11816 f_mkdir(argvars, rettv) 11817 typval_T *argvars; 11818 typval_T *rettv; 11819 { 11820 char_u *dir; 11821 char_u buf[NUMBUFLEN]; 11822 int prot = 0755; 11823 11824 rettv->vval.v_number = FAIL; 11825 if (check_restricted() || check_secure()) 11826 return; 11827 11828 dir = get_tv_string_buf(&argvars[0], buf); 11829 if (argvars[1].v_type != VAR_UNKNOWN) 11830 { 11831 if (argvars[2].v_type != VAR_UNKNOWN) 11832 prot = get_tv_number_chk(&argvars[2], NULL); 11833 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11834 mkdir_recurse(dir, prot); 11835 } 11836 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11837 } 11838 #endif 11839 11840 /* 11841 * "mode()" function 11842 */ 11843 /*ARGSUSED*/ 11844 static void 11845 f_mode(argvars, rettv) 11846 typval_T *argvars; 11847 typval_T *rettv; 11848 { 11849 char_u buf[2]; 11850 11851 #ifdef FEAT_VISUAL 11852 if (VIsual_active) 11853 { 11854 if (VIsual_select) 11855 buf[0] = VIsual_mode + 's' - 'v'; 11856 else 11857 buf[0] = VIsual_mode; 11858 } 11859 else 11860 #endif 11861 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11862 buf[0] = 'r'; 11863 else if (State & INSERT) 11864 { 11865 if (State & REPLACE_FLAG) 11866 buf[0] = 'R'; 11867 else 11868 buf[0] = 'i'; 11869 } 11870 else if (State & CMDLINE) 11871 buf[0] = 'c'; 11872 else 11873 buf[0] = 'n'; 11874 11875 buf[1] = NUL; 11876 rettv->vval.v_string = vim_strsave(buf); 11877 rettv->v_type = VAR_STRING; 11878 } 11879 11880 /* 11881 * "nextnonblank()" function 11882 */ 11883 static void 11884 f_nextnonblank(argvars, rettv) 11885 typval_T *argvars; 11886 typval_T *rettv; 11887 { 11888 linenr_T lnum; 11889 11890 for (lnum = get_tv_lnum(argvars); ; ++lnum) 11891 { 11892 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 11893 { 11894 lnum = 0; 11895 break; 11896 } 11897 if (*skipwhite(ml_get(lnum)) != NUL) 11898 break; 11899 } 11900 rettv->vval.v_number = lnum; 11901 } 11902 11903 /* 11904 * "nr2char()" function 11905 */ 11906 static void 11907 f_nr2char(argvars, rettv) 11908 typval_T *argvars; 11909 typval_T *rettv; 11910 { 11911 char_u buf[NUMBUFLEN]; 11912 11913 #ifdef FEAT_MBYTE 11914 if (has_mbyte) 11915 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 11916 else 11917 #endif 11918 { 11919 buf[0] = (char_u)get_tv_number(&argvars[0]); 11920 buf[1] = NUL; 11921 } 11922 rettv->v_type = VAR_STRING; 11923 rettv->vval.v_string = vim_strsave(buf); 11924 } 11925 11926 /* 11927 * "prevnonblank()" function 11928 */ 11929 static void 11930 f_prevnonblank(argvars, rettv) 11931 typval_T *argvars; 11932 typval_T *rettv; 11933 { 11934 linenr_T lnum; 11935 11936 lnum = get_tv_lnum(argvars); 11937 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 11938 lnum = 0; 11939 else 11940 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 11941 --lnum; 11942 rettv->vval.v_number = lnum; 11943 } 11944 11945 /* 11946 * "printf()" function 11947 */ 11948 static void 11949 f_printf(argvars, rettv) 11950 typval_T *argvars; 11951 typval_T *rettv; 11952 { 11953 rettv->v_type = VAR_STRING; 11954 rettv->vval.v_string = NULL; 11955 #ifdef HAVE_STDARG_H 11956 { 11957 char_u buf[NUMBUFLEN]; 11958 int len; 11959 char_u *s; 11960 int saved_did_emsg = did_emsg; 11961 char *fmt; 11962 va_list ap; /* dummy */ 11963 11964 # ifdef LINT 11965 /* avoid warning for "ap" used before set; it is unused. */ 11966 va_start(ap, rettv); 11967 # endif 11968 11969 /* Get the required length, allocate the buffer and do it for real. */ 11970 did_emsg = FALSE; 11971 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 11972 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 11973 if (!did_emsg) 11974 { 11975 s = alloc(len + 1); 11976 if (s != NULL) 11977 { 11978 rettv->vval.v_string = s; 11979 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 11980 } 11981 } 11982 did_emsg |= saved_did_emsg; 11983 } 11984 #endif 11985 } 11986 11987 /* 11988 * "range()" function 11989 */ 11990 static void 11991 f_range(argvars, rettv) 11992 typval_T *argvars; 11993 typval_T *rettv; 11994 { 11995 long start; 11996 long end; 11997 long stride = 1; 11998 long i; 11999 list_T *l; 12000 listitem_T *li; 12001 int error = FALSE; 12002 12003 start = get_tv_number_chk(&argvars[0], &error); 12004 if (argvars[1].v_type == VAR_UNKNOWN) 12005 { 12006 end = start - 1; 12007 start = 0; 12008 } 12009 else 12010 { 12011 end = get_tv_number_chk(&argvars[1], &error); 12012 if (argvars[2].v_type != VAR_UNKNOWN) 12013 stride = get_tv_number_chk(&argvars[2], &error); 12014 } 12015 12016 rettv->vval.v_number = 0; 12017 if (error) 12018 return; /* type error; errmsg already given */ 12019 if (stride == 0) 12020 EMSG(_("E726: Stride is zero")); 12021 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12022 EMSG(_("E727: Start past end")); 12023 else 12024 { 12025 l = list_alloc(); 12026 if (l != NULL) 12027 { 12028 rettv->v_type = VAR_LIST; 12029 rettv->vval.v_list = l; 12030 ++l->lv_refcount; 12031 12032 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12033 { 12034 li = listitem_alloc(); 12035 if (li == NULL) 12036 break; 12037 li->li_tv.v_type = VAR_NUMBER; 12038 li->li_tv.v_lock = 0; 12039 li->li_tv.vval.v_number = i; 12040 list_append(l, li); 12041 } 12042 } 12043 } 12044 } 12045 12046 /* 12047 * "readfile()" function 12048 */ 12049 static void 12050 f_readfile(argvars, rettv) 12051 typval_T *argvars; 12052 typval_T *rettv; 12053 { 12054 int binary = FALSE; 12055 char_u *fname; 12056 FILE *fd; 12057 list_T *l; 12058 listitem_T *li; 12059 #define FREAD_SIZE 200 /* optimized for text lines */ 12060 char_u buf[FREAD_SIZE]; 12061 int readlen; /* size of last fread() */ 12062 int buflen; /* nr of valid chars in buf[] */ 12063 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12064 int tolist; /* first byte in buf[] still to be put in list */ 12065 int chop; /* how many CR to chop off */ 12066 char_u *prev = NULL; /* previously read bytes, if any */ 12067 int prevlen = 0; /* length of "prev" if not NULL */ 12068 char_u *s; 12069 int len; 12070 long maxline = MAXLNUM; 12071 long cnt = 0; 12072 12073 if (argvars[1].v_type != VAR_UNKNOWN) 12074 { 12075 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12076 binary = TRUE; 12077 if (argvars[2].v_type != VAR_UNKNOWN) 12078 maxline = get_tv_number(&argvars[2]); 12079 } 12080 12081 l = list_alloc(); 12082 if (l == NULL) 12083 return; 12084 rettv->v_type = VAR_LIST; 12085 rettv->vval.v_list = l; 12086 l->lv_refcount = 1; 12087 12088 /* Always open the file in binary mode, library functions have a mind of 12089 * their own about CR-LF conversion. */ 12090 fname = get_tv_string(&argvars[0]); 12091 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12092 { 12093 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12094 return; 12095 } 12096 12097 filtd = 0; 12098 while (cnt < maxline || maxline < 0) 12099 { 12100 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12101 buflen = filtd + readlen; 12102 tolist = 0; 12103 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12104 { 12105 if (buf[filtd] == '\n' || readlen <= 0) 12106 { 12107 /* Only when in binary mode add an empty list item when the 12108 * last line ends in a '\n'. */ 12109 if (!binary && readlen == 0 && filtd == 0) 12110 break; 12111 12112 /* Found end-of-line or end-of-file: add a text line to the 12113 * list. */ 12114 chop = 0; 12115 if (!binary) 12116 while (filtd - chop - 1 >= tolist 12117 && buf[filtd - chop - 1] == '\r') 12118 ++chop; 12119 len = filtd - tolist - chop; 12120 if (prev == NULL) 12121 s = vim_strnsave(buf + tolist, len); 12122 else 12123 { 12124 s = alloc((unsigned)(prevlen + len + 1)); 12125 if (s != NULL) 12126 { 12127 mch_memmove(s, prev, prevlen); 12128 vim_free(prev); 12129 prev = NULL; 12130 mch_memmove(s + prevlen, buf + tolist, len); 12131 s[prevlen + len] = NUL; 12132 } 12133 } 12134 tolist = filtd + 1; 12135 12136 li = listitem_alloc(); 12137 if (li == NULL) 12138 { 12139 vim_free(s); 12140 break; 12141 } 12142 li->li_tv.v_type = VAR_STRING; 12143 li->li_tv.v_lock = 0; 12144 li->li_tv.vval.v_string = s; 12145 list_append(l, li); 12146 12147 if (++cnt >= maxline && maxline >= 0) 12148 break; 12149 if (readlen <= 0) 12150 break; 12151 } 12152 else if (buf[filtd] == NUL) 12153 buf[filtd] = '\n'; 12154 } 12155 if (readlen <= 0) 12156 break; 12157 12158 if (tolist == 0) 12159 { 12160 /* "buf" is full, need to move text to an allocated buffer */ 12161 if (prev == NULL) 12162 { 12163 prev = vim_strnsave(buf, buflen); 12164 prevlen = buflen; 12165 } 12166 else 12167 { 12168 s = alloc((unsigned)(prevlen + buflen)); 12169 if (s != NULL) 12170 { 12171 mch_memmove(s, prev, prevlen); 12172 mch_memmove(s + prevlen, buf, buflen); 12173 vim_free(prev); 12174 prev = s; 12175 prevlen += buflen; 12176 } 12177 } 12178 filtd = 0; 12179 } 12180 else 12181 { 12182 mch_memmove(buf, buf + tolist, buflen - tolist); 12183 filtd -= tolist; 12184 } 12185 } 12186 12187 /* 12188 * For a negative line count use only the lines at the end of the file, 12189 * free the rest. 12190 */ 12191 if (maxline < 0) 12192 while (cnt > -maxline) 12193 { 12194 listitem_remove(l, l->lv_first); 12195 --cnt; 12196 } 12197 12198 vim_free(prev); 12199 fclose(fd); 12200 } 12201 12202 12203 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12204 static void make_connection __ARGS((void)); 12205 static int check_connection __ARGS((void)); 12206 12207 static void 12208 make_connection() 12209 { 12210 if (X_DISPLAY == NULL 12211 # ifdef FEAT_GUI 12212 && !gui.in_use 12213 # endif 12214 ) 12215 { 12216 x_force_connect = TRUE; 12217 setup_term_clip(); 12218 x_force_connect = FALSE; 12219 } 12220 } 12221 12222 static int 12223 check_connection() 12224 { 12225 make_connection(); 12226 if (X_DISPLAY == NULL) 12227 { 12228 EMSG(_("E240: No connection to Vim server")); 12229 return FAIL; 12230 } 12231 return OK; 12232 } 12233 #endif 12234 12235 #ifdef FEAT_CLIENTSERVER 12236 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12237 12238 static void 12239 remote_common(argvars, rettv, expr) 12240 typval_T *argvars; 12241 typval_T *rettv; 12242 int expr; 12243 { 12244 char_u *server_name; 12245 char_u *keys; 12246 char_u *r = NULL; 12247 char_u buf[NUMBUFLEN]; 12248 # ifdef WIN32 12249 HWND w; 12250 # else 12251 Window w; 12252 # endif 12253 12254 if (check_restricted() || check_secure()) 12255 return; 12256 12257 # ifdef FEAT_X11 12258 if (check_connection() == FAIL) 12259 return; 12260 # endif 12261 12262 server_name = get_tv_string_chk(&argvars[0]); 12263 if (server_name == NULL) 12264 return; /* type error; errmsg already given */ 12265 keys = get_tv_string_buf(&argvars[1], buf); 12266 # ifdef WIN32 12267 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12268 # else 12269 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12270 < 0) 12271 # endif 12272 { 12273 if (r != NULL) 12274 EMSG(r); /* sending worked but evaluation failed */ 12275 else 12276 EMSG2(_("E241: Unable to send to %s"), server_name); 12277 return; 12278 } 12279 12280 rettv->vval.v_string = r; 12281 12282 if (argvars[2].v_type != VAR_UNKNOWN) 12283 { 12284 dictitem_T v; 12285 char_u str[30]; 12286 char_u *idvar; 12287 12288 sprintf((char *)str, "0x%x", (unsigned int)w); 12289 v.di_tv.v_type = VAR_STRING; 12290 v.di_tv.vval.v_string = vim_strsave(str); 12291 idvar = get_tv_string_chk(&argvars[2]); 12292 if (idvar != NULL) 12293 set_var(idvar, &v.di_tv, FALSE); 12294 vim_free(v.di_tv.vval.v_string); 12295 } 12296 } 12297 #endif 12298 12299 /* 12300 * "remote_expr()" function 12301 */ 12302 /*ARGSUSED*/ 12303 static void 12304 f_remote_expr(argvars, rettv) 12305 typval_T *argvars; 12306 typval_T *rettv; 12307 { 12308 rettv->v_type = VAR_STRING; 12309 rettv->vval.v_string = NULL; 12310 #ifdef FEAT_CLIENTSERVER 12311 remote_common(argvars, rettv, TRUE); 12312 #endif 12313 } 12314 12315 /* 12316 * "remote_foreground()" function 12317 */ 12318 /*ARGSUSED*/ 12319 static void 12320 f_remote_foreground(argvars, rettv) 12321 typval_T *argvars; 12322 typval_T *rettv; 12323 { 12324 rettv->vval.v_number = 0; 12325 #ifdef FEAT_CLIENTSERVER 12326 # ifdef WIN32 12327 /* On Win32 it's done in this application. */ 12328 { 12329 char_u *server_name = get_tv_string_chk(&argvars[0]); 12330 12331 if (server_name != NULL) 12332 serverForeground(server_name); 12333 } 12334 # else 12335 /* Send a foreground() expression to the server. */ 12336 argvars[1].v_type = VAR_STRING; 12337 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12338 argvars[2].v_type = VAR_UNKNOWN; 12339 remote_common(argvars, rettv, TRUE); 12340 vim_free(argvars[1].vval.v_string); 12341 # endif 12342 #endif 12343 } 12344 12345 /*ARGSUSED*/ 12346 static void 12347 f_remote_peek(argvars, rettv) 12348 typval_T *argvars; 12349 typval_T *rettv; 12350 { 12351 #ifdef FEAT_CLIENTSERVER 12352 dictitem_T v; 12353 char_u *s = NULL; 12354 # ifdef WIN32 12355 int n = 0; 12356 # endif 12357 char_u *serverid; 12358 12359 if (check_restricted() || check_secure()) 12360 { 12361 rettv->vval.v_number = -1; 12362 return; 12363 } 12364 serverid = get_tv_string_chk(&argvars[0]); 12365 if (serverid == NULL) 12366 { 12367 rettv->vval.v_number = -1; 12368 return; /* type error; errmsg already given */ 12369 } 12370 # ifdef WIN32 12371 sscanf(serverid, "%x", &n); 12372 if (n == 0) 12373 rettv->vval.v_number = -1; 12374 else 12375 { 12376 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12377 rettv->vval.v_number = (s != NULL); 12378 } 12379 # else 12380 rettv->vval.v_number = 0; 12381 if (check_connection() == FAIL) 12382 return; 12383 12384 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12385 serverStrToWin(serverid), &s); 12386 # endif 12387 12388 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12389 { 12390 char_u *retvar; 12391 12392 v.di_tv.v_type = VAR_STRING; 12393 v.di_tv.vval.v_string = vim_strsave(s); 12394 retvar = get_tv_string_chk(&argvars[1]); 12395 if (retvar != NULL) 12396 set_var(retvar, &v.di_tv, FALSE); 12397 vim_free(v.di_tv.vval.v_string); 12398 } 12399 #else 12400 rettv->vval.v_number = -1; 12401 #endif 12402 } 12403 12404 /*ARGSUSED*/ 12405 static void 12406 f_remote_read(argvars, rettv) 12407 typval_T *argvars; 12408 typval_T *rettv; 12409 { 12410 char_u *r = NULL; 12411 12412 #ifdef FEAT_CLIENTSERVER 12413 char_u *serverid = get_tv_string_chk(&argvars[0]); 12414 12415 if (serverid != NULL && !check_restricted() && !check_secure()) 12416 { 12417 # ifdef WIN32 12418 /* The server's HWND is encoded in the 'id' parameter */ 12419 int n = 0; 12420 12421 sscanf(serverid, "%x", &n); 12422 if (n != 0) 12423 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12424 if (r == NULL) 12425 # else 12426 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12427 serverStrToWin(serverid), &r, FALSE) < 0) 12428 # endif 12429 EMSG(_("E277: Unable to read a server reply")); 12430 } 12431 #endif 12432 rettv->v_type = VAR_STRING; 12433 rettv->vval.v_string = r; 12434 } 12435 12436 /* 12437 * "remote_send()" function 12438 */ 12439 /*ARGSUSED*/ 12440 static void 12441 f_remote_send(argvars, rettv) 12442 typval_T *argvars; 12443 typval_T *rettv; 12444 { 12445 rettv->v_type = VAR_STRING; 12446 rettv->vval.v_string = NULL; 12447 #ifdef FEAT_CLIENTSERVER 12448 remote_common(argvars, rettv, FALSE); 12449 #endif 12450 } 12451 12452 /* 12453 * "remove()" function 12454 */ 12455 static void 12456 f_remove(argvars, rettv) 12457 typval_T *argvars; 12458 typval_T *rettv; 12459 { 12460 list_T *l; 12461 listitem_T *item, *item2; 12462 listitem_T *li; 12463 long idx; 12464 long end; 12465 char_u *key; 12466 dict_T *d; 12467 dictitem_T *di; 12468 12469 rettv->vval.v_number = 0; 12470 if (argvars[0].v_type == VAR_DICT) 12471 { 12472 if (argvars[2].v_type != VAR_UNKNOWN) 12473 EMSG2(_(e_toomanyarg), "remove()"); 12474 else if ((d = argvars[0].vval.v_dict) != NULL 12475 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12476 { 12477 key = get_tv_string_chk(&argvars[1]); 12478 if (key != NULL) 12479 { 12480 di = dict_find(d, key, -1); 12481 if (di == NULL) 12482 EMSG2(_(e_dictkey), key); 12483 else 12484 { 12485 *rettv = di->di_tv; 12486 init_tv(&di->di_tv); 12487 dictitem_remove(d, di); 12488 } 12489 } 12490 } 12491 } 12492 else if (argvars[0].v_type != VAR_LIST) 12493 EMSG2(_(e_listdictarg), "remove()"); 12494 else if ((l = argvars[0].vval.v_list) != NULL 12495 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12496 { 12497 int error = FALSE; 12498 12499 idx = get_tv_number_chk(&argvars[1], &error); 12500 if (error) 12501 ; /* type error: do nothing, errmsg already given */ 12502 else if ((item = list_find(l, idx)) == NULL) 12503 EMSGN(_(e_listidx), idx); 12504 else 12505 { 12506 if (argvars[2].v_type == VAR_UNKNOWN) 12507 { 12508 /* Remove one item, return its value. */ 12509 list_remove(l, item, item); 12510 *rettv = item->li_tv; 12511 vim_free(item); 12512 } 12513 else 12514 { 12515 /* Remove range of items, return list with values. */ 12516 end = get_tv_number_chk(&argvars[2], &error); 12517 if (error) 12518 ; /* type error: do nothing */ 12519 else if ((item2 = list_find(l, end)) == NULL) 12520 EMSGN(_(e_listidx), end); 12521 else 12522 { 12523 int cnt = 0; 12524 12525 for (li = item; li != NULL; li = li->li_next) 12526 { 12527 ++cnt; 12528 if (li == item2) 12529 break; 12530 } 12531 if (li == NULL) /* didn't find "item2" after "item" */ 12532 EMSG(_(e_invrange)); 12533 else 12534 { 12535 list_remove(l, item, item2); 12536 l = list_alloc(); 12537 if (l != NULL) 12538 { 12539 rettv->v_type = VAR_LIST; 12540 rettv->vval.v_list = l; 12541 l->lv_first = item; 12542 l->lv_last = item2; 12543 l->lv_refcount = 1; 12544 item->li_prev = NULL; 12545 item2->li_next = NULL; 12546 l->lv_len = cnt; 12547 } 12548 } 12549 } 12550 } 12551 } 12552 } 12553 } 12554 12555 /* 12556 * "rename({from}, {to})" function 12557 */ 12558 static void 12559 f_rename(argvars, rettv) 12560 typval_T *argvars; 12561 typval_T *rettv; 12562 { 12563 char_u buf[NUMBUFLEN]; 12564 12565 if (check_restricted() || check_secure()) 12566 rettv->vval.v_number = -1; 12567 else 12568 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12569 get_tv_string_buf(&argvars[1], buf)); 12570 } 12571 12572 /* 12573 * "repeat()" function 12574 */ 12575 /*ARGSUSED*/ 12576 static void 12577 f_repeat(argvars, rettv) 12578 typval_T *argvars; 12579 typval_T *rettv; 12580 { 12581 char_u *p; 12582 int n; 12583 int slen; 12584 int len; 12585 char_u *r; 12586 int i; 12587 list_T *l; 12588 12589 n = get_tv_number(&argvars[1]); 12590 if (argvars[0].v_type == VAR_LIST) 12591 { 12592 l = list_alloc(); 12593 if (l != NULL && argvars[0].vval.v_list != NULL) 12594 { 12595 l->lv_refcount = 1; 12596 while (n-- > 0) 12597 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12598 break; 12599 } 12600 rettv->v_type = VAR_LIST; 12601 rettv->vval.v_list = l; 12602 } 12603 else 12604 { 12605 p = get_tv_string(&argvars[0]); 12606 rettv->v_type = VAR_STRING; 12607 rettv->vval.v_string = NULL; 12608 12609 slen = (int)STRLEN(p); 12610 len = slen * n; 12611 if (len <= 0) 12612 return; 12613 12614 r = alloc(len + 1); 12615 if (r != NULL) 12616 { 12617 for (i = 0; i < n; i++) 12618 mch_memmove(r + i * slen, p, (size_t)slen); 12619 r[len] = NUL; 12620 } 12621 12622 rettv->vval.v_string = r; 12623 } 12624 } 12625 12626 /* 12627 * "resolve()" function 12628 */ 12629 static void 12630 f_resolve(argvars, rettv) 12631 typval_T *argvars; 12632 typval_T *rettv; 12633 { 12634 char_u *p; 12635 12636 p = get_tv_string(&argvars[0]); 12637 #ifdef FEAT_SHORTCUT 12638 { 12639 char_u *v = NULL; 12640 12641 v = mch_resolve_shortcut(p); 12642 if (v != NULL) 12643 rettv->vval.v_string = v; 12644 else 12645 rettv->vval.v_string = vim_strsave(p); 12646 } 12647 #else 12648 # ifdef HAVE_READLINK 12649 { 12650 char_u buf[MAXPATHL + 1]; 12651 char_u *cpy; 12652 int len; 12653 char_u *remain = NULL; 12654 char_u *q; 12655 int is_relative_to_current = FALSE; 12656 int has_trailing_pathsep = FALSE; 12657 int limit = 100; 12658 12659 p = vim_strsave(p); 12660 12661 if (p[0] == '.' && (vim_ispathsep(p[1]) 12662 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12663 is_relative_to_current = TRUE; 12664 12665 len = STRLEN(p); 12666 if (len > 0 && after_pathsep(p, p + len)) 12667 has_trailing_pathsep = TRUE; 12668 12669 q = getnextcomp(p); 12670 if (*q != NUL) 12671 { 12672 /* Separate the first path component in "p", and keep the 12673 * remainder (beginning with the path separator). */ 12674 remain = vim_strsave(q - 1); 12675 q[-1] = NUL; 12676 } 12677 12678 for (;;) 12679 { 12680 for (;;) 12681 { 12682 len = readlink((char *)p, (char *)buf, MAXPATHL); 12683 if (len <= 0) 12684 break; 12685 buf[len] = NUL; 12686 12687 if (limit-- == 0) 12688 { 12689 vim_free(p); 12690 vim_free(remain); 12691 EMSG(_("E655: Too many symbolic links (cycle?)")); 12692 rettv->vval.v_string = NULL; 12693 goto fail; 12694 } 12695 12696 /* Ensure that the result will have a trailing path separator 12697 * if the argument has one. */ 12698 if (remain == NULL && has_trailing_pathsep) 12699 add_pathsep(buf); 12700 12701 /* Separate the first path component in the link value and 12702 * concatenate the remainders. */ 12703 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12704 if (*q != NUL) 12705 { 12706 if (remain == NULL) 12707 remain = vim_strsave(q - 1); 12708 else 12709 { 12710 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12711 if (cpy != NULL) 12712 { 12713 STRCAT(cpy, remain); 12714 vim_free(remain); 12715 remain = cpy; 12716 } 12717 } 12718 q[-1] = NUL; 12719 } 12720 12721 q = gettail(p); 12722 if (q > p && *q == NUL) 12723 { 12724 /* Ignore trailing path separator. */ 12725 q[-1] = NUL; 12726 q = gettail(p); 12727 } 12728 if (q > p && !mch_isFullName(buf)) 12729 { 12730 /* symlink is relative to directory of argument */ 12731 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12732 if (cpy != NULL) 12733 { 12734 STRCPY(cpy, p); 12735 STRCPY(gettail(cpy), buf); 12736 vim_free(p); 12737 p = cpy; 12738 } 12739 } 12740 else 12741 { 12742 vim_free(p); 12743 p = vim_strsave(buf); 12744 } 12745 } 12746 12747 if (remain == NULL) 12748 break; 12749 12750 /* Append the first path component of "remain" to "p". */ 12751 q = getnextcomp(remain + 1); 12752 len = q - remain - (*q != NUL); 12753 cpy = vim_strnsave(p, STRLEN(p) + len); 12754 if (cpy != NULL) 12755 { 12756 STRNCAT(cpy, remain, len); 12757 vim_free(p); 12758 p = cpy; 12759 } 12760 /* Shorten "remain". */ 12761 if (*q != NUL) 12762 STRCPY(remain, q - 1); 12763 else 12764 { 12765 vim_free(remain); 12766 remain = NULL; 12767 } 12768 } 12769 12770 /* If the result is a relative path name, make it explicitly relative to 12771 * the current directory if and only if the argument had this form. */ 12772 if (!vim_ispathsep(*p)) 12773 { 12774 if (is_relative_to_current 12775 && *p != NUL 12776 && !(p[0] == '.' 12777 && (p[1] == NUL 12778 || vim_ispathsep(p[1]) 12779 || (p[1] == '.' 12780 && (p[2] == NUL 12781 || vim_ispathsep(p[2])))))) 12782 { 12783 /* Prepend "./". */ 12784 cpy = concat_str((char_u *)"./", p); 12785 if (cpy != NULL) 12786 { 12787 vim_free(p); 12788 p = cpy; 12789 } 12790 } 12791 else if (!is_relative_to_current) 12792 { 12793 /* Strip leading "./". */ 12794 q = p; 12795 while (q[0] == '.' && vim_ispathsep(q[1])) 12796 q += 2; 12797 if (q > p) 12798 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12799 } 12800 } 12801 12802 /* Ensure that the result will have no trailing path separator 12803 * if the argument had none. But keep "/" or "//". */ 12804 if (!has_trailing_pathsep) 12805 { 12806 q = p + STRLEN(p); 12807 if (after_pathsep(p, q)) 12808 *gettail_sep(p) = NUL; 12809 } 12810 12811 rettv->vval.v_string = p; 12812 } 12813 # else 12814 rettv->vval.v_string = vim_strsave(p); 12815 # endif 12816 #endif 12817 12818 simplify_filename(rettv->vval.v_string); 12819 12820 #ifdef HAVE_READLINK 12821 fail: 12822 #endif 12823 rettv->v_type = VAR_STRING; 12824 } 12825 12826 /* 12827 * "reverse({list})" function 12828 */ 12829 static void 12830 f_reverse(argvars, rettv) 12831 typval_T *argvars; 12832 typval_T *rettv; 12833 { 12834 list_T *l; 12835 listitem_T *li, *ni; 12836 12837 rettv->vval.v_number = 0; 12838 if (argvars[0].v_type != VAR_LIST) 12839 EMSG2(_(e_listarg), "reverse()"); 12840 else if ((l = argvars[0].vval.v_list) != NULL 12841 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12842 { 12843 li = l->lv_last; 12844 l->lv_first = l->lv_last = NULL; 12845 l->lv_len = 0; 12846 while (li != NULL) 12847 { 12848 ni = li->li_prev; 12849 list_append(l, li); 12850 li = ni; 12851 } 12852 rettv->vval.v_list = l; 12853 rettv->v_type = VAR_LIST; 12854 ++l->lv_refcount; 12855 } 12856 } 12857 12858 #define SP_NOMOVE 1 /* don't move cursor */ 12859 #define SP_REPEAT 2 /* repeat to find outer pair */ 12860 #define SP_RETCOUNT 4 /* return matchcount */ 12861 #define SP_SETPCMARK 8 /* set previous context mark */ 12862 12863 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12864 12865 /* 12866 * Get flags for a search function. 12867 * Possibly sets "p_ws". 12868 * Returns BACKWARD, FORWARD or zero (for an error). 12869 */ 12870 static int 12871 get_search_arg(varp, flagsp) 12872 typval_T *varp; 12873 int *flagsp; 12874 { 12875 int dir = FORWARD; 12876 char_u *flags; 12877 char_u nbuf[NUMBUFLEN]; 12878 int mask; 12879 12880 if (varp->v_type != VAR_UNKNOWN) 12881 { 12882 flags = get_tv_string_buf_chk(varp, nbuf); 12883 if (flags == NULL) 12884 return 0; /* type error; errmsg already given */ 12885 while (*flags != NUL) 12886 { 12887 switch (*flags) 12888 { 12889 case 'b': dir = BACKWARD; break; 12890 case 'w': p_ws = TRUE; break; 12891 case 'W': p_ws = FALSE; break; 12892 default: mask = 0; 12893 if (flagsp != NULL) 12894 switch (*flags) 12895 { 12896 case 'n': mask = SP_NOMOVE; break; 12897 case 'r': mask = SP_REPEAT; break; 12898 case 'm': mask = SP_RETCOUNT; break; 12899 case 's': mask = SP_SETPCMARK; break; 12900 } 12901 if (mask == 0) 12902 { 12903 EMSG2(_(e_invarg2), flags); 12904 dir = 0; 12905 } 12906 else 12907 *flagsp |= mask; 12908 } 12909 if (dir == 0) 12910 break; 12911 ++flags; 12912 } 12913 } 12914 return dir; 12915 } 12916 12917 /* 12918 * "search()" function 12919 */ 12920 static void 12921 f_search(argvars, rettv) 12922 typval_T *argvars; 12923 typval_T *rettv; 12924 { 12925 char_u *pat; 12926 pos_T pos; 12927 pos_T save_cursor; 12928 int save_p_ws = p_ws; 12929 int dir; 12930 int flags = 0; 12931 12932 rettv->vval.v_number = 0; /* default: FAIL */ 12933 12934 pat = get_tv_string(&argvars[0]); 12935 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 12936 if (dir == 0) 12937 goto theend; 12938 /* 12939 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 12940 * Check to make sure only those flags are set. 12941 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 12942 * flags cannot be set. Check for that condition also. 12943 */ 12944 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 12945 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 12946 { 12947 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 12948 goto theend; 12949 } 12950 12951 pos = save_cursor = curwin->w_cursor; 12952 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 12953 SEARCH_KEEP, RE_SEARCH) != FAIL) 12954 { 12955 rettv->vval.v_number = pos.lnum; 12956 if (flags & SP_SETPCMARK) 12957 setpcmark(); 12958 curwin->w_cursor = pos; 12959 /* "/$" will put the cursor after the end of the line, may need to 12960 * correct that here */ 12961 check_cursor(); 12962 } 12963 12964 /* If 'n' flag is used: restore cursor position. */ 12965 if (flags & SP_NOMOVE) 12966 curwin->w_cursor = save_cursor; 12967 theend: 12968 p_ws = save_p_ws; 12969 } 12970 12971 /* 12972 * "searchpair()" function 12973 */ 12974 static void 12975 f_searchpair(argvars, rettv) 12976 typval_T *argvars; 12977 typval_T *rettv; 12978 { 12979 char_u *spat, *mpat, *epat; 12980 char_u *skip; 12981 int save_p_ws = p_ws; 12982 int dir; 12983 int flags = 0; 12984 char_u nbuf1[NUMBUFLEN]; 12985 char_u nbuf2[NUMBUFLEN]; 12986 char_u nbuf3[NUMBUFLEN]; 12987 12988 rettv->vval.v_number = 0; /* default: FAIL */ 12989 12990 /* Get the three pattern arguments: start, middle, end. */ 12991 spat = get_tv_string_chk(&argvars[0]); 12992 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 12993 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 12994 if (spat == NULL || mpat == NULL || epat == NULL) 12995 goto theend; /* type error */ 12996 12997 /* Handle the optional fourth argument: flags */ 12998 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 12999 if (dir == 0) 13000 goto theend; 13001 /* 13002 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13003 */ 13004 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13005 { 13006 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13007 goto theend; 13008 } 13009 13010 /* Optional fifth argument: skip expresion */ 13011 if (argvars[3].v_type == VAR_UNKNOWN 13012 || argvars[4].v_type == VAR_UNKNOWN) 13013 skip = (char_u *)""; 13014 else 13015 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13016 if (skip == NULL) 13017 goto theend; /* type error */ 13018 13019 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13020 13021 theend: 13022 p_ws = save_p_ws; 13023 } 13024 13025 /* 13026 * Search for a start/middle/end thing. 13027 * Used by searchpair(), see its documentation for the details. 13028 * Returns 0 or -1 for no match, 13029 */ 13030 long 13031 do_searchpair(spat, mpat, epat, dir, skip, flags) 13032 char_u *spat; /* start pattern */ 13033 char_u *mpat; /* middle pattern */ 13034 char_u *epat; /* end pattern */ 13035 int dir; /* BACKWARD or FORWARD */ 13036 char_u *skip; /* skip expression */ 13037 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13038 { 13039 char_u *save_cpo; 13040 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13041 long retval = 0; 13042 pos_T pos; 13043 pos_T firstpos; 13044 pos_T foundpos; 13045 pos_T save_cursor; 13046 pos_T save_pos; 13047 int n; 13048 int r; 13049 int nest = 1; 13050 int err; 13051 13052 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13053 save_cpo = p_cpo; 13054 p_cpo = (char_u *)""; 13055 13056 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13057 * start/middle/end (pat3, for the top pair). */ 13058 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13059 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13060 if (pat2 == NULL || pat3 == NULL) 13061 goto theend; 13062 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13063 if (*mpat == NUL) 13064 STRCPY(pat3, pat2); 13065 else 13066 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13067 spat, epat, mpat); 13068 13069 save_cursor = curwin->w_cursor; 13070 pos = curwin->w_cursor; 13071 firstpos.lnum = 0; 13072 foundpos.lnum = 0; 13073 pat = pat3; 13074 for (;;) 13075 { 13076 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13077 SEARCH_KEEP, RE_SEARCH); 13078 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13079 /* didn't find it or found the first match again: FAIL */ 13080 break; 13081 13082 if (firstpos.lnum == 0) 13083 firstpos = pos; 13084 if (equalpos(pos, foundpos)) 13085 { 13086 /* Found the same position again. Can happen with a pattern that 13087 * has "\zs" at the end and searching backwards. Advance one 13088 * character and try again. */ 13089 if (dir == BACKWARD) 13090 decl(&pos); 13091 else 13092 incl(&pos); 13093 } 13094 foundpos = pos; 13095 13096 /* If the skip pattern matches, ignore this match. */ 13097 if (*skip != NUL) 13098 { 13099 save_pos = curwin->w_cursor; 13100 curwin->w_cursor = pos; 13101 r = eval_to_bool(skip, &err, NULL, FALSE); 13102 curwin->w_cursor = save_pos; 13103 if (err) 13104 { 13105 /* Evaluating {skip} caused an error, break here. */ 13106 curwin->w_cursor = save_cursor; 13107 retval = -1; 13108 break; 13109 } 13110 if (r) 13111 continue; 13112 } 13113 13114 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13115 { 13116 /* Found end when searching backwards or start when searching 13117 * forward: nested pair. */ 13118 ++nest; 13119 pat = pat2; /* nested, don't search for middle */ 13120 } 13121 else 13122 { 13123 /* Found end when searching forward or start when searching 13124 * backward: end of (nested) pair; or found middle in outer pair. */ 13125 if (--nest == 1) 13126 pat = pat3; /* outer level, search for middle */ 13127 } 13128 13129 if (nest == 0) 13130 { 13131 /* Found the match: return matchcount or line number. */ 13132 if (flags & SP_RETCOUNT) 13133 ++retval; 13134 else 13135 retval = pos.lnum; 13136 if (flags & SP_SETPCMARK) 13137 setpcmark(); 13138 curwin->w_cursor = pos; 13139 if (!(flags & SP_REPEAT)) 13140 break; 13141 nest = 1; /* search for next unmatched */ 13142 } 13143 } 13144 13145 /* If 'n' flag is used or search failed: restore cursor position. */ 13146 if ((flags & SP_NOMOVE) || retval == 0) 13147 curwin->w_cursor = save_cursor; 13148 13149 theend: 13150 vim_free(pat2); 13151 vim_free(pat3); 13152 p_cpo = save_cpo; 13153 13154 return retval; 13155 } 13156 13157 /*ARGSUSED*/ 13158 static void 13159 f_server2client(argvars, rettv) 13160 typval_T *argvars; 13161 typval_T *rettv; 13162 { 13163 #ifdef FEAT_CLIENTSERVER 13164 char_u buf[NUMBUFLEN]; 13165 char_u *server = get_tv_string_chk(&argvars[0]); 13166 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13167 13168 rettv->vval.v_number = -1; 13169 if (server == NULL || reply == NULL) 13170 return; 13171 if (check_restricted() || check_secure()) 13172 return; 13173 # ifdef FEAT_X11 13174 if (check_connection() == FAIL) 13175 return; 13176 # endif 13177 13178 if (serverSendReply(server, reply) < 0) 13179 { 13180 EMSG(_("E258: Unable to send to client")); 13181 return; 13182 } 13183 rettv->vval.v_number = 0; 13184 #else 13185 rettv->vval.v_number = -1; 13186 #endif 13187 } 13188 13189 /*ARGSUSED*/ 13190 static void 13191 f_serverlist(argvars, rettv) 13192 typval_T *argvars; 13193 typval_T *rettv; 13194 { 13195 char_u *r = NULL; 13196 13197 #ifdef FEAT_CLIENTSERVER 13198 # ifdef WIN32 13199 r = serverGetVimNames(); 13200 # else 13201 make_connection(); 13202 if (X_DISPLAY != NULL) 13203 r = serverGetVimNames(X_DISPLAY); 13204 # endif 13205 #endif 13206 rettv->v_type = VAR_STRING; 13207 rettv->vval.v_string = r; 13208 } 13209 13210 /* 13211 * "setbufvar()" function 13212 */ 13213 /*ARGSUSED*/ 13214 static void 13215 f_setbufvar(argvars, rettv) 13216 typval_T *argvars; 13217 typval_T *rettv; 13218 { 13219 buf_T *buf; 13220 #ifdef FEAT_AUTOCMD 13221 aco_save_T aco; 13222 #else 13223 buf_T *save_curbuf; 13224 #endif 13225 char_u *varname, *bufvarname; 13226 typval_T *varp; 13227 char_u nbuf[NUMBUFLEN]; 13228 13229 rettv->vval.v_number = 0; 13230 13231 if (check_restricted() || check_secure()) 13232 return; 13233 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13234 varname = get_tv_string_chk(&argvars[1]); 13235 buf = get_buf_tv(&argvars[0]); 13236 varp = &argvars[2]; 13237 13238 if (buf != NULL && varname != NULL && varp != NULL) 13239 { 13240 /* set curbuf to be our buf, temporarily */ 13241 #ifdef FEAT_AUTOCMD 13242 aucmd_prepbuf(&aco, buf); 13243 #else 13244 save_curbuf = curbuf; 13245 curbuf = buf; 13246 #endif 13247 13248 if (*varname == '&') 13249 { 13250 long numval; 13251 char_u *strval; 13252 int error = FALSE; 13253 13254 ++varname; 13255 numval = get_tv_number_chk(varp, &error); 13256 strval = get_tv_string_buf_chk(varp, nbuf); 13257 if (!error && strval != NULL) 13258 set_option_value(varname, numval, strval, OPT_LOCAL); 13259 } 13260 else 13261 { 13262 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13263 if (bufvarname != NULL) 13264 { 13265 STRCPY(bufvarname, "b:"); 13266 STRCPY(bufvarname + 2, varname); 13267 set_var(bufvarname, varp, TRUE); 13268 vim_free(bufvarname); 13269 } 13270 } 13271 13272 /* reset notion of buffer */ 13273 #ifdef FEAT_AUTOCMD 13274 aucmd_restbuf(&aco); 13275 #else 13276 curbuf = save_curbuf; 13277 #endif 13278 } 13279 } 13280 13281 /* 13282 * "setcmdpos()" function 13283 */ 13284 static void 13285 f_setcmdpos(argvars, rettv) 13286 typval_T *argvars; 13287 typval_T *rettv; 13288 { 13289 int pos = (int)get_tv_number(&argvars[0]) - 1; 13290 13291 if (pos >= 0) 13292 rettv->vval.v_number = set_cmdline_pos(pos); 13293 } 13294 13295 /* 13296 * "setline()" function 13297 */ 13298 static void 13299 f_setline(argvars, rettv) 13300 typval_T *argvars; 13301 typval_T *rettv; 13302 { 13303 linenr_T lnum; 13304 char_u *line = NULL; 13305 list_T *l = NULL; 13306 listitem_T *li = NULL; 13307 long added = 0; 13308 linenr_T lcount = curbuf->b_ml.ml_line_count; 13309 13310 lnum = get_tv_lnum(&argvars[0]); 13311 if (argvars[1].v_type == VAR_LIST) 13312 { 13313 l = argvars[1].vval.v_list; 13314 li = l->lv_first; 13315 } 13316 else 13317 line = get_tv_string_chk(&argvars[1]); 13318 13319 rettv->vval.v_number = 0; /* OK */ 13320 for (;;) 13321 { 13322 if (l != NULL) 13323 { 13324 /* list argument, get next string */ 13325 if (li == NULL) 13326 break; 13327 line = get_tv_string_chk(&li->li_tv); 13328 li = li->li_next; 13329 } 13330 13331 rettv->vval.v_number = 1; /* FAIL */ 13332 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13333 break; 13334 if (lnum <= curbuf->b_ml.ml_line_count) 13335 { 13336 /* existing line, replace it */ 13337 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13338 { 13339 changed_bytes(lnum, 0); 13340 check_cursor_col(); 13341 rettv->vval.v_number = 0; /* OK */ 13342 } 13343 } 13344 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13345 { 13346 /* lnum is one past the last line, append the line */ 13347 ++added; 13348 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13349 rettv->vval.v_number = 0; /* OK */ 13350 } 13351 13352 if (l == NULL) /* only one string argument */ 13353 break; 13354 ++lnum; 13355 } 13356 13357 if (added > 0) 13358 appended_lines_mark(lcount, added); 13359 } 13360 13361 /* 13362 * "setqflist()" function 13363 */ 13364 /*ARGSUSED*/ 13365 static void 13366 f_setqflist(argvars, rettv) 13367 typval_T *argvars; 13368 typval_T *rettv; 13369 { 13370 char_u *act; 13371 int action = ' '; 13372 13373 rettv->vval.v_number = -1; 13374 13375 #ifdef FEAT_QUICKFIX 13376 if (argvars[0].v_type != VAR_LIST) 13377 EMSG(_(e_listreq)); 13378 else 13379 { 13380 list_T *l = argvars[0].vval.v_list; 13381 13382 if (argvars[1].v_type == VAR_STRING) 13383 { 13384 act = get_tv_string_chk(&argvars[1]); 13385 if (act == NULL) 13386 return; /* type error; errmsg already given */ 13387 if (*act == 'a' || *act == 'r') 13388 action = *act; 13389 } 13390 13391 if (l != NULL && set_errorlist(l, action) == OK) 13392 rettv->vval.v_number = 0; 13393 } 13394 #endif 13395 } 13396 13397 /* 13398 * "setreg()" function 13399 */ 13400 static void 13401 f_setreg(argvars, rettv) 13402 typval_T *argvars; 13403 typval_T *rettv; 13404 { 13405 int regname; 13406 char_u *strregname; 13407 char_u *stropt; 13408 char_u *strval; 13409 int append; 13410 char_u yank_type; 13411 long block_len; 13412 13413 block_len = -1; 13414 yank_type = MAUTO; 13415 append = FALSE; 13416 13417 strregname = get_tv_string_chk(argvars); 13418 rettv->vval.v_number = 1; /* FAIL is default */ 13419 13420 if (strregname == NULL) 13421 return; /* type error; errmsg already given */ 13422 regname = *strregname; 13423 if (regname == 0 || regname == '@') 13424 regname = '"'; 13425 else if (regname == '=') 13426 return; 13427 13428 if (argvars[2].v_type != VAR_UNKNOWN) 13429 { 13430 stropt = get_tv_string_chk(&argvars[2]); 13431 if (stropt == NULL) 13432 return; /* type error */ 13433 for (; *stropt != NUL; ++stropt) 13434 switch (*stropt) 13435 { 13436 case 'a': case 'A': /* append */ 13437 append = TRUE; 13438 break; 13439 case 'v': case 'c': /* character-wise selection */ 13440 yank_type = MCHAR; 13441 break; 13442 case 'V': case 'l': /* line-wise selection */ 13443 yank_type = MLINE; 13444 break; 13445 #ifdef FEAT_VISUAL 13446 case 'b': case Ctrl_V: /* block-wise selection */ 13447 yank_type = MBLOCK; 13448 if (VIM_ISDIGIT(stropt[1])) 13449 { 13450 ++stropt; 13451 block_len = getdigits(&stropt) - 1; 13452 --stropt; 13453 } 13454 break; 13455 #endif 13456 } 13457 } 13458 13459 strval = get_tv_string_chk(&argvars[1]); 13460 if (strval != NULL) 13461 write_reg_contents_ex(regname, strval, -1, 13462 append, yank_type, block_len); 13463 rettv->vval.v_number = 0; 13464 } 13465 13466 13467 /* 13468 * "setwinvar(expr)" function 13469 */ 13470 /*ARGSUSED*/ 13471 static void 13472 f_setwinvar(argvars, rettv) 13473 typval_T *argvars; 13474 typval_T *rettv; 13475 { 13476 win_T *win; 13477 #ifdef FEAT_WINDOWS 13478 win_T *save_curwin; 13479 #endif 13480 char_u *varname, *winvarname; 13481 typval_T *varp; 13482 char_u nbuf[NUMBUFLEN]; 13483 13484 rettv->vval.v_number = 0; 13485 13486 if (check_restricted() || check_secure()) 13487 return; 13488 win = find_win_by_nr(&argvars[0]); 13489 varname = get_tv_string_chk(&argvars[1]); 13490 varp = &argvars[2]; 13491 13492 if (win != NULL && varname != NULL && varp != NULL) 13493 { 13494 #ifdef FEAT_WINDOWS 13495 /* set curwin to be our win, temporarily */ 13496 save_curwin = curwin; 13497 curwin = win; 13498 curbuf = curwin->w_buffer; 13499 #endif 13500 13501 if (*varname == '&') 13502 { 13503 long numval; 13504 char_u *strval; 13505 int error = FALSE; 13506 13507 ++varname; 13508 numval = get_tv_number_chk(varp, &error); 13509 strval = get_tv_string_buf_chk(varp, nbuf); 13510 if (!error && strval != NULL) 13511 set_option_value(varname, numval, strval, OPT_LOCAL); 13512 } 13513 else 13514 { 13515 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13516 if (winvarname != NULL) 13517 { 13518 STRCPY(winvarname, "w:"); 13519 STRCPY(winvarname + 2, varname); 13520 set_var(winvarname, varp, TRUE); 13521 vim_free(winvarname); 13522 } 13523 } 13524 13525 #ifdef FEAT_WINDOWS 13526 /* Restore current window, if it's still valid (autocomands can make 13527 * it invalid). */ 13528 if (win_valid(save_curwin)) 13529 { 13530 curwin = save_curwin; 13531 curbuf = curwin->w_buffer; 13532 } 13533 #endif 13534 } 13535 } 13536 13537 /* 13538 * "simplify()" function 13539 */ 13540 static void 13541 f_simplify(argvars, rettv) 13542 typval_T *argvars; 13543 typval_T *rettv; 13544 { 13545 char_u *p; 13546 13547 p = get_tv_string(&argvars[0]); 13548 rettv->vval.v_string = vim_strsave(p); 13549 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13550 rettv->v_type = VAR_STRING; 13551 } 13552 13553 static int 13554 #ifdef __BORLANDC__ 13555 _RTLENTRYF 13556 #endif 13557 item_compare __ARGS((const void *s1, const void *s2)); 13558 static int 13559 #ifdef __BORLANDC__ 13560 _RTLENTRYF 13561 #endif 13562 item_compare2 __ARGS((const void *s1, const void *s2)); 13563 13564 static int item_compare_ic; 13565 static char_u *item_compare_func; 13566 static int item_compare_func_err; 13567 #define ITEM_COMPARE_FAIL 999 13568 13569 /* 13570 * Compare functions for f_sort() below. 13571 */ 13572 static int 13573 #ifdef __BORLANDC__ 13574 _RTLENTRYF 13575 #endif 13576 item_compare(s1, s2) 13577 const void *s1; 13578 const void *s2; 13579 { 13580 char_u *p1, *p2; 13581 char_u *tofree1, *tofree2; 13582 int res; 13583 char_u numbuf1[NUMBUFLEN]; 13584 char_u numbuf2[NUMBUFLEN]; 13585 13586 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13587 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13588 if (item_compare_ic) 13589 res = STRICMP(p1, p2); 13590 else 13591 res = STRCMP(p1, p2); 13592 vim_free(tofree1); 13593 vim_free(tofree2); 13594 return res; 13595 } 13596 13597 static int 13598 #ifdef __BORLANDC__ 13599 _RTLENTRYF 13600 #endif 13601 item_compare2(s1, s2) 13602 const void *s1; 13603 const void *s2; 13604 { 13605 int res; 13606 typval_T rettv; 13607 typval_T argv[2]; 13608 int dummy; 13609 13610 /* shortcut after failure in previous call; compare all items equal */ 13611 if (item_compare_func_err) 13612 return 0; 13613 13614 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13615 * in the copy without changing the original list items. */ 13616 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13617 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13618 13619 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13620 res = call_func(item_compare_func, STRLEN(item_compare_func), 13621 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13622 clear_tv(&argv[0]); 13623 clear_tv(&argv[1]); 13624 13625 if (res == FAIL) 13626 res = ITEM_COMPARE_FAIL; 13627 else 13628 /* return value has wrong type */ 13629 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13630 if (item_compare_func_err) 13631 res = ITEM_COMPARE_FAIL; 13632 clear_tv(&rettv); 13633 return res; 13634 } 13635 13636 /* 13637 * "sort({list})" function 13638 */ 13639 static void 13640 f_sort(argvars, rettv) 13641 typval_T *argvars; 13642 typval_T *rettv; 13643 { 13644 list_T *l; 13645 listitem_T *li; 13646 listitem_T **ptrs; 13647 long len; 13648 long i; 13649 13650 rettv->vval.v_number = 0; 13651 if (argvars[0].v_type != VAR_LIST) 13652 EMSG2(_(e_listarg), "sort()"); 13653 else 13654 { 13655 l = argvars[0].vval.v_list; 13656 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13657 return; 13658 rettv->vval.v_list = l; 13659 rettv->v_type = VAR_LIST; 13660 ++l->lv_refcount; 13661 13662 len = list_len(l); 13663 if (len <= 1) 13664 return; /* short list sorts pretty quickly */ 13665 13666 item_compare_ic = FALSE; 13667 item_compare_func = NULL; 13668 if (argvars[1].v_type != VAR_UNKNOWN) 13669 { 13670 if (argvars[1].v_type == VAR_FUNC) 13671 item_compare_func = argvars[1].vval.v_string; 13672 else 13673 { 13674 int error = FALSE; 13675 13676 i = get_tv_number_chk(&argvars[1], &error); 13677 if (error) 13678 return; /* type error; errmsg already given */ 13679 if (i == 1) 13680 item_compare_ic = TRUE; 13681 else 13682 item_compare_func = get_tv_string(&argvars[1]); 13683 } 13684 } 13685 13686 /* Make an array with each entry pointing to an item in the List. */ 13687 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13688 if (ptrs == NULL) 13689 return; 13690 i = 0; 13691 for (li = l->lv_first; li != NULL; li = li->li_next) 13692 ptrs[i++] = li; 13693 13694 item_compare_func_err = FALSE; 13695 /* test the compare function */ 13696 if (item_compare_func != NULL 13697 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13698 == ITEM_COMPARE_FAIL) 13699 EMSG(_("E702: Sort compare function failed")); 13700 else 13701 { 13702 /* Sort the array with item pointers. */ 13703 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13704 item_compare_func == NULL ? item_compare : item_compare2); 13705 13706 if (!item_compare_func_err) 13707 { 13708 /* Clear the List and append the items in the sorted order. */ 13709 l->lv_first = l->lv_last = NULL; 13710 l->lv_len = 0; 13711 for (i = 0; i < len; ++i) 13712 list_append(l, ptrs[i]); 13713 } 13714 } 13715 13716 vim_free(ptrs); 13717 } 13718 } 13719 13720 /* 13721 * "soundfold({word})" function 13722 */ 13723 static void 13724 f_soundfold(argvars, rettv) 13725 typval_T *argvars; 13726 typval_T *rettv; 13727 { 13728 char_u *s; 13729 13730 rettv->v_type = VAR_STRING; 13731 s = get_tv_string(&argvars[0]); 13732 #ifdef FEAT_SYN_HL 13733 rettv->vval.v_string = eval_soundfold(s); 13734 #else 13735 rettv->vval.v_string = vim_strsave(s); 13736 #endif 13737 } 13738 13739 /* 13740 * "spellbadword()" function 13741 */ 13742 /* ARGSUSED */ 13743 static void 13744 f_spellbadword(argvars, rettv) 13745 typval_T *argvars; 13746 typval_T *rettv; 13747 { 13748 int attr; 13749 char_u *ptr; 13750 int len; 13751 13752 rettv->vval.v_string = NULL; 13753 rettv->v_type = VAR_STRING; 13754 13755 #ifdef FEAT_SYN_HL 13756 /* Find the start of the badly spelled word. */ 13757 if (spell_move_to(FORWARD, TRUE, TRUE) == FAIL) 13758 return; 13759 13760 /* Get the length of the word and copy it. */ 13761 ptr = ml_get_cursor(); 13762 len = spell_check(curwin, ptr, &attr, NULL); 13763 rettv->vval.v_string = vim_strnsave(ptr, len); 13764 #endif 13765 } 13766 13767 /* 13768 * "spellsuggest()" function 13769 */ 13770 static void 13771 f_spellsuggest(argvars, rettv) 13772 typval_T *argvars; 13773 typval_T *rettv; 13774 { 13775 char_u *str; 13776 int maxcount; 13777 garray_T ga; 13778 list_T *l; 13779 listitem_T *li; 13780 int i; 13781 13782 l = list_alloc(); 13783 if (l == NULL) 13784 return; 13785 rettv->v_type = VAR_LIST; 13786 rettv->vval.v_list = l; 13787 ++l->lv_refcount; 13788 13789 #ifdef FEAT_SYN_HL 13790 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13791 { 13792 str = get_tv_string(&argvars[0]); 13793 if (argvars[1].v_type != VAR_UNKNOWN) 13794 { 13795 maxcount = get_tv_number(&argvars[1]); 13796 if (maxcount <= 0) 13797 return; 13798 } 13799 else 13800 maxcount = 25; 13801 13802 spell_suggest_list(&ga, str, maxcount, FALSE); 13803 13804 for (i = 0; i < ga.ga_len; ++i) 13805 { 13806 str = ((char_u **)ga.ga_data)[i]; 13807 13808 li = listitem_alloc(); 13809 if (li == NULL) 13810 vim_free(str); 13811 else 13812 { 13813 li->li_tv.v_type = VAR_STRING; 13814 li->li_tv.v_lock = 0; 13815 li->li_tv.vval.v_string = str; 13816 list_append(l, li); 13817 } 13818 } 13819 ga_clear(&ga); 13820 } 13821 #endif 13822 } 13823 13824 static void 13825 f_split(argvars, rettv) 13826 typval_T *argvars; 13827 typval_T *rettv; 13828 { 13829 char_u *str; 13830 char_u *end; 13831 char_u *pat = NULL; 13832 regmatch_T regmatch; 13833 char_u patbuf[NUMBUFLEN]; 13834 char_u *save_cpo; 13835 int match; 13836 listitem_T *ni; 13837 list_T *l; 13838 colnr_T col = 0; 13839 int keepempty = FALSE; 13840 int typeerr = FALSE; 13841 13842 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13843 save_cpo = p_cpo; 13844 p_cpo = (char_u *)""; 13845 13846 str = get_tv_string(&argvars[0]); 13847 if (argvars[1].v_type != VAR_UNKNOWN) 13848 { 13849 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13850 if (pat == NULL) 13851 typeerr = TRUE; 13852 if (argvars[2].v_type != VAR_UNKNOWN) 13853 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 13854 } 13855 if (pat == NULL || *pat == NUL) 13856 pat = (char_u *)"[\\x01- ]\\+"; 13857 13858 l = list_alloc(); 13859 if (l == NULL) 13860 return; 13861 rettv->v_type = VAR_LIST; 13862 rettv->vval.v_list = l; 13863 ++l->lv_refcount; 13864 if (typeerr) 13865 return; 13866 13867 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13868 if (regmatch.regprog != NULL) 13869 { 13870 regmatch.rm_ic = FALSE; 13871 while (*str != NUL || keepempty) 13872 { 13873 if (*str == NUL) 13874 match = FALSE; /* empty item at the end */ 13875 else 13876 match = vim_regexec_nl(®match, str, col); 13877 if (match) 13878 end = regmatch.startp[0]; 13879 else 13880 end = str + STRLEN(str); 13881 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 13882 && match && end < regmatch.endp[0])) 13883 { 13884 ni = listitem_alloc(); 13885 if (ni == NULL) 13886 break; 13887 ni->li_tv.v_type = VAR_STRING; 13888 ni->li_tv.v_lock = 0; 13889 ni->li_tv.vval.v_string = vim_strnsave(str, end - str); 13890 list_append(l, ni); 13891 } 13892 if (!match) 13893 break; 13894 /* Advance to just after the match. */ 13895 if (regmatch.endp[0] > str) 13896 col = 0; 13897 else 13898 { 13899 /* Don't get stuck at the same match. */ 13900 #ifdef FEAT_MBYTE 13901 col = (*mb_ptr2len)(regmatch.endp[0]); 13902 #else 13903 col = 1; 13904 #endif 13905 } 13906 str = regmatch.endp[0]; 13907 } 13908 13909 vim_free(regmatch.regprog); 13910 } 13911 13912 p_cpo = save_cpo; 13913 } 13914 13915 #ifdef HAVE_STRFTIME 13916 /* 13917 * "strftime({format}[, {time}])" function 13918 */ 13919 static void 13920 f_strftime(argvars, rettv) 13921 typval_T *argvars; 13922 typval_T *rettv; 13923 { 13924 char_u result_buf[256]; 13925 struct tm *curtime; 13926 time_t seconds; 13927 char_u *p; 13928 13929 rettv->v_type = VAR_STRING; 13930 13931 p = get_tv_string(&argvars[0]); 13932 if (argvars[1].v_type == VAR_UNKNOWN) 13933 seconds = time(NULL); 13934 else 13935 seconds = (time_t)get_tv_number(&argvars[1]); 13936 curtime = localtime(&seconds); 13937 /* MSVC returns NULL for an invalid value of seconds. */ 13938 if (curtime == NULL) 13939 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 13940 else 13941 { 13942 # ifdef FEAT_MBYTE 13943 vimconv_T conv; 13944 char_u *enc; 13945 13946 conv.vc_type = CONV_NONE; 13947 enc = enc_locale(); 13948 convert_setup(&conv, p_enc, enc); 13949 if (conv.vc_type != CONV_NONE) 13950 p = string_convert(&conv, p, NULL); 13951 # endif 13952 if (p != NULL) 13953 (void)strftime((char *)result_buf, sizeof(result_buf), 13954 (char *)p, curtime); 13955 else 13956 result_buf[0] = NUL; 13957 13958 # ifdef FEAT_MBYTE 13959 if (conv.vc_type != CONV_NONE) 13960 vim_free(p); 13961 convert_setup(&conv, enc, p_enc); 13962 if (conv.vc_type != CONV_NONE) 13963 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 13964 else 13965 # endif 13966 rettv->vval.v_string = vim_strsave(result_buf); 13967 13968 # ifdef FEAT_MBYTE 13969 /* Release conversion descriptors */ 13970 convert_setup(&conv, NULL, NULL); 13971 vim_free(enc); 13972 # endif 13973 } 13974 } 13975 #endif 13976 13977 /* 13978 * "stridx()" function 13979 */ 13980 static void 13981 f_stridx(argvars, rettv) 13982 typval_T *argvars; 13983 typval_T *rettv; 13984 { 13985 char_u buf[NUMBUFLEN]; 13986 char_u *needle; 13987 char_u *haystack; 13988 char_u *save_haystack; 13989 char_u *pos; 13990 int start_idx; 13991 13992 needle = get_tv_string_chk(&argvars[1]); 13993 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 13994 rettv->vval.v_number = -1; 13995 if (needle == NULL || haystack == NULL) 13996 return; /* type error; errmsg already given */ 13997 13998 if (argvars[2].v_type != VAR_UNKNOWN) 13999 { 14000 int error = FALSE; 14001 14002 start_idx = get_tv_number_chk(&argvars[2], &error); 14003 if (error || start_idx >= (int)STRLEN(haystack)) 14004 return; 14005 if (start_idx >= 0) 14006 haystack += start_idx; 14007 } 14008 14009 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14010 if (pos != NULL) 14011 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14012 } 14013 14014 /* 14015 * "string()" function 14016 */ 14017 static void 14018 f_string(argvars, rettv) 14019 typval_T *argvars; 14020 typval_T *rettv; 14021 { 14022 char_u *tofree; 14023 char_u numbuf[NUMBUFLEN]; 14024 14025 rettv->v_type = VAR_STRING; 14026 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14027 if (tofree == NULL) 14028 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14029 } 14030 14031 /* 14032 * "strlen()" function 14033 */ 14034 static void 14035 f_strlen(argvars, rettv) 14036 typval_T *argvars; 14037 typval_T *rettv; 14038 { 14039 rettv->vval.v_number = (varnumber_T)(STRLEN( 14040 get_tv_string(&argvars[0]))); 14041 } 14042 14043 /* 14044 * "strpart()" function 14045 */ 14046 static void 14047 f_strpart(argvars, rettv) 14048 typval_T *argvars; 14049 typval_T *rettv; 14050 { 14051 char_u *p; 14052 int n; 14053 int len; 14054 int slen; 14055 int error = FALSE; 14056 14057 p = get_tv_string(&argvars[0]); 14058 slen = (int)STRLEN(p); 14059 14060 n = get_tv_number_chk(&argvars[1], &error); 14061 if (error) 14062 len = 0; 14063 else if (argvars[2].v_type != VAR_UNKNOWN) 14064 len = get_tv_number(&argvars[2]); 14065 else 14066 len = slen - n; /* default len: all bytes that are available. */ 14067 14068 /* 14069 * Only return the overlap between the specified part and the actual 14070 * string. 14071 */ 14072 if (n < 0) 14073 { 14074 len += n; 14075 n = 0; 14076 } 14077 else if (n > slen) 14078 n = slen; 14079 if (len < 0) 14080 len = 0; 14081 else if (n + len > slen) 14082 len = slen - n; 14083 14084 rettv->v_type = VAR_STRING; 14085 rettv->vval.v_string = vim_strnsave(p + n, len); 14086 } 14087 14088 /* 14089 * "strridx()" function 14090 */ 14091 static void 14092 f_strridx(argvars, rettv) 14093 typval_T *argvars; 14094 typval_T *rettv; 14095 { 14096 char_u buf[NUMBUFLEN]; 14097 char_u *needle; 14098 char_u *haystack; 14099 char_u *rest; 14100 char_u *lastmatch = NULL; 14101 int haystack_len, end_idx; 14102 14103 needle = get_tv_string_chk(&argvars[1]); 14104 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14105 haystack_len = STRLEN(haystack); 14106 14107 rettv->vval.v_number = -1; 14108 if (needle == NULL || haystack == NULL) 14109 return; /* type error; errmsg already given */ 14110 if (argvars[2].v_type != VAR_UNKNOWN) 14111 { 14112 /* Third argument: upper limit for index */ 14113 end_idx = get_tv_number_chk(&argvars[2], NULL); 14114 if (end_idx < 0) 14115 return; /* can never find a match */ 14116 } 14117 else 14118 end_idx = haystack_len; 14119 14120 if (*needle == NUL) 14121 { 14122 /* Empty string matches past the end. */ 14123 lastmatch = haystack + end_idx; 14124 } 14125 else 14126 { 14127 for (rest = haystack; *rest != '\0'; ++rest) 14128 { 14129 rest = (char_u *)strstr((char *)rest, (char *)needle); 14130 if (rest == NULL || rest > haystack + end_idx) 14131 break; 14132 lastmatch = rest; 14133 } 14134 } 14135 14136 if (lastmatch == NULL) 14137 rettv->vval.v_number = -1; 14138 else 14139 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14140 } 14141 14142 /* 14143 * "strtrans()" function 14144 */ 14145 static void 14146 f_strtrans(argvars, rettv) 14147 typval_T *argvars; 14148 typval_T *rettv; 14149 { 14150 rettv->v_type = VAR_STRING; 14151 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14152 } 14153 14154 /* 14155 * "submatch()" function 14156 */ 14157 static void 14158 f_submatch(argvars, rettv) 14159 typval_T *argvars; 14160 typval_T *rettv; 14161 { 14162 rettv->v_type = VAR_STRING; 14163 rettv->vval.v_string = 14164 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14165 } 14166 14167 /* 14168 * "substitute()" function 14169 */ 14170 static void 14171 f_substitute(argvars, rettv) 14172 typval_T *argvars; 14173 typval_T *rettv; 14174 { 14175 char_u patbuf[NUMBUFLEN]; 14176 char_u subbuf[NUMBUFLEN]; 14177 char_u flagsbuf[NUMBUFLEN]; 14178 14179 char_u *str = get_tv_string_chk(&argvars[0]); 14180 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14181 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14182 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14183 14184 rettv->v_type = VAR_STRING; 14185 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14186 rettv->vval.v_string = NULL; 14187 else 14188 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14189 } 14190 14191 /* 14192 * "synID(lnum, col, trans)" function 14193 */ 14194 /*ARGSUSED*/ 14195 static void 14196 f_synID(argvars, rettv) 14197 typval_T *argvars; 14198 typval_T *rettv; 14199 { 14200 int id = 0; 14201 #ifdef FEAT_SYN_HL 14202 long lnum; 14203 long col; 14204 int trans; 14205 int transerr = FALSE; 14206 14207 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14208 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14209 trans = get_tv_number_chk(&argvars[2], &transerr); 14210 14211 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14212 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14213 id = syn_get_id(lnum, (colnr_T)col, trans, NULL); 14214 #endif 14215 14216 rettv->vval.v_number = id; 14217 } 14218 14219 /* 14220 * "synIDattr(id, what [, mode])" function 14221 */ 14222 /*ARGSUSED*/ 14223 static void 14224 f_synIDattr(argvars, rettv) 14225 typval_T *argvars; 14226 typval_T *rettv; 14227 { 14228 char_u *p = NULL; 14229 #ifdef FEAT_SYN_HL 14230 int id; 14231 char_u *what; 14232 char_u *mode; 14233 char_u modebuf[NUMBUFLEN]; 14234 int modec; 14235 14236 id = get_tv_number(&argvars[0]); 14237 what = get_tv_string(&argvars[1]); 14238 if (argvars[2].v_type != VAR_UNKNOWN) 14239 { 14240 mode = get_tv_string_buf(&argvars[2], modebuf); 14241 modec = TOLOWER_ASC(mode[0]); 14242 if (modec != 't' && modec != 'c' 14243 #ifdef FEAT_GUI 14244 && modec != 'g' 14245 #endif 14246 ) 14247 modec = 0; /* replace invalid with current */ 14248 } 14249 else 14250 { 14251 #ifdef FEAT_GUI 14252 if (gui.in_use) 14253 modec = 'g'; 14254 else 14255 #endif 14256 if (t_colors > 1) 14257 modec = 'c'; 14258 else 14259 modec = 't'; 14260 } 14261 14262 14263 switch (TOLOWER_ASC(what[0])) 14264 { 14265 case 'b': 14266 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14267 p = highlight_color(id, what, modec); 14268 else /* bold */ 14269 p = highlight_has_attr(id, HL_BOLD, modec); 14270 break; 14271 14272 case 'f': /* fg[#] */ 14273 p = highlight_color(id, what, modec); 14274 break; 14275 14276 case 'i': 14277 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14278 p = highlight_has_attr(id, HL_INVERSE, modec); 14279 else /* italic */ 14280 p = highlight_has_attr(id, HL_ITALIC, modec); 14281 break; 14282 14283 case 'n': /* name */ 14284 p = get_highlight_name(NULL, id - 1); 14285 break; 14286 14287 case 'r': /* reverse */ 14288 p = highlight_has_attr(id, HL_INVERSE, modec); 14289 break; 14290 14291 case 's': /* standout */ 14292 p = highlight_has_attr(id, HL_STANDOUT, modec); 14293 break; 14294 14295 case 'u': 14296 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14297 /* underline */ 14298 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14299 else 14300 /* undercurl */ 14301 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14302 break; 14303 } 14304 14305 if (p != NULL) 14306 p = vim_strsave(p); 14307 #endif 14308 rettv->v_type = VAR_STRING; 14309 rettv->vval.v_string = p; 14310 } 14311 14312 /* 14313 * "synIDtrans(id)" function 14314 */ 14315 /*ARGSUSED*/ 14316 static void 14317 f_synIDtrans(argvars, rettv) 14318 typval_T *argvars; 14319 typval_T *rettv; 14320 { 14321 int id; 14322 14323 #ifdef FEAT_SYN_HL 14324 id = get_tv_number(&argvars[0]); 14325 14326 if (id > 0) 14327 id = syn_get_final_id(id); 14328 else 14329 #endif 14330 id = 0; 14331 14332 rettv->vval.v_number = id; 14333 } 14334 14335 /* 14336 * "system()" function 14337 */ 14338 static void 14339 f_system(argvars, rettv) 14340 typval_T *argvars; 14341 typval_T *rettv; 14342 { 14343 char_u *res = NULL; 14344 char_u *p; 14345 char_u *infile = NULL; 14346 char_u buf[NUMBUFLEN]; 14347 int err = FALSE; 14348 FILE *fd; 14349 14350 if (argvars[1].v_type != VAR_UNKNOWN) 14351 { 14352 /* 14353 * Write the string to a temp file, to be used for input of the shell 14354 * command. 14355 */ 14356 if ((infile = vim_tempname('i')) == NULL) 14357 { 14358 EMSG(_(e_notmp)); 14359 return; 14360 } 14361 14362 fd = mch_fopen((char *)infile, WRITEBIN); 14363 if (fd == NULL) 14364 { 14365 EMSG2(_(e_notopen), infile); 14366 goto done; 14367 } 14368 p = get_tv_string_buf_chk(&argvars[1], buf); 14369 if (p == NULL) 14370 goto done; /* type error; errmsg already given */ 14371 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14372 err = TRUE; 14373 if (fclose(fd) != 0) 14374 err = TRUE; 14375 if (err) 14376 { 14377 EMSG(_("E677: Error writing temp file")); 14378 goto done; 14379 } 14380 } 14381 14382 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14383 14384 #ifdef USE_CR 14385 /* translate <CR> into <NL> */ 14386 if (res != NULL) 14387 { 14388 char_u *s; 14389 14390 for (s = res; *s; ++s) 14391 { 14392 if (*s == CAR) 14393 *s = NL; 14394 } 14395 } 14396 #else 14397 # ifdef USE_CRNL 14398 /* translate <CR><NL> into <NL> */ 14399 if (res != NULL) 14400 { 14401 char_u *s, *d; 14402 14403 d = res; 14404 for (s = res; *s; ++s) 14405 { 14406 if (s[0] == CAR && s[1] == NL) 14407 ++s; 14408 *d++ = *s; 14409 } 14410 *d = NUL; 14411 } 14412 # endif 14413 #endif 14414 14415 done: 14416 if (infile != NULL) 14417 { 14418 mch_remove(infile); 14419 vim_free(infile); 14420 } 14421 rettv->v_type = VAR_STRING; 14422 rettv->vval.v_string = res; 14423 } 14424 14425 /* 14426 * "taglist()" function 14427 */ 14428 static void 14429 f_taglist(argvars, rettv) 14430 typval_T *argvars; 14431 typval_T *rettv; 14432 { 14433 char_u *tag_pattern; 14434 list_T *l; 14435 14436 tag_pattern = get_tv_string(&argvars[0]); 14437 14438 rettv->vval.v_number = FALSE; 14439 if (*tag_pattern == NUL) 14440 return; 14441 14442 l = list_alloc(); 14443 if (l != NULL) 14444 { 14445 if (get_tags(l, tag_pattern) != FAIL) 14446 { 14447 rettv->vval.v_list = l; 14448 rettv->v_type = VAR_LIST; 14449 ++l->lv_refcount; 14450 } 14451 else 14452 list_free(l); 14453 } 14454 } 14455 14456 /* 14457 * "tempname()" function 14458 */ 14459 /*ARGSUSED*/ 14460 static void 14461 f_tempname(argvars, rettv) 14462 typval_T *argvars; 14463 typval_T *rettv; 14464 { 14465 static int x = 'A'; 14466 14467 rettv->v_type = VAR_STRING; 14468 rettv->vval.v_string = vim_tempname(x); 14469 14470 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14471 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14472 do 14473 { 14474 if (x == 'Z') 14475 x = '0'; 14476 else if (x == '9') 14477 x = 'A'; 14478 else 14479 { 14480 #ifdef EBCDIC 14481 if (x == 'I') 14482 x = 'J'; 14483 else if (x == 'R') 14484 x = 'S'; 14485 else 14486 #endif 14487 ++x; 14488 } 14489 } while (x == 'I' || x == 'O'); 14490 } 14491 14492 /* 14493 * "tolower(string)" function 14494 */ 14495 static void 14496 f_tolower(argvars, rettv) 14497 typval_T *argvars; 14498 typval_T *rettv; 14499 { 14500 char_u *p; 14501 14502 p = vim_strsave(get_tv_string(&argvars[0])); 14503 rettv->v_type = VAR_STRING; 14504 rettv->vval.v_string = p; 14505 14506 if (p != NULL) 14507 while (*p != NUL) 14508 { 14509 #ifdef FEAT_MBYTE 14510 int l; 14511 14512 if (enc_utf8) 14513 { 14514 int c, lc; 14515 14516 c = utf_ptr2char(p); 14517 lc = utf_tolower(c); 14518 l = utf_ptr2len(p); 14519 /* TODO: reallocate string when byte count changes. */ 14520 if (utf_char2len(lc) == l) 14521 utf_char2bytes(lc, p); 14522 p += l; 14523 } 14524 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14525 p += l; /* skip multi-byte character */ 14526 else 14527 #endif 14528 { 14529 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14530 ++p; 14531 } 14532 } 14533 } 14534 14535 /* 14536 * "toupper(string)" function 14537 */ 14538 static void 14539 f_toupper(argvars, rettv) 14540 typval_T *argvars; 14541 typval_T *rettv; 14542 { 14543 rettv->v_type = VAR_STRING; 14544 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14545 } 14546 14547 /* 14548 * "tr(string, fromstr, tostr)" function 14549 */ 14550 static void 14551 f_tr(argvars, rettv) 14552 typval_T *argvars; 14553 typval_T *rettv; 14554 { 14555 char_u *instr; 14556 char_u *fromstr; 14557 char_u *tostr; 14558 char_u *p; 14559 #ifdef FEAT_MBYTE 14560 int inlen; 14561 int fromlen; 14562 int tolen; 14563 int idx; 14564 char_u *cpstr; 14565 int cplen; 14566 int first = TRUE; 14567 #endif 14568 char_u buf[NUMBUFLEN]; 14569 char_u buf2[NUMBUFLEN]; 14570 garray_T ga; 14571 14572 instr = get_tv_string(&argvars[0]); 14573 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14574 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14575 14576 /* Default return value: empty string. */ 14577 rettv->v_type = VAR_STRING; 14578 rettv->vval.v_string = NULL; 14579 if (fromstr == NULL || tostr == NULL) 14580 return; /* type error; errmsg already given */ 14581 ga_init2(&ga, (int)sizeof(char), 80); 14582 14583 #ifdef FEAT_MBYTE 14584 if (!has_mbyte) 14585 #endif 14586 /* not multi-byte: fromstr and tostr must be the same length */ 14587 if (STRLEN(fromstr) != STRLEN(tostr)) 14588 { 14589 #ifdef FEAT_MBYTE 14590 error: 14591 #endif 14592 EMSG2(_(e_invarg2), fromstr); 14593 ga_clear(&ga); 14594 return; 14595 } 14596 14597 /* fromstr and tostr have to contain the same number of chars */ 14598 while (*instr != NUL) 14599 { 14600 #ifdef FEAT_MBYTE 14601 if (has_mbyte) 14602 { 14603 inlen = (*mb_ptr2len)(instr); 14604 cpstr = instr; 14605 cplen = inlen; 14606 idx = 0; 14607 for (p = fromstr; *p != NUL; p += fromlen) 14608 { 14609 fromlen = (*mb_ptr2len)(p); 14610 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14611 { 14612 for (p = tostr; *p != NUL; p += tolen) 14613 { 14614 tolen = (*mb_ptr2len)(p); 14615 if (idx-- == 0) 14616 { 14617 cplen = tolen; 14618 cpstr = p; 14619 break; 14620 } 14621 } 14622 if (*p == NUL) /* tostr is shorter than fromstr */ 14623 goto error; 14624 break; 14625 } 14626 ++idx; 14627 } 14628 14629 if (first && cpstr == instr) 14630 { 14631 /* Check that fromstr and tostr have the same number of 14632 * (multi-byte) characters. Done only once when a character 14633 * of instr doesn't appear in fromstr. */ 14634 first = FALSE; 14635 for (p = tostr; *p != NUL; p += tolen) 14636 { 14637 tolen = (*mb_ptr2len)(p); 14638 --idx; 14639 } 14640 if (idx != 0) 14641 goto error; 14642 } 14643 14644 ga_grow(&ga, cplen); 14645 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14646 ga.ga_len += cplen; 14647 14648 instr += inlen; 14649 } 14650 else 14651 #endif 14652 { 14653 /* When not using multi-byte chars we can do it faster. */ 14654 p = vim_strchr(fromstr, *instr); 14655 if (p != NULL) 14656 ga_append(&ga, tostr[p - fromstr]); 14657 else 14658 ga_append(&ga, *instr); 14659 ++instr; 14660 } 14661 } 14662 14663 rettv->vval.v_string = ga.ga_data; 14664 } 14665 14666 /* 14667 * "type(expr)" function 14668 */ 14669 static void 14670 f_type(argvars, rettv) 14671 typval_T *argvars; 14672 typval_T *rettv; 14673 { 14674 int n; 14675 14676 switch (argvars[0].v_type) 14677 { 14678 case VAR_NUMBER: n = 0; break; 14679 case VAR_STRING: n = 1; break; 14680 case VAR_FUNC: n = 2; break; 14681 case VAR_LIST: n = 3; break; 14682 case VAR_DICT: n = 4; break; 14683 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14684 } 14685 rettv->vval.v_number = n; 14686 } 14687 14688 /* 14689 * "values(dict)" function 14690 */ 14691 static void 14692 f_values(argvars, rettv) 14693 typval_T *argvars; 14694 typval_T *rettv; 14695 { 14696 dict_list(argvars, rettv, 1); 14697 } 14698 14699 /* 14700 * "virtcol(string)" function 14701 */ 14702 static void 14703 f_virtcol(argvars, rettv) 14704 typval_T *argvars; 14705 typval_T *rettv; 14706 { 14707 colnr_T vcol = 0; 14708 pos_T *fp; 14709 14710 fp = var2fpos(&argvars[0], FALSE); 14711 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14712 { 14713 getvvcol(curwin, fp, NULL, NULL, &vcol); 14714 ++vcol; 14715 } 14716 14717 rettv->vval.v_number = vcol; 14718 } 14719 14720 /* 14721 * "visualmode()" function 14722 */ 14723 /*ARGSUSED*/ 14724 static void 14725 f_visualmode(argvars, rettv) 14726 typval_T *argvars; 14727 typval_T *rettv; 14728 { 14729 #ifdef FEAT_VISUAL 14730 char_u str[2]; 14731 14732 rettv->v_type = VAR_STRING; 14733 str[0] = curbuf->b_visual_mode_eval; 14734 str[1] = NUL; 14735 rettv->vval.v_string = vim_strsave(str); 14736 14737 /* A non-zero number or non-empty string argument: reset mode. */ 14738 if ((argvars[0].v_type == VAR_NUMBER 14739 && argvars[0].vval.v_number != 0) 14740 || (argvars[0].v_type == VAR_STRING 14741 && *get_tv_string(&argvars[0]) != NUL)) 14742 curbuf->b_visual_mode_eval = NUL; 14743 #else 14744 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14745 #endif 14746 } 14747 14748 /* 14749 * "winbufnr(nr)" function 14750 */ 14751 static void 14752 f_winbufnr(argvars, rettv) 14753 typval_T *argvars; 14754 typval_T *rettv; 14755 { 14756 win_T *wp; 14757 14758 wp = find_win_by_nr(&argvars[0]); 14759 if (wp == NULL) 14760 rettv->vval.v_number = -1; 14761 else 14762 rettv->vval.v_number = wp->w_buffer->b_fnum; 14763 } 14764 14765 /* 14766 * "wincol()" function 14767 */ 14768 /*ARGSUSED*/ 14769 static void 14770 f_wincol(argvars, rettv) 14771 typval_T *argvars; 14772 typval_T *rettv; 14773 { 14774 validate_cursor(); 14775 rettv->vval.v_number = curwin->w_wcol + 1; 14776 } 14777 14778 /* 14779 * "winheight(nr)" function 14780 */ 14781 static void 14782 f_winheight(argvars, rettv) 14783 typval_T *argvars; 14784 typval_T *rettv; 14785 { 14786 win_T *wp; 14787 14788 wp = find_win_by_nr(&argvars[0]); 14789 if (wp == NULL) 14790 rettv->vval.v_number = -1; 14791 else 14792 rettv->vval.v_number = wp->w_height; 14793 } 14794 14795 /* 14796 * "winline()" function 14797 */ 14798 /*ARGSUSED*/ 14799 static void 14800 f_winline(argvars, rettv) 14801 typval_T *argvars; 14802 typval_T *rettv; 14803 { 14804 validate_cursor(); 14805 rettv->vval.v_number = curwin->w_wrow + 1; 14806 } 14807 14808 /* 14809 * "winnr()" function 14810 */ 14811 /* ARGSUSED */ 14812 static void 14813 f_winnr(argvars, rettv) 14814 typval_T *argvars; 14815 typval_T *rettv; 14816 { 14817 int nr = 1; 14818 #ifdef FEAT_WINDOWS 14819 win_T *wp; 14820 win_T *twin = curwin; 14821 char_u *arg; 14822 14823 if (argvars[0].v_type != VAR_UNKNOWN) 14824 { 14825 arg = get_tv_string_chk(&argvars[0]); 14826 if (arg == NULL) 14827 nr = 0; /* type error; errmsg already given */ 14828 else if (STRCMP(arg, "$") == 0) 14829 twin = lastwin; 14830 else if (STRCMP(arg, "#") == 0) 14831 { 14832 twin = prevwin; 14833 if (prevwin == NULL) 14834 nr = 0; 14835 } 14836 else 14837 { 14838 EMSG2(_(e_invexpr2), arg); 14839 nr = 0; 14840 } 14841 } 14842 14843 if (nr > 0) 14844 for (wp = firstwin; wp != twin; wp = wp->w_next) 14845 ++nr; 14846 #endif 14847 rettv->vval.v_number = nr; 14848 } 14849 14850 /* 14851 * "winrestcmd()" function 14852 */ 14853 /* ARGSUSED */ 14854 static void 14855 f_winrestcmd(argvars, rettv) 14856 typval_T *argvars; 14857 typval_T *rettv; 14858 { 14859 #ifdef FEAT_WINDOWS 14860 win_T *wp; 14861 int winnr = 1; 14862 garray_T ga; 14863 char_u buf[50]; 14864 14865 ga_init2(&ga, (int)sizeof(char), 70); 14866 for (wp = firstwin; wp != NULL; wp = wp->w_next) 14867 { 14868 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 14869 ga_concat(&ga, buf); 14870 # ifdef FEAT_VERTSPLIT 14871 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 14872 ga_concat(&ga, buf); 14873 # endif 14874 ++winnr; 14875 } 14876 ga_append(&ga, NUL); 14877 14878 rettv->vval.v_string = ga.ga_data; 14879 #else 14880 rettv->vval.v_string = NULL; 14881 #endif 14882 rettv->v_type = VAR_STRING; 14883 } 14884 14885 /* 14886 * "winwidth(nr)" function 14887 */ 14888 static void 14889 f_winwidth(argvars, rettv) 14890 typval_T *argvars; 14891 typval_T *rettv; 14892 { 14893 win_T *wp; 14894 14895 wp = find_win_by_nr(&argvars[0]); 14896 if (wp == NULL) 14897 rettv->vval.v_number = -1; 14898 else 14899 #ifdef FEAT_VERTSPLIT 14900 rettv->vval.v_number = wp->w_width; 14901 #else 14902 rettv->vval.v_number = Columns; 14903 #endif 14904 } 14905 14906 /* 14907 * "writefile()" function 14908 */ 14909 static void 14910 f_writefile(argvars, rettv) 14911 typval_T *argvars; 14912 typval_T *rettv; 14913 { 14914 int binary = FALSE; 14915 char_u *fname; 14916 FILE *fd; 14917 listitem_T *li; 14918 char_u *s; 14919 int ret = 0; 14920 int c; 14921 14922 if (argvars[0].v_type != VAR_LIST) 14923 { 14924 EMSG2(_(e_listarg), "writefile()"); 14925 return; 14926 } 14927 if (argvars[0].vval.v_list == NULL) 14928 return; 14929 14930 if (argvars[2].v_type != VAR_UNKNOWN 14931 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 14932 binary = TRUE; 14933 14934 /* Always open the file in binary mode, library functions have a mind of 14935 * their own about CR-LF conversion. */ 14936 fname = get_tv_string(&argvars[1]); 14937 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 14938 { 14939 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 14940 ret = -1; 14941 } 14942 else 14943 { 14944 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 14945 li = li->li_next) 14946 { 14947 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 14948 { 14949 if (*s == '\n') 14950 c = putc(NUL, fd); 14951 else 14952 c = putc(*s, fd); 14953 if (c == EOF) 14954 { 14955 ret = -1; 14956 break; 14957 } 14958 } 14959 if (!binary || li->li_next != NULL) 14960 if (putc('\n', fd) == EOF) 14961 { 14962 ret = -1; 14963 break; 14964 } 14965 if (ret < 0) 14966 { 14967 EMSG(_(e_write)); 14968 break; 14969 } 14970 } 14971 fclose(fd); 14972 } 14973 14974 rettv->vval.v_number = ret; 14975 } 14976 14977 /* 14978 * Translate a String variable into a position. 14979 */ 14980 static pos_T * 14981 var2fpos(varp, lnum) 14982 typval_T *varp; 14983 int lnum; /* TRUE when $ is last line */ 14984 { 14985 char_u *name; 14986 static pos_T pos; 14987 pos_T *pp; 14988 14989 name = get_tv_string_chk(varp); 14990 if (name == NULL) 14991 return NULL; 14992 if (name[0] == '.') /* cursor */ 14993 return &curwin->w_cursor; 14994 if (name[0] == '\'') /* mark */ 14995 { 14996 pp = getmark(name[1], FALSE); 14997 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 14998 return NULL; 14999 return pp; 15000 } 15001 if (name[0] == '$') /* last column or line */ 15002 { 15003 if (lnum) 15004 { 15005 pos.lnum = curbuf->b_ml.ml_line_count; 15006 pos.col = 0; 15007 } 15008 else 15009 { 15010 pos.lnum = curwin->w_cursor.lnum; 15011 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15012 } 15013 return &pos; 15014 } 15015 return NULL; 15016 } 15017 15018 /* 15019 * Get the length of an environment variable name. 15020 * Advance "arg" to the first character after the name. 15021 * Return 0 for error. 15022 */ 15023 static int 15024 get_env_len(arg) 15025 char_u **arg; 15026 { 15027 char_u *p; 15028 int len; 15029 15030 for (p = *arg; vim_isIDc(*p); ++p) 15031 ; 15032 if (p == *arg) /* no name found */ 15033 return 0; 15034 15035 len = (int)(p - *arg); 15036 *arg = p; 15037 return len; 15038 } 15039 15040 /* 15041 * Get the length of the name of a function or internal variable. 15042 * "arg" is advanced to the first non-white character after the name. 15043 * Return 0 if something is wrong. 15044 */ 15045 static int 15046 get_id_len(arg) 15047 char_u **arg; 15048 { 15049 char_u *p; 15050 int len; 15051 15052 /* Find the end of the name. */ 15053 for (p = *arg; eval_isnamec(*p); ++p) 15054 ; 15055 if (p == *arg) /* no name found */ 15056 return 0; 15057 15058 len = (int)(p - *arg); 15059 *arg = skipwhite(p); 15060 15061 return len; 15062 } 15063 15064 /* 15065 * Get the length of the name of a variable or function. 15066 * Only the name is recognized, does not handle ".key" or "[idx]". 15067 * "arg" is advanced to the first non-white character after the name. 15068 * Return -1 if curly braces expansion failed. 15069 * Return 0 if something else is wrong. 15070 * If the name contains 'magic' {}'s, expand them and return the 15071 * expanded name in an allocated string via 'alias' - caller must free. 15072 */ 15073 static int 15074 get_name_len(arg, alias, evaluate, verbose) 15075 char_u **arg; 15076 char_u **alias; 15077 int evaluate; 15078 int verbose; 15079 { 15080 int len; 15081 char_u *p; 15082 char_u *expr_start; 15083 char_u *expr_end; 15084 15085 *alias = NULL; /* default to no alias */ 15086 15087 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15088 && (*arg)[2] == (int)KE_SNR) 15089 { 15090 /* hard coded <SNR>, already translated */ 15091 *arg += 3; 15092 return get_id_len(arg) + 3; 15093 } 15094 len = eval_fname_script(*arg); 15095 if (len > 0) 15096 { 15097 /* literal "<SID>", "s:" or "<SNR>" */ 15098 *arg += len; 15099 } 15100 15101 /* 15102 * Find the end of the name; check for {} construction. 15103 */ 15104 p = find_name_end(*arg, &expr_start, &expr_end, 15105 len > 0 ? 0 : FNE_CHECK_START); 15106 if (expr_start != NULL) 15107 { 15108 char_u *temp_string; 15109 15110 if (!evaluate) 15111 { 15112 len += (int)(p - *arg); 15113 *arg = skipwhite(p); 15114 return len; 15115 } 15116 15117 /* 15118 * Include any <SID> etc in the expanded string: 15119 * Thus the -len here. 15120 */ 15121 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15122 if (temp_string == NULL) 15123 return -1; 15124 *alias = temp_string; 15125 *arg = skipwhite(p); 15126 return (int)STRLEN(temp_string); 15127 } 15128 15129 len += get_id_len(arg); 15130 if (len == 0 && verbose) 15131 EMSG2(_(e_invexpr2), *arg); 15132 15133 return len; 15134 } 15135 15136 /* 15137 * Find the end of a variable or function name, taking care of magic braces. 15138 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15139 * start and end of the first magic braces item. 15140 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15141 * Return a pointer to just after the name. Equal to "arg" if there is no 15142 * valid name. 15143 */ 15144 static char_u * 15145 find_name_end(arg, expr_start, expr_end, flags) 15146 char_u *arg; 15147 char_u **expr_start; 15148 char_u **expr_end; 15149 int flags; 15150 { 15151 int mb_nest = 0; 15152 int br_nest = 0; 15153 char_u *p; 15154 15155 if (expr_start != NULL) 15156 { 15157 *expr_start = NULL; 15158 *expr_end = NULL; 15159 } 15160 15161 /* Quick check for valid starting character. */ 15162 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15163 return arg; 15164 15165 for (p = arg; *p != NUL 15166 && (eval_isnamec(*p) 15167 || *p == '{' 15168 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15169 || mb_nest != 0 15170 || br_nest != 0); mb_ptr_adv(p)) 15171 { 15172 if (*p == '\'') 15173 { 15174 /* skip over 'string' to avoid counting [ and ] inside it. */ 15175 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15176 ; 15177 if (*p == NUL) 15178 break; 15179 } 15180 else if (*p == '"') 15181 { 15182 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15183 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15184 if (*p == '\\' && p[1] != NUL) 15185 ++p; 15186 if (*p == NUL) 15187 break; 15188 } 15189 15190 if (mb_nest == 0) 15191 { 15192 if (*p == '[') 15193 ++br_nest; 15194 else if (*p == ']') 15195 --br_nest; 15196 } 15197 15198 if (br_nest == 0) 15199 { 15200 if (*p == '{') 15201 { 15202 mb_nest++; 15203 if (expr_start != NULL && *expr_start == NULL) 15204 *expr_start = p; 15205 } 15206 else if (*p == '}') 15207 { 15208 mb_nest--; 15209 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15210 *expr_end = p; 15211 } 15212 } 15213 } 15214 15215 return p; 15216 } 15217 15218 /* 15219 * Expands out the 'magic' {}'s in a variable/function name. 15220 * Note that this can call itself recursively, to deal with 15221 * constructs like foo{bar}{baz}{bam} 15222 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15223 * "in_start" ^ 15224 * "expr_start" ^ 15225 * "expr_end" ^ 15226 * "in_end" ^ 15227 * 15228 * Returns a new allocated string, which the caller must free. 15229 * Returns NULL for failure. 15230 */ 15231 static char_u * 15232 make_expanded_name(in_start, expr_start, expr_end, in_end) 15233 char_u *in_start; 15234 char_u *expr_start; 15235 char_u *expr_end; 15236 char_u *in_end; 15237 { 15238 char_u c1; 15239 char_u *retval = NULL; 15240 char_u *temp_result; 15241 char_u *nextcmd = NULL; 15242 15243 if (expr_end == NULL || in_end == NULL) 15244 return NULL; 15245 *expr_start = NUL; 15246 *expr_end = NUL; 15247 c1 = *in_end; 15248 *in_end = NUL; 15249 15250 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15251 if (temp_result != NULL && nextcmd == NULL) 15252 { 15253 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15254 + (in_end - expr_end) + 1)); 15255 if (retval != NULL) 15256 { 15257 STRCPY(retval, in_start); 15258 STRCAT(retval, temp_result); 15259 STRCAT(retval, expr_end + 1); 15260 } 15261 } 15262 vim_free(temp_result); 15263 15264 *in_end = c1; /* put char back for error messages */ 15265 *expr_start = '{'; 15266 *expr_end = '}'; 15267 15268 if (retval != NULL) 15269 { 15270 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15271 if (expr_start != NULL) 15272 { 15273 /* Further expansion! */ 15274 temp_result = make_expanded_name(retval, expr_start, 15275 expr_end, temp_result); 15276 vim_free(retval); 15277 retval = temp_result; 15278 } 15279 } 15280 15281 return retval; 15282 } 15283 15284 /* 15285 * Return TRUE if character "c" can be used in a variable or function name. 15286 * Does not include '{' or '}' for magic braces. 15287 */ 15288 static int 15289 eval_isnamec(c) 15290 int c; 15291 { 15292 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15293 } 15294 15295 /* 15296 * Return TRUE if character "c" can be used as the first character in a 15297 * variable or function name (excluding '{' and '}'). 15298 */ 15299 static int 15300 eval_isnamec1(c) 15301 int c; 15302 { 15303 return (ASCII_ISALPHA(c) || c == '_'); 15304 } 15305 15306 /* 15307 * Set number v: variable to "val". 15308 */ 15309 void 15310 set_vim_var_nr(idx, val) 15311 int idx; 15312 long val; 15313 { 15314 vimvars[idx].vv_nr = val; 15315 } 15316 15317 /* 15318 * Get number v: variable value. 15319 */ 15320 long 15321 get_vim_var_nr(idx) 15322 int idx; 15323 { 15324 return vimvars[idx].vv_nr; 15325 } 15326 15327 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15328 /* 15329 * Get string v: variable value. Uses a static buffer, can only be used once. 15330 */ 15331 char_u * 15332 get_vim_var_str(idx) 15333 int idx; 15334 { 15335 return get_tv_string(&vimvars[idx].vv_tv); 15336 } 15337 #endif 15338 15339 /* 15340 * Set v:count, v:count1 and v:prevcount. 15341 */ 15342 void 15343 set_vcount(count, count1) 15344 long count; 15345 long count1; 15346 { 15347 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15348 vimvars[VV_COUNT].vv_nr = count; 15349 vimvars[VV_COUNT1].vv_nr = count1; 15350 } 15351 15352 /* 15353 * Set string v: variable to a copy of "val". 15354 */ 15355 void 15356 set_vim_var_string(idx, val, len) 15357 int idx; 15358 char_u *val; 15359 int len; /* length of "val" to use or -1 (whole string) */ 15360 { 15361 /* Need to do this (at least) once, since we can't initialize a union. 15362 * Will always be invoked when "v:progname" is set. */ 15363 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15364 15365 vim_free(vimvars[idx].vv_str); 15366 if (val == NULL) 15367 vimvars[idx].vv_str = NULL; 15368 else if (len == -1) 15369 vimvars[idx].vv_str = vim_strsave(val); 15370 else 15371 vimvars[idx].vv_str = vim_strnsave(val, len); 15372 } 15373 15374 /* 15375 * Set v:register if needed. 15376 */ 15377 void 15378 set_reg_var(c) 15379 int c; 15380 { 15381 char_u regname; 15382 15383 if (c == 0 || c == ' ') 15384 regname = '"'; 15385 else 15386 regname = c; 15387 /* Avoid free/alloc when the value is already right. */ 15388 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15389 set_vim_var_string(VV_REG, ®name, 1); 15390 } 15391 15392 /* 15393 * Get or set v:exception. If "oldval" == NULL, return the current value. 15394 * Otherwise, restore the value to "oldval" and return NULL. 15395 * Must always be called in pairs to save and restore v:exception! Does not 15396 * take care of memory allocations. 15397 */ 15398 char_u * 15399 v_exception(oldval) 15400 char_u *oldval; 15401 { 15402 if (oldval == NULL) 15403 return vimvars[VV_EXCEPTION].vv_str; 15404 15405 vimvars[VV_EXCEPTION].vv_str = oldval; 15406 return NULL; 15407 } 15408 15409 /* 15410 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15411 * Otherwise, restore the value to "oldval" and return NULL. 15412 * Must always be called in pairs to save and restore v:throwpoint! Does not 15413 * take care of memory allocations. 15414 */ 15415 char_u * 15416 v_throwpoint(oldval) 15417 char_u *oldval; 15418 { 15419 if (oldval == NULL) 15420 return vimvars[VV_THROWPOINT].vv_str; 15421 15422 vimvars[VV_THROWPOINT].vv_str = oldval; 15423 return NULL; 15424 } 15425 15426 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15427 /* 15428 * Set v:cmdarg. 15429 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15430 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15431 * Must always be called in pairs! 15432 */ 15433 char_u * 15434 set_cmdarg(eap, oldarg) 15435 exarg_T *eap; 15436 char_u *oldarg; 15437 { 15438 char_u *oldval; 15439 char_u *newval; 15440 unsigned len; 15441 15442 oldval = vimvars[VV_CMDARG].vv_str; 15443 if (eap == NULL) 15444 { 15445 vim_free(oldval); 15446 vimvars[VV_CMDARG].vv_str = oldarg; 15447 return NULL; 15448 } 15449 15450 if (eap->force_bin == FORCE_BIN) 15451 len = 6; 15452 else if (eap->force_bin == FORCE_NOBIN) 15453 len = 8; 15454 else 15455 len = 0; 15456 if (eap->force_ff != 0) 15457 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15458 # ifdef FEAT_MBYTE 15459 if (eap->force_enc != 0) 15460 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15461 # endif 15462 15463 newval = alloc(len + 1); 15464 if (newval == NULL) 15465 return NULL; 15466 15467 if (eap->force_bin == FORCE_BIN) 15468 sprintf((char *)newval, " ++bin"); 15469 else if (eap->force_bin == FORCE_NOBIN) 15470 sprintf((char *)newval, " ++nobin"); 15471 else 15472 *newval = NUL; 15473 if (eap->force_ff != 0) 15474 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15475 eap->cmd + eap->force_ff); 15476 # ifdef FEAT_MBYTE 15477 if (eap->force_enc != 0) 15478 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15479 eap->cmd + eap->force_enc); 15480 # endif 15481 vimvars[VV_CMDARG].vv_str = newval; 15482 return oldval; 15483 } 15484 #endif 15485 15486 /* 15487 * Get the value of internal variable "name". 15488 * Return OK or FAIL. 15489 */ 15490 static int 15491 get_var_tv(name, len, rettv, verbose) 15492 char_u *name; 15493 int len; /* length of "name" */ 15494 typval_T *rettv; /* NULL when only checking existence */ 15495 int verbose; /* may give error message */ 15496 { 15497 int ret = OK; 15498 typval_T *tv = NULL; 15499 typval_T atv; 15500 dictitem_T *v; 15501 int cc; 15502 15503 /* truncate the name, so that we can use strcmp() */ 15504 cc = name[len]; 15505 name[len] = NUL; 15506 15507 /* 15508 * Check for "b:changedtick". 15509 */ 15510 if (STRCMP(name, "b:changedtick") == 0) 15511 { 15512 atv.v_type = VAR_NUMBER; 15513 atv.vval.v_number = curbuf->b_changedtick; 15514 tv = &atv; 15515 } 15516 15517 /* 15518 * Check for user-defined variables. 15519 */ 15520 else 15521 { 15522 v = find_var(name, NULL); 15523 if (v != NULL) 15524 tv = &v->di_tv; 15525 } 15526 15527 if (tv == NULL) 15528 { 15529 if (rettv != NULL && verbose) 15530 EMSG2(_(e_undefvar), name); 15531 ret = FAIL; 15532 } 15533 else if (rettv != NULL) 15534 copy_tv(tv, rettv); 15535 15536 name[len] = cc; 15537 15538 return ret; 15539 } 15540 15541 /* 15542 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15543 * Also handle function call with Funcref variable: func(expr) 15544 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15545 */ 15546 static int 15547 handle_subscript(arg, rettv, evaluate, verbose) 15548 char_u **arg; 15549 typval_T *rettv; 15550 int evaluate; /* do more than finding the end */ 15551 int verbose; /* give error messages */ 15552 { 15553 int ret = OK; 15554 dict_T *selfdict = NULL; 15555 char_u *s; 15556 int len; 15557 typval_T functv; 15558 15559 while (ret == OK 15560 && (**arg == '[' 15561 || (**arg == '.' && rettv->v_type == VAR_DICT) 15562 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15563 && !vim_iswhite(*(*arg - 1))) 15564 { 15565 if (**arg == '(') 15566 { 15567 /* need to copy the funcref so that we can clear rettv */ 15568 functv = *rettv; 15569 rettv->v_type = VAR_UNKNOWN; 15570 15571 /* Invoke the function. Recursive! */ 15572 s = functv.vval.v_string; 15573 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15574 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15575 &len, evaluate, selfdict); 15576 15577 /* Clear the funcref afterwards, so that deleting it while 15578 * evaluating the arguments is possible (see test55). */ 15579 clear_tv(&functv); 15580 15581 /* Stop the expression evaluation when immediately aborting on 15582 * error, or when an interrupt occurred or an exception was thrown 15583 * but not caught. */ 15584 if (aborting()) 15585 { 15586 if (ret == OK) 15587 clear_tv(rettv); 15588 ret = FAIL; 15589 } 15590 dict_unref(selfdict); 15591 selfdict = NULL; 15592 } 15593 else /* **arg == '[' || **arg == '.' */ 15594 { 15595 dict_unref(selfdict); 15596 if (rettv->v_type == VAR_DICT) 15597 { 15598 selfdict = rettv->vval.v_dict; 15599 if (selfdict != NULL) 15600 ++selfdict->dv_refcount; 15601 } 15602 else 15603 selfdict = NULL; 15604 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15605 { 15606 clear_tv(rettv); 15607 ret = FAIL; 15608 } 15609 } 15610 } 15611 dict_unref(selfdict); 15612 return ret; 15613 } 15614 15615 /* 15616 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15617 * value). 15618 */ 15619 static typval_T * 15620 alloc_tv() 15621 { 15622 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15623 } 15624 15625 /* 15626 * Allocate memory for a variable type-value, and assign a string to it. 15627 * The string "s" must have been allocated, it is consumed. 15628 * Return NULL for out of memory, the variable otherwise. 15629 */ 15630 static typval_T * 15631 alloc_string_tv(s) 15632 char_u *s; 15633 { 15634 typval_T *rettv; 15635 15636 rettv = alloc_tv(); 15637 if (rettv != NULL) 15638 { 15639 rettv->v_type = VAR_STRING; 15640 rettv->vval.v_string = s; 15641 } 15642 else 15643 vim_free(s); 15644 return rettv; 15645 } 15646 15647 /* 15648 * Free the memory for a variable type-value. 15649 */ 15650 static void 15651 free_tv(varp) 15652 typval_T *varp; 15653 { 15654 if (varp != NULL) 15655 { 15656 switch (varp->v_type) 15657 { 15658 case VAR_FUNC: 15659 func_unref(varp->vval.v_string); 15660 /*FALLTHROUGH*/ 15661 case VAR_STRING: 15662 vim_free(varp->vval.v_string); 15663 break; 15664 case VAR_LIST: 15665 list_unref(varp->vval.v_list); 15666 break; 15667 case VAR_DICT: 15668 dict_unref(varp->vval.v_dict); 15669 break; 15670 case VAR_NUMBER: 15671 case VAR_UNKNOWN: 15672 break; 15673 default: 15674 EMSG2(_(e_intern2), "free_tv()"); 15675 break; 15676 } 15677 vim_free(varp); 15678 } 15679 } 15680 15681 /* 15682 * Free the memory for a variable value and set the value to NULL or 0. 15683 */ 15684 void 15685 clear_tv(varp) 15686 typval_T *varp; 15687 { 15688 if (varp != NULL) 15689 { 15690 switch (varp->v_type) 15691 { 15692 case VAR_FUNC: 15693 func_unref(varp->vval.v_string); 15694 /*FALLTHROUGH*/ 15695 case VAR_STRING: 15696 vim_free(varp->vval.v_string); 15697 varp->vval.v_string = NULL; 15698 break; 15699 case VAR_LIST: 15700 list_unref(varp->vval.v_list); 15701 varp->vval.v_list = NULL; 15702 break; 15703 case VAR_DICT: 15704 dict_unref(varp->vval.v_dict); 15705 varp->vval.v_dict = NULL; 15706 break; 15707 case VAR_NUMBER: 15708 varp->vval.v_number = 0; 15709 break; 15710 case VAR_UNKNOWN: 15711 break; 15712 default: 15713 EMSG2(_(e_intern2), "clear_tv()"); 15714 } 15715 varp->v_lock = 0; 15716 } 15717 } 15718 15719 /* 15720 * Set the value of a variable to NULL without freeing items. 15721 */ 15722 static void 15723 init_tv(varp) 15724 typval_T *varp; 15725 { 15726 if (varp != NULL) 15727 vim_memset(varp, 0, sizeof(typval_T)); 15728 } 15729 15730 /* 15731 * Get the number value of a variable. 15732 * If it is a String variable, uses vim_str2nr(). 15733 * For incompatible types, return 0. 15734 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15735 * caller of incompatible types: it sets *denote to TRUE if "denote" 15736 * is not NULL or returns -1 otherwise. 15737 */ 15738 static long 15739 get_tv_number(varp) 15740 typval_T *varp; 15741 { 15742 int error = FALSE; 15743 15744 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15745 } 15746 15747 long 15748 get_tv_number_chk(varp, denote) 15749 typval_T *varp; 15750 int *denote; 15751 { 15752 long n = 0L; 15753 15754 switch (varp->v_type) 15755 { 15756 case VAR_NUMBER: 15757 return (long)(varp->vval.v_number); 15758 case VAR_FUNC: 15759 EMSG(_("E703: Using a Funcref as a number")); 15760 break; 15761 case VAR_STRING: 15762 if (varp->vval.v_string != NULL) 15763 vim_str2nr(varp->vval.v_string, NULL, NULL, 15764 TRUE, TRUE, &n, NULL); 15765 return n; 15766 case VAR_LIST: 15767 EMSG(_("E745: Using a List as a number")); 15768 break; 15769 case VAR_DICT: 15770 EMSG(_("E728: Using a Dictionary as a number")); 15771 break; 15772 default: 15773 EMSG2(_(e_intern2), "get_tv_number()"); 15774 break; 15775 } 15776 if (denote == NULL) /* useful for values that must be unsigned */ 15777 n = -1; 15778 else 15779 *denote = TRUE; 15780 return n; 15781 } 15782 15783 /* 15784 * Get the lnum from the first argument. 15785 * Also accepts ".", "$", etc., but that only works for the current buffer. 15786 * Returns -1 on error. 15787 */ 15788 static linenr_T 15789 get_tv_lnum(argvars) 15790 typval_T *argvars; 15791 { 15792 typval_T rettv; 15793 linenr_T lnum; 15794 15795 lnum = get_tv_number_chk(&argvars[0], NULL); 15796 if (lnum == 0) /* no valid number, try using line() */ 15797 { 15798 rettv.v_type = VAR_NUMBER; 15799 f_line(argvars, &rettv); 15800 lnum = rettv.vval.v_number; 15801 clear_tv(&rettv); 15802 } 15803 return lnum; 15804 } 15805 15806 /* 15807 * Get the lnum from the first argument. 15808 * Also accepts "$", then "buf" is used. 15809 * Returns 0 on error. 15810 */ 15811 static linenr_T 15812 get_tv_lnum_buf(argvars, buf) 15813 typval_T *argvars; 15814 buf_T *buf; 15815 { 15816 if (argvars[0].v_type == VAR_STRING 15817 && argvars[0].vval.v_string != NULL 15818 && argvars[0].vval.v_string[0] == '$' 15819 && buf != NULL) 15820 return buf->b_ml.ml_line_count; 15821 return get_tv_number_chk(&argvars[0], NULL); 15822 } 15823 15824 /* 15825 * Get the string value of a variable. 15826 * If it is a Number variable, the number is converted into a string. 15827 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 15828 * get_tv_string_buf() uses a given buffer. 15829 * If the String variable has never been set, return an empty string. 15830 * Never returns NULL; 15831 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 15832 * NULL on error. 15833 */ 15834 static char_u * 15835 get_tv_string(varp) 15836 typval_T *varp; 15837 { 15838 static char_u mybuf[NUMBUFLEN]; 15839 15840 return get_tv_string_buf(varp, mybuf); 15841 } 15842 15843 static char_u * 15844 get_tv_string_buf(varp, buf) 15845 typval_T *varp; 15846 char_u *buf; 15847 { 15848 char_u *res = get_tv_string_buf_chk(varp, buf); 15849 15850 return res != NULL ? res : (char_u *)""; 15851 } 15852 15853 char_u * 15854 get_tv_string_chk(varp) 15855 typval_T *varp; 15856 { 15857 static char_u mybuf[NUMBUFLEN]; 15858 15859 return get_tv_string_buf_chk(varp, mybuf); 15860 } 15861 15862 static char_u * 15863 get_tv_string_buf_chk(varp, buf) 15864 typval_T *varp; 15865 char_u *buf; 15866 { 15867 switch (varp->v_type) 15868 { 15869 case VAR_NUMBER: 15870 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 15871 return buf; 15872 case VAR_FUNC: 15873 EMSG(_("E729: using Funcref as a String")); 15874 break; 15875 case VAR_LIST: 15876 EMSG(_("E730: using List as a String")); 15877 break; 15878 case VAR_DICT: 15879 EMSG(_("E731: using Dictionary as a String")); 15880 break; 15881 case VAR_STRING: 15882 if (varp->vval.v_string != NULL) 15883 return varp->vval.v_string; 15884 return (char_u *)""; 15885 default: 15886 EMSG2(_(e_intern2), "get_tv_string_buf()"); 15887 break; 15888 } 15889 return NULL; 15890 } 15891 15892 /* 15893 * Find variable "name" in the list of variables. 15894 * Return a pointer to it if found, NULL if not found. 15895 * Careful: "a:0" variables don't have a name. 15896 * When "htp" is not NULL we are writing to the variable, set "htp" to the 15897 * hashtab_T used. 15898 */ 15899 static dictitem_T * 15900 find_var(name, htp) 15901 char_u *name; 15902 hashtab_T **htp; 15903 { 15904 char_u *varname; 15905 hashtab_T *ht; 15906 15907 ht = find_var_ht(name, &varname); 15908 if (htp != NULL) 15909 *htp = ht; 15910 if (ht == NULL) 15911 return NULL; 15912 return find_var_in_ht(ht, varname, htp != NULL); 15913 } 15914 15915 /* 15916 * Find variable "varname" in hashtab "ht". 15917 * Returns NULL if not found. 15918 */ 15919 static dictitem_T * 15920 find_var_in_ht(ht, varname, writing) 15921 hashtab_T *ht; 15922 char_u *varname; 15923 int writing; 15924 { 15925 hashitem_T *hi; 15926 15927 if (*varname == NUL) 15928 { 15929 /* Must be something like "s:", otherwise "ht" would be NULL. */ 15930 switch (varname[-2]) 15931 { 15932 case 's': return &SCRIPT_SV(current_SID).sv_var; 15933 case 'g': return &globvars_var; 15934 case 'v': return &vimvars_var; 15935 case 'b': return &curbuf->b_bufvar; 15936 case 'w': return &curwin->w_winvar; 15937 case 'l': return current_funccal == NULL 15938 ? NULL : ¤t_funccal->l_vars_var; 15939 case 'a': return current_funccal == NULL 15940 ? NULL : ¤t_funccal->l_avars_var; 15941 } 15942 return NULL; 15943 } 15944 15945 hi = hash_find(ht, varname); 15946 if (HASHITEM_EMPTY(hi)) 15947 { 15948 /* For global variables we may try auto-loading the script. If it 15949 * worked find the variable again. Don't auto-load a script if it was 15950 * loaded already, otherwise it would be loaded every time when 15951 * checking if a function name is a Funcref variable. */ 15952 if (ht == &globvarht && !writing 15953 && script_autoload(varname, FALSE) && !aborting()) 15954 hi = hash_find(ht, varname); 15955 if (HASHITEM_EMPTY(hi)) 15956 return NULL; 15957 } 15958 return HI2DI(hi); 15959 } 15960 15961 /* 15962 * Find the hashtab used for a variable name. 15963 * Set "varname" to the start of name without ':'. 15964 */ 15965 static hashtab_T * 15966 find_var_ht(name, varname) 15967 char_u *name; 15968 char_u **varname; 15969 { 15970 hashitem_T *hi; 15971 15972 if (name[1] != ':') 15973 { 15974 /* The name must not start with a colon or #. */ 15975 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 15976 return NULL; 15977 *varname = name; 15978 15979 /* "version" is "v:version" in all scopes */ 15980 hi = hash_find(&compat_hashtab, name); 15981 if (!HASHITEM_EMPTY(hi)) 15982 return &compat_hashtab; 15983 15984 if (current_funccal == NULL) 15985 return &globvarht; /* global variable */ 15986 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 15987 } 15988 *varname = name + 2; 15989 if (*name == 'g') /* global variable */ 15990 return &globvarht; 15991 /* There must be no ':' or '#' in the rest of the name, unless g: is used 15992 */ 15993 if (vim_strchr(name + 2, ':') != NULL 15994 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 15995 return NULL; 15996 if (*name == 'b') /* buffer variable */ 15997 return &curbuf->b_vars.dv_hashtab; 15998 if (*name == 'w') /* window variable */ 15999 return &curwin->w_vars.dv_hashtab; 16000 if (*name == 'v') /* v: variable */ 16001 return &vimvarht; 16002 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16003 return ¤t_funccal->l_avars.dv_hashtab; 16004 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16005 return ¤t_funccal->l_vars.dv_hashtab; 16006 if (*name == 's' /* script variable */ 16007 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16008 return &SCRIPT_VARS(current_SID); 16009 return NULL; 16010 } 16011 16012 /* 16013 * Get the string value of a (global/local) variable. 16014 * Returns NULL when it doesn't exist. 16015 */ 16016 char_u * 16017 get_var_value(name) 16018 char_u *name; 16019 { 16020 dictitem_T *v; 16021 16022 v = find_var(name, NULL); 16023 if (v == NULL) 16024 return NULL; 16025 return get_tv_string(&v->di_tv); 16026 } 16027 16028 /* 16029 * Allocate a new hashtab for a sourced script. It will be used while 16030 * sourcing this script and when executing functions defined in the script. 16031 */ 16032 void 16033 new_script_vars(id) 16034 scid_T id; 16035 { 16036 int i; 16037 hashtab_T *ht; 16038 scriptvar_T *sv; 16039 16040 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16041 { 16042 /* Re-allocating ga_data means that an ht_array pointing to 16043 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16044 * at its init value. Also reset "v_dict", it's always the same. */ 16045 for (i = 1; i <= ga_scripts.ga_len; ++i) 16046 { 16047 ht = &SCRIPT_VARS(i); 16048 if (ht->ht_mask == HT_INIT_SIZE - 1) 16049 ht->ht_array = ht->ht_smallarray; 16050 sv = &SCRIPT_SV(i); 16051 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16052 } 16053 16054 while (ga_scripts.ga_len < id) 16055 { 16056 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16057 init_var_dict(&sv->sv_dict, &sv->sv_var); 16058 ++ga_scripts.ga_len; 16059 } 16060 } 16061 } 16062 16063 /* 16064 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16065 * point to it. 16066 */ 16067 void 16068 init_var_dict(dict, dict_var) 16069 dict_T *dict; 16070 dictitem_T *dict_var; 16071 { 16072 hash_init(&dict->dv_hashtab); 16073 dict->dv_refcount = 99999; 16074 dict_var->di_tv.vval.v_dict = dict; 16075 dict_var->di_tv.v_type = VAR_DICT; 16076 dict_var->di_tv.v_lock = VAR_FIXED; 16077 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16078 dict_var->di_key[0] = NUL; 16079 } 16080 16081 /* 16082 * Clean up a list of internal variables. 16083 * Frees all allocated variables and the value they contain. 16084 * Clears hashtab "ht", does not free it. 16085 */ 16086 void 16087 vars_clear(ht) 16088 hashtab_T *ht; 16089 { 16090 vars_clear_ext(ht, TRUE); 16091 } 16092 16093 /* 16094 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16095 */ 16096 static void 16097 vars_clear_ext(ht, free_val) 16098 hashtab_T *ht; 16099 int free_val; 16100 { 16101 int todo; 16102 hashitem_T *hi; 16103 dictitem_T *v; 16104 16105 hash_lock(ht); 16106 todo = ht->ht_used; 16107 for (hi = ht->ht_array; todo > 0; ++hi) 16108 { 16109 if (!HASHITEM_EMPTY(hi)) 16110 { 16111 --todo; 16112 16113 /* Free the variable. Don't remove it from the hashtab, 16114 * ht_array might change then. hash_clear() takes care of it 16115 * later. */ 16116 v = HI2DI(hi); 16117 if (free_val) 16118 clear_tv(&v->di_tv); 16119 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16120 vim_free(v); 16121 } 16122 } 16123 hash_clear(ht); 16124 ht->ht_used = 0; 16125 } 16126 16127 /* 16128 * Delete a variable from hashtab "ht" at item "hi". 16129 * Clear the variable value and free the dictitem. 16130 */ 16131 static void 16132 delete_var(ht, hi) 16133 hashtab_T *ht; 16134 hashitem_T *hi; 16135 { 16136 dictitem_T *di = HI2DI(hi); 16137 16138 hash_remove(ht, hi); 16139 clear_tv(&di->di_tv); 16140 vim_free(di); 16141 } 16142 16143 /* 16144 * List the value of one internal variable. 16145 */ 16146 static void 16147 list_one_var(v, prefix) 16148 dictitem_T *v; 16149 char_u *prefix; 16150 { 16151 char_u *tofree; 16152 char_u *s; 16153 char_u numbuf[NUMBUFLEN]; 16154 16155 s = echo_string(&v->di_tv, &tofree, numbuf); 16156 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16157 s == NULL ? (char_u *)"" : s); 16158 vim_free(tofree); 16159 } 16160 16161 static void 16162 list_one_var_a(prefix, name, type, string) 16163 char_u *prefix; 16164 char_u *name; 16165 int type; 16166 char_u *string; 16167 { 16168 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16169 if (name != NULL) /* "a:" vars don't have a name stored */ 16170 msg_puts(name); 16171 msg_putchar(' '); 16172 msg_advance(22); 16173 if (type == VAR_NUMBER) 16174 msg_putchar('#'); 16175 else if (type == VAR_FUNC) 16176 msg_putchar('*'); 16177 else if (type == VAR_LIST) 16178 { 16179 msg_putchar('['); 16180 if (*string == '[') 16181 ++string; 16182 } 16183 else if (type == VAR_DICT) 16184 { 16185 msg_putchar('{'); 16186 if (*string == '{') 16187 ++string; 16188 } 16189 else 16190 msg_putchar(' '); 16191 16192 msg_outtrans(string); 16193 16194 if (type == VAR_FUNC) 16195 msg_puts((char_u *)"()"); 16196 } 16197 16198 /* 16199 * Set variable "name" to value in "tv". 16200 * If the variable already exists, the value is updated. 16201 * Otherwise the variable is created. 16202 */ 16203 static void 16204 set_var(name, tv, copy) 16205 char_u *name; 16206 typval_T *tv; 16207 int copy; /* make copy of value in "tv" */ 16208 { 16209 dictitem_T *v; 16210 char_u *varname; 16211 hashtab_T *ht; 16212 char_u *p; 16213 16214 if (tv->v_type == VAR_FUNC) 16215 { 16216 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16217 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16218 ? name[2] : name[0])) 16219 { 16220 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16221 return; 16222 } 16223 if (function_exists(name)) 16224 { 16225 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16226 name); 16227 return; 16228 } 16229 } 16230 16231 ht = find_var_ht(name, &varname); 16232 if (ht == NULL || *varname == NUL) 16233 { 16234 EMSG2(_(e_illvar), name); 16235 return; 16236 } 16237 16238 v = find_var_in_ht(ht, varname, TRUE); 16239 if (v != NULL) 16240 { 16241 /* existing variable, need to clear the value */ 16242 if (var_check_ro(v->di_flags, name) 16243 || tv_check_lock(v->di_tv.v_lock, name)) 16244 return; 16245 if (v->di_tv.v_type != tv->v_type 16246 && !((v->di_tv.v_type == VAR_STRING 16247 || v->di_tv.v_type == VAR_NUMBER) 16248 && (tv->v_type == VAR_STRING 16249 || tv->v_type == VAR_NUMBER))) 16250 { 16251 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16252 return; 16253 } 16254 16255 /* 16256 * Handle setting internal v: variables separately: we don't change 16257 * the type. 16258 */ 16259 if (ht == &vimvarht) 16260 { 16261 if (v->di_tv.v_type == VAR_STRING) 16262 { 16263 vim_free(v->di_tv.vval.v_string); 16264 if (copy || tv->v_type != VAR_STRING) 16265 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16266 else 16267 { 16268 /* Take over the string to avoid an extra alloc/free. */ 16269 v->di_tv.vval.v_string = tv->vval.v_string; 16270 tv->vval.v_string = NULL; 16271 } 16272 } 16273 else if (v->di_tv.v_type != VAR_NUMBER) 16274 EMSG2(_(e_intern2), "set_var()"); 16275 else 16276 v->di_tv.vval.v_number = get_tv_number(tv); 16277 return; 16278 } 16279 16280 clear_tv(&v->di_tv); 16281 } 16282 else /* add a new variable */ 16283 { 16284 /* Make sure the variable name is valid. */ 16285 for (p = varname; *p != NUL; ++p) 16286 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16287 { 16288 EMSG2(_(e_illvar), varname); 16289 return; 16290 } 16291 16292 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16293 + STRLEN(varname))); 16294 if (v == NULL) 16295 return; 16296 STRCPY(v->di_key, varname); 16297 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16298 { 16299 vim_free(v); 16300 return; 16301 } 16302 v->di_flags = 0; 16303 } 16304 16305 if (copy || tv->v_type == VAR_NUMBER) 16306 copy_tv(tv, &v->di_tv); 16307 else 16308 { 16309 v->di_tv = *tv; 16310 v->di_tv.v_lock = 0; 16311 init_tv(tv); 16312 } 16313 } 16314 16315 /* 16316 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16317 * Also give an error message. 16318 */ 16319 static int 16320 var_check_ro(flags, name) 16321 int flags; 16322 char_u *name; 16323 { 16324 if (flags & DI_FLAGS_RO) 16325 { 16326 EMSG2(_(e_readonlyvar), name); 16327 return TRUE; 16328 } 16329 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16330 { 16331 EMSG2(_(e_readonlysbx), name); 16332 return TRUE; 16333 } 16334 return FALSE; 16335 } 16336 16337 /* 16338 * Return TRUE if typeval "tv" is set to be locked (immutable). 16339 * Also give an error message, using "name". 16340 */ 16341 static int 16342 tv_check_lock(lock, name) 16343 int lock; 16344 char_u *name; 16345 { 16346 if (lock & VAR_LOCKED) 16347 { 16348 EMSG2(_("E741: Value is locked: %s"), 16349 name == NULL ? (char_u *)_("Unknown") : name); 16350 return TRUE; 16351 } 16352 if (lock & VAR_FIXED) 16353 { 16354 EMSG2(_("E742: Cannot change value of %s"), 16355 name == NULL ? (char_u *)_("Unknown") : name); 16356 return TRUE; 16357 } 16358 return FALSE; 16359 } 16360 16361 /* 16362 * Copy the values from typval_T "from" to typval_T "to". 16363 * When needed allocates string or increases reference count. 16364 * Does not make a copy of a list or dict but copies the reference! 16365 */ 16366 static void 16367 copy_tv(from, to) 16368 typval_T *from; 16369 typval_T *to; 16370 { 16371 to->v_type = from->v_type; 16372 to->v_lock = 0; 16373 switch (from->v_type) 16374 { 16375 case VAR_NUMBER: 16376 to->vval.v_number = from->vval.v_number; 16377 break; 16378 case VAR_STRING: 16379 case VAR_FUNC: 16380 if (from->vval.v_string == NULL) 16381 to->vval.v_string = NULL; 16382 else 16383 { 16384 to->vval.v_string = vim_strsave(from->vval.v_string); 16385 if (from->v_type == VAR_FUNC) 16386 func_ref(to->vval.v_string); 16387 } 16388 break; 16389 case VAR_LIST: 16390 if (from->vval.v_list == NULL) 16391 to->vval.v_list = NULL; 16392 else 16393 { 16394 to->vval.v_list = from->vval.v_list; 16395 ++to->vval.v_list->lv_refcount; 16396 } 16397 break; 16398 case VAR_DICT: 16399 if (from->vval.v_dict == NULL) 16400 to->vval.v_dict = NULL; 16401 else 16402 { 16403 to->vval.v_dict = from->vval.v_dict; 16404 ++to->vval.v_dict->dv_refcount; 16405 } 16406 break; 16407 default: 16408 EMSG2(_(e_intern2), "copy_tv()"); 16409 break; 16410 } 16411 } 16412 16413 /* 16414 * Make a copy of an item. 16415 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16416 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16417 * reference to an already copied list/dict can be used. 16418 * Returns FAIL or OK. 16419 */ 16420 static int 16421 item_copy(from, to, deep, copyID) 16422 typval_T *from; 16423 typval_T *to; 16424 int deep; 16425 int copyID; 16426 { 16427 static int recurse = 0; 16428 int ret = OK; 16429 16430 if (recurse >= DICT_MAXNEST) 16431 { 16432 EMSG(_("E698: variable nested too deep for making a copy")); 16433 return FAIL; 16434 } 16435 ++recurse; 16436 16437 switch (from->v_type) 16438 { 16439 case VAR_NUMBER: 16440 case VAR_STRING: 16441 case VAR_FUNC: 16442 copy_tv(from, to); 16443 break; 16444 case VAR_LIST: 16445 to->v_type = VAR_LIST; 16446 to->v_lock = 0; 16447 if (from->vval.v_list == NULL) 16448 to->vval.v_list = NULL; 16449 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16450 { 16451 /* use the copy made earlier */ 16452 to->vval.v_list = from->vval.v_list->lv_copylist; 16453 ++to->vval.v_list->lv_refcount; 16454 } 16455 else 16456 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16457 if (to->vval.v_list == NULL) 16458 ret = FAIL; 16459 break; 16460 case VAR_DICT: 16461 to->v_type = VAR_DICT; 16462 to->v_lock = 0; 16463 if (from->vval.v_dict == NULL) 16464 to->vval.v_dict = NULL; 16465 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16466 { 16467 /* use the copy made earlier */ 16468 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16469 ++to->vval.v_dict->dv_refcount; 16470 } 16471 else 16472 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16473 if (to->vval.v_dict == NULL) 16474 ret = FAIL; 16475 break; 16476 default: 16477 EMSG2(_(e_intern2), "item_copy()"); 16478 ret = FAIL; 16479 } 16480 --recurse; 16481 return ret; 16482 } 16483 16484 /* 16485 * ":echo expr1 ..." print each argument separated with a space, add a 16486 * newline at the end. 16487 * ":echon expr1 ..." print each argument plain. 16488 */ 16489 void 16490 ex_echo(eap) 16491 exarg_T *eap; 16492 { 16493 char_u *arg = eap->arg; 16494 typval_T rettv; 16495 char_u *tofree; 16496 char_u *p; 16497 int needclr = TRUE; 16498 int atstart = TRUE; 16499 char_u numbuf[NUMBUFLEN]; 16500 16501 if (eap->skip) 16502 ++emsg_skip; 16503 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16504 { 16505 p = arg; 16506 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16507 { 16508 /* 16509 * Report the invalid expression unless the expression evaluation 16510 * has been cancelled due to an aborting error, an interrupt, or an 16511 * exception. 16512 */ 16513 if (!aborting()) 16514 EMSG2(_(e_invexpr2), p); 16515 break; 16516 } 16517 if (!eap->skip) 16518 { 16519 if (atstart) 16520 { 16521 atstart = FALSE; 16522 /* Call msg_start() after eval1(), evaluating the expression 16523 * may cause a message to appear. */ 16524 if (eap->cmdidx == CMD_echo) 16525 msg_start(); 16526 } 16527 else if (eap->cmdidx == CMD_echo) 16528 msg_puts_attr((char_u *)" ", echo_attr); 16529 p = echo_string(&rettv, &tofree, numbuf); 16530 if (p != NULL) 16531 for ( ; *p != NUL && !got_int; ++p) 16532 { 16533 if (*p == '\n' || *p == '\r' || *p == TAB) 16534 { 16535 if (*p != TAB && needclr) 16536 { 16537 /* remove any text still there from the command */ 16538 msg_clr_eos(); 16539 needclr = FALSE; 16540 } 16541 msg_putchar_attr(*p, echo_attr); 16542 } 16543 else 16544 { 16545 #ifdef FEAT_MBYTE 16546 if (has_mbyte) 16547 { 16548 int i = (*mb_ptr2len)(p); 16549 16550 (void)msg_outtrans_len_attr(p, i, echo_attr); 16551 p += i - 1; 16552 } 16553 else 16554 #endif 16555 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16556 } 16557 } 16558 vim_free(tofree); 16559 } 16560 clear_tv(&rettv); 16561 arg = skipwhite(arg); 16562 } 16563 eap->nextcmd = check_nextcmd(arg); 16564 16565 if (eap->skip) 16566 --emsg_skip; 16567 else 16568 { 16569 /* remove text that may still be there from the command */ 16570 if (needclr) 16571 msg_clr_eos(); 16572 if (eap->cmdidx == CMD_echo) 16573 msg_end(); 16574 } 16575 } 16576 16577 /* 16578 * ":echohl {name}". 16579 */ 16580 void 16581 ex_echohl(eap) 16582 exarg_T *eap; 16583 { 16584 int id; 16585 16586 id = syn_name2id(eap->arg); 16587 if (id == 0) 16588 echo_attr = 0; 16589 else 16590 echo_attr = syn_id2attr(id); 16591 } 16592 16593 /* 16594 * ":execute expr1 ..." execute the result of an expression. 16595 * ":echomsg expr1 ..." Print a message 16596 * ":echoerr expr1 ..." Print an error 16597 * Each gets spaces around each argument and a newline at the end for 16598 * echo commands 16599 */ 16600 void 16601 ex_execute(eap) 16602 exarg_T *eap; 16603 { 16604 char_u *arg = eap->arg; 16605 typval_T rettv; 16606 int ret = OK; 16607 char_u *p; 16608 garray_T ga; 16609 int len; 16610 int save_did_emsg; 16611 16612 ga_init2(&ga, 1, 80); 16613 16614 if (eap->skip) 16615 ++emsg_skip; 16616 while (*arg != NUL && *arg != '|' && *arg != '\n') 16617 { 16618 p = arg; 16619 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16620 { 16621 /* 16622 * Report the invalid expression unless the expression evaluation 16623 * has been cancelled due to an aborting error, an interrupt, or an 16624 * exception. 16625 */ 16626 if (!aborting()) 16627 EMSG2(_(e_invexpr2), p); 16628 ret = FAIL; 16629 break; 16630 } 16631 16632 if (!eap->skip) 16633 { 16634 p = get_tv_string(&rettv); 16635 len = (int)STRLEN(p); 16636 if (ga_grow(&ga, len + 2) == FAIL) 16637 { 16638 clear_tv(&rettv); 16639 ret = FAIL; 16640 break; 16641 } 16642 if (ga.ga_len) 16643 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16644 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16645 ga.ga_len += len; 16646 } 16647 16648 clear_tv(&rettv); 16649 arg = skipwhite(arg); 16650 } 16651 16652 if (ret != FAIL && ga.ga_data != NULL) 16653 { 16654 if (eap->cmdidx == CMD_echomsg) 16655 MSG_ATTR(ga.ga_data, echo_attr); 16656 else if (eap->cmdidx == CMD_echoerr) 16657 { 16658 /* We don't want to abort following commands, restore did_emsg. */ 16659 save_did_emsg = did_emsg; 16660 EMSG((char_u *)ga.ga_data); 16661 if (!force_abort) 16662 did_emsg = save_did_emsg; 16663 } 16664 else if (eap->cmdidx == CMD_execute) 16665 do_cmdline((char_u *)ga.ga_data, 16666 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16667 } 16668 16669 ga_clear(&ga); 16670 16671 if (eap->skip) 16672 --emsg_skip; 16673 16674 eap->nextcmd = check_nextcmd(arg); 16675 } 16676 16677 /* 16678 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16679 * "arg" points to the "&" or '+' when called, to "option" when returning. 16680 * Returns NULL when no option name found. Otherwise pointer to the char 16681 * after the option name. 16682 */ 16683 static char_u * 16684 find_option_end(arg, opt_flags) 16685 char_u **arg; 16686 int *opt_flags; 16687 { 16688 char_u *p = *arg; 16689 16690 ++p; 16691 if (*p == 'g' && p[1] == ':') 16692 { 16693 *opt_flags = OPT_GLOBAL; 16694 p += 2; 16695 } 16696 else if (*p == 'l' && p[1] == ':') 16697 { 16698 *opt_flags = OPT_LOCAL; 16699 p += 2; 16700 } 16701 else 16702 *opt_flags = 0; 16703 16704 if (!ASCII_ISALPHA(*p)) 16705 return NULL; 16706 *arg = p; 16707 16708 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16709 p += 4; /* termcap option */ 16710 else 16711 while (ASCII_ISALPHA(*p)) 16712 ++p; 16713 return p; 16714 } 16715 16716 /* 16717 * ":function" 16718 */ 16719 void 16720 ex_function(eap) 16721 exarg_T *eap; 16722 { 16723 char_u *theline; 16724 int j; 16725 int c; 16726 int saved_did_emsg; 16727 char_u *name = NULL; 16728 char_u *p; 16729 char_u *arg; 16730 garray_T newargs; 16731 garray_T newlines; 16732 int varargs = FALSE; 16733 int mustend = FALSE; 16734 int flags = 0; 16735 ufunc_T *fp; 16736 int indent; 16737 int nesting; 16738 char_u *skip_until = NULL; 16739 dictitem_T *v; 16740 funcdict_T fudi; 16741 static int func_nr = 0; /* number for nameless function */ 16742 int paren; 16743 hashtab_T *ht; 16744 int todo; 16745 hashitem_T *hi; 16746 16747 /* 16748 * ":function" without argument: list functions. 16749 */ 16750 if (ends_excmd(*eap->arg)) 16751 { 16752 if (!eap->skip) 16753 { 16754 todo = func_hashtab.ht_used; 16755 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16756 { 16757 if (!HASHITEM_EMPTY(hi)) 16758 { 16759 --todo; 16760 fp = HI2UF(hi); 16761 if (!isdigit(*fp->uf_name)) 16762 list_func_head(fp, FALSE); 16763 } 16764 } 16765 } 16766 eap->nextcmd = check_nextcmd(eap->arg); 16767 return; 16768 } 16769 16770 /* 16771 * Get the function name. There are these situations: 16772 * func normal function name 16773 * "name" == func, "fudi.fd_dict" == NULL 16774 * dict.func new dictionary entry 16775 * "name" == NULL, "fudi.fd_dict" set, 16776 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 16777 * dict.func existing dict entry with a Funcref 16778 * "name" == func, "fudi.fd_dict" set, 16779 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16780 * dict.func existing dict entry that's not a Funcref 16781 * "name" == NULL, "fudi.fd_dict" set, 16782 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16783 */ 16784 p = eap->arg; 16785 name = trans_function_name(&p, eap->skip, 0, &fudi); 16786 paren = (vim_strchr(p, '(') != NULL); 16787 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 16788 { 16789 /* 16790 * Return on an invalid expression in braces, unless the expression 16791 * evaluation has been cancelled due to an aborting error, an 16792 * interrupt, or an exception. 16793 */ 16794 if (!aborting()) 16795 { 16796 if (!eap->skip && fudi.fd_newkey != NULL) 16797 EMSG2(_(e_dictkey), fudi.fd_newkey); 16798 vim_free(fudi.fd_newkey); 16799 return; 16800 } 16801 else 16802 eap->skip = TRUE; 16803 } 16804 /* An error in a function call during evaluation of an expression in magic 16805 * braces should not cause the function not to be defined. */ 16806 saved_did_emsg = did_emsg; 16807 did_emsg = FALSE; 16808 16809 /* 16810 * ":function func" with only function name: list function. 16811 */ 16812 if (!paren) 16813 { 16814 if (!ends_excmd(*skipwhite(p))) 16815 { 16816 EMSG(_(e_trailing)); 16817 goto ret_free; 16818 } 16819 eap->nextcmd = check_nextcmd(p); 16820 if (eap->nextcmd != NULL) 16821 *p = NUL; 16822 if (!eap->skip && !got_int) 16823 { 16824 fp = find_func(name); 16825 if (fp != NULL) 16826 { 16827 list_func_head(fp, TRUE); 16828 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 16829 { 16830 msg_putchar('\n'); 16831 msg_outnum((long)(j + 1)); 16832 if (j < 9) 16833 msg_putchar(' '); 16834 if (j < 99) 16835 msg_putchar(' '); 16836 msg_prt_line(FUNCLINE(fp, j), FALSE); 16837 out_flush(); /* show a line at a time */ 16838 ui_breakcheck(); 16839 } 16840 if (!got_int) 16841 { 16842 msg_putchar('\n'); 16843 msg_puts((char_u *)" endfunction"); 16844 } 16845 } 16846 else 16847 emsg_funcname("E123: Undefined function: %s", name); 16848 } 16849 goto ret_free; 16850 } 16851 16852 /* 16853 * ":function name(arg1, arg2)" Define function. 16854 */ 16855 p = skipwhite(p); 16856 if (*p != '(') 16857 { 16858 if (!eap->skip) 16859 { 16860 EMSG2(_("E124: Missing '(': %s"), eap->arg); 16861 goto ret_free; 16862 } 16863 /* attempt to continue by skipping some text */ 16864 if (vim_strchr(p, '(') != NULL) 16865 p = vim_strchr(p, '('); 16866 } 16867 p = skipwhite(p + 1); 16868 16869 ga_init2(&newargs, (int)sizeof(char_u *), 3); 16870 ga_init2(&newlines, (int)sizeof(char_u *), 3); 16871 16872 if (!eap->skip) 16873 { 16874 /* Check the name of the function. */ 16875 if (name != NULL) 16876 arg = name; 16877 else 16878 arg = fudi.fd_newkey; 16879 if (arg != NULL) 16880 { 16881 if (*arg == K_SPECIAL) 16882 j = 3; 16883 else 16884 j = 0; 16885 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 16886 : eval_isnamec(arg[j]))) 16887 ++j; 16888 if (arg[j] != NUL) 16889 emsg_funcname(_(e_invarg2), arg); 16890 } 16891 } 16892 16893 /* 16894 * Isolate the arguments: "arg1, arg2, ...)" 16895 */ 16896 while (*p != ')') 16897 { 16898 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 16899 { 16900 varargs = TRUE; 16901 p += 3; 16902 mustend = TRUE; 16903 } 16904 else 16905 { 16906 arg = p; 16907 while (ASCII_ISALNUM(*p) || *p == '_') 16908 ++p; 16909 if (arg == p || isdigit(*arg) 16910 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 16911 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 16912 { 16913 if (!eap->skip) 16914 EMSG2(_("E125: Illegal argument: %s"), arg); 16915 break; 16916 } 16917 if (ga_grow(&newargs, 1) == FAIL) 16918 goto erret; 16919 c = *p; 16920 *p = NUL; 16921 arg = vim_strsave(arg); 16922 if (arg == NULL) 16923 goto erret; 16924 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 16925 *p = c; 16926 newargs.ga_len++; 16927 if (*p == ',') 16928 ++p; 16929 else 16930 mustend = TRUE; 16931 } 16932 p = skipwhite(p); 16933 if (mustend && *p != ')') 16934 { 16935 if (!eap->skip) 16936 EMSG2(_(e_invarg2), eap->arg); 16937 break; 16938 } 16939 } 16940 ++p; /* skip the ')' */ 16941 16942 /* find extra arguments "range", "dict" and "abort" */ 16943 for (;;) 16944 { 16945 p = skipwhite(p); 16946 if (STRNCMP(p, "range", 5) == 0) 16947 { 16948 flags |= FC_RANGE; 16949 p += 5; 16950 } 16951 else if (STRNCMP(p, "dict", 4) == 0) 16952 { 16953 flags |= FC_DICT; 16954 p += 4; 16955 } 16956 else if (STRNCMP(p, "abort", 5) == 0) 16957 { 16958 flags |= FC_ABORT; 16959 p += 5; 16960 } 16961 else 16962 break; 16963 } 16964 16965 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 16966 EMSG(_(e_trailing)); 16967 16968 /* 16969 * Read the body of the function, until ":endfunction" is found. 16970 */ 16971 if (KeyTyped) 16972 { 16973 /* Check if the function already exists, don't let the user type the 16974 * whole function before telling him it doesn't work! For a script we 16975 * need to skip the body to be able to find what follows. */ 16976 if (!eap->skip && !eap->forceit) 16977 { 16978 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 16979 EMSG(_(e_funcdict)); 16980 else if (name != NULL && find_func(name) != NULL) 16981 emsg_funcname(e_funcexts, name); 16982 } 16983 16984 if (!eap->skip && did_emsg) 16985 goto erret; 16986 16987 msg_putchar('\n'); /* don't overwrite the function name */ 16988 cmdline_row = msg_row; 16989 } 16990 16991 indent = 2; 16992 nesting = 0; 16993 for (;;) 16994 { 16995 msg_scroll = TRUE; 16996 need_wait_return = FALSE; 16997 if (eap->getline == NULL) 16998 theline = getcmdline(':', 0L, indent); 16999 else 17000 theline = eap->getline(':', eap->cookie, indent); 17001 if (KeyTyped) 17002 lines_left = Rows - 1; 17003 if (theline == NULL) 17004 { 17005 EMSG(_("E126: Missing :endfunction")); 17006 goto erret; 17007 } 17008 17009 if (skip_until != NULL) 17010 { 17011 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17012 * don't check for ":endfunc". */ 17013 if (STRCMP(theline, skip_until) == 0) 17014 { 17015 vim_free(skip_until); 17016 skip_until = NULL; 17017 } 17018 } 17019 else 17020 { 17021 /* skip ':' and blanks*/ 17022 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17023 ; 17024 17025 /* Check for "endfunction". */ 17026 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17027 { 17028 vim_free(theline); 17029 break; 17030 } 17031 17032 /* Increase indent inside "if", "while", "for" and "try", decrease 17033 * at "end". */ 17034 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17035 indent -= 2; 17036 else if (STRNCMP(p, "if", 2) == 0 17037 || STRNCMP(p, "wh", 2) == 0 17038 || STRNCMP(p, "for", 3) == 0 17039 || STRNCMP(p, "try", 3) == 0) 17040 indent += 2; 17041 17042 /* Check for defining a function inside this function. */ 17043 if (checkforcmd(&p, "function", 2)) 17044 { 17045 if (*p == '!') 17046 p = skipwhite(p + 1); 17047 p += eval_fname_script(p); 17048 if (ASCII_ISALPHA(*p)) 17049 { 17050 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17051 if (*skipwhite(p) == '(') 17052 { 17053 ++nesting; 17054 indent += 2; 17055 } 17056 } 17057 } 17058 17059 /* Check for ":append" or ":insert". */ 17060 p = skip_range(p, NULL); 17061 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17062 || (p[0] == 'i' 17063 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17064 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17065 skip_until = vim_strsave((char_u *)"."); 17066 17067 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17068 arg = skipwhite(skiptowhite(p)); 17069 if (arg[0] == '<' && arg[1] =='<' 17070 && ((p[0] == 'p' && p[1] == 'y' 17071 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17072 || (p[0] == 'p' && p[1] == 'e' 17073 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17074 || (p[0] == 't' && p[1] == 'c' 17075 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17076 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17077 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17078 || (p[0] == 'm' && p[1] == 'z' 17079 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17080 )) 17081 { 17082 /* ":python <<" continues until a dot, like ":append" */ 17083 p = skipwhite(arg + 2); 17084 if (*p == NUL) 17085 skip_until = vim_strsave((char_u *)"."); 17086 else 17087 skip_until = vim_strsave(p); 17088 } 17089 } 17090 17091 /* Add the line to the function. */ 17092 if (ga_grow(&newlines, 1) == FAIL) 17093 { 17094 vim_free(theline); 17095 goto erret; 17096 } 17097 17098 /* Copy the line to newly allocated memory. get_one_sourceline() 17099 * allocates 250 bytes per line, this saves 80% on average. The cost 17100 * is an extra alloc/free. */ 17101 p = vim_strsave(theline); 17102 if (p != NULL) 17103 { 17104 vim_free(theline); 17105 theline = p; 17106 } 17107 17108 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17109 newlines.ga_len++; 17110 } 17111 17112 /* Don't define the function when skipping commands or when an error was 17113 * detected. */ 17114 if (eap->skip || did_emsg) 17115 goto erret; 17116 17117 /* 17118 * If there are no errors, add the function 17119 */ 17120 if (fudi.fd_dict == NULL) 17121 { 17122 v = find_var(name, &ht); 17123 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17124 { 17125 emsg_funcname("E707: Function name conflicts with variable: %s", 17126 name); 17127 goto erret; 17128 } 17129 17130 fp = find_func(name); 17131 if (fp != NULL) 17132 { 17133 if (!eap->forceit) 17134 { 17135 emsg_funcname(e_funcexts, name); 17136 goto erret; 17137 } 17138 if (fp->uf_calls > 0) 17139 { 17140 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17141 name); 17142 goto erret; 17143 } 17144 /* redefine existing function */ 17145 ga_clear_strings(&(fp->uf_args)); 17146 ga_clear_strings(&(fp->uf_lines)); 17147 vim_free(name); 17148 name = NULL; 17149 } 17150 } 17151 else 17152 { 17153 char numbuf[20]; 17154 17155 fp = NULL; 17156 if (fudi.fd_newkey == NULL && !eap->forceit) 17157 { 17158 EMSG(_(e_funcdict)); 17159 goto erret; 17160 } 17161 if (fudi.fd_di == NULL) 17162 { 17163 /* Can't add a function to a locked dictionary */ 17164 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17165 goto erret; 17166 } 17167 /* Can't change an existing function if it is locked */ 17168 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17169 goto erret; 17170 17171 /* Give the function a sequential number. Can only be used with a 17172 * Funcref! */ 17173 vim_free(name); 17174 sprintf(numbuf, "%d", ++func_nr); 17175 name = vim_strsave((char_u *)numbuf); 17176 if (name == NULL) 17177 goto erret; 17178 } 17179 17180 if (fp == NULL) 17181 { 17182 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17183 { 17184 int slen, plen; 17185 char_u *scriptname; 17186 17187 /* Check that the autoload name matches the script name. */ 17188 j = FAIL; 17189 if (sourcing_name != NULL) 17190 { 17191 scriptname = autoload_name(name); 17192 if (scriptname != NULL) 17193 { 17194 p = vim_strchr(scriptname, '/'); 17195 plen = STRLEN(p); 17196 slen = STRLEN(sourcing_name); 17197 if (slen > plen && fnamecmp(p, 17198 sourcing_name + slen - plen) == 0) 17199 j = OK; 17200 vim_free(scriptname); 17201 } 17202 } 17203 if (j == FAIL) 17204 { 17205 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17206 goto erret; 17207 } 17208 } 17209 17210 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17211 if (fp == NULL) 17212 goto erret; 17213 17214 if (fudi.fd_dict != NULL) 17215 { 17216 if (fudi.fd_di == NULL) 17217 { 17218 /* add new dict entry */ 17219 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17220 if (fudi.fd_di == NULL) 17221 { 17222 vim_free(fp); 17223 goto erret; 17224 } 17225 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17226 { 17227 vim_free(fudi.fd_di); 17228 goto erret; 17229 } 17230 } 17231 else 17232 /* overwrite existing dict entry */ 17233 clear_tv(&fudi.fd_di->di_tv); 17234 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17235 fudi.fd_di->di_tv.v_lock = 0; 17236 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17237 fp->uf_refcount = 1; 17238 } 17239 17240 /* insert the new function in the function list */ 17241 STRCPY(fp->uf_name, name); 17242 hash_add(&func_hashtab, UF2HIKEY(fp)); 17243 } 17244 fp->uf_args = newargs; 17245 fp->uf_lines = newlines; 17246 #ifdef FEAT_PROFILE 17247 fp->uf_tml_count = NULL; 17248 fp->uf_tml_total = NULL; 17249 fp->uf_tml_self = NULL; 17250 fp->uf_profiling = FALSE; 17251 if (prof_def_func()) 17252 func_do_profile(fp); 17253 #endif 17254 fp->uf_varargs = varargs; 17255 fp->uf_flags = flags; 17256 fp->uf_calls = 0; 17257 fp->uf_script_ID = current_SID; 17258 goto ret_free; 17259 17260 erret: 17261 ga_clear_strings(&newargs); 17262 ga_clear_strings(&newlines); 17263 ret_free: 17264 vim_free(skip_until); 17265 vim_free(fudi.fd_newkey); 17266 vim_free(name); 17267 did_emsg |= saved_did_emsg; 17268 } 17269 17270 /* 17271 * Get a function name, translating "<SID>" and "<SNR>". 17272 * Also handles a Funcref in a List or Dictionary. 17273 * Returns the function name in allocated memory, or NULL for failure. 17274 * flags: 17275 * TFN_INT: internal function name OK 17276 * TFN_QUIET: be quiet 17277 * Advances "pp" to just after the function name (if no error). 17278 */ 17279 static char_u * 17280 trans_function_name(pp, skip, flags, fdp) 17281 char_u **pp; 17282 int skip; /* only find the end, don't evaluate */ 17283 int flags; 17284 funcdict_T *fdp; /* return: info about dictionary used */ 17285 { 17286 char_u *name = NULL; 17287 char_u *start; 17288 char_u *end; 17289 int lead; 17290 char_u sid_buf[20]; 17291 int len; 17292 lval_T lv; 17293 17294 if (fdp != NULL) 17295 vim_memset(fdp, 0, sizeof(funcdict_T)); 17296 start = *pp; 17297 17298 /* Check for hard coded <SNR>: already translated function ID (from a user 17299 * command). */ 17300 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17301 && (*pp)[2] == (int)KE_SNR) 17302 { 17303 *pp += 3; 17304 len = get_id_len(pp) + 3; 17305 return vim_strnsave(start, len); 17306 } 17307 17308 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17309 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17310 lead = eval_fname_script(start); 17311 if (lead > 2) 17312 start += lead; 17313 17314 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17315 lead > 2 ? 0 : FNE_CHECK_START); 17316 if (end == start) 17317 { 17318 if (!skip) 17319 EMSG(_("E129: Function name required")); 17320 goto theend; 17321 } 17322 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17323 { 17324 /* 17325 * Report an invalid expression in braces, unless the expression 17326 * evaluation has been cancelled due to an aborting error, an 17327 * interrupt, or an exception. 17328 */ 17329 if (!aborting()) 17330 { 17331 if (end != NULL) 17332 EMSG2(_(e_invarg2), start); 17333 } 17334 else 17335 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17336 goto theend; 17337 } 17338 17339 if (lv.ll_tv != NULL) 17340 { 17341 if (fdp != NULL) 17342 { 17343 fdp->fd_dict = lv.ll_dict; 17344 fdp->fd_newkey = lv.ll_newkey; 17345 lv.ll_newkey = NULL; 17346 fdp->fd_di = lv.ll_di; 17347 } 17348 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17349 { 17350 name = vim_strsave(lv.ll_tv->vval.v_string); 17351 *pp = end; 17352 } 17353 else 17354 { 17355 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17356 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17357 EMSG(_(e_funcref)); 17358 else 17359 *pp = end; 17360 name = NULL; 17361 } 17362 goto theend; 17363 } 17364 17365 if (lv.ll_name == NULL) 17366 { 17367 /* Error found, but continue after the function name. */ 17368 *pp = end; 17369 goto theend; 17370 } 17371 17372 if (lv.ll_exp_name != NULL) 17373 len = STRLEN(lv.ll_exp_name); 17374 else 17375 { 17376 if (lead == 2) /* skip over "s:" */ 17377 lv.ll_name += 2; 17378 len = (int)(end - lv.ll_name); 17379 } 17380 17381 /* 17382 * Copy the function name to allocated memory. 17383 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17384 * Accept <SNR>123_name() outside a script. 17385 */ 17386 if (skip) 17387 lead = 0; /* do nothing */ 17388 else if (lead > 0) 17389 { 17390 lead = 3; 17391 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17392 { 17393 if (current_SID <= 0) 17394 { 17395 EMSG(_(e_usingsid)); 17396 goto theend; 17397 } 17398 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17399 lead += (int)STRLEN(sid_buf); 17400 } 17401 } 17402 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17403 { 17404 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17405 goto theend; 17406 } 17407 name = alloc((unsigned)(len + lead + 1)); 17408 if (name != NULL) 17409 { 17410 if (lead > 0) 17411 { 17412 name[0] = K_SPECIAL; 17413 name[1] = KS_EXTRA; 17414 name[2] = (int)KE_SNR; 17415 if (lead > 3) /* If it's "<SID>" */ 17416 STRCPY(name + 3, sid_buf); 17417 } 17418 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17419 name[len + lead] = NUL; 17420 } 17421 *pp = end; 17422 17423 theend: 17424 clear_lval(&lv); 17425 return name; 17426 } 17427 17428 /* 17429 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17430 * Return 2 if "p" starts with "s:". 17431 * Return 0 otherwise. 17432 */ 17433 static int 17434 eval_fname_script(p) 17435 char_u *p; 17436 { 17437 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17438 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17439 return 5; 17440 if (p[0] == 's' && p[1] == ':') 17441 return 2; 17442 return 0; 17443 } 17444 17445 /* 17446 * Return TRUE if "p" starts with "<SID>" or "s:". 17447 * Only works if eval_fname_script() returned non-zero for "p"! 17448 */ 17449 static int 17450 eval_fname_sid(p) 17451 char_u *p; 17452 { 17453 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17454 } 17455 17456 /* 17457 * List the head of the function: "name(arg1, arg2)". 17458 */ 17459 static void 17460 list_func_head(fp, indent) 17461 ufunc_T *fp; 17462 int indent; 17463 { 17464 int j; 17465 17466 msg_start(); 17467 if (indent) 17468 MSG_PUTS(" "); 17469 MSG_PUTS("function "); 17470 if (fp->uf_name[0] == K_SPECIAL) 17471 { 17472 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17473 msg_puts(fp->uf_name + 3); 17474 } 17475 else 17476 msg_puts(fp->uf_name); 17477 msg_putchar('('); 17478 for (j = 0; j < fp->uf_args.ga_len; ++j) 17479 { 17480 if (j) 17481 MSG_PUTS(", "); 17482 msg_puts(FUNCARG(fp, j)); 17483 } 17484 if (fp->uf_varargs) 17485 { 17486 if (j) 17487 MSG_PUTS(", "); 17488 MSG_PUTS("..."); 17489 } 17490 msg_putchar(')'); 17491 #ifdef FEAT_EVAL 17492 if (p_verbose > 0) 17493 last_set_msg(fp->uf_script_ID); 17494 #endif 17495 } 17496 17497 /* 17498 * Find a function by name, return pointer to it in ufuncs. 17499 * Return NULL for unknown function. 17500 */ 17501 static ufunc_T * 17502 find_func(name) 17503 char_u *name; 17504 { 17505 hashitem_T *hi; 17506 17507 hi = hash_find(&func_hashtab, name); 17508 if (!HASHITEM_EMPTY(hi)) 17509 return HI2UF(hi); 17510 return NULL; 17511 } 17512 17513 #if defined(EXITFREE) || defined(PROTO) 17514 void 17515 free_all_functions() 17516 { 17517 hashitem_T *hi; 17518 17519 /* Need to start all over every time, because func_free() may change the 17520 * hash table. */ 17521 while (func_hashtab.ht_used > 0) 17522 for (hi = func_hashtab.ht_array; ; ++hi) 17523 if (!HASHITEM_EMPTY(hi)) 17524 { 17525 func_free(HI2UF(hi)); 17526 break; 17527 } 17528 } 17529 #endif 17530 17531 /* 17532 * Return TRUE if a function "name" exists. 17533 */ 17534 static int 17535 function_exists(name) 17536 char_u *name; 17537 { 17538 char_u *p = name; 17539 int n = FALSE; 17540 17541 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17542 if (p != NULL) 17543 { 17544 if (builtin_function(p)) 17545 n = (find_internal_func(p) >= 0); 17546 else 17547 n = (find_func(p) != NULL); 17548 vim_free(p); 17549 } 17550 return n; 17551 } 17552 17553 /* 17554 * Return TRUE if "name" looks like a builtin function name: starts with a 17555 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17556 */ 17557 static int 17558 builtin_function(name) 17559 char_u *name; 17560 { 17561 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17562 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17563 } 17564 17565 #if defined(FEAT_PROFILE) || defined(PROTO) 17566 /* 17567 * Start profiling function "fp". 17568 */ 17569 static void 17570 func_do_profile(fp) 17571 ufunc_T *fp; 17572 { 17573 fp->uf_tm_count = 0; 17574 profile_zero(&fp->uf_tm_self); 17575 profile_zero(&fp->uf_tm_total); 17576 if (fp->uf_tml_count == NULL) 17577 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17578 (sizeof(int) * fp->uf_lines.ga_len)); 17579 if (fp->uf_tml_total == NULL) 17580 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17581 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17582 if (fp->uf_tml_self == NULL) 17583 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17584 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17585 fp->uf_tml_idx = -1; 17586 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17587 || fp->uf_tml_self == NULL) 17588 return; /* out of memory */ 17589 17590 fp->uf_profiling = TRUE; 17591 } 17592 17593 /* 17594 * Dump the profiling results for all functions in file "fd". 17595 */ 17596 void 17597 func_dump_profile(fd) 17598 FILE *fd; 17599 { 17600 hashitem_T *hi; 17601 int todo; 17602 ufunc_T *fp; 17603 int i; 17604 ufunc_T **sorttab; 17605 int st_len = 0; 17606 17607 todo = func_hashtab.ht_used; 17608 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17609 17610 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17611 { 17612 if (!HASHITEM_EMPTY(hi)) 17613 { 17614 --todo; 17615 fp = HI2UF(hi); 17616 if (fp->uf_profiling) 17617 { 17618 if (sorttab != NULL) 17619 sorttab[st_len++] = fp; 17620 17621 if (fp->uf_name[0] == K_SPECIAL) 17622 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17623 else 17624 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17625 if (fp->uf_tm_count == 1) 17626 fprintf(fd, "Called 1 time\n"); 17627 else 17628 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17629 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17630 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17631 fprintf(fd, "\n"); 17632 fprintf(fd, "count total (s) self (s)\n"); 17633 17634 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17635 { 17636 prof_func_line(fd, fp->uf_tml_count[i], 17637 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17638 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17639 } 17640 fprintf(fd, "\n"); 17641 } 17642 } 17643 } 17644 17645 if (sorttab != NULL && st_len > 0) 17646 { 17647 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17648 prof_total_cmp); 17649 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17650 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17651 prof_self_cmp); 17652 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17653 } 17654 } 17655 17656 static void 17657 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17658 FILE *fd; 17659 ufunc_T **sorttab; 17660 int st_len; 17661 char *title; 17662 int prefer_self; /* when equal print only self time */ 17663 { 17664 int i; 17665 ufunc_T *fp; 17666 17667 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17668 fprintf(fd, "count total (s) self (s) function\n"); 17669 for (i = 0; i < 20 && i < st_len; ++i) 17670 { 17671 fp = sorttab[i]; 17672 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17673 prefer_self); 17674 if (fp->uf_name[0] == K_SPECIAL) 17675 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17676 else 17677 fprintf(fd, " %s()\n", fp->uf_name); 17678 } 17679 fprintf(fd, "\n"); 17680 } 17681 17682 /* 17683 * Print the count and times for one function or function line. 17684 */ 17685 static void 17686 prof_func_line(fd, count, total, self, prefer_self) 17687 FILE *fd; 17688 int count; 17689 proftime_T *total; 17690 proftime_T *self; 17691 int prefer_self; /* when equal print only self time */ 17692 { 17693 if (count > 0) 17694 { 17695 fprintf(fd, "%5d ", count); 17696 if (prefer_self && profile_equal(total, self)) 17697 fprintf(fd, " "); 17698 else 17699 fprintf(fd, "%s ", profile_msg(total)); 17700 if (!prefer_self && profile_equal(total, self)) 17701 fprintf(fd, " "); 17702 else 17703 fprintf(fd, "%s ", profile_msg(self)); 17704 } 17705 else 17706 fprintf(fd, " "); 17707 } 17708 17709 /* 17710 * Compare function for total time sorting. 17711 */ 17712 static int 17713 #ifdef __BORLANDC__ 17714 _RTLENTRYF 17715 #endif 17716 prof_total_cmp(s1, s2) 17717 const void *s1; 17718 const void *s2; 17719 { 17720 ufunc_T *p1, *p2; 17721 17722 p1 = *(ufunc_T **)s1; 17723 p2 = *(ufunc_T **)s2; 17724 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 17725 } 17726 17727 /* 17728 * Compare function for self time sorting. 17729 */ 17730 static int 17731 #ifdef __BORLANDC__ 17732 _RTLENTRYF 17733 #endif 17734 prof_self_cmp(s1, s2) 17735 const void *s1; 17736 const void *s2; 17737 { 17738 ufunc_T *p1, *p2; 17739 17740 p1 = *(ufunc_T **)s1; 17741 p2 = *(ufunc_T **)s2; 17742 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 17743 } 17744 17745 #endif 17746 17747 /* The names of packages that once were loaded is remembered. */ 17748 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 17749 17750 /* 17751 * If "name" has a package name try autoloading the script for it. 17752 * Return TRUE if a package was loaded. 17753 */ 17754 static int 17755 script_autoload(name, reload) 17756 char_u *name; 17757 int reload; /* load script again when already loaded */ 17758 { 17759 char_u *p; 17760 char_u *scriptname, *tofree; 17761 int ret = FALSE; 17762 int i; 17763 17764 /* If there is no '#' after name[0] there is no package name. */ 17765 p = vim_strchr(name, AUTOLOAD_CHAR); 17766 if (p == NULL || p == name) 17767 return FALSE; 17768 17769 tofree = scriptname = autoload_name(name); 17770 17771 /* Find the name in the list of previously loaded package names. Skip 17772 * "autoload/", it's always the same. */ 17773 for (i = 0; i < ga_loaded.ga_len; ++i) 17774 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 17775 break; 17776 if (!reload && i < ga_loaded.ga_len) 17777 ret = FALSE; /* was loaded already */ 17778 else 17779 { 17780 /* Remember the name if it wasn't loaded already. */ 17781 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 17782 { 17783 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 17784 tofree = NULL; 17785 } 17786 17787 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 17788 if (source_runtime(scriptname, FALSE) == OK) 17789 ret = TRUE; 17790 } 17791 17792 vim_free(tofree); 17793 return ret; 17794 } 17795 17796 /* 17797 * Return the autoload script name for a function or variable name. 17798 * Returns NULL when out of memory. 17799 */ 17800 static char_u * 17801 autoload_name(name) 17802 char_u *name; 17803 { 17804 char_u *p; 17805 char_u *scriptname; 17806 17807 /* Get the script file name: replace '#' with '/', append ".vim". */ 17808 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 17809 if (scriptname == NULL) 17810 return FALSE; 17811 STRCPY(scriptname, "autoload/"); 17812 STRCAT(scriptname, name); 17813 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 17814 STRCAT(scriptname, ".vim"); 17815 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 17816 *p = '/'; 17817 return scriptname; 17818 } 17819 17820 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 17821 17822 /* 17823 * Function given to ExpandGeneric() to obtain the list of user defined 17824 * function names. 17825 */ 17826 char_u * 17827 get_user_func_name(xp, idx) 17828 expand_T *xp; 17829 int idx; 17830 { 17831 static long_u done; 17832 static hashitem_T *hi; 17833 ufunc_T *fp; 17834 17835 if (idx == 0) 17836 { 17837 done = 0; 17838 hi = func_hashtab.ht_array; 17839 } 17840 if (done < func_hashtab.ht_used) 17841 { 17842 if (done++ > 0) 17843 ++hi; 17844 while (HASHITEM_EMPTY(hi)) 17845 ++hi; 17846 fp = HI2UF(hi); 17847 17848 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 17849 return fp->uf_name; /* prevents overflow */ 17850 17851 cat_func_name(IObuff, fp); 17852 if (xp->xp_context != EXPAND_USER_FUNC) 17853 { 17854 STRCAT(IObuff, "("); 17855 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 17856 STRCAT(IObuff, ")"); 17857 } 17858 return IObuff; 17859 } 17860 return NULL; 17861 } 17862 17863 #endif /* FEAT_CMDL_COMPL */ 17864 17865 /* 17866 * Copy the function name of "fp" to buffer "buf". 17867 * "buf" must be able to hold the function name plus three bytes. 17868 * Takes care of script-local function names. 17869 */ 17870 static void 17871 cat_func_name(buf, fp) 17872 char_u *buf; 17873 ufunc_T *fp; 17874 { 17875 if (fp->uf_name[0] == K_SPECIAL) 17876 { 17877 STRCPY(buf, "<SNR>"); 17878 STRCAT(buf, fp->uf_name + 3); 17879 } 17880 else 17881 STRCPY(buf, fp->uf_name); 17882 } 17883 17884 /* 17885 * ":delfunction {name}" 17886 */ 17887 void 17888 ex_delfunction(eap) 17889 exarg_T *eap; 17890 { 17891 ufunc_T *fp = NULL; 17892 char_u *p; 17893 char_u *name; 17894 funcdict_T fudi; 17895 17896 p = eap->arg; 17897 name = trans_function_name(&p, eap->skip, 0, &fudi); 17898 vim_free(fudi.fd_newkey); 17899 if (name == NULL) 17900 { 17901 if (fudi.fd_dict != NULL && !eap->skip) 17902 EMSG(_(e_funcref)); 17903 return; 17904 } 17905 if (!ends_excmd(*skipwhite(p))) 17906 { 17907 vim_free(name); 17908 EMSG(_(e_trailing)); 17909 return; 17910 } 17911 eap->nextcmd = check_nextcmd(p); 17912 if (eap->nextcmd != NULL) 17913 *p = NUL; 17914 17915 if (!eap->skip) 17916 fp = find_func(name); 17917 vim_free(name); 17918 17919 if (!eap->skip) 17920 { 17921 if (fp == NULL) 17922 { 17923 EMSG2(_(e_nofunc), eap->arg); 17924 return; 17925 } 17926 if (fp->uf_calls > 0) 17927 { 17928 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 17929 return; 17930 } 17931 17932 if (fudi.fd_dict != NULL) 17933 { 17934 /* Delete the dict item that refers to the function, it will 17935 * invoke func_unref() and possibly delete the function. */ 17936 dictitem_remove(fudi.fd_dict, fudi.fd_di); 17937 } 17938 else 17939 func_free(fp); 17940 } 17941 } 17942 17943 /* 17944 * Free a function and remove it from the list of functions. 17945 */ 17946 static void 17947 func_free(fp) 17948 ufunc_T *fp; 17949 { 17950 hashitem_T *hi; 17951 17952 /* clear this function */ 17953 ga_clear_strings(&(fp->uf_args)); 17954 ga_clear_strings(&(fp->uf_lines)); 17955 #ifdef FEAT_PROFILE 17956 vim_free(fp->uf_tml_count); 17957 vim_free(fp->uf_tml_total); 17958 vim_free(fp->uf_tml_self); 17959 #endif 17960 17961 /* remove the function from the function hashtable */ 17962 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 17963 if (HASHITEM_EMPTY(hi)) 17964 EMSG2(_(e_intern2), "func_free()"); 17965 else 17966 hash_remove(&func_hashtab, hi); 17967 17968 vim_free(fp); 17969 } 17970 17971 /* 17972 * Unreference a Function: decrement the reference count and free it when it 17973 * becomes zero. Only for numbered functions. 17974 */ 17975 static void 17976 func_unref(name) 17977 char_u *name; 17978 { 17979 ufunc_T *fp; 17980 17981 if (name != NULL && isdigit(*name)) 17982 { 17983 fp = find_func(name); 17984 if (fp == NULL) 17985 EMSG2(_(e_intern2), "func_unref()"); 17986 else if (--fp->uf_refcount <= 0) 17987 { 17988 /* Only delete it when it's not being used. Otherwise it's done 17989 * when "uf_calls" becomes zero. */ 17990 if (fp->uf_calls == 0) 17991 func_free(fp); 17992 } 17993 } 17994 } 17995 17996 /* 17997 * Count a reference to a Function. 17998 */ 17999 static void 18000 func_ref(name) 18001 char_u *name; 18002 { 18003 ufunc_T *fp; 18004 18005 if (name != NULL && isdigit(*name)) 18006 { 18007 fp = find_func(name); 18008 if (fp == NULL) 18009 EMSG2(_(e_intern2), "func_ref()"); 18010 else 18011 ++fp->uf_refcount; 18012 } 18013 } 18014 18015 /* 18016 * Call a user function. 18017 */ 18018 static void 18019 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18020 ufunc_T *fp; /* pointer to function */ 18021 int argcount; /* nr of args */ 18022 typval_T *argvars; /* arguments */ 18023 typval_T *rettv; /* return value */ 18024 linenr_T firstline; /* first line of range */ 18025 linenr_T lastline; /* last line of range */ 18026 dict_T *selfdict; /* Dictionary for "self" */ 18027 { 18028 char_u *save_sourcing_name; 18029 linenr_T save_sourcing_lnum; 18030 scid_T save_current_SID; 18031 funccall_T fc; 18032 int save_did_emsg; 18033 static int depth = 0; 18034 dictitem_T *v; 18035 int fixvar_idx = 0; /* index in fixvar[] */ 18036 int i; 18037 int ai; 18038 char_u numbuf[NUMBUFLEN]; 18039 char_u *name; 18040 #ifdef FEAT_PROFILE 18041 proftime_T wait_start; 18042 #endif 18043 18044 /* If depth of calling is getting too high, don't execute the function */ 18045 if (depth >= p_mfd) 18046 { 18047 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18048 rettv->v_type = VAR_NUMBER; 18049 rettv->vval.v_number = -1; 18050 return; 18051 } 18052 ++depth; 18053 18054 line_breakcheck(); /* check for CTRL-C hit */ 18055 18056 fc.caller = current_funccal; 18057 current_funccal = &fc; 18058 fc.func = fp; 18059 fc.rettv = rettv; 18060 rettv->vval.v_number = 0; 18061 fc.linenr = 0; 18062 fc.returned = FALSE; 18063 fc.level = ex_nesting_level; 18064 /* Check if this function has a breakpoint. */ 18065 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18066 fc.dbg_tick = debug_tick; 18067 18068 /* 18069 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18070 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18071 * each argument variable and saves a lot of time. 18072 */ 18073 /* 18074 * Init l: variables. 18075 */ 18076 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18077 if (selfdict != NULL) 18078 { 18079 /* Set l:self to "selfdict". */ 18080 v = &fc.fixvar[fixvar_idx++].var; 18081 STRCPY(v->di_key, "self"); 18082 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18083 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18084 v->di_tv.v_type = VAR_DICT; 18085 v->di_tv.v_lock = 0; 18086 v->di_tv.vval.v_dict = selfdict; 18087 ++selfdict->dv_refcount; 18088 } 18089 18090 /* 18091 * Init a: variables. 18092 * Set a:0 to "argcount". 18093 * Set a:000 to a list with room for the "..." arguments. 18094 */ 18095 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18096 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18097 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18098 v = &fc.fixvar[fixvar_idx++].var; 18099 STRCPY(v->di_key, "000"); 18100 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18101 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18102 v->di_tv.v_type = VAR_LIST; 18103 v->di_tv.v_lock = VAR_FIXED; 18104 v->di_tv.vval.v_list = &fc.l_varlist; 18105 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18106 fc.l_varlist.lv_refcount = 99999; 18107 18108 /* 18109 * Set a:firstline to "firstline" and a:lastline to "lastline". 18110 * Set a:name to named arguments. 18111 * Set a:N to the "..." arguments. 18112 */ 18113 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18114 (varnumber_T)firstline); 18115 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18116 (varnumber_T)lastline); 18117 for (i = 0; i < argcount; ++i) 18118 { 18119 ai = i - fp->uf_args.ga_len; 18120 if (ai < 0) 18121 /* named argument a:name */ 18122 name = FUNCARG(fp, i); 18123 else 18124 { 18125 /* "..." argument a:1, a:2, etc. */ 18126 sprintf((char *)numbuf, "%d", ai + 1); 18127 name = numbuf; 18128 } 18129 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18130 { 18131 v = &fc.fixvar[fixvar_idx++].var; 18132 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18133 } 18134 else 18135 { 18136 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18137 + STRLEN(name))); 18138 if (v == NULL) 18139 break; 18140 v->di_flags = DI_FLAGS_RO; 18141 } 18142 STRCPY(v->di_key, name); 18143 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18144 18145 /* Note: the values are copied directly to avoid alloc/free. 18146 * "argvars" must have VAR_FIXED for v_lock. */ 18147 v->di_tv = argvars[i]; 18148 v->di_tv.v_lock = VAR_FIXED; 18149 18150 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18151 { 18152 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18153 fc.l_listitems[ai].li_tv = argvars[i]; 18154 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18155 } 18156 } 18157 18158 /* Don't redraw while executing the function. */ 18159 ++RedrawingDisabled; 18160 save_sourcing_name = sourcing_name; 18161 save_sourcing_lnum = sourcing_lnum; 18162 sourcing_lnum = 1; 18163 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18164 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18165 if (sourcing_name != NULL) 18166 { 18167 if (save_sourcing_name != NULL 18168 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18169 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18170 else 18171 STRCPY(sourcing_name, "function "); 18172 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18173 18174 if (p_verbose >= 12) 18175 { 18176 ++no_wait_return; 18177 verbose_enter_scroll(); 18178 18179 smsg((char_u *)_("calling %s"), sourcing_name); 18180 if (p_verbose >= 14) 18181 { 18182 char_u buf[MSG_BUF_LEN]; 18183 char_u numbuf[NUMBUFLEN]; 18184 char_u *tofree; 18185 18186 msg_puts((char_u *)"("); 18187 for (i = 0; i < argcount; ++i) 18188 { 18189 if (i > 0) 18190 msg_puts((char_u *)", "); 18191 if (argvars[i].v_type == VAR_NUMBER) 18192 msg_outnum((long)argvars[i].vval.v_number); 18193 else 18194 { 18195 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18196 buf, MSG_BUF_CLEN); 18197 msg_puts(buf); 18198 vim_free(tofree); 18199 } 18200 } 18201 msg_puts((char_u *)")"); 18202 } 18203 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18204 18205 verbose_leave_scroll(); 18206 --no_wait_return; 18207 } 18208 } 18209 #ifdef FEAT_PROFILE 18210 if (do_profiling) 18211 { 18212 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18213 func_do_profile(fp); 18214 if (fp->uf_profiling 18215 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18216 { 18217 ++fp->uf_tm_count; 18218 profile_start(&fp->uf_tm_start); 18219 profile_zero(&fp->uf_tm_children); 18220 } 18221 script_prof_save(&wait_start); 18222 } 18223 #endif 18224 18225 save_current_SID = current_SID; 18226 current_SID = fp->uf_script_ID; 18227 save_did_emsg = did_emsg; 18228 did_emsg = FALSE; 18229 18230 /* call do_cmdline() to execute the lines */ 18231 do_cmdline(NULL, get_func_line, (void *)&fc, 18232 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18233 18234 --RedrawingDisabled; 18235 18236 /* when the function was aborted because of an error, return -1 */ 18237 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18238 { 18239 clear_tv(rettv); 18240 rettv->v_type = VAR_NUMBER; 18241 rettv->vval.v_number = -1; 18242 } 18243 18244 #ifdef FEAT_PROFILE 18245 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18246 { 18247 profile_end(&fp->uf_tm_start); 18248 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18249 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18250 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18251 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18252 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18253 { 18254 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18255 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18256 } 18257 } 18258 #endif 18259 18260 /* when being verbose, mention the return value */ 18261 if (p_verbose >= 12) 18262 { 18263 ++no_wait_return; 18264 verbose_enter_scroll(); 18265 18266 if (aborting()) 18267 smsg((char_u *)_("%s aborted"), sourcing_name); 18268 else if (fc.rettv->v_type == VAR_NUMBER) 18269 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18270 (long)fc.rettv->vval.v_number); 18271 else 18272 { 18273 char_u buf[MSG_BUF_LEN]; 18274 char_u numbuf[NUMBUFLEN]; 18275 char_u *tofree; 18276 18277 /* The value may be very long. Skip the middle part, so that we 18278 * have some idea how it starts and ends. smsg() would always 18279 * truncate it at the end. */ 18280 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18281 buf, MSG_BUF_CLEN); 18282 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18283 vim_free(tofree); 18284 } 18285 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18286 18287 verbose_leave_scroll(); 18288 --no_wait_return; 18289 } 18290 18291 vim_free(sourcing_name); 18292 sourcing_name = save_sourcing_name; 18293 sourcing_lnum = save_sourcing_lnum; 18294 current_SID = save_current_SID; 18295 #ifdef FEAT_PROFILE 18296 if (do_profiling) 18297 script_prof_restore(&wait_start); 18298 #endif 18299 18300 if (p_verbose >= 12 && sourcing_name != NULL) 18301 { 18302 ++no_wait_return; 18303 verbose_enter_scroll(); 18304 18305 smsg((char_u *)_("continuing in %s"), sourcing_name); 18306 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18307 18308 verbose_leave_scroll(); 18309 --no_wait_return; 18310 } 18311 18312 did_emsg |= save_did_emsg; 18313 current_funccal = fc.caller; 18314 18315 /* The a: variables typevals were not alloced, only free the allocated 18316 * variables. */ 18317 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18318 18319 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18320 --depth; 18321 } 18322 18323 /* 18324 * Add a number variable "name" to dict "dp" with value "nr". 18325 */ 18326 static void 18327 add_nr_var(dp, v, name, nr) 18328 dict_T *dp; 18329 dictitem_T *v; 18330 char *name; 18331 varnumber_T nr; 18332 { 18333 STRCPY(v->di_key, name); 18334 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18335 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18336 v->di_tv.v_type = VAR_NUMBER; 18337 v->di_tv.v_lock = VAR_FIXED; 18338 v->di_tv.vval.v_number = nr; 18339 } 18340 18341 /* 18342 * ":return [expr]" 18343 */ 18344 void 18345 ex_return(eap) 18346 exarg_T *eap; 18347 { 18348 char_u *arg = eap->arg; 18349 typval_T rettv; 18350 int returning = FALSE; 18351 18352 if (current_funccal == NULL) 18353 { 18354 EMSG(_("E133: :return not inside a function")); 18355 return; 18356 } 18357 18358 if (eap->skip) 18359 ++emsg_skip; 18360 18361 eap->nextcmd = NULL; 18362 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18363 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18364 { 18365 if (!eap->skip) 18366 returning = do_return(eap, FALSE, TRUE, &rettv); 18367 else 18368 clear_tv(&rettv); 18369 } 18370 /* It's safer to return also on error. */ 18371 else if (!eap->skip) 18372 { 18373 /* 18374 * Return unless the expression evaluation has been cancelled due to an 18375 * aborting error, an interrupt, or an exception. 18376 */ 18377 if (!aborting()) 18378 returning = do_return(eap, FALSE, TRUE, NULL); 18379 } 18380 18381 /* When skipping or the return gets pending, advance to the next command 18382 * in this line (!returning). Otherwise, ignore the rest of the line. 18383 * Following lines will be ignored by get_func_line(). */ 18384 if (returning) 18385 eap->nextcmd = NULL; 18386 else if (eap->nextcmd == NULL) /* no argument */ 18387 eap->nextcmd = check_nextcmd(arg); 18388 18389 if (eap->skip) 18390 --emsg_skip; 18391 } 18392 18393 /* 18394 * Return from a function. Possibly makes the return pending. Also called 18395 * for a pending return at the ":endtry" or after returning from an extra 18396 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18397 * when called due to a ":return" command. "rettv" may point to a typval_T 18398 * with the return rettv. Returns TRUE when the return can be carried out, 18399 * FALSE when the return gets pending. 18400 */ 18401 int 18402 do_return(eap, reanimate, is_cmd, rettv) 18403 exarg_T *eap; 18404 int reanimate; 18405 int is_cmd; 18406 void *rettv; 18407 { 18408 int idx; 18409 struct condstack *cstack = eap->cstack; 18410 18411 if (reanimate) 18412 /* Undo the return. */ 18413 current_funccal->returned = FALSE; 18414 18415 /* 18416 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18417 * not in its finally clause (which then is to be executed next) is found. 18418 * In this case, make the ":return" pending for execution at the ":endtry". 18419 * Otherwise, return normally. 18420 */ 18421 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18422 if (idx >= 0) 18423 { 18424 cstack->cs_pending[idx] = CSTP_RETURN; 18425 18426 if (!is_cmd && !reanimate) 18427 /* A pending return again gets pending. "rettv" points to an 18428 * allocated variable with the rettv of the original ":return"'s 18429 * argument if present or is NULL else. */ 18430 cstack->cs_rettv[idx] = rettv; 18431 else 18432 { 18433 /* When undoing a return in order to make it pending, get the stored 18434 * return rettv. */ 18435 if (reanimate) 18436 rettv = current_funccal->rettv; 18437 18438 if (rettv != NULL) 18439 { 18440 /* Store the value of the pending return. */ 18441 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18442 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18443 else 18444 EMSG(_(e_outofmem)); 18445 } 18446 else 18447 cstack->cs_rettv[idx] = NULL; 18448 18449 if (reanimate) 18450 { 18451 /* The pending return value could be overwritten by a ":return" 18452 * without argument in a finally clause; reset the default 18453 * return value. */ 18454 current_funccal->rettv->v_type = VAR_NUMBER; 18455 current_funccal->rettv->vval.v_number = 0; 18456 } 18457 } 18458 report_make_pending(CSTP_RETURN, rettv); 18459 } 18460 else 18461 { 18462 current_funccal->returned = TRUE; 18463 18464 /* If the return is carried out now, store the return value. For 18465 * a return immediately after reanimation, the value is already 18466 * there. */ 18467 if (!reanimate && rettv != NULL) 18468 { 18469 clear_tv(current_funccal->rettv); 18470 *current_funccal->rettv = *(typval_T *)rettv; 18471 if (!is_cmd) 18472 vim_free(rettv); 18473 } 18474 } 18475 18476 return idx < 0; 18477 } 18478 18479 /* 18480 * Free the variable with a pending return value. 18481 */ 18482 void 18483 discard_pending_return(rettv) 18484 void *rettv; 18485 { 18486 free_tv((typval_T *)rettv); 18487 } 18488 18489 /* 18490 * Generate a return command for producing the value of "rettv". The result 18491 * is an allocated string. Used by report_pending() for verbose messages. 18492 */ 18493 char_u * 18494 get_return_cmd(rettv) 18495 void *rettv; 18496 { 18497 char_u *s = NULL; 18498 char_u *tofree = NULL; 18499 char_u numbuf[NUMBUFLEN]; 18500 18501 if (rettv != NULL) 18502 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18503 if (s == NULL) 18504 s = (char_u *)""; 18505 18506 STRCPY(IObuff, ":return "); 18507 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18508 if (STRLEN(s) + 8 >= IOSIZE) 18509 STRCPY(IObuff + IOSIZE - 4, "..."); 18510 vim_free(tofree); 18511 return vim_strsave(IObuff); 18512 } 18513 18514 /* 18515 * Get next function line. 18516 * Called by do_cmdline() to get the next line. 18517 * Returns allocated string, or NULL for end of function. 18518 */ 18519 /* ARGSUSED */ 18520 char_u * 18521 get_func_line(c, cookie, indent) 18522 int c; /* not used */ 18523 void *cookie; 18524 int indent; /* not used */ 18525 { 18526 funccall_T *fcp = (funccall_T *)cookie; 18527 ufunc_T *fp = fcp->func; 18528 char_u *retval; 18529 garray_T *gap; /* growarray with function lines */ 18530 18531 /* If breakpoints have been added/deleted need to check for it. */ 18532 if (fcp->dbg_tick != debug_tick) 18533 { 18534 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18535 sourcing_lnum); 18536 fcp->dbg_tick = debug_tick; 18537 } 18538 #ifdef FEAT_PROFILE 18539 if (do_profiling) 18540 func_line_end(cookie); 18541 #endif 18542 18543 gap = &fp->uf_lines; 18544 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18545 retval = NULL; 18546 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18547 retval = NULL; 18548 else 18549 { 18550 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18551 sourcing_lnum = fcp->linenr; 18552 #ifdef FEAT_PROFILE 18553 if (do_profiling) 18554 func_line_start(cookie); 18555 #endif 18556 } 18557 18558 /* Did we encounter a breakpoint? */ 18559 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18560 { 18561 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18562 /* Find next breakpoint. */ 18563 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18564 sourcing_lnum); 18565 fcp->dbg_tick = debug_tick; 18566 } 18567 18568 return retval; 18569 } 18570 18571 #if defined(FEAT_PROFILE) || defined(PROTO) 18572 /* 18573 * Called when starting to read a function line. 18574 * "sourcing_lnum" must be correct! 18575 * When skipping lines it may not actually be executed, but we won't find out 18576 * until later and we need to store the time now. 18577 */ 18578 void 18579 func_line_start(cookie) 18580 void *cookie; 18581 { 18582 funccall_T *fcp = (funccall_T *)cookie; 18583 ufunc_T *fp = fcp->func; 18584 18585 if (fp->uf_profiling && sourcing_lnum >= 1 18586 && sourcing_lnum <= fp->uf_lines.ga_len) 18587 { 18588 fp->uf_tml_idx = sourcing_lnum - 1; 18589 fp->uf_tml_execed = FALSE; 18590 profile_start(&fp->uf_tml_start); 18591 profile_zero(&fp->uf_tml_children); 18592 profile_get_wait(&fp->uf_tml_wait); 18593 } 18594 } 18595 18596 /* 18597 * Called when actually executing a function line. 18598 */ 18599 void 18600 func_line_exec(cookie) 18601 void *cookie; 18602 { 18603 funccall_T *fcp = (funccall_T *)cookie; 18604 ufunc_T *fp = fcp->func; 18605 18606 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18607 fp->uf_tml_execed = TRUE; 18608 } 18609 18610 /* 18611 * Called when done with a function line. 18612 */ 18613 void 18614 func_line_end(cookie) 18615 void *cookie; 18616 { 18617 funccall_T *fcp = (funccall_T *)cookie; 18618 ufunc_T *fp = fcp->func; 18619 18620 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18621 { 18622 if (fp->uf_tml_execed) 18623 { 18624 ++fp->uf_tml_count[fp->uf_tml_idx]; 18625 profile_end(&fp->uf_tml_start); 18626 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18627 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18628 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18629 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18630 } 18631 fp->uf_tml_idx = -1; 18632 } 18633 } 18634 #endif 18635 18636 /* 18637 * Return TRUE if the currently active function should be ended, because a 18638 * return was encountered or an error occured. Used inside a ":while". 18639 */ 18640 int 18641 func_has_ended(cookie) 18642 void *cookie; 18643 { 18644 funccall_T *fcp = (funccall_T *)cookie; 18645 18646 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18647 * an error inside a try conditional. */ 18648 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18649 || fcp->returned); 18650 } 18651 18652 /* 18653 * return TRUE if cookie indicates a function which "abort"s on errors. 18654 */ 18655 int 18656 func_has_abort(cookie) 18657 void *cookie; 18658 { 18659 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18660 } 18661 18662 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18663 typedef enum 18664 { 18665 VAR_FLAVOUR_DEFAULT, 18666 VAR_FLAVOUR_SESSION, 18667 VAR_FLAVOUR_VIMINFO 18668 } var_flavour_T; 18669 18670 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18671 18672 static var_flavour_T 18673 var_flavour(varname) 18674 char_u *varname; 18675 { 18676 char_u *p = varname; 18677 18678 if (ASCII_ISUPPER(*p)) 18679 { 18680 while (*(++p)) 18681 if (ASCII_ISLOWER(*p)) 18682 return VAR_FLAVOUR_SESSION; 18683 return VAR_FLAVOUR_VIMINFO; 18684 } 18685 else 18686 return VAR_FLAVOUR_DEFAULT; 18687 } 18688 #endif 18689 18690 #if defined(FEAT_VIMINFO) || defined(PROTO) 18691 /* 18692 * Restore global vars that start with a capital from the viminfo file 18693 */ 18694 int 18695 read_viminfo_varlist(virp, writing) 18696 vir_T *virp; 18697 int writing; 18698 { 18699 char_u *tab; 18700 int is_string = FALSE; 18701 typval_T tv; 18702 18703 if (!writing && (find_viminfo_parameter('!') != NULL)) 18704 { 18705 tab = vim_strchr(virp->vir_line + 1, '\t'); 18706 if (tab != NULL) 18707 { 18708 *tab++ = '\0'; /* isolate the variable name */ 18709 if (*tab == 'S') /* string var */ 18710 is_string = TRUE; 18711 18712 tab = vim_strchr(tab, '\t'); 18713 if (tab != NULL) 18714 { 18715 if (is_string) 18716 { 18717 tv.v_type = VAR_STRING; 18718 tv.vval.v_string = viminfo_readstring(virp, 18719 (int)(tab - virp->vir_line + 1), TRUE); 18720 } 18721 else 18722 { 18723 tv.v_type = VAR_NUMBER; 18724 tv.vval.v_number = atol((char *)tab + 1); 18725 } 18726 set_var(virp->vir_line + 1, &tv, FALSE); 18727 if (is_string) 18728 vim_free(tv.vval.v_string); 18729 } 18730 } 18731 } 18732 18733 return viminfo_readline(virp); 18734 } 18735 18736 /* 18737 * Write global vars that start with a capital to the viminfo file 18738 */ 18739 void 18740 write_viminfo_varlist(fp) 18741 FILE *fp; 18742 { 18743 hashitem_T *hi; 18744 dictitem_T *this_var; 18745 int todo; 18746 char *s; 18747 char_u *p; 18748 char_u *tofree; 18749 char_u numbuf[NUMBUFLEN]; 18750 18751 if (find_viminfo_parameter('!') == NULL) 18752 return; 18753 18754 fprintf(fp, _("\n# global variables:\n")); 18755 18756 todo = globvarht.ht_used; 18757 for (hi = globvarht.ht_array; todo > 0; ++hi) 18758 { 18759 if (!HASHITEM_EMPTY(hi)) 18760 { 18761 --todo; 18762 this_var = HI2DI(hi); 18763 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 18764 { 18765 switch (this_var->di_tv.v_type) 18766 { 18767 case VAR_STRING: s = "STR"; break; 18768 case VAR_NUMBER: s = "NUM"; break; 18769 default: continue; 18770 } 18771 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 18772 p = echo_string(&this_var->di_tv, &tofree, numbuf); 18773 if (p != NULL) 18774 viminfo_writestring(fp, p); 18775 vim_free(tofree); 18776 } 18777 } 18778 } 18779 } 18780 #endif 18781 18782 #if defined(FEAT_SESSION) || defined(PROTO) 18783 int 18784 store_session_globals(fd) 18785 FILE *fd; 18786 { 18787 hashitem_T *hi; 18788 dictitem_T *this_var; 18789 int todo; 18790 char_u *p, *t; 18791 18792 todo = globvarht.ht_used; 18793 for (hi = globvarht.ht_array; todo > 0; ++hi) 18794 { 18795 if (!HASHITEM_EMPTY(hi)) 18796 { 18797 --todo; 18798 this_var = HI2DI(hi); 18799 if ((this_var->di_tv.v_type == VAR_NUMBER 18800 || this_var->di_tv.v_type == VAR_STRING) 18801 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 18802 { 18803 /* Escape special characters with a backslash. Turn a LF and 18804 * CR into \n and \r. */ 18805 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 18806 (char_u *)"\\\"\n\r"); 18807 if (p == NULL) /* out of memory */ 18808 break; 18809 for (t = p; *t != NUL; ++t) 18810 if (*t == '\n') 18811 *t = 'n'; 18812 else if (*t == '\r') 18813 *t = 'r'; 18814 if ((fprintf(fd, "let %s = %c%s%c", 18815 this_var->di_key, 18816 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18817 : ' ', 18818 p, 18819 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18820 : ' ') < 0) 18821 || put_eol(fd) == FAIL) 18822 { 18823 vim_free(p); 18824 return FAIL; 18825 } 18826 vim_free(p); 18827 } 18828 } 18829 } 18830 return OK; 18831 } 18832 #endif 18833 18834 /* 18835 * Display script name where an item was last set. 18836 * Should only be invoked when 'verbose' is non-zero. 18837 */ 18838 void 18839 last_set_msg(scriptID) 18840 scid_T scriptID; 18841 { 18842 if (scriptID != 0) 18843 { 18844 verbose_enter(); 18845 MSG_PUTS(_("\n\tLast set from ")); 18846 MSG_PUTS(get_scriptname(scriptID)); 18847 verbose_leave(); 18848 } 18849 } 18850 18851 #endif /* FEAT_EVAL */ 18852 18853 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 18854 18855 18856 #ifdef WIN3264 18857 /* 18858 * Functions for ":8" filename modifier: get 8.3 version of a filename. 18859 */ 18860 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18861 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 18862 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18863 18864 /* 18865 * Get the short pathname of a file. 18866 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 18867 */ 18868 static int 18869 get_short_pathname(fnamep, bufp, fnamelen) 18870 char_u **fnamep; 18871 char_u **bufp; 18872 int *fnamelen; 18873 { 18874 int l,len; 18875 char_u *newbuf; 18876 18877 len = *fnamelen; 18878 18879 l = GetShortPathName(*fnamep, *fnamep, len); 18880 if (l > len - 1) 18881 { 18882 /* If that doesn't work (not enough space), then save the string 18883 * and try again with a new buffer big enough 18884 */ 18885 newbuf = vim_strnsave(*fnamep, l); 18886 if (newbuf == NULL) 18887 return 0; 18888 18889 vim_free(*bufp); 18890 *fnamep = *bufp = newbuf; 18891 18892 l = GetShortPathName(*fnamep,*fnamep,l+1); 18893 18894 /* Really should always succeed, as the buffer is big enough */ 18895 } 18896 18897 *fnamelen = l; 18898 return 1; 18899 } 18900 18901 /* 18902 * Create a short path name. Returns the length of the buffer it needs. 18903 * Doesn't copy over the end of the buffer passed in. 18904 */ 18905 static int 18906 shortpath_for_invalid_fname(fname, bufp, fnamelen) 18907 char_u **fname; 18908 char_u **bufp; 18909 int *fnamelen; 18910 { 18911 char_u *s, *p, *pbuf2, *pbuf3; 18912 char_u ch; 18913 int len, len2, plen, slen; 18914 18915 /* Make a copy */ 18916 len2 = *fnamelen; 18917 pbuf2 = vim_strnsave(*fname, len2); 18918 pbuf3 = NULL; 18919 18920 s = pbuf2 + len2 - 1; /* Find the end */ 18921 slen = 1; 18922 plen = len2; 18923 18924 if (after_pathsep(pbuf2, s + 1)) 18925 { 18926 --s; 18927 ++slen; 18928 --plen; 18929 } 18930 18931 do 18932 { 18933 /* Go back one path-seperator */ 18934 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 18935 { 18936 --s; 18937 ++slen; 18938 --plen; 18939 } 18940 if (s <= pbuf2) 18941 break; 18942 18943 /* Remeber the character that is about to be blatted */ 18944 ch = *s; 18945 *s = 0; /* get_short_pathname requires a null-terminated string */ 18946 18947 /* Try it in situ */ 18948 p = pbuf2; 18949 if (!get_short_pathname(&p, &pbuf3, &plen)) 18950 { 18951 vim_free(pbuf2); 18952 return -1; 18953 } 18954 *s = ch; /* Preserve the string */ 18955 } while (plen == 0); 18956 18957 if (plen > 0) 18958 { 18959 /* Remeber the length of the new string. */ 18960 *fnamelen = len = plen + slen; 18961 vim_free(*bufp); 18962 if (len > len2) 18963 { 18964 /* If there's not enough space in the currently allocated string, 18965 * then copy it to a buffer big enough. 18966 */ 18967 *fname= *bufp = vim_strnsave(p, len); 18968 if (*fname == NULL) 18969 return -1; 18970 } 18971 else 18972 { 18973 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 18974 *fname = *bufp = pbuf2; 18975 if (p != pbuf2) 18976 strncpy(*fname, p, plen); 18977 pbuf2 = NULL; 18978 } 18979 /* Concat the next bit */ 18980 strncpy(*fname + plen, s, slen); 18981 (*fname)[len] = '\0'; 18982 } 18983 vim_free(pbuf3); 18984 vim_free(pbuf2); 18985 return 0; 18986 } 18987 18988 /* 18989 * Get a pathname for a partial path. 18990 */ 18991 static int 18992 shortpath_for_partial(fnamep, bufp, fnamelen) 18993 char_u **fnamep; 18994 char_u **bufp; 18995 int *fnamelen; 18996 { 18997 int sepcount, len, tflen; 18998 char_u *p; 18999 char_u *pbuf, *tfname; 19000 int hasTilde; 19001 19002 /* Count up the path seperators from the RHS.. so we know which part 19003 * of the path to return. 19004 */ 19005 sepcount = 0; 19006 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19007 if (vim_ispathsep(*p)) 19008 ++sepcount; 19009 19010 /* Need full path first (use expand_env() to remove a "~/") */ 19011 hasTilde = (**fnamep == '~'); 19012 if (hasTilde) 19013 pbuf = tfname = expand_env_save(*fnamep); 19014 else 19015 pbuf = tfname = FullName_save(*fnamep, FALSE); 19016 19017 len = tflen = STRLEN(tfname); 19018 19019 if (!get_short_pathname(&tfname, &pbuf, &len)) 19020 return -1; 19021 19022 if (len == 0) 19023 { 19024 /* Don't have a valid filename, so shorten the rest of the 19025 * path if we can. This CAN give us invalid 8.3 filenames, but 19026 * there's not a lot of point in guessing what it might be. 19027 */ 19028 len = tflen; 19029 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19030 return -1; 19031 } 19032 19033 /* Count the paths backward to find the beginning of the desired string. */ 19034 for (p = tfname + len - 1; p >= tfname; --p) 19035 { 19036 #ifdef FEAT_MBYTE 19037 if (has_mbyte) 19038 p -= mb_head_off(tfname, p); 19039 #endif 19040 if (vim_ispathsep(*p)) 19041 { 19042 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19043 break; 19044 else 19045 sepcount --; 19046 } 19047 } 19048 if (hasTilde) 19049 { 19050 --p; 19051 if (p >= tfname) 19052 *p = '~'; 19053 else 19054 return -1; 19055 } 19056 else 19057 ++p; 19058 19059 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19060 vim_free(*bufp); 19061 *fnamelen = (int)STRLEN(p); 19062 *bufp = pbuf; 19063 *fnamep = p; 19064 19065 return 0; 19066 } 19067 #endif /* WIN3264 */ 19068 19069 /* 19070 * Adjust a filename, according to a string of modifiers. 19071 * *fnamep must be NUL terminated when called. When returning, the length is 19072 * determined by *fnamelen. 19073 * Returns valid flags. 19074 * When there is an error, *fnamep is set to NULL. 19075 */ 19076 int 19077 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19078 char_u *src; /* string with modifiers */ 19079 int *usedlen; /* characters after src that are used */ 19080 char_u **fnamep; /* file name so far */ 19081 char_u **bufp; /* buffer for allocated file name or NULL */ 19082 int *fnamelen; /* length of fnamep */ 19083 { 19084 int valid = 0; 19085 char_u *tail; 19086 char_u *s, *p, *pbuf; 19087 char_u dirname[MAXPATHL]; 19088 int c; 19089 int has_fullname = 0; 19090 #ifdef WIN3264 19091 int has_shortname = 0; 19092 #endif 19093 19094 repeat: 19095 /* ":p" - full path/file_name */ 19096 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19097 { 19098 has_fullname = 1; 19099 19100 valid |= VALID_PATH; 19101 *usedlen += 2; 19102 19103 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19104 if ((*fnamep)[0] == '~' 19105 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19106 && ((*fnamep)[1] == '/' 19107 # ifdef BACKSLASH_IN_FILENAME 19108 || (*fnamep)[1] == '\\' 19109 # endif 19110 || (*fnamep)[1] == NUL) 19111 19112 #endif 19113 ) 19114 { 19115 *fnamep = expand_env_save(*fnamep); 19116 vim_free(*bufp); /* free any allocated file name */ 19117 *bufp = *fnamep; 19118 if (*fnamep == NULL) 19119 return -1; 19120 } 19121 19122 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19123 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19124 { 19125 if (vim_ispathsep(*p) 19126 && p[1] == '.' 19127 && (p[2] == NUL 19128 || vim_ispathsep(p[2]) 19129 || (p[2] == '.' 19130 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19131 break; 19132 } 19133 19134 /* FullName_save() is slow, don't use it when not needed. */ 19135 if (*p != NUL || !vim_isAbsName(*fnamep)) 19136 { 19137 *fnamep = FullName_save(*fnamep, *p != NUL); 19138 vim_free(*bufp); /* free any allocated file name */ 19139 *bufp = *fnamep; 19140 if (*fnamep == NULL) 19141 return -1; 19142 } 19143 19144 /* Append a path separator to a directory. */ 19145 if (mch_isdir(*fnamep)) 19146 { 19147 /* Make room for one or two extra characters. */ 19148 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19149 vim_free(*bufp); /* free any allocated file name */ 19150 *bufp = *fnamep; 19151 if (*fnamep == NULL) 19152 return -1; 19153 add_pathsep(*fnamep); 19154 } 19155 } 19156 19157 /* ":." - path relative to the current directory */ 19158 /* ":~" - path relative to the home directory */ 19159 /* ":8" - shortname path - postponed till after */ 19160 while (src[*usedlen] == ':' 19161 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19162 { 19163 *usedlen += 2; 19164 if (c == '8') 19165 { 19166 #ifdef WIN3264 19167 has_shortname = 1; /* Postpone this. */ 19168 #endif 19169 continue; 19170 } 19171 pbuf = NULL; 19172 /* Need full path first (use expand_env() to remove a "~/") */ 19173 if (!has_fullname) 19174 { 19175 if (c == '.' && **fnamep == '~') 19176 p = pbuf = expand_env_save(*fnamep); 19177 else 19178 p = pbuf = FullName_save(*fnamep, FALSE); 19179 } 19180 else 19181 p = *fnamep; 19182 19183 has_fullname = 0; 19184 19185 if (p != NULL) 19186 { 19187 if (c == '.') 19188 { 19189 mch_dirname(dirname, MAXPATHL); 19190 s = shorten_fname(p, dirname); 19191 if (s != NULL) 19192 { 19193 *fnamep = s; 19194 if (pbuf != NULL) 19195 { 19196 vim_free(*bufp); /* free any allocated file name */ 19197 *bufp = pbuf; 19198 pbuf = NULL; 19199 } 19200 } 19201 } 19202 else 19203 { 19204 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19205 /* Only replace it when it starts with '~' */ 19206 if (*dirname == '~') 19207 { 19208 s = vim_strsave(dirname); 19209 if (s != NULL) 19210 { 19211 *fnamep = s; 19212 vim_free(*bufp); 19213 *bufp = s; 19214 } 19215 } 19216 } 19217 vim_free(pbuf); 19218 } 19219 } 19220 19221 tail = gettail(*fnamep); 19222 *fnamelen = (int)STRLEN(*fnamep); 19223 19224 /* ":h" - head, remove "/file_name", can be repeated */ 19225 /* Don't remove the first "/" or "c:\" */ 19226 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19227 { 19228 valid |= VALID_HEAD; 19229 *usedlen += 2; 19230 s = get_past_head(*fnamep); 19231 while (tail > s && after_pathsep(s, tail)) 19232 --tail; 19233 *fnamelen = (int)(tail - *fnamep); 19234 #ifdef VMS 19235 if (*fnamelen > 0) 19236 *fnamelen += 1; /* the path separator is part of the path */ 19237 #endif 19238 while (tail > s && !after_pathsep(s, tail)) 19239 mb_ptr_back(*fnamep, tail); 19240 } 19241 19242 /* ":8" - shortname */ 19243 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19244 { 19245 *usedlen += 2; 19246 #ifdef WIN3264 19247 has_shortname = 1; 19248 #endif 19249 } 19250 19251 #ifdef WIN3264 19252 /* Check shortname after we have done 'heads' and before we do 'tails' 19253 */ 19254 if (has_shortname) 19255 { 19256 pbuf = NULL; 19257 /* Copy the string if it is shortened by :h */ 19258 if (*fnamelen < (int)STRLEN(*fnamep)) 19259 { 19260 p = vim_strnsave(*fnamep, *fnamelen); 19261 if (p == 0) 19262 return -1; 19263 vim_free(*bufp); 19264 *bufp = *fnamep = p; 19265 } 19266 19267 /* Split into two implementations - makes it easier. First is where 19268 * there isn't a full name already, second is where there is. 19269 */ 19270 if (!has_fullname && !vim_isAbsName(*fnamep)) 19271 { 19272 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19273 return -1; 19274 } 19275 else 19276 { 19277 int l; 19278 19279 /* Simple case, already have the full-name 19280 * Nearly always shorter, so try first time. */ 19281 l = *fnamelen; 19282 if (!get_short_pathname(fnamep, bufp, &l)) 19283 return -1; 19284 19285 if (l == 0) 19286 { 19287 /* Couldn't find the filename.. search the paths. 19288 */ 19289 l = *fnamelen; 19290 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19291 return -1; 19292 } 19293 *fnamelen = l; 19294 } 19295 } 19296 #endif /* WIN3264 */ 19297 19298 /* ":t" - tail, just the basename */ 19299 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19300 { 19301 *usedlen += 2; 19302 *fnamelen -= (int)(tail - *fnamep); 19303 *fnamep = tail; 19304 } 19305 19306 /* ":e" - extension, can be repeated */ 19307 /* ":r" - root, without extension, can be repeated */ 19308 while (src[*usedlen] == ':' 19309 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19310 { 19311 /* find a '.' in the tail: 19312 * - for second :e: before the current fname 19313 * - otherwise: The last '.' 19314 */ 19315 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19316 s = *fnamep - 2; 19317 else 19318 s = *fnamep + *fnamelen - 1; 19319 for ( ; s > tail; --s) 19320 if (s[0] == '.') 19321 break; 19322 if (src[*usedlen + 1] == 'e') /* :e */ 19323 { 19324 if (s > tail) 19325 { 19326 *fnamelen += (int)(*fnamep - (s + 1)); 19327 *fnamep = s + 1; 19328 #ifdef VMS 19329 /* cut version from the extension */ 19330 s = *fnamep + *fnamelen - 1; 19331 for ( ; s > *fnamep; --s) 19332 if (s[0] == ';') 19333 break; 19334 if (s > *fnamep) 19335 *fnamelen = s - *fnamep; 19336 #endif 19337 } 19338 else if (*fnamep <= tail) 19339 *fnamelen = 0; 19340 } 19341 else /* :r */ 19342 { 19343 if (s > tail) /* remove one extension */ 19344 *fnamelen = (int)(s - *fnamep); 19345 } 19346 *usedlen += 2; 19347 } 19348 19349 /* ":s?pat?foo?" - substitute */ 19350 /* ":gs?pat?foo?" - global substitute */ 19351 if (src[*usedlen] == ':' 19352 && (src[*usedlen + 1] == 's' 19353 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19354 { 19355 char_u *str; 19356 char_u *pat; 19357 char_u *sub; 19358 int sep; 19359 char_u *flags; 19360 int didit = FALSE; 19361 19362 flags = (char_u *)""; 19363 s = src + *usedlen + 2; 19364 if (src[*usedlen + 1] == 'g') 19365 { 19366 flags = (char_u *)"g"; 19367 ++s; 19368 } 19369 19370 sep = *s++; 19371 if (sep) 19372 { 19373 /* find end of pattern */ 19374 p = vim_strchr(s, sep); 19375 if (p != NULL) 19376 { 19377 pat = vim_strnsave(s, (int)(p - s)); 19378 if (pat != NULL) 19379 { 19380 s = p + 1; 19381 /* find end of substitution */ 19382 p = vim_strchr(s, sep); 19383 if (p != NULL) 19384 { 19385 sub = vim_strnsave(s, (int)(p - s)); 19386 str = vim_strnsave(*fnamep, *fnamelen); 19387 if (sub != NULL && str != NULL) 19388 { 19389 *usedlen = (int)(p + 1 - src); 19390 s = do_string_sub(str, pat, sub, flags); 19391 if (s != NULL) 19392 { 19393 *fnamep = s; 19394 *fnamelen = (int)STRLEN(s); 19395 vim_free(*bufp); 19396 *bufp = s; 19397 didit = TRUE; 19398 } 19399 } 19400 vim_free(sub); 19401 vim_free(str); 19402 } 19403 vim_free(pat); 19404 } 19405 } 19406 /* after using ":s", repeat all the modifiers */ 19407 if (didit) 19408 goto repeat; 19409 } 19410 } 19411 19412 return valid; 19413 } 19414 19415 /* 19416 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19417 * "flags" can be "g" to do a global substitute. 19418 * Returns an allocated string, NULL for error. 19419 */ 19420 char_u * 19421 do_string_sub(str, pat, sub, flags) 19422 char_u *str; 19423 char_u *pat; 19424 char_u *sub; 19425 char_u *flags; 19426 { 19427 int sublen; 19428 regmatch_T regmatch; 19429 int i; 19430 int do_all; 19431 char_u *tail; 19432 garray_T ga; 19433 char_u *ret; 19434 char_u *save_cpo; 19435 19436 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19437 save_cpo = p_cpo; 19438 p_cpo = (char_u *)""; 19439 19440 ga_init2(&ga, 1, 200); 19441 19442 do_all = (flags[0] == 'g'); 19443 19444 regmatch.rm_ic = p_ic; 19445 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19446 if (regmatch.regprog != NULL) 19447 { 19448 tail = str; 19449 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19450 { 19451 /* 19452 * Get some space for a temporary buffer to do the substitution 19453 * into. It will contain: 19454 * - The text up to where the match is. 19455 * - The substituted text. 19456 * - The text after the match. 19457 */ 19458 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19459 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19460 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19461 { 19462 ga_clear(&ga); 19463 break; 19464 } 19465 19466 /* copy the text up to where the match is */ 19467 i = (int)(regmatch.startp[0] - tail); 19468 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19469 /* add the substituted text */ 19470 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19471 + ga.ga_len + i, TRUE, TRUE, FALSE); 19472 ga.ga_len += i + sublen - 1; 19473 /* avoid getting stuck on a match with an empty string */ 19474 if (tail == regmatch.endp[0]) 19475 { 19476 if (*tail == NUL) 19477 break; 19478 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19479 ++ga.ga_len; 19480 } 19481 else 19482 { 19483 tail = regmatch.endp[0]; 19484 if (*tail == NUL) 19485 break; 19486 } 19487 if (!do_all) 19488 break; 19489 } 19490 19491 if (ga.ga_data != NULL) 19492 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19493 19494 vim_free(regmatch.regprog); 19495 } 19496 19497 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19498 ga_clear(&ga); 19499 p_cpo = save_cpo; 19500 19501 return ret; 19502 } 19503 19504 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19505