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 {VV_NAME("scrollstart", VAR_STRING), 0}, 341 {VV_NAME("swapname", VAR_STRING), VV_RO}, 342 {VV_NAME("swapchoice", VAR_STRING), 0}, 343 }; 344 345 /* shorthand */ 346 #define vv_type vv_di.di_tv.v_type 347 #define vv_nr vv_di.di_tv.vval.v_number 348 #define vv_str vv_di.di_tv.vval.v_string 349 #define vv_tv vv_di.di_tv 350 351 /* 352 * The v: variables are stored in dictionary "vimvardict". 353 * "vimvars_var" is the variable that is used for the "l:" scope. 354 */ 355 static dict_T vimvardict; 356 static dictitem_T vimvars_var; 357 #define vimvarht vimvardict.dv_hashtab 358 359 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 360 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 361 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 362 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 363 #endif 364 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 365 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 366 static char_u *skip_var_one __ARGS((char_u *arg)); 367 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 368 static void list_glob_vars __ARGS((void)); 369 static void list_buf_vars __ARGS((void)); 370 static void list_win_vars __ARGS((void)); 371 static void list_vim_vars __ARGS((void)); 372 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 373 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 374 static int check_changedtick __ARGS((char_u *arg)); 375 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 376 static void clear_lval __ARGS((lval_T *lp)); 377 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 378 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 379 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 380 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 381 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 382 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 383 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 384 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 385 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 386 static int tv_islocked __ARGS((typval_T *tv)); 387 388 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 389 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 390 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 391 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 392 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 393 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 394 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 395 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 396 397 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 398 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 399 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 400 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 401 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 402 static list_T *list_alloc __ARGS((void)); 403 static void list_free __ARGS((list_T *l)); 404 static listitem_T *listitem_alloc __ARGS((void)); 405 static void listitem_free __ARGS((listitem_T *item)); 406 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 407 static long list_len __ARGS((list_T *l)); 408 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 409 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 410 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 411 static listitem_T *list_find __ARGS((list_T *l, long n)); 412 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 413 static void list_append __ARGS((list_T *l, listitem_T *item)); 414 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 415 static int list_append_string __ARGS((list_T *l, char_u *str, int len)); 416 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 417 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 418 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 419 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 420 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 421 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 422 static char_u *list2string __ARGS((typval_T *tv)); 423 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); 424 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 425 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 426 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 427 static void dict_unref __ARGS((dict_T *d)); 428 static void dict_free __ARGS((dict_T *d)); 429 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 430 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 431 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 432 static void dictitem_free __ARGS((dictitem_T *item)); 433 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 434 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 435 static long dict_len __ARGS((dict_T *d)); 436 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 437 static char_u *dict2string __ARGS((typval_T *tv)); 438 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 439 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 440 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 441 static char_u *string_quote __ARGS((char_u *str, int function)); 442 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 443 static int find_internal_func __ARGS((char_u *name)); 444 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 445 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)); 446 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)); 447 static void emsg_funcname __ARGS((char *msg, char_u *name)); 448 449 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 450 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 468 #if defined(FEAT_INS_EXPAND) 469 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 471 #endif 472 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 477 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 569 #ifdef vim_mkdir 570 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 571 #endif 572 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 606 #ifdef HAVE_STRFTIME 607 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 608 #endif 609 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 636 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 637 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 640 641 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 642 static int get_env_len __ARGS((char_u **arg)); 643 static int get_id_len __ARGS((char_u **arg)); 644 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 645 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 646 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 647 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 648 valid character */ 649 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 650 static int eval_isnamec __ARGS((int c)); 651 static int eval_isnamec1 __ARGS((int c)); 652 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 653 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 654 static typval_T *alloc_tv __ARGS((void)); 655 static typval_T *alloc_string_tv __ARGS((char_u *string)); 656 static void free_tv __ARGS((typval_T *varp)); 657 static void init_tv __ARGS((typval_T *varp)); 658 static long get_tv_number __ARGS((typval_T *varp)); 659 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 660 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 661 static char_u *get_tv_string __ARGS((typval_T *varp)); 662 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 663 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 664 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 665 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 666 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 667 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 668 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 669 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 670 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 671 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 672 static int var_check_ro __ARGS((int flags, char_u *name)); 673 static int tv_check_lock __ARGS((int lock, char_u *name)); 674 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 675 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 676 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 677 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 678 static int eval_fname_script __ARGS((char_u *p)); 679 static int eval_fname_sid __ARGS((char_u *p)); 680 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 681 static ufunc_T *find_func __ARGS((char_u *name)); 682 static int function_exists __ARGS((char_u *name)); 683 static int builtin_function __ARGS((char_u *name)); 684 #ifdef FEAT_PROFILE 685 static void func_do_profile __ARGS((ufunc_T *fp)); 686 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 687 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 688 static int 689 # ifdef __BORLANDC__ 690 _RTLENTRYF 691 # endif 692 prof_total_cmp __ARGS((const void *s1, const void *s2)); 693 static int 694 # ifdef __BORLANDC__ 695 _RTLENTRYF 696 # endif 697 prof_self_cmp __ARGS((const void *s1, const void *s2)); 698 #endif 699 static int script_autoload __ARGS((char_u *name, int reload)); 700 static char_u *autoload_name __ARGS((char_u *name)); 701 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 702 static void func_free __ARGS((ufunc_T *fp)); 703 static void func_unref __ARGS((char_u *name)); 704 static void func_ref __ARGS((char_u *name)); 705 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)); 706 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 707 708 /* Character used as separated in autoload function/variable names. */ 709 #define AUTOLOAD_CHAR '#' 710 711 /* 712 * Initialize the global and v: variables. 713 */ 714 void 715 eval_init() 716 { 717 int i; 718 struct vimvar *p; 719 720 init_var_dict(&globvardict, &globvars_var); 721 init_var_dict(&vimvardict, &vimvars_var); 722 hash_init(&compat_hashtab); 723 hash_init(&func_hashtab); 724 725 for (i = 0; i < VV_LEN; ++i) 726 { 727 p = &vimvars[i]; 728 STRCPY(p->vv_di.di_key, p->vv_name); 729 if (p->vv_flags & VV_RO) 730 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 731 else if (p->vv_flags & VV_RO_SBX) 732 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 733 else 734 p->vv_di.di_flags = DI_FLAGS_FIX; 735 736 /* add to v: scope dict, unless the value is not always available */ 737 if (p->vv_type != VAR_UNKNOWN) 738 hash_add(&vimvarht, p->vv_di.di_key); 739 if (p->vv_flags & VV_COMPAT) 740 /* add to compat scope dict */ 741 hash_add(&compat_hashtab, p->vv_di.di_key); 742 } 743 } 744 745 #if defined(EXITFREE) || defined(PROTO) 746 void 747 eval_clear() 748 { 749 int i; 750 struct vimvar *p; 751 752 for (i = 0; i < VV_LEN; ++i) 753 { 754 p = &vimvars[i]; 755 if (p->vv_di.di_tv.v_type == VAR_STRING) 756 { 757 vim_free(p->vv_di.di_tv.vval.v_string); 758 p->vv_di.di_tv.vval.v_string = NULL; 759 } 760 } 761 hash_clear(&vimvarht); 762 hash_clear(&compat_hashtab); 763 764 /* script-local variables */ 765 for (i = 1; i <= ga_scripts.ga_len; ++i) 766 vars_clear(&SCRIPT_VARS(i)); 767 ga_clear(&ga_scripts); 768 free_scriptnames(); 769 770 /* global variables */ 771 vars_clear(&globvarht); 772 773 /* functions */ 774 free_all_functions(); 775 hash_clear(&func_hashtab); 776 777 /* unreferenced lists and dicts */ 778 (void)garbage_collect(); 779 } 780 #endif 781 782 /* 783 * Return the name of the executed function. 784 */ 785 char_u * 786 func_name(cookie) 787 void *cookie; 788 { 789 return ((funccall_T *)cookie)->func->uf_name; 790 } 791 792 /* 793 * Return the address holding the next breakpoint line for a funccall cookie. 794 */ 795 linenr_T * 796 func_breakpoint(cookie) 797 void *cookie; 798 { 799 return &((funccall_T *)cookie)->breakpoint; 800 } 801 802 /* 803 * Return the address holding the debug tick for a funccall cookie. 804 */ 805 int * 806 func_dbg_tick(cookie) 807 void *cookie; 808 { 809 return &((funccall_T *)cookie)->dbg_tick; 810 } 811 812 /* 813 * Return the nesting level for a funccall cookie. 814 */ 815 int 816 func_level(cookie) 817 void *cookie; 818 { 819 return ((funccall_T *)cookie)->level; 820 } 821 822 /* pointer to funccal for currently active function */ 823 funccall_T *current_funccal = NULL; 824 825 /* 826 * Return TRUE when a function was ended by a ":return" command. 827 */ 828 int 829 current_func_returned() 830 { 831 return current_funccal->returned; 832 } 833 834 835 /* 836 * Set an internal variable to a string value. Creates the variable if it does 837 * not already exist. 838 */ 839 void 840 set_internal_string_var(name, value) 841 char_u *name; 842 char_u *value; 843 { 844 char_u *val; 845 typval_T *tvp; 846 847 val = vim_strsave(value); 848 if (val != NULL) 849 { 850 tvp = alloc_string_tv(val); 851 if (tvp != NULL) 852 { 853 set_var(name, tvp, FALSE); 854 free_tv(tvp); 855 } 856 } 857 } 858 859 static lval_T *redir_lval = NULL; 860 static char_u *redir_endp = NULL; 861 static char_u *redir_varname = NULL; 862 863 /* 864 * Start recording command output to a variable 865 * Returns OK if successfully completed the setup. FAIL otherwise. 866 */ 867 int 868 var_redir_start(name, append) 869 char_u *name; 870 int append; /* append to an existing variable */ 871 { 872 int save_emsg; 873 int err; 874 typval_T tv; 875 876 /* Make sure a valid variable name is specified */ 877 if (!eval_isnamec1(*name)) 878 { 879 EMSG(_(e_invarg)); 880 return FAIL; 881 } 882 883 redir_varname = vim_strsave(name); 884 if (redir_varname == NULL) 885 return FAIL; 886 887 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 888 if (redir_lval == NULL) 889 { 890 var_redir_stop(); 891 return FAIL; 892 } 893 894 /* Parse the variable name (can be a dict or list entry). */ 895 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 896 FNE_CHECK_START); 897 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 898 { 899 if (redir_endp != NULL && *redir_endp != NUL) 900 /* Trailing characters are present after the variable name */ 901 EMSG(_(e_trailing)); 902 else 903 EMSG(_(e_invarg)); 904 var_redir_stop(); 905 return FAIL; 906 } 907 908 /* check if we can write to the variable: set it to or append an empty 909 * string */ 910 save_emsg = did_emsg; 911 did_emsg = FALSE; 912 tv.v_type = VAR_STRING; 913 tv.vval.v_string = (char_u *)""; 914 if (append) 915 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 916 else 917 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 918 err = did_emsg; 919 did_emsg += save_emsg; 920 if (err) 921 { 922 var_redir_stop(); 923 return FAIL; 924 } 925 if (redir_lval->ll_newkey != NULL) 926 { 927 /* Dictionary item was created, don't do it again. */ 928 vim_free(redir_lval->ll_newkey); 929 redir_lval->ll_newkey = NULL; 930 } 931 932 return OK; 933 } 934 935 /* 936 * Append "value[len]" to the variable set by var_redir_start(). 937 */ 938 void 939 var_redir_str(value, len) 940 char_u *value; 941 int len; 942 { 943 char_u *val; 944 typval_T tv; 945 int save_emsg; 946 int err; 947 948 if (redir_lval == NULL) 949 return; 950 951 if (len == -1) 952 /* Append the entire string */ 953 val = vim_strsave(value); 954 else 955 /* Append only the specified number of characters */ 956 val = vim_strnsave(value, len); 957 if (val == NULL) 958 return; 959 960 tv.v_type = VAR_STRING; 961 tv.vval.v_string = val; 962 963 save_emsg = did_emsg; 964 did_emsg = FALSE; 965 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 966 err = did_emsg; 967 did_emsg += save_emsg; 968 if (err) 969 var_redir_stop(); 970 971 vim_free(tv.vval.v_string); 972 } 973 974 /* 975 * Stop redirecting command output to a variable. 976 */ 977 void 978 var_redir_stop() 979 { 980 if (redir_lval != NULL) 981 { 982 clear_lval(redir_lval); 983 vim_free(redir_lval); 984 redir_lval = NULL; 985 } 986 vim_free(redir_varname); 987 redir_varname = NULL; 988 } 989 990 # if defined(FEAT_MBYTE) || defined(PROTO) 991 int 992 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 993 char_u *enc_from; 994 char_u *enc_to; 995 char_u *fname_from; 996 char_u *fname_to; 997 { 998 int err = FALSE; 999 1000 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1001 set_vim_var_string(VV_CC_TO, enc_to, -1); 1002 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1003 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1004 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1005 err = TRUE; 1006 set_vim_var_string(VV_CC_FROM, NULL, -1); 1007 set_vim_var_string(VV_CC_TO, NULL, -1); 1008 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1009 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1010 1011 if (err) 1012 return FAIL; 1013 return OK; 1014 } 1015 # endif 1016 1017 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1018 int 1019 eval_printexpr(fname, args) 1020 char_u *fname; 1021 char_u *args; 1022 { 1023 int err = FALSE; 1024 1025 set_vim_var_string(VV_FNAME_IN, fname, -1); 1026 set_vim_var_string(VV_CMDARG, args, -1); 1027 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1028 err = TRUE; 1029 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1030 set_vim_var_string(VV_CMDARG, NULL, -1); 1031 1032 if (err) 1033 { 1034 mch_remove(fname); 1035 return FAIL; 1036 } 1037 return OK; 1038 } 1039 # endif 1040 1041 # if defined(FEAT_DIFF) || defined(PROTO) 1042 void 1043 eval_diff(origfile, newfile, outfile) 1044 char_u *origfile; 1045 char_u *newfile; 1046 char_u *outfile; 1047 { 1048 int err = FALSE; 1049 1050 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1051 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1052 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1053 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1054 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1055 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1056 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1057 } 1058 1059 void 1060 eval_patch(origfile, difffile, outfile) 1061 char_u *origfile; 1062 char_u *difffile; 1063 char_u *outfile; 1064 { 1065 int err; 1066 1067 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1068 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1069 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1070 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1071 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1072 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1073 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1074 } 1075 # endif 1076 1077 /* 1078 * Top level evaluation function, returning a boolean. 1079 * Sets "error" to TRUE if there was an error. 1080 * Return TRUE or FALSE. 1081 */ 1082 int 1083 eval_to_bool(arg, error, nextcmd, skip) 1084 char_u *arg; 1085 int *error; 1086 char_u **nextcmd; 1087 int skip; /* only parse, don't execute */ 1088 { 1089 typval_T tv; 1090 int retval = FALSE; 1091 1092 if (skip) 1093 ++emsg_skip; 1094 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1095 *error = TRUE; 1096 else 1097 { 1098 *error = FALSE; 1099 if (!skip) 1100 { 1101 retval = (get_tv_number_chk(&tv, error) != 0); 1102 clear_tv(&tv); 1103 } 1104 } 1105 if (skip) 1106 --emsg_skip; 1107 1108 return retval; 1109 } 1110 1111 /* 1112 * Top level evaluation function, returning a string. If "skip" is TRUE, 1113 * only parsing to "nextcmd" is done, without reporting errors. Return 1114 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1115 */ 1116 char_u * 1117 eval_to_string_skip(arg, nextcmd, skip) 1118 char_u *arg; 1119 char_u **nextcmd; 1120 int skip; /* only parse, don't execute */ 1121 { 1122 typval_T tv; 1123 char_u *retval; 1124 1125 if (skip) 1126 ++emsg_skip; 1127 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1128 retval = NULL; 1129 else 1130 { 1131 retval = vim_strsave(get_tv_string(&tv)); 1132 clear_tv(&tv); 1133 } 1134 if (skip) 1135 --emsg_skip; 1136 1137 return retval; 1138 } 1139 1140 /* 1141 * Skip over an expression at "*pp". 1142 * Return FAIL for an error, OK otherwise. 1143 */ 1144 int 1145 skip_expr(pp) 1146 char_u **pp; 1147 { 1148 typval_T rettv; 1149 1150 *pp = skipwhite(*pp); 1151 return eval1(pp, &rettv, FALSE); 1152 } 1153 1154 /* 1155 * Top level evaluation function, returning a string. 1156 * Return pointer to allocated memory, or NULL for failure. 1157 */ 1158 char_u * 1159 eval_to_string(arg, nextcmd) 1160 char_u *arg; 1161 char_u **nextcmd; 1162 { 1163 typval_T tv; 1164 char_u *retval; 1165 1166 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1167 retval = NULL; 1168 else 1169 { 1170 retval = vim_strsave(get_tv_string(&tv)); 1171 clear_tv(&tv); 1172 } 1173 1174 return retval; 1175 } 1176 1177 /* 1178 * Call eval_to_string() with "sandbox" set and not using local variables. 1179 */ 1180 char_u * 1181 eval_to_string_safe(arg, nextcmd) 1182 char_u *arg; 1183 char_u **nextcmd; 1184 { 1185 char_u *retval; 1186 void *save_funccalp; 1187 1188 save_funccalp = save_funccal(); 1189 ++sandbox; 1190 retval = eval_to_string(arg, nextcmd); 1191 --sandbox; 1192 restore_funccal(save_funccalp); 1193 return retval; 1194 } 1195 1196 /* 1197 * Top level evaluation function, returning a number. 1198 * Evaluates "expr" silently. 1199 * Returns -1 for an error. 1200 */ 1201 int 1202 eval_to_number(expr) 1203 char_u *expr; 1204 { 1205 typval_T rettv; 1206 int retval; 1207 char_u *p = skipwhite(expr); 1208 1209 ++emsg_off; 1210 1211 if (eval1(&p, &rettv, TRUE) == FAIL) 1212 retval = -1; 1213 else 1214 { 1215 retval = get_tv_number_chk(&rettv, NULL); 1216 clear_tv(&rettv); 1217 } 1218 --emsg_off; 1219 1220 return retval; 1221 } 1222 1223 /* 1224 * Prepare v: variable "idx" to be used. 1225 * Save the current typeval in "save_tv". 1226 * When not used yet add the variable to the v: hashtable. 1227 */ 1228 static void 1229 prepare_vimvar(idx, save_tv) 1230 int idx; 1231 typval_T *save_tv; 1232 { 1233 *save_tv = vimvars[idx].vv_tv; 1234 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1235 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1236 } 1237 1238 /* 1239 * Restore v: variable "idx" to typeval "save_tv". 1240 * When no longer defined, remove the variable from the v: hashtable. 1241 */ 1242 static void 1243 restore_vimvar(idx, save_tv) 1244 int idx; 1245 typval_T *save_tv; 1246 { 1247 hashitem_T *hi; 1248 1249 clear_tv(&vimvars[idx].vv_tv); 1250 vimvars[idx].vv_tv = *save_tv; 1251 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1252 { 1253 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1254 if (HASHITEM_EMPTY(hi)) 1255 EMSG2(_(e_intern2), "restore_vimvar()"); 1256 else 1257 hash_remove(&vimvarht, hi); 1258 } 1259 } 1260 1261 #if defined(FEAT_SYN_HL) || defined(PROTO) 1262 /* 1263 * Evaluate an expression to a list with suggestions. 1264 * For the "expr:" part of 'spellsuggest'. 1265 */ 1266 list_T * 1267 eval_spell_expr(badword, expr) 1268 char_u *badword; 1269 char_u *expr; 1270 { 1271 typval_T save_val; 1272 typval_T rettv; 1273 list_T *list = NULL; 1274 char_u *p = skipwhite(expr); 1275 1276 /* Set "v:val" to the bad word. */ 1277 prepare_vimvar(VV_VAL, &save_val); 1278 vimvars[VV_VAL].vv_type = VAR_STRING; 1279 vimvars[VV_VAL].vv_str = badword; 1280 if (p_verbose == 0) 1281 ++emsg_off; 1282 1283 if (eval1(&p, &rettv, TRUE) == OK) 1284 { 1285 if (rettv.v_type != VAR_LIST) 1286 clear_tv(&rettv); 1287 else 1288 list = rettv.vval.v_list; 1289 } 1290 1291 if (p_verbose == 0) 1292 --emsg_off; 1293 vimvars[VV_VAL].vv_str = NULL; 1294 restore_vimvar(VV_VAL, &save_val); 1295 1296 return list; 1297 } 1298 1299 /* 1300 * "list" is supposed to contain two items: a word and a number. Return the 1301 * word in "pp" and the number as the return value. 1302 * Return -1 if anything isn't right. 1303 * Used to get the good word and score from the eval_spell_expr() result. 1304 */ 1305 int 1306 get_spellword(list, pp) 1307 list_T *list; 1308 char_u **pp; 1309 { 1310 listitem_T *li; 1311 1312 li = list->lv_first; 1313 if (li == NULL) 1314 return -1; 1315 *pp = get_tv_string(&li->li_tv); 1316 1317 li = li->li_next; 1318 if (li == NULL) 1319 return -1; 1320 return get_tv_number(&li->li_tv); 1321 } 1322 #endif 1323 1324 /* 1325 * Top level evaluation function, 1326 */ 1327 typval_T * 1328 eval_expr(arg, nextcmd) 1329 char_u *arg; 1330 char_u **nextcmd; 1331 { 1332 typval_T *tv; 1333 1334 tv = (typval_T *)alloc(sizeof(typval_T)); 1335 if (!tv) 1336 return NULL; 1337 1338 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1339 { 1340 vim_free(tv); 1341 return NULL; 1342 } 1343 1344 return tv; 1345 } 1346 1347 1348 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1349 /* 1350 * Call some vimL function and return the result in "*rettv". 1351 * Uses argv[argc] for the function arguments. 1352 * Returns OK or FAIL. 1353 */ 1354 static int 1355 call_vim_function(func, argc, argv, safe, rettv) 1356 char_u *func; 1357 int argc; 1358 char_u **argv; 1359 int safe; /* use the sandbox */ 1360 typval_T *rettv; 1361 { 1362 typval_T *argvars; 1363 long n; 1364 int len; 1365 int i; 1366 int doesrange; 1367 void *save_funccalp = NULL; 1368 int ret; 1369 1370 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1371 if (argvars == NULL) 1372 return FAIL; 1373 1374 for (i = 0; i < argc; i++) 1375 { 1376 /* Pass a NULL or empty argument as an empty string */ 1377 if (argv[i] == NULL || *argv[i] == NUL) 1378 { 1379 argvars[i].v_type = VAR_STRING; 1380 argvars[i].vval.v_string = (char_u *)""; 1381 continue; 1382 } 1383 1384 /* Recognize a number argument, the others must be strings. */ 1385 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1386 if (len != 0 && len == (int)STRLEN(argv[i])) 1387 { 1388 argvars[i].v_type = VAR_NUMBER; 1389 argvars[i].vval.v_number = n; 1390 } 1391 else 1392 { 1393 argvars[i].v_type = VAR_STRING; 1394 argvars[i].vval.v_string = argv[i]; 1395 } 1396 } 1397 1398 if (safe) 1399 { 1400 save_funccalp = save_funccal(); 1401 ++sandbox; 1402 } 1403 1404 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1405 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1406 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1407 &doesrange, TRUE, NULL); 1408 if (safe) 1409 { 1410 --sandbox; 1411 restore_funccal(save_funccalp); 1412 } 1413 vim_free(argvars); 1414 1415 if (ret == FAIL) 1416 clear_tv(rettv); 1417 1418 return ret; 1419 } 1420 1421 /* 1422 * Call vimL function "func" and return the result as a string. 1423 * Returns NULL when calling the function fails. 1424 * Uses argv[argc] for the function arguments. 1425 */ 1426 void * 1427 call_func_retstr(func, argc, argv, safe) 1428 char_u *func; 1429 int argc; 1430 char_u **argv; 1431 int safe; /* use the sandbox */ 1432 { 1433 typval_T rettv; 1434 char_u *retval; 1435 1436 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1437 return NULL; 1438 1439 retval = vim_strsave(get_tv_string(&rettv)); 1440 clear_tv(&rettv); 1441 return retval; 1442 } 1443 1444 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1445 /* 1446 * Call vimL function "func" and return the result as a number. 1447 * Returns -1 when calling the function fails. 1448 * Uses argv[argc] for the function arguments. 1449 */ 1450 long 1451 call_func_retnr(func, argc, argv, safe) 1452 char_u *func; 1453 int argc; 1454 char_u **argv; 1455 int safe; /* use the sandbox */ 1456 { 1457 typval_T rettv; 1458 long retval; 1459 1460 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1461 return -1; 1462 1463 retval = get_tv_number_chk(&rettv, NULL); 1464 clear_tv(&rettv); 1465 return retval; 1466 } 1467 #endif 1468 1469 /* 1470 * Call vimL function "func" and return the result as a list 1471 * Uses argv[argc] for the function arguments. 1472 */ 1473 void * 1474 call_func_retlist(func, argc, argv, safe) 1475 char_u *func; 1476 int argc; 1477 char_u **argv; 1478 int safe; /* use the sandbox */ 1479 { 1480 typval_T rettv; 1481 1482 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1483 return NULL; 1484 1485 if (rettv.v_type != VAR_LIST) 1486 { 1487 clear_tv(&rettv); 1488 return NULL; 1489 } 1490 1491 return rettv.vval.v_list; 1492 } 1493 1494 #endif 1495 1496 /* 1497 * Save the current function call pointer, and set it to NULL. 1498 * Used when executing autocommands and for ":source". 1499 */ 1500 void * 1501 save_funccal() 1502 { 1503 funccall_T *fc = current_funccal; 1504 1505 current_funccal = NULL; 1506 return (void *)fc; 1507 } 1508 1509 void 1510 restore_funccal(vfc) 1511 void *vfc; 1512 { 1513 funccall_T *fc = (funccall_T *)vfc; 1514 1515 current_funccal = fc; 1516 } 1517 1518 #if defined(FEAT_PROFILE) || defined(PROTO) 1519 /* 1520 * Prepare profiling for entering a child or something else that is not 1521 * counted for the script/function itself. 1522 * Should always be called in pair with prof_child_exit(). 1523 */ 1524 void 1525 prof_child_enter(tm) 1526 proftime_T *tm; /* place to store waittime */ 1527 { 1528 funccall_T *fc = current_funccal; 1529 1530 if (fc != NULL && fc->func->uf_profiling) 1531 profile_start(&fc->prof_child); 1532 script_prof_save(tm); 1533 } 1534 1535 /* 1536 * Take care of time spent in a child. 1537 * Should always be called after prof_child_enter(). 1538 */ 1539 void 1540 prof_child_exit(tm) 1541 proftime_T *tm; /* where waittime was stored */ 1542 { 1543 funccall_T *fc = current_funccal; 1544 1545 if (fc != NULL && fc->func->uf_profiling) 1546 { 1547 profile_end(&fc->prof_child); 1548 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1549 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1550 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1551 } 1552 script_prof_restore(tm); 1553 } 1554 #endif 1555 1556 1557 #ifdef FEAT_FOLDING 1558 /* 1559 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1560 * it in "*cp". Doesn't give error messages. 1561 */ 1562 int 1563 eval_foldexpr(arg, cp) 1564 char_u *arg; 1565 int *cp; 1566 { 1567 typval_T tv; 1568 int retval; 1569 char_u *s; 1570 1571 ++emsg_off; 1572 ++sandbox; 1573 *cp = NUL; 1574 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1575 retval = 0; 1576 else 1577 { 1578 /* If the result is a number, just return the number. */ 1579 if (tv.v_type == VAR_NUMBER) 1580 retval = tv.vval.v_number; 1581 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1582 retval = 0; 1583 else 1584 { 1585 /* If the result is a string, check if there is a non-digit before 1586 * the number. */ 1587 s = tv.vval.v_string; 1588 if (!VIM_ISDIGIT(*s) && *s != '-') 1589 *cp = *s++; 1590 retval = atol((char *)s); 1591 } 1592 clear_tv(&tv); 1593 } 1594 --emsg_off; 1595 --sandbox; 1596 1597 return retval; 1598 } 1599 #endif 1600 1601 /* 1602 * ":let" list all variable values 1603 * ":let var1 var2" list variable values 1604 * ":let var = expr" assignment command. 1605 * ":let var += expr" assignment command. 1606 * ":let var -= expr" assignment command. 1607 * ":let var .= expr" assignment command. 1608 * ":let [var1, var2] = expr" unpack list. 1609 */ 1610 void 1611 ex_let(eap) 1612 exarg_T *eap; 1613 { 1614 char_u *arg = eap->arg; 1615 char_u *expr = NULL; 1616 typval_T rettv; 1617 int i; 1618 int var_count = 0; 1619 int semicolon = 0; 1620 char_u op[2]; 1621 1622 expr = skip_var_list(arg, &var_count, &semicolon); 1623 if (expr == NULL) 1624 return; 1625 expr = vim_strchr(expr, '='); 1626 if (expr == NULL) 1627 { 1628 /* 1629 * ":let" without "=": list variables 1630 */ 1631 if (*arg == '[') 1632 EMSG(_(e_invarg)); 1633 else if (!ends_excmd(*arg)) 1634 /* ":let var1 var2" */ 1635 arg = list_arg_vars(eap, arg); 1636 else if (!eap->skip) 1637 { 1638 /* ":let" */ 1639 list_glob_vars(); 1640 list_buf_vars(); 1641 list_win_vars(); 1642 list_vim_vars(); 1643 } 1644 eap->nextcmd = check_nextcmd(arg); 1645 } 1646 else 1647 { 1648 op[0] = '='; 1649 op[1] = NUL; 1650 if (expr > arg) 1651 { 1652 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1653 op[0] = expr[-1]; /* +=, -= or .= */ 1654 } 1655 expr = skipwhite(expr + 1); 1656 1657 if (eap->skip) 1658 ++emsg_skip; 1659 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1660 if (eap->skip) 1661 { 1662 if (i != FAIL) 1663 clear_tv(&rettv); 1664 --emsg_skip; 1665 } 1666 else if (i != FAIL) 1667 { 1668 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1669 op); 1670 clear_tv(&rettv); 1671 } 1672 } 1673 } 1674 1675 /* 1676 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1677 * Handles both "var" with any type and "[var, var; var]" with a list type. 1678 * When "nextchars" is not NULL it points to a string with characters that 1679 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1680 * or concatenate. 1681 * Returns OK or FAIL; 1682 */ 1683 static int 1684 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1685 char_u *arg_start; 1686 typval_T *tv; 1687 int copy; /* copy values from "tv", don't move */ 1688 int semicolon; /* from skip_var_list() */ 1689 int var_count; /* from skip_var_list() */ 1690 char_u *nextchars; 1691 { 1692 char_u *arg = arg_start; 1693 list_T *l; 1694 int i; 1695 listitem_T *item; 1696 typval_T ltv; 1697 1698 if (*arg != '[') 1699 { 1700 /* 1701 * ":let var = expr" or ":for var in list" 1702 */ 1703 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1704 return FAIL; 1705 return OK; 1706 } 1707 1708 /* 1709 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1710 */ 1711 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1712 { 1713 EMSG(_(e_listreq)); 1714 return FAIL; 1715 } 1716 1717 i = list_len(l); 1718 if (semicolon == 0 && var_count < i) 1719 { 1720 EMSG(_("E687: Less targets than List items")); 1721 return FAIL; 1722 } 1723 if (var_count - semicolon > i) 1724 { 1725 EMSG(_("E688: More targets than List items")); 1726 return FAIL; 1727 } 1728 1729 item = l->lv_first; 1730 while (*arg != ']') 1731 { 1732 arg = skipwhite(arg + 1); 1733 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1734 item = item->li_next; 1735 if (arg == NULL) 1736 return FAIL; 1737 1738 arg = skipwhite(arg); 1739 if (*arg == ';') 1740 { 1741 /* Put the rest of the list (may be empty) in the var after ';'. 1742 * Create a new list for this. */ 1743 l = list_alloc(); 1744 if (l == NULL) 1745 return FAIL; 1746 while (item != NULL) 1747 { 1748 list_append_tv(l, &item->li_tv); 1749 item = item->li_next; 1750 } 1751 1752 ltv.v_type = VAR_LIST; 1753 ltv.v_lock = 0; 1754 ltv.vval.v_list = l; 1755 l->lv_refcount = 1; 1756 1757 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1758 (char_u *)"]", nextchars); 1759 clear_tv(<v); 1760 if (arg == NULL) 1761 return FAIL; 1762 break; 1763 } 1764 else if (*arg != ',' && *arg != ']') 1765 { 1766 EMSG2(_(e_intern2), "ex_let_vars()"); 1767 return FAIL; 1768 } 1769 } 1770 1771 return OK; 1772 } 1773 1774 /* 1775 * Skip over assignable variable "var" or list of variables "[var, var]". 1776 * Used for ":let varvar = expr" and ":for varvar in expr". 1777 * For "[var, var]" increment "*var_count" for each variable. 1778 * for "[var, var; var]" set "semicolon". 1779 * Return NULL for an error. 1780 */ 1781 static char_u * 1782 skip_var_list(arg, var_count, semicolon) 1783 char_u *arg; 1784 int *var_count; 1785 int *semicolon; 1786 { 1787 char_u *p, *s; 1788 1789 if (*arg == '[') 1790 { 1791 /* "[var, var]": find the matching ']'. */ 1792 p = arg; 1793 for (;;) 1794 { 1795 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1796 s = skip_var_one(p); 1797 if (s == p) 1798 { 1799 EMSG2(_(e_invarg2), p); 1800 return NULL; 1801 } 1802 ++*var_count; 1803 1804 p = skipwhite(s); 1805 if (*p == ']') 1806 break; 1807 else if (*p == ';') 1808 { 1809 if (*semicolon == 1) 1810 { 1811 EMSG(_("Double ; in list of variables")); 1812 return NULL; 1813 } 1814 *semicolon = 1; 1815 } 1816 else if (*p != ',') 1817 { 1818 EMSG2(_(e_invarg2), p); 1819 return NULL; 1820 } 1821 } 1822 return p + 1; 1823 } 1824 else 1825 return skip_var_one(arg); 1826 } 1827 1828 /* 1829 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1830 * l[idx]. 1831 */ 1832 static char_u * 1833 skip_var_one(arg) 1834 char_u *arg; 1835 { 1836 if (*arg == '@' && arg[1] != NUL) 1837 return arg + 2; 1838 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1839 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1840 } 1841 1842 /* 1843 * List variables for hashtab "ht" with prefix "prefix". 1844 * If "empty" is TRUE also list NULL strings as empty strings. 1845 */ 1846 static void 1847 list_hashtable_vars(ht, prefix, empty) 1848 hashtab_T *ht; 1849 char_u *prefix; 1850 int empty; 1851 { 1852 hashitem_T *hi; 1853 dictitem_T *di; 1854 int todo; 1855 1856 todo = ht->ht_used; 1857 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1858 { 1859 if (!HASHITEM_EMPTY(hi)) 1860 { 1861 --todo; 1862 di = HI2DI(hi); 1863 if (empty || di->di_tv.v_type != VAR_STRING 1864 || di->di_tv.vval.v_string != NULL) 1865 list_one_var(di, prefix); 1866 } 1867 } 1868 } 1869 1870 /* 1871 * List global variables. 1872 */ 1873 static void 1874 list_glob_vars() 1875 { 1876 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1877 } 1878 1879 /* 1880 * List buffer variables. 1881 */ 1882 static void 1883 list_buf_vars() 1884 { 1885 char_u numbuf[NUMBUFLEN]; 1886 1887 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1888 1889 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1890 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1891 } 1892 1893 /* 1894 * List window variables. 1895 */ 1896 static void 1897 list_win_vars() 1898 { 1899 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1900 } 1901 1902 /* 1903 * List Vim variables. 1904 */ 1905 static void 1906 list_vim_vars() 1907 { 1908 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1909 } 1910 1911 /* 1912 * List variables in "arg". 1913 */ 1914 static char_u * 1915 list_arg_vars(eap, arg) 1916 exarg_T *eap; 1917 char_u *arg; 1918 { 1919 int error = FALSE; 1920 int len; 1921 char_u *name; 1922 char_u *name_start; 1923 char_u *arg_subsc; 1924 char_u *tofree; 1925 typval_T tv; 1926 1927 while (!ends_excmd(*arg) && !got_int) 1928 { 1929 if (error || eap->skip) 1930 { 1931 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1932 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1933 { 1934 emsg_severe = TRUE; 1935 EMSG(_(e_trailing)); 1936 break; 1937 } 1938 } 1939 else 1940 { 1941 /* get_name_len() takes care of expanding curly braces */ 1942 name_start = name = arg; 1943 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1944 if (len <= 0) 1945 { 1946 /* This is mainly to keep test 49 working: when expanding 1947 * curly braces fails overrule the exception error message. */ 1948 if (len < 0 && !aborting()) 1949 { 1950 emsg_severe = TRUE; 1951 EMSG2(_(e_invarg2), arg); 1952 break; 1953 } 1954 error = TRUE; 1955 } 1956 else 1957 { 1958 if (tofree != NULL) 1959 name = tofree; 1960 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1961 error = TRUE; 1962 else 1963 { 1964 /* handle d.key, l[idx], f(expr) */ 1965 arg_subsc = arg; 1966 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1967 error = TRUE; 1968 else 1969 { 1970 if (arg == arg_subsc && len == 2 && name[1] == ':') 1971 { 1972 switch (*name) 1973 { 1974 case 'g': list_glob_vars(); break; 1975 case 'b': list_buf_vars(); break; 1976 case 'w': list_win_vars(); break; 1977 case 'v': list_vim_vars(); break; 1978 default: 1979 EMSG2(_("E738: Can't list variables for %s"), name); 1980 } 1981 } 1982 else 1983 { 1984 char_u numbuf[NUMBUFLEN]; 1985 char_u *tf; 1986 int c; 1987 char_u *s; 1988 1989 s = echo_string(&tv, &tf, numbuf); 1990 c = *arg; 1991 *arg = NUL; 1992 list_one_var_a((char_u *)"", 1993 arg == arg_subsc ? name : name_start, 1994 tv.v_type, s == NULL ? (char_u *)"" : s); 1995 *arg = c; 1996 vim_free(tf); 1997 } 1998 clear_tv(&tv); 1999 } 2000 } 2001 } 2002 2003 vim_free(tofree); 2004 } 2005 2006 arg = skipwhite(arg); 2007 } 2008 2009 return arg; 2010 } 2011 2012 /* 2013 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2014 * Returns a pointer to the char just after the var name. 2015 * Returns NULL if there is an error. 2016 */ 2017 static char_u * 2018 ex_let_one(arg, tv, copy, endchars, op) 2019 char_u *arg; /* points to variable name */ 2020 typval_T *tv; /* value to assign to variable */ 2021 int copy; /* copy value from "tv" */ 2022 char_u *endchars; /* valid chars after variable name or NULL */ 2023 char_u *op; /* "+", "-", "." or NULL*/ 2024 { 2025 int c1; 2026 char_u *name; 2027 char_u *p; 2028 char_u *arg_end = NULL; 2029 int len; 2030 int opt_flags; 2031 char_u *tofree = NULL; 2032 2033 /* 2034 * ":let $VAR = expr": Set environment variable. 2035 */ 2036 if (*arg == '$') 2037 { 2038 /* Find the end of the name. */ 2039 ++arg; 2040 name = arg; 2041 len = get_env_len(&arg); 2042 if (len == 0) 2043 EMSG2(_(e_invarg2), name - 1); 2044 else 2045 { 2046 if (op != NULL && (*op == '+' || *op == '-')) 2047 EMSG2(_(e_letwrong), op); 2048 else if (endchars != NULL 2049 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2050 EMSG(_(e_letunexp)); 2051 else 2052 { 2053 c1 = name[len]; 2054 name[len] = NUL; 2055 p = get_tv_string_chk(tv); 2056 if (p != NULL && op != NULL && *op == '.') 2057 { 2058 int mustfree = FALSE; 2059 char_u *s = vim_getenv(name, &mustfree); 2060 2061 if (s != NULL) 2062 { 2063 p = tofree = concat_str(s, p); 2064 if (mustfree) 2065 vim_free(s); 2066 } 2067 } 2068 if (p != NULL) 2069 { 2070 vim_setenv(name, p); 2071 if (STRICMP(name, "HOME") == 0) 2072 init_homedir(); 2073 else if (didset_vim && STRICMP(name, "VIM") == 0) 2074 didset_vim = FALSE; 2075 else if (didset_vimruntime 2076 && STRICMP(name, "VIMRUNTIME") == 0) 2077 didset_vimruntime = FALSE; 2078 arg_end = arg; 2079 } 2080 name[len] = c1; 2081 vim_free(tofree); 2082 } 2083 } 2084 } 2085 2086 /* 2087 * ":let &option = expr": Set option value. 2088 * ":let &l:option = expr": Set local option value. 2089 * ":let &g:option = expr": Set global option value. 2090 */ 2091 else if (*arg == '&') 2092 { 2093 /* Find the end of the name. */ 2094 p = find_option_end(&arg, &opt_flags); 2095 if (p == NULL || (endchars != NULL 2096 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2097 EMSG(_(e_letunexp)); 2098 else 2099 { 2100 long n; 2101 int opt_type; 2102 long numval; 2103 char_u *stringval = NULL; 2104 char_u *s; 2105 2106 c1 = *p; 2107 *p = NUL; 2108 2109 n = get_tv_number(tv); 2110 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2111 if (s != NULL && op != NULL && *op != '=') 2112 { 2113 opt_type = get_option_value(arg, &numval, 2114 &stringval, opt_flags); 2115 if ((opt_type == 1 && *op == '.') 2116 || (opt_type == 0 && *op != '.')) 2117 EMSG2(_(e_letwrong), op); 2118 else 2119 { 2120 if (opt_type == 1) /* number */ 2121 { 2122 if (*op == '+') 2123 n = numval + n; 2124 else 2125 n = numval - n; 2126 } 2127 else if (opt_type == 0 && stringval != NULL) /* string */ 2128 { 2129 s = concat_str(stringval, s); 2130 vim_free(stringval); 2131 stringval = s; 2132 } 2133 } 2134 } 2135 if (s != NULL) 2136 { 2137 set_option_value(arg, n, s, opt_flags); 2138 arg_end = p; 2139 } 2140 *p = c1; 2141 vim_free(stringval); 2142 } 2143 } 2144 2145 /* 2146 * ":let @r = expr": Set register contents. 2147 */ 2148 else if (*arg == '@') 2149 { 2150 ++arg; 2151 if (op != NULL && (*op == '+' || *op == '-')) 2152 EMSG2(_(e_letwrong), op); 2153 else if (endchars != NULL 2154 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2155 EMSG(_(e_letunexp)); 2156 else 2157 { 2158 char_u *tofree = NULL; 2159 char_u *s; 2160 2161 p = get_tv_string_chk(tv); 2162 if (p != NULL && op != NULL && *op == '.') 2163 { 2164 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2165 if (s != NULL) 2166 { 2167 p = tofree = concat_str(s, p); 2168 vim_free(s); 2169 } 2170 } 2171 if (p != NULL) 2172 { 2173 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2174 arg_end = arg + 1; 2175 } 2176 vim_free(tofree); 2177 } 2178 } 2179 2180 /* 2181 * ":let var = expr": Set internal variable. 2182 * ":let {expr} = expr": Idem, name made with curly braces 2183 */ 2184 else if (eval_isnamec1(*arg) || *arg == '{') 2185 { 2186 lval_T lv; 2187 2188 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2189 if (p != NULL && lv.ll_name != NULL) 2190 { 2191 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2192 EMSG(_(e_letunexp)); 2193 else 2194 { 2195 set_var_lval(&lv, p, tv, copy, op); 2196 arg_end = p; 2197 } 2198 } 2199 clear_lval(&lv); 2200 } 2201 2202 else 2203 EMSG2(_(e_invarg2), arg); 2204 2205 return arg_end; 2206 } 2207 2208 /* 2209 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2210 */ 2211 static int 2212 check_changedtick(arg) 2213 char_u *arg; 2214 { 2215 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2216 { 2217 EMSG2(_(e_readonlyvar), arg); 2218 return TRUE; 2219 } 2220 return FALSE; 2221 } 2222 2223 /* 2224 * Get an lval: variable, Dict item or List item that can be assigned a value 2225 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2226 * "name.key", "name.key[expr]" etc. 2227 * Indexing only works if "name" is an existing List or Dictionary. 2228 * "name" points to the start of the name. 2229 * If "rettv" is not NULL it points to the value to be assigned. 2230 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2231 * wrong; must end in space or cmd separator. 2232 * 2233 * Returns a pointer to just after the name, including indexes. 2234 * When an evaluation error occurs "lp->ll_name" is NULL; 2235 * Returns NULL for a parsing error. Still need to free items in "lp"! 2236 */ 2237 static char_u * 2238 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2239 char_u *name; 2240 typval_T *rettv; 2241 lval_T *lp; 2242 int unlet; 2243 int skip; 2244 int quiet; /* don't give error messages */ 2245 int fne_flags; /* flags for find_name_end() */ 2246 { 2247 char_u *p; 2248 char_u *expr_start, *expr_end; 2249 int cc; 2250 dictitem_T *v; 2251 typval_T var1; 2252 typval_T var2; 2253 int empty1 = FALSE; 2254 listitem_T *ni; 2255 char_u *key = NULL; 2256 int len; 2257 hashtab_T *ht; 2258 2259 /* Clear everything in "lp". */ 2260 vim_memset(lp, 0, sizeof(lval_T)); 2261 2262 if (skip) 2263 { 2264 /* When skipping just find the end of the name. */ 2265 lp->ll_name = name; 2266 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2267 } 2268 2269 /* Find the end of the name. */ 2270 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2271 if (expr_start != NULL) 2272 { 2273 /* Don't expand the name when we already know there is an error. */ 2274 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2275 && *p != '[' && *p != '.') 2276 { 2277 EMSG(_(e_trailing)); 2278 return NULL; 2279 } 2280 2281 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2282 if (lp->ll_exp_name == NULL) 2283 { 2284 /* Report an invalid expression in braces, unless the 2285 * expression evaluation has been cancelled due to an 2286 * aborting error, an interrupt, or an exception. */ 2287 if (!aborting() && !quiet) 2288 { 2289 emsg_severe = TRUE; 2290 EMSG2(_(e_invarg2), name); 2291 return NULL; 2292 } 2293 } 2294 lp->ll_name = lp->ll_exp_name; 2295 } 2296 else 2297 lp->ll_name = name; 2298 2299 /* Without [idx] or .key we are done. */ 2300 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2301 return p; 2302 2303 cc = *p; 2304 *p = NUL; 2305 v = find_var(lp->ll_name, &ht); 2306 if (v == NULL && !quiet) 2307 EMSG2(_(e_undefvar), lp->ll_name); 2308 *p = cc; 2309 if (v == NULL) 2310 return NULL; 2311 2312 /* 2313 * Loop until no more [idx] or .key is following. 2314 */ 2315 lp->ll_tv = &v->di_tv; 2316 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2317 { 2318 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2319 && !(lp->ll_tv->v_type == VAR_DICT 2320 && lp->ll_tv->vval.v_dict != NULL)) 2321 { 2322 if (!quiet) 2323 EMSG(_("E689: Can only index a List or Dictionary")); 2324 return NULL; 2325 } 2326 if (lp->ll_range) 2327 { 2328 if (!quiet) 2329 EMSG(_("E708: [:] must come last")); 2330 return NULL; 2331 } 2332 2333 len = -1; 2334 if (*p == '.') 2335 { 2336 key = p + 1; 2337 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2338 ; 2339 if (len == 0) 2340 { 2341 if (!quiet) 2342 EMSG(_(e_emptykey)); 2343 return NULL; 2344 } 2345 p = key + len; 2346 } 2347 else 2348 { 2349 /* Get the index [expr] or the first index [expr: ]. */ 2350 p = skipwhite(p + 1); 2351 if (*p == ':') 2352 empty1 = TRUE; 2353 else 2354 { 2355 empty1 = FALSE; 2356 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2357 return NULL; 2358 if (get_tv_string_chk(&var1) == NULL) 2359 { 2360 /* not a number or string */ 2361 clear_tv(&var1); 2362 return NULL; 2363 } 2364 } 2365 2366 /* Optionally get the second index [ :expr]. */ 2367 if (*p == ':') 2368 { 2369 if (lp->ll_tv->v_type == VAR_DICT) 2370 { 2371 if (!quiet) 2372 EMSG(_(e_dictrange)); 2373 if (!empty1) 2374 clear_tv(&var1); 2375 return NULL; 2376 } 2377 if (rettv != NULL && (rettv->v_type != VAR_LIST 2378 || rettv->vval.v_list == NULL)) 2379 { 2380 if (!quiet) 2381 EMSG(_("E709: [:] requires a List value")); 2382 if (!empty1) 2383 clear_tv(&var1); 2384 return NULL; 2385 } 2386 p = skipwhite(p + 1); 2387 if (*p == ']') 2388 lp->ll_empty2 = TRUE; 2389 else 2390 { 2391 lp->ll_empty2 = FALSE; 2392 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2393 { 2394 if (!empty1) 2395 clear_tv(&var1); 2396 return NULL; 2397 } 2398 if (get_tv_string_chk(&var2) == NULL) 2399 { 2400 /* not a number or string */ 2401 if (!empty1) 2402 clear_tv(&var1); 2403 clear_tv(&var2); 2404 return NULL; 2405 } 2406 } 2407 lp->ll_range = TRUE; 2408 } 2409 else 2410 lp->ll_range = FALSE; 2411 2412 if (*p != ']') 2413 { 2414 if (!quiet) 2415 EMSG(_(e_missbrac)); 2416 if (!empty1) 2417 clear_tv(&var1); 2418 if (lp->ll_range && !lp->ll_empty2) 2419 clear_tv(&var2); 2420 return NULL; 2421 } 2422 2423 /* Skip to past ']'. */ 2424 ++p; 2425 } 2426 2427 if (lp->ll_tv->v_type == VAR_DICT) 2428 { 2429 if (len == -1) 2430 { 2431 /* "[key]": get key from "var1" */ 2432 key = get_tv_string(&var1); /* is number or string */ 2433 if (*key == NUL) 2434 { 2435 if (!quiet) 2436 EMSG(_(e_emptykey)); 2437 clear_tv(&var1); 2438 return NULL; 2439 } 2440 } 2441 lp->ll_list = NULL; 2442 lp->ll_dict = lp->ll_tv->vval.v_dict; 2443 lp->ll_di = dict_find(lp->ll_dict, key, len); 2444 if (lp->ll_di == NULL) 2445 { 2446 /* Key does not exist in dict: may need to add it. */ 2447 if (*p == '[' || *p == '.' || unlet) 2448 { 2449 if (!quiet) 2450 EMSG2(_(e_dictkey), key); 2451 if (len == -1) 2452 clear_tv(&var1); 2453 return NULL; 2454 } 2455 if (len == -1) 2456 lp->ll_newkey = vim_strsave(key); 2457 else 2458 lp->ll_newkey = vim_strnsave(key, len); 2459 if (len == -1) 2460 clear_tv(&var1); 2461 if (lp->ll_newkey == NULL) 2462 p = NULL; 2463 break; 2464 } 2465 if (len == -1) 2466 clear_tv(&var1); 2467 lp->ll_tv = &lp->ll_di->di_tv; 2468 } 2469 else 2470 { 2471 /* 2472 * Get the number and item for the only or first index of the List. 2473 */ 2474 if (empty1) 2475 lp->ll_n1 = 0; 2476 else 2477 { 2478 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2479 clear_tv(&var1); 2480 } 2481 lp->ll_dict = NULL; 2482 lp->ll_list = lp->ll_tv->vval.v_list; 2483 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2484 if (lp->ll_li == NULL) 2485 { 2486 if (!quiet) 2487 EMSGN(_(e_listidx), lp->ll_n1); 2488 if (lp->ll_range && !lp->ll_empty2) 2489 clear_tv(&var2); 2490 return NULL; 2491 } 2492 2493 /* 2494 * May need to find the item or absolute index for the second 2495 * index of a range. 2496 * When no index given: "lp->ll_empty2" is TRUE. 2497 * Otherwise "lp->ll_n2" is set to the second index. 2498 */ 2499 if (lp->ll_range && !lp->ll_empty2) 2500 { 2501 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2502 clear_tv(&var2); 2503 if (lp->ll_n2 < 0) 2504 { 2505 ni = list_find(lp->ll_list, lp->ll_n2); 2506 if (ni == NULL) 2507 { 2508 if (!quiet) 2509 EMSGN(_(e_listidx), lp->ll_n2); 2510 return NULL; 2511 } 2512 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2513 } 2514 2515 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2516 if (lp->ll_n1 < 0) 2517 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2518 if (lp->ll_n2 < lp->ll_n1) 2519 { 2520 if (!quiet) 2521 EMSGN(_(e_listidx), lp->ll_n2); 2522 return NULL; 2523 } 2524 } 2525 2526 lp->ll_tv = &lp->ll_li->li_tv; 2527 } 2528 } 2529 2530 return p; 2531 } 2532 2533 /* 2534 * Clear lval "lp" that was filled by get_lval(). 2535 */ 2536 static void 2537 clear_lval(lp) 2538 lval_T *lp; 2539 { 2540 vim_free(lp->ll_exp_name); 2541 vim_free(lp->ll_newkey); 2542 } 2543 2544 /* 2545 * Set a variable that was parsed by get_lval() to "rettv". 2546 * "endp" points to just after the parsed name. 2547 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2548 */ 2549 static void 2550 set_var_lval(lp, endp, rettv, copy, op) 2551 lval_T *lp; 2552 char_u *endp; 2553 typval_T *rettv; 2554 int copy; 2555 char_u *op; 2556 { 2557 int cc; 2558 listitem_T *ri; 2559 dictitem_T *di; 2560 2561 if (lp->ll_tv == NULL) 2562 { 2563 if (!check_changedtick(lp->ll_name)) 2564 { 2565 cc = *endp; 2566 *endp = NUL; 2567 if (op != NULL && *op != '=') 2568 { 2569 typval_T tv; 2570 2571 /* handle +=, -= and .= */ 2572 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2573 &tv, TRUE) == OK) 2574 { 2575 if (tv_op(&tv, rettv, op) == OK) 2576 set_var(lp->ll_name, &tv, FALSE); 2577 clear_tv(&tv); 2578 } 2579 } 2580 else 2581 set_var(lp->ll_name, rettv, copy); 2582 *endp = cc; 2583 } 2584 } 2585 else if (tv_check_lock(lp->ll_newkey == NULL 2586 ? lp->ll_tv->v_lock 2587 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2588 ; 2589 else if (lp->ll_range) 2590 { 2591 /* 2592 * Assign the List values to the list items. 2593 */ 2594 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2595 { 2596 if (op != NULL && *op != '=') 2597 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2598 else 2599 { 2600 clear_tv(&lp->ll_li->li_tv); 2601 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2602 } 2603 ri = ri->li_next; 2604 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2605 break; 2606 if (lp->ll_li->li_next == NULL) 2607 { 2608 /* Need to add an empty item. */ 2609 if (list_append_number(lp->ll_list, 0) == FAIL) 2610 { 2611 ri = NULL; 2612 break; 2613 } 2614 } 2615 lp->ll_li = lp->ll_li->li_next; 2616 ++lp->ll_n1; 2617 } 2618 if (ri != NULL) 2619 EMSG(_("E710: List value has more items than target")); 2620 else if (lp->ll_empty2 2621 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2622 : lp->ll_n1 != lp->ll_n2) 2623 EMSG(_("E711: List value has not enough items")); 2624 } 2625 else 2626 { 2627 /* 2628 * Assign to a List or Dictionary item. 2629 */ 2630 if (lp->ll_newkey != NULL) 2631 { 2632 if (op != NULL && *op != '=') 2633 { 2634 EMSG2(_(e_letwrong), op); 2635 return; 2636 } 2637 2638 /* Need to add an item to the Dictionary. */ 2639 di = dictitem_alloc(lp->ll_newkey); 2640 if (di == NULL) 2641 return; 2642 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2643 { 2644 vim_free(di); 2645 return; 2646 } 2647 lp->ll_tv = &di->di_tv; 2648 } 2649 else if (op != NULL && *op != '=') 2650 { 2651 tv_op(lp->ll_tv, rettv, op); 2652 return; 2653 } 2654 else 2655 clear_tv(lp->ll_tv); 2656 2657 /* 2658 * Assign the value to the variable or list item. 2659 */ 2660 if (copy) 2661 copy_tv(rettv, lp->ll_tv); 2662 else 2663 { 2664 *lp->ll_tv = *rettv; 2665 lp->ll_tv->v_lock = 0; 2666 init_tv(rettv); 2667 } 2668 } 2669 } 2670 2671 /* 2672 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2673 * Returns OK or FAIL. 2674 */ 2675 static int 2676 tv_op(tv1, tv2, op) 2677 typval_T *tv1; 2678 typval_T *tv2; 2679 char_u *op; 2680 { 2681 long n; 2682 char_u numbuf[NUMBUFLEN]; 2683 char_u *s; 2684 2685 /* Can't do anything with a Funcref or a Dict on the right. */ 2686 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2687 { 2688 switch (tv1->v_type) 2689 { 2690 case VAR_DICT: 2691 case VAR_FUNC: 2692 break; 2693 2694 case VAR_LIST: 2695 if (*op != '+' || tv2->v_type != VAR_LIST) 2696 break; 2697 /* List += List */ 2698 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2699 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2700 return OK; 2701 2702 case VAR_NUMBER: 2703 case VAR_STRING: 2704 if (tv2->v_type == VAR_LIST) 2705 break; 2706 if (*op == '+' || *op == '-') 2707 { 2708 /* nr += nr or nr -= nr*/ 2709 n = get_tv_number(tv1); 2710 if (*op == '+') 2711 n += get_tv_number(tv2); 2712 else 2713 n -= get_tv_number(tv2); 2714 clear_tv(tv1); 2715 tv1->v_type = VAR_NUMBER; 2716 tv1->vval.v_number = n; 2717 } 2718 else 2719 { 2720 /* str .= str */ 2721 s = get_tv_string(tv1); 2722 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2723 clear_tv(tv1); 2724 tv1->v_type = VAR_STRING; 2725 tv1->vval.v_string = s; 2726 } 2727 return OK; 2728 } 2729 } 2730 2731 EMSG2(_(e_letwrong), op); 2732 return FAIL; 2733 } 2734 2735 /* 2736 * Add a watcher to a list. 2737 */ 2738 static void 2739 list_add_watch(l, lw) 2740 list_T *l; 2741 listwatch_T *lw; 2742 { 2743 lw->lw_next = l->lv_watch; 2744 l->lv_watch = lw; 2745 } 2746 2747 /* 2748 * Remove a watcher from a list. 2749 * No warning when it isn't found... 2750 */ 2751 static void 2752 list_rem_watch(l, lwrem) 2753 list_T *l; 2754 listwatch_T *lwrem; 2755 { 2756 listwatch_T *lw, **lwp; 2757 2758 lwp = &l->lv_watch; 2759 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2760 { 2761 if (lw == lwrem) 2762 { 2763 *lwp = lw->lw_next; 2764 break; 2765 } 2766 lwp = &lw->lw_next; 2767 } 2768 } 2769 2770 /* 2771 * Just before removing an item from a list: advance watchers to the next 2772 * item. 2773 */ 2774 static void 2775 list_fix_watch(l, item) 2776 list_T *l; 2777 listitem_T *item; 2778 { 2779 listwatch_T *lw; 2780 2781 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2782 if (lw->lw_item == item) 2783 lw->lw_item = item->li_next; 2784 } 2785 2786 /* 2787 * Evaluate the expression used in a ":for var in expr" command. 2788 * "arg" points to "var". 2789 * Set "*errp" to TRUE for an error, FALSE otherwise; 2790 * Return a pointer that holds the info. Null when there is an error. 2791 */ 2792 void * 2793 eval_for_line(arg, errp, nextcmdp, skip) 2794 char_u *arg; 2795 int *errp; 2796 char_u **nextcmdp; 2797 int skip; 2798 { 2799 forinfo_T *fi; 2800 char_u *expr; 2801 typval_T tv; 2802 list_T *l; 2803 2804 *errp = TRUE; /* default: there is an error */ 2805 2806 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2807 if (fi == NULL) 2808 return NULL; 2809 2810 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2811 if (expr == NULL) 2812 return fi; 2813 2814 expr = skipwhite(expr); 2815 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2816 { 2817 EMSG(_("E690: Missing \"in\" after :for")); 2818 return fi; 2819 } 2820 2821 if (skip) 2822 ++emsg_skip; 2823 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2824 { 2825 *errp = FALSE; 2826 if (!skip) 2827 { 2828 l = tv.vval.v_list; 2829 if (tv.v_type != VAR_LIST || l == NULL) 2830 { 2831 EMSG(_(e_listreq)); 2832 clear_tv(&tv); 2833 } 2834 else 2835 { 2836 /* No need to increment the refcount, it's already set for the 2837 * list being used in "tv". */ 2838 fi->fi_list = l; 2839 list_add_watch(l, &fi->fi_lw); 2840 fi->fi_lw.lw_item = l->lv_first; 2841 } 2842 } 2843 } 2844 if (skip) 2845 --emsg_skip; 2846 2847 return fi; 2848 } 2849 2850 /* 2851 * Use the first item in a ":for" list. Advance to the next. 2852 * Assign the values to the variable (list). "arg" points to the first one. 2853 * Return TRUE when a valid item was found, FALSE when at end of list or 2854 * something wrong. 2855 */ 2856 int 2857 next_for_item(fi_void, arg) 2858 void *fi_void; 2859 char_u *arg; 2860 { 2861 forinfo_T *fi = (forinfo_T *)fi_void; 2862 int result; 2863 listitem_T *item; 2864 2865 item = fi->fi_lw.lw_item; 2866 if (item == NULL) 2867 result = FALSE; 2868 else 2869 { 2870 fi->fi_lw.lw_item = item->li_next; 2871 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2872 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2873 } 2874 return result; 2875 } 2876 2877 /* 2878 * Free the structure used to store info used by ":for". 2879 */ 2880 void 2881 free_for_info(fi_void) 2882 void *fi_void; 2883 { 2884 forinfo_T *fi = (forinfo_T *)fi_void; 2885 2886 if (fi != NULL && fi->fi_list != NULL) 2887 { 2888 list_rem_watch(fi->fi_list, &fi->fi_lw); 2889 list_unref(fi->fi_list); 2890 } 2891 vim_free(fi); 2892 } 2893 2894 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2895 2896 void 2897 set_context_for_expression(xp, arg, cmdidx) 2898 expand_T *xp; 2899 char_u *arg; 2900 cmdidx_T cmdidx; 2901 { 2902 int got_eq = FALSE; 2903 int c; 2904 char_u *p; 2905 2906 if (cmdidx == CMD_let) 2907 { 2908 xp->xp_context = EXPAND_USER_VARS; 2909 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2910 { 2911 /* ":let var1 var2 ...": find last space. */ 2912 for (p = arg + STRLEN(arg); p >= arg; ) 2913 { 2914 xp->xp_pattern = p; 2915 mb_ptr_back(arg, p); 2916 if (vim_iswhite(*p)) 2917 break; 2918 } 2919 return; 2920 } 2921 } 2922 else 2923 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2924 : EXPAND_EXPRESSION; 2925 while ((xp->xp_pattern = vim_strpbrk(arg, 2926 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2927 { 2928 c = *xp->xp_pattern; 2929 if (c == '&') 2930 { 2931 c = xp->xp_pattern[1]; 2932 if (c == '&') 2933 { 2934 ++xp->xp_pattern; 2935 xp->xp_context = cmdidx != CMD_let || got_eq 2936 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2937 } 2938 else if (c != ' ') 2939 { 2940 xp->xp_context = EXPAND_SETTINGS; 2941 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2942 xp->xp_pattern += 2; 2943 2944 } 2945 } 2946 else if (c == '$') 2947 { 2948 /* environment variable */ 2949 xp->xp_context = EXPAND_ENV_VARS; 2950 } 2951 else if (c == '=') 2952 { 2953 got_eq = TRUE; 2954 xp->xp_context = EXPAND_EXPRESSION; 2955 } 2956 else if (c == '<' 2957 && xp->xp_context == EXPAND_FUNCTIONS 2958 && vim_strchr(xp->xp_pattern, '(') == NULL) 2959 { 2960 /* Function name can start with "<SNR>" */ 2961 break; 2962 } 2963 else if (cmdidx != CMD_let || got_eq) 2964 { 2965 if (c == '"') /* string */ 2966 { 2967 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2968 if (c == '\\' && xp->xp_pattern[1] != NUL) 2969 ++xp->xp_pattern; 2970 xp->xp_context = EXPAND_NOTHING; 2971 } 2972 else if (c == '\'') /* literal string */ 2973 { 2974 /* Trick: '' is like stopping and starting a literal string. */ 2975 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2976 /* skip */ ; 2977 xp->xp_context = EXPAND_NOTHING; 2978 } 2979 else if (c == '|') 2980 { 2981 if (xp->xp_pattern[1] == '|') 2982 { 2983 ++xp->xp_pattern; 2984 xp->xp_context = EXPAND_EXPRESSION; 2985 } 2986 else 2987 xp->xp_context = EXPAND_COMMANDS; 2988 } 2989 else 2990 xp->xp_context = EXPAND_EXPRESSION; 2991 } 2992 else 2993 /* Doesn't look like something valid, expand as an expression 2994 * anyway. */ 2995 xp->xp_context = EXPAND_EXPRESSION; 2996 arg = xp->xp_pattern; 2997 if (*arg != NUL) 2998 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 2999 /* skip */ ; 3000 } 3001 xp->xp_pattern = arg; 3002 } 3003 3004 #endif /* FEAT_CMDL_COMPL */ 3005 3006 /* 3007 * ":1,25call func(arg1, arg2)" function call. 3008 */ 3009 void 3010 ex_call(eap) 3011 exarg_T *eap; 3012 { 3013 char_u *arg = eap->arg; 3014 char_u *startarg; 3015 char_u *name; 3016 char_u *tofree; 3017 int len; 3018 typval_T rettv; 3019 linenr_T lnum; 3020 int doesrange; 3021 int failed = FALSE; 3022 funcdict_T fudi; 3023 3024 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3025 vim_free(fudi.fd_newkey); 3026 if (tofree == NULL) 3027 return; 3028 3029 /* Increase refcount on dictionary, it could get deleted when evaluating 3030 * the arguments. */ 3031 if (fudi.fd_dict != NULL) 3032 ++fudi.fd_dict->dv_refcount; 3033 3034 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3035 len = STRLEN(tofree); 3036 name = deref_func_name(tofree, &len); 3037 3038 /* Skip white space to allow ":call func ()". Not good, but required for 3039 * backward compatibility. */ 3040 startarg = skipwhite(arg); 3041 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3042 3043 if (*startarg != '(') 3044 { 3045 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3046 goto end; 3047 } 3048 3049 /* 3050 * When skipping, evaluate the function once, to find the end of the 3051 * arguments. 3052 * When the function takes a range, this is discovered after the first 3053 * call, and the loop is broken. 3054 */ 3055 if (eap->skip) 3056 { 3057 ++emsg_skip; 3058 lnum = eap->line2; /* do it once, also with an invalid range */ 3059 } 3060 else 3061 lnum = eap->line1; 3062 for ( ; lnum <= eap->line2; ++lnum) 3063 { 3064 if (!eap->skip && eap->addr_count > 0) 3065 { 3066 curwin->w_cursor.lnum = lnum; 3067 curwin->w_cursor.col = 0; 3068 } 3069 arg = startarg; 3070 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3071 eap->line1, eap->line2, &doesrange, 3072 !eap->skip, fudi.fd_dict) == FAIL) 3073 { 3074 failed = TRUE; 3075 break; 3076 } 3077 clear_tv(&rettv); 3078 if (doesrange || eap->skip) 3079 break; 3080 /* Stop when immediately aborting on error, or when an interrupt 3081 * occurred or an exception was thrown but not caught. 3082 * get_func_tv() returned OK, so that the check for trailing 3083 * characters below is executed. */ 3084 if (aborting()) 3085 break; 3086 } 3087 if (eap->skip) 3088 --emsg_skip; 3089 3090 if (!failed) 3091 { 3092 /* Check for trailing illegal characters and a following command. */ 3093 if (!ends_excmd(*arg)) 3094 { 3095 emsg_severe = TRUE; 3096 EMSG(_(e_trailing)); 3097 } 3098 else 3099 eap->nextcmd = check_nextcmd(arg); 3100 } 3101 3102 end: 3103 dict_unref(fudi.fd_dict); 3104 vim_free(tofree); 3105 } 3106 3107 /* 3108 * ":unlet[!] var1 ... " command. 3109 */ 3110 void 3111 ex_unlet(eap) 3112 exarg_T *eap; 3113 { 3114 ex_unletlock(eap, eap->arg, 0); 3115 } 3116 3117 /* 3118 * ":lockvar" and ":unlockvar" commands 3119 */ 3120 void 3121 ex_lockvar(eap) 3122 exarg_T *eap; 3123 { 3124 char_u *arg = eap->arg; 3125 int deep = 2; 3126 3127 if (eap->forceit) 3128 deep = -1; 3129 else if (vim_isdigit(*arg)) 3130 { 3131 deep = getdigits(&arg); 3132 arg = skipwhite(arg); 3133 } 3134 3135 ex_unletlock(eap, arg, deep); 3136 } 3137 3138 /* 3139 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3140 */ 3141 static void 3142 ex_unletlock(eap, argstart, deep) 3143 exarg_T *eap; 3144 char_u *argstart; 3145 int deep; 3146 { 3147 char_u *arg = argstart; 3148 char_u *name_end; 3149 int error = FALSE; 3150 lval_T lv; 3151 3152 do 3153 { 3154 /* Parse the name and find the end. */ 3155 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3156 FNE_CHECK_START); 3157 if (lv.ll_name == NULL) 3158 error = TRUE; /* error but continue parsing */ 3159 if (name_end == NULL || (!vim_iswhite(*name_end) 3160 && !ends_excmd(*name_end))) 3161 { 3162 if (name_end != NULL) 3163 { 3164 emsg_severe = TRUE; 3165 EMSG(_(e_trailing)); 3166 } 3167 if (!(eap->skip || error)) 3168 clear_lval(&lv); 3169 break; 3170 } 3171 3172 if (!error && !eap->skip) 3173 { 3174 if (eap->cmdidx == CMD_unlet) 3175 { 3176 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3177 error = TRUE; 3178 } 3179 else 3180 { 3181 if (do_lock_var(&lv, name_end, deep, 3182 eap->cmdidx == CMD_lockvar) == FAIL) 3183 error = TRUE; 3184 } 3185 } 3186 3187 if (!eap->skip) 3188 clear_lval(&lv); 3189 3190 arg = skipwhite(name_end); 3191 } while (!ends_excmd(*arg)); 3192 3193 eap->nextcmd = check_nextcmd(arg); 3194 } 3195 3196 static int 3197 do_unlet_var(lp, name_end, forceit) 3198 lval_T *lp; 3199 char_u *name_end; 3200 int forceit; 3201 { 3202 int ret = OK; 3203 int cc; 3204 3205 if (lp->ll_tv == NULL) 3206 { 3207 cc = *name_end; 3208 *name_end = NUL; 3209 3210 /* Normal name or expanded name. */ 3211 if (check_changedtick(lp->ll_name)) 3212 ret = FAIL; 3213 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3214 ret = FAIL; 3215 *name_end = cc; 3216 } 3217 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3218 return FAIL; 3219 else if (lp->ll_range) 3220 { 3221 listitem_T *li; 3222 3223 /* Delete a range of List items. */ 3224 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3225 { 3226 li = lp->ll_li->li_next; 3227 listitem_remove(lp->ll_list, lp->ll_li); 3228 lp->ll_li = li; 3229 ++lp->ll_n1; 3230 } 3231 } 3232 else 3233 { 3234 if (lp->ll_list != NULL) 3235 /* unlet a List item. */ 3236 listitem_remove(lp->ll_list, lp->ll_li); 3237 else 3238 /* unlet a Dictionary item. */ 3239 dictitem_remove(lp->ll_dict, lp->ll_di); 3240 } 3241 3242 return ret; 3243 } 3244 3245 /* 3246 * "unlet" a variable. Return OK if it existed, FAIL if not. 3247 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3248 */ 3249 int 3250 do_unlet(name, forceit) 3251 char_u *name; 3252 int forceit; 3253 { 3254 hashtab_T *ht; 3255 hashitem_T *hi; 3256 char_u *varname; 3257 3258 ht = find_var_ht(name, &varname); 3259 if (ht != NULL && *varname != NUL) 3260 { 3261 hi = hash_find(ht, varname); 3262 if (!HASHITEM_EMPTY(hi)) 3263 { 3264 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3265 return FAIL; 3266 delete_var(ht, hi); 3267 return OK; 3268 } 3269 } 3270 if (forceit) 3271 return OK; 3272 EMSG2(_("E108: No such variable: \"%s\""), name); 3273 return FAIL; 3274 } 3275 3276 /* 3277 * Lock or unlock variable indicated by "lp". 3278 * "deep" is the levels to go (-1 for unlimited); 3279 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3280 */ 3281 static int 3282 do_lock_var(lp, name_end, deep, lock) 3283 lval_T *lp; 3284 char_u *name_end; 3285 int deep; 3286 int lock; 3287 { 3288 int ret = OK; 3289 int cc; 3290 dictitem_T *di; 3291 3292 if (deep == 0) /* nothing to do */ 3293 return OK; 3294 3295 if (lp->ll_tv == NULL) 3296 { 3297 cc = *name_end; 3298 *name_end = NUL; 3299 3300 /* Normal name or expanded name. */ 3301 if (check_changedtick(lp->ll_name)) 3302 ret = FAIL; 3303 else 3304 { 3305 di = find_var(lp->ll_name, NULL); 3306 if (di == NULL) 3307 ret = FAIL; 3308 else 3309 { 3310 if (lock) 3311 di->di_flags |= DI_FLAGS_LOCK; 3312 else 3313 di->di_flags &= ~DI_FLAGS_LOCK; 3314 item_lock(&di->di_tv, deep, lock); 3315 } 3316 } 3317 *name_end = cc; 3318 } 3319 else if (lp->ll_range) 3320 { 3321 listitem_T *li = lp->ll_li; 3322 3323 /* (un)lock a range of List items. */ 3324 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3325 { 3326 item_lock(&li->li_tv, deep, lock); 3327 li = li->li_next; 3328 ++lp->ll_n1; 3329 } 3330 } 3331 else if (lp->ll_list != NULL) 3332 /* (un)lock a List item. */ 3333 item_lock(&lp->ll_li->li_tv, deep, lock); 3334 else 3335 /* un(lock) a Dictionary item. */ 3336 item_lock(&lp->ll_di->di_tv, deep, lock); 3337 3338 return ret; 3339 } 3340 3341 /* 3342 * Lock or unlock an item. "deep" is nr of levels to go. 3343 */ 3344 static void 3345 item_lock(tv, deep, lock) 3346 typval_T *tv; 3347 int deep; 3348 int lock; 3349 { 3350 static int recurse = 0; 3351 list_T *l; 3352 listitem_T *li; 3353 dict_T *d; 3354 hashitem_T *hi; 3355 int todo; 3356 3357 if (recurse >= DICT_MAXNEST) 3358 { 3359 EMSG(_("E743: variable nested too deep for (un)lock")); 3360 return; 3361 } 3362 if (deep == 0) 3363 return; 3364 ++recurse; 3365 3366 /* lock/unlock the item itself */ 3367 if (lock) 3368 tv->v_lock |= VAR_LOCKED; 3369 else 3370 tv->v_lock &= ~VAR_LOCKED; 3371 3372 switch (tv->v_type) 3373 { 3374 case VAR_LIST: 3375 if ((l = tv->vval.v_list) != NULL) 3376 { 3377 if (lock) 3378 l->lv_lock |= VAR_LOCKED; 3379 else 3380 l->lv_lock &= ~VAR_LOCKED; 3381 if (deep < 0 || deep > 1) 3382 /* recursive: lock/unlock the items the List contains */ 3383 for (li = l->lv_first; li != NULL; li = li->li_next) 3384 item_lock(&li->li_tv, deep - 1, lock); 3385 } 3386 break; 3387 case VAR_DICT: 3388 if ((d = tv->vval.v_dict) != NULL) 3389 { 3390 if (lock) 3391 d->dv_lock |= VAR_LOCKED; 3392 else 3393 d->dv_lock &= ~VAR_LOCKED; 3394 if (deep < 0 || deep > 1) 3395 { 3396 /* recursive: lock/unlock the items the List contains */ 3397 todo = d->dv_hashtab.ht_used; 3398 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3399 { 3400 if (!HASHITEM_EMPTY(hi)) 3401 { 3402 --todo; 3403 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3404 } 3405 } 3406 } 3407 } 3408 } 3409 --recurse; 3410 } 3411 3412 /* 3413 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3414 * it refers to a List or Dictionary that is locked. 3415 */ 3416 static int 3417 tv_islocked(tv) 3418 typval_T *tv; 3419 { 3420 return (tv->v_lock & VAR_LOCKED) 3421 || (tv->v_type == VAR_LIST 3422 && tv->vval.v_list != NULL 3423 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3424 || (tv->v_type == VAR_DICT 3425 && tv->vval.v_dict != NULL 3426 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3427 } 3428 3429 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3430 /* 3431 * Delete all "menutrans_" variables. 3432 */ 3433 void 3434 del_menutrans_vars() 3435 { 3436 hashitem_T *hi; 3437 int todo; 3438 3439 hash_lock(&globvarht); 3440 todo = globvarht.ht_used; 3441 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3442 { 3443 if (!HASHITEM_EMPTY(hi)) 3444 { 3445 --todo; 3446 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3447 delete_var(&globvarht, hi); 3448 } 3449 } 3450 hash_unlock(&globvarht); 3451 } 3452 #endif 3453 3454 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3455 3456 /* 3457 * Local string buffer for the next two functions to store a variable name 3458 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3459 * get_user_var_name(). 3460 */ 3461 3462 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3463 3464 static char_u *varnamebuf = NULL; 3465 static int varnamebuflen = 0; 3466 3467 /* 3468 * Function to concatenate a prefix and a variable name. 3469 */ 3470 static char_u * 3471 cat_prefix_varname(prefix, name) 3472 int prefix; 3473 char_u *name; 3474 { 3475 int len; 3476 3477 len = (int)STRLEN(name) + 3; 3478 if (len > varnamebuflen) 3479 { 3480 vim_free(varnamebuf); 3481 len += 10; /* some additional space */ 3482 varnamebuf = alloc(len); 3483 if (varnamebuf == NULL) 3484 { 3485 varnamebuflen = 0; 3486 return NULL; 3487 } 3488 varnamebuflen = len; 3489 } 3490 *varnamebuf = prefix; 3491 varnamebuf[1] = ':'; 3492 STRCPY(varnamebuf + 2, name); 3493 return varnamebuf; 3494 } 3495 3496 /* 3497 * Function given to ExpandGeneric() to obtain the list of user defined 3498 * (global/buffer/window/built-in) variable names. 3499 */ 3500 /*ARGSUSED*/ 3501 char_u * 3502 get_user_var_name(xp, idx) 3503 expand_T *xp; 3504 int idx; 3505 { 3506 static long_u gdone; 3507 static long_u bdone; 3508 static long_u wdone; 3509 static int vidx; 3510 static hashitem_T *hi; 3511 hashtab_T *ht; 3512 3513 if (idx == 0) 3514 gdone = bdone = wdone = vidx = 0; 3515 3516 /* Global variables */ 3517 if (gdone < globvarht.ht_used) 3518 { 3519 if (gdone++ == 0) 3520 hi = globvarht.ht_array; 3521 else 3522 ++hi; 3523 while (HASHITEM_EMPTY(hi)) 3524 ++hi; 3525 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3526 return cat_prefix_varname('g', hi->hi_key); 3527 return hi->hi_key; 3528 } 3529 3530 /* b: variables */ 3531 ht = &curbuf->b_vars.dv_hashtab; 3532 if (bdone < ht->ht_used) 3533 { 3534 if (bdone++ == 0) 3535 hi = ht->ht_array; 3536 else 3537 ++hi; 3538 while (HASHITEM_EMPTY(hi)) 3539 ++hi; 3540 return cat_prefix_varname('b', hi->hi_key); 3541 } 3542 if (bdone == ht->ht_used) 3543 { 3544 ++bdone; 3545 return (char_u *)"b:changedtick"; 3546 } 3547 3548 /* w: variables */ 3549 ht = &curwin->w_vars.dv_hashtab; 3550 if (wdone < ht->ht_used) 3551 { 3552 if (wdone++ == 0) 3553 hi = ht->ht_array; 3554 else 3555 ++hi; 3556 while (HASHITEM_EMPTY(hi)) 3557 ++hi; 3558 return cat_prefix_varname('w', hi->hi_key); 3559 } 3560 3561 /* v: variables */ 3562 if (vidx < VV_LEN) 3563 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3564 3565 vim_free(varnamebuf); 3566 varnamebuf = NULL; 3567 varnamebuflen = 0; 3568 return NULL; 3569 } 3570 3571 #endif /* FEAT_CMDL_COMPL */ 3572 3573 /* 3574 * types for expressions. 3575 */ 3576 typedef enum 3577 { 3578 TYPE_UNKNOWN = 0 3579 , TYPE_EQUAL /* == */ 3580 , TYPE_NEQUAL /* != */ 3581 , TYPE_GREATER /* > */ 3582 , TYPE_GEQUAL /* >= */ 3583 , TYPE_SMALLER /* < */ 3584 , TYPE_SEQUAL /* <= */ 3585 , TYPE_MATCH /* =~ */ 3586 , TYPE_NOMATCH /* !~ */ 3587 } exptype_T; 3588 3589 /* 3590 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3591 * executed. The function may return OK, but the rettv will be of type 3592 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3593 */ 3594 3595 /* 3596 * Handle zero level expression. 3597 * This calls eval1() and handles error message and nextcmd. 3598 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3599 * Note: "rettv.v_lock" is not set. 3600 * Return OK or FAIL. 3601 */ 3602 static int 3603 eval0(arg, rettv, nextcmd, evaluate) 3604 char_u *arg; 3605 typval_T *rettv; 3606 char_u **nextcmd; 3607 int evaluate; 3608 { 3609 int ret; 3610 char_u *p; 3611 3612 p = skipwhite(arg); 3613 ret = eval1(&p, rettv, evaluate); 3614 if (ret == FAIL || !ends_excmd(*p)) 3615 { 3616 if (ret != FAIL) 3617 clear_tv(rettv); 3618 /* 3619 * Report the invalid expression unless the expression evaluation has 3620 * been cancelled due to an aborting error, an interrupt, or an 3621 * exception. 3622 */ 3623 if (!aborting()) 3624 EMSG2(_(e_invexpr2), arg); 3625 ret = FAIL; 3626 } 3627 if (nextcmd != NULL) 3628 *nextcmd = check_nextcmd(p); 3629 3630 return ret; 3631 } 3632 3633 /* 3634 * Handle top level expression: 3635 * expr1 ? expr0 : expr0 3636 * 3637 * "arg" must point to the first non-white of the expression. 3638 * "arg" is advanced to the next non-white after the recognized expression. 3639 * 3640 * Note: "rettv.v_lock" is not set. 3641 * 3642 * Return OK or FAIL. 3643 */ 3644 static int 3645 eval1(arg, rettv, evaluate) 3646 char_u **arg; 3647 typval_T *rettv; 3648 int evaluate; 3649 { 3650 int result; 3651 typval_T var2; 3652 3653 /* 3654 * Get the first variable. 3655 */ 3656 if (eval2(arg, rettv, evaluate) == FAIL) 3657 return FAIL; 3658 3659 if ((*arg)[0] == '?') 3660 { 3661 result = FALSE; 3662 if (evaluate) 3663 { 3664 int error = FALSE; 3665 3666 if (get_tv_number_chk(rettv, &error) != 0) 3667 result = TRUE; 3668 clear_tv(rettv); 3669 if (error) 3670 return FAIL; 3671 } 3672 3673 /* 3674 * Get the second variable. 3675 */ 3676 *arg = skipwhite(*arg + 1); 3677 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3678 return FAIL; 3679 3680 /* 3681 * Check for the ":". 3682 */ 3683 if ((*arg)[0] != ':') 3684 { 3685 EMSG(_("E109: Missing ':' after '?'")); 3686 if (evaluate && result) 3687 clear_tv(rettv); 3688 return FAIL; 3689 } 3690 3691 /* 3692 * Get the third variable. 3693 */ 3694 *arg = skipwhite(*arg + 1); 3695 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3696 { 3697 if (evaluate && result) 3698 clear_tv(rettv); 3699 return FAIL; 3700 } 3701 if (evaluate && !result) 3702 *rettv = var2; 3703 } 3704 3705 return OK; 3706 } 3707 3708 /* 3709 * Handle first level expression: 3710 * expr2 || expr2 || expr2 logical OR 3711 * 3712 * "arg" must point to the first non-white of the expression. 3713 * "arg" is advanced to the next non-white after the recognized expression. 3714 * 3715 * Return OK or FAIL. 3716 */ 3717 static int 3718 eval2(arg, rettv, evaluate) 3719 char_u **arg; 3720 typval_T *rettv; 3721 int evaluate; 3722 { 3723 typval_T var2; 3724 long result; 3725 int first; 3726 int error = FALSE; 3727 3728 /* 3729 * Get the first variable. 3730 */ 3731 if (eval3(arg, rettv, evaluate) == FAIL) 3732 return FAIL; 3733 3734 /* 3735 * Repeat until there is no following "||". 3736 */ 3737 first = TRUE; 3738 result = FALSE; 3739 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3740 { 3741 if (evaluate && first) 3742 { 3743 if (get_tv_number_chk(rettv, &error) != 0) 3744 result = TRUE; 3745 clear_tv(rettv); 3746 if (error) 3747 return FAIL; 3748 first = FALSE; 3749 } 3750 3751 /* 3752 * Get the second variable. 3753 */ 3754 *arg = skipwhite(*arg + 2); 3755 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3756 return FAIL; 3757 3758 /* 3759 * Compute the result. 3760 */ 3761 if (evaluate && !result) 3762 { 3763 if (get_tv_number_chk(&var2, &error) != 0) 3764 result = TRUE; 3765 clear_tv(&var2); 3766 if (error) 3767 return FAIL; 3768 } 3769 if (evaluate) 3770 { 3771 rettv->v_type = VAR_NUMBER; 3772 rettv->vval.v_number = result; 3773 } 3774 } 3775 3776 return OK; 3777 } 3778 3779 /* 3780 * Handle second level expression: 3781 * expr3 && expr3 && expr3 logical AND 3782 * 3783 * "arg" must point to the first non-white of the expression. 3784 * "arg" is advanced to the next non-white after the recognized expression. 3785 * 3786 * Return OK or FAIL. 3787 */ 3788 static int 3789 eval3(arg, rettv, evaluate) 3790 char_u **arg; 3791 typval_T *rettv; 3792 int evaluate; 3793 { 3794 typval_T var2; 3795 long result; 3796 int first; 3797 int error = FALSE; 3798 3799 /* 3800 * Get the first variable. 3801 */ 3802 if (eval4(arg, rettv, evaluate) == FAIL) 3803 return FAIL; 3804 3805 /* 3806 * Repeat until there is no following "&&". 3807 */ 3808 first = TRUE; 3809 result = TRUE; 3810 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3811 { 3812 if (evaluate && first) 3813 { 3814 if (get_tv_number_chk(rettv, &error) == 0) 3815 result = FALSE; 3816 clear_tv(rettv); 3817 if (error) 3818 return FAIL; 3819 first = FALSE; 3820 } 3821 3822 /* 3823 * Get the second variable. 3824 */ 3825 *arg = skipwhite(*arg + 2); 3826 if (eval4(arg, &var2, evaluate && result) == FAIL) 3827 return FAIL; 3828 3829 /* 3830 * Compute the result. 3831 */ 3832 if (evaluate && result) 3833 { 3834 if (get_tv_number_chk(&var2, &error) == 0) 3835 result = FALSE; 3836 clear_tv(&var2); 3837 if (error) 3838 return FAIL; 3839 } 3840 if (evaluate) 3841 { 3842 rettv->v_type = VAR_NUMBER; 3843 rettv->vval.v_number = result; 3844 } 3845 } 3846 3847 return OK; 3848 } 3849 3850 /* 3851 * Handle third level expression: 3852 * var1 == var2 3853 * var1 =~ var2 3854 * var1 != var2 3855 * var1 !~ var2 3856 * var1 > var2 3857 * var1 >= var2 3858 * var1 < var2 3859 * var1 <= var2 3860 * var1 is var2 3861 * var1 isnot var2 3862 * 3863 * "arg" must point to the first non-white of the expression. 3864 * "arg" is advanced to the next non-white after the recognized expression. 3865 * 3866 * Return OK or FAIL. 3867 */ 3868 static int 3869 eval4(arg, rettv, evaluate) 3870 char_u **arg; 3871 typval_T *rettv; 3872 int evaluate; 3873 { 3874 typval_T var2; 3875 char_u *p; 3876 int i; 3877 exptype_T type = TYPE_UNKNOWN; 3878 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3879 int len = 2; 3880 long n1, n2; 3881 char_u *s1, *s2; 3882 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3883 regmatch_T regmatch; 3884 int ic; 3885 char_u *save_cpo; 3886 3887 /* 3888 * Get the first variable. 3889 */ 3890 if (eval5(arg, rettv, evaluate) == FAIL) 3891 return FAIL; 3892 3893 p = *arg; 3894 switch (p[0]) 3895 { 3896 case '=': if (p[1] == '=') 3897 type = TYPE_EQUAL; 3898 else if (p[1] == '~') 3899 type = TYPE_MATCH; 3900 break; 3901 case '!': if (p[1] == '=') 3902 type = TYPE_NEQUAL; 3903 else if (p[1] == '~') 3904 type = TYPE_NOMATCH; 3905 break; 3906 case '>': if (p[1] != '=') 3907 { 3908 type = TYPE_GREATER; 3909 len = 1; 3910 } 3911 else 3912 type = TYPE_GEQUAL; 3913 break; 3914 case '<': if (p[1] != '=') 3915 { 3916 type = TYPE_SMALLER; 3917 len = 1; 3918 } 3919 else 3920 type = TYPE_SEQUAL; 3921 break; 3922 case 'i': if (p[1] == 's') 3923 { 3924 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3925 len = 5; 3926 if (!vim_isIDc(p[len])) 3927 { 3928 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3929 type_is = TRUE; 3930 } 3931 } 3932 break; 3933 } 3934 3935 /* 3936 * If there is a comparitive operator, use it. 3937 */ 3938 if (type != TYPE_UNKNOWN) 3939 { 3940 /* extra question mark appended: ignore case */ 3941 if (p[len] == '?') 3942 { 3943 ic = TRUE; 3944 ++len; 3945 } 3946 /* extra '#' appended: match case */ 3947 else if (p[len] == '#') 3948 { 3949 ic = FALSE; 3950 ++len; 3951 } 3952 /* nothing appened: use 'ignorecase' */ 3953 else 3954 ic = p_ic; 3955 3956 /* 3957 * Get the second variable. 3958 */ 3959 *arg = skipwhite(p + len); 3960 if (eval5(arg, &var2, evaluate) == FAIL) 3961 { 3962 clear_tv(rettv); 3963 return FAIL; 3964 } 3965 3966 if (evaluate) 3967 { 3968 if (type_is && rettv->v_type != var2.v_type) 3969 { 3970 /* For "is" a different type always means FALSE, for "notis" 3971 * it means TRUE. */ 3972 n1 = (type == TYPE_NEQUAL); 3973 } 3974 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3975 { 3976 if (type_is) 3977 { 3978 n1 = (rettv->v_type == var2.v_type 3979 && rettv->vval.v_list == var2.vval.v_list); 3980 if (type == TYPE_NEQUAL) 3981 n1 = !n1; 3982 } 3983 else if (rettv->v_type != var2.v_type 3984 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3985 { 3986 if (rettv->v_type != var2.v_type) 3987 EMSG(_("E691: Can only compare List with List")); 3988 else 3989 EMSG(_("E692: Invalid operation for Lists")); 3990 clear_tv(rettv); 3991 clear_tv(&var2); 3992 return FAIL; 3993 } 3994 else 3995 { 3996 /* Compare two Lists for being equal or unequal. */ 3997 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3998 if (type == TYPE_NEQUAL) 3999 n1 = !n1; 4000 } 4001 } 4002 4003 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4004 { 4005 if (type_is) 4006 { 4007 n1 = (rettv->v_type == var2.v_type 4008 && rettv->vval.v_dict == var2.vval.v_dict); 4009 if (type == TYPE_NEQUAL) 4010 n1 = !n1; 4011 } 4012 else if (rettv->v_type != var2.v_type 4013 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4014 { 4015 if (rettv->v_type != var2.v_type) 4016 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4017 else 4018 EMSG(_("E736: Invalid operation for Dictionary")); 4019 clear_tv(rettv); 4020 clear_tv(&var2); 4021 return FAIL; 4022 } 4023 else 4024 { 4025 /* Compare two Dictionaries for being equal or unequal. */ 4026 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4027 if (type == TYPE_NEQUAL) 4028 n1 = !n1; 4029 } 4030 } 4031 4032 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4033 { 4034 if (rettv->v_type != var2.v_type 4035 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4036 { 4037 if (rettv->v_type != var2.v_type) 4038 EMSG(_("E693: Can only compare Funcref with Funcref")); 4039 else 4040 EMSG(_("E694: Invalid operation for Funcrefs")); 4041 clear_tv(rettv); 4042 clear_tv(&var2); 4043 return FAIL; 4044 } 4045 else 4046 { 4047 /* Compare two Funcrefs for being equal or unequal. */ 4048 if (rettv->vval.v_string == NULL 4049 || var2.vval.v_string == NULL) 4050 n1 = FALSE; 4051 else 4052 n1 = STRCMP(rettv->vval.v_string, 4053 var2.vval.v_string) == 0; 4054 if (type == TYPE_NEQUAL) 4055 n1 = !n1; 4056 } 4057 } 4058 4059 /* 4060 * If one of the two variables is a number, compare as a number. 4061 * When using "=~" or "!~", always compare as string. 4062 */ 4063 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4064 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4065 { 4066 n1 = get_tv_number(rettv); 4067 n2 = get_tv_number(&var2); 4068 switch (type) 4069 { 4070 case TYPE_EQUAL: n1 = (n1 == n2); break; 4071 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4072 case TYPE_GREATER: n1 = (n1 > n2); break; 4073 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4074 case TYPE_SMALLER: n1 = (n1 < n2); break; 4075 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4076 case TYPE_UNKNOWN: 4077 case TYPE_MATCH: 4078 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4079 } 4080 } 4081 else 4082 { 4083 s1 = get_tv_string_buf(rettv, buf1); 4084 s2 = get_tv_string_buf(&var2, buf2); 4085 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4086 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4087 else 4088 i = 0; 4089 n1 = FALSE; 4090 switch (type) 4091 { 4092 case TYPE_EQUAL: n1 = (i == 0); break; 4093 case TYPE_NEQUAL: n1 = (i != 0); break; 4094 case TYPE_GREATER: n1 = (i > 0); break; 4095 case TYPE_GEQUAL: n1 = (i >= 0); break; 4096 case TYPE_SMALLER: n1 = (i < 0); break; 4097 case TYPE_SEQUAL: n1 = (i <= 0); break; 4098 4099 case TYPE_MATCH: 4100 case TYPE_NOMATCH: 4101 /* avoid 'l' flag in 'cpoptions' */ 4102 save_cpo = p_cpo; 4103 p_cpo = (char_u *)""; 4104 regmatch.regprog = vim_regcomp(s2, 4105 RE_MAGIC + RE_STRING); 4106 regmatch.rm_ic = ic; 4107 if (regmatch.regprog != NULL) 4108 { 4109 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4110 vim_free(regmatch.regprog); 4111 if (type == TYPE_NOMATCH) 4112 n1 = !n1; 4113 } 4114 p_cpo = save_cpo; 4115 break; 4116 4117 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4118 } 4119 } 4120 clear_tv(rettv); 4121 clear_tv(&var2); 4122 rettv->v_type = VAR_NUMBER; 4123 rettv->vval.v_number = n1; 4124 } 4125 } 4126 4127 return OK; 4128 } 4129 4130 /* 4131 * Handle fourth level expression: 4132 * + number addition 4133 * - number subtraction 4134 * . string concatenation 4135 * 4136 * "arg" must point to the first non-white of the expression. 4137 * "arg" is advanced to the next non-white after the recognized expression. 4138 * 4139 * Return OK or FAIL. 4140 */ 4141 static int 4142 eval5(arg, rettv, evaluate) 4143 char_u **arg; 4144 typval_T *rettv; 4145 int evaluate; 4146 { 4147 typval_T var2; 4148 typval_T var3; 4149 int op; 4150 long n1, n2; 4151 char_u *s1, *s2; 4152 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4153 char_u *p; 4154 4155 /* 4156 * Get the first variable. 4157 */ 4158 if (eval6(arg, rettv, evaluate) == FAIL) 4159 return FAIL; 4160 4161 /* 4162 * Repeat computing, until no '+', '-' or '.' is following. 4163 */ 4164 for (;;) 4165 { 4166 op = **arg; 4167 if (op != '+' && op != '-' && op != '.') 4168 break; 4169 4170 if (op != '+' || rettv->v_type != VAR_LIST) 4171 { 4172 /* For "list + ...", an illegal use of the first operand as 4173 * a number cannot be determined before evaluating the 2nd 4174 * operand: if this is also a list, all is ok. 4175 * For "something . ...", "something - ..." or "non-list + ...", 4176 * we know that the first operand needs to be a string or number 4177 * without evaluating the 2nd operand. So check before to avoid 4178 * side effects after an error. */ 4179 if (evaluate && get_tv_string_chk(rettv) == NULL) 4180 { 4181 clear_tv(rettv); 4182 return FAIL; 4183 } 4184 } 4185 4186 /* 4187 * Get the second variable. 4188 */ 4189 *arg = skipwhite(*arg + 1); 4190 if (eval6(arg, &var2, evaluate) == FAIL) 4191 { 4192 clear_tv(rettv); 4193 return FAIL; 4194 } 4195 4196 if (evaluate) 4197 { 4198 /* 4199 * Compute the result. 4200 */ 4201 if (op == '.') 4202 { 4203 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4204 s2 = get_tv_string_buf_chk(&var2, buf2); 4205 if (s2 == NULL) /* type error ? */ 4206 { 4207 clear_tv(rettv); 4208 clear_tv(&var2); 4209 return FAIL; 4210 } 4211 p = concat_str(s1, s2); 4212 clear_tv(rettv); 4213 rettv->v_type = VAR_STRING; 4214 rettv->vval.v_string = p; 4215 } 4216 else if (op == '+' && rettv->v_type == VAR_LIST 4217 && var2.v_type == VAR_LIST) 4218 { 4219 /* concatenate Lists */ 4220 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4221 &var3) == FAIL) 4222 { 4223 clear_tv(rettv); 4224 clear_tv(&var2); 4225 return FAIL; 4226 } 4227 clear_tv(rettv); 4228 *rettv = var3; 4229 } 4230 else 4231 { 4232 int error = FALSE; 4233 4234 n1 = get_tv_number_chk(rettv, &error); 4235 if (error) 4236 { 4237 /* This can only happen for "list + non-list". 4238 * For "non-list + ..." or "something - ...", we returned 4239 * before evaluating the 2nd operand. */ 4240 clear_tv(rettv); 4241 return FAIL; 4242 } 4243 n2 = get_tv_number_chk(&var2, &error); 4244 if (error) 4245 { 4246 clear_tv(rettv); 4247 clear_tv(&var2); 4248 return FAIL; 4249 } 4250 clear_tv(rettv); 4251 if (op == '+') 4252 n1 = n1 + n2; 4253 else 4254 n1 = n1 - n2; 4255 rettv->v_type = VAR_NUMBER; 4256 rettv->vval.v_number = n1; 4257 } 4258 clear_tv(&var2); 4259 } 4260 } 4261 return OK; 4262 } 4263 4264 /* 4265 * Handle fifth level expression: 4266 * * number multiplication 4267 * / number division 4268 * % number modulo 4269 * 4270 * "arg" must point to the first non-white of the expression. 4271 * "arg" is advanced to the next non-white after the recognized expression. 4272 * 4273 * Return OK or FAIL. 4274 */ 4275 static int 4276 eval6(arg, rettv, evaluate) 4277 char_u **arg; 4278 typval_T *rettv; 4279 int evaluate; 4280 { 4281 typval_T var2; 4282 int op; 4283 long n1, n2; 4284 int error = FALSE; 4285 4286 /* 4287 * Get the first variable. 4288 */ 4289 if (eval7(arg, rettv, evaluate) == FAIL) 4290 return FAIL; 4291 4292 /* 4293 * Repeat computing, until no '*', '/' or '%' is following. 4294 */ 4295 for (;;) 4296 { 4297 op = **arg; 4298 if (op != '*' && op != '/' && op != '%') 4299 break; 4300 4301 if (evaluate) 4302 { 4303 n1 = get_tv_number_chk(rettv, &error); 4304 clear_tv(rettv); 4305 if (error) 4306 return FAIL; 4307 } 4308 else 4309 n1 = 0; 4310 4311 /* 4312 * Get the second variable. 4313 */ 4314 *arg = skipwhite(*arg + 1); 4315 if (eval7(arg, &var2, evaluate) == FAIL) 4316 return FAIL; 4317 4318 if (evaluate) 4319 { 4320 n2 = get_tv_number_chk(&var2, &error); 4321 clear_tv(&var2); 4322 if (error) 4323 return FAIL; 4324 4325 /* 4326 * Compute the result. 4327 */ 4328 if (op == '*') 4329 n1 = n1 * n2; 4330 else if (op == '/') 4331 { 4332 if (n2 == 0) /* give an error message? */ 4333 n1 = 0x7fffffffL; 4334 else 4335 n1 = n1 / n2; 4336 } 4337 else 4338 { 4339 if (n2 == 0) /* give an error message? */ 4340 n1 = 0; 4341 else 4342 n1 = n1 % n2; 4343 } 4344 rettv->v_type = VAR_NUMBER; 4345 rettv->vval.v_number = n1; 4346 } 4347 } 4348 4349 return OK; 4350 } 4351 4352 /* 4353 * Handle sixth level expression: 4354 * number number constant 4355 * "string" string contstant 4356 * 'string' literal string contstant 4357 * &option-name option value 4358 * @r register contents 4359 * identifier variable value 4360 * function() function call 4361 * $VAR environment variable 4362 * (expression) nested expression 4363 * [expr, expr] List 4364 * {key: val, key: val} Dictionary 4365 * 4366 * Also handle: 4367 * ! in front logical NOT 4368 * - in front unary minus 4369 * + in front unary plus (ignored) 4370 * trailing [] subscript in String or List 4371 * trailing .name entry in Dictionary 4372 * 4373 * "arg" must point to the first non-white of the expression. 4374 * "arg" is advanced to the next non-white after the recognized expression. 4375 * 4376 * Return OK or FAIL. 4377 */ 4378 static int 4379 eval7(arg, rettv, evaluate) 4380 char_u **arg; 4381 typval_T *rettv; 4382 int evaluate; 4383 { 4384 long n; 4385 int len; 4386 char_u *s; 4387 int val; 4388 char_u *start_leader, *end_leader; 4389 int ret = OK; 4390 char_u *alias; 4391 4392 /* 4393 * Initialise variable so that clear_tv() can't mistake this for a 4394 * string and free a string that isn't there. 4395 */ 4396 rettv->v_type = VAR_UNKNOWN; 4397 4398 /* 4399 * Skip '!' and '-' characters. They are handled later. 4400 */ 4401 start_leader = *arg; 4402 while (**arg == '!' || **arg == '-' || **arg == '+') 4403 *arg = skipwhite(*arg + 1); 4404 end_leader = *arg; 4405 4406 switch (**arg) 4407 { 4408 /* 4409 * Number constant. 4410 */ 4411 case '0': 4412 case '1': 4413 case '2': 4414 case '3': 4415 case '4': 4416 case '5': 4417 case '6': 4418 case '7': 4419 case '8': 4420 case '9': 4421 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4422 *arg += len; 4423 if (evaluate) 4424 { 4425 rettv->v_type = VAR_NUMBER; 4426 rettv->vval.v_number = n; 4427 } 4428 break; 4429 4430 /* 4431 * String constant: "string". 4432 */ 4433 case '"': ret = get_string_tv(arg, rettv, evaluate); 4434 break; 4435 4436 /* 4437 * Literal string constant: 'str''ing'. 4438 */ 4439 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4440 break; 4441 4442 /* 4443 * List: [expr, expr] 4444 */ 4445 case '[': ret = get_list_tv(arg, rettv, evaluate); 4446 break; 4447 4448 /* 4449 * Dictionary: {key: val, key: val} 4450 */ 4451 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4452 break; 4453 4454 /* 4455 * Option value: &name 4456 */ 4457 case '&': ret = get_option_tv(arg, rettv, evaluate); 4458 break; 4459 4460 /* 4461 * Environment variable: $VAR. 4462 */ 4463 case '$': ret = get_env_tv(arg, rettv, evaluate); 4464 break; 4465 4466 /* 4467 * Register contents: @r. 4468 */ 4469 case '@': ++*arg; 4470 if (evaluate) 4471 { 4472 rettv->v_type = VAR_STRING; 4473 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4474 } 4475 if (**arg != NUL) 4476 ++*arg; 4477 break; 4478 4479 /* 4480 * nested expression: (expression). 4481 */ 4482 case '(': *arg = skipwhite(*arg + 1); 4483 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4484 if (**arg == ')') 4485 ++*arg; 4486 else if (ret == OK) 4487 { 4488 EMSG(_("E110: Missing ')'")); 4489 clear_tv(rettv); 4490 ret = FAIL; 4491 } 4492 break; 4493 4494 default: ret = NOTDONE; 4495 break; 4496 } 4497 4498 if (ret == NOTDONE) 4499 { 4500 /* 4501 * Must be a variable or function name. 4502 * Can also be a curly-braces kind of name: {expr}. 4503 */ 4504 s = *arg; 4505 len = get_name_len(arg, &alias, evaluate, TRUE); 4506 if (alias != NULL) 4507 s = alias; 4508 4509 if (len <= 0) 4510 ret = FAIL; 4511 else 4512 { 4513 if (**arg == '(') /* recursive! */ 4514 { 4515 /* If "s" is the name of a variable of type VAR_FUNC 4516 * use its contents. */ 4517 s = deref_func_name(s, &len); 4518 4519 /* Invoke the function. */ 4520 ret = get_func_tv(s, len, rettv, arg, 4521 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4522 &len, evaluate, NULL); 4523 /* Stop the expression evaluation when immediately 4524 * aborting on error, or when an interrupt occurred or 4525 * an exception was thrown but not caught. */ 4526 if (aborting()) 4527 { 4528 if (ret == OK) 4529 clear_tv(rettv); 4530 ret = FAIL; 4531 } 4532 } 4533 else if (evaluate) 4534 ret = get_var_tv(s, len, rettv, TRUE); 4535 else 4536 ret = OK; 4537 } 4538 4539 if (alias != NULL) 4540 vim_free(alias); 4541 } 4542 4543 *arg = skipwhite(*arg); 4544 4545 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4546 * expr(expr). */ 4547 if (ret == OK) 4548 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4549 4550 /* 4551 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4552 */ 4553 if (ret == OK && evaluate && end_leader > start_leader) 4554 { 4555 int error = FALSE; 4556 4557 val = get_tv_number_chk(rettv, &error); 4558 if (error) 4559 { 4560 clear_tv(rettv); 4561 ret = FAIL; 4562 } 4563 else 4564 { 4565 while (end_leader > start_leader) 4566 { 4567 --end_leader; 4568 if (*end_leader == '!') 4569 val = !val; 4570 else if (*end_leader == '-') 4571 val = -val; 4572 } 4573 clear_tv(rettv); 4574 rettv->v_type = VAR_NUMBER; 4575 rettv->vval.v_number = val; 4576 } 4577 } 4578 4579 return ret; 4580 } 4581 4582 /* 4583 * Evaluate an "[expr]" or "[expr:expr]" index. 4584 * "*arg" points to the '['. 4585 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4586 */ 4587 static int 4588 eval_index(arg, rettv, evaluate, verbose) 4589 char_u **arg; 4590 typval_T *rettv; 4591 int evaluate; 4592 int verbose; /* give error messages */ 4593 { 4594 int empty1 = FALSE, empty2 = FALSE; 4595 typval_T var1, var2; 4596 long n1, n2 = 0; 4597 long len = -1; 4598 int range = FALSE; 4599 char_u *s; 4600 char_u *key = NULL; 4601 4602 if (rettv->v_type == VAR_FUNC) 4603 { 4604 if (verbose) 4605 EMSG(_("E695: Cannot index a Funcref")); 4606 return FAIL; 4607 } 4608 4609 if (**arg == '.') 4610 { 4611 /* 4612 * dict.name 4613 */ 4614 key = *arg + 1; 4615 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4616 ; 4617 if (len == 0) 4618 return FAIL; 4619 *arg = skipwhite(key + len); 4620 } 4621 else 4622 { 4623 /* 4624 * something[idx] 4625 * 4626 * Get the (first) variable from inside the []. 4627 */ 4628 *arg = skipwhite(*arg + 1); 4629 if (**arg == ':') 4630 empty1 = TRUE; 4631 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4632 return FAIL; 4633 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4634 { 4635 /* not a number or string */ 4636 clear_tv(&var1); 4637 return FAIL; 4638 } 4639 4640 /* 4641 * Get the second variable from inside the [:]. 4642 */ 4643 if (**arg == ':') 4644 { 4645 range = TRUE; 4646 *arg = skipwhite(*arg + 1); 4647 if (**arg == ']') 4648 empty2 = TRUE; 4649 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4650 { 4651 if (!empty1) 4652 clear_tv(&var1); 4653 return FAIL; 4654 } 4655 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4656 { 4657 /* not a number or string */ 4658 if (!empty1) 4659 clear_tv(&var1); 4660 clear_tv(&var2); 4661 return FAIL; 4662 } 4663 } 4664 4665 /* Check for the ']'. */ 4666 if (**arg != ']') 4667 { 4668 if (verbose) 4669 EMSG(_(e_missbrac)); 4670 clear_tv(&var1); 4671 if (range) 4672 clear_tv(&var2); 4673 return FAIL; 4674 } 4675 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4676 } 4677 4678 if (evaluate) 4679 { 4680 n1 = 0; 4681 if (!empty1 && rettv->v_type != VAR_DICT) 4682 { 4683 n1 = get_tv_number(&var1); 4684 clear_tv(&var1); 4685 } 4686 if (range) 4687 { 4688 if (empty2) 4689 n2 = -1; 4690 else 4691 { 4692 n2 = get_tv_number(&var2); 4693 clear_tv(&var2); 4694 } 4695 } 4696 4697 switch (rettv->v_type) 4698 { 4699 case VAR_NUMBER: 4700 case VAR_STRING: 4701 s = get_tv_string(rettv); 4702 len = (long)STRLEN(s); 4703 if (range) 4704 { 4705 /* The resulting variable is a substring. If the indexes 4706 * are out of range the result is empty. */ 4707 if (n1 < 0) 4708 { 4709 n1 = len + n1; 4710 if (n1 < 0) 4711 n1 = 0; 4712 } 4713 if (n2 < 0) 4714 n2 = len + n2; 4715 else if (n2 >= len) 4716 n2 = len; 4717 if (n1 >= len || n2 < 0 || n1 > n2) 4718 s = NULL; 4719 else 4720 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4721 } 4722 else 4723 { 4724 /* The resulting variable is a string of a single 4725 * character. If the index is too big or negative the 4726 * result is empty. */ 4727 if (n1 >= len || n1 < 0) 4728 s = NULL; 4729 else 4730 s = vim_strnsave(s + n1, 1); 4731 } 4732 clear_tv(rettv); 4733 rettv->v_type = VAR_STRING; 4734 rettv->vval.v_string = s; 4735 break; 4736 4737 case VAR_LIST: 4738 len = list_len(rettv->vval.v_list); 4739 if (n1 < 0) 4740 n1 = len + n1; 4741 if (!empty1 && (n1 < 0 || n1 >= len)) 4742 { 4743 if (verbose) 4744 EMSGN(_(e_listidx), n1); 4745 return FAIL; 4746 } 4747 if (range) 4748 { 4749 list_T *l; 4750 listitem_T *item; 4751 4752 if (n2 < 0) 4753 n2 = len + n2; 4754 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4755 { 4756 if (verbose) 4757 EMSGN(_(e_listidx), n2); 4758 return FAIL; 4759 } 4760 l = list_alloc(); 4761 if (l == NULL) 4762 return FAIL; 4763 for (item = list_find(rettv->vval.v_list, n1); 4764 n1 <= n2; ++n1) 4765 { 4766 if (list_append_tv(l, &item->li_tv) == FAIL) 4767 { 4768 list_free(l); 4769 return FAIL; 4770 } 4771 item = item->li_next; 4772 } 4773 clear_tv(rettv); 4774 rettv->v_type = VAR_LIST; 4775 rettv->vval.v_list = l; 4776 ++l->lv_refcount; 4777 } 4778 else 4779 { 4780 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4781 &var1); 4782 clear_tv(rettv); 4783 *rettv = var1; 4784 } 4785 break; 4786 4787 case VAR_DICT: 4788 if (range) 4789 { 4790 if (verbose) 4791 EMSG(_(e_dictrange)); 4792 if (len == -1) 4793 clear_tv(&var1); 4794 return FAIL; 4795 } 4796 { 4797 dictitem_T *item; 4798 4799 if (len == -1) 4800 { 4801 key = get_tv_string(&var1); 4802 if (*key == NUL) 4803 { 4804 if (verbose) 4805 EMSG(_(e_emptykey)); 4806 clear_tv(&var1); 4807 return FAIL; 4808 } 4809 } 4810 4811 item = dict_find(rettv->vval.v_dict, key, (int)len); 4812 4813 if (item == NULL && verbose) 4814 EMSG2(_(e_dictkey), key); 4815 if (len == -1) 4816 clear_tv(&var1); 4817 if (item == NULL) 4818 return FAIL; 4819 4820 copy_tv(&item->di_tv, &var1); 4821 clear_tv(rettv); 4822 *rettv = var1; 4823 } 4824 break; 4825 } 4826 } 4827 4828 return OK; 4829 } 4830 4831 /* 4832 * Get an option value. 4833 * "arg" points to the '&' or '+' before the option name. 4834 * "arg" is advanced to character after the option name. 4835 * Return OK or FAIL. 4836 */ 4837 static int 4838 get_option_tv(arg, rettv, evaluate) 4839 char_u **arg; 4840 typval_T *rettv; /* when NULL, only check if option exists */ 4841 int evaluate; 4842 { 4843 char_u *option_end; 4844 long numval; 4845 char_u *stringval; 4846 int opt_type; 4847 int c; 4848 int working = (**arg == '+'); /* has("+option") */ 4849 int ret = OK; 4850 int opt_flags; 4851 4852 /* 4853 * Isolate the option name and find its value. 4854 */ 4855 option_end = find_option_end(arg, &opt_flags); 4856 if (option_end == NULL) 4857 { 4858 if (rettv != NULL) 4859 EMSG2(_("E112: Option name missing: %s"), *arg); 4860 return FAIL; 4861 } 4862 4863 if (!evaluate) 4864 { 4865 *arg = option_end; 4866 return OK; 4867 } 4868 4869 c = *option_end; 4870 *option_end = NUL; 4871 opt_type = get_option_value(*arg, &numval, 4872 rettv == NULL ? NULL : &stringval, opt_flags); 4873 4874 if (opt_type == -3) /* invalid name */ 4875 { 4876 if (rettv != NULL) 4877 EMSG2(_("E113: Unknown option: %s"), *arg); 4878 ret = FAIL; 4879 } 4880 else if (rettv != NULL) 4881 { 4882 if (opt_type == -2) /* hidden string option */ 4883 { 4884 rettv->v_type = VAR_STRING; 4885 rettv->vval.v_string = NULL; 4886 } 4887 else if (opt_type == -1) /* hidden number option */ 4888 { 4889 rettv->v_type = VAR_NUMBER; 4890 rettv->vval.v_number = 0; 4891 } 4892 else if (opt_type == 1) /* number option */ 4893 { 4894 rettv->v_type = VAR_NUMBER; 4895 rettv->vval.v_number = numval; 4896 } 4897 else /* string option */ 4898 { 4899 rettv->v_type = VAR_STRING; 4900 rettv->vval.v_string = stringval; 4901 } 4902 } 4903 else if (working && (opt_type == -2 || opt_type == -1)) 4904 ret = FAIL; 4905 4906 *option_end = c; /* put back for error messages */ 4907 *arg = option_end; 4908 4909 return ret; 4910 } 4911 4912 /* 4913 * Allocate a variable for a string constant. 4914 * Return OK or FAIL. 4915 */ 4916 static int 4917 get_string_tv(arg, rettv, evaluate) 4918 char_u **arg; 4919 typval_T *rettv; 4920 int evaluate; 4921 { 4922 char_u *p; 4923 char_u *name; 4924 int extra = 0; 4925 4926 /* 4927 * Find the end of the string, skipping backslashed characters. 4928 */ 4929 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4930 { 4931 if (*p == '\\' && p[1] != NUL) 4932 { 4933 ++p; 4934 /* A "\<x>" form occupies at least 4 characters, and produces up 4935 * to 6 characters: reserve space for 2 extra */ 4936 if (*p == '<') 4937 extra += 2; 4938 } 4939 } 4940 4941 if (*p != '"') 4942 { 4943 EMSG2(_("E114: Missing quote: %s"), *arg); 4944 return FAIL; 4945 } 4946 4947 /* If only parsing, set *arg and return here */ 4948 if (!evaluate) 4949 { 4950 *arg = p + 1; 4951 return OK; 4952 } 4953 4954 /* 4955 * Copy the string into allocated memory, handling backslashed 4956 * characters. 4957 */ 4958 name = alloc((unsigned)(p - *arg + extra)); 4959 if (name == NULL) 4960 return FAIL; 4961 rettv->v_type = VAR_STRING; 4962 rettv->vval.v_string = name; 4963 4964 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4965 { 4966 if (*p == '\\') 4967 { 4968 switch (*++p) 4969 { 4970 case 'b': *name++ = BS; ++p; break; 4971 case 'e': *name++ = ESC; ++p; break; 4972 case 'f': *name++ = FF; ++p; break; 4973 case 'n': *name++ = NL; ++p; break; 4974 case 'r': *name++ = CAR; ++p; break; 4975 case 't': *name++ = TAB; ++p; break; 4976 4977 case 'X': /* hex: "\x1", "\x12" */ 4978 case 'x': 4979 case 'u': /* Unicode: "\u0023" */ 4980 case 'U': 4981 if (vim_isxdigit(p[1])) 4982 { 4983 int n, nr; 4984 int c = toupper(*p); 4985 4986 if (c == 'X') 4987 n = 2; 4988 else 4989 n = 4; 4990 nr = 0; 4991 while (--n >= 0 && vim_isxdigit(p[1])) 4992 { 4993 ++p; 4994 nr = (nr << 4) + hex2nr(*p); 4995 } 4996 ++p; 4997 #ifdef FEAT_MBYTE 4998 /* For "\u" store the number according to 4999 * 'encoding'. */ 5000 if (c != 'X') 5001 name += (*mb_char2bytes)(nr, name); 5002 else 5003 #endif 5004 *name++ = nr; 5005 } 5006 break; 5007 5008 /* octal: "\1", "\12", "\123" */ 5009 case '0': 5010 case '1': 5011 case '2': 5012 case '3': 5013 case '4': 5014 case '5': 5015 case '6': 5016 case '7': *name = *p++ - '0'; 5017 if (*p >= '0' && *p <= '7') 5018 { 5019 *name = (*name << 3) + *p++ - '0'; 5020 if (*p >= '0' && *p <= '7') 5021 *name = (*name << 3) + *p++ - '0'; 5022 } 5023 ++name; 5024 break; 5025 5026 /* Special key, e.g.: "\<C-W>" */ 5027 case '<': extra = trans_special(&p, name, TRUE); 5028 if (extra != 0) 5029 { 5030 name += extra; 5031 break; 5032 } 5033 /* FALLTHROUGH */ 5034 5035 default: MB_COPY_CHAR(p, name); 5036 break; 5037 } 5038 } 5039 else 5040 MB_COPY_CHAR(p, name); 5041 5042 } 5043 *name = NUL; 5044 *arg = p + 1; 5045 5046 return OK; 5047 } 5048 5049 /* 5050 * Allocate a variable for a 'str''ing' constant. 5051 * Return OK or FAIL. 5052 */ 5053 static int 5054 get_lit_string_tv(arg, rettv, evaluate) 5055 char_u **arg; 5056 typval_T *rettv; 5057 int evaluate; 5058 { 5059 char_u *p; 5060 char_u *str; 5061 int reduce = 0; 5062 5063 /* 5064 * Find the end of the string, skipping ''. 5065 */ 5066 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5067 { 5068 if (*p == '\'') 5069 { 5070 if (p[1] != '\'') 5071 break; 5072 ++reduce; 5073 ++p; 5074 } 5075 } 5076 5077 if (*p != '\'') 5078 { 5079 EMSG2(_("E115: Missing quote: %s"), *arg); 5080 return FAIL; 5081 } 5082 5083 /* If only parsing return after setting "*arg" */ 5084 if (!evaluate) 5085 { 5086 *arg = p + 1; 5087 return OK; 5088 } 5089 5090 /* 5091 * Copy the string into allocated memory, handling '' to ' reduction. 5092 */ 5093 str = alloc((unsigned)((p - *arg) - reduce)); 5094 if (str == NULL) 5095 return FAIL; 5096 rettv->v_type = VAR_STRING; 5097 rettv->vval.v_string = str; 5098 5099 for (p = *arg + 1; *p != NUL; ) 5100 { 5101 if (*p == '\'') 5102 { 5103 if (p[1] != '\'') 5104 break; 5105 ++p; 5106 } 5107 MB_COPY_CHAR(p, str); 5108 } 5109 *str = NUL; 5110 *arg = p + 1; 5111 5112 return OK; 5113 } 5114 5115 /* 5116 * Allocate a variable for a List and fill it from "*arg". 5117 * Return OK or FAIL. 5118 */ 5119 static int 5120 get_list_tv(arg, rettv, evaluate) 5121 char_u **arg; 5122 typval_T *rettv; 5123 int evaluate; 5124 { 5125 list_T *l = NULL; 5126 typval_T tv; 5127 listitem_T *item; 5128 5129 if (evaluate) 5130 { 5131 l = list_alloc(); 5132 if (l == NULL) 5133 return FAIL; 5134 } 5135 5136 *arg = skipwhite(*arg + 1); 5137 while (**arg != ']' && **arg != NUL) 5138 { 5139 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5140 goto failret; 5141 if (evaluate) 5142 { 5143 item = listitem_alloc(); 5144 if (item != NULL) 5145 { 5146 item->li_tv = tv; 5147 item->li_tv.v_lock = 0; 5148 list_append(l, item); 5149 } 5150 else 5151 clear_tv(&tv); 5152 } 5153 5154 if (**arg == ']') 5155 break; 5156 if (**arg != ',') 5157 { 5158 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5159 goto failret; 5160 } 5161 *arg = skipwhite(*arg + 1); 5162 } 5163 5164 if (**arg != ']') 5165 { 5166 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5167 failret: 5168 if (evaluate) 5169 list_free(l); 5170 return FAIL; 5171 } 5172 5173 *arg = skipwhite(*arg + 1); 5174 if (evaluate) 5175 { 5176 rettv->v_type = VAR_LIST; 5177 rettv->vval.v_list = l; 5178 ++l->lv_refcount; 5179 } 5180 5181 return OK; 5182 } 5183 5184 /* 5185 * Allocate an empty header for a list. 5186 * Caller should take care of the reference count. 5187 */ 5188 static list_T * 5189 list_alloc() 5190 { 5191 list_T *l; 5192 5193 l = (list_T *)alloc_clear(sizeof(list_T)); 5194 if (l != NULL) 5195 { 5196 /* Prepend the list to the list of lists for garbage collection. */ 5197 if (first_list != NULL) 5198 first_list->lv_used_prev = l; 5199 l->lv_used_prev = NULL; 5200 l->lv_used_next = first_list; 5201 first_list = l; 5202 } 5203 return l; 5204 } 5205 5206 /* 5207 * Unreference a list: decrement the reference count and free it when it 5208 * becomes zero. 5209 */ 5210 void 5211 list_unref(l) 5212 list_T *l; 5213 { 5214 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5215 list_free(l); 5216 } 5217 5218 /* 5219 * Free a list, including all items it points to. 5220 * Ignores the reference count. 5221 */ 5222 static void 5223 list_free(l) 5224 list_T *l; 5225 { 5226 listitem_T *item; 5227 5228 /* Avoid that recursive reference to the list frees us again. */ 5229 l->lv_refcount = DEL_REFCOUNT; 5230 5231 /* Remove the list from the list of lists for garbage collection. */ 5232 if (l->lv_used_prev == NULL) 5233 first_list = l->lv_used_next; 5234 else 5235 l->lv_used_prev->lv_used_next = l->lv_used_next; 5236 if (l->lv_used_next != NULL) 5237 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5238 5239 for (item = l->lv_first; item != NULL; item = l->lv_first) 5240 { 5241 /* Remove the item before deleting it. */ 5242 l->lv_first = item->li_next; 5243 listitem_free(item); 5244 } 5245 vim_free(l); 5246 } 5247 5248 /* 5249 * Allocate a list item. 5250 */ 5251 static listitem_T * 5252 listitem_alloc() 5253 { 5254 return (listitem_T *)alloc(sizeof(listitem_T)); 5255 } 5256 5257 /* 5258 * Free a list item. Also clears the value. Does not notify watchers. 5259 */ 5260 static void 5261 listitem_free(item) 5262 listitem_T *item; 5263 { 5264 clear_tv(&item->li_tv); 5265 vim_free(item); 5266 } 5267 5268 /* 5269 * Remove a list item from a List and free it. Also clears the value. 5270 */ 5271 static void 5272 listitem_remove(l, item) 5273 list_T *l; 5274 listitem_T *item; 5275 { 5276 list_remove(l, item, item); 5277 listitem_free(item); 5278 } 5279 5280 /* 5281 * Get the number of items in a list. 5282 */ 5283 static long 5284 list_len(l) 5285 list_T *l; 5286 { 5287 if (l == NULL) 5288 return 0L; 5289 return l->lv_len; 5290 } 5291 5292 /* 5293 * Return TRUE when two lists have exactly the same values. 5294 */ 5295 static int 5296 list_equal(l1, l2, ic) 5297 list_T *l1; 5298 list_T *l2; 5299 int ic; /* ignore case for strings */ 5300 { 5301 listitem_T *item1, *item2; 5302 5303 if (list_len(l1) != list_len(l2)) 5304 return FALSE; 5305 5306 for (item1 = l1->lv_first, item2 = l2->lv_first; 5307 item1 != NULL && item2 != NULL; 5308 item1 = item1->li_next, item2 = item2->li_next) 5309 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5310 return FALSE; 5311 return item1 == NULL && item2 == NULL; 5312 } 5313 5314 /* 5315 * Return TRUE when two dictionaries have exactly the same key/values. 5316 */ 5317 static int 5318 dict_equal(d1, d2, ic) 5319 dict_T *d1; 5320 dict_T *d2; 5321 int ic; /* ignore case for strings */ 5322 { 5323 hashitem_T *hi; 5324 dictitem_T *item2; 5325 int todo; 5326 5327 if (dict_len(d1) != dict_len(d2)) 5328 return FALSE; 5329 5330 todo = d1->dv_hashtab.ht_used; 5331 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5332 { 5333 if (!HASHITEM_EMPTY(hi)) 5334 { 5335 item2 = dict_find(d2, hi->hi_key, -1); 5336 if (item2 == NULL) 5337 return FALSE; 5338 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5339 return FALSE; 5340 --todo; 5341 } 5342 } 5343 return TRUE; 5344 } 5345 5346 /* 5347 * Return TRUE if "tv1" and "tv2" have the same value. 5348 * Compares the items just like "==" would compare them, but strings and 5349 * numbers are different. 5350 */ 5351 static int 5352 tv_equal(tv1, tv2, ic) 5353 typval_T *tv1; 5354 typval_T *tv2; 5355 int ic; /* ignore case */ 5356 { 5357 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5358 char_u *s1, *s2; 5359 5360 if (tv1->v_type != tv2->v_type) 5361 return FALSE; 5362 5363 switch (tv1->v_type) 5364 { 5365 case VAR_LIST: 5366 /* recursive! */ 5367 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5368 5369 case VAR_DICT: 5370 /* recursive! */ 5371 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5372 5373 case VAR_FUNC: 5374 return (tv1->vval.v_string != NULL 5375 && tv2->vval.v_string != NULL 5376 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5377 5378 case VAR_NUMBER: 5379 return tv1->vval.v_number == tv2->vval.v_number; 5380 5381 case VAR_STRING: 5382 s1 = get_tv_string_buf(tv1, buf1); 5383 s2 = get_tv_string_buf(tv2, buf2); 5384 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5385 } 5386 5387 EMSG2(_(e_intern2), "tv_equal()"); 5388 return TRUE; 5389 } 5390 5391 /* 5392 * Locate item with index "n" in list "l" and return it. 5393 * A negative index is counted from the end; -1 is the last item. 5394 * Returns NULL when "n" is out of range. 5395 */ 5396 static listitem_T * 5397 list_find(l, n) 5398 list_T *l; 5399 long n; 5400 { 5401 listitem_T *item; 5402 long idx; 5403 5404 if (l == NULL) 5405 return NULL; 5406 5407 /* Negative index is relative to the end. */ 5408 if (n < 0) 5409 n = l->lv_len + n; 5410 5411 /* Check for index out of range. */ 5412 if (n < 0 || n >= l->lv_len) 5413 return NULL; 5414 5415 /* When there is a cached index may start search from there. */ 5416 if (l->lv_idx_item != NULL) 5417 { 5418 if (n < l->lv_idx / 2) 5419 { 5420 /* closest to the start of the list */ 5421 item = l->lv_first; 5422 idx = 0; 5423 } 5424 else if (n > (l->lv_idx + l->lv_len) / 2) 5425 { 5426 /* closest to the end of the list */ 5427 item = l->lv_last; 5428 idx = l->lv_len - 1; 5429 } 5430 else 5431 { 5432 /* closest to the cached index */ 5433 item = l->lv_idx_item; 5434 idx = l->lv_idx; 5435 } 5436 } 5437 else 5438 { 5439 if (n < l->lv_len / 2) 5440 { 5441 /* closest to the start of the list */ 5442 item = l->lv_first; 5443 idx = 0; 5444 } 5445 else 5446 { 5447 /* closest to the end of the list */ 5448 item = l->lv_last; 5449 idx = l->lv_len - 1; 5450 } 5451 } 5452 5453 while (n > idx) 5454 { 5455 /* search forward */ 5456 item = item->li_next; 5457 ++idx; 5458 } 5459 while (n < idx) 5460 { 5461 /* search backward */ 5462 item = item->li_prev; 5463 --idx; 5464 } 5465 5466 /* cache the used index */ 5467 l->lv_idx = idx; 5468 l->lv_idx_item = item; 5469 5470 return item; 5471 } 5472 5473 /* 5474 * Locate "item" list "l" and return its index. 5475 * Returns -1 when "item" is not in the list. 5476 */ 5477 static long 5478 list_idx_of_item(l, item) 5479 list_T *l; 5480 listitem_T *item; 5481 { 5482 long idx = 0; 5483 listitem_T *li; 5484 5485 if (l == NULL) 5486 return -1; 5487 idx = 0; 5488 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5489 ++idx; 5490 if (li == NULL) 5491 return -1; 5492 return idx; 5493 } 5494 5495 /* 5496 * Append item "item" to the end of list "l". 5497 */ 5498 static void 5499 list_append(l, item) 5500 list_T *l; 5501 listitem_T *item; 5502 { 5503 if (l->lv_last == NULL) 5504 { 5505 /* empty list */ 5506 l->lv_first = item; 5507 l->lv_last = item; 5508 item->li_prev = NULL; 5509 } 5510 else 5511 { 5512 l->lv_last->li_next = item; 5513 item->li_prev = l->lv_last; 5514 l->lv_last = item; 5515 } 5516 ++l->lv_len; 5517 item->li_next = NULL; 5518 } 5519 5520 /* 5521 * Append typval_T "tv" to the end of list "l". 5522 * Return FAIL when out of memory. 5523 */ 5524 static int 5525 list_append_tv(l, tv) 5526 list_T *l; 5527 typval_T *tv; 5528 { 5529 listitem_T *li = listitem_alloc(); 5530 5531 if (li == NULL) 5532 return FAIL; 5533 copy_tv(tv, &li->li_tv); 5534 list_append(l, li); 5535 return OK; 5536 } 5537 5538 /* 5539 * Add a dictionary to a list. Used by getqflist(). 5540 * Return FAIL when out of memory. 5541 */ 5542 int 5543 list_append_dict(list, dict) 5544 list_T *list; 5545 dict_T *dict; 5546 { 5547 listitem_T *li = listitem_alloc(); 5548 5549 if (li == NULL) 5550 return FAIL; 5551 li->li_tv.v_type = VAR_DICT; 5552 li->li_tv.v_lock = 0; 5553 li->li_tv.vval.v_dict = dict; 5554 list_append(list, li); 5555 ++dict->dv_refcount; 5556 return OK; 5557 } 5558 5559 /* 5560 * Make a copy of "str" and append it as an item to list "l". 5561 * When "len" >= 0 use "str[len]". 5562 * Returns FAIL when out of memory. 5563 */ 5564 static int 5565 list_append_string(l, str, len) 5566 list_T *l; 5567 char_u *str; 5568 int len; 5569 { 5570 listitem_T *li = listitem_alloc(); 5571 5572 if (li == NULL) 5573 return FAIL; 5574 list_append(l, li); 5575 li->li_tv.v_type = VAR_STRING; 5576 li->li_tv.v_lock = 0; 5577 if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 5578 : vim_strsave(str))) == NULL) 5579 return FAIL; 5580 return OK; 5581 } 5582 5583 /* 5584 * Append "n" to list "l". 5585 * Returns FAIL when out of memory. 5586 */ 5587 static int 5588 list_append_number(l, n) 5589 list_T *l; 5590 varnumber_T n; 5591 { 5592 listitem_T *li; 5593 5594 li = listitem_alloc(); 5595 if (li == NULL) 5596 return FAIL; 5597 li->li_tv.v_type = VAR_NUMBER; 5598 li->li_tv.v_lock = 0; 5599 li->li_tv.vval.v_number = n; 5600 list_append(l, li); 5601 return OK; 5602 } 5603 5604 /* 5605 * Insert typval_T "tv" in list "l" before "item". 5606 * If "item" is NULL append at the end. 5607 * Return FAIL when out of memory. 5608 */ 5609 static int 5610 list_insert_tv(l, tv, item) 5611 list_T *l; 5612 typval_T *tv; 5613 listitem_T *item; 5614 { 5615 listitem_T *ni = listitem_alloc(); 5616 5617 if (ni == NULL) 5618 return FAIL; 5619 copy_tv(tv, &ni->li_tv); 5620 if (item == NULL) 5621 /* Append new item at end of list. */ 5622 list_append(l, ni); 5623 else 5624 { 5625 /* Insert new item before existing item. */ 5626 ni->li_prev = item->li_prev; 5627 ni->li_next = item; 5628 if (item->li_prev == NULL) 5629 { 5630 l->lv_first = ni; 5631 ++l->lv_idx; 5632 } 5633 else 5634 { 5635 item->li_prev->li_next = ni; 5636 l->lv_idx_item = NULL; 5637 } 5638 item->li_prev = ni; 5639 ++l->lv_len; 5640 } 5641 return OK; 5642 } 5643 5644 /* 5645 * Extend "l1" with "l2". 5646 * If "bef" is NULL append at the end, otherwise insert before this item. 5647 * Returns FAIL when out of memory. 5648 */ 5649 static int 5650 list_extend(l1, l2, bef) 5651 list_T *l1; 5652 list_T *l2; 5653 listitem_T *bef; 5654 { 5655 listitem_T *item; 5656 5657 for (item = l2->lv_first; item != NULL; item = item->li_next) 5658 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5659 return FAIL; 5660 return OK; 5661 } 5662 5663 /* 5664 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5665 * Return FAIL when out of memory. 5666 */ 5667 static int 5668 list_concat(l1, l2, tv) 5669 list_T *l1; 5670 list_T *l2; 5671 typval_T *tv; 5672 { 5673 list_T *l; 5674 5675 /* make a copy of the first list. */ 5676 l = list_copy(l1, FALSE, 0); 5677 if (l == NULL) 5678 return FAIL; 5679 tv->v_type = VAR_LIST; 5680 tv->vval.v_list = l; 5681 5682 /* append all items from the second list */ 5683 return list_extend(l, l2, NULL); 5684 } 5685 5686 /* 5687 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5688 * The refcount of the new list is set to 1. 5689 * See item_copy() for "copyID". 5690 * Returns NULL when out of memory. 5691 */ 5692 static list_T * 5693 list_copy(orig, deep, copyID) 5694 list_T *orig; 5695 int deep; 5696 int copyID; 5697 { 5698 list_T *copy; 5699 listitem_T *item; 5700 listitem_T *ni; 5701 5702 if (orig == NULL) 5703 return NULL; 5704 5705 copy = list_alloc(); 5706 if (copy != NULL) 5707 { 5708 if (copyID != 0) 5709 { 5710 /* Do this before adding the items, because one of the items may 5711 * refer back to this list. */ 5712 orig->lv_copyID = copyID; 5713 orig->lv_copylist = copy; 5714 } 5715 for (item = orig->lv_first; item != NULL && !got_int; 5716 item = item->li_next) 5717 { 5718 ni = listitem_alloc(); 5719 if (ni == NULL) 5720 break; 5721 if (deep) 5722 { 5723 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5724 { 5725 vim_free(ni); 5726 break; 5727 } 5728 } 5729 else 5730 copy_tv(&item->li_tv, &ni->li_tv); 5731 list_append(copy, ni); 5732 } 5733 ++copy->lv_refcount; 5734 if (item != NULL) 5735 { 5736 list_unref(copy); 5737 copy = NULL; 5738 } 5739 } 5740 5741 return copy; 5742 } 5743 5744 /* 5745 * Remove items "item" to "item2" from list "l". 5746 * Does not free the listitem or the value! 5747 */ 5748 static void 5749 list_remove(l, item, item2) 5750 list_T *l; 5751 listitem_T *item; 5752 listitem_T *item2; 5753 { 5754 listitem_T *ip; 5755 5756 /* notify watchers */ 5757 for (ip = item; ip != NULL; ip = ip->li_next) 5758 { 5759 --l->lv_len; 5760 list_fix_watch(l, ip); 5761 if (ip == item2) 5762 break; 5763 } 5764 5765 if (item2->li_next == NULL) 5766 l->lv_last = item->li_prev; 5767 else 5768 item2->li_next->li_prev = item->li_prev; 5769 if (item->li_prev == NULL) 5770 l->lv_first = item2->li_next; 5771 else 5772 item->li_prev->li_next = item2->li_next; 5773 l->lv_idx_item = NULL; 5774 } 5775 5776 /* 5777 * Return an allocated string with the string representation of a list. 5778 * May return NULL. 5779 */ 5780 static char_u * 5781 list2string(tv) 5782 typval_T *tv; 5783 { 5784 garray_T ga; 5785 5786 if (tv->vval.v_list == NULL) 5787 return NULL; 5788 ga_init2(&ga, (int)sizeof(char), 80); 5789 ga_append(&ga, '['); 5790 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5791 { 5792 vim_free(ga.ga_data); 5793 return NULL; 5794 } 5795 ga_append(&ga, ']'); 5796 ga_append(&ga, NUL); 5797 return (char_u *)ga.ga_data; 5798 } 5799 5800 /* 5801 * Join list "l" into a string in "*gap", using separator "sep". 5802 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5803 * Return FAIL or OK. 5804 */ 5805 static int 5806 list_join(gap, l, sep, echo) 5807 garray_T *gap; 5808 list_T *l; 5809 char_u *sep; 5810 int echo; 5811 { 5812 int first = TRUE; 5813 char_u *tofree; 5814 char_u numbuf[NUMBUFLEN]; 5815 listitem_T *item; 5816 char_u *s; 5817 5818 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5819 { 5820 if (first) 5821 first = FALSE; 5822 else 5823 ga_concat(gap, sep); 5824 5825 if (echo) 5826 s = echo_string(&item->li_tv, &tofree, numbuf); 5827 else 5828 s = tv2string(&item->li_tv, &tofree, numbuf); 5829 if (s != NULL) 5830 ga_concat(gap, s); 5831 vim_free(tofree); 5832 if (s == NULL) 5833 return FAIL; 5834 } 5835 return OK; 5836 } 5837 5838 /* 5839 * Garbage collection for lists and dictionaries. 5840 * 5841 * We use reference counts to be able to free most items right away when they 5842 * are no longer used. But for composite items it's possible that it becomes 5843 * unused while the reference count is > 0: When there is a recursive 5844 * reference. Example: 5845 * :let l = [1, 2, 3] 5846 * :let d = {9: l} 5847 * :let l[1] = d 5848 * 5849 * Since this is quite unusual we handle this with garbage collection: every 5850 * once in a while find out which lists and dicts are not referenced from any 5851 * variable. 5852 * 5853 * Here is a good reference text about garbage collection (refers to Python 5854 * but it applies to all reference-counting mechanisms): 5855 * http://python.ca/nas/python/gc/ 5856 */ 5857 5858 /* 5859 * Do garbage collection for lists and dicts. 5860 * Return TRUE if some memory was freed. 5861 */ 5862 int 5863 garbage_collect() 5864 { 5865 dict_T *dd; 5866 list_T *ll; 5867 int copyID = ++current_copyID; 5868 buf_T *buf; 5869 win_T *wp; 5870 int i; 5871 funccall_T *fc; 5872 int did_free = FALSE; 5873 5874 /* 5875 * 1. Go through all accessible variables and mark all lists and dicts 5876 * with copyID. 5877 */ 5878 /* script-local variables */ 5879 for (i = 1; i <= ga_scripts.ga_len; ++i) 5880 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5881 5882 /* buffer-local variables */ 5883 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5884 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5885 5886 /* window-local variables */ 5887 FOR_ALL_WINDOWS(wp) 5888 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5889 5890 /* global variables */ 5891 set_ref_in_ht(&globvarht, copyID); 5892 5893 /* function-local variables */ 5894 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5895 { 5896 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5897 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5898 } 5899 5900 /* 5901 * 2. Go through the list of dicts and free items without the copyID. 5902 */ 5903 for (dd = first_dict; dd != NULL; ) 5904 if (dd->dv_copyID != copyID) 5905 { 5906 dict_free(dd); 5907 did_free = TRUE; 5908 5909 /* restart, next dict may also have been freed */ 5910 dd = first_dict; 5911 } 5912 else 5913 dd = dd->dv_used_next; 5914 5915 /* 5916 * 3. Go through the list of lists and free items without the copyID. 5917 * But don't free a list that has a watcher (used in a for loop), these 5918 * are not referenced anywhere. 5919 */ 5920 for (ll = first_list; ll != NULL; ) 5921 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 5922 { 5923 list_free(ll); 5924 did_free = TRUE; 5925 5926 /* restart, next list may also have been freed */ 5927 ll = first_list; 5928 } 5929 else 5930 ll = ll->lv_used_next; 5931 5932 return did_free; 5933 } 5934 5935 /* 5936 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5937 */ 5938 static void 5939 set_ref_in_ht(ht, copyID) 5940 hashtab_T *ht; 5941 int copyID; 5942 { 5943 int todo; 5944 hashitem_T *hi; 5945 5946 todo = ht->ht_used; 5947 for (hi = ht->ht_array; todo > 0; ++hi) 5948 if (!HASHITEM_EMPTY(hi)) 5949 { 5950 --todo; 5951 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5952 } 5953 } 5954 5955 /* 5956 * Mark all lists and dicts referenced through list "l" with "copyID". 5957 */ 5958 static void 5959 set_ref_in_list(l, copyID) 5960 list_T *l; 5961 int copyID; 5962 { 5963 listitem_T *li; 5964 5965 for (li = l->lv_first; li != NULL; li = li->li_next) 5966 set_ref_in_item(&li->li_tv, copyID); 5967 } 5968 5969 /* 5970 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5971 */ 5972 static void 5973 set_ref_in_item(tv, copyID) 5974 typval_T *tv; 5975 int copyID; 5976 { 5977 dict_T *dd; 5978 list_T *ll; 5979 5980 switch (tv->v_type) 5981 { 5982 case VAR_DICT: 5983 dd = tv->vval.v_dict; 5984 if (dd->dv_copyID != copyID) 5985 { 5986 /* Didn't see this dict yet. */ 5987 dd->dv_copyID = copyID; 5988 set_ref_in_ht(&dd->dv_hashtab, copyID); 5989 } 5990 break; 5991 5992 case VAR_LIST: 5993 ll = tv->vval.v_list; 5994 if (ll->lv_copyID != copyID) 5995 { 5996 /* Didn't see this list yet. */ 5997 ll->lv_copyID = copyID; 5998 set_ref_in_list(ll, copyID); 5999 } 6000 break; 6001 } 6002 return; 6003 } 6004 6005 /* 6006 * Allocate an empty header for a dictionary. 6007 */ 6008 dict_T * 6009 dict_alloc() 6010 { 6011 dict_T *d; 6012 6013 d = (dict_T *)alloc(sizeof(dict_T)); 6014 if (d != NULL) 6015 { 6016 /* Add the list to the hashtable for garbage collection. */ 6017 if (first_dict != NULL) 6018 first_dict->dv_used_prev = d; 6019 d->dv_used_next = first_dict; 6020 d->dv_used_prev = NULL; 6021 6022 hash_init(&d->dv_hashtab); 6023 d->dv_lock = 0; 6024 d->dv_refcount = 0; 6025 d->dv_copyID = 0; 6026 } 6027 return d; 6028 } 6029 6030 /* 6031 * Unreference a Dictionary: decrement the reference count and free it when it 6032 * becomes zero. 6033 */ 6034 static void 6035 dict_unref(d) 6036 dict_T *d; 6037 { 6038 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6039 dict_free(d); 6040 } 6041 6042 /* 6043 * Free a Dictionary, including all items it contains. 6044 * Ignores the reference count. 6045 */ 6046 static void 6047 dict_free(d) 6048 dict_T *d; 6049 { 6050 int todo; 6051 hashitem_T *hi; 6052 dictitem_T *di; 6053 6054 /* Avoid that recursive reference to the dict frees us again. */ 6055 d->dv_refcount = DEL_REFCOUNT; 6056 6057 /* Remove the dict from the list of dicts for garbage collection. */ 6058 if (d->dv_used_prev == NULL) 6059 first_dict = d->dv_used_next; 6060 else 6061 d->dv_used_prev->dv_used_next = d->dv_used_next; 6062 if (d->dv_used_next != NULL) 6063 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6064 6065 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6066 hash_lock(&d->dv_hashtab); 6067 todo = d->dv_hashtab.ht_used; 6068 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6069 { 6070 if (!HASHITEM_EMPTY(hi)) 6071 { 6072 /* Remove the item before deleting it, just in case there is 6073 * something recursive causing trouble. */ 6074 di = HI2DI(hi); 6075 hash_remove(&d->dv_hashtab, hi); 6076 dictitem_free(di); 6077 --todo; 6078 } 6079 } 6080 hash_clear(&d->dv_hashtab); 6081 vim_free(d); 6082 } 6083 6084 /* 6085 * Allocate a Dictionary item. 6086 * The "key" is copied to the new item. 6087 * Note that the value of the item "di_tv" still needs to be initialized! 6088 * Returns NULL when out of memory. 6089 */ 6090 static dictitem_T * 6091 dictitem_alloc(key) 6092 char_u *key; 6093 { 6094 dictitem_T *di; 6095 6096 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6097 if (di != NULL) 6098 { 6099 STRCPY(di->di_key, key); 6100 di->di_flags = 0; 6101 } 6102 return di; 6103 } 6104 6105 /* 6106 * Make a copy of a Dictionary item. 6107 */ 6108 static dictitem_T * 6109 dictitem_copy(org) 6110 dictitem_T *org; 6111 { 6112 dictitem_T *di; 6113 6114 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6115 if (di != NULL) 6116 { 6117 STRCPY(di->di_key, org->di_key); 6118 di->di_flags = 0; 6119 copy_tv(&org->di_tv, &di->di_tv); 6120 } 6121 return di; 6122 } 6123 6124 /* 6125 * Remove item "item" from Dictionary "dict" and free it. 6126 */ 6127 static void 6128 dictitem_remove(dict, item) 6129 dict_T *dict; 6130 dictitem_T *item; 6131 { 6132 hashitem_T *hi; 6133 6134 hi = hash_find(&dict->dv_hashtab, item->di_key); 6135 if (HASHITEM_EMPTY(hi)) 6136 EMSG2(_(e_intern2), "dictitem_remove()"); 6137 else 6138 hash_remove(&dict->dv_hashtab, hi); 6139 dictitem_free(item); 6140 } 6141 6142 /* 6143 * Free a dict item. Also clears the value. 6144 */ 6145 static void 6146 dictitem_free(item) 6147 dictitem_T *item; 6148 { 6149 clear_tv(&item->di_tv); 6150 vim_free(item); 6151 } 6152 6153 /* 6154 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6155 * The refcount of the new dict is set to 1. 6156 * See item_copy() for "copyID". 6157 * Returns NULL when out of memory. 6158 */ 6159 static dict_T * 6160 dict_copy(orig, deep, copyID) 6161 dict_T *orig; 6162 int deep; 6163 int copyID; 6164 { 6165 dict_T *copy; 6166 dictitem_T *di; 6167 int todo; 6168 hashitem_T *hi; 6169 6170 if (orig == NULL) 6171 return NULL; 6172 6173 copy = dict_alloc(); 6174 if (copy != NULL) 6175 { 6176 if (copyID != 0) 6177 { 6178 orig->dv_copyID = copyID; 6179 orig->dv_copydict = copy; 6180 } 6181 todo = orig->dv_hashtab.ht_used; 6182 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6183 { 6184 if (!HASHITEM_EMPTY(hi)) 6185 { 6186 --todo; 6187 6188 di = dictitem_alloc(hi->hi_key); 6189 if (di == NULL) 6190 break; 6191 if (deep) 6192 { 6193 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6194 copyID) == FAIL) 6195 { 6196 vim_free(di); 6197 break; 6198 } 6199 } 6200 else 6201 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6202 if (dict_add(copy, di) == FAIL) 6203 { 6204 dictitem_free(di); 6205 break; 6206 } 6207 } 6208 } 6209 6210 ++copy->dv_refcount; 6211 if (todo > 0) 6212 { 6213 dict_unref(copy); 6214 copy = NULL; 6215 } 6216 } 6217 6218 return copy; 6219 } 6220 6221 /* 6222 * Add item "item" to Dictionary "d". 6223 * Returns FAIL when out of memory and when key already existed. 6224 */ 6225 static int 6226 dict_add(d, item) 6227 dict_T *d; 6228 dictitem_T *item; 6229 { 6230 return hash_add(&d->dv_hashtab, item->di_key); 6231 } 6232 6233 /* 6234 * Add a number or string entry to dictionary "d". 6235 * When "str" is NULL use number "nr", otherwise use "str". 6236 * Returns FAIL when out of memory and when key already exists. 6237 */ 6238 int 6239 dict_add_nr_str(d, key, nr, str) 6240 dict_T *d; 6241 char *key; 6242 long nr; 6243 char_u *str; 6244 { 6245 dictitem_T *item; 6246 6247 item = dictitem_alloc((char_u *)key); 6248 if (item == NULL) 6249 return FAIL; 6250 item->di_tv.v_lock = 0; 6251 if (str == NULL) 6252 { 6253 item->di_tv.v_type = VAR_NUMBER; 6254 item->di_tv.vval.v_number = nr; 6255 } 6256 else 6257 { 6258 item->di_tv.v_type = VAR_STRING; 6259 item->di_tv.vval.v_string = vim_strsave(str); 6260 } 6261 if (dict_add(d, item) == FAIL) 6262 { 6263 dictitem_free(item); 6264 return FAIL; 6265 } 6266 return OK; 6267 } 6268 6269 /* 6270 * Get the number of items in a Dictionary. 6271 */ 6272 static long 6273 dict_len(d) 6274 dict_T *d; 6275 { 6276 if (d == NULL) 6277 return 0L; 6278 return d->dv_hashtab.ht_used; 6279 } 6280 6281 /* 6282 * Find item "key[len]" in Dictionary "d". 6283 * If "len" is negative use strlen(key). 6284 * Returns NULL when not found. 6285 */ 6286 static dictitem_T * 6287 dict_find(d, key, len) 6288 dict_T *d; 6289 char_u *key; 6290 int len; 6291 { 6292 #define AKEYLEN 200 6293 char_u buf[AKEYLEN]; 6294 char_u *akey; 6295 char_u *tofree = NULL; 6296 hashitem_T *hi; 6297 6298 if (len < 0) 6299 akey = key; 6300 else if (len >= AKEYLEN) 6301 { 6302 tofree = akey = vim_strnsave(key, len); 6303 if (akey == NULL) 6304 return NULL; 6305 } 6306 else 6307 { 6308 /* Avoid a malloc/free by using buf[]. */ 6309 vim_strncpy(buf, key, len); 6310 akey = buf; 6311 } 6312 6313 hi = hash_find(&d->dv_hashtab, akey); 6314 vim_free(tofree); 6315 if (HASHITEM_EMPTY(hi)) 6316 return NULL; 6317 return HI2DI(hi); 6318 } 6319 6320 /* 6321 * Get a string item from a dictionary in allocated memory. 6322 * Returns NULL if the entry doesn't exist or out of memory. 6323 */ 6324 char_u * 6325 get_dict_string(d, key) 6326 dict_T *d; 6327 char_u *key; 6328 { 6329 dictitem_T *di; 6330 6331 di = dict_find(d, key, -1); 6332 if (di == NULL) 6333 return NULL; 6334 return vim_strsave(get_tv_string(&di->di_tv)); 6335 } 6336 6337 /* 6338 * Get a number item from a dictionary. 6339 * Returns 0 if the entry doesn't exist or out of memory. 6340 */ 6341 long 6342 get_dict_number(d, key) 6343 dict_T *d; 6344 char_u *key; 6345 { 6346 dictitem_T *di; 6347 6348 di = dict_find(d, key, -1); 6349 if (di == NULL) 6350 return 0; 6351 return get_tv_number(&di->di_tv); 6352 } 6353 6354 /* 6355 * Return an allocated string with the string representation of a Dictionary. 6356 * May return NULL. 6357 */ 6358 static char_u * 6359 dict2string(tv) 6360 typval_T *tv; 6361 { 6362 garray_T ga; 6363 int first = TRUE; 6364 char_u *tofree; 6365 char_u numbuf[NUMBUFLEN]; 6366 hashitem_T *hi; 6367 char_u *s; 6368 dict_T *d; 6369 int todo; 6370 6371 if ((d = tv->vval.v_dict) == NULL) 6372 return NULL; 6373 ga_init2(&ga, (int)sizeof(char), 80); 6374 ga_append(&ga, '{'); 6375 6376 todo = d->dv_hashtab.ht_used; 6377 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6378 { 6379 if (!HASHITEM_EMPTY(hi)) 6380 { 6381 --todo; 6382 6383 if (first) 6384 first = FALSE; 6385 else 6386 ga_concat(&ga, (char_u *)", "); 6387 6388 tofree = string_quote(hi->hi_key, FALSE); 6389 if (tofree != NULL) 6390 { 6391 ga_concat(&ga, tofree); 6392 vim_free(tofree); 6393 } 6394 ga_concat(&ga, (char_u *)": "); 6395 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6396 if (s != NULL) 6397 ga_concat(&ga, s); 6398 vim_free(tofree); 6399 if (s == NULL) 6400 break; 6401 } 6402 } 6403 if (todo > 0) 6404 { 6405 vim_free(ga.ga_data); 6406 return NULL; 6407 } 6408 6409 ga_append(&ga, '}'); 6410 ga_append(&ga, NUL); 6411 return (char_u *)ga.ga_data; 6412 } 6413 6414 /* 6415 * Allocate a variable for a Dictionary and fill it from "*arg". 6416 * Return OK or FAIL. Returns NOTDONE for {expr}. 6417 */ 6418 static int 6419 get_dict_tv(arg, rettv, evaluate) 6420 char_u **arg; 6421 typval_T *rettv; 6422 int evaluate; 6423 { 6424 dict_T *d = NULL; 6425 typval_T tvkey; 6426 typval_T tv; 6427 char_u *key; 6428 dictitem_T *item; 6429 char_u *start = skipwhite(*arg + 1); 6430 char_u buf[NUMBUFLEN]; 6431 6432 /* 6433 * First check if it's not a curly-braces thing: {expr}. 6434 * Must do this without evaluating, otherwise a function may be called 6435 * twice. Unfortunately this means we need to call eval1() twice for the 6436 * first item. 6437 * But {} is an empty Dictionary. 6438 */ 6439 if (*start != '}') 6440 { 6441 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6442 return FAIL; 6443 if (*start == '}') 6444 return NOTDONE; 6445 } 6446 6447 if (evaluate) 6448 { 6449 d = dict_alloc(); 6450 if (d == NULL) 6451 return FAIL; 6452 } 6453 tvkey.v_type = VAR_UNKNOWN; 6454 tv.v_type = VAR_UNKNOWN; 6455 6456 *arg = skipwhite(*arg + 1); 6457 while (**arg != '}' && **arg != NUL) 6458 { 6459 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6460 goto failret; 6461 if (**arg != ':') 6462 { 6463 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6464 clear_tv(&tvkey); 6465 goto failret; 6466 } 6467 key = get_tv_string_buf_chk(&tvkey, buf); 6468 if (key == NULL || *key == NUL) 6469 { 6470 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6471 if (key != NULL) 6472 EMSG(_(e_emptykey)); 6473 clear_tv(&tvkey); 6474 goto failret; 6475 } 6476 6477 *arg = skipwhite(*arg + 1); 6478 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6479 { 6480 clear_tv(&tvkey); 6481 goto failret; 6482 } 6483 if (evaluate) 6484 { 6485 item = dict_find(d, key, -1); 6486 if (item != NULL) 6487 { 6488 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6489 clear_tv(&tvkey); 6490 clear_tv(&tv); 6491 goto failret; 6492 } 6493 item = dictitem_alloc(key); 6494 clear_tv(&tvkey); 6495 if (item != NULL) 6496 { 6497 item->di_tv = tv; 6498 item->di_tv.v_lock = 0; 6499 if (dict_add(d, item) == FAIL) 6500 dictitem_free(item); 6501 } 6502 } 6503 6504 if (**arg == '}') 6505 break; 6506 if (**arg != ',') 6507 { 6508 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6509 goto failret; 6510 } 6511 *arg = skipwhite(*arg + 1); 6512 } 6513 6514 if (**arg != '}') 6515 { 6516 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6517 failret: 6518 if (evaluate) 6519 dict_free(d); 6520 return FAIL; 6521 } 6522 6523 *arg = skipwhite(*arg + 1); 6524 if (evaluate) 6525 { 6526 rettv->v_type = VAR_DICT; 6527 rettv->vval.v_dict = d; 6528 ++d->dv_refcount; 6529 } 6530 6531 return OK; 6532 } 6533 6534 /* 6535 * Return a string with the string representation of a variable. 6536 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6537 * "numbuf" is used for a number. 6538 * Does not put quotes around strings, as ":echo" displays values. 6539 * May return NULL; 6540 */ 6541 static char_u * 6542 echo_string(tv, tofree, numbuf) 6543 typval_T *tv; 6544 char_u **tofree; 6545 char_u *numbuf; 6546 { 6547 static int recurse = 0; 6548 char_u *r = NULL; 6549 6550 if (recurse >= DICT_MAXNEST) 6551 { 6552 EMSG(_("E724: variable nested too deep for displaying")); 6553 *tofree = NULL; 6554 return NULL; 6555 } 6556 ++recurse; 6557 6558 switch (tv->v_type) 6559 { 6560 case VAR_FUNC: 6561 *tofree = NULL; 6562 r = tv->vval.v_string; 6563 break; 6564 case VAR_LIST: 6565 *tofree = list2string(tv); 6566 r = *tofree; 6567 break; 6568 case VAR_DICT: 6569 *tofree = dict2string(tv); 6570 r = *tofree; 6571 break; 6572 case VAR_STRING: 6573 case VAR_NUMBER: 6574 *tofree = NULL; 6575 r = get_tv_string_buf(tv, numbuf); 6576 break; 6577 default: 6578 EMSG2(_(e_intern2), "echo_string()"); 6579 *tofree = NULL; 6580 } 6581 6582 --recurse; 6583 return r; 6584 } 6585 6586 /* 6587 * Return a string with the string representation of a variable. 6588 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6589 * "numbuf" is used for a number. 6590 * Puts quotes around strings, so that they can be parsed back by eval(). 6591 * May return NULL; 6592 */ 6593 static char_u * 6594 tv2string(tv, tofree, numbuf) 6595 typval_T *tv; 6596 char_u **tofree; 6597 char_u *numbuf; 6598 { 6599 switch (tv->v_type) 6600 { 6601 case VAR_FUNC: 6602 *tofree = string_quote(tv->vval.v_string, TRUE); 6603 return *tofree; 6604 case VAR_STRING: 6605 *tofree = string_quote(tv->vval.v_string, FALSE); 6606 return *tofree; 6607 case VAR_NUMBER: 6608 case VAR_LIST: 6609 case VAR_DICT: 6610 break; 6611 default: 6612 EMSG2(_(e_intern2), "tv2string()"); 6613 } 6614 return echo_string(tv, tofree, numbuf); 6615 } 6616 6617 /* 6618 * Return string "str" in ' quotes, doubling ' characters. 6619 * If "str" is NULL an empty string is assumed. 6620 * If "function" is TRUE make it function('string'). 6621 */ 6622 static char_u * 6623 string_quote(str, function) 6624 char_u *str; 6625 int function; 6626 { 6627 unsigned len; 6628 char_u *p, *r, *s; 6629 6630 len = (function ? 13 : 3); 6631 if (str != NULL) 6632 { 6633 len += STRLEN(str); 6634 for (p = str; *p != NUL; mb_ptr_adv(p)) 6635 if (*p == '\'') 6636 ++len; 6637 } 6638 s = r = alloc(len); 6639 if (r != NULL) 6640 { 6641 if (function) 6642 { 6643 STRCPY(r, "function('"); 6644 r += 10; 6645 } 6646 else 6647 *r++ = '\''; 6648 if (str != NULL) 6649 for (p = str; *p != NUL; ) 6650 { 6651 if (*p == '\'') 6652 *r++ = '\''; 6653 MB_COPY_CHAR(p, r); 6654 } 6655 *r++ = '\''; 6656 if (function) 6657 *r++ = ')'; 6658 *r++ = NUL; 6659 } 6660 return s; 6661 } 6662 6663 /* 6664 * Get the value of an environment variable. 6665 * "arg" is pointing to the '$'. It is advanced to after the name. 6666 * If the environment variable was not set, silently assume it is empty. 6667 * Always return OK. 6668 */ 6669 static int 6670 get_env_tv(arg, rettv, evaluate) 6671 char_u **arg; 6672 typval_T *rettv; 6673 int evaluate; 6674 { 6675 char_u *string = NULL; 6676 int len; 6677 int cc; 6678 char_u *name; 6679 int mustfree = FALSE; 6680 6681 ++*arg; 6682 name = *arg; 6683 len = get_env_len(arg); 6684 if (evaluate) 6685 { 6686 if (len != 0) 6687 { 6688 cc = name[len]; 6689 name[len] = NUL; 6690 /* first try vim_getenv(), fast for normal environment vars */ 6691 string = vim_getenv(name, &mustfree); 6692 if (string != NULL && *string != NUL) 6693 { 6694 if (!mustfree) 6695 string = vim_strsave(string); 6696 } 6697 else 6698 { 6699 if (mustfree) 6700 vim_free(string); 6701 6702 /* next try expanding things like $VIM and ${HOME} */ 6703 string = expand_env_save(name - 1); 6704 if (string != NULL && *string == '$') 6705 { 6706 vim_free(string); 6707 string = NULL; 6708 } 6709 } 6710 name[len] = cc; 6711 } 6712 rettv->v_type = VAR_STRING; 6713 rettv->vval.v_string = string; 6714 } 6715 6716 return OK; 6717 } 6718 6719 /* 6720 * Array with names and number of arguments of all internal functions 6721 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6722 */ 6723 static struct fst 6724 { 6725 char *f_name; /* function name */ 6726 char f_min_argc; /* minimal number of arguments */ 6727 char f_max_argc; /* maximal number of arguments */ 6728 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6729 /* implemenation of function */ 6730 } functions[] = 6731 { 6732 {"add", 2, 2, f_add}, 6733 {"append", 2, 2, f_append}, 6734 {"argc", 0, 0, f_argc}, 6735 {"argidx", 0, 0, f_argidx}, 6736 {"argv", 1, 1, f_argv}, 6737 {"browse", 4, 4, f_browse}, 6738 {"browsedir", 2, 2, f_browsedir}, 6739 {"bufexists", 1, 1, f_bufexists}, 6740 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6741 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6742 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6743 {"buflisted", 1, 1, f_buflisted}, 6744 {"bufloaded", 1, 1, f_bufloaded}, 6745 {"bufname", 1, 1, f_bufname}, 6746 {"bufnr", 1, 1, f_bufnr}, 6747 {"bufwinnr", 1, 1, f_bufwinnr}, 6748 {"byte2line", 1, 1, f_byte2line}, 6749 {"byteidx", 2, 2, f_byteidx}, 6750 {"call", 2, 3, f_call}, 6751 {"char2nr", 1, 1, f_char2nr}, 6752 {"cindent", 1, 1, f_cindent}, 6753 {"col", 1, 1, f_col}, 6754 #if defined(FEAT_INS_EXPAND) 6755 {"complete_add", 1, 1, f_complete_add}, 6756 {"complete_check", 0, 0, f_complete_check}, 6757 #endif 6758 {"confirm", 1, 4, f_confirm}, 6759 {"copy", 1, 1, f_copy}, 6760 {"count", 2, 4, f_count}, 6761 {"cscope_connection",0,3, f_cscope_connection}, 6762 {"cursor", 2, 2, f_cursor}, 6763 {"deepcopy", 1, 2, f_deepcopy}, 6764 {"delete", 1, 1, f_delete}, 6765 {"did_filetype", 0, 0, f_did_filetype}, 6766 {"diff_filler", 1, 1, f_diff_filler}, 6767 {"diff_hlID", 2, 2, f_diff_hlID}, 6768 {"empty", 1, 1, f_empty}, 6769 {"escape", 2, 2, f_escape}, 6770 {"eval", 1, 1, f_eval}, 6771 {"eventhandler", 0, 0, f_eventhandler}, 6772 {"executable", 1, 1, f_executable}, 6773 {"exists", 1, 1, f_exists}, 6774 {"expand", 1, 2, f_expand}, 6775 {"extend", 2, 3, f_extend}, 6776 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6777 {"filereadable", 1, 1, f_filereadable}, 6778 {"filewritable", 1, 1, f_filewritable}, 6779 {"filter", 2, 2, f_filter}, 6780 {"finddir", 1, 3, f_finddir}, 6781 {"findfile", 1, 3, f_findfile}, 6782 {"fnamemodify", 2, 2, f_fnamemodify}, 6783 {"foldclosed", 1, 1, f_foldclosed}, 6784 {"foldclosedend", 1, 1, f_foldclosedend}, 6785 {"foldlevel", 1, 1, f_foldlevel}, 6786 {"foldtext", 0, 0, f_foldtext}, 6787 {"foldtextresult", 1, 1, f_foldtextresult}, 6788 {"foreground", 0, 0, f_foreground}, 6789 {"function", 1, 1, f_function}, 6790 {"garbagecollect", 0, 0, f_garbagecollect}, 6791 {"get", 2, 3, f_get}, 6792 {"getbufline", 2, 3, f_getbufline}, 6793 {"getbufvar", 2, 2, f_getbufvar}, 6794 {"getchar", 0, 1, f_getchar}, 6795 {"getcharmod", 0, 0, f_getcharmod}, 6796 {"getcmdline", 0, 0, f_getcmdline}, 6797 {"getcmdpos", 0, 0, f_getcmdpos}, 6798 {"getcmdtype", 0, 0, f_getcmdtype}, 6799 {"getcwd", 0, 0, f_getcwd}, 6800 {"getfontname", 0, 1, f_getfontname}, 6801 {"getfperm", 1, 1, f_getfperm}, 6802 {"getfsize", 1, 1, f_getfsize}, 6803 {"getftime", 1, 1, f_getftime}, 6804 {"getftype", 1, 1, f_getftype}, 6805 {"getline", 1, 2, f_getline}, 6806 {"getqflist", 0, 0, f_getqflist}, 6807 {"getreg", 0, 2, f_getreg}, 6808 {"getregtype", 0, 1, f_getregtype}, 6809 {"getwinposx", 0, 0, f_getwinposx}, 6810 {"getwinposy", 0, 0, f_getwinposy}, 6811 {"getwinvar", 2, 2, f_getwinvar}, 6812 {"glob", 1, 1, f_glob}, 6813 {"globpath", 2, 2, f_globpath}, 6814 {"has", 1, 1, f_has}, 6815 {"has_key", 2, 2, f_has_key}, 6816 {"hasmapto", 1, 2, f_hasmapto}, 6817 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6818 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6819 {"histadd", 2, 2, f_histadd}, 6820 {"histdel", 1, 2, f_histdel}, 6821 {"histget", 1, 2, f_histget}, 6822 {"histnr", 1, 1, f_histnr}, 6823 {"hlID", 1, 1, f_hlID}, 6824 {"hlexists", 1, 1, f_hlexists}, 6825 {"hostname", 0, 0, f_hostname}, 6826 {"iconv", 3, 3, f_iconv}, 6827 {"indent", 1, 1, f_indent}, 6828 {"index", 2, 4, f_index}, 6829 {"input", 1, 3, f_input}, 6830 {"inputdialog", 1, 3, f_inputdialog}, 6831 {"inputlist", 1, 1, f_inputlist}, 6832 {"inputrestore", 0, 0, f_inputrestore}, 6833 {"inputsave", 0, 0, f_inputsave}, 6834 {"inputsecret", 1, 2, f_inputsecret}, 6835 {"insert", 2, 3, f_insert}, 6836 {"isdirectory", 1, 1, f_isdirectory}, 6837 {"islocked", 1, 1, f_islocked}, 6838 {"items", 1, 1, f_items}, 6839 {"join", 1, 2, f_join}, 6840 {"keys", 1, 1, f_keys}, 6841 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6842 {"len", 1, 1, f_len}, 6843 {"libcall", 3, 3, f_libcall}, 6844 {"libcallnr", 3, 3, f_libcallnr}, 6845 {"line", 1, 1, f_line}, 6846 {"line2byte", 1, 1, f_line2byte}, 6847 {"lispindent", 1, 1, f_lispindent}, 6848 {"localtime", 0, 0, f_localtime}, 6849 {"map", 2, 2, f_map}, 6850 {"maparg", 1, 2, f_maparg}, 6851 {"mapcheck", 1, 2, f_mapcheck}, 6852 {"match", 2, 4, f_match}, 6853 {"matchend", 2, 4, f_matchend}, 6854 {"matchlist", 2, 4, f_matchlist}, 6855 {"matchstr", 2, 4, f_matchstr}, 6856 {"max", 1, 1, f_max}, 6857 {"min", 1, 1, f_min}, 6858 #ifdef vim_mkdir 6859 {"mkdir", 1, 3, f_mkdir}, 6860 #endif 6861 {"mode", 0, 0, f_mode}, 6862 {"nextnonblank", 1, 1, f_nextnonblank}, 6863 {"nr2char", 1, 1, f_nr2char}, 6864 {"prevnonblank", 1, 1, f_prevnonblank}, 6865 {"printf", 2, 19, f_printf}, 6866 {"range", 1, 3, f_range}, 6867 {"readfile", 1, 3, f_readfile}, 6868 {"remote_expr", 2, 3, f_remote_expr}, 6869 {"remote_foreground", 1, 1, f_remote_foreground}, 6870 {"remote_peek", 1, 2, f_remote_peek}, 6871 {"remote_read", 1, 1, f_remote_read}, 6872 {"remote_send", 2, 3, f_remote_send}, 6873 {"remove", 2, 3, f_remove}, 6874 {"rename", 2, 2, f_rename}, 6875 {"repeat", 2, 2, f_repeat}, 6876 {"resolve", 1, 1, f_resolve}, 6877 {"reverse", 1, 1, f_reverse}, 6878 {"search", 1, 2, f_search}, 6879 {"searchdecl", 1, 3, f_searchdecl}, 6880 {"searchpair", 3, 5, f_searchpair}, 6881 {"server2client", 2, 2, f_server2client}, 6882 {"serverlist", 0, 0, f_serverlist}, 6883 {"setbufvar", 3, 3, f_setbufvar}, 6884 {"setcmdpos", 1, 1, f_setcmdpos}, 6885 {"setline", 2, 2, f_setline}, 6886 {"setqflist", 1, 2, f_setqflist}, 6887 {"setreg", 2, 3, f_setreg}, 6888 {"setwinvar", 3, 3, f_setwinvar}, 6889 {"simplify", 1, 1, f_simplify}, 6890 {"sort", 1, 2, f_sort}, 6891 {"soundfold", 1, 1, f_soundfold}, 6892 {"spellbadword", 0, 1, f_spellbadword}, 6893 {"spellsuggest", 1, 3, f_spellsuggest}, 6894 {"split", 1, 3, f_split}, 6895 #ifdef HAVE_STRFTIME 6896 {"strftime", 1, 2, f_strftime}, 6897 #endif 6898 {"stridx", 2, 3, f_stridx}, 6899 {"string", 1, 1, f_string}, 6900 {"strlen", 1, 1, f_strlen}, 6901 {"strpart", 2, 3, f_strpart}, 6902 {"strridx", 2, 3, f_strridx}, 6903 {"strtrans", 1, 1, f_strtrans}, 6904 {"submatch", 1, 1, f_submatch}, 6905 {"substitute", 4, 4, f_substitute}, 6906 {"synID", 3, 3, f_synID}, 6907 {"synIDattr", 2, 3, f_synIDattr}, 6908 {"synIDtrans", 1, 1, f_synIDtrans}, 6909 {"system", 1, 2, f_system}, 6910 {"tagfiles", 0, 0, f_tagfiles}, 6911 {"taglist", 1, 1, f_taglist}, 6912 {"tempname", 0, 0, f_tempname}, 6913 {"test", 1, 1, f_test}, 6914 {"tolower", 1, 1, f_tolower}, 6915 {"toupper", 1, 1, f_toupper}, 6916 {"tr", 3, 3, f_tr}, 6917 {"type", 1, 1, f_type}, 6918 {"values", 1, 1, f_values}, 6919 {"virtcol", 1, 1, f_virtcol}, 6920 {"visualmode", 0, 1, f_visualmode}, 6921 {"winbufnr", 1, 1, f_winbufnr}, 6922 {"wincol", 0, 0, f_wincol}, 6923 {"winheight", 1, 1, f_winheight}, 6924 {"winline", 0, 0, f_winline}, 6925 {"winnr", 0, 1, f_winnr}, 6926 {"winrestcmd", 0, 0, f_winrestcmd}, 6927 {"winwidth", 1, 1, f_winwidth}, 6928 {"writefile", 2, 3, f_writefile}, 6929 }; 6930 6931 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6932 6933 /* 6934 * Function given to ExpandGeneric() to obtain the list of internal 6935 * or user defined function names. 6936 */ 6937 char_u * 6938 get_function_name(xp, idx) 6939 expand_T *xp; 6940 int idx; 6941 { 6942 static int intidx = -1; 6943 char_u *name; 6944 6945 if (idx == 0) 6946 intidx = -1; 6947 if (intidx < 0) 6948 { 6949 name = get_user_func_name(xp, idx); 6950 if (name != NULL) 6951 return name; 6952 } 6953 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6954 { 6955 STRCPY(IObuff, functions[intidx].f_name); 6956 STRCAT(IObuff, "("); 6957 if (functions[intidx].f_max_argc == 0) 6958 STRCAT(IObuff, ")"); 6959 return IObuff; 6960 } 6961 6962 return NULL; 6963 } 6964 6965 /* 6966 * Function given to ExpandGeneric() to obtain the list of internal or 6967 * user defined variable or function names. 6968 */ 6969 /*ARGSUSED*/ 6970 char_u * 6971 get_expr_name(xp, idx) 6972 expand_T *xp; 6973 int idx; 6974 { 6975 static int intidx = -1; 6976 char_u *name; 6977 6978 if (idx == 0) 6979 intidx = -1; 6980 if (intidx < 0) 6981 { 6982 name = get_function_name(xp, idx); 6983 if (name != NULL) 6984 return name; 6985 } 6986 return get_user_var_name(xp, ++intidx); 6987 } 6988 6989 #endif /* FEAT_CMDL_COMPL */ 6990 6991 /* 6992 * Find internal function in table above. 6993 * Return index, or -1 if not found 6994 */ 6995 static int 6996 find_internal_func(name) 6997 char_u *name; /* name of the function */ 6998 { 6999 int first = 0; 7000 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 7001 int cmp; 7002 int x; 7003 7004 /* 7005 * Find the function name in the table. Binary search. 7006 */ 7007 while (first <= last) 7008 { 7009 x = first + ((unsigned)(last - first) >> 1); 7010 cmp = STRCMP(name, functions[x].f_name); 7011 if (cmp < 0) 7012 last = x - 1; 7013 else if (cmp > 0) 7014 first = x + 1; 7015 else 7016 return x; 7017 } 7018 return -1; 7019 } 7020 7021 /* 7022 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7023 * name it contains, otherwise return "name". 7024 */ 7025 static char_u * 7026 deref_func_name(name, lenp) 7027 char_u *name; 7028 int *lenp; 7029 { 7030 dictitem_T *v; 7031 int cc; 7032 7033 cc = name[*lenp]; 7034 name[*lenp] = NUL; 7035 v = find_var(name, NULL); 7036 name[*lenp] = cc; 7037 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7038 { 7039 if (v->di_tv.vval.v_string == NULL) 7040 { 7041 *lenp = 0; 7042 return (char_u *)""; /* just in case */ 7043 } 7044 *lenp = STRLEN(v->di_tv.vval.v_string); 7045 return v->di_tv.vval.v_string; 7046 } 7047 7048 return name; 7049 } 7050 7051 /* 7052 * Allocate a variable for the result of a function. 7053 * Return OK or FAIL. 7054 */ 7055 static int 7056 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7057 evaluate, selfdict) 7058 char_u *name; /* name of the function */ 7059 int len; /* length of "name" */ 7060 typval_T *rettv; 7061 char_u **arg; /* argument, pointing to the '(' */ 7062 linenr_T firstline; /* first line of range */ 7063 linenr_T lastline; /* last line of range */ 7064 int *doesrange; /* return: function handled range */ 7065 int evaluate; 7066 dict_T *selfdict; /* Dictionary for "self" */ 7067 { 7068 char_u *argp; 7069 int ret = OK; 7070 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7071 int argcount = 0; /* number of arguments found */ 7072 7073 /* 7074 * Get the arguments. 7075 */ 7076 argp = *arg; 7077 while (argcount < MAX_FUNC_ARGS) 7078 { 7079 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7080 if (*argp == ')' || *argp == ',' || *argp == NUL) 7081 break; 7082 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7083 { 7084 ret = FAIL; 7085 break; 7086 } 7087 ++argcount; 7088 if (*argp != ',') 7089 break; 7090 } 7091 if (*argp == ')') 7092 ++argp; 7093 else 7094 ret = FAIL; 7095 7096 if (ret == OK) 7097 ret = call_func(name, len, rettv, argcount, argvars, 7098 firstline, lastline, doesrange, evaluate, selfdict); 7099 else if (!aborting()) 7100 { 7101 if (argcount == MAX_FUNC_ARGS) 7102 emsg_funcname("E740: Too many arguments for function %s", name); 7103 else 7104 emsg_funcname("E116: Invalid arguments for function %s", name); 7105 } 7106 7107 while (--argcount >= 0) 7108 clear_tv(&argvars[argcount]); 7109 7110 *arg = skipwhite(argp); 7111 return ret; 7112 } 7113 7114 7115 /* 7116 * Call a function with its resolved parameters 7117 * Return OK or FAIL. 7118 */ 7119 static int 7120 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7121 doesrange, evaluate, selfdict) 7122 char_u *name; /* name of the function */ 7123 int len; /* length of "name" */ 7124 typval_T *rettv; /* return value goes here */ 7125 int argcount; /* number of "argvars" */ 7126 typval_T *argvars; /* vars for arguments */ 7127 linenr_T firstline; /* first line of range */ 7128 linenr_T lastline; /* last line of range */ 7129 int *doesrange; /* return: function handled range */ 7130 int evaluate; 7131 dict_T *selfdict; /* Dictionary for "self" */ 7132 { 7133 int ret = FAIL; 7134 #define ERROR_UNKNOWN 0 7135 #define ERROR_TOOMANY 1 7136 #define ERROR_TOOFEW 2 7137 #define ERROR_SCRIPT 3 7138 #define ERROR_DICT 4 7139 #define ERROR_NONE 5 7140 #define ERROR_OTHER 6 7141 int error = ERROR_NONE; 7142 int i; 7143 int llen; 7144 ufunc_T *fp; 7145 int cc; 7146 #define FLEN_FIXED 40 7147 char_u fname_buf[FLEN_FIXED + 1]; 7148 char_u *fname; 7149 7150 /* 7151 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7152 * Change <SNR>123_name() to K_SNR 123_name(). 7153 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7154 */ 7155 cc = name[len]; 7156 name[len] = NUL; 7157 llen = eval_fname_script(name); 7158 if (llen > 0) 7159 { 7160 fname_buf[0] = K_SPECIAL; 7161 fname_buf[1] = KS_EXTRA; 7162 fname_buf[2] = (int)KE_SNR; 7163 i = 3; 7164 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7165 { 7166 if (current_SID <= 0) 7167 error = ERROR_SCRIPT; 7168 else 7169 { 7170 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7171 i = (int)STRLEN(fname_buf); 7172 } 7173 } 7174 if (i + STRLEN(name + llen) < FLEN_FIXED) 7175 { 7176 STRCPY(fname_buf + i, name + llen); 7177 fname = fname_buf; 7178 } 7179 else 7180 { 7181 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7182 if (fname == NULL) 7183 error = ERROR_OTHER; 7184 else 7185 { 7186 mch_memmove(fname, fname_buf, (size_t)i); 7187 STRCPY(fname + i, name + llen); 7188 } 7189 } 7190 } 7191 else 7192 fname = name; 7193 7194 *doesrange = FALSE; 7195 7196 7197 /* execute the function if no errors detected and executing */ 7198 if (evaluate && error == ERROR_NONE) 7199 { 7200 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7201 error = ERROR_UNKNOWN; 7202 7203 if (!builtin_function(fname)) 7204 { 7205 /* 7206 * User defined function. 7207 */ 7208 fp = find_func(fname); 7209 7210 #ifdef FEAT_AUTOCMD 7211 /* Trigger FuncUndefined event, may load the function. */ 7212 if (fp == NULL 7213 && apply_autocmds(EVENT_FUNCUNDEFINED, 7214 fname, fname, TRUE, NULL) 7215 && !aborting()) 7216 { 7217 /* executed an autocommand, search for the function again */ 7218 fp = find_func(fname); 7219 } 7220 #endif 7221 /* Try loading a package. */ 7222 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7223 { 7224 /* loaded a package, search for the function again */ 7225 fp = find_func(fname); 7226 } 7227 7228 if (fp != NULL) 7229 { 7230 if (fp->uf_flags & FC_RANGE) 7231 *doesrange = TRUE; 7232 if (argcount < fp->uf_args.ga_len) 7233 error = ERROR_TOOFEW; 7234 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7235 error = ERROR_TOOMANY; 7236 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7237 error = ERROR_DICT; 7238 else 7239 { 7240 /* 7241 * Call the user function. 7242 * Save and restore search patterns, script variables and 7243 * redo buffer. 7244 */ 7245 save_search_patterns(); 7246 saveRedobuff(); 7247 ++fp->uf_calls; 7248 call_user_func(fp, argcount, argvars, rettv, 7249 firstline, lastline, 7250 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7251 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7252 && fp->uf_refcount <= 0) 7253 /* Function was unreferenced while being used, free it 7254 * now. */ 7255 func_free(fp); 7256 restoreRedobuff(); 7257 restore_search_patterns(); 7258 error = ERROR_NONE; 7259 } 7260 } 7261 } 7262 else 7263 { 7264 /* 7265 * Find the function name in the table, call its implementation. 7266 */ 7267 i = find_internal_func(fname); 7268 if (i >= 0) 7269 { 7270 if (argcount < functions[i].f_min_argc) 7271 error = ERROR_TOOFEW; 7272 else if (argcount > functions[i].f_max_argc) 7273 error = ERROR_TOOMANY; 7274 else 7275 { 7276 argvars[argcount].v_type = VAR_UNKNOWN; 7277 functions[i].f_func(argvars, rettv); 7278 error = ERROR_NONE; 7279 } 7280 } 7281 } 7282 /* 7283 * The function call (or "FuncUndefined" autocommand sequence) might 7284 * have been aborted by an error, an interrupt, or an explicitly thrown 7285 * exception that has not been caught so far. This situation can be 7286 * tested for by calling aborting(). For an error in an internal 7287 * function or for the "E132" error in call_user_func(), however, the 7288 * throw point at which the "force_abort" flag (temporarily reset by 7289 * emsg()) is normally updated has not been reached yet. We need to 7290 * update that flag first to make aborting() reliable. 7291 */ 7292 update_force_abort(); 7293 } 7294 if (error == ERROR_NONE) 7295 ret = OK; 7296 7297 /* 7298 * Report an error unless the argument evaluation or function call has been 7299 * cancelled due to an aborting error, an interrupt, or an exception. 7300 */ 7301 if (!aborting()) 7302 { 7303 switch (error) 7304 { 7305 case ERROR_UNKNOWN: 7306 emsg_funcname("E117: Unknown function: %s", name); 7307 break; 7308 case ERROR_TOOMANY: 7309 emsg_funcname(e_toomanyarg, name); 7310 break; 7311 case ERROR_TOOFEW: 7312 emsg_funcname("E119: Not enough arguments for function: %s", 7313 name); 7314 break; 7315 case ERROR_SCRIPT: 7316 emsg_funcname("E120: Using <SID> not in a script context: %s", 7317 name); 7318 break; 7319 case ERROR_DICT: 7320 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7321 name); 7322 break; 7323 } 7324 } 7325 7326 name[len] = cc; 7327 if (fname != name && fname != fname_buf) 7328 vim_free(fname); 7329 7330 return ret; 7331 } 7332 7333 /* 7334 * Give an error message with a function name. Handle <SNR> things. 7335 */ 7336 static void 7337 emsg_funcname(msg, name) 7338 char *msg; 7339 char_u *name; 7340 { 7341 char_u *p; 7342 7343 if (*name == K_SPECIAL) 7344 p = concat_str((char_u *)"<SNR>", name + 3); 7345 else 7346 p = name; 7347 EMSG2(_(msg), p); 7348 if (p != name) 7349 vim_free(p); 7350 } 7351 7352 /********************************************* 7353 * Implementation of the built-in functions 7354 */ 7355 7356 /* 7357 * "add(list, item)" function 7358 */ 7359 static void 7360 f_add(argvars, rettv) 7361 typval_T *argvars; 7362 typval_T *rettv; 7363 { 7364 list_T *l; 7365 7366 rettv->vval.v_number = 1; /* Default: Failed */ 7367 if (argvars[0].v_type == VAR_LIST) 7368 { 7369 if ((l = argvars[0].vval.v_list) != NULL 7370 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7371 && list_append_tv(l, &argvars[1]) == OK) 7372 copy_tv(&argvars[0], rettv); 7373 } 7374 else 7375 EMSG(_(e_listreq)); 7376 } 7377 7378 /* 7379 * "append(lnum, string/list)" function 7380 */ 7381 static void 7382 f_append(argvars, rettv) 7383 typval_T *argvars; 7384 typval_T *rettv; 7385 { 7386 long lnum; 7387 char_u *line; 7388 list_T *l = NULL; 7389 listitem_T *li = NULL; 7390 typval_T *tv; 7391 long added = 0; 7392 7393 lnum = get_tv_lnum(argvars); 7394 if (lnum >= 0 7395 && lnum <= curbuf->b_ml.ml_line_count 7396 && u_save(lnum, lnum + 1) == OK) 7397 { 7398 if (argvars[1].v_type == VAR_LIST) 7399 { 7400 l = argvars[1].vval.v_list; 7401 if (l == NULL) 7402 return; 7403 li = l->lv_first; 7404 } 7405 rettv->vval.v_number = 0; /* Default: Success */ 7406 for (;;) 7407 { 7408 if (l == NULL) 7409 tv = &argvars[1]; /* append a string */ 7410 else if (li == NULL) 7411 break; /* end of list */ 7412 else 7413 tv = &li->li_tv; /* append item from list */ 7414 line = get_tv_string_chk(tv); 7415 if (line == NULL) /* type error */ 7416 { 7417 rettv->vval.v_number = 1; /* Failed */ 7418 break; 7419 } 7420 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7421 ++added; 7422 if (l == NULL) 7423 break; 7424 li = li->li_next; 7425 } 7426 7427 appended_lines_mark(lnum, added); 7428 if (curwin->w_cursor.lnum > lnum) 7429 curwin->w_cursor.lnum += added; 7430 } 7431 else 7432 rettv->vval.v_number = 1; /* Failed */ 7433 } 7434 7435 /* 7436 * "argc()" function 7437 */ 7438 /* ARGSUSED */ 7439 static void 7440 f_argc(argvars, rettv) 7441 typval_T *argvars; 7442 typval_T *rettv; 7443 { 7444 rettv->vval.v_number = ARGCOUNT; 7445 } 7446 7447 /* 7448 * "argidx()" function 7449 */ 7450 /* ARGSUSED */ 7451 static void 7452 f_argidx(argvars, rettv) 7453 typval_T *argvars; 7454 typval_T *rettv; 7455 { 7456 rettv->vval.v_number = curwin->w_arg_idx; 7457 } 7458 7459 /* 7460 * "argv(nr)" function 7461 */ 7462 static void 7463 f_argv(argvars, rettv) 7464 typval_T *argvars; 7465 typval_T *rettv; 7466 { 7467 int idx; 7468 7469 idx = get_tv_number_chk(&argvars[0], NULL); 7470 if (idx >= 0 && idx < ARGCOUNT) 7471 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7472 else 7473 rettv->vval.v_string = NULL; 7474 rettv->v_type = VAR_STRING; 7475 } 7476 7477 /* 7478 * "browse(save, title, initdir, default)" function 7479 */ 7480 /* ARGSUSED */ 7481 static void 7482 f_browse(argvars, rettv) 7483 typval_T *argvars; 7484 typval_T *rettv; 7485 { 7486 #ifdef FEAT_BROWSE 7487 int save; 7488 char_u *title; 7489 char_u *initdir; 7490 char_u *defname; 7491 char_u buf[NUMBUFLEN]; 7492 char_u buf2[NUMBUFLEN]; 7493 int error = FALSE; 7494 7495 save = get_tv_number_chk(&argvars[0], &error); 7496 title = get_tv_string_chk(&argvars[1]); 7497 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7498 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7499 7500 if (error || title == NULL || initdir == NULL || defname == NULL) 7501 rettv->vval.v_string = NULL; 7502 else 7503 rettv->vval.v_string = 7504 do_browse(save ? BROWSE_SAVE : 0, 7505 title, defname, NULL, initdir, NULL, curbuf); 7506 #else 7507 rettv->vval.v_string = NULL; 7508 #endif 7509 rettv->v_type = VAR_STRING; 7510 } 7511 7512 /* 7513 * "browsedir(title, initdir)" function 7514 */ 7515 /* ARGSUSED */ 7516 static void 7517 f_browsedir(argvars, rettv) 7518 typval_T *argvars; 7519 typval_T *rettv; 7520 { 7521 #ifdef FEAT_BROWSE 7522 char_u *title; 7523 char_u *initdir; 7524 char_u buf[NUMBUFLEN]; 7525 7526 title = get_tv_string_chk(&argvars[0]); 7527 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7528 7529 if (title == NULL || initdir == NULL) 7530 rettv->vval.v_string = NULL; 7531 else 7532 rettv->vval.v_string = do_browse(BROWSE_DIR, 7533 title, NULL, NULL, initdir, NULL, curbuf); 7534 #else 7535 rettv->vval.v_string = NULL; 7536 #endif 7537 rettv->v_type = VAR_STRING; 7538 } 7539 7540 static buf_T *find_buffer __ARGS((typval_T *avar)); 7541 7542 /* 7543 * Find a buffer by number or exact name. 7544 */ 7545 static buf_T * 7546 find_buffer(avar) 7547 typval_T *avar; 7548 { 7549 buf_T *buf = NULL; 7550 7551 if (avar->v_type == VAR_NUMBER) 7552 buf = buflist_findnr((int)avar->vval.v_number); 7553 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7554 { 7555 buf = buflist_findname_exp(avar->vval.v_string); 7556 if (buf == NULL) 7557 { 7558 /* No full path name match, try a match with a URL or a "nofile" 7559 * buffer, these don't use the full path. */ 7560 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7561 if (buf->b_fname != NULL 7562 && (path_with_url(buf->b_fname) 7563 #ifdef FEAT_QUICKFIX 7564 || bt_nofile(buf) 7565 #endif 7566 ) 7567 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7568 break; 7569 } 7570 } 7571 return buf; 7572 } 7573 7574 /* 7575 * "bufexists(expr)" function 7576 */ 7577 static void 7578 f_bufexists(argvars, rettv) 7579 typval_T *argvars; 7580 typval_T *rettv; 7581 { 7582 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7583 } 7584 7585 /* 7586 * "buflisted(expr)" function 7587 */ 7588 static void 7589 f_buflisted(argvars, rettv) 7590 typval_T *argvars; 7591 typval_T *rettv; 7592 { 7593 buf_T *buf; 7594 7595 buf = find_buffer(&argvars[0]); 7596 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7597 } 7598 7599 /* 7600 * "bufloaded(expr)" function 7601 */ 7602 static void 7603 f_bufloaded(argvars, rettv) 7604 typval_T *argvars; 7605 typval_T *rettv; 7606 { 7607 buf_T *buf; 7608 7609 buf = find_buffer(&argvars[0]); 7610 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7611 } 7612 7613 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7614 7615 /* 7616 * Get buffer by number or pattern. 7617 */ 7618 static buf_T * 7619 get_buf_tv(tv) 7620 typval_T *tv; 7621 { 7622 char_u *name = tv->vval.v_string; 7623 int save_magic; 7624 char_u *save_cpo; 7625 buf_T *buf; 7626 7627 if (tv->v_type == VAR_NUMBER) 7628 return buflist_findnr((int)tv->vval.v_number); 7629 if (tv->v_type != VAR_STRING) 7630 return NULL; 7631 if (name == NULL || *name == NUL) 7632 return curbuf; 7633 if (name[0] == '$' && name[1] == NUL) 7634 return lastbuf; 7635 7636 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7637 save_magic = p_magic; 7638 p_magic = TRUE; 7639 save_cpo = p_cpo; 7640 p_cpo = (char_u *)""; 7641 7642 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7643 TRUE, FALSE)); 7644 7645 p_magic = save_magic; 7646 p_cpo = save_cpo; 7647 7648 /* If not found, try expanding the name, like done for bufexists(). */ 7649 if (buf == NULL) 7650 buf = find_buffer(tv); 7651 7652 return buf; 7653 } 7654 7655 /* 7656 * "bufname(expr)" function 7657 */ 7658 static void 7659 f_bufname(argvars, rettv) 7660 typval_T *argvars; 7661 typval_T *rettv; 7662 { 7663 buf_T *buf; 7664 7665 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7666 ++emsg_off; 7667 buf = get_buf_tv(&argvars[0]); 7668 rettv->v_type = VAR_STRING; 7669 if (buf != NULL && buf->b_fname != NULL) 7670 rettv->vval.v_string = vim_strsave(buf->b_fname); 7671 else 7672 rettv->vval.v_string = NULL; 7673 --emsg_off; 7674 } 7675 7676 /* 7677 * "bufnr(expr)" function 7678 */ 7679 static void 7680 f_bufnr(argvars, rettv) 7681 typval_T *argvars; 7682 typval_T *rettv; 7683 { 7684 buf_T *buf; 7685 7686 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7687 ++emsg_off; 7688 buf = get_buf_tv(&argvars[0]); 7689 if (buf != NULL) 7690 rettv->vval.v_number = buf->b_fnum; 7691 else 7692 rettv->vval.v_number = -1; 7693 --emsg_off; 7694 } 7695 7696 /* 7697 * "bufwinnr(nr)" function 7698 */ 7699 static void 7700 f_bufwinnr(argvars, rettv) 7701 typval_T *argvars; 7702 typval_T *rettv; 7703 { 7704 #ifdef FEAT_WINDOWS 7705 win_T *wp; 7706 int winnr = 0; 7707 #endif 7708 buf_T *buf; 7709 7710 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7711 ++emsg_off; 7712 buf = get_buf_tv(&argvars[0]); 7713 #ifdef FEAT_WINDOWS 7714 for (wp = firstwin; wp; wp = wp->w_next) 7715 { 7716 ++winnr; 7717 if (wp->w_buffer == buf) 7718 break; 7719 } 7720 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7721 #else 7722 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7723 #endif 7724 --emsg_off; 7725 } 7726 7727 /* 7728 * "byte2line(byte)" function 7729 */ 7730 /*ARGSUSED*/ 7731 static void 7732 f_byte2line(argvars, rettv) 7733 typval_T *argvars; 7734 typval_T *rettv; 7735 { 7736 #ifndef FEAT_BYTEOFF 7737 rettv->vval.v_number = -1; 7738 #else 7739 long boff = 0; 7740 7741 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7742 if (boff < 0) 7743 rettv->vval.v_number = -1; 7744 else 7745 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7746 (linenr_T)0, &boff); 7747 #endif 7748 } 7749 7750 /* 7751 * "byteidx()" function 7752 */ 7753 /*ARGSUSED*/ 7754 static void 7755 f_byteidx(argvars, rettv) 7756 typval_T *argvars; 7757 typval_T *rettv; 7758 { 7759 #ifdef FEAT_MBYTE 7760 char_u *t; 7761 #endif 7762 char_u *str; 7763 long idx; 7764 7765 str = get_tv_string_chk(&argvars[0]); 7766 idx = get_tv_number_chk(&argvars[1], NULL); 7767 rettv->vval.v_number = -1; 7768 if (str == NULL || idx < 0) 7769 return; 7770 7771 #ifdef FEAT_MBYTE 7772 t = str; 7773 for ( ; idx > 0; idx--) 7774 { 7775 if (*t == NUL) /* EOL reached */ 7776 return; 7777 t += (*mb_ptr2len)(t); 7778 } 7779 rettv->vval.v_number = t - str; 7780 #else 7781 if (idx <= STRLEN(str)) 7782 rettv->vval.v_number = idx; 7783 #endif 7784 } 7785 7786 /* 7787 * "call(func, arglist)" function 7788 */ 7789 static void 7790 f_call(argvars, rettv) 7791 typval_T *argvars; 7792 typval_T *rettv; 7793 { 7794 char_u *func; 7795 typval_T argv[MAX_FUNC_ARGS]; 7796 int argc = 0; 7797 listitem_T *item; 7798 int dummy; 7799 dict_T *selfdict = NULL; 7800 7801 rettv->vval.v_number = 0; 7802 if (argvars[1].v_type != VAR_LIST) 7803 { 7804 EMSG(_(e_listreq)); 7805 return; 7806 } 7807 if (argvars[1].vval.v_list == NULL) 7808 return; 7809 7810 if (argvars[0].v_type == VAR_FUNC) 7811 func = argvars[0].vval.v_string; 7812 else 7813 func = get_tv_string(&argvars[0]); 7814 if (*func == NUL) 7815 return; /* type error or empty name */ 7816 7817 if (argvars[2].v_type != VAR_UNKNOWN) 7818 { 7819 if (argvars[2].v_type != VAR_DICT) 7820 { 7821 EMSG(_(e_dictreq)); 7822 return; 7823 } 7824 selfdict = argvars[2].vval.v_dict; 7825 } 7826 7827 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7828 item = item->li_next) 7829 { 7830 if (argc == MAX_FUNC_ARGS) 7831 { 7832 EMSG(_("E699: Too many arguments")); 7833 break; 7834 } 7835 /* Make a copy of each argument. This is needed to be able to set 7836 * v_lock to VAR_FIXED in the copy without changing the original list. 7837 */ 7838 copy_tv(&item->li_tv, &argv[argc++]); 7839 } 7840 7841 if (item == NULL) 7842 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7843 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7844 &dummy, TRUE, selfdict); 7845 7846 /* Free the arguments. */ 7847 while (argc > 0) 7848 clear_tv(&argv[--argc]); 7849 } 7850 7851 /* 7852 * "char2nr(string)" function 7853 */ 7854 static void 7855 f_char2nr(argvars, rettv) 7856 typval_T *argvars; 7857 typval_T *rettv; 7858 { 7859 #ifdef FEAT_MBYTE 7860 if (has_mbyte) 7861 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7862 else 7863 #endif 7864 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7865 } 7866 7867 /* 7868 * "cindent(lnum)" function 7869 */ 7870 static void 7871 f_cindent(argvars, rettv) 7872 typval_T *argvars; 7873 typval_T *rettv; 7874 { 7875 #ifdef FEAT_CINDENT 7876 pos_T pos; 7877 linenr_T lnum; 7878 7879 pos = curwin->w_cursor; 7880 lnum = get_tv_lnum(argvars); 7881 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7882 { 7883 curwin->w_cursor.lnum = lnum; 7884 rettv->vval.v_number = get_c_indent(); 7885 curwin->w_cursor = pos; 7886 } 7887 else 7888 #endif 7889 rettv->vval.v_number = -1; 7890 } 7891 7892 /* 7893 * "col(string)" function 7894 */ 7895 static void 7896 f_col(argvars, rettv) 7897 typval_T *argvars; 7898 typval_T *rettv; 7899 { 7900 colnr_T col = 0; 7901 pos_T *fp; 7902 7903 fp = var2fpos(&argvars[0], FALSE); 7904 if (fp != NULL) 7905 { 7906 if (fp->col == MAXCOL) 7907 { 7908 /* '> can be MAXCOL, get the length of the line then */ 7909 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7910 col = STRLEN(ml_get(fp->lnum)) + 1; 7911 else 7912 col = MAXCOL; 7913 } 7914 else 7915 { 7916 col = fp->col + 1; 7917 #ifdef FEAT_VIRTUALEDIT 7918 /* col(".") when the cursor is on the NUL at the end of the line 7919 * because of "coladd" can be seen as an extra column. */ 7920 if (virtual_active() && fp == &curwin->w_cursor) 7921 { 7922 char_u *p = ml_get_cursor(); 7923 7924 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7925 curwin->w_virtcol - curwin->w_cursor.coladd)) 7926 { 7927 # ifdef FEAT_MBYTE 7928 int l; 7929 7930 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 7931 col += l; 7932 # else 7933 if (*p != NUL && p[1] == NUL) 7934 ++col; 7935 # endif 7936 } 7937 } 7938 #endif 7939 } 7940 } 7941 rettv->vval.v_number = col; 7942 } 7943 7944 #if defined(FEAT_INS_EXPAND) 7945 /* 7946 * "complete_add()" function 7947 */ 7948 /*ARGSUSED*/ 7949 static void 7950 f_complete_add(argvars, rettv) 7951 typval_T *argvars; 7952 typval_T *rettv; 7953 { 7954 char_u *s; 7955 7956 s = get_tv_string_chk(&argvars[0]); 7957 if (s != NULL) 7958 rettv->vval.v_number = ins_compl_add(s, -1, NULL, FORWARD, 0); 7959 } 7960 7961 /* 7962 * "complete_check()" function 7963 */ 7964 /*ARGSUSED*/ 7965 static void 7966 f_complete_check(argvars, rettv) 7967 typval_T *argvars; 7968 typval_T *rettv; 7969 { 7970 int saved = RedrawingDisabled; 7971 7972 RedrawingDisabled = 0; 7973 ins_compl_check_keys(0); 7974 rettv->vval.v_number = compl_interrupted; 7975 RedrawingDisabled = saved; 7976 } 7977 #endif 7978 7979 /* 7980 * "confirm(message, buttons[, default [, type]])" function 7981 */ 7982 /*ARGSUSED*/ 7983 static void 7984 f_confirm(argvars, rettv) 7985 typval_T *argvars; 7986 typval_T *rettv; 7987 { 7988 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7989 char_u *message; 7990 char_u *buttons = NULL; 7991 char_u buf[NUMBUFLEN]; 7992 char_u buf2[NUMBUFLEN]; 7993 int def = 1; 7994 int type = VIM_GENERIC; 7995 char_u *typestr; 7996 int error = FALSE; 7997 7998 message = get_tv_string_chk(&argvars[0]); 7999 if (message == NULL) 8000 error = TRUE; 8001 if (argvars[1].v_type != VAR_UNKNOWN) 8002 { 8003 buttons = get_tv_string_buf_chk(&argvars[1], buf); 8004 if (buttons == NULL) 8005 error = TRUE; 8006 if (argvars[2].v_type != VAR_UNKNOWN) 8007 { 8008 def = get_tv_number_chk(&argvars[2], &error); 8009 if (argvars[3].v_type != VAR_UNKNOWN) 8010 { 8011 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 8012 if (typestr == NULL) 8013 error = TRUE; 8014 else 8015 { 8016 switch (TOUPPER_ASC(*typestr)) 8017 { 8018 case 'E': type = VIM_ERROR; break; 8019 case 'Q': type = VIM_QUESTION; break; 8020 case 'I': type = VIM_INFO; break; 8021 case 'W': type = VIM_WARNING; break; 8022 case 'G': type = VIM_GENERIC; break; 8023 } 8024 } 8025 } 8026 } 8027 } 8028 8029 if (buttons == NULL || *buttons == NUL) 8030 buttons = (char_u *)_("&Ok"); 8031 8032 if (error) 8033 rettv->vval.v_number = 0; 8034 else 8035 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8036 def, NULL); 8037 #else 8038 rettv->vval.v_number = 0; 8039 #endif 8040 } 8041 8042 /* 8043 * "copy()" function 8044 */ 8045 static void 8046 f_copy(argvars, rettv) 8047 typval_T *argvars; 8048 typval_T *rettv; 8049 { 8050 item_copy(&argvars[0], rettv, FALSE, 0); 8051 } 8052 8053 /* 8054 * "count()" function 8055 */ 8056 static void 8057 f_count(argvars, rettv) 8058 typval_T *argvars; 8059 typval_T *rettv; 8060 { 8061 long n = 0; 8062 int ic = FALSE; 8063 8064 if (argvars[0].v_type == VAR_LIST) 8065 { 8066 listitem_T *li; 8067 list_T *l; 8068 long idx; 8069 8070 if ((l = argvars[0].vval.v_list) != NULL) 8071 { 8072 li = l->lv_first; 8073 if (argvars[2].v_type != VAR_UNKNOWN) 8074 { 8075 int error = FALSE; 8076 8077 ic = get_tv_number_chk(&argvars[2], &error); 8078 if (argvars[3].v_type != VAR_UNKNOWN) 8079 { 8080 idx = get_tv_number_chk(&argvars[3], &error); 8081 if (!error) 8082 { 8083 li = list_find(l, idx); 8084 if (li == NULL) 8085 EMSGN(_(e_listidx), idx); 8086 } 8087 } 8088 if (error) 8089 li = NULL; 8090 } 8091 8092 for ( ; li != NULL; li = li->li_next) 8093 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8094 ++n; 8095 } 8096 } 8097 else if (argvars[0].v_type == VAR_DICT) 8098 { 8099 int todo; 8100 dict_T *d; 8101 hashitem_T *hi; 8102 8103 if ((d = argvars[0].vval.v_dict) != NULL) 8104 { 8105 int error = FALSE; 8106 8107 if (argvars[2].v_type != VAR_UNKNOWN) 8108 { 8109 ic = get_tv_number_chk(&argvars[2], &error); 8110 if (argvars[3].v_type != VAR_UNKNOWN) 8111 EMSG(_(e_invarg)); 8112 } 8113 8114 todo = error ? 0 : d->dv_hashtab.ht_used; 8115 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8116 { 8117 if (!HASHITEM_EMPTY(hi)) 8118 { 8119 --todo; 8120 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8121 ++n; 8122 } 8123 } 8124 } 8125 } 8126 else 8127 EMSG2(_(e_listdictarg), "count()"); 8128 rettv->vval.v_number = n; 8129 } 8130 8131 /* 8132 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8133 * 8134 * Checks the existence of a cscope connection. 8135 */ 8136 /*ARGSUSED*/ 8137 static void 8138 f_cscope_connection(argvars, rettv) 8139 typval_T *argvars; 8140 typval_T *rettv; 8141 { 8142 #ifdef FEAT_CSCOPE 8143 int num = 0; 8144 char_u *dbpath = NULL; 8145 char_u *prepend = NULL; 8146 char_u buf[NUMBUFLEN]; 8147 8148 if (argvars[0].v_type != VAR_UNKNOWN 8149 && argvars[1].v_type != VAR_UNKNOWN) 8150 { 8151 num = (int)get_tv_number(&argvars[0]); 8152 dbpath = get_tv_string(&argvars[1]); 8153 if (argvars[2].v_type != VAR_UNKNOWN) 8154 prepend = get_tv_string_buf(&argvars[2], buf); 8155 } 8156 8157 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8158 #else 8159 rettv->vval.v_number = 0; 8160 #endif 8161 } 8162 8163 /* 8164 * "cursor(lnum, col)" function 8165 * 8166 * Moves the cursor to the specified line and column 8167 */ 8168 /*ARGSUSED*/ 8169 static void 8170 f_cursor(argvars, rettv) 8171 typval_T *argvars; 8172 typval_T *rettv; 8173 { 8174 long line, col; 8175 8176 line = get_tv_lnum(argvars); 8177 col = get_tv_number_chk(&argvars[1], NULL); 8178 if (line < 0 || col < 0) 8179 return; /* type error; errmsg already given */ 8180 if (line > 0) 8181 curwin->w_cursor.lnum = line; 8182 if (col > 0) 8183 curwin->w_cursor.col = col - 1; 8184 #ifdef FEAT_VIRTUALEDIT 8185 curwin->w_cursor.coladd = 0; 8186 #endif 8187 8188 /* Make sure the cursor is in a valid position. */ 8189 check_cursor(); 8190 #ifdef FEAT_MBYTE 8191 /* Correct cursor for multi-byte character. */ 8192 if (has_mbyte) 8193 mb_adjust_cursor(); 8194 #endif 8195 8196 curwin->w_set_curswant = TRUE; 8197 } 8198 8199 /* 8200 * "deepcopy()" function 8201 */ 8202 static void 8203 f_deepcopy(argvars, rettv) 8204 typval_T *argvars; 8205 typval_T *rettv; 8206 { 8207 int noref = 0; 8208 8209 if (argvars[1].v_type != VAR_UNKNOWN) 8210 noref = get_tv_number_chk(&argvars[1], NULL); 8211 if (noref < 0 || noref > 1) 8212 EMSG(_(e_invarg)); 8213 else 8214 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8215 } 8216 8217 /* 8218 * "delete()" function 8219 */ 8220 static void 8221 f_delete(argvars, rettv) 8222 typval_T *argvars; 8223 typval_T *rettv; 8224 { 8225 if (check_restricted() || check_secure()) 8226 rettv->vval.v_number = -1; 8227 else 8228 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8229 } 8230 8231 /* 8232 * "did_filetype()" function 8233 */ 8234 /*ARGSUSED*/ 8235 static void 8236 f_did_filetype(argvars, rettv) 8237 typval_T *argvars; 8238 typval_T *rettv; 8239 { 8240 #ifdef FEAT_AUTOCMD 8241 rettv->vval.v_number = did_filetype; 8242 #else 8243 rettv->vval.v_number = 0; 8244 #endif 8245 } 8246 8247 /* 8248 * "diff_filler()" function 8249 */ 8250 /*ARGSUSED*/ 8251 static void 8252 f_diff_filler(argvars, rettv) 8253 typval_T *argvars; 8254 typval_T *rettv; 8255 { 8256 #ifdef FEAT_DIFF 8257 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8258 #endif 8259 } 8260 8261 /* 8262 * "diff_hlID()" function 8263 */ 8264 /*ARGSUSED*/ 8265 static void 8266 f_diff_hlID(argvars, rettv) 8267 typval_T *argvars; 8268 typval_T *rettv; 8269 { 8270 #ifdef FEAT_DIFF 8271 linenr_T lnum = get_tv_lnum(argvars); 8272 static linenr_T prev_lnum = 0; 8273 static int changedtick = 0; 8274 static int fnum = 0; 8275 static int change_start = 0; 8276 static int change_end = 0; 8277 static hlf_T hlID = 0; 8278 int filler_lines; 8279 int col; 8280 8281 if (lnum < 0) /* ignore type error in {lnum} arg */ 8282 lnum = 0; 8283 if (lnum != prev_lnum 8284 || changedtick != curbuf->b_changedtick 8285 || fnum != curbuf->b_fnum) 8286 { 8287 /* New line, buffer, change: need to get the values. */ 8288 filler_lines = diff_check(curwin, lnum); 8289 if (filler_lines < 0) 8290 { 8291 if (filler_lines == -1) 8292 { 8293 change_start = MAXCOL; 8294 change_end = -1; 8295 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8296 hlID = HLF_ADD; /* added line */ 8297 else 8298 hlID = HLF_CHD; /* changed line */ 8299 } 8300 else 8301 hlID = HLF_ADD; /* added line */ 8302 } 8303 else 8304 hlID = (hlf_T)0; 8305 prev_lnum = lnum; 8306 changedtick = curbuf->b_changedtick; 8307 fnum = curbuf->b_fnum; 8308 } 8309 8310 if (hlID == HLF_CHD || hlID == HLF_TXD) 8311 { 8312 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8313 if (col >= change_start && col <= change_end) 8314 hlID = HLF_TXD; /* changed text */ 8315 else 8316 hlID = HLF_CHD; /* changed line */ 8317 } 8318 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 8319 #endif 8320 } 8321 8322 /* 8323 * "empty({expr})" function 8324 */ 8325 static void 8326 f_empty(argvars, rettv) 8327 typval_T *argvars; 8328 typval_T *rettv; 8329 { 8330 int n; 8331 8332 switch (argvars[0].v_type) 8333 { 8334 case VAR_STRING: 8335 case VAR_FUNC: 8336 n = argvars[0].vval.v_string == NULL 8337 || *argvars[0].vval.v_string == NUL; 8338 break; 8339 case VAR_NUMBER: 8340 n = argvars[0].vval.v_number == 0; 8341 break; 8342 case VAR_LIST: 8343 n = argvars[0].vval.v_list == NULL 8344 || argvars[0].vval.v_list->lv_first == NULL; 8345 break; 8346 case VAR_DICT: 8347 n = argvars[0].vval.v_dict == NULL 8348 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8349 break; 8350 default: 8351 EMSG2(_(e_intern2), "f_empty()"); 8352 n = 0; 8353 } 8354 8355 rettv->vval.v_number = n; 8356 } 8357 8358 /* 8359 * "escape({string}, {chars})" function 8360 */ 8361 static void 8362 f_escape(argvars, rettv) 8363 typval_T *argvars; 8364 typval_T *rettv; 8365 { 8366 char_u buf[NUMBUFLEN]; 8367 8368 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8369 get_tv_string_buf(&argvars[1], buf)); 8370 rettv->v_type = VAR_STRING; 8371 } 8372 8373 /* 8374 * "eval()" function 8375 */ 8376 /*ARGSUSED*/ 8377 static void 8378 f_eval(argvars, rettv) 8379 typval_T *argvars; 8380 typval_T *rettv; 8381 { 8382 char_u *s; 8383 8384 s = get_tv_string_chk(&argvars[0]); 8385 if (s != NULL) 8386 s = skipwhite(s); 8387 8388 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8389 { 8390 rettv->v_type = VAR_NUMBER; 8391 rettv->vval.v_number = 0; 8392 } 8393 else if (*s != NUL) 8394 EMSG(_(e_trailing)); 8395 } 8396 8397 /* 8398 * "eventhandler()" function 8399 */ 8400 /*ARGSUSED*/ 8401 static void 8402 f_eventhandler(argvars, rettv) 8403 typval_T *argvars; 8404 typval_T *rettv; 8405 { 8406 rettv->vval.v_number = vgetc_busy; 8407 } 8408 8409 /* 8410 * "executable()" function 8411 */ 8412 static void 8413 f_executable(argvars, rettv) 8414 typval_T *argvars; 8415 typval_T *rettv; 8416 { 8417 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8418 } 8419 8420 /* 8421 * "exists()" function 8422 */ 8423 static void 8424 f_exists(argvars, rettv) 8425 typval_T *argvars; 8426 typval_T *rettv; 8427 { 8428 char_u *p; 8429 char_u *name; 8430 int n = FALSE; 8431 int len = 0; 8432 8433 p = get_tv_string(&argvars[0]); 8434 if (*p == '$') /* environment variable */ 8435 { 8436 /* first try "normal" environment variables (fast) */ 8437 if (mch_getenv(p + 1) != NULL) 8438 n = TRUE; 8439 else 8440 { 8441 /* try expanding things like $VIM and ${HOME} */ 8442 p = expand_env_save(p); 8443 if (p != NULL && *p != '$') 8444 n = TRUE; 8445 vim_free(p); 8446 } 8447 } 8448 else if (*p == '&' || *p == '+') /* option */ 8449 n = (get_option_tv(&p, NULL, TRUE) == OK); 8450 else if (*p == '*') /* internal or user defined function */ 8451 { 8452 n = function_exists(p + 1); 8453 } 8454 else if (*p == ':') 8455 { 8456 n = cmd_exists(p + 1); 8457 } 8458 else if (*p == '#') 8459 { 8460 #ifdef FEAT_AUTOCMD 8461 name = p + 1; 8462 p = vim_strchr(name, '#'); 8463 if (p != NULL) 8464 n = au_exists(name, p, p + 1); 8465 else 8466 n = au_exists(name, name + STRLEN(name), NULL); 8467 #endif 8468 } 8469 else /* internal variable */ 8470 { 8471 char_u *tofree; 8472 typval_T tv; 8473 8474 /* get_name_len() takes care of expanding curly braces */ 8475 name = p; 8476 len = get_name_len(&p, &tofree, TRUE, FALSE); 8477 if (len > 0) 8478 { 8479 if (tofree != NULL) 8480 name = tofree; 8481 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8482 if (n) 8483 { 8484 /* handle d.key, l[idx], f(expr) */ 8485 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8486 if (n) 8487 clear_tv(&tv); 8488 } 8489 } 8490 8491 vim_free(tofree); 8492 } 8493 8494 rettv->vval.v_number = n; 8495 } 8496 8497 /* 8498 * "expand()" function 8499 */ 8500 static void 8501 f_expand(argvars, rettv) 8502 typval_T *argvars; 8503 typval_T *rettv; 8504 { 8505 char_u *s; 8506 int len; 8507 char_u *errormsg; 8508 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8509 expand_T xpc; 8510 int error = FALSE; 8511 8512 rettv->v_type = VAR_STRING; 8513 s = get_tv_string(&argvars[0]); 8514 if (*s == '%' || *s == '#' || *s == '<') 8515 { 8516 ++emsg_off; 8517 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8518 --emsg_off; 8519 } 8520 else 8521 { 8522 /* When the optional second argument is non-zero, don't remove matches 8523 * for 'suffixes' and 'wildignore' */ 8524 if (argvars[1].v_type != VAR_UNKNOWN 8525 && get_tv_number_chk(&argvars[1], &error)) 8526 flags |= WILD_KEEP_ALL; 8527 if (!error) 8528 { 8529 ExpandInit(&xpc); 8530 xpc.xp_context = EXPAND_FILES; 8531 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8532 ExpandCleanup(&xpc); 8533 } 8534 else 8535 rettv->vval.v_string = NULL; 8536 } 8537 } 8538 8539 /* 8540 * "extend(list, list [, idx])" function 8541 * "extend(dict, dict [, action])" function 8542 */ 8543 static void 8544 f_extend(argvars, rettv) 8545 typval_T *argvars; 8546 typval_T *rettv; 8547 { 8548 rettv->vval.v_number = 0; 8549 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8550 { 8551 list_T *l1, *l2; 8552 listitem_T *item; 8553 long before; 8554 int error = FALSE; 8555 8556 l1 = argvars[0].vval.v_list; 8557 l2 = argvars[1].vval.v_list; 8558 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8559 && l2 != NULL) 8560 { 8561 if (argvars[2].v_type != VAR_UNKNOWN) 8562 { 8563 before = get_tv_number_chk(&argvars[2], &error); 8564 if (error) 8565 return; /* type error; errmsg already given */ 8566 8567 if (before == l1->lv_len) 8568 item = NULL; 8569 else 8570 { 8571 item = list_find(l1, before); 8572 if (item == NULL) 8573 { 8574 EMSGN(_(e_listidx), before); 8575 return; 8576 } 8577 } 8578 } 8579 else 8580 item = NULL; 8581 list_extend(l1, l2, item); 8582 8583 copy_tv(&argvars[0], rettv); 8584 } 8585 } 8586 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8587 { 8588 dict_T *d1, *d2; 8589 dictitem_T *di1; 8590 char_u *action; 8591 int i; 8592 hashitem_T *hi2; 8593 int todo; 8594 8595 d1 = argvars[0].vval.v_dict; 8596 d2 = argvars[1].vval.v_dict; 8597 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8598 && d2 != NULL) 8599 { 8600 /* Check the third argument. */ 8601 if (argvars[2].v_type != VAR_UNKNOWN) 8602 { 8603 static char *(av[]) = {"keep", "force", "error"}; 8604 8605 action = get_tv_string_chk(&argvars[2]); 8606 if (action == NULL) 8607 return; /* type error; errmsg already given */ 8608 for (i = 0; i < 3; ++i) 8609 if (STRCMP(action, av[i]) == 0) 8610 break; 8611 if (i == 3) 8612 { 8613 EMSGN(_(e_invarg2), action); 8614 return; 8615 } 8616 } 8617 else 8618 action = (char_u *)"force"; 8619 8620 /* Go over all entries in the second dict and add them to the 8621 * first dict. */ 8622 todo = d2->dv_hashtab.ht_used; 8623 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8624 { 8625 if (!HASHITEM_EMPTY(hi2)) 8626 { 8627 --todo; 8628 di1 = dict_find(d1, hi2->hi_key, -1); 8629 if (di1 == NULL) 8630 { 8631 di1 = dictitem_copy(HI2DI(hi2)); 8632 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8633 dictitem_free(di1); 8634 } 8635 else if (*action == 'e') 8636 { 8637 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8638 break; 8639 } 8640 else if (*action == 'f') 8641 { 8642 clear_tv(&di1->di_tv); 8643 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8644 } 8645 } 8646 } 8647 8648 copy_tv(&argvars[0], rettv); 8649 } 8650 } 8651 else 8652 EMSG2(_(e_listdictarg), "extend()"); 8653 } 8654 8655 /* 8656 * "filereadable()" function 8657 */ 8658 static void 8659 f_filereadable(argvars, rettv) 8660 typval_T *argvars; 8661 typval_T *rettv; 8662 { 8663 FILE *fd; 8664 char_u *p; 8665 int n; 8666 8667 p = get_tv_string(&argvars[0]); 8668 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8669 { 8670 n = TRUE; 8671 fclose(fd); 8672 } 8673 else 8674 n = FALSE; 8675 8676 rettv->vval.v_number = n; 8677 } 8678 8679 /* 8680 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8681 * rights to write into. 8682 */ 8683 static void 8684 f_filewritable(argvars, rettv) 8685 typval_T *argvars; 8686 typval_T *rettv; 8687 { 8688 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8689 } 8690 8691 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8692 8693 static void 8694 findfilendir(argvars, rettv, dir) 8695 typval_T *argvars; 8696 typval_T *rettv; 8697 int dir; 8698 { 8699 #ifdef FEAT_SEARCHPATH 8700 char_u *fname; 8701 char_u *fresult = NULL; 8702 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8703 char_u *p; 8704 char_u pathbuf[NUMBUFLEN]; 8705 int count = 1; 8706 int first = TRUE; 8707 8708 fname = get_tv_string(&argvars[0]); 8709 8710 if (argvars[1].v_type != VAR_UNKNOWN) 8711 { 8712 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8713 if (p == NULL) 8714 count = -1; /* error */ 8715 else 8716 { 8717 if (*p != NUL) 8718 path = p; 8719 8720 if (argvars[2].v_type != VAR_UNKNOWN) 8721 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8722 } 8723 } 8724 8725 if (*fname != NUL && count >= 0) 8726 { 8727 do 8728 { 8729 vim_free(fresult); 8730 fresult = find_file_in_path_option(first ? fname : NULL, 8731 first ? (int)STRLEN(fname) : 0, 8732 0, first, path, dir, NULL); 8733 first = FALSE; 8734 } while (--count > 0 && fresult != NULL); 8735 } 8736 8737 rettv->vval.v_string = fresult; 8738 #else 8739 rettv->vval.v_string = NULL; 8740 #endif 8741 rettv->v_type = VAR_STRING; 8742 } 8743 8744 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8745 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8746 8747 /* 8748 * Implementation of map() and filter(). 8749 */ 8750 static void 8751 filter_map(argvars, rettv, map) 8752 typval_T *argvars; 8753 typval_T *rettv; 8754 int map; 8755 { 8756 char_u buf[NUMBUFLEN]; 8757 char_u *expr; 8758 listitem_T *li, *nli; 8759 list_T *l = NULL; 8760 dictitem_T *di; 8761 hashtab_T *ht; 8762 hashitem_T *hi; 8763 dict_T *d = NULL; 8764 typval_T save_val; 8765 typval_T save_key; 8766 int rem; 8767 int todo; 8768 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8769 8770 8771 rettv->vval.v_number = 0; 8772 if (argvars[0].v_type == VAR_LIST) 8773 { 8774 if ((l = argvars[0].vval.v_list) == NULL 8775 || (map && tv_check_lock(l->lv_lock, msg))) 8776 return; 8777 } 8778 else if (argvars[0].v_type == VAR_DICT) 8779 { 8780 if ((d = argvars[0].vval.v_dict) == NULL 8781 || (map && tv_check_lock(d->dv_lock, msg))) 8782 return; 8783 } 8784 else 8785 { 8786 EMSG2(_(e_listdictarg), msg); 8787 return; 8788 } 8789 8790 expr = get_tv_string_buf_chk(&argvars[1], buf); 8791 /* On type errors, the preceding call has already displayed an error 8792 * message. Avoid a misleading error message for an empty string that 8793 * was not passed as argument. */ 8794 if (expr != NULL) 8795 { 8796 prepare_vimvar(VV_VAL, &save_val); 8797 expr = skipwhite(expr); 8798 8799 if (argvars[0].v_type == VAR_DICT) 8800 { 8801 prepare_vimvar(VV_KEY, &save_key); 8802 vimvars[VV_KEY].vv_type = VAR_STRING; 8803 8804 ht = &d->dv_hashtab; 8805 hash_lock(ht); 8806 todo = ht->ht_used; 8807 for (hi = ht->ht_array; todo > 0; ++hi) 8808 { 8809 if (!HASHITEM_EMPTY(hi)) 8810 { 8811 --todo; 8812 di = HI2DI(hi); 8813 if (tv_check_lock(di->di_tv.v_lock, msg)) 8814 break; 8815 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8816 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8817 break; 8818 if (!map && rem) 8819 dictitem_remove(d, di); 8820 clear_tv(&vimvars[VV_KEY].vv_tv); 8821 } 8822 } 8823 hash_unlock(ht); 8824 8825 restore_vimvar(VV_KEY, &save_key); 8826 } 8827 else 8828 { 8829 for (li = l->lv_first; li != NULL; li = nli) 8830 { 8831 if (tv_check_lock(li->li_tv.v_lock, msg)) 8832 break; 8833 nli = li->li_next; 8834 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8835 break; 8836 if (!map && rem) 8837 listitem_remove(l, li); 8838 } 8839 } 8840 8841 restore_vimvar(VV_VAL, &save_val); 8842 } 8843 8844 copy_tv(&argvars[0], rettv); 8845 } 8846 8847 static int 8848 filter_map_one(tv, expr, map, remp) 8849 typval_T *tv; 8850 char_u *expr; 8851 int map; 8852 int *remp; 8853 { 8854 typval_T rettv; 8855 char_u *s; 8856 8857 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8858 s = expr; 8859 if (eval1(&s, &rettv, TRUE) == FAIL) 8860 return FAIL; 8861 if (*s != NUL) /* check for trailing chars after expr */ 8862 { 8863 EMSG2(_(e_invexpr2), s); 8864 return FAIL; 8865 } 8866 if (map) 8867 { 8868 /* map(): replace the list item value */ 8869 clear_tv(tv); 8870 rettv.v_lock = 0; 8871 *tv = rettv; 8872 } 8873 else 8874 { 8875 int error = FALSE; 8876 8877 /* filter(): when expr is zero remove the item */ 8878 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8879 clear_tv(&rettv); 8880 /* On type error, nothing has been removed; return FAIL to stop the 8881 * loop. The error message was given by get_tv_number_chk(). */ 8882 if (error) 8883 return FAIL; 8884 } 8885 clear_tv(&vimvars[VV_VAL].vv_tv); 8886 return OK; 8887 } 8888 8889 /* 8890 * "filter()" function 8891 */ 8892 static void 8893 f_filter(argvars, rettv) 8894 typval_T *argvars; 8895 typval_T *rettv; 8896 { 8897 filter_map(argvars, rettv, FALSE); 8898 } 8899 8900 /* 8901 * "finddir({fname}[, {path}[, {count}]])" function 8902 */ 8903 static void 8904 f_finddir(argvars, rettv) 8905 typval_T *argvars; 8906 typval_T *rettv; 8907 { 8908 findfilendir(argvars, rettv, TRUE); 8909 } 8910 8911 /* 8912 * "findfile({fname}[, {path}[, {count}]])" function 8913 */ 8914 static void 8915 f_findfile(argvars, rettv) 8916 typval_T *argvars; 8917 typval_T *rettv; 8918 { 8919 findfilendir(argvars, rettv, FALSE); 8920 } 8921 8922 /* 8923 * "fnamemodify({fname}, {mods})" function 8924 */ 8925 static void 8926 f_fnamemodify(argvars, rettv) 8927 typval_T *argvars; 8928 typval_T *rettv; 8929 { 8930 char_u *fname; 8931 char_u *mods; 8932 int usedlen = 0; 8933 int len; 8934 char_u *fbuf = NULL; 8935 char_u buf[NUMBUFLEN]; 8936 8937 fname = get_tv_string_chk(&argvars[0]); 8938 mods = get_tv_string_buf_chk(&argvars[1], buf); 8939 if (fname == NULL || mods == NULL) 8940 fname = NULL; 8941 else 8942 { 8943 len = (int)STRLEN(fname); 8944 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8945 } 8946 8947 rettv->v_type = VAR_STRING; 8948 if (fname == NULL) 8949 rettv->vval.v_string = NULL; 8950 else 8951 rettv->vval.v_string = vim_strnsave(fname, len); 8952 vim_free(fbuf); 8953 } 8954 8955 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8956 8957 /* 8958 * "foldclosed()" function 8959 */ 8960 static void 8961 foldclosed_both(argvars, rettv, end) 8962 typval_T *argvars; 8963 typval_T *rettv; 8964 int end; 8965 { 8966 #ifdef FEAT_FOLDING 8967 linenr_T lnum; 8968 linenr_T first, last; 8969 8970 lnum = get_tv_lnum(argvars); 8971 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8972 { 8973 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8974 { 8975 if (end) 8976 rettv->vval.v_number = (varnumber_T)last; 8977 else 8978 rettv->vval.v_number = (varnumber_T)first; 8979 return; 8980 } 8981 } 8982 #endif 8983 rettv->vval.v_number = -1; 8984 } 8985 8986 /* 8987 * "foldclosed()" function 8988 */ 8989 static void 8990 f_foldclosed(argvars, rettv) 8991 typval_T *argvars; 8992 typval_T *rettv; 8993 { 8994 foldclosed_both(argvars, rettv, FALSE); 8995 } 8996 8997 /* 8998 * "foldclosedend()" function 8999 */ 9000 static void 9001 f_foldclosedend(argvars, rettv) 9002 typval_T *argvars; 9003 typval_T *rettv; 9004 { 9005 foldclosed_both(argvars, rettv, TRUE); 9006 } 9007 9008 /* 9009 * "foldlevel()" function 9010 */ 9011 static void 9012 f_foldlevel(argvars, rettv) 9013 typval_T *argvars; 9014 typval_T *rettv; 9015 { 9016 #ifdef FEAT_FOLDING 9017 linenr_T lnum; 9018 9019 lnum = get_tv_lnum(argvars); 9020 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9021 rettv->vval.v_number = foldLevel(lnum); 9022 else 9023 #endif 9024 rettv->vval.v_number = 0; 9025 } 9026 9027 /* 9028 * "foldtext()" function 9029 */ 9030 /*ARGSUSED*/ 9031 static void 9032 f_foldtext(argvars, rettv) 9033 typval_T *argvars; 9034 typval_T *rettv; 9035 { 9036 #ifdef FEAT_FOLDING 9037 linenr_T lnum; 9038 char_u *s; 9039 char_u *r; 9040 int len; 9041 char *txt; 9042 #endif 9043 9044 rettv->v_type = VAR_STRING; 9045 rettv->vval.v_string = NULL; 9046 #ifdef FEAT_FOLDING 9047 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9048 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9049 <= curbuf->b_ml.ml_line_count 9050 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9051 { 9052 /* Find first non-empty line in the fold. */ 9053 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9054 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9055 { 9056 if (!linewhite(lnum)) 9057 break; 9058 ++lnum; 9059 } 9060 9061 /* Find interesting text in this line. */ 9062 s = skipwhite(ml_get(lnum)); 9063 /* skip C comment-start */ 9064 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9065 { 9066 s = skipwhite(s + 2); 9067 if (*skipwhite(s) == NUL 9068 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9069 { 9070 s = skipwhite(ml_get(lnum + 1)); 9071 if (*s == '*') 9072 s = skipwhite(s + 1); 9073 } 9074 } 9075 txt = _("+-%s%3ld lines: "); 9076 r = alloc((unsigned)(STRLEN(txt) 9077 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9078 + 20 /* for %3ld */ 9079 + STRLEN(s))); /* concatenated */ 9080 if (r != NULL) 9081 { 9082 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9083 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9084 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9085 len = (int)STRLEN(r); 9086 STRCAT(r, s); 9087 /* remove 'foldmarker' and 'commentstring' */ 9088 foldtext_cleanup(r + len); 9089 rettv->vval.v_string = r; 9090 } 9091 } 9092 #endif 9093 } 9094 9095 /* 9096 * "foldtextresult(lnum)" function 9097 */ 9098 /*ARGSUSED*/ 9099 static void 9100 f_foldtextresult(argvars, rettv) 9101 typval_T *argvars; 9102 typval_T *rettv; 9103 { 9104 #ifdef FEAT_FOLDING 9105 linenr_T lnum; 9106 char_u *text; 9107 char_u buf[51]; 9108 foldinfo_T foldinfo; 9109 int fold_count; 9110 #endif 9111 9112 rettv->v_type = VAR_STRING; 9113 rettv->vval.v_string = NULL; 9114 #ifdef FEAT_FOLDING 9115 lnum = get_tv_lnum(argvars); 9116 /* treat illegal types and illegal string values for {lnum} the same */ 9117 if (lnum < 0) 9118 lnum = 0; 9119 fold_count = foldedCount(curwin, lnum, &foldinfo); 9120 if (fold_count > 0) 9121 { 9122 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9123 &foldinfo, buf); 9124 if (text == buf) 9125 text = vim_strsave(text); 9126 rettv->vval.v_string = text; 9127 } 9128 #endif 9129 } 9130 9131 /* 9132 * "foreground()" function 9133 */ 9134 /*ARGSUSED*/ 9135 static void 9136 f_foreground(argvars, rettv) 9137 typval_T *argvars; 9138 typval_T *rettv; 9139 { 9140 rettv->vval.v_number = 0; 9141 #ifdef FEAT_GUI 9142 if (gui.in_use) 9143 gui_mch_set_foreground(); 9144 #else 9145 # ifdef WIN32 9146 win32_set_foreground(); 9147 # endif 9148 #endif 9149 } 9150 9151 /* 9152 * "function()" function 9153 */ 9154 /*ARGSUSED*/ 9155 static void 9156 f_function(argvars, rettv) 9157 typval_T *argvars; 9158 typval_T *rettv; 9159 { 9160 char_u *s; 9161 9162 rettv->vval.v_number = 0; 9163 s = get_tv_string(&argvars[0]); 9164 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9165 EMSG2(_(e_invarg2), s); 9166 else if (!function_exists(s)) 9167 EMSG2(_("E700: Unknown function: %s"), s); 9168 else 9169 { 9170 rettv->vval.v_string = vim_strsave(s); 9171 rettv->v_type = VAR_FUNC; 9172 } 9173 } 9174 9175 /* 9176 * "garbagecollect()" function 9177 */ 9178 /*ARGSUSED*/ 9179 static void 9180 f_garbagecollect(argvars, rettv) 9181 typval_T *argvars; 9182 typval_T *rettv; 9183 { 9184 garbage_collect(); 9185 } 9186 9187 /* 9188 * "get()" function 9189 */ 9190 static void 9191 f_get(argvars, rettv) 9192 typval_T *argvars; 9193 typval_T *rettv; 9194 { 9195 listitem_T *li; 9196 list_T *l; 9197 dictitem_T *di; 9198 dict_T *d; 9199 typval_T *tv = NULL; 9200 9201 if (argvars[0].v_type == VAR_LIST) 9202 { 9203 if ((l = argvars[0].vval.v_list) != NULL) 9204 { 9205 int error = FALSE; 9206 9207 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9208 if (!error && li != NULL) 9209 tv = &li->li_tv; 9210 } 9211 } 9212 else if (argvars[0].v_type == VAR_DICT) 9213 { 9214 if ((d = argvars[0].vval.v_dict) != NULL) 9215 { 9216 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9217 if (di != NULL) 9218 tv = &di->di_tv; 9219 } 9220 } 9221 else 9222 EMSG2(_(e_listdictarg), "get()"); 9223 9224 if (tv == NULL) 9225 { 9226 if (argvars[2].v_type == VAR_UNKNOWN) 9227 rettv->vval.v_number = 0; 9228 else 9229 copy_tv(&argvars[2], rettv); 9230 } 9231 else 9232 copy_tv(tv, rettv); 9233 } 9234 9235 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9236 9237 /* 9238 * Get line or list of lines from buffer "buf" into "rettv". 9239 * Return a range (from start to end) of lines in rettv from the specified 9240 * buffer. 9241 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9242 */ 9243 static void 9244 get_buffer_lines(buf, start, end, retlist, rettv) 9245 buf_T *buf; 9246 linenr_T start; 9247 linenr_T end; 9248 int retlist; 9249 typval_T *rettv; 9250 { 9251 char_u *p; 9252 list_T *l = NULL; 9253 9254 if (retlist) 9255 { 9256 l = list_alloc(); 9257 if (l == NULL) 9258 return; 9259 9260 rettv->vval.v_list = l; 9261 rettv->v_type = VAR_LIST; 9262 ++l->lv_refcount; 9263 } 9264 else 9265 rettv->vval.v_number = 0; 9266 9267 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9268 return; 9269 9270 if (!retlist) 9271 { 9272 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9273 p = ml_get_buf(buf, start, FALSE); 9274 else 9275 p = (char_u *)""; 9276 9277 rettv->v_type = VAR_STRING; 9278 rettv->vval.v_string = vim_strsave(p); 9279 } 9280 else 9281 { 9282 if (end < start) 9283 return; 9284 9285 if (start < 1) 9286 start = 1; 9287 if (end > buf->b_ml.ml_line_count) 9288 end = buf->b_ml.ml_line_count; 9289 while (start <= end) 9290 if (list_append_string(l, ml_get_buf(buf, start++, FALSE), -1) 9291 == FAIL) 9292 break; 9293 } 9294 } 9295 9296 /* 9297 * "getbufline()" function 9298 */ 9299 static void 9300 f_getbufline(argvars, rettv) 9301 typval_T *argvars; 9302 typval_T *rettv; 9303 { 9304 linenr_T lnum; 9305 linenr_T end; 9306 buf_T *buf; 9307 9308 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9309 ++emsg_off; 9310 buf = get_buf_tv(&argvars[0]); 9311 --emsg_off; 9312 9313 lnum = get_tv_lnum_buf(&argvars[1], buf); 9314 if (argvars[2].v_type == VAR_UNKNOWN) 9315 end = lnum; 9316 else 9317 end = get_tv_lnum_buf(&argvars[2], buf); 9318 9319 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9320 } 9321 9322 /* 9323 * "getbufvar()" function 9324 */ 9325 static void 9326 f_getbufvar(argvars, rettv) 9327 typval_T *argvars; 9328 typval_T *rettv; 9329 { 9330 buf_T *buf; 9331 buf_T *save_curbuf; 9332 char_u *varname; 9333 dictitem_T *v; 9334 9335 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9336 varname = get_tv_string_chk(&argvars[1]); 9337 ++emsg_off; 9338 buf = get_buf_tv(&argvars[0]); 9339 9340 rettv->v_type = VAR_STRING; 9341 rettv->vval.v_string = NULL; 9342 9343 if (buf != NULL && varname != NULL) 9344 { 9345 if (*varname == '&') /* buffer-local-option */ 9346 { 9347 /* set curbuf to be our buf, temporarily */ 9348 save_curbuf = curbuf; 9349 curbuf = buf; 9350 9351 get_option_tv(&varname, rettv, TRUE); 9352 9353 /* restore previous notion of curbuf */ 9354 curbuf = save_curbuf; 9355 } 9356 else 9357 { 9358 if (*varname == NUL) 9359 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9360 * scope prefix before the NUL byte is required by 9361 * find_var_in_ht(). */ 9362 varname = (char_u *)"b:" + 2; 9363 /* look up the variable */ 9364 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9365 if (v != NULL) 9366 copy_tv(&v->di_tv, rettv); 9367 } 9368 } 9369 9370 --emsg_off; 9371 } 9372 9373 /* 9374 * "getchar()" function 9375 */ 9376 static void 9377 f_getchar(argvars, rettv) 9378 typval_T *argvars; 9379 typval_T *rettv; 9380 { 9381 varnumber_T n; 9382 int error = FALSE; 9383 9384 ++no_mapping; 9385 ++allow_keys; 9386 if (argvars[0].v_type == VAR_UNKNOWN) 9387 /* getchar(): blocking wait. */ 9388 n = safe_vgetc(); 9389 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9390 /* getchar(1): only check if char avail */ 9391 n = vpeekc(); 9392 else if (error || vpeekc() == NUL) 9393 /* illegal argument or getchar(0) and no char avail: return zero */ 9394 n = 0; 9395 else 9396 /* getchar(0) and char avail: return char */ 9397 n = safe_vgetc(); 9398 --no_mapping; 9399 --allow_keys; 9400 9401 rettv->vval.v_number = n; 9402 if (IS_SPECIAL(n) || mod_mask != 0) 9403 { 9404 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9405 int i = 0; 9406 9407 /* Turn a special key into three bytes, plus modifier. */ 9408 if (mod_mask != 0) 9409 { 9410 temp[i++] = K_SPECIAL; 9411 temp[i++] = KS_MODIFIER; 9412 temp[i++] = mod_mask; 9413 } 9414 if (IS_SPECIAL(n)) 9415 { 9416 temp[i++] = K_SPECIAL; 9417 temp[i++] = K_SECOND(n); 9418 temp[i++] = K_THIRD(n); 9419 } 9420 #ifdef FEAT_MBYTE 9421 else if (has_mbyte) 9422 i += (*mb_char2bytes)(n, temp + i); 9423 #endif 9424 else 9425 temp[i++] = n; 9426 temp[i++] = NUL; 9427 rettv->v_type = VAR_STRING; 9428 rettv->vval.v_string = vim_strsave(temp); 9429 } 9430 } 9431 9432 /* 9433 * "getcharmod()" function 9434 */ 9435 /*ARGSUSED*/ 9436 static void 9437 f_getcharmod(argvars, rettv) 9438 typval_T *argvars; 9439 typval_T *rettv; 9440 { 9441 rettv->vval.v_number = mod_mask; 9442 } 9443 9444 /* 9445 * "getcmdline()" function 9446 */ 9447 /*ARGSUSED*/ 9448 static void 9449 f_getcmdline(argvars, rettv) 9450 typval_T *argvars; 9451 typval_T *rettv; 9452 { 9453 rettv->v_type = VAR_STRING; 9454 rettv->vval.v_string = get_cmdline_str(); 9455 } 9456 9457 /* 9458 * "getcmdpos()" function 9459 */ 9460 /*ARGSUSED*/ 9461 static void 9462 f_getcmdpos(argvars, rettv) 9463 typval_T *argvars; 9464 typval_T *rettv; 9465 { 9466 rettv->vval.v_number = get_cmdline_pos() + 1; 9467 } 9468 9469 /* 9470 * "getcmdtype()" function 9471 */ 9472 /*ARGSUSED*/ 9473 static void 9474 f_getcmdtype(argvars, rettv) 9475 typval_T *argvars; 9476 typval_T *rettv; 9477 { 9478 rettv->v_type = VAR_STRING; 9479 rettv->vval.v_string = alloc(2); 9480 if (rettv->vval.v_string != NULL) 9481 { 9482 rettv->vval.v_string[0] = get_cmdline_type(); 9483 rettv->vval.v_string[1] = NUL; 9484 } 9485 } 9486 9487 /* 9488 * "getcwd()" function 9489 */ 9490 /*ARGSUSED*/ 9491 static void 9492 f_getcwd(argvars, rettv) 9493 typval_T *argvars; 9494 typval_T *rettv; 9495 { 9496 char_u cwd[MAXPATHL]; 9497 9498 rettv->v_type = VAR_STRING; 9499 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9500 rettv->vval.v_string = NULL; 9501 else 9502 { 9503 rettv->vval.v_string = vim_strsave(cwd); 9504 #ifdef BACKSLASH_IN_FILENAME 9505 if (rettv->vval.v_string != NULL) 9506 slash_adjust(rettv->vval.v_string); 9507 #endif 9508 } 9509 } 9510 9511 /* 9512 * "getfontname()" function 9513 */ 9514 /*ARGSUSED*/ 9515 static void 9516 f_getfontname(argvars, rettv) 9517 typval_T *argvars; 9518 typval_T *rettv; 9519 { 9520 rettv->v_type = VAR_STRING; 9521 rettv->vval.v_string = NULL; 9522 #ifdef FEAT_GUI 9523 if (gui.in_use) 9524 { 9525 GuiFont font; 9526 char_u *name = NULL; 9527 9528 if (argvars[0].v_type == VAR_UNKNOWN) 9529 { 9530 /* Get the "Normal" font. Either the name saved by 9531 * hl_set_font_name() or from the font ID. */ 9532 font = gui.norm_font; 9533 name = hl_get_font_name(); 9534 } 9535 else 9536 { 9537 name = get_tv_string(&argvars[0]); 9538 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9539 return; 9540 font = gui_mch_get_font(name, FALSE); 9541 if (font == NOFONT) 9542 return; /* Invalid font name, return empty string. */ 9543 } 9544 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9545 if (argvars[0].v_type != VAR_UNKNOWN) 9546 gui_mch_free_font(font); 9547 } 9548 #endif 9549 } 9550 9551 /* 9552 * "getfperm({fname})" function 9553 */ 9554 static void 9555 f_getfperm(argvars, rettv) 9556 typval_T *argvars; 9557 typval_T *rettv; 9558 { 9559 char_u *fname; 9560 struct stat st; 9561 char_u *perm = NULL; 9562 char_u flags[] = "rwx"; 9563 int i; 9564 9565 fname = get_tv_string(&argvars[0]); 9566 9567 rettv->v_type = VAR_STRING; 9568 if (mch_stat((char *)fname, &st) >= 0) 9569 { 9570 perm = vim_strsave((char_u *)"---------"); 9571 if (perm != NULL) 9572 { 9573 for (i = 0; i < 9; i++) 9574 { 9575 if (st.st_mode & (1 << (8 - i))) 9576 perm[i] = flags[i % 3]; 9577 } 9578 } 9579 } 9580 rettv->vval.v_string = perm; 9581 } 9582 9583 /* 9584 * "getfsize({fname})" function 9585 */ 9586 static void 9587 f_getfsize(argvars, rettv) 9588 typval_T *argvars; 9589 typval_T *rettv; 9590 { 9591 char_u *fname; 9592 struct stat st; 9593 9594 fname = get_tv_string(&argvars[0]); 9595 9596 rettv->v_type = VAR_NUMBER; 9597 9598 if (mch_stat((char *)fname, &st) >= 0) 9599 { 9600 if (mch_isdir(fname)) 9601 rettv->vval.v_number = 0; 9602 else 9603 rettv->vval.v_number = (varnumber_T)st.st_size; 9604 } 9605 else 9606 rettv->vval.v_number = -1; 9607 } 9608 9609 /* 9610 * "getftime({fname})" function 9611 */ 9612 static void 9613 f_getftime(argvars, rettv) 9614 typval_T *argvars; 9615 typval_T *rettv; 9616 { 9617 char_u *fname; 9618 struct stat st; 9619 9620 fname = get_tv_string(&argvars[0]); 9621 9622 if (mch_stat((char *)fname, &st) >= 0) 9623 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9624 else 9625 rettv->vval.v_number = -1; 9626 } 9627 9628 /* 9629 * "getftype({fname})" function 9630 */ 9631 static void 9632 f_getftype(argvars, rettv) 9633 typval_T *argvars; 9634 typval_T *rettv; 9635 { 9636 char_u *fname; 9637 struct stat st; 9638 char_u *type = NULL; 9639 char *t; 9640 9641 fname = get_tv_string(&argvars[0]); 9642 9643 rettv->v_type = VAR_STRING; 9644 if (mch_lstat((char *)fname, &st) >= 0) 9645 { 9646 #ifdef S_ISREG 9647 if (S_ISREG(st.st_mode)) 9648 t = "file"; 9649 else if (S_ISDIR(st.st_mode)) 9650 t = "dir"; 9651 # ifdef S_ISLNK 9652 else if (S_ISLNK(st.st_mode)) 9653 t = "link"; 9654 # endif 9655 # ifdef S_ISBLK 9656 else if (S_ISBLK(st.st_mode)) 9657 t = "bdev"; 9658 # endif 9659 # ifdef S_ISCHR 9660 else if (S_ISCHR(st.st_mode)) 9661 t = "cdev"; 9662 # endif 9663 # ifdef S_ISFIFO 9664 else if (S_ISFIFO(st.st_mode)) 9665 t = "fifo"; 9666 # endif 9667 # ifdef S_ISSOCK 9668 else if (S_ISSOCK(st.st_mode)) 9669 t = "fifo"; 9670 # endif 9671 else 9672 t = "other"; 9673 #else 9674 # ifdef S_IFMT 9675 switch (st.st_mode & S_IFMT) 9676 { 9677 case S_IFREG: t = "file"; break; 9678 case S_IFDIR: t = "dir"; break; 9679 # ifdef S_IFLNK 9680 case S_IFLNK: t = "link"; break; 9681 # endif 9682 # ifdef S_IFBLK 9683 case S_IFBLK: t = "bdev"; break; 9684 # endif 9685 # ifdef S_IFCHR 9686 case S_IFCHR: t = "cdev"; break; 9687 # endif 9688 # ifdef S_IFIFO 9689 case S_IFIFO: t = "fifo"; break; 9690 # endif 9691 # ifdef S_IFSOCK 9692 case S_IFSOCK: t = "socket"; break; 9693 # endif 9694 default: t = "other"; 9695 } 9696 # else 9697 if (mch_isdir(fname)) 9698 t = "dir"; 9699 else 9700 t = "file"; 9701 # endif 9702 #endif 9703 type = vim_strsave((char_u *)t); 9704 } 9705 rettv->vval.v_string = type; 9706 } 9707 9708 /* 9709 * "getline(lnum, [end])" function 9710 */ 9711 static void 9712 f_getline(argvars, rettv) 9713 typval_T *argvars; 9714 typval_T *rettv; 9715 { 9716 linenr_T lnum; 9717 linenr_T end; 9718 int retlist; 9719 9720 lnum = get_tv_lnum(argvars); 9721 if (argvars[1].v_type == VAR_UNKNOWN) 9722 { 9723 end = 0; 9724 retlist = FALSE; 9725 } 9726 else 9727 { 9728 end = get_tv_lnum(&argvars[1]); 9729 retlist = TRUE; 9730 } 9731 9732 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9733 } 9734 9735 /* 9736 * "getqflist()" function 9737 */ 9738 /*ARGSUSED*/ 9739 static void 9740 f_getqflist(argvars, rettv) 9741 typval_T *argvars; 9742 typval_T *rettv; 9743 { 9744 #ifdef FEAT_QUICKFIX 9745 list_T *l; 9746 #endif 9747 9748 rettv->vval.v_number = FALSE; 9749 #ifdef FEAT_QUICKFIX 9750 l = list_alloc(); 9751 if (l != NULL) 9752 { 9753 rettv->vval.v_list = l; 9754 rettv->v_type = VAR_LIST; 9755 ++l->lv_refcount; 9756 (void)get_errorlist(l); 9757 } 9758 #endif 9759 } 9760 9761 /* 9762 * "getreg()" function 9763 */ 9764 static void 9765 f_getreg(argvars, rettv) 9766 typval_T *argvars; 9767 typval_T *rettv; 9768 { 9769 char_u *strregname; 9770 int regname; 9771 int arg2 = FALSE; 9772 int error = FALSE; 9773 9774 if (argvars[0].v_type != VAR_UNKNOWN) 9775 { 9776 strregname = get_tv_string_chk(&argvars[0]); 9777 error = strregname == NULL; 9778 if (argvars[1].v_type != VAR_UNKNOWN) 9779 arg2 = get_tv_number_chk(&argvars[1], &error); 9780 } 9781 else 9782 strregname = vimvars[VV_REG].vv_str; 9783 regname = (strregname == NULL ? '"' : *strregname); 9784 if (regname == 0) 9785 regname = '"'; 9786 9787 rettv->v_type = VAR_STRING; 9788 rettv->vval.v_string = error ? NULL : 9789 get_reg_contents(regname, TRUE, arg2); 9790 } 9791 9792 /* 9793 * "getregtype()" function 9794 */ 9795 static void 9796 f_getregtype(argvars, rettv) 9797 typval_T *argvars; 9798 typval_T *rettv; 9799 { 9800 char_u *strregname; 9801 int regname; 9802 char_u buf[NUMBUFLEN + 2]; 9803 long reglen = 0; 9804 9805 if (argvars[0].v_type != VAR_UNKNOWN) 9806 { 9807 strregname = get_tv_string_chk(&argvars[0]); 9808 if (strregname == NULL) /* type error; errmsg already given */ 9809 { 9810 rettv->v_type = VAR_STRING; 9811 rettv->vval.v_string = NULL; 9812 return; 9813 } 9814 } 9815 else 9816 /* Default to v:register */ 9817 strregname = vimvars[VV_REG].vv_str; 9818 9819 regname = (strregname == NULL ? '"' : *strregname); 9820 if (regname == 0) 9821 regname = '"'; 9822 9823 buf[0] = NUL; 9824 buf[1] = NUL; 9825 switch (get_reg_type(regname, ®len)) 9826 { 9827 case MLINE: buf[0] = 'V'; break; 9828 case MCHAR: buf[0] = 'v'; break; 9829 #ifdef FEAT_VISUAL 9830 case MBLOCK: 9831 buf[0] = Ctrl_V; 9832 sprintf((char *)buf + 1, "%ld", reglen + 1); 9833 break; 9834 #endif 9835 } 9836 rettv->v_type = VAR_STRING; 9837 rettv->vval.v_string = vim_strsave(buf); 9838 } 9839 9840 /* 9841 * "getwinposx()" function 9842 */ 9843 /*ARGSUSED*/ 9844 static void 9845 f_getwinposx(argvars, rettv) 9846 typval_T *argvars; 9847 typval_T *rettv; 9848 { 9849 rettv->vval.v_number = -1; 9850 #ifdef FEAT_GUI 9851 if (gui.in_use) 9852 { 9853 int x, y; 9854 9855 if (gui_mch_get_winpos(&x, &y) == OK) 9856 rettv->vval.v_number = x; 9857 } 9858 #endif 9859 } 9860 9861 /* 9862 * "getwinposy()" function 9863 */ 9864 /*ARGSUSED*/ 9865 static void 9866 f_getwinposy(argvars, rettv) 9867 typval_T *argvars; 9868 typval_T *rettv; 9869 { 9870 rettv->vval.v_number = -1; 9871 #ifdef FEAT_GUI 9872 if (gui.in_use) 9873 { 9874 int x, y; 9875 9876 if (gui_mch_get_winpos(&x, &y) == OK) 9877 rettv->vval.v_number = y; 9878 } 9879 #endif 9880 } 9881 9882 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9883 9884 static win_T * 9885 find_win_by_nr(vp) 9886 typval_T *vp; 9887 { 9888 #ifdef FEAT_WINDOWS 9889 win_T *wp; 9890 #endif 9891 int nr; 9892 9893 nr = get_tv_number_chk(vp, NULL); 9894 9895 #ifdef FEAT_WINDOWS 9896 if (nr < 0) 9897 return NULL; 9898 if (nr == 0) 9899 return curwin; 9900 9901 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9902 if (--nr <= 0) 9903 break; 9904 return wp; 9905 #else 9906 if (nr == 0 || nr == 1) 9907 return curwin; 9908 return NULL; 9909 #endif 9910 } 9911 9912 /* 9913 * "getwinvar()" function 9914 */ 9915 static void 9916 f_getwinvar(argvars, rettv) 9917 typval_T *argvars; 9918 typval_T *rettv; 9919 { 9920 win_T *win, *oldcurwin; 9921 char_u *varname; 9922 dictitem_T *v; 9923 9924 win = find_win_by_nr(&argvars[0]); 9925 varname = get_tv_string_chk(&argvars[1]); 9926 ++emsg_off; 9927 9928 rettv->v_type = VAR_STRING; 9929 rettv->vval.v_string = NULL; 9930 9931 if (win != NULL && varname != NULL) 9932 { 9933 if (*varname == '&') /* window-local-option */ 9934 { 9935 /* Set curwin to be our win, temporarily. Also set curbuf, so 9936 * that we can get buffer-local options. */ 9937 oldcurwin = curwin; 9938 curwin = win; 9939 curbuf = win->w_buffer; 9940 9941 get_option_tv(&varname, rettv, 1); 9942 9943 /* restore previous notion of curwin */ 9944 curwin = oldcurwin; 9945 curbuf = curwin->w_buffer; 9946 } 9947 else 9948 { 9949 if (*varname == NUL) 9950 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9951 * scope prefix before the NUL byte is required by 9952 * find_var_in_ht(). */ 9953 varname = (char_u *)"w:" + 2; 9954 /* look up the variable */ 9955 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9956 if (v != NULL) 9957 copy_tv(&v->di_tv, rettv); 9958 } 9959 } 9960 9961 --emsg_off; 9962 } 9963 9964 /* 9965 * "glob()" function 9966 */ 9967 static void 9968 f_glob(argvars, rettv) 9969 typval_T *argvars; 9970 typval_T *rettv; 9971 { 9972 expand_T xpc; 9973 9974 ExpandInit(&xpc); 9975 xpc.xp_context = EXPAND_FILES; 9976 rettv->v_type = VAR_STRING; 9977 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9978 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9979 ExpandCleanup(&xpc); 9980 } 9981 9982 /* 9983 * "globpath()" function 9984 */ 9985 static void 9986 f_globpath(argvars, rettv) 9987 typval_T *argvars; 9988 typval_T *rettv; 9989 { 9990 char_u buf1[NUMBUFLEN]; 9991 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9992 9993 rettv->v_type = VAR_STRING; 9994 if (file == NULL) 9995 rettv->vval.v_string = NULL; 9996 else 9997 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9998 } 9999 10000 /* 10001 * "has()" function 10002 */ 10003 static void 10004 f_has(argvars, rettv) 10005 typval_T *argvars; 10006 typval_T *rettv; 10007 { 10008 int i; 10009 char_u *name; 10010 int n = FALSE; 10011 static char *(has_list[]) = 10012 { 10013 #ifdef AMIGA 10014 "amiga", 10015 # ifdef FEAT_ARP 10016 "arp", 10017 # endif 10018 #endif 10019 #ifdef __BEOS__ 10020 "beos", 10021 #endif 10022 #ifdef MSDOS 10023 # ifdef DJGPP 10024 "dos32", 10025 # else 10026 "dos16", 10027 # endif 10028 #endif 10029 #ifdef MACOS 10030 "mac", 10031 #endif 10032 #if defined(MACOS_X_UNIX) 10033 "macunix", 10034 #endif 10035 #ifdef OS2 10036 "os2", 10037 #endif 10038 #ifdef __QNX__ 10039 "qnx", 10040 #endif 10041 #ifdef RISCOS 10042 "riscos", 10043 #endif 10044 #ifdef UNIX 10045 "unix", 10046 #endif 10047 #ifdef VMS 10048 "vms", 10049 #endif 10050 #ifdef WIN16 10051 "win16", 10052 #endif 10053 #ifdef WIN32 10054 "win32", 10055 #endif 10056 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10057 "win32unix", 10058 #endif 10059 #ifdef WIN64 10060 "win64", 10061 #endif 10062 #ifdef EBCDIC 10063 "ebcdic", 10064 #endif 10065 #ifndef CASE_INSENSITIVE_FILENAME 10066 "fname_case", 10067 #endif 10068 #ifdef FEAT_ARABIC 10069 "arabic", 10070 #endif 10071 #ifdef FEAT_AUTOCMD 10072 "autocmd", 10073 #endif 10074 #ifdef FEAT_BEVAL 10075 "balloon_eval", 10076 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10077 "balloon_multiline", 10078 # endif 10079 #endif 10080 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10081 "builtin_terms", 10082 # ifdef ALL_BUILTIN_TCAPS 10083 "all_builtin_terms", 10084 # endif 10085 #endif 10086 #ifdef FEAT_BYTEOFF 10087 "byte_offset", 10088 #endif 10089 #ifdef FEAT_CINDENT 10090 "cindent", 10091 #endif 10092 #ifdef FEAT_CLIENTSERVER 10093 "clientserver", 10094 #endif 10095 #ifdef FEAT_CLIPBOARD 10096 "clipboard", 10097 #endif 10098 #ifdef FEAT_CMDL_COMPL 10099 "cmdline_compl", 10100 #endif 10101 #ifdef FEAT_CMDHIST 10102 "cmdline_hist", 10103 #endif 10104 #ifdef FEAT_COMMENTS 10105 "comments", 10106 #endif 10107 #ifdef FEAT_CRYPT 10108 "cryptv", 10109 #endif 10110 #ifdef FEAT_CSCOPE 10111 "cscope", 10112 #endif 10113 #ifdef CURSOR_SHAPE 10114 "cursorshape", 10115 #endif 10116 #ifdef DEBUG 10117 "debug", 10118 #endif 10119 #ifdef FEAT_CON_DIALOG 10120 "dialog_con", 10121 #endif 10122 #ifdef FEAT_GUI_DIALOG 10123 "dialog_gui", 10124 #endif 10125 #ifdef FEAT_DIFF 10126 "diff", 10127 #endif 10128 #ifdef FEAT_DIGRAPHS 10129 "digraphs", 10130 #endif 10131 #ifdef FEAT_DND 10132 "dnd", 10133 #endif 10134 #ifdef FEAT_EMACS_TAGS 10135 "emacs_tags", 10136 #endif 10137 "eval", /* always present, of course! */ 10138 #ifdef FEAT_EX_EXTRA 10139 "ex_extra", 10140 #endif 10141 #ifdef FEAT_SEARCH_EXTRA 10142 "extra_search", 10143 #endif 10144 #ifdef FEAT_FKMAP 10145 "farsi", 10146 #endif 10147 #ifdef FEAT_SEARCHPATH 10148 "file_in_path", 10149 #endif 10150 #if defined(UNIX) && !defined(USE_SYSTEM) 10151 "filterpipe", 10152 #endif 10153 #ifdef FEAT_FIND_ID 10154 "find_in_path", 10155 #endif 10156 #ifdef FEAT_FOLDING 10157 "folding", 10158 #endif 10159 #ifdef FEAT_FOOTER 10160 "footer", 10161 #endif 10162 #if !defined(USE_SYSTEM) && defined(UNIX) 10163 "fork", 10164 #endif 10165 #ifdef FEAT_GETTEXT 10166 "gettext", 10167 #endif 10168 #ifdef FEAT_GUI 10169 "gui", 10170 #endif 10171 #ifdef FEAT_GUI_ATHENA 10172 # ifdef FEAT_GUI_NEXTAW 10173 "gui_neXtaw", 10174 # else 10175 "gui_athena", 10176 # endif 10177 #endif 10178 #ifdef FEAT_GUI_GTK 10179 "gui_gtk", 10180 # ifdef HAVE_GTK2 10181 "gui_gtk2", 10182 # endif 10183 #endif 10184 #ifdef FEAT_GUI_MAC 10185 "gui_mac", 10186 #endif 10187 #ifdef FEAT_GUI_MOTIF 10188 "gui_motif", 10189 #endif 10190 #ifdef FEAT_GUI_PHOTON 10191 "gui_photon", 10192 #endif 10193 #ifdef FEAT_GUI_W16 10194 "gui_win16", 10195 #endif 10196 #ifdef FEAT_GUI_W32 10197 "gui_win32", 10198 #endif 10199 #ifdef FEAT_HANGULIN 10200 "hangul_input", 10201 #endif 10202 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10203 "iconv", 10204 #endif 10205 #ifdef FEAT_INS_EXPAND 10206 "insert_expand", 10207 #endif 10208 #ifdef FEAT_JUMPLIST 10209 "jumplist", 10210 #endif 10211 #ifdef FEAT_KEYMAP 10212 "keymap", 10213 #endif 10214 #ifdef FEAT_LANGMAP 10215 "langmap", 10216 #endif 10217 #ifdef FEAT_LIBCALL 10218 "libcall", 10219 #endif 10220 #ifdef FEAT_LINEBREAK 10221 "linebreak", 10222 #endif 10223 #ifdef FEAT_LISP 10224 "lispindent", 10225 #endif 10226 #ifdef FEAT_LISTCMDS 10227 "listcmds", 10228 #endif 10229 #ifdef FEAT_LOCALMAP 10230 "localmap", 10231 #endif 10232 #ifdef FEAT_MENU 10233 "menu", 10234 #endif 10235 #ifdef FEAT_SESSION 10236 "mksession", 10237 #endif 10238 #ifdef FEAT_MODIFY_FNAME 10239 "modify_fname", 10240 #endif 10241 #ifdef FEAT_MOUSE 10242 "mouse", 10243 #endif 10244 #ifdef FEAT_MOUSESHAPE 10245 "mouseshape", 10246 #endif 10247 #if defined(UNIX) || defined(VMS) 10248 # ifdef FEAT_MOUSE_DEC 10249 "mouse_dec", 10250 # endif 10251 # ifdef FEAT_MOUSE_GPM 10252 "mouse_gpm", 10253 # endif 10254 # ifdef FEAT_MOUSE_JSB 10255 "mouse_jsbterm", 10256 # endif 10257 # ifdef FEAT_MOUSE_NET 10258 "mouse_netterm", 10259 # endif 10260 # ifdef FEAT_MOUSE_PTERM 10261 "mouse_pterm", 10262 # endif 10263 # ifdef FEAT_MOUSE_XTERM 10264 "mouse_xterm", 10265 # endif 10266 #endif 10267 #ifdef FEAT_MBYTE 10268 "multi_byte", 10269 #endif 10270 #ifdef FEAT_MBYTE_IME 10271 "multi_byte_ime", 10272 #endif 10273 #ifdef FEAT_MULTI_LANG 10274 "multi_lang", 10275 #endif 10276 #ifdef FEAT_MZSCHEME 10277 #ifndef DYNAMIC_MZSCHEME 10278 "mzscheme", 10279 #endif 10280 #endif 10281 #ifdef FEAT_OLE 10282 "ole", 10283 #endif 10284 #ifdef FEAT_OSFILETYPE 10285 "osfiletype", 10286 #endif 10287 #ifdef FEAT_PATH_EXTRA 10288 "path_extra", 10289 #endif 10290 #ifdef FEAT_PERL 10291 #ifndef DYNAMIC_PERL 10292 "perl", 10293 #endif 10294 #endif 10295 #ifdef FEAT_PYTHON 10296 #ifndef DYNAMIC_PYTHON 10297 "python", 10298 #endif 10299 #endif 10300 #ifdef FEAT_POSTSCRIPT 10301 "postscript", 10302 #endif 10303 #ifdef FEAT_PRINTER 10304 "printer", 10305 #endif 10306 #ifdef FEAT_PROFILE 10307 "profile", 10308 #endif 10309 #ifdef FEAT_QUICKFIX 10310 "quickfix", 10311 #endif 10312 #ifdef FEAT_RIGHTLEFT 10313 "rightleft", 10314 #endif 10315 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10316 "ruby", 10317 #endif 10318 #ifdef FEAT_SCROLLBIND 10319 "scrollbind", 10320 #endif 10321 #ifdef FEAT_CMDL_INFO 10322 "showcmd", 10323 "cmdline_info", 10324 #endif 10325 #ifdef FEAT_SIGNS 10326 "signs", 10327 #endif 10328 #ifdef FEAT_SMARTINDENT 10329 "smartindent", 10330 #endif 10331 #ifdef FEAT_SNIFF 10332 "sniff", 10333 #endif 10334 #ifdef FEAT_STL_OPT 10335 "statusline", 10336 #endif 10337 #ifdef FEAT_SUN_WORKSHOP 10338 "sun_workshop", 10339 #endif 10340 #ifdef FEAT_NETBEANS_INTG 10341 "netbeans_intg", 10342 #endif 10343 #ifdef FEAT_SYN_HL 10344 "spell", 10345 #endif 10346 #ifdef FEAT_SYN_HL 10347 "syntax", 10348 #endif 10349 #if defined(USE_SYSTEM) || !defined(UNIX) 10350 "system", 10351 #endif 10352 #ifdef FEAT_TAG_BINS 10353 "tag_binary", 10354 #endif 10355 #ifdef FEAT_TAG_OLDSTATIC 10356 "tag_old_static", 10357 #endif 10358 #ifdef FEAT_TAG_ANYWHITE 10359 "tag_any_white", 10360 #endif 10361 #ifdef FEAT_TCL 10362 # ifndef DYNAMIC_TCL 10363 "tcl", 10364 # endif 10365 #endif 10366 #ifdef TERMINFO 10367 "terminfo", 10368 #endif 10369 #ifdef FEAT_TERMRESPONSE 10370 "termresponse", 10371 #endif 10372 #ifdef FEAT_TEXTOBJ 10373 "textobjects", 10374 #endif 10375 #ifdef HAVE_TGETENT 10376 "tgetent", 10377 #endif 10378 #ifdef FEAT_TITLE 10379 "title", 10380 #endif 10381 #ifdef FEAT_TOOLBAR 10382 "toolbar", 10383 #endif 10384 #ifdef FEAT_USR_CMDS 10385 "user-commands", /* was accidentally included in 5.4 */ 10386 "user_commands", 10387 #endif 10388 #ifdef FEAT_VIMINFO 10389 "viminfo", 10390 #endif 10391 #ifdef FEAT_VERTSPLIT 10392 "vertsplit", 10393 #endif 10394 #ifdef FEAT_VIRTUALEDIT 10395 "virtualedit", 10396 #endif 10397 #ifdef FEAT_VISUAL 10398 "visual", 10399 #endif 10400 #ifdef FEAT_VISUALEXTRA 10401 "visualextra", 10402 #endif 10403 #ifdef FEAT_VREPLACE 10404 "vreplace", 10405 #endif 10406 #ifdef FEAT_WILDIGN 10407 "wildignore", 10408 #endif 10409 #ifdef FEAT_WILDMENU 10410 "wildmenu", 10411 #endif 10412 #ifdef FEAT_WINDOWS 10413 "windows", 10414 #endif 10415 #ifdef FEAT_WAK 10416 "winaltkeys", 10417 #endif 10418 #ifdef FEAT_WRITEBACKUP 10419 "writebackup", 10420 #endif 10421 #ifdef FEAT_XIM 10422 "xim", 10423 #endif 10424 #ifdef FEAT_XFONTSET 10425 "xfontset", 10426 #endif 10427 #ifdef USE_XSMP 10428 "xsmp", 10429 #endif 10430 #ifdef USE_XSMP_INTERACT 10431 "xsmp_interact", 10432 #endif 10433 #ifdef FEAT_XCLIPBOARD 10434 "xterm_clipboard", 10435 #endif 10436 #ifdef FEAT_XTERM_SAVE 10437 "xterm_save", 10438 #endif 10439 #if defined(UNIX) && defined(FEAT_X11) 10440 "X11", 10441 #endif 10442 NULL 10443 }; 10444 10445 name = get_tv_string(&argvars[0]); 10446 for (i = 0; has_list[i] != NULL; ++i) 10447 if (STRICMP(name, has_list[i]) == 0) 10448 { 10449 n = TRUE; 10450 break; 10451 } 10452 10453 if (n == FALSE) 10454 { 10455 if (STRNICMP(name, "patch", 5) == 0) 10456 n = has_patch(atoi((char *)name + 5)); 10457 else if (STRICMP(name, "vim_starting") == 0) 10458 n = (starting != 0); 10459 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10460 else if (STRICMP(name, "balloon_multiline") == 0) 10461 n = multiline_balloon_available(); 10462 #endif 10463 #ifdef DYNAMIC_TCL 10464 else if (STRICMP(name, "tcl") == 0) 10465 n = tcl_enabled(FALSE); 10466 #endif 10467 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10468 else if (STRICMP(name, "iconv") == 0) 10469 n = iconv_enabled(FALSE); 10470 #endif 10471 #ifdef DYNAMIC_MZSCHEME 10472 else if (STRICMP(name, "mzscheme") == 0) 10473 n = mzscheme_enabled(FALSE); 10474 #endif 10475 #ifdef DYNAMIC_RUBY 10476 else if (STRICMP(name, "ruby") == 0) 10477 n = ruby_enabled(FALSE); 10478 #endif 10479 #ifdef DYNAMIC_PYTHON 10480 else if (STRICMP(name, "python") == 0) 10481 n = python_enabled(FALSE); 10482 #endif 10483 #ifdef DYNAMIC_PERL 10484 else if (STRICMP(name, "perl") == 0) 10485 n = perl_enabled(FALSE); 10486 #endif 10487 #ifdef FEAT_GUI 10488 else if (STRICMP(name, "gui_running") == 0) 10489 n = (gui.in_use || gui.starting); 10490 # ifdef FEAT_GUI_W32 10491 else if (STRICMP(name, "gui_win32s") == 0) 10492 n = gui_is_win32s(); 10493 # endif 10494 # ifdef FEAT_BROWSE 10495 else if (STRICMP(name, "browse") == 0) 10496 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10497 # endif 10498 #endif 10499 #ifdef FEAT_SYN_HL 10500 else if (STRICMP(name, "syntax_items") == 0) 10501 n = syntax_present(curbuf); 10502 #endif 10503 #if defined(WIN3264) 10504 else if (STRICMP(name, "win95") == 0) 10505 n = mch_windows95(); 10506 #endif 10507 #ifdef FEAT_NETBEANS_INTG 10508 else if (STRICMP(name, "netbeans_enabled") == 0) 10509 n = usingNetbeans; 10510 #endif 10511 } 10512 10513 rettv->vval.v_number = n; 10514 } 10515 10516 /* 10517 * "has_key()" function 10518 */ 10519 static void 10520 f_has_key(argvars, rettv) 10521 typval_T *argvars; 10522 typval_T *rettv; 10523 { 10524 rettv->vval.v_number = 0; 10525 if (argvars[0].v_type != VAR_DICT) 10526 { 10527 EMSG(_(e_dictreq)); 10528 return; 10529 } 10530 if (argvars[0].vval.v_dict == NULL) 10531 return; 10532 10533 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10534 get_tv_string(&argvars[1]), -1) != NULL; 10535 } 10536 10537 /* 10538 * "hasmapto()" function 10539 */ 10540 static void 10541 f_hasmapto(argvars, rettv) 10542 typval_T *argvars; 10543 typval_T *rettv; 10544 { 10545 char_u *name; 10546 char_u *mode; 10547 char_u buf[NUMBUFLEN]; 10548 10549 name = get_tv_string(&argvars[0]); 10550 if (argvars[1].v_type == VAR_UNKNOWN) 10551 mode = (char_u *)"nvo"; 10552 else 10553 mode = get_tv_string_buf(&argvars[1], buf); 10554 10555 if (map_to_exists(name, mode)) 10556 rettv->vval.v_number = TRUE; 10557 else 10558 rettv->vval.v_number = FALSE; 10559 } 10560 10561 /* 10562 * "histadd()" function 10563 */ 10564 /*ARGSUSED*/ 10565 static void 10566 f_histadd(argvars, rettv) 10567 typval_T *argvars; 10568 typval_T *rettv; 10569 { 10570 #ifdef FEAT_CMDHIST 10571 int histype; 10572 char_u *str; 10573 char_u buf[NUMBUFLEN]; 10574 #endif 10575 10576 rettv->vval.v_number = FALSE; 10577 if (check_restricted() || check_secure()) 10578 return; 10579 #ifdef FEAT_CMDHIST 10580 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10581 histype = str != NULL ? get_histtype(str) : -1; 10582 if (histype >= 0) 10583 { 10584 str = get_tv_string_buf(&argvars[1], buf); 10585 if (*str != NUL) 10586 { 10587 add_to_history(histype, str, FALSE, NUL); 10588 rettv->vval.v_number = TRUE; 10589 return; 10590 } 10591 } 10592 #endif 10593 } 10594 10595 /* 10596 * "histdel()" function 10597 */ 10598 /*ARGSUSED*/ 10599 static void 10600 f_histdel(argvars, rettv) 10601 typval_T *argvars; 10602 typval_T *rettv; 10603 { 10604 #ifdef FEAT_CMDHIST 10605 int n; 10606 char_u buf[NUMBUFLEN]; 10607 char_u *str; 10608 10609 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10610 if (str == NULL) 10611 n = 0; 10612 else if (argvars[1].v_type == VAR_UNKNOWN) 10613 /* only one argument: clear entire history */ 10614 n = clr_history(get_histtype(str)); 10615 else if (argvars[1].v_type == VAR_NUMBER) 10616 /* index given: remove that entry */ 10617 n = del_history_idx(get_histtype(str), 10618 (int)get_tv_number(&argvars[1])); 10619 else 10620 /* string given: remove all matching entries */ 10621 n = del_history_entry(get_histtype(str), 10622 get_tv_string_buf(&argvars[1], buf)); 10623 rettv->vval.v_number = n; 10624 #else 10625 rettv->vval.v_number = 0; 10626 #endif 10627 } 10628 10629 /* 10630 * "histget()" function 10631 */ 10632 /*ARGSUSED*/ 10633 static void 10634 f_histget(argvars, rettv) 10635 typval_T *argvars; 10636 typval_T *rettv; 10637 { 10638 #ifdef FEAT_CMDHIST 10639 int type; 10640 int idx; 10641 char_u *str; 10642 10643 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10644 if (str == NULL) 10645 rettv->vval.v_string = NULL; 10646 else 10647 { 10648 type = get_histtype(str); 10649 if (argvars[1].v_type == VAR_UNKNOWN) 10650 idx = get_history_idx(type); 10651 else 10652 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10653 /* -1 on type error */ 10654 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10655 } 10656 #else 10657 rettv->vval.v_string = NULL; 10658 #endif 10659 rettv->v_type = VAR_STRING; 10660 } 10661 10662 /* 10663 * "histnr()" function 10664 */ 10665 /*ARGSUSED*/ 10666 static void 10667 f_histnr(argvars, rettv) 10668 typval_T *argvars; 10669 typval_T *rettv; 10670 { 10671 int i; 10672 10673 #ifdef FEAT_CMDHIST 10674 char_u *history = get_tv_string_chk(&argvars[0]); 10675 10676 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10677 if (i >= HIST_CMD && i < HIST_COUNT) 10678 i = get_history_idx(i); 10679 else 10680 #endif 10681 i = -1; 10682 rettv->vval.v_number = i; 10683 } 10684 10685 /* 10686 * "highlightID(name)" function 10687 */ 10688 static void 10689 f_hlID(argvars, rettv) 10690 typval_T *argvars; 10691 typval_T *rettv; 10692 { 10693 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10694 } 10695 10696 /* 10697 * "highlight_exists()" function 10698 */ 10699 static void 10700 f_hlexists(argvars, rettv) 10701 typval_T *argvars; 10702 typval_T *rettv; 10703 { 10704 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10705 } 10706 10707 /* 10708 * "hostname()" function 10709 */ 10710 /*ARGSUSED*/ 10711 static void 10712 f_hostname(argvars, rettv) 10713 typval_T *argvars; 10714 typval_T *rettv; 10715 { 10716 char_u hostname[256]; 10717 10718 mch_get_host_name(hostname, 256); 10719 rettv->v_type = VAR_STRING; 10720 rettv->vval.v_string = vim_strsave(hostname); 10721 } 10722 10723 /* 10724 * iconv() function 10725 */ 10726 /*ARGSUSED*/ 10727 static void 10728 f_iconv(argvars, rettv) 10729 typval_T *argvars; 10730 typval_T *rettv; 10731 { 10732 #ifdef FEAT_MBYTE 10733 char_u buf1[NUMBUFLEN]; 10734 char_u buf2[NUMBUFLEN]; 10735 char_u *from, *to, *str; 10736 vimconv_T vimconv; 10737 #endif 10738 10739 rettv->v_type = VAR_STRING; 10740 rettv->vval.v_string = NULL; 10741 10742 #ifdef FEAT_MBYTE 10743 str = get_tv_string(&argvars[0]); 10744 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10745 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10746 vimconv.vc_type = CONV_NONE; 10747 convert_setup(&vimconv, from, to); 10748 10749 /* If the encodings are equal, no conversion needed. */ 10750 if (vimconv.vc_type == CONV_NONE) 10751 rettv->vval.v_string = vim_strsave(str); 10752 else 10753 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10754 10755 convert_setup(&vimconv, NULL, NULL); 10756 vim_free(from); 10757 vim_free(to); 10758 #endif 10759 } 10760 10761 /* 10762 * "indent()" function 10763 */ 10764 static void 10765 f_indent(argvars, rettv) 10766 typval_T *argvars; 10767 typval_T *rettv; 10768 { 10769 linenr_T lnum; 10770 10771 lnum = get_tv_lnum(argvars); 10772 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10773 rettv->vval.v_number = get_indent_lnum(lnum); 10774 else 10775 rettv->vval.v_number = -1; 10776 } 10777 10778 /* 10779 * "index()" function 10780 */ 10781 static void 10782 f_index(argvars, rettv) 10783 typval_T *argvars; 10784 typval_T *rettv; 10785 { 10786 list_T *l; 10787 listitem_T *item; 10788 long idx = 0; 10789 int ic = FALSE; 10790 10791 rettv->vval.v_number = -1; 10792 if (argvars[0].v_type != VAR_LIST) 10793 { 10794 EMSG(_(e_listreq)); 10795 return; 10796 } 10797 l = argvars[0].vval.v_list; 10798 if (l != NULL) 10799 { 10800 item = l->lv_first; 10801 if (argvars[2].v_type != VAR_UNKNOWN) 10802 { 10803 int error = FALSE; 10804 10805 /* Start at specified item. Use the cached index that list_find() 10806 * sets, so that a negative number also works. */ 10807 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10808 idx = l->lv_idx; 10809 if (argvars[3].v_type != VAR_UNKNOWN) 10810 ic = get_tv_number_chk(&argvars[3], &error); 10811 if (error) 10812 item = NULL; 10813 } 10814 10815 for ( ; item != NULL; item = item->li_next, ++idx) 10816 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10817 { 10818 rettv->vval.v_number = idx; 10819 break; 10820 } 10821 } 10822 } 10823 10824 static int inputsecret_flag = 0; 10825 10826 /* 10827 * "input()" function 10828 * Also handles inputsecret() when inputsecret is set. 10829 */ 10830 static void 10831 f_input(argvars, rettv) 10832 typval_T *argvars; 10833 typval_T *rettv; 10834 { 10835 char_u *prompt = get_tv_string_chk(&argvars[0]); 10836 char_u *p = NULL; 10837 int c; 10838 char_u buf[NUMBUFLEN]; 10839 int cmd_silent_save = cmd_silent; 10840 char_u *defstr = (char_u *)""; 10841 int xp_type = EXPAND_NOTHING; 10842 char_u *xp_arg = NULL; 10843 10844 rettv->v_type = VAR_STRING; 10845 10846 #ifdef NO_CONSOLE_INPUT 10847 /* While starting up, there is no place to enter text. */ 10848 if (no_console_input()) 10849 { 10850 rettv->vval.v_string = NULL; 10851 return; 10852 } 10853 #endif 10854 10855 cmd_silent = FALSE; /* Want to see the prompt. */ 10856 if (prompt != NULL) 10857 { 10858 /* Only the part of the message after the last NL is considered as 10859 * prompt for the command line */ 10860 p = vim_strrchr(prompt, '\n'); 10861 if (p == NULL) 10862 p = prompt; 10863 else 10864 { 10865 ++p; 10866 c = *p; 10867 *p = NUL; 10868 msg_start(); 10869 msg_clr_eos(); 10870 msg_puts_attr(prompt, echo_attr); 10871 msg_didout = FALSE; 10872 msg_starthere(); 10873 *p = c; 10874 } 10875 cmdline_row = msg_row; 10876 10877 if (argvars[1].v_type != VAR_UNKNOWN) 10878 { 10879 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10880 if (defstr != NULL) 10881 stuffReadbuffSpec(defstr); 10882 10883 if (argvars[2].v_type != VAR_UNKNOWN) 10884 { 10885 char_u *xp_name; 10886 int xp_namelen; 10887 long argt; 10888 10889 rettv->vval.v_string = NULL; 10890 10891 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 10892 if (xp_name == NULL) 10893 return; 10894 10895 xp_namelen = STRLEN(xp_name); 10896 10897 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 10898 &xp_arg) == FAIL) 10899 return; 10900 } 10901 } 10902 10903 if (defstr != NULL) 10904 rettv->vval.v_string = 10905 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 10906 xp_type, xp_arg); 10907 10908 vim_free(xp_arg); 10909 10910 /* since the user typed this, no need to wait for return */ 10911 need_wait_return = FALSE; 10912 msg_didout = FALSE; 10913 } 10914 cmd_silent = cmd_silent_save; 10915 } 10916 10917 /* 10918 * "inputdialog()" function 10919 */ 10920 static void 10921 f_inputdialog(argvars, rettv) 10922 typval_T *argvars; 10923 typval_T *rettv; 10924 { 10925 #if defined(FEAT_GUI_TEXTDIALOG) 10926 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10927 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10928 { 10929 char_u *message; 10930 char_u buf[NUMBUFLEN]; 10931 char_u *defstr = (char_u *)""; 10932 10933 message = get_tv_string_chk(&argvars[0]); 10934 if (argvars[1].v_type != VAR_UNKNOWN 10935 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10936 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10937 else 10938 IObuff[0] = NUL; 10939 if (message != NULL && defstr != NULL 10940 && do_dialog(VIM_QUESTION, NULL, message, 10941 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10942 rettv->vval.v_string = vim_strsave(IObuff); 10943 else 10944 { 10945 if (message != NULL && defstr != NULL 10946 && argvars[1].v_type != VAR_UNKNOWN 10947 && argvars[2].v_type != VAR_UNKNOWN) 10948 rettv->vval.v_string = vim_strsave( 10949 get_tv_string_buf(&argvars[2], buf)); 10950 else 10951 rettv->vval.v_string = NULL; 10952 } 10953 rettv->v_type = VAR_STRING; 10954 } 10955 else 10956 #endif 10957 f_input(argvars, rettv); 10958 } 10959 10960 /* 10961 * "inputlist()" function 10962 */ 10963 static void 10964 f_inputlist(argvars, rettv) 10965 typval_T *argvars; 10966 typval_T *rettv; 10967 { 10968 listitem_T *li; 10969 int selected; 10970 int mouse_used; 10971 10972 rettv->vval.v_number = 0; 10973 #ifdef NO_CONSOLE_INPUT 10974 /* While starting up, there is no place to enter text. */ 10975 if (no_console_input()) 10976 return; 10977 #endif 10978 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 10979 { 10980 EMSG2(_(e_listarg), "inputlist()"); 10981 return; 10982 } 10983 10984 msg_start(); 10985 lines_left = Rows; /* avoid more prompt */ 10986 msg_scroll = TRUE; 10987 msg_clr_eos(); 10988 10989 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 10990 { 10991 msg_puts(get_tv_string(&li->li_tv)); 10992 msg_putchar('\n'); 10993 } 10994 10995 /* Ask for choice. */ 10996 selected = prompt_for_number(&mouse_used); 10997 if (mouse_used) 10998 selected -= lines_left; 10999 11000 rettv->vval.v_number = selected; 11001 } 11002 11003 11004 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 11005 11006 /* 11007 * "inputrestore()" function 11008 */ 11009 /*ARGSUSED*/ 11010 static void 11011 f_inputrestore(argvars, rettv) 11012 typval_T *argvars; 11013 typval_T *rettv; 11014 { 11015 if (ga_userinput.ga_len > 0) 11016 { 11017 --ga_userinput.ga_len; 11018 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 11019 + ga_userinput.ga_len); 11020 rettv->vval.v_number = 0; /* OK */ 11021 } 11022 else if (p_verbose > 1) 11023 { 11024 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11025 rettv->vval.v_number = 1; /* Failed */ 11026 } 11027 } 11028 11029 /* 11030 * "inputsave()" function 11031 */ 11032 /*ARGSUSED*/ 11033 static void 11034 f_inputsave(argvars, rettv) 11035 typval_T *argvars; 11036 typval_T *rettv; 11037 { 11038 /* Add an entry to the stack of typehead storage. */ 11039 if (ga_grow(&ga_userinput, 1) == OK) 11040 { 11041 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11042 + ga_userinput.ga_len); 11043 ++ga_userinput.ga_len; 11044 rettv->vval.v_number = 0; /* OK */ 11045 } 11046 else 11047 rettv->vval.v_number = 1; /* Failed */ 11048 } 11049 11050 /* 11051 * "inputsecret()" function 11052 */ 11053 static void 11054 f_inputsecret(argvars, rettv) 11055 typval_T *argvars; 11056 typval_T *rettv; 11057 { 11058 ++cmdline_star; 11059 ++inputsecret_flag; 11060 f_input(argvars, rettv); 11061 --cmdline_star; 11062 --inputsecret_flag; 11063 } 11064 11065 /* 11066 * "insert()" function 11067 */ 11068 static void 11069 f_insert(argvars, rettv) 11070 typval_T *argvars; 11071 typval_T *rettv; 11072 { 11073 long before = 0; 11074 listitem_T *item; 11075 list_T *l; 11076 int error = FALSE; 11077 11078 rettv->vval.v_number = 0; 11079 if (argvars[0].v_type != VAR_LIST) 11080 EMSG2(_(e_listarg), "insert()"); 11081 else if ((l = argvars[0].vval.v_list) != NULL 11082 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11083 { 11084 if (argvars[2].v_type != VAR_UNKNOWN) 11085 before = get_tv_number_chk(&argvars[2], &error); 11086 if (error) 11087 return; /* type error; errmsg already given */ 11088 11089 if (before == l->lv_len) 11090 item = NULL; 11091 else 11092 { 11093 item = list_find(l, before); 11094 if (item == NULL) 11095 { 11096 EMSGN(_(e_listidx), before); 11097 l = NULL; 11098 } 11099 } 11100 if (l != NULL) 11101 { 11102 list_insert_tv(l, &argvars[1], item); 11103 copy_tv(&argvars[0], rettv); 11104 } 11105 } 11106 } 11107 11108 /* 11109 * "isdirectory()" function 11110 */ 11111 static void 11112 f_isdirectory(argvars, rettv) 11113 typval_T *argvars; 11114 typval_T *rettv; 11115 { 11116 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11117 } 11118 11119 /* 11120 * "islocked()" function 11121 */ 11122 static void 11123 f_islocked(argvars, rettv) 11124 typval_T *argvars; 11125 typval_T *rettv; 11126 { 11127 lval_T lv; 11128 char_u *end; 11129 dictitem_T *di; 11130 11131 rettv->vval.v_number = -1; 11132 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11133 FNE_CHECK_START); 11134 if (end != NULL && lv.ll_name != NULL) 11135 { 11136 if (*end != NUL) 11137 EMSG(_(e_trailing)); 11138 else 11139 { 11140 if (lv.ll_tv == NULL) 11141 { 11142 if (check_changedtick(lv.ll_name)) 11143 rettv->vval.v_number = 1; /* always locked */ 11144 else 11145 { 11146 di = find_var(lv.ll_name, NULL); 11147 if (di != NULL) 11148 { 11149 /* Consider a variable locked when: 11150 * 1. the variable itself is locked 11151 * 2. the value of the variable is locked. 11152 * 3. the List or Dict value is locked. 11153 */ 11154 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11155 || tv_islocked(&di->di_tv)); 11156 } 11157 } 11158 } 11159 else if (lv.ll_range) 11160 EMSG(_("E745: Range not allowed")); 11161 else if (lv.ll_newkey != NULL) 11162 EMSG2(_(e_dictkey), lv.ll_newkey); 11163 else if (lv.ll_list != NULL) 11164 /* List item. */ 11165 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11166 else 11167 /* Dictionary item. */ 11168 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11169 } 11170 } 11171 11172 clear_lval(&lv); 11173 } 11174 11175 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11176 11177 /* 11178 * Turn a dict into a list: 11179 * "what" == 0: list of keys 11180 * "what" == 1: list of values 11181 * "what" == 2: list of items 11182 */ 11183 static void 11184 dict_list(argvars, rettv, what) 11185 typval_T *argvars; 11186 typval_T *rettv; 11187 int what; 11188 { 11189 list_T *l; 11190 list_T *l2; 11191 dictitem_T *di; 11192 hashitem_T *hi; 11193 listitem_T *li; 11194 listitem_T *li2; 11195 dict_T *d; 11196 int todo; 11197 11198 rettv->vval.v_number = 0; 11199 if (argvars[0].v_type != VAR_DICT) 11200 { 11201 EMSG(_(e_dictreq)); 11202 return; 11203 } 11204 if ((d = argvars[0].vval.v_dict) == NULL) 11205 return; 11206 11207 l = list_alloc(); 11208 if (l == NULL) 11209 return; 11210 rettv->v_type = VAR_LIST; 11211 rettv->vval.v_list = l; 11212 ++l->lv_refcount; 11213 11214 todo = d->dv_hashtab.ht_used; 11215 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11216 { 11217 if (!HASHITEM_EMPTY(hi)) 11218 { 11219 --todo; 11220 di = HI2DI(hi); 11221 11222 li = listitem_alloc(); 11223 if (li == NULL) 11224 break; 11225 list_append(l, li); 11226 11227 if (what == 0) 11228 { 11229 /* keys() */ 11230 li->li_tv.v_type = VAR_STRING; 11231 li->li_tv.v_lock = 0; 11232 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11233 } 11234 else if (what == 1) 11235 { 11236 /* values() */ 11237 copy_tv(&di->di_tv, &li->li_tv); 11238 } 11239 else 11240 { 11241 /* items() */ 11242 l2 = list_alloc(); 11243 li->li_tv.v_type = VAR_LIST; 11244 li->li_tv.v_lock = 0; 11245 li->li_tv.vval.v_list = l2; 11246 if (l2 == NULL) 11247 break; 11248 ++l2->lv_refcount; 11249 11250 li2 = listitem_alloc(); 11251 if (li2 == NULL) 11252 break; 11253 list_append(l2, li2); 11254 li2->li_tv.v_type = VAR_STRING; 11255 li2->li_tv.v_lock = 0; 11256 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11257 11258 li2 = listitem_alloc(); 11259 if (li2 == NULL) 11260 break; 11261 list_append(l2, li2); 11262 copy_tv(&di->di_tv, &li2->li_tv); 11263 } 11264 } 11265 } 11266 } 11267 11268 /* 11269 * "items(dict)" function 11270 */ 11271 static void 11272 f_items(argvars, rettv) 11273 typval_T *argvars; 11274 typval_T *rettv; 11275 { 11276 dict_list(argvars, rettv, 2); 11277 } 11278 11279 /* 11280 * "join()" function 11281 */ 11282 static void 11283 f_join(argvars, rettv) 11284 typval_T *argvars; 11285 typval_T *rettv; 11286 { 11287 garray_T ga; 11288 char_u *sep; 11289 11290 rettv->vval.v_number = 0; 11291 if (argvars[0].v_type != VAR_LIST) 11292 { 11293 EMSG(_(e_listreq)); 11294 return; 11295 } 11296 if (argvars[0].vval.v_list == NULL) 11297 return; 11298 if (argvars[1].v_type == VAR_UNKNOWN) 11299 sep = (char_u *)" "; 11300 else 11301 sep = get_tv_string_chk(&argvars[1]); 11302 11303 rettv->v_type = VAR_STRING; 11304 11305 if (sep != NULL) 11306 { 11307 ga_init2(&ga, (int)sizeof(char), 80); 11308 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11309 ga_append(&ga, NUL); 11310 rettv->vval.v_string = (char_u *)ga.ga_data; 11311 } 11312 else 11313 rettv->vval.v_string = NULL; 11314 } 11315 11316 /* 11317 * "keys()" function 11318 */ 11319 static void 11320 f_keys(argvars, rettv) 11321 typval_T *argvars; 11322 typval_T *rettv; 11323 { 11324 dict_list(argvars, rettv, 0); 11325 } 11326 11327 /* 11328 * "last_buffer_nr()" function. 11329 */ 11330 /*ARGSUSED*/ 11331 static void 11332 f_last_buffer_nr(argvars, rettv) 11333 typval_T *argvars; 11334 typval_T *rettv; 11335 { 11336 int n = 0; 11337 buf_T *buf; 11338 11339 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11340 if (n < buf->b_fnum) 11341 n = buf->b_fnum; 11342 11343 rettv->vval.v_number = n; 11344 } 11345 11346 /* 11347 * "len()" function 11348 */ 11349 static void 11350 f_len(argvars, rettv) 11351 typval_T *argvars; 11352 typval_T *rettv; 11353 { 11354 switch (argvars[0].v_type) 11355 { 11356 case VAR_STRING: 11357 case VAR_NUMBER: 11358 rettv->vval.v_number = (varnumber_T)STRLEN( 11359 get_tv_string(&argvars[0])); 11360 break; 11361 case VAR_LIST: 11362 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11363 break; 11364 case VAR_DICT: 11365 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11366 break; 11367 default: 11368 EMSG(_("E701: Invalid type for len()")); 11369 break; 11370 } 11371 } 11372 11373 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11374 11375 static void 11376 libcall_common(argvars, rettv, type) 11377 typval_T *argvars; 11378 typval_T *rettv; 11379 int type; 11380 { 11381 #ifdef FEAT_LIBCALL 11382 char_u *string_in; 11383 char_u **string_result; 11384 int nr_result; 11385 #endif 11386 11387 rettv->v_type = type; 11388 if (type == VAR_NUMBER) 11389 rettv->vval.v_number = 0; 11390 else 11391 rettv->vval.v_string = NULL; 11392 11393 if (check_restricted() || check_secure()) 11394 return; 11395 11396 #ifdef FEAT_LIBCALL 11397 /* The first two args must be strings, otherwise its meaningless */ 11398 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11399 { 11400 string_in = NULL; 11401 if (argvars[2].v_type == VAR_STRING) 11402 string_in = argvars[2].vval.v_string; 11403 if (type == VAR_NUMBER) 11404 string_result = NULL; 11405 else 11406 string_result = &rettv->vval.v_string; 11407 if (mch_libcall(argvars[0].vval.v_string, 11408 argvars[1].vval.v_string, 11409 string_in, 11410 argvars[2].vval.v_number, 11411 string_result, 11412 &nr_result) == OK 11413 && type == VAR_NUMBER) 11414 rettv->vval.v_number = nr_result; 11415 } 11416 #endif 11417 } 11418 11419 /* 11420 * "libcall()" function 11421 */ 11422 static void 11423 f_libcall(argvars, rettv) 11424 typval_T *argvars; 11425 typval_T *rettv; 11426 { 11427 libcall_common(argvars, rettv, VAR_STRING); 11428 } 11429 11430 /* 11431 * "libcallnr()" function 11432 */ 11433 static void 11434 f_libcallnr(argvars, rettv) 11435 typval_T *argvars; 11436 typval_T *rettv; 11437 { 11438 libcall_common(argvars, rettv, VAR_NUMBER); 11439 } 11440 11441 /* 11442 * "line(string)" function 11443 */ 11444 static void 11445 f_line(argvars, rettv) 11446 typval_T *argvars; 11447 typval_T *rettv; 11448 { 11449 linenr_T lnum = 0; 11450 pos_T *fp; 11451 11452 fp = var2fpos(&argvars[0], TRUE); 11453 if (fp != NULL) 11454 lnum = fp->lnum; 11455 rettv->vval.v_number = lnum; 11456 } 11457 11458 /* 11459 * "line2byte(lnum)" function 11460 */ 11461 /*ARGSUSED*/ 11462 static void 11463 f_line2byte(argvars, rettv) 11464 typval_T *argvars; 11465 typval_T *rettv; 11466 { 11467 #ifndef FEAT_BYTEOFF 11468 rettv->vval.v_number = -1; 11469 #else 11470 linenr_T lnum; 11471 11472 lnum = get_tv_lnum(argvars); 11473 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11474 rettv->vval.v_number = -1; 11475 else 11476 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11477 if (rettv->vval.v_number >= 0) 11478 ++rettv->vval.v_number; 11479 #endif 11480 } 11481 11482 /* 11483 * "lispindent(lnum)" function 11484 */ 11485 static void 11486 f_lispindent(argvars, rettv) 11487 typval_T *argvars; 11488 typval_T *rettv; 11489 { 11490 #ifdef FEAT_LISP 11491 pos_T pos; 11492 linenr_T lnum; 11493 11494 pos = curwin->w_cursor; 11495 lnum = get_tv_lnum(argvars); 11496 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11497 { 11498 curwin->w_cursor.lnum = lnum; 11499 rettv->vval.v_number = get_lisp_indent(); 11500 curwin->w_cursor = pos; 11501 } 11502 else 11503 #endif 11504 rettv->vval.v_number = -1; 11505 } 11506 11507 /* 11508 * "localtime()" function 11509 */ 11510 /*ARGSUSED*/ 11511 static void 11512 f_localtime(argvars, rettv) 11513 typval_T *argvars; 11514 typval_T *rettv; 11515 { 11516 rettv->vval.v_number = (varnumber_T)time(NULL); 11517 } 11518 11519 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11520 11521 static void 11522 get_maparg(argvars, rettv, exact) 11523 typval_T *argvars; 11524 typval_T *rettv; 11525 int exact; 11526 { 11527 char_u *keys; 11528 char_u *which; 11529 char_u buf[NUMBUFLEN]; 11530 char_u *keys_buf = NULL; 11531 char_u *rhs; 11532 int mode; 11533 garray_T ga; 11534 11535 /* return empty string for failure */ 11536 rettv->v_type = VAR_STRING; 11537 rettv->vval.v_string = NULL; 11538 11539 keys = get_tv_string(&argvars[0]); 11540 if (*keys == NUL) 11541 return; 11542 11543 if (argvars[1].v_type != VAR_UNKNOWN) 11544 which = get_tv_string_buf_chk(&argvars[1], buf); 11545 else 11546 which = (char_u *)""; 11547 if (which == NULL) 11548 return; 11549 11550 mode = get_map_mode(&which, 0); 11551 11552 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11553 rhs = check_map(keys, mode, exact, FALSE); 11554 vim_free(keys_buf); 11555 if (rhs != NULL) 11556 { 11557 ga_init(&ga); 11558 ga.ga_itemsize = 1; 11559 ga.ga_growsize = 40; 11560 11561 while (*rhs != NUL) 11562 ga_concat(&ga, str2special(&rhs, FALSE)); 11563 11564 ga_append(&ga, NUL); 11565 rettv->vval.v_string = (char_u *)ga.ga_data; 11566 } 11567 } 11568 11569 /* 11570 * "map()" function 11571 */ 11572 static void 11573 f_map(argvars, rettv) 11574 typval_T *argvars; 11575 typval_T *rettv; 11576 { 11577 filter_map(argvars, rettv, TRUE); 11578 } 11579 11580 /* 11581 * "maparg()" function 11582 */ 11583 static void 11584 f_maparg(argvars, rettv) 11585 typval_T *argvars; 11586 typval_T *rettv; 11587 { 11588 get_maparg(argvars, rettv, TRUE); 11589 } 11590 11591 /* 11592 * "mapcheck()" function 11593 */ 11594 static void 11595 f_mapcheck(argvars, rettv) 11596 typval_T *argvars; 11597 typval_T *rettv; 11598 { 11599 get_maparg(argvars, rettv, FALSE); 11600 } 11601 11602 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11603 11604 static void 11605 find_some_match(argvars, rettv, type) 11606 typval_T *argvars; 11607 typval_T *rettv; 11608 int type; 11609 { 11610 char_u *str = NULL; 11611 char_u *expr = NULL; 11612 char_u *pat; 11613 regmatch_T regmatch; 11614 char_u patbuf[NUMBUFLEN]; 11615 char_u strbuf[NUMBUFLEN]; 11616 char_u *save_cpo; 11617 long start = 0; 11618 long nth = 1; 11619 int match = 0; 11620 list_T *l = NULL; 11621 listitem_T *li = NULL; 11622 long idx = 0; 11623 char_u *tofree = NULL; 11624 11625 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11626 save_cpo = p_cpo; 11627 p_cpo = (char_u *)""; 11628 11629 rettv->vval.v_number = -1; 11630 if (type == 3) 11631 { 11632 /* return empty list when there are no matches */ 11633 if ((rettv->vval.v_list = list_alloc()) == NULL) 11634 goto theend; 11635 rettv->v_type = VAR_LIST; 11636 ++rettv->vval.v_list->lv_refcount; 11637 } 11638 else if (type == 2) 11639 { 11640 rettv->v_type = VAR_STRING; 11641 rettv->vval.v_string = NULL; 11642 } 11643 11644 if (argvars[0].v_type == VAR_LIST) 11645 { 11646 if ((l = argvars[0].vval.v_list) == NULL) 11647 goto theend; 11648 li = l->lv_first; 11649 } 11650 else 11651 expr = str = get_tv_string(&argvars[0]); 11652 11653 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11654 if (pat == NULL) 11655 goto theend; 11656 11657 if (argvars[2].v_type != VAR_UNKNOWN) 11658 { 11659 int error = FALSE; 11660 11661 start = get_tv_number_chk(&argvars[2], &error); 11662 if (error) 11663 goto theend; 11664 if (l != NULL) 11665 { 11666 li = list_find(l, start); 11667 if (li == NULL) 11668 goto theend; 11669 idx = l->lv_idx; /* use the cached index */ 11670 } 11671 else 11672 { 11673 if (start < 0) 11674 start = 0; 11675 if (start > (long)STRLEN(str)) 11676 goto theend; 11677 str += start; 11678 } 11679 11680 if (argvars[3].v_type != VAR_UNKNOWN) 11681 nth = get_tv_number_chk(&argvars[3], &error); 11682 if (error) 11683 goto theend; 11684 } 11685 11686 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11687 if (regmatch.regprog != NULL) 11688 { 11689 regmatch.rm_ic = p_ic; 11690 11691 for (;;) 11692 { 11693 if (l != NULL) 11694 { 11695 if (li == NULL) 11696 { 11697 match = FALSE; 11698 break; 11699 } 11700 vim_free(tofree); 11701 str = echo_string(&li->li_tv, &tofree, strbuf); 11702 if (str == NULL) 11703 break; 11704 } 11705 11706 match = vim_regexec_nl(®match, str, (colnr_T)0); 11707 11708 if (match && --nth <= 0) 11709 break; 11710 if (l == NULL && !match) 11711 break; 11712 11713 /* Advance to just after the match. */ 11714 if (l != NULL) 11715 { 11716 li = li->li_next; 11717 ++idx; 11718 } 11719 else 11720 { 11721 #ifdef FEAT_MBYTE 11722 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11723 #else 11724 str = regmatch.startp[0] + 1; 11725 #endif 11726 } 11727 } 11728 11729 if (match) 11730 { 11731 if (type == 3) 11732 { 11733 int i; 11734 11735 /* return list with matched string and submatches */ 11736 for (i = 0; i < NSUBEXP; ++i) 11737 { 11738 if (regmatch.endp[i] == NULL) 11739 break; 11740 if (list_append_string(rettv->vval.v_list, 11741 regmatch.startp[i], 11742 (int)(regmatch.endp[i] - regmatch.startp[i])) 11743 == FAIL) 11744 break; 11745 } 11746 } 11747 else if (type == 2) 11748 { 11749 /* return matched string */ 11750 if (l != NULL) 11751 copy_tv(&li->li_tv, rettv); 11752 else 11753 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11754 (int)(regmatch.endp[0] - regmatch.startp[0])); 11755 } 11756 else if (l != NULL) 11757 rettv->vval.v_number = idx; 11758 else 11759 { 11760 if (type != 0) 11761 rettv->vval.v_number = 11762 (varnumber_T)(regmatch.startp[0] - str); 11763 else 11764 rettv->vval.v_number = 11765 (varnumber_T)(regmatch.endp[0] - str); 11766 rettv->vval.v_number += str - expr; 11767 } 11768 } 11769 vim_free(regmatch.regprog); 11770 } 11771 11772 theend: 11773 vim_free(tofree); 11774 p_cpo = save_cpo; 11775 } 11776 11777 /* 11778 * "match()" function 11779 */ 11780 static void 11781 f_match(argvars, rettv) 11782 typval_T *argvars; 11783 typval_T *rettv; 11784 { 11785 find_some_match(argvars, rettv, 1); 11786 } 11787 11788 /* 11789 * "matchend()" function 11790 */ 11791 static void 11792 f_matchend(argvars, rettv) 11793 typval_T *argvars; 11794 typval_T *rettv; 11795 { 11796 find_some_match(argvars, rettv, 0); 11797 } 11798 11799 /* 11800 * "matchlist()" function 11801 */ 11802 static void 11803 f_matchlist(argvars, rettv) 11804 typval_T *argvars; 11805 typval_T *rettv; 11806 { 11807 find_some_match(argvars, rettv, 3); 11808 } 11809 11810 /* 11811 * "matchstr()" function 11812 */ 11813 static void 11814 f_matchstr(argvars, rettv) 11815 typval_T *argvars; 11816 typval_T *rettv; 11817 { 11818 find_some_match(argvars, rettv, 2); 11819 } 11820 11821 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11822 11823 static void 11824 max_min(argvars, rettv, domax) 11825 typval_T *argvars; 11826 typval_T *rettv; 11827 int domax; 11828 { 11829 long n = 0; 11830 long i; 11831 int error = FALSE; 11832 11833 if (argvars[0].v_type == VAR_LIST) 11834 { 11835 list_T *l; 11836 listitem_T *li; 11837 11838 l = argvars[0].vval.v_list; 11839 if (l != NULL) 11840 { 11841 li = l->lv_first; 11842 if (li != NULL) 11843 { 11844 n = get_tv_number_chk(&li->li_tv, &error); 11845 for (;;) 11846 { 11847 li = li->li_next; 11848 if (li == NULL) 11849 break; 11850 i = get_tv_number_chk(&li->li_tv, &error); 11851 if (domax ? i > n : i < n) 11852 n = i; 11853 } 11854 } 11855 } 11856 } 11857 else if (argvars[0].v_type == VAR_DICT) 11858 { 11859 dict_T *d; 11860 int first = TRUE; 11861 hashitem_T *hi; 11862 int todo; 11863 11864 d = argvars[0].vval.v_dict; 11865 if (d != NULL) 11866 { 11867 todo = d->dv_hashtab.ht_used; 11868 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11869 { 11870 if (!HASHITEM_EMPTY(hi)) 11871 { 11872 --todo; 11873 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11874 if (first) 11875 { 11876 n = i; 11877 first = FALSE; 11878 } 11879 else if (domax ? i > n : i < n) 11880 n = i; 11881 } 11882 } 11883 } 11884 } 11885 else 11886 EMSG(_(e_listdictarg)); 11887 rettv->vval.v_number = error ? 0 : n; 11888 } 11889 11890 /* 11891 * "max()" function 11892 */ 11893 static void 11894 f_max(argvars, rettv) 11895 typval_T *argvars; 11896 typval_T *rettv; 11897 { 11898 max_min(argvars, rettv, TRUE); 11899 } 11900 11901 /* 11902 * "min()" function 11903 */ 11904 static void 11905 f_min(argvars, rettv) 11906 typval_T *argvars; 11907 typval_T *rettv; 11908 { 11909 max_min(argvars, rettv, FALSE); 11910 } 11911 11912 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11913 11914 /* 11915 * Create the directory in which "dir" is located, and higher levels when 11916 * needed. 11917 */ 11918 static int 11919 mkdir_recurse(dir, prot) 11920 char_u *dir; 11921 int prot; 11922 { 11923 char_u *p; 11924 char_u *updir; 11925 int r = FAIL; 11926 11927 /* Get end of directory name in "dir". 11928 * We're done when it's "/" or "c:/". */ 11929 p = gettail_sep(dir); 11930 if (p <= get_past_head(dir)) 11931 return OK; 11932 11933 /* If the directory exists we're done. Otherwise: create it.*/ 11934 updir = vim_strnsave(dir, (int)(p - dir)); 11935 if (updir == NULL) 11936 return FAIL; 11937 if (mch_isdir(updir)) 11938 r = OK; 11939 else if (mkdir_recurse(updir, prot) == OK) 11940 r = vim_mkdir_emsg(updir, prot); 11941 vim_free(updir); 11942 return r; 11943 } 11944 11945 #ifdef vim_mkdir 11946 /* 11947 * "mkdir()" function 11948 */ 11949 static void 11950 f_mkdir(argvars, rettv) 11951 typval_T *argvars; 11952 typval_T *rettv; 11953 { 11954 char_u *dir; 11955 char_u buf[NUMBUFLEN]; 11956 int prot = 0755; 11957 11958 rettv->vval.v_number = FAIL; 11959 if (check_restricted() || check_secure()) 11960 return; 11961 11962 dir = get_tv_string_buf(&argvars[0], buf); 11963 if (argvars[1].v_type != VAR_UNKNOWN) 11964 { 11965 if (argvars[2].v_type != VAR_UNKNOWN) 11966 prot = get_tv_number_chk(&argvars[2], NULL); 11967 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11968 mkdir_recurse(dir, prot); 11969 } 11970 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11971 } 11972 #endif 11973 11974 /* 11975 * "mode()" function 11976 */ 11977 /*ARGSUSED*/ 11978 static void 11979 f_mode(argvars, rettv) 11980 typval_T *argvars; 11981 typval_T *rettv; 11982 { 11983 char_u buf[2]; 11984 11985 #ifdef FEAT_VISUAL 11986 if (VIsual_active) 11987 { 11988 if (VIsual_select) 11989 buf[0] = VIsual_mode + 's' - 'v'; 11990 else 11991 buf[0] = VIsual_mode; 11992 } 11993 else 11994 #endif 11995 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11996 buf[0] = 'r'; 11997 else if (State & INSERT) 11998 { 11999 if (State & REPLACE_FLAG) 12000 buf[0] = 'R'; 12001 else 12002 buf[0] = 'i'; 12003 } 12004 else if (State & CMDLINE) 12005 buf[0] = 'c'; 12006 else 12007 buf[0] = 'n'; 12008 12009 buf[1] = NUL; 12010 rettv->vval.v_string = vim_strsave(buf); 12011 rettv->v_type = VAR_STRING; 12012 } 12013 12014 /* 12015 * "nextnonblank()" function 12016 */ 12017 static void 12018 f_nextnonblank(argvars, rettv) 12019 typval_T *argvars; 12020 typval_T *rettv; 12021 { 12022 linenr_T lnum; 12023 12024 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12025 { 12026 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12027 { 12028 lnum = 0; 12029 break; 12030 } 12031 if (*skipwhite(ml_get(lnum)) != NUL) 12032 break; 12033 } 12034 rettv->vval.v_number = lnum; 12035 } 12036 12037 /* 12038 * "nr2char()" function 12039 */ 12040 static void 12041 f_nr2char(argvars, rettv) 12042 typval_T *argvars; 12043 typval_T *rettv; 12044 { 12045 char_u buf[NUMBUFLEN]; 12046 12047 #ifdef FEAT_MBYTE 12048 if (has_mbyte) 12049 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12050 else 12051 #endif 12052 { 12053 buf[0] = (char_u)get_tv_number(&argvars[0]); 12054 buf[1] = NUL; 12055 } 12056 rettv->v_type = VAR_STRING; 12057 rettv->vval.v_string = vim_strsave(buf); 12058 } 12059 12060 /* 12061 * "prevnonblank()" function 12062 */ 12063 static void 12064 f_prevnonblank(argvars, rettv) 12065 typval_T *argvars; 12066 typval_T *rettv; 12067 { 12068 linenr_T lnum; 12069 12070 lnum = get_tv_lnum(argvars); 12071 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12072 lnum = 0; 12073 else 12074 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12075 --lnum; 12076 rettv->vval.v_number = lnum; 12077 } 12078 12079 #ifdef HAVE_STDARG_H 12080 /* This dummy va_list is here because: 12081 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12082 * - locally in the function results in a "used before set" warning 12083 * - using va_start() to initialize it gives "function with fixed args" error */ 12084 static va_list ap; 12085 #endif 12086 12087 /* 12088 * "printf()" function 12089 */ 12090 static void 12091 f_printf(argvars, rettv) 12092 typval_T *argvars; 12093 typval_T *rettv; 12094 { 12095 rettv->v_type = VAR_STRING; 12096 rettv->vval.v_string = NULL; 12097 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12098 { 12099 char_u buf[NUMBUFLEN]; 12100 int len; 12101 char_u *s; 12102 int saved_did_emsg = did_emsg; 12103 char *fmt; 12104 12105 /* Get the required length, allocate the buffer and do it for real. */ 12106 did_emsg = FALSE; 12107 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12108 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12109 if (!did_emsg) 12110 { 12111 s = alloc(len + 1); 12112 if (s != NULL) 12113 { 12114 rettv->vval.v_string = s; 12115 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12116 } 12117 } 12118 did_emsg |= saved_did_emsg; 12119 } 12120 #endif 12121 } 12122 12123 /* 12124 * "range()" function 12125 */ 12126 static void 12127 f_range(argvars, rettv) 12128 typval_T *argvars; 12129 typval_T *rettv; 12130 { 12131 long start; 12132 long end; 12133 long stride = 1; 12134 long i; 12135 list_T *l; 12136 int error = FALSE; 12137 12138 start = get_tv_number_chk(&argvars[0], &error); 12139 if (argvars[1].v_type == VAR_UNKNOWN) 12140 { 12141 end = start - 1; 12142 start = 0; 12143 } 12144 else 12145 { 12146 end = get_tv_number_chk(&argvars[1], &error); 12147 if (argvars[2].v_type != VAR_UNKNOWN) 12148 stride = get_tv_number_chk(&argvars[2], &error); 12149 } 12150 12151 rettv->vval.v_number = 0; 12152 if (error) 12153 return; /* type error; errmsg already given */ 12154 if (stride == 0) 12155 EMSG(_("E726: Stride is zero")); 12156 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12157 EMSG(_("E727: Start past end")); 12158 else 12159 { 12160 l = list_alloc(); 12161 if (l != NULL) 12162 { 12163 rettv->v_type = VAR_LIST; 12164 rettv->vval.v_list = l; 12165 ++l->lv_refcount; 12166 12167 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12168 if (list_append_number(l, (varnumber_T)i) == FAIL) 12169 break; 12170 } 12171 } 12172 } 12173 12174 /* 12175 * "readfile()" function 12176 */ 12177 static void 12178 f_readfile(argvars, rettv) 12179 typval_T *argvars; 12180 typval_T *rettv; 12181 { 12182 int binary = FALSE; 12183 char_u *fname; 12184 FILE *fd; 12185 list_T *l; 12186 listitem_T *li; 12187 #define FREAD_SIZE 200 /* optimized for text lines */ 12188 char_u buf[FREAD_SIZE]; 12189 int readlen; /* size of last fread() */ 12190 int buflen; /* nr of valid chars in buf[] */ 12191 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12192 int tolist; /* first byte in buf[] still to be put in list */ 12193 int chop; /* how many CR to chop off */ 12194 char_u *prev = NULL; /* previously read bytes, if any */ 12195 int prevlen = 0; /* length of "prev" if not NULL */ 12196 char_u *s; 12197 int len; 12198 long maxline = MAXLNUM; 12199 long cnt = 0; 12200 12201 if (argvars[1].v_type != VAR_UNKNOWN) 12202 { 12203 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12204 binary = TRUE; 12205 if (argvars[2].v_type != VAR_UNKNOWN) 12206 maxline = get_tv_number(&argvars[2]); 12207 } 12208 12209 l = list_alloc(); 12210 if (l == NULL) 12211 return; 12212 rettv->v_type = VAR_LIST; 12213 rettv->vval.v_list = l; 12214 l->lv_refcount = 1; 12215 12216 /* Always open the file in binary mode, library functions have a mind of 12217 * their own about CR-LF conversion. */ 12218 fname = get_tv_string(&argvars[0]); 12219 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12220 { 12221 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12222 return; 12223 } 12224 12225 filtd = 0; 12226 while (cnt < maxline || maxline < 0) 12227 { 12228 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12229 buflen = filtd + readlen; 12230 tolist = 0; 12231 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12232 { 12233 if (buf[filtd] == '\n' || readlen <= 0) 12234 { 12235 /* Only when in binary mode add an empty list item when the 12236 * last line ends in a '\n'. */ 12237 if (!binary && readlen == 0 && filtd == 0) 12238 break; 12239 12240 /* Found end-of-line or end-of-file: add a text line to the 12241 * list. */ 12242 chop = 0; 12243 if (!binary) 12244 while (filtd - chop - 1 >= tolist 12245 && buf[filtd - chop - 1] == '\r') 12246 ++chop; 12247 len = filtd - tolist - chop; 12248 if (prev == NULL) 12249 s = vim_strnsave(buf + tolist, len); 12250 else 12251 { 12252 s = alloc((unsigned)(prevlen + len + 1)); 12253 if (s != NULL) 12254 { 12255 mch_memmove(s, prev, prevlen); 12256 vim_free(prev); 12257 prev = NULL; 12258 mch_memmove(s + prevlen, buf + tolist, len); 12259 s[prevlen + len] = NUL; 12260 } 12261 } 12262 tolist = filtd + 1; 12263 12264 li = listitem_alloc(); 12265 if (li == NULL) 12266 { 12267 vim_free(s); 12268 break; 12269 } 12270 li->li_tv.v_type = VAR_STRING; 12271 li->li_tv.v_lock = 0; 12272 li->li_tv.vval.v_string = s; 12273 list_append(l, li); 12274 12275 if (++cnt >= maxline && maxline >= 0) 12276 break; 12277 if (readlen <= 0) 12278 break; 12279 } 12280 else if (buf[filtd] == NUL) 12281 buf[filtd] = '\n'; 12282 } 12283 if (readlen <= 0) 12284 break; 12285 12286 if (tolist == 0) 12287 { 12288 /* "buf" is full, need to move text to an allocated buffer */ 12289 if (prev == NULL) 12290 { 12291 prev = vim_strnsave(buf, buflen); 12292 prevlen = buflen; 12293 } 12294 else 12295 { 12296 s = alloc((unsigned)(prevlen + buflen)); 12297 if (s != NULL) 12298 { 12299 mch_memmove(s, prev, prevlen); 12300 mch_memmove(s + prevlen, buf, buflen); 12301 vim_free(prev); 12302 prev = s; 12303 prevlen += buflen; 12304 } 12305 } 12306 filtd = 0; 12307 } 12308 else 12309 { 12310 mch_memmove(buf, buf + tolist, buflen - tolist); 12311 filtd -= tolist; 12312 } 12313 } 12314 12315 /* 12316 * For a negative line count use only the lines at the end of the file, 12317 * free the rest. 12318 */ 12319 if (maxline < 0) 12320 while (cnt > -maxline) 12321 { 12322 listitem_remove(l, l->lv_first); 12323 --cnt; 12324 } 12325 12326 vim_free(prev); 12327 fclose(fd); 12328 } 12329 12330 12331 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12332 static void make_connection __ARGS((void)); 12333 static int check_connection __ARGS((void)); 12334 12335 static void 12336 make_connection() 12337 { 12338 if (X_DISPLAY == NULL 12339 # ifdef FEAT_GUI 12340 && !gui.in_use 12341 # endif 12342 ) 12343 { 12344 x_force_connect = TRUE; 12345 setup_term_clip(); 12346 x_force_connect = FALSE; 12347 } 12348 } 12349 12350 static int 12351 check_connection() 12352 { 12353 make_connection(); 12354 if (X_DISPLAY == NULL) 12355 { 12356 EMSG(_("E240: No connection to Vim server")); 12357 return FAIL; 12358 } 12359 return OK; 12360 } 12361 #endif 12362 12363 #ifdef FEAT_CLIENTSERVER 12364 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12365 12366 static void 12367 remote_common(argvars, rettv, expr) 12368 typval_T *argvars; 12369 typval_T *rettv; 12370 int expr; 12371 { 12372 char_u *server_name; 12373 char_u *keys; 12374 char_u *r = NULL; 12375 char_u buf[NUMBUFLEN]; 12376 # ifdef WIN32 12377 HWND w; 12378 # else 12379 Window w; 12380 # endif 12381 12382 if (check_restricted() || check_secure()) 12383 return; 12384 12385 # ifdef FEAT_X11 12386 if (check_connection() == FAIL) 12387 return; 12388 # endif 12389 12390 server_name = get_tv_string_chk(&argvars[0]); 12391 if (server_name == NULL) 12392 return; /* type error; errmsg already given */ 12393 keys = get_tv_string_buf(&argvars[1], buf); 12394 # ifdef WIN32 12395 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12396 # else 12397 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12398 < 0) 12399 # endif 12400 { 12401 if (r != NULL) 12402 EMSG(r); /* sending worked but evaluation failed */ 12403 else 12404 EMSG2(_("E241: Unable to send to %s"), server_name); 12405 return; 12406 } 12407 12408 rettv->vval.v_string = r; 12409 12410 if (argvars[2].v_type != VAR_UNKNOWN) 12411 { 12412 dictitem_T v; 12413 char_u str[30]; 12414 char_u *idvar; 12415 12416 sprintf((char *)str, "0x%x", (unsigned int)w); 12417 v.di_tv.v_type = VAR_STRING; 12418 v.di_tv.vval.v_string = vim_strsave(str); 12419 idvar = get_tv_string_chk(&argvars[2]); 12420 if (idvar != NULL) 12421 set_var(idvar, &v.di_tv, FALSE); 12422 vim_free(v.di_tv.vval.v_string); 12423 } 12424 } 12425 #endif 12426 12427 /* 12428 * "remote_expr()" function 12429 */ 12430 /*ARGSUSED*/ 12431 static void 12432 f_remote_expr(argvars, rettv) 12433 typval_T *argvars; 12434 typval_T *rettv; 12435 { 12436 rettv->v_type = VAR_STRING; 12437 rettv->vval.v_string = NULL; 12438 #ifdef FEAT_CLIENTSERVER 12439 remote_common(argvars, rettv, TRUE); 12440 #endif 12441 } 12442 12443 /* 12444 * "remote_foreground()" function 12445 */ 12446 /*ARGSUSED*/ 12447 static void 12448 f_remote_foreground(argvars, rettv) 12449 typval_T *argvars; 12450 typval_T *rettv; 12451 { 12452 rettv->vval.v_number = 0; 12453 #ifdef FEAT_CLIENTSERVER 12454 # ifdef WIN32 12455 /* On Win32 it's done in this application. */ 12456 { 12457 char_u *server_name = get_tv_string_chk(&argvars[0]); 12458 12459 if (server_name != NULL) 12460 serverForeground(server_name); 12461 } 12462 # else 12463 /* Send a foreground() expression to the server. */ 12464 argvars[1].v_type = VAR_STRING; 12465 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12466 argvars[2].v_type = VAR_UNKNOWN; 12467 remote_common(argvars, rettv, TRUE); 12468 vim_free(argvars[1].vval.v_string); 12469 # endif 12470 #endif 12471 } 12472 12473 /*ARGSUSED*/ 12474 static void 12475 f_remote_peek(argvars, rettv) 12476 typval_T *argvars; 12477 typval_T *rettv; 12478 { 12479 #ifdef FEAT_CLIENTSERVER 12480 dictitem_T v; 12481 char_u *s = NULL; 12482 # ifdef WIN32 12483 int n = 0; 12484 # endif 12485 char_u *serverid; 12486 12487 if (check_restricted() || check_secure()) 12488 { 12489 rettv->vval.v_number = -1; 12490 return; 12491 } 12492 serverid = get_tv_string_chk(&argvars[0]); 12493 if (serverid == NULL) 12494 { 12495 rettv->vval.v_number = -1; 12496 return; /* type error; errmsg already given */ 12497 } 12498 # ifdef WIN32 12499 sscanf(serverid, "%x", &n); 12500 if (n == 0) 12501 rettv->vval.v_number = -1; 12502 else 12503 { 12504 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12505 rettv->vval.v_number = (s != NULL); 12506 } 12507 # else 12508 rettv->vval.v_number = 0; 12509 if (check_connection() == FAIL) 12510 return; 12511 12512 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12513 serverStrToWin(serverid), &s); 12514 # endif 12515 12516 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12517 { 12518 char_u *retvar; 12519 12520 v.di_tv.v_type = VAR_STRING; 12521 v.di_tv.vval.v_string = vim_strsave(s); 12522 retvar = get_tv_string_chk(&argvars[1]); 12523 if (retvar != NULL) 12524 set_var(retvar, &v.di_tv, FALSE); 12525 vim_free(v.di_tv.vval.v_string); 12526 } 12527 #else 12528 rettv->vval.v_number = -1; 12529 #endif 12530 } 12531 12532 /*ARGSUSED*/ 12533 static void 12534 f_remote_read(argvars, rettv) 12535 typval_T *argvars; 12536 typval_T *rettv; 12537 { 12538 char_u *r = NULL; 12539 12540 #ifdef FEAT_CLIENTSERVER 12541 char_u *serverid = get_tv_string_chk(&argvars[0]); 12542 12543 if (serverid != NULL && !check_restricted() && !check_secure()) 12544 { 12545 # ifdef WIN32 12546 /* The server's HWND is encoded in the 'id' parameter */ 12547 int n = 0; 12548 12549 sscanf(serverid, "%x", &n); 12550 if (n != 0) 12551 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12552 if (r == NULL) 12553 # else 12554 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12555 serverStrToWin(serverid), &r, FALSE) < 0) 12556 # endif 12557 EMSG(_("E277: Unable to read a server reply")); 12558 } 12559 #endif 12560 rettv->v_type = VAR_STRING; 12561 rettv->vval.v_string = r; 12562 } 12563 12564 /* 12565 * "remote_send()" function 12566 */ 12567 /*ARGSUSED*/ 12568 static void 12569 f_remote_send(argvars, rettv) 12570 typval_T *argvars; 12571 typval_T *rettv; 12572 { 12573 rettv->v_type = VAR_STRING; 12574 rettv->vval.v_string = NULL; 12575 #ifdef FEAT_CLIENTSERVER 12576 remote_common(argvars, rettv, FALSE); 12577 #endif 12578 } 12579 12580 /* 12581 * "remove()" function 12582 */ 12583 static void 12584 f_remove(argvars, rettv) 12585 typval_T *argvars; 12586 typval_T *rettv; 12587 { 12588 list_T *l; 12589 listitem_T *item, *item2; 12590 listitem_T *li; 12591 long idx; 12592 long end; 12593 char_u *key; 12594 dict_T *d; 12595 dictitem_T *di; 12596 12597 rettv->vval.v_number = 0; 12598 if (argvars[0].v_type == VAR_DICT) 12599 { 12600 if (argvars[2].v_type != VAR_UNKNOWN) 12601 EMSG2(_(e_toomanyarg), "remove()"); 12602 else if ((d = argvars[0].vval.v_dict) != NULL 12603 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12604 { 12605 key = get_tv_string_chk(&argvars[1]); 12606 if (key != NULL) 12607 { 12608 di = dict_find(d, key, -1); 12609 if (di == NULL) 12610 EMSG2(_(e_dictkey), key); 12611 else 12612 { 12613 *rettv = di->di_tv; 12614 init_tv(&di->di_tv); 12615 dictitem_remove(d, di); 12616 } 12617 } 12618 } 12619 } 12620 else if (argvars[0].v_type != VAR_LIST) 12621 EMSG2(_(e_listdictarg), "remove()"); 12622 else if ((l = argvars[0].vval.v_list) != NULL 12623 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12624 { 12625 int error = FALSE; 12626 12627 idx = get_tv_number_chk(&argvars[1], &error); 12628 if (error) 12629 ; /* type error: do nothing, errmsg already given */ 12630 else if ((item = list_find(l, idx)) == NULL) 12631 EMSGN(_(e_listidx), idx); 12632 else 12633 { 12634 if (argvars[2].v_type == VAR_UNKNOWN) 12635 { 12636 /* Remove one item, return its value. */ 12637 list_remove(l, item, item); 12638 *rettv = item->li_tv; 12639 vim_free(item); 12640 } 12641 else 12642 { 12643 /* Remove range of items, return list with values. */ 12644 end = get_tv_number_chk(&argvars[2], &error); 12645 if (error) 12646 ; /* type error: do nothing */ 12647 else if ((item2 = list_find(l, end)) == NULL) 12648 EMSGN(_(e_listidx), end); 12649 else 12650 { 12651 int cnt = 0; 12652 12653 for (li = item; li != NULL; li = li->li_next) 12654 { 12655 ++cnt; 12656 if (li == item2) 12657 break; 12658 } 12659 if (li == NULL) /* didn't find "item2" after "item" */ 12660 EMSG(_(e_invrange)); 12661 else 12662 { 12663 list_remove(l, item, item2); 12664 l = list_alloc(); 12665 if (l != NULL) 12666 { 12667 rettv->v_type = VAR_LIST; 12668 rettv->vval.v_list = l; 12669 l->lv_first = item; 12670 l->lv_last = item2; 12671 l->lv_refcount = 1; 12672 item->li_prev = NULL; 12673 item2->li_next = NULL; 12674 l->lv_len = cnt; 12675 } 12676 } 12677 } 12678 } 12679 } 12680 } 12681 } 12682 12683 /* 12684 * "rename({from}, {to})" function 12685 */ 12686 static void 12687 f_rename(argvars, rettv) 12688 typval_T *argvars; 12689 typval_T *rettv; 12690 { 12691 char_u buf[NUMBUFLEN]; 12692 12693 if (check_restricted() || check_secure()) 12694 rettv->vval.v_number = -1; 12695 else 12696 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12697 get_tv_string_buf(&argvars[1], buf)); 12698 } 12699 12700 /* 12701 * "repeat()" function 12702 */ 12703 /*ARGSUSED*/ 12704 static void 12705 f_repeat(argvars, rettv) 12706 typval_T *argvars; 12707 typval_T *rettv; 12708 { 12709 char_u *p; 12710 int n; 12711 int slen; 12712 int len; 12713 char_u *r; 12714 int i; 12715 list_T *l; 12716 12717 n = get_tv_number(&argvars[1]); 12718 if (argvars[0].v_type == VAR_LIST) 12719 { 12720 l = list_alloc(); 12721 if (l != NULL && argvars[0].vval.v_list != NULL) 12722 { 12723 l->lv_refcount = 1; 12724 while (n-- > 0) 12725 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12726 break; 12727 } 12728 rettv->v_type = VAR_LIST; 12729 rettv->vval.v_list = l; 12730 } 12731 else 12732 { 12733 p = get_tv_string(&argvars[0]); 12734 rettv->v_type = VAR_STRING; 12735 rettv->vval.v_string = NULL; 12736 12737 slen = (int)STRLEN(p); 12738 len = slen * n; 12739 if (len <= 0) 12740 return; 12741 12742 r = alloc(len + 1); 12743 if (r != NULL) 12744 { 12745 for (i = 0; i < n; i++) 12746 mch_memmove(r + i * slen, p, (size_t)slen); 12747 r[len] = NUL; 12748 } 12749 12750 rettv->vval.v_string = r; 12751 } 12752 } 12753 12754 /* 12755 * "resolve()" function 12756 */ 12757 static void 12758 f_resolve(argvars, rettv) 12759 typval_T *argvars; 12760 typval_T *rettv; 12761 { 12762 char_u *p; 12763 12764 p = get_tv_string(&argvars[0]); 12765 #ifdef FEAT_SHORTCUT 12766 { 12767 char_u *v = NULL; 12768 12769 v = mch_resolve_shortcut(p); 12770 if (v != NULL) 12771 rettv->vval.v_string = v; 12772 else 12773 rettv->vval.v_string = vim_strsave(p); 12774 } 12775 #else 12776 # ifdef HAVE_READLINK 12777 { 12778 char_u buf[MAXPATHL + 1]; 12779 char_u *cpy; 12780 int len; 12781 char_u *remain = NULL; 12782 char_u *q; 12783 int is_relative_to_current = FALSE; 12784 int has_trailing_pathsep = FALSE; 12785 int limit = 100; 12786 12787 p = vim_strsave(p); 12788 12789 if (p[0] == '.' && (vim_ispathsep(p[1]) 12790 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12791 is_relative_to_current = TRUE; 12792 12793 len = STRLEN(p); 12794 if (len > 0 && after_pathsep(p, p + len)) 12795 has_trailing_pathsep = TRUE; 12796 12797 q = getnextcomp(p); 12798 if (*q != NUL) 12799 { 12800 /* Separate the first path component in "p", and keep the 12801 * remainder (beginning with the path separator). */ 12802 remain = vim_strsave(q - 1); 12803 q[-1] = NUL; 12804 } 12805 12806 for (;;) 12807 { 12808 for (;;) 12809 { 12810 len = readlink((char *)p, (char *)buf, MAXPATHL); 12811 if (len <= 0) 12812 break; 12813 buf[len] = NUL; 12814 12815 if (limit-- == 0) 12816 { 12817 vim_free(p); 12818 vim_free(remain); 12819 EMSG(_("E655: Too many symbolic links (cycle?)")); 12820 rettv->vval.v_string = NULL; 12821 goto fail; 12822 } 12823 12824 /* Ensure that the result will have a trailing path separator 12825 * if the argument has one. */ 12826 if (remain == NULL && has_trailing_pathsep) 12827 add_pathsep(buf); 12828 12829 /* Separate the first path component in the link value and 12830 * concatenate the remainders. */ 12831 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12832 if (*q != NUL) 12833 { 12834 if (remain == NULL) 12835 remain = vim_strsave(q - 1); 12836 else 12837 { 12838 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12839 if (cpy != NULL) 12840 { 12841 STRCAT(cpy, remain); 12842 vim_free(remain); 12843 remain = cpy; 12844 } 12845 } 12846 q[-1] = NUL; 12847 } 12848 12849 q = gettail(p); 12850 if (q > p && *q == NUL) 12851 { 12852 /* Ignore trailing path separator. */ 12853 q[-1] = NUL; 12854 q = gettail(p); 12855 } 12856 if (q > p && !mch_isFullName(buf)) 12857 { 12858 /* symlink is relative to directory of argument */ 12859 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12860 if (cpy != NULL) 12861 { 12862 STRCPY(cpy, p); 12863 STRCPY(gettail(cpy), buf); 12864 vim_free(p); 12865 p = cpy; 12866 } 12867 } 12868 else 12869 { 12870 vim_free(p); 12871 p = vim_strsave(buf); 12872 } 12873 } 12874 12875 if (remain == NULL) 12876 break; 12877 12878 /* Append the first path component of "remain" to "p". */ 12879 q = getnextcomp(remain + 1); 12880 len = q - remain - (*q != NUL); 12881 cpy = vim_strnsave(p, STRLEN(p) + len); 12882 if (cpy != NULL) 12883 { 12884 STRNCAT(cpy, remain, len); 12885 vim_free(p); 12886 p = cpy; 12887 } 12888 /* Shorten "remain". */ 12889 if (*q != NUL) 12890 STRCPY(remain, q - 1); 12891 else 12892 { 12893 vim_free(remain); 12894 remain = NULL; 12895 } 12896 } 12897 12898 /* If the result is a relative path name, make it explicitly relative to 12899 * the current directory if and only if the argument had this form. */ 12900 if (!vim_ispathsep(*p)) 12901 { 12902 if (is_relative_to_current 12903 && *p != NUL 12904 && !(p[0] == '.' 12905 && (p[1] == NUL 12906 || vim_ispathsep(p[1]) 12907 || (p[1] == '.' 12908 && (p[2] == NUL 12909 || vim_ispathsep(p[2])))))) 12910 { 12911 /* Prepend "./". */ 12912 cpy = concat_str((char_u *)"./", p); 12913 if (cpy != NULL) 12914 { 12915 vim_free(p); 12916 p = cpy; 12917 } 12918 } 12919 else if (!is_relative_to_current) 12920 { 12921 /* Strip leading "./". */ 12922 q = p; 12923 while (q[0] == '.' && vim_ispathsep(q[1])) 12924 q += 2; 12925 if (q > p) 12926 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12927 } 12928 } 12929 12930 /* Ensure that the result will have no trailing path separator 12931 * if the argument had none. But keep "/" or "//". */ 12932 if (!has_trailing_pathsep) 12933 { 12934 q = p + STRLEN(p); 12935 if (after_pathsep(p, q)) 12936 *gettail_sep(p) = NUL; 12937 } 12938 12939 rettv->vval.v_string = p; 12940 } 12941 # else 12942 rettv->vval.v_string = vim_strsave(p); 12943 # endif 12944 #endif 12945 12946 simplify_filename(rettv->vval.v_string); 12947 12948 #ifdef HAVE_READLINK 12949 fail: 12950 #endif 12951 rettv->v_type = VAR_STRING; 12952 } 12953 12954 /* 12955 * "reverse({list})" function 12956 */ 12957 static void 12958 f_reverse(argvars, rettv) 12959 typval_T *argvars; 12960 typval_T *rettv; 12961 { 12962 list_T *l; 12963 listitem_T *li, *ni; 12964 12965 rettv->vval.v_number = 0; 12966 if (argvars[0].v_type != VAR_LIST) 12967 EMSG2(_(e_listarg), "reverse()"); 12968 else if ((l = argvars[0].vval.v_list) != NULL 12969 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12970 { 12971 li = l->lv_last; 12972 l->lv_first = l->lv_last = NULL; 12973 l->lv_len = 0; 12974 while (li != NULL) 12975 { 12976 ni = li->li_prev; 12977 list_append(l, li); 12978 li = ni; 12979 } 12980 rettv->vval.v_list = l; 12981 rettv->v_type = VAR_LIST; 12982 ++l->lv_refcount; 12983 } 12984 } 12985 12986 #define SP_NOMOVE 1 /* don't move cursor */ 12987 #define SP_REPEAT 2 /* repeat to find outer pair */ 12988 #define SP_RETCOUNT 4 /* return matchcount */ 12989 #define SP_SETPCMARK 8 /* set previous context mark */ 12990 12991 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12992 12993 /* 12994 * Get flags for a search function. 12995 * Possibly sets "p_ws". 12996 * Returns BACKWARD, FORWARD or zero (for an error). 12997 */ 12998 static int 12999 get_search_arg(varp, flagsp) 13000 typval_T *varp; 13001 int *flagsp; 13002 { 13003 int dir = FORWARD; 13004 char_u *flags; 13005 char_u nbuf[NUMBUFLEN]; 13006 int mask; 13007 13008 if (varp->v_type != VAR_UNKNOWN) 13009 { 13010 flags = get_tv_string_buf_chk(varp, nbuf); 13011 if (flags == NULL) 13012 return 0; /* type error; errmsg already given */ 13013 while (*flags != NUL) 13014 { 13015 switch (*flags) 13016 { 13017 case 'b': dir = BACKWARD; break; 13018 case 'w': p_ws = TRUE; break; 13019 case 'W': p_ws = FALSE; break; 13020 default: mask = 0; 13021 if (flagsp != NULL) 13022 switch (*flags) 13023 { 13024 case 'n': mask = SP_NOMOVE; break; 13025 case 'r': mask = SP_REPEAT; break; 13026 case 'm': mask = SP_RETCOUNT; break; 13027 case 's': mask = SP_SETPCMARK; break; 13028 } 13029 if (mask == 0) 13030 { 13031 EMSG2(_(e_invarg2), flags); 13032 dir = 0; 13033 } 13034 else 13035 *flagsp |= mask; 13036 } 13037 if (dir == 0) 13038 break; 13039 ++flags; 13040 } 13041 } 13042 return dir; 13043 } 13044 13045 /* 13046 * "search()" function 13047 */ 13048 static void 13049 f_search(argvars, rettv) 13050 typval_T *argvars; 13051 typval_T *rettv; 13052 { 13053 char_u *pat; 13054 pos_T pos; 13055 pos_T save_cursor; 13056 int save_p_ws = p_ws; 13057 int dir; 13058 int flags = 0; 13059 13060 rettv->vval.v_number = 0; /* default: FAIL */ 13061 13062 pat = get_tv_string(&argvars[0]); 13063 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 13064 if (dir == 0) 13065 goto theend; 13066 /* 13067 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 13068 * Check to make sure only those flags are set. 13069 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13070 * flags cannot be set. Check for that condition also. 13071 */ 13072 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 13073 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13074 { 13075 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13076 goto theend; 13077 } 13078 13079 pos = save_cursor = curwin->w_cursor; 13080 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 13081 SEARCH_KEEP, RE_SEARCH) != FAIL) 13082 { 13083 rettv->vval.v_number = pos.lnum; 13084 if (flags & SP_SETPCMARK) 13085 setpcmark(); 13086 curwin->w_cursor = pos; 13087 /* "/$" will put the cursor after the end of the line, may need to 13088 * correct that here */ 13089 check_cursor(); 13090 } 13091 13092 /* If 'n' flag is used: restore cursor position. */ 13093 if (flags & SP_NOMOVE) 13094 curwin->w_cursor = save_cursor; 13095 theend: 13096 p_ws = save_p_ws; 13097 } 13098 13099 /* 13100 * "searchdecl()" function 13101 */ 13102 static void 13103 f_searchdecl(argvars, rettv) 13104 typval_T *argvars; 13105 typval_T *rettv; 13106 { 13107 int locally = 1; 13108 int thisblock = 0; 13109 int error = FALSE; 13110 char_u *name; 13111 13112 rettv->vval.v_number = 1; /* default: FAIL */ 13113 13114 name = get_tv_string_chk(&argvars[0]); 13115 if (argvars[1].v_type != VAR_UNKNOWN) 13116 { 13117 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13118 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13119 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13120 } 13121 if (!error && name != NULL) 13122 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13123 locally, thisblock, SEARCH_KEEP) == FAIL; 13124 } 13125 13126 /* 13127 * "searchpair()" function 13128 */ 13129 static void 13130 f_searchpair(argvars, rettv) 13131 typval_T *argvars; 13132 typval_T *rettv; 13133 { 13134 char_u *spat, *mpat, *epat; 13135 char_u *skip; 13136 int save_p_ws = p_ws; 13137 int dir; 13138 int flags = 0; 13139 char_u nbuf1[NUMBUFLEN]; 13140 char_u nbuf2[NUMBUFLEN]; 13141 char_u nbuf3[NUMBUFLEN]; 13142 13143 rettv->vval.v_number = 0; /* default: FAIL */ 13144 13145 /* Get the three pattern arguments: start, middle, end. */ 13146 spat = get_tv_string_chk(&argvars[0]); 13147 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13148 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13149 if (spat == NULL || mpat == NULL || epat == NULL) 13150 goto theend; /* type error */ 13151 13152 /* Handle the optional fourth argument: flags */ 13153 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13154 if (dir == 0) 13155 goto theend; 13156 /* 13157 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13158 */ 13159 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13160 { 13161 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13162 goto theend; 13163 } 13164 13165 /* Optional fifth argument: skip expresion */ 13166 if (argvars[3].v_type == VAR_UNKNOWN 13167 || argvars[4].v_type == VAR_UNKNOWN) 13168 skip = (char_u *)""; 13169 else 13170 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13171 if (skip == NULL) 13172 goto theend; /* type error */ 13173 13174 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13175 13176 theend: 13177 p_ws = save_p_ws; 13178 } 13179 13180 /* 13181 * Search for a start/middle/end thing. 13182 * Used by searchpair(), see its documentation for the details. 13183 * Returns 0 or -1 for no match, 13184 */ 13185 long 13186 do_searchpair(spat, mpat, epat, dir, skip, flags) 13187 char_u *spat; /* start pattern */ 13188 char_u *mpat; /* middle pattern */ 13189 char_u *epat; /* end pattern */ 13190 int dir; /* BACKWARD or FORWARD */ 13191 char_u *skip; /* skip expression */ 13192 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13193 { 13194 char_u *save_cpo; 13195 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13196 long retval = 0; 13197 pos_T pos; 13198 pos_T firstpos; 13199 pos_T foundpos; 13200 pos_T save_cursor; 13201 pos_T save_pos; 13202 int n; 13203 int r; 13204 int nest = 1; 13205 int err; 13206 13207 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13208 save_cpo = p_cpo; 13209 p_cpo = (char_u *)""; 13210 13211 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13212 * start/middle/end (pat3, for the top pair). */ 13213 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13214 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13215 if (pat2 == NULL || pat3 == NULL) 13216 goto theend; 13217 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13218 if (*mpat == NUL) 13219 STRCPY(pat3, pat2); 13220 else 13221 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13222 spat, epat, mpat); 13223 13224 save_cursor = curwin->w_cursor; 13225 pos = curwin->w_cursor; 13226 firstpos.lnum = 0; 13227 foundpos.lnum = 0; 13228 pat = pat3; 13229 for (;;) 13230 { 13231 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13232 SEARCH_KEEP, RE_SEARCH); 13233 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13234 /* didn't find it or found the first match again: FAIL */ 13235 break; 13236 13237 if (firstpos.lnum == 0) 13238 firstpos = pos; 13239 if (equalpos(pos, foundpos)) 13240 { 13241 /* Found the same position again. Can happen with a pattern that 13242 * has "\zs" at the end and searching backwards. Advance one 13243 * character and try again. */ 13244 if (dir == BACKWARD) 13245 decl(&pos); 13246 else 13247 incl(&pos); 13248 } 13249 foundpos = pos; 13250 13251 /* If the skip pattern matches, ignore this match. */ 13252 if (*skip != NUL) 13253 { 13254 save_pos = curwin->w_cursor; 13255 curwin->w_cursor = pos; 13256 r = eval_to_bool(skip, &err, NULL, FALSE); 13257 curwin->w_cursor = save_pos; 13258 if (err) 13259 { 13260 /* Evaluating {skip} caused an error, break here. */ 13261 curwin->w_cursor = save_cursor; 13262 retval = -1; 13263 break; 13264 } 13265 if (r) 13266 continue; 13267 } 13268 13269 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13270 { 13271 /* Found end when searching backwards or start when searching 13272 * forward: nested pair. */ 13273 ++nest; 13274 pat = pat2; /* nested, don't search for middle */ 13275 } 13276 else 13277 { 13278 /* Found end when searching forward or start when searching 13279 * backward: end of (nested) pair; or found middle in outer pair. */ 13280 if (--nest == 1) 13281 pat = pat3; /* outer level, search for middle */ 13282 } 13283 13284 if (nest == 0) 13285 { 13286 /* Found the match: return matchcount or line number. */ 13287 if (flags & SP_RETCOUNT) 13288 ++retval; 13289 else 13290 retval = pos.lnum; 13291 if (flags & SP_SETPCMARK) 13292 setpcmark(); 13293 curwin->w_cursor = pos; 13294 if (!(flags & SP_REPEAT)) 13295 break; 13296 nest = 1; /* search for next unmatched */ 13297 } 13298 } 13299 13300 /* If 'n' flag is used or search failed: restore cursor position. */ 13301 if ((flags & SP_NOMOVE) || retval == 0) 13302 curwin->w_cursor = save_cursor; 13303 13304 theend: 13305 vim_free(pat2); 13306 vim_free(pat3); 13307 p_cpo = save_cpo; 13308 13309 return retval; 13310 } 13311 13312 /*ARGSUSED*/ 13313 static void 13314 f_server2client(argvars, rettv) 13315 typval_T *argvars; 13316 typval_T *rettv; 13317 { 13318 #ifdef FEAT_CLIENTSERVER 13319 char_u buf[NUMBUFLEN]; 13320 char_u *server = get_tv_string_chk(&argvars[0]); 13321 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13322 13323 rettv->vval.v_number = -1; 13324 if (server == NULL || reply == NULL) 13325 return; 13326 if (check_restricted() || check_secure()) 13327 return; 13328 # ifdef FEAT_X11 13329 if (check_connection() == FAIL) 13330 return; 13331 # endif 13332 13333 if (serverSendReply(server, reply) < 0) 13334 { 13335 EMSG(_("E258: Unable to send to client")); 13336 return; 13337 } 13338 rettv->vval.v_number = 0; 13339 #else 13340 rettv->vval.v_number = -1; 13341 #endif 13342 } 13343 13344 /*ARGSUSED*/ 13345 static void 13346 f_serverlist(argvars, rettv) 13347 typval_T *argvars; 13348 typval_T *rettv; 13349 { 13350 char_u *r = NULL; 13351 13352 #ifdef FEAT_CLIENTSERVER 13353 # ifdef WIN32 13354 r = serverGetVimNames(); 13355 # else 13356 make_connection(); 13357 if (X_DISPLAY != NULL) 13358 r = serverGetVimNames(X_DISPLAY); 13359 # endif 13360 #endif 13361 rettv->v_type = VAR_STRING; 13362 rettv->vval.v_string = r; 13363 } 13364 13365 /* 13366 * "setbufvar()" function 13367 */ 13368 /*ARGSUSED*/ 13369 static void 13370 f_setbufvar(argvars, rettv) 13371 typval_T *argvars; 13372 typval_T *rettv; 13373 { 13374 buf_T *buf; 13375 #ifdef FEAT_AUTOCMD 13376 aco_save_T aco; 13377 #else 13378 buf_T *save_curbuf; 13379 #endif 13380 char_u *varname, *bufvarname; 13381 typval_T *varp; 13382 char_u nbuf[NUMBUFLEN]; 13383 13384 rettv->vval.v_number = 0; 13385 13386 if (check_restricted() || check_secure()) 13387 return; 13388 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13389 varname = get_tv_string_chk(&argvars[1]); 13390 buf = get_buf_tv(&argvars[0]); 13391 varp = &argvars[2]; 13392 13393 if (buf != NULL && varname != NULL && varp != NULL) 13394 { 13395 /* set curbuf to be our buf, temporarily */ 13396 #ifdef FEAT_AUTOCMD 13397 aucmd_prepbuf(&aco, buf); 13398 #else 13399 save_curbuf = curbuf; 13400 curbuf = buf; 13401 #endif 13402 13403 if (*varname == '&') 13404 { 13405 long numval; 13406 char_u *strval; 13407 int error = FALSE; 13408 13409 ++varname; 13410 numval = get_tv_number_chk(varp, &error); 13411 strval = get_tv_string_buf_chk(varp, nbuf); 13412 if (!error && strval != NULL) 13413 set_option_value(varname, numval, strval, OPT_LOCAL); 13414 } 13415 else 13416 { 13417 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13418 if (bufvarname != NULL) 13419 { 13420 STRCPY(bufvarname, "b:"); 13421 STRCPY(bufvarname + 2, varname); 13422 set_var(bufvarname, varp, TRUE); 13423 vim_free(bufvarname); 13424 } 13425 } 13426 13427 /* reset notion of buffer */ 13428 #ifdef FEAT_AUTOCMD 13429 aucmd_restbuf(&aco); 13430 #else 13431 curbuf = save_curbuf; 13432 #endif 13433 } 13434 } 13435 13436 /* 13437 * "setcmdpos()" function 13438 */ 13439 static void 13440 f_setcmdpos(argvars, rettv) 13441 typval_T *argvars; 13442 typval_T *rettv; 13443 { 13444 int pos = (int)get_tv_number(&argvars[0]) - 1; 13445 13446 if (pos >= 0) 13447 rettv->vval.v_number = set_cmdline_pos(pos); 13448 } 13449 13450 /* 13451 * "setline()" function 13452 */ 13453 static void 13454 f_setline(argvars, rettv) 13455 typval_T *argvars; 13456 typval_T *rettv; 13457 { 13458 linenr_T lnum; 13459 char_u *line = NULL; 13460 list_T *l = NULL; 13461 listitem_T *li = NULL; 13462 long added = 0; 13463 linenr_T lcount = curbuf->b_ml.ml_line_count; 13464 13465 lnum = get_tv_lnum(&argvars[0]); 13466 if (argvars[1].v_type == VAR_LIST) 13467 { 13468 l = argvars[1].vval.v_list; 13469 li = l->lv_first; 13470 } 13471 else 13472 line = get_tv_string_chk(&argvars[1]); 13473 13474 rettv->vval.v_number = 0; /* OK */ 13475 for (;;) 13476 { 13477 if (l != NULL) 13478 { 13479 /* list argument, get next string */ 13480 if (li == NULL) 13481 break; 13482 line = get_tv_string_chk(&li->li_tv); 13483 li = li->li_next; 13484 } 13485 13486 rettv->vval.v_number = 1; /* FAIL */ 13487 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13488 break; 13489 if (lnum <= curbuf->b_ml.ml_line_count) 13490 { 13491 /* existing line, replace it */ 13492 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13493 { 13494 changed_bytes(lnum, 0); 13495 check_cursor_col(); 13496 rettv->vval.v_number = 0; /* OK */ 13497 } 13498 } 13499 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13500 { 13501 /* lnum is one past the last line, append the line */ 13502 ++added; 13503 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13504 rettv->vval.v_number = 0; /* OK */ 13505 } 13506 13507 if (l == NULL) /* only one string argument */ 13508 break; 13509 ++lnum; 13510 } 13511 13512 if (added > 0) 13513 appended_lines_mark(lcount, added); 13514 } 13515 13516 /* 13517 * "setqflist()" function 13518 */ 13519 /*ARGSUSED*/ 13520 static void 13521 f_setqflist(argvars, rettv) 13522 typval_T *argvars; 13523 typval_T *rettv; 13524 { 13525 char_u *act; 13526 int action = ' '; 13527 13528 rettv->vval.v_number = -1; 13529 13530 #ifdef FEAT_QUICKFIX 13531 if (argvars[0].v_type != VAR_LIST) 13532 EMSG(_(e_listreq)); 13533 else 13534 { 13535 list_T *l = argvars[0].vval.v_list; 13536 13537 if (argvars[1].v_type == VAR_STRING) 13538 { 13539 act = get_tv_string_chk(&argvars[1]); 13540 if (act == NULL) 13541 return; /* type error; errmsg already given */ 13542 if (*act == 'a' || *act == 'r') 13543 action = *act; 13544 } 13545 13546 if (l != NULL && set_errorlist(l, action) == OK) 13547 rettv->vval.v_number = 0; 13548 } 13549 #endif 13550 } 13551 13552 /* 13553 * "setreg()" function 13554 */ 13555 static void 13556 f_setreg(argvars, rettv) 13557 typval_T *argvars; 13558 typval_T *rettv; 13559 { 13560 int regname; 13561 char_u *strregname; 13562 char_u *stropt; 13563 char_u *strval; 13564 int append; 13565 char_u yank_type; 13566 long block_len; 13567 13568 block_len = -1; 13569 yank_type = MAUTO; 13570 append = FALSE; 13571 13572 strregname = get_tv_string_chk(argvars); 13573 rettv->vval.v_number = 1; /* FAIL is default */ 13574 13575 if (strregname == NULL) 13576 return; /* type error; errmsg already given */ 13577 regname = *strregname; 13578 if (regname == 0 || regname == '@') 13579 regname = '"'; 13580 else if (regname == '=') 13581 return; 13582 13583 if (argvars[2].v_type != VAR_UNKNOWN) 13584 { 13585 stropt = get_tv_string_chk(&argvars[2]); 13586 if (stropt == NULL) 13587 return; /* type error */ 13588 for (; *stropt != NUL; ++stropt) 13589 switch (*stropt) 13590 { 13591 case 'a': case 'A': /* append */ 13592 append = TRUE; 13593 break; 13594 case 'v': case 'c': /* character-wise selection */ 13595 yank_type = MCHAR; 13596 break; 13597 case 'V': case 'l': /* line-wise selection */ 13598 yank_type = MLINE; 13599 break; 13600 #ifdef FEAT_VISUAL 13601 case 'b': case Ctrl_V: /* block-wise selection */ 13602 yank_type = MBLOCK; 13603 if (VIM_ISDIGIT(stropt[1])) 13604 { 13605 ++stropt; 13606 block_len = getdigits(&stropt) - 1; 13607 --stropt; 13608 } 13609 break; 13610 #endif 13611 } 13612 } 13613 13614 strval = get_tv_string_chk(&argvars[1]); 13615 if (strval != NULL) 13616 write_reg_contents_ex(regname, strval, -1, 13617 append, yank_type, block_len); 13618 rettv->vval.v_number = 0; 13619 } 13620 13621 13622 /* 13623 * "setwinvar(expr)" function 13624 */ 13625 /*ARGSUSED*/ 13626 static void 13627 f_setwinvar(argvars, rettv) 13628 typval_T *argvars; 13629 typval_T *rettv; 13630 { 13631 win_T *win; 13632 #ifdef FEAT_WINDOWS 13633 win_T *save_curwin; 13634 #endif 13635 char_u *varname, *winvarname; 13636 typval_T *varp; 13637 char_u nbuf[NUMBUFLEN]; 13638 13639 rettv->vval.v_number = 0; 13640 13641 if (check_restricted() || check_secure()) 13642 return; 13643 win = find_win_by_nr(&argvars[0]); 13644 varname = get_tv_string_chk(&argvars[1]); 13645 varp = &argvars[2]; 13646 13647 if (win != NULL && varname != NULL && varp != NULL) 13648 { 13649 #ifdef FEAT_WINDOWS 13650 /* set curwin to be our win, temporarily */ 13651 save_curwin = curwin; 13652 curwin = win; 13653 curbuf = curwin->w_buffer; 13654 #endif 13655 13656 if (*varname == '&') 13657 { 13658 long numval; 13659 char_u *strval; 13660 int error = FALSE; 13661 13662 ++varname; 13663 numval = get_tv_number_chk(varp, &error); 13664 strval = get_tv_string_buf_chk(varp, nbuf); 13665 if (!error && strval != NULL) 13666 set_option_value(varname, numval, strval, OPT_LOCAL); 13667 } 13668 else 13669 { 13670 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13671 if (winvarname != NULL) 13672 { 13673 STRCPY(winvarname, "w:"); 13674 STRCPY(winvarname + 2, varname); 13675 set_var(winvarname, varp, TRUE); 13676 vim_free(winvarname); 13677 } 13678 } 13679 13680 #ifdef FEAT_WINDOWS 13681 /* Restore current window, if it's still valid (autocomands can make 13682 * it invalid). */ 13683 if (win_valid(save_curwin)) 13684 { 13685 curwin = save_curwin; 13686 curbuf = curwin->w_buffer; 13687 } 13688 #endif 13689 } 13690 } 13691 13692 /* 13693 * "simplify()" function 13694 */ 13695 static void 13696 f_simplify(argvars, rettv) 13697 typval_T *argvars; 13698 typval_T *rettv; 13699 { 13700 char_u *p; 13701 13702 p = get_tv_string(&argvars[0]); 13703 rettv->vval.v_string = vim_strsave(p); 13704 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13705 rettv->v_type = VAR_STRING; 13706 } 13707 13708 static int 13709 #ifdef __BORLANDC__ 13710 _RTLENTRYF 13711 #endif 13712 item_compare __ARGS((const void *s1, const void *s2)); 13713 static int 13714 #ifdef __BORLANDC__ 13715 _RTLENTRYF 13716 #endif 13717 item_compare2 __ARGS((const void *s1, const void *s2)); 13718 13719 static int item_compare_ic; 13720 static char_u *item_compare_func; 13721 static int item_compare_func_err; 13722 #define ITEM_COMPARE_FAIL 999 13723 13724 /* 13725 * Compare functions for f_sort() below. 13726 */ 13727 static int 13728 #ifdef __BORLANDC__ 13729 _RTLENTRYF 13730 #endif 13731 item_compare(s1, s2) 13732 const void *s1; 13733 const void *s2; 13734 { 13735 char_u *p1, *p2; 13736 char_u *tofree1, *tofree2; 13737 int res; 13738 char_u numbuf1[NUMBUFLEN]; 13739 char_u numbuf2[NUMBUFLEN]; 13740 13741 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13742 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13743 if (item_compare_ic) 13744 res = STRICMP(p1, p2); 13745 else 13746 res = STRCMP(p1, p2); 13747 vim_free(tofree1); 13748 vim_free(tofree2); 13749 return res; 13750 } 13751 13752 static int 13753 #ifdef __BORLANDC__ 13754 _RTLENTRYF 13755 #endif 13756 item_compare2(s1, s2) 13757 const void *s1; 13758 const void *s2; 13759 { 13760 int res; 13761 typval_T rettv; 13762 typval_T argv[2]; 13763 int dummy; 13764 13765 /* shortcut after failure in previous call; compare all items equal */ 13766 if (item_compare_func_err) 13767 return 0; 13768 13769 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13770 * in the copy without changing the original list items. */ 13771 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13772 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13773 13774 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13775 res = call_func(item_compare_func, STRLEN(item_compare_func), 13776 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13777 clear_tv(&argv[0]); 13778 clear_tv(&argv[1]); 13779 13780 if (res == FAIL) 13781 res = ITEM_COMPARE_FAIL; 13782 else 13783 /* return value has wrong type */ 13784 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13785 if (item_compare_func_err) 13786 res = ITEM_COMPARE_FAIL; 13787 clear_tv(&rettv); 13788 return res; 13789 } 13790 13791 /* 13792 * "sort({list})" function 13793 */ 13794 static void 13795 f_sort(argvars, rettv) 13796 typval_T *argvars; 13797 typval_T *rettv; 13798 { 13799 list_T *l; 13800 listitem_T *li; 13801 listitem_T **ptrs; 13802 long len; 13803 long i; 13804 13805 rettv->vval.v_number = 0; 13806 if (argvars[0].v_type != VAR_LIST) 13807 EMSG2(_(e_listarg), "sort()"); 13808 else 13809 { 13810 l = argvars[0].vval.v_list; 13811 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13812 return; 13813 rettv->vval.v_list = l; 13814 rettv->v_type = VAR_LIST; 13815 ++l->lv_refcount; 13816 13817 len = list_len(l); 13818 if (len <= 1) 13819 return; /* short list sorts pretty quickly */ 13820 13821 item_compare_ic = FALSE; 13822 item_compare_func = NULL; 13823 if (argvars[1].v_type != VAR_UNKNOWN) 13824 { 13825 if (argvars[1].v_type == VAR_FUNC) 13826 item_compare_func = argvars[1].vval.v_string; 13827 else 13828 { 13829 int error = FALSE; 13830 13831 i = get_tv_number_chk(&argvars[1], &error); 13832 if (error) 13833 return; /* type error; errmsg already given */ 13834 if (i == 1) 13835 item_compare_ic = TRUE; 13836 else 13837 item_compare_func = get_tv_string(&argvars[1]); 13838 } 13839 } 13840 13841 /* Make an array with each entry pointing to an item in the List. */ 13842 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13843 if (ptrs == NULL) 13844 return; 13845 i = 0; 13846 for (li = l->lv_first; li != NULL; li = li->li_next) 13847 ptrs[i++] = li; 13848 13849 item_compare_func_err = FALSE; 13850 /* test the compare function */ 13851 if (item_compare_func != NULL 13852 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13853 == ITEM_COMPARE_FAIL) 13854 EMSG(_("E702: Sort compare function failed")); 13855 else 13856 { 13857 /* Sort the array with item pointers. */ 13858 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13859 item_compare_func == NULL ? item_compare : item_compare2); 13860 13861 if (!item_compare_func_err) 13862 { 13863 /* Clear the List and append the items in the sorted order. */ 13864 l->lv_first = l->lv_last = NULL; 13865 l->lv_len = 0; 13866 for (i = 0; i < len; ++i) 13867 list_append(l, ptrs[i]); 13868 } 13869 } 13870 13871 vim_free(ptrs); 13872 } 13873 } 13874 13875 /* 13876 * "soundfold({word})" function 13877 */ 13878 static void 13879 f_soundfold(argvars, rettv) 13880 typval_T *argvars; 13881 typval_T *rettv; 13882 { 13883 char_u *s; 13884 13885 rettv->v_type = VAR_STRING; 13886 s = get_tv_string(&argvars[0]); 13887 #ifdef FEAT_SYN_HL 13888 rettv->vval.v_string = eval_soundfold(s); 13889 #else 13890 rettv->vval.v_string = vim_strsave(s); 13891 #endif 13892 } 13893 13894 /* 13895 * "spellbadword()" function 13896 */ 13897 /* ARGSUSED */ 13898 static void 13899 f_spellbadword(argvars, rettv) 13900 typval_T *argvars; 13901 typval_T *rettv; 13902 { 13903 char_u *word = (char_u *)""; 13904 #ifdef FEAT_SYN_HL 13905 int len = 0; 13906 hlf_T attr = HLF_COUNT; 13907 list_T *l; 13908 #endif 13909 13910 l = list_alloc(); 13911 if (l == NULL) 13912 return; 13913 rettv->v_type = VAR_LIST; 13914 rettv->vval.v_list = l; 13915 ++l->lv_refcount; 13916 13917 #ifdef FEAT_SYN_HL 13918 if (argvars[0].v_type == VAR_UNKNOWN) 13919 { 13920 /* Find the start and length of the badly spelled word. */ 13921 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 13922 if (len != 0) 13923 word = ml_get_cursor(); 13924 } 13925 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13926 { 13927 char_u *str = get_tv_string_chk(&argvars[0]); 13928 int capcol = -1; 13929 13930 if (str != NULL) 13931 { 13932 /* Check the argument for spelling. */ 13933 while (*str != NUL) 13934 { 13935 len = spell_check(curwin, str, &attr, &capcol); 13936 if (attr != HLF_COUNT) 13937 { 13938 word = str; 13939 break; 13940 } 13941 str += len; 13942 } 13943 } 13944 } 13945 #endif 13946 13947 list_append_string(l, word, len); 13948 list_append_string(l, (char_u *)( 13949 attr == HLF_SPB ? "bad" : 13950 attr == HLF_SPR ? "rare" : 13951 attr == HLF_SPL ? "local" : 13952 attr == HLF_SPC ? "caps" : 13953 ""), -1); 13954 } 13955 13956 /* 13957 * "spellsuggest()" function 13958 */ 13959 static void 13960 f_spellsuggest(argvars, rettv) 13961 typval_T *argvars; 13962 typval_T *rettv; 13963 { 13964 list_T *l; 13965 #ifdef FEAT_SYN_HL 13966 char_u *str; 13967 int typeerr = FALSE; 13968 int maxcount; 13969 garray_T ga; 13970 int i; 13971 listitem_T *li; 13972 int need_capital = FALSE; 13973 #endif 13974 13975 l = list_alloc(); 13976 if (l == NULL) 13977 return; 13978 rettv->v_type = VAR_LIST; 13979 rettv->vval.v_list = l; 13980 ++l->lv_refcount; 13981 13982 #ifdef FEAT_SYN_HL 13983 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13984 { 13985 str = get_tv_string(&argvars[0]); 13986 if (argvars[1].v_type != VAR_UNKNOWN) 13987 { 13988 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 13989 if (maxcount <= 0) 13990 return; 13991 if (argvars[2].v_type != VAR_UNKNOWN) 13992 { 13993 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 13994 if (typeerr) 13995 return; 13996 } 13997 } 13998 else 13999 maxcount = 25; 14000 14001 spell_suggest_list(&ga, str, maxcount, need_capital); 14002 14003 for (i = 0; i < ga.ga_len; ++i) 14004 { 14005 str = ((char_u **)ga.ga_data)[i]; 14006 14007 li = listitem_alloc(); 14008 if (li == NULL) 14009 vim_free(str); 14010 else 14011 { 14012 li->li_tv.v_type = VAR_STRING; 14013 li->li_tv.v_lock = 0; 14014 li->li_tv.vval.v_string = str; 14015 list_append(l, li); 14016 } 14017 } 14018 ga_clear(&ga); 14019 } 14020 #endif 14021 } 14022 14023 static void 14024 f_split(argvars, rettv) 14025 typval_T *argvars; 14026 typval_T *rettv; 14027 { 14028 char_u *str; 14029 char_u *end; 14030 char_u *pat = NULL; 14031 regmatch_T regmatch; 14032 char_u patbuf[NUMBUFLEN]; 14033 char_u *save_cpo; 14034 int match; 14035 list_T *l; 14036 colnr_T col = 0; 14037 int keepempty = FALSE; 14038 int typeerr = FALSE; 14039 14040 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14041 save_cpo = p_cpo; 14042 p_cpo = (char_u *)""; 14043 14044 str = get_tv_string(&argvars[0]); 14045 if (argvars[1].v_type != VAR_UNKNOWN) 14046 { 14047 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14048 if (pat == NULL) 14049 typeerr = TRUE; 14050 if (argvars[2].v_type != VAR_UNKNOWN) 14051 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 14052 } 14053 if (pat == NULL || *pat == NUL) 14054 pat = (char_u *)"[\\x01- ]\\+"; 14055 14056 l = list_alloc(); 14057 if (l == NULL) 14058 return; 14059 rettv->v_type = VAR_LIST; 14060 rettv->vval.v_list = l; 14061 ++l->lv_refcount; 14062 if (typeerr) 14063 return; 14064 14065 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14066 if (regmatch.regprog != NULL) 14067 { 14068 regmatch.rm_ic = FALSE; 14069 while (*str != NUL || keepempty) 14070 { 14071 if (*str == NUL) 14072 match = FALSE; /* empty item at the end */ 14073 else 14074 match = vim_regexec_nl(®match, str, col); 14075 if (match) 14076 end = regmatch.startp[0]; 14077 else 14078 end = str + STRLEN(str); 14079 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 14080 && match && end < regmatch.endp[0])) 14081 { 14082 if (list_append_string(l, str, (int)(end - str)) == FAIL) 14083 break; 14084 } 14085 if (!match) 14086 break; 14087 /* Advance to just after the match. */ 14088 if (regmatch.endp[0] > str) 14089 col = 0; 14090 else 14091 { 14092 /* Don't get stuck at the same match. */ 14093 #ifdef FEAT_MBYTE 14094 col = (*mb_ptr2len)(regmatch.endp[0]); 14095 #else 14096 col = 1; 14097 #endif 14098 } 14099 str = regmatch.endp[0]; 14100 } 14101 14102 vim_free(regmatch.regprog); 14103 } 14104 14105 p_cpo = save_cpo; 14106 } 14107 14108 #ifdef HAVE_STRFTIME 14109 /* 14110 * "strftime({format}[, {time}])" function 14111 */ 14112 static void 14113 f_strftime(argvars, rettv) 14114 typval_T *argvars; 14115 typval_T *rettv; 14116 { 14117 char_u result_buf[256]; 14118 struct tm *curtime; 14119 time_t seconds; 14120 char_u *p; 14121 14122 rettv->v_type = VAR_STRING; 14123 14124 p = get_tv_string(&argvars[0]); 14125 if (argvars[1].v_type == VAR_UNKNOWN) 14126 seconds = time(NULL); 14127 else 14128 seconds = (time_t)get_tv_number(&argvars[1]); 14129 curtime = localtime(&seconds); 14130 /* MSVC returns NULL for an invalid value of seconds. */ 14131 if (curtime == NULL) 14132 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 14133 else 14134 { 14135 # ifdef FEAT_MBYTE 14136 vimconv_T conv; 14137 char_u *enc; 14138 14139 conv.vc_type = CONV_NONE; 14140 enc = enc_locale(); 14141 convert_setup(&conv, p_enc, enc); 14142 if (conv.vc_type != CONV_NONE) 14143 p = string_convert(&conv, p, NULL); 14144 # endif 14145 if (p != NULL) 14146 (void)strftime((char *)result_buf, sizeof(result_buf), 14147 (char *)p, curtime); 14148 else 14149 result_buf[0] = NUL; 14150 14151 # ifdef FEAT_MBYTE 14152 if (conv.vc_type != CONV_NONE) 14153 vim_free(p); 14154 convert_setup(&conv, enc, p_enc); 14155 if (conv.vc_type != CONV_NONE) 14156 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 14157 else 14158 # endif 14159 rettv->vval.v_string = vim_strsave(result_buf); 14160 14161 # ifdef FEAT_MBYTE 14162 /* Release conversion descriptors */ 14163 convert_setup(&conv, NULL, NULL); 14164 vim_free(enc); 14165 # endif 14166 } 14167 } 14168 #endif 14169 14170 /* 14171 * "stridx()" function 14172 */ 14173 static void 14174 f_stridx(argvars, rettv) 14175 typval_T *argvars; 14176 typval_T *rettv; 14177 { 14178 char_u buf[NUMBUFLEN]; 14179 char_u *needle; 14180 char_u *haystack; 14181 char_u *save_haystack; 14182 char_u *pos; 14183 int start_idx; 14184 14185 needle = get_tv_string_chk(&argvars[1]); 14186 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 14187 rettv->vval.v_number = -1; 14188 if (needle == NULL || haystack == NULL) 14189 return; /* type error; errmsg already given */ 14190 14191 if (argvars[2].v_type != VAR_UNKNOWN) 14192 { 14193 int error = FALSE; 14194 14195 start_idx = get_tv_number_chk(&argvars[2], &error); 14196 if (error || start_idx >= (int)STRLEN(haystack)) 14197 return; 14198 if (start_idx >= 0) 14199 haystack += start_idx; 14200 } 14201 14202 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14203 if (pos != NULL) 14204 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14205 } 14206 14207 /* 14208 * "string()" function 14209 */ 14210 static void 14211 f_string(argvars, rettv) 14212 typval_T *argvars; 14213 typval_T *rettv; 14214 { 14215 char_u *tofree; 14216 char_u numbuf[NUMBUFLEN]; 14217 14218 rettv->v_type = VAR_STRING; 14219 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14220 if (tofree == NULL) 14221 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14222 } 14223 14224 /* 14225 * "strlen()" function 14226 */ 14227 static void 14228 f_strlen(argvars, rettv) 14229 typval_T *argvars; 14230 typval_T *rettv; 14231 { 14232 rettv->vval.v_number = (varnumber_T)(STRLEN( 14233 get_tv_string(&argvars[0]))); 14234 } 14235 14236 /* 14237 * "strpart()" function 14238 */ 14239 static void 14240 f_strpart(argvars, rettv) 14241 typval_T *argvars; 14242 typval_T *rettv; 14243 { 14244 char_u *p; 14245 int n; 14246 int len; 14247 int slen; 14248 int error = FALSE; 14249 14250 p = get_tv_string(&argvars[0]); 14251 slen = (int)STRLEN(p); 14252 14253 n = get_tv_number_chk(&argvars[1], &error); 14254 if (error) 14255 len = 0; 14256 else if (argvars[2].v_type != VAR_UNKNOWN) 14257 len = get_tv_number(&argvars[2]); 14258 else 14259 len = slen - n; /* default len: all bytes that are available. */ 14260 14261 /* 14262 * Only return the overlap between the specified part and the actual 14263 * string. 14264 */ 14265 if (n < 0) 14266 { 14267 len += n; 14268 n = 0; 14269 } 14270 else if (n > slen) 14271 n = slen; 14272 if (len < 0) 14273 len = 0; 14274 else if (n + len > slen) 14275 len = slen - n; 14276 14277 rettv->v_type = VAR_STRING; 14278 rettv->vval.v_string = vim_strnsave(p + n, len); 14279 } 14280 14281 /* 14282 * "strridx()" function 14283 */ 14284 static void 14285 f_strridx(argvars, rettv) 14286 typval_T *argvars; 14287 typval_T *rettv; 14288 { 14289 char_u buf[NUMBUFLEN]; 14290 char_u *needle; 14291 char_u *haystack; 14292 char_u *rest; 14293 char_u *lastmatch = NULL; 14294 int haystack_len, end_idx; 14295 14296 needle = get_tv_string_chk(&argvars[1]); 14297 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14298 haystack_len = STRLEN(haystack); 14299 14300 rettv->vval.v_number = -1; 14301 if (needle == NULL || haystack == NULL) 14302 return; /* type error; errmsg already given */ 14303 if (argvars[2].v_type != VAR_UNKNOWN) 14304 { 14305 /* Third argument: upper limit for index */ 14306 end_idx = get_tv_number_chk(&argvars[2], NULL); 14307 if (end_idx < 0) 14308 return; /* can never find a match */ 14309 } 14310 else 14311 end_idx = haystack_len; 14312 14313 if (*needle == NUL) 14314 { 14315 /* Empty string matches past the end. */ 14316 lastmatch = haystack + end_idx; 14317 } 14318 else 14319 { 14320 for (rest = haystack; *rest != '\0'; ++rest) 14321 { 14322 rest = (char_u *)strstr((char *)rest, (char *)needle); 14323 if (rest == NULL || rest > haystack + end_idx) 14324 break; 14325 lastmatch = rest; 14326 } 14327 } 14328 14329 if (lastmatch == NULL) 14330 rettv->vval.v_number = -1; 14331 else 14332 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14333 } 14334 14335 /* 14336 * "strtrans()" function 14337 */ 14338 static void 14339 f_strtrans(argvars, rettv) 14340 typval_T *argvars; 14341 typval_T *rettv; 14342 { 14343 rettv->v_type = VAR_STRING; 14344 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14345 } 14346 14347 /* 14348 * "submatch()" function 14349 */ 14350 static void 14351 f_submatch(argvars, rettv) 14352 typval_T *argvars; 14353 typval_T *rettv; 14354 { 14355 rettv->v_type = VAR_STRING; 14356 rettv->vval.v_string = 14357 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14358 } 14359 14360 /* 14361 * "substitute()" function 14362 */ 14363 static void 14364 f_substitute(argvars, rettv) 14365 typval_T *argvars; 14366 typval_T *rettv; 14367 { 14368 char_u patbuf[NUMBUFLEN]; 14369 char_u subbuf[NUMBUFLEN]; 14370 char_u flagsbuf[NUMBUFLEN]; 14371 14372 char_u *str = get_tv_string_chk(&argvars[0]); 14373 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14374 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14375 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14376 14377 rettv->v_type = VAR_STRING; 14378 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14379 rettv->vval.v_string = NULL; 14380 else 14381 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14382 } 14383 14384 /* 14385 * "synID(lnum, col, trans)" function 14386 */ 14387 /*ARGSUSED*/ 14388 static void 14389 f_synID(argvars, rettv) 14390 typval_T *argvars; 14391 typval_T *rettv; 14392 { 14393 int id = 0; 14394 #ifdef FEAT_SYN_HL 14395 long lnum; 14396 long col; 14397 int trans; 14398 int transerr = FALSE; 14399 14400 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14401 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14402 trans = get_tv_number_chk(&argvars[2], &transerr); 14403 14404 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14405 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14406 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14407 #endif 14408 14409 rettv->vval.v_number = id; 14410 } 14411 14412 /* 14413 * "synIDattr(id, what [, mode])" function 14414 */ 14415 /*ARGSUSED*/ 14416 static void 14417 f_synIDattr(argvars, rettv) 14418 typval_T *argvars; 14419 typval_T *rettv; 14420 { 14421 char_u *p = NULL; 14422 #ifdef FEAT_SYN_HL 14423 int id; 14424 char_u *what; 14425 char_u *mode; 14426 char_u modebuf[NUMBUFLEN]; 14427 int modec; 14428 14429 id = get_tv_number(&argvars[0]); 14430 what = get_tv_string(&argvars[1]); 14431 if (argvars[2].v_type != VAR_UNKNOWN) 14432 { 14433 mode = get_tv_string_buf(&argvars[2], modebuf); 14434 modec = TOLOWER_ASC(mode[0]); 14435 if (modec != 't' && modec != 'c' 14436 #ifdef FEAT_GUI 14437 && modec != 'g' 14438 #endif 14439 ) 14440 modec = 0; /* replace invalid with current */ 14441 } 14442 else 14443 { 14444 #ifdef FEAT_GUI 14445 if (gui.in_use) 14446 modec = 'g'; 14447 else 14448 #endif 14449 if (t_colors > 1) 14450 modec = 'c'; 14451 else 14452 modec = 't'; 14453 } 14454 14455 14456 switch (TOLOWER_ASC(what[0])) 14457 { 14458 case 'b': 14459 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14460 p = highlight_color(id, what, modec); 14461 else /* bold */ 14462 p = highlight_has_attr(id, HL_BOLD, modec); 14463 break; 14464 14465 case 'f': /* fg[#] */ 14466 p = highlight_color(id, what, modec); 14467 break; 14468 14469 case 'i': 14470 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14471 p = highlight_has_attr(id, HL_INVERSE, modec); 14472 else /* italic */ 14473 p = highlight_has_attr(id, HL_ITALIC, modec); 14474 break; 14475 14476 case 'n': /* name */ 14477 p = get_highlight_name(NULL, id - 1); 14478 break; 14479 14480 case 'r': /* reverse */ 14481 p = highlight_has_attr(id, HL_INVERSE, modec); 14482 break; 14483 14484 case 's': /* standout */ 14485 p = highlight_has_attr(id, HL_STANDOUT, modec); 14486 break; 14487 14488 case 'u': 14489 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14490 /* underline */ 14491 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14492 else 14493 /* undercurl */ 14494 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14495 break; 14496 } 14497 14498 if (p != NULL) 14499 p = vim_strsave(p); 14500 #endif 14501 rettv->v_type = VAR_STRING; 14502 rettv->vval.v_string = p; 14503 } 14504 14505 /* 14506 * "synIDtrans(id)" function 14507 */ 14508 /*ARGSUSED*/ 14509 static void 14510 f_synIDtrans(argvars, rettv) 14511 typval_T *argvars; 14512 typval_T *rettv; 14513 { 14514 int id; 14515 14516 #ifdef FEAT_SYN_HL 14517 id = get_tv_number(&argvars[0]); 14518 14519 if (id > 0) 14520 id = syn_get_final_id(id); 14521 else 14522 #endif 14523 id = 0; 14524 14525 rettv->vval.v_number = id; 14526 } 14527 14528 /* 14529 * "system()" function 14530 */ 14531 static void 14532 f_system(argvars, rettv) 14533 typval_T *argvars; 14534 typval_T *rettv; 14535 { 14536 char_u *res = NULL; 14537 char_u *p; 14538 char_u *infile = NULL; 14539 char_u buf[NUMBUFLEN]; 14540 int err = FALSE; 14541 FILE *fd; 14542 14543 if (argvars[1].v_type != VAR_UNKNOWN) 14544 { 14545 /* 14546 * Write the string to a temp file, to be used for input of the shell 14547 * command. 14548 */ 14549 if ((infile = vim_tempname('i')) == NULL) 14550 { 14551 EMSG(_(e_notmp)); 14552 return; 14553 } 14554 14555 fd = mch_fopen((char *)infile, WRITEBIN); 14556 if (fd == NULL) 14557 { 14558 EMSG2(_(e_notopen), infile); 14559 goto done; 14560 } 14561 p = get_tv_string_buf_chk(&argvars[1], buf); 14562 if (p == NULL) 14563 goto done; /* type error; errmsg already given */ 14564 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14565 err = TRUE; 14566 if (fclose(fd) != 0) 14567 err = TRUE; 14568 if (err) 14569 { 14570 EMSG(_("E677: Error writing temp file")); 14571 goto done; 14572 } 14573 } 14574 14575 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14576 14577 #ifdef USE_CR 14578 /* translate <CR> into <NL> */ 14579 if (res != NULL) 14580 { 14581 char_u *s; 14582 14583 for (s = res; *s; ++s) 14584 { 14585 if (*s == CAR) 14586 *s = NL; 14587 } 14588 } 14589 #else 14590 # ifdef USE_CRNL 14591 /* translate <CR><NL> into <NL> */ 14592 if (res != NULL) 14593 { 14594 char_u *s, *d; 14595 14596 d = res; 14597 for (s = res; *s; ++s) 14598 { 14599 if (s[0] == CAR && s[1] == NL) 14600 ++s; 14601 *d++ = *s; 14602 } 14603 *d = NUL; 14604 } 14605 # endif 14606 #endif 14607 14608 done: 14609 if (infile != NULL) 14610 { 14611 mch_remove(infile); 14612 vim_free(infile); 14613 } 14614 rettv->v_type = VAR_STRING; 14615 rettv->vval.v_string = res; 14616 } 14617 14618 /* 14619 * "tagfiles()" function 14620 */ 14621 /*ARGSUSED*/ 14622 static void 14623 f_tagfiles(argvars, rettv) 14624 typval_T *argvars; 14625 typval_T *rettv; 14626 { 14627 char_u fname[MAXPATHL + 1]; 14628 list_T *l; 14629 14630 l = list_alloc(); 14631 if (l == NULL) 14632 { 14633 rettv->vval.v_number = 0; 14634 return; 14635 } 14636 rettv->vval.v_list = l; 14637 rettv->v_type = VAR_LIST; 14638 ++l->lv_refcount; 14639 14640 get_tagfname(TRUE, NULL); 14641 for (;;) 14642 if (get_tagfname(FALSE, fname) == FAIL 14643 || list_append_string(l, fname, -1) == FAIL) 14644 break; 14645 } 14646 14647 /* 14648 * "taglist()" function 14649 */ 14650 static void 14651 f_taglist(argvars, rettv) 14652 typval_T *argvars; 14653 typval_T *rettv; 14654 { 14655 char_u *tag_pattern; 14656 list_T *l; 14657 14658 tag_pattern = get_tv_string(&argvars[0]); 14659 14660 rettv->vval.v_number = FALSE; 14661 if (*tag_pattern == NUL) 14662 return; 14663 14664 l = list_alloc(); 14665 if (l != NULL) 14666 { 14667 if (get_tags(l, tag_pattern) != FAIL) 14668 { 14669 rettv->vval.v_list = l; 14670 rettv->v_type = VAR_LIST; 14671 ++l->lv_refcount; 14672 } 14673 else 14674 list_free(l); 14675 } 14676 } 14677 14678 /* 14679 * "tempname()" function 14680 */ 14681 /*ARGSUSED*/ 14682 static void 14683 f_tempname(argvars, rettv) 14684 typval_T *argvars; 14685 typval_T *rettv; 14686 { 14687 static int x = 'A'; 14688 14689 rettv->v_type = VAR_STRING; 14690 rettv->vval.v_string = vim_tempname(x); 14691 14692 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14693 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14694 do 14695 { 14696 if (x == 'Z') 14697 x = '0'; 14698 else if (x == '9') 14699 x = 'A'; 14700 else 14701 { 14702 #ifdef EBCDIC 14703 if (x == 'I') 14704 x = 'J'; 14705 else if (x == 'R') 14706 x = 'S'; 14707 else 14708 #endif 14709 ++x; 14710 } 14711 } while (x == 'I' || x == 'O'); 14712 } 14713 14714 /* 14715 * "test(list)" function: Just checking the walls... 14716 */ 14717 /*ARGSUSED*/ 14718 static void 14719 f_test(argvars, rettv) 14720 typval_T *argvars; 14721 typval_T *rettv; 14722 { 14723 /* Used for unit testing. Change the code below to your liking. */ 14724 #if 0 14725 listitem_T *li; 14726 list_T *l; 14727 char_u *bad, *good; 14728 14729 if (argvars[0].v_type != VAR_LIST) 14730 return; 14731 l = argvars[0].vval.v_list; 14732 if (l == NULL) 14733 return; 14734 li = l->lv_first; 14735 if (li == NULL) 14736 return; 14737 bad = get_tv_string(&li->li_tv); 14738 li = li->li_next; 14739 if (li == NULL) 14740 return; 14741 good = get_tv_string(&li->li_tv); 14742 rettv->vval.v_number = test_edit_score(bad, good); 14743 #endif 14744 } 14745 14746 /* 14747 * "tolower(string)" function 14748 */ 14749 static void 14750 f_tolower(argvars, rettv) 14751 typval_T *argvars; 14752 typval_T *rettv; 14753 { 14754 char_u *p; 14755 14756 p = vim_strsave(get_tv_string(&argvars[0])); 14757 rettv->v_type = VAR_STRING; 14758 rettv->vval.v_string = p; 14759 14760 if (p != NULL) 14761 while (*p != NUL) 14762 { 14763 #ifdef FEAT_MBYTE 14764 int l; 14765 14766 if (enc_utf8) 14767 { 14768 int c, lc; 14769 14770 c = utf_ptr2char(p); 14771 lc = utf_tolower(c); 14772 l = utf_ptr2len(p); 14773 /* TODO: reallocate string when byte count changes. */ 14774 if (utf_char2len(lc) == l) 14775 utf_char2bytes(lc, p); 14776 p += l; 14777 } 14778 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14779 p += l; /* skip multi-byte character */ 14780 else 14781 #endif 14782 { 14783 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14784 ++p; 14785 } 14786 } 14787 } 14788 14789 /* 14790 * "toupper(string)" function 14791 */ 14792 static void 14793 f_toupper(argvars, rettv) 14794 typval_T *argvars; 14795 typval_T *rettv; 14796 { 14797 rettv->v_type = VAR_STRING; 14798 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14799 } 14800 14801 /* 14802 * "tr(string, fromstr, tostr)" function 14803 */ 14804 static void 14805 f_tr(argvars, rettv) 14806 typval_T *argvars; 14807 typval_T *rettv; 14808 { 14809 char_u *instr; 14810 char_u *fromstr; 14811 char_u *tostr; 14812 char_u *p; 14813 #ifdef FEAT_MBYTE 14814 int inlen; 14815 int fromlen; 14816 int tolen; 14817 int idx; 14818 char_u *cpstr; 14819 int cplen; 14820 int first = TRUE; 14821 #endif 14822 char_u buf[NUMBUFLEN]; 14823 char_u buf2[NUMBUFLEN]; 14824 garray_T ga; 14825 14826 instr = get_tv_string(&argvars[0]); 14827 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14828 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14829 14830 /* Default return value: empty string. */ 14831 rettv->v_type = VAR_STRING; 14832 rettv->vval.v_string = NULL; 14833 if (fromstr == NULL || tostr == NULL) 14834 return; /* type error; errmsg already given */ 14835 ga_init2(&ga, (int)sizeof(char), 80); 14836 14837 #ifdef FEAT_MBYTE 14838 if (!has_mbyte) 14839 #endif 14840 /* not multi-byte: fromstr and tostr must be the same length */ 14841 if (STRLEN(fromstr) != STRLEN(tostr)) 14842 { 14843 #ifdef FEAT_MBYTE 14844 error: 14845 #endif 14846 EMSG2(_(e_invarg2), fromstr); 14847 ga_clear(&ga); 14848 return; 14849 } 14850 14851 /* fromstr and tostr have to contain the same number of chars */ 14852 while (*instr != NUL) 14853 { 14854 #ifdef FEAT_MBYTE 14855 if (has_mbyte) 14856 { 14857 inlen = (*mb_ptr2len)(instr); 14858 cpstr = instr; 14859 cplen = inlen; 14860 idx = 0; 14861 for (p = fromstr; *p != NUL; p += fromlen) 14862 { 14863 fromlen = (*mb_ptr2len)(p); 14864 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14865 { 14866 for (p = tostr; *p != NUL; p += tolen) 14867 { 14868 tolen = (*mb_ptr2len)(p); 14869 if (idx-- == 0) 14870 { 14871 cplen = tolen; 14872 cpstr = p; 14873 break; 14874 } 14875 } 14876 if (*p == NUL) /* tostr is shorter than fromstr */ 14877 goto error; 14878 break; 14879 } 14880 ++idx; 14881 } 14882 14883 if (first && cpstr == instr) 14884 { 14885 /* Check that fromstr and tostr have the same number of 14886 * (multi-byte) characters. Done only once when a character 14887 * of instr doesn't appear in fromstr. */ 14888 first = FALSE; 14889 for (p = tostr; *p != NUL; p += tolen) 14890 { 14891 tolen = (*mb_ptr2len)(p); 14892 --idx; 14893 } 14894 if (idx != 0) 14895 goto error; 14896 } 14897 14898 ga_grow(&ga, cplen); 14899 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14900 ga.ga_len += cplen; 14901 14902 instr += inlen; 14903 } 14904 else 14905 #endif 14906 { 14907 /* When not using multi-byte chars we can do it faster. */ 14908 p = vim_strchr(fromstr, *instr); 14909 if (p != NULL) 14910 ga_append(&ga, tostr[p - fromstr]); 14911 else 14912 ga_append(&ga, *instr); 14913 ++instr; 14914 } 14915 } 14916 14917 rettv->vval.v_string = ga.ga_data; 14918 } 14919 14920 /* 14921 * "type(expr)" function 14922 */ 14923 static void 14924 f_type(argvars, rettv) 14925 typval_T *argvars; 14926 typval_T *rettv; 14927 { 14928 int n; 14929 14930 switch (argvars[0].v_type) 14931 { 14932 case VAR_NUMBER: n = 0; break; 14933 case VAR_STRING: n = 1; break; 14934 case VAR_FUNC: n = 2; break; 14935 case VAR_LIST: n = 3; break; 14936 case VAR_DICT: n = 4; break; 14937 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14938 } 14939 rettv->vval.v_number = n; 14940 } 14941 14942 /* 14943 * "values(dict)" function 14944 */ 14945 static void 14946 f_values(argvars, rettv) 14947 typval_T *argvars; 14948 typval_T *rettv; 14949 { 14950 dict_list(argvars, rettv, 1); 14951 } 14952 14953 /* 14954 * "virtcol(string)" function 14955 */ 14956 static void 14957 f_virtcol(argvars, rettv) 14958 typval_T *argvars; 14959 typval_T *rettv; 14960 { 14961 colnr_T vcol = 0; 14962 pos_T *fp; 14963 14964 fp = var2fpos(&argvars[0], FALSE); 14965 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14966 { 14967 getvvcol(curwin, fp, NULL, NULL, &vcol); 14968 ++vcol; 14969 } 14970 14971 rettv->vval.v_number = vcol; 14972 } 14973 14974 /* 14975 * "visualmode()" function 14976 */ 14977 /*ARGSUSED*/ 14978 static void 14979 f_visualmode(argvars, rettv) 14980 typval_T *argvars; 14981 typval_T *rettv; 14982 { 14983 #ifdef FEAT_VISUAL 14984 char_u str[2]; 14985 14986 rettv->v_type = VAR_STRING; 14987 str[0] = curbuf->b_visual_mode_eval; 14988 str[1] = NUL; 14989 rettv->vval.v_string = vim_strsave(str); 14990 14991 /* A non-zero number or non-empty string argument: reset mode. */ 14992 if ((argvars[0].v_type == VAR_NUMBER 14993 && argvars[0].vval.v_number != 0) 14994 || (argvars[0].v_type == VAR_STRING 14995 && *get_tv_string(&argvars[0]) != NUL)) 14996 curbuf->b_visual_mode_eval = NUL; 14997 #else 14998 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14999 #endif 15000 } 15001 15002 /* 15003 * "winbufnr(nr)" function 15004 */ 15005 static void 15006 f_winbufnr(argvars, rettv) 15007 typval_T *argvars; 15008 typval_T *rettv; 15009 { 15010 win_T *wp; 15011 15012 wp = find_win_by_nr(&argvars[0]); 15013 if (wp == NULL) 15014 rettv->vval.v_number = -1; 15015 else 15016 rettv->vval.v_number = wp->w_buffer->b_fnum; 15017 } 15018 15019 /* 15020 * "wincol()" function 15021 */ 15022 /*ARGSUSED*/ 15023 static void 15024 f_wincol(argvars, rettv) 15025 typval_T *argvars; 15026 typval_T *rettv; 15027 { 15028 validate_cursor(); 15029 rettv->vval.v_number = curwin->w_wcol + 1; 15030 } 15031 15032 /* 15033 * "winheight(nr)" function 15034 */ 15035 static void 15036 f_winheight(argvars, rettv) 15037 typval_T *argvars; 15038 typval_T *rettv; 15039 { 15040 win_T *wp; 15041 15042 wp = find_win_by_nr(&argvars[0]); 15043 if (wp == NULL) 15044 rettv->vval.v_number = -1; 15045 else 15046 rettv->vval.v_number = wp->w_height; 15047 } 15048 15049 /* 15050 * "winline()" function 15051 */ 15052 /*ARGSUSED*/ 15053 static void 15054 f_winline(argvars, rettv) 15055 typval_T *argvars; 15056 typval_T *rettv; 15057 { 15058 validate_cursor(); 15059 rettv->vval.v_number = curwin->w_wrow + 1; 15060 } 15061 15062 /* 15063 * "winnr()" function 15064 */ 15065 /* ARGSUSED */ 15066 static void 15067 f_winnr(argvars, rettv) 15068 typval_T *argvars; 15069 typval_T *rettv; 15070 { 15071 int nr = 1; 15072 #ifdef FEAT_WINDOWS 15073 win_T *wp; 15074 win_T *twin = curwin; 15075 char_u *arg; 15076 15077 if (argvars[0].v_type != VAR_UNKNOWN) 15078 { 15079 arg = get_tv_string_chk(&argvars[0]); 15080 if (arg == NULL) 15081 nr = 0; /* type error; errmsg already given */ 15082 else if (STRCMP(arg, "$") == 0) 15083 twin = lastwin; 15084 else if (STRCMP(arg, "#") == 0) 15085 { 15086 twin = prevwin; 15087 if (prevwin == NULL) 15088 nr = 0; 15089 } 15090 else 15091 { 15092 EMSG2(_(e_invexpr2), arg); 15093 nr = 0; 15094 } 15095 } 15096 15097 if (nr > 0) 15098 for (wp = firstwin; wp != twin; wp = wp->w_next) 15099 ++nr; 15100 #endif 15101 rettv->vval.v_number = nr; 15102 } 15103 15104 /* 15105 * "winrestcmd()" function 15106 */ 15107 /* ARGSUSED */ 15108 static void 15109 f_winrestcmd(argvars, rettv) 15110 typval_T *argvars; 15111 typval_T *rettv; 15112 { 15113 #ifdef FEAT_WINDOWS 15114 win_T *wp; 15115 int winnr = 1; 15116 garray_T ga; 15117 char_u buf[50]; 15118 15119 ga_init2(&ga, (int)sizeof(char), 70); 15120 for (wp = firstwin; wp != NULL; wp = wp->w_next) 15121 { 15122 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 15123 ga_concat(&ga, buf); 15124 # ifdef FEAT_VERTSPLIT 15125 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 15126 ga_concat(&ga, buf); 15127 # endif 15128 ++winnr; 15129 } 15130 ga_append(&ga, NUL); 15131 15132 rettv->vval.v_string = ga.ga_data; 15133 #else 15134 rettv->vval.v_string = NULL; 15135 #endif 15136 rettv->v_type = VAR_STRING; 15137 } 15138 15139 /* 15140 * "winwidth(nr)" function 15141 */ 15142 static void 15143 f_winwidth(argvars, rettv) 15144 typval_T *argvars; 15145 typval_T *rettv; 15146 { 15147 win_T *wp; 15148 15149 wp = find_win_by_nr(&argvars[0]); 15150 if (wp == NULL) 15151 rettv->vval.v_number = -1; 15152 else 15153 #ifdef FEAT_VERTSPLIT 15154 rettv->vval.v_number = wp->w_width; 15155 #else 15156 rettv->vval.v_number = Columns; 15157 #endif 15158 } 15159 15160 /* 15161 * "writefile()" function 15162 */ 15163 static void 15164 f_writefile(argvars, rettv) 15165 typval_T *argvars; 15166 typval_T *rettv; 15167 { 15168 int binary = FALSE; 15169 char_u *fname; 15170 FILE *fd; 15171 listitem_T *li; 15172 char_u *s; 15173 int ret = 0; 15174 int c; 15175 15176 if (argvars[0].v_type != VAR_LIST) 15177 { 15178 EMSG2(_(e_listarg), "writefile()"); 15179 return; 15180 } 15181 if (argvars[0].vval.v_list == NULL) 15182 return; 15183 15184 if (argvars[2].v_type != VAR_UNKNOWN 15185 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 15186 binary = TRUE; 15187 15188 /* Always open the file in binary mode, library functions have a mind of 15189 * their own about CR-LF conversion. */ 15190 fname = get_tv_string(&argvars[1]); 15191 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 15192 { 15193 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 15194 ret = -1; 15195 } 15196 else 15197 { 15198 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 15199 li = li->li_next) 15200 { 15201 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 15202 { 15203 if (*s == '\n') 15204 c = putc(NUL, fd); 15205 else 15206 c = putc(*s, fd); 15207 if (c == EOF) 15208 { 15209 ret = -1; 15210 break; 15211 } 15212 } 15213 if (!binary || li->li_next != NULL) 15214 if (putc('\n', fd) == EOF) 15215 { 15216 ret = -1; 15217 break; 15218 } 15219 if (ret < 0) 15220 { 15221 EMSG(_(e_write)); 15222 break; 15223 } 15224 } 15225 fclose(fd); 15226 } 15227 15228 rettv->vval.v_number = ret; 15229 } 15230 15231 /* 15232 * Translate a String variable into a position. 15233 */ 15234 static pos_T * 15235 var2fpos(varp, lnum) 15236 typval_T *varp; 15237 int lnum; /* TRUE when $ is last line */ 15238 { 15239 char_u *name; 15240 static pos_T pos; 15241 pos_T *pp; 15242 15243 name = get_tv_string_chk(varp); 15244 if (name == NULL) 15245 return NULL; 15246 if (name[0] == '.') /* cursor */ 15247 return &curwin->w_cursor; 15248 if (name[0] == '\'') /* mark */ 15249 { 15250 pp = getmark(name[1], FALSE); 15251 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15252 return NULL; 15253 return pp; 15254 } 15255 if (name[0] == '$') /* last column or line */ 15256 { 15257 if (lnum) 15258 { 15259 pos.lnum = curbuf->b_ml.ml_line_count; 15260 pos.col = 0; 15261 } 15262 else 15263 { 15264 pos.lnum = curwin->w_cursor.lnum; 15265 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15266 } 15267 return &pos; 15268 } 15269 return NULL; 15270 } 15271 15272 /* 15273 * Get the length of an environment variable name. 15274 * Advance "arg" to the first character after the name. 15275 * Return 0 for error. 15276 */ 15277 static int 15278 get_env_len(arg) 15279 char_u **arg; 15280 { 15281 char_u *p; 15282 int len; 15283 15284 for (p = *arg; vim_isIDc(*p); ++p) 15285 ; 15286 if (p == *arg) /* no name found */ 15287 return 0; 15288 15289 len = (int)(p - *arg); 15290 *arg = p; 15291 return len; 15292 } 15293 15294 /* 15295 * Get the length of the name of a function or internal variable. 15296 * "arg" is advanced to the first non-white character after the name. 15297 * Return 0 if something is wrong. 15298 */ 15299 static int 15300 get_id_len(arg) 15301 char_u **arg; 15302 { 15303 char_u *p; 15304 int len; 15305 15306 /* Find the end of the name. */ 15307 for (p = *arg; eval_isnamec(*p); ++p) 15308 ; 15309 if (p == *arg) /* no name found */ 15310 return 0; 15311 15312 len = (int)(p - *arg); 15313 *arg = skipwhite(p); 15314 15315 return len; 15316 } 15317 15318 /* 15319 * Get the length of the name of a variable or function. 15320 * Only the name is recognized, does not handle ".key" or "[idx]". 15321 * "arg" is advanced to the first non-white character after the name. 15322 * Return -1 if curly braces expansion failed. 15323 * Return 0 if something else is wrong. 15324 * If the name contains 'magic' {}'s, expand them and return the 15325 * expanded name in an allocated string via 'alias' - caller must free. 15326 */ 15327 static int 15328 get_name_len(arg, alias, evaluate, verbose) 15329 char_u **arg; 15330 char_u **alias; 15331 int evaluate; 15332 int verbose; 15333 { 15334 int len; 15335 char_u *p; 15336 char_u *expr_start; 15337 char_u *expr_end; 15338 15339 *alias = NULL; /* default to no alias */ 15340 15341 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15342 && (*arg)[2] == (int)KE_SNR) 15343 { 15344 /* hard coded <SNR>, already translated */ 15345 *arg += 3; 15346 return get_id_len(arg) + 3; 15347 } 15348 len = eval_fname_script(*arg); 15349 if (len > 0) 15350 { 15351 /* literal "<SID>", "s:" or "<SNR>" */ 15352 *arg += len; 15353 } 15354 15355 /* 15356 * Find the end of the name; check for {} construction. 15357 */ 15358 p = find_name_end(*arg, &expr_start, &expr_end, 15359 len > 0 ? 0 : FNE_CHECK_START); 15360 if (expr_start != NULL) 15361 { 15362 char_u *temp_string; 15363 15364 if (!evaluate) 15365 { 15366 len += (int)(p - *arg); 15367 *arg = skipwhite(p); 15368 return len; 15369 } 15370 15371 /* 15372 * Include any <SID> etc in the expanded string: 15373 * Thus the -len here. 15374 */ 15375 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15376 if (temp_string == NULL) 15377 return -1; 15378 *alias = temp_string; 15379 *arg = skipwhite(p); 15380 return (int)STRLEN(temp_string); 15381 } 15382 15383 len += get_id_len(arg); 15384 if (len == 0 && verbose) 15385 EMSG2(_(e_invexpr2), *arg); 15386 15387 return len; 15388 } 15389 15390 /* 15391 * Find the end of a variable or function name, taking care of magic braces. 15392 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15393 * start and end of the first magic braces item. 15394 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15395 * Return a pointer to just after the name. Equal to "arg" if there is no 15396 * valid name. 15397 */ 15398 static char_u * 15399 find_name_end(arg, expr_start, expr_end, flags) 15400 char_u *arg; 15401 char_u **expr_start; 15402 char_u **expr_end; 15403 int flags; 15404 { 15405 int mb_nest = 0; 15406 int br_nest = 0; 15407 char_u *p; 15408 15409 if (expr_start != NULL) 15410 { 15411 *expr_start = NULL; 15412 *expr_end = NULL; 15413 } 15414 15415 /* Quick check for valid starting character. */ 15416 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15417 return arg; 15418 15419 for (p = arg; *p != NUL 15420 && (eval_isnamec(*p) 15421 || *p == '{' 15422 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15423 || mb_nest != 0 15424 || br_nest != 0); mb_ptr_adv(p)) 15425 { 15426 if (*p == '\'') 15427 { 15428 /* skip over 'string' to avoid counting [ and ] inside it. */ 15429 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15430 ; 15431 if (*p == NUL) 15432 break; 15433 } 15434 else if (*p == '"') 15435 { 15436 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15437 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15438 if (*p == '\\' && p[1] != NUL) 15439 ++p; 15440 if (*p == NUL) 15441 break; 15442 } 15443 15444 if (mb_nest == 0) 15445 { 15446 if (*p == '[') 15447 ++br_nest; 15448 else if (*p == ']') 15449 --br_nest; 15450 } 15451 15452 if (br_nest == 0) 15453 { 15454 if (*p == '{') 15455 { 15456 mb_nest++; 15457 if (expr_start != NULL && *expr_start == NULL) 15458 *expr_start = p; 15459 } 15460 else if (*p == '}') 15461 { 15462 mb_nest--; 15463 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15464 *expr_end = p; 15465 } 15466 } 15467 } 15468 15469 return p; 15470 } 15471 15472 /* 15473 * Expands out the 'magic' {}'s in a variable/function name. 15474 * Note that this can call itself recursively, to deal with 15475 * constructs like foo{bar}{baz}{bam} 15476 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15477 * "in_start" ^ 15478 * "expr_start" ^ 15479 * "expr_end" ^ 15480 * "in_end" ^ 15481 * 15482 * Returns a new allocated string, which the caller must free. 15483 * Returns NULL for failure. 15484 */ 15485 static char_u * 15486 make_expanded_name(in_start, expr_start, expr_end, in_end) 15487 char_u *in_start; 15488 char_u *expr_start; 15489 char_u *expr_end; 15490 char_u *in_end; 15491 { 15492 char_u c1; 15493 char_u *retval = NULL; 15494 char_u *temp_result; 15495 char_u *nextcmd = NULL; 15496 15497 if (expr_end == NULL || in_end == NULL) 15498 return NULL; 15499 *expr_start = NUL; 15500 *expr_end = NUL; 15501 c1 = *in_end; 15502 *in_end = NUL; 15503 15504 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15505 if (temp_result != NULL && nextcmd == NULL) 15506 { 15507 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15508 + (in_end - expr_end) + 1)); 15509 if (retval != NULL) 15510 { 15511 STRCPY(retval, in_start); 15512 STRCAT(retval, temp_result); 15513 STRCAT(retval, expr_end + 1); 15514 } 15515 } 15516 vim_free(temp_result); 15517 15518 *in_end = c1; /* put char back for error messages */ 15519 *expr_start = '{'; 15520 *expr_end = '}'; 15521 15522 if (retval != NULL) 15523 { 15524 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15525 if (expr_start != NULL) 15526 { 15527 /* Further expansion! */ 15528 temp_result = make_expanded_name(retval, expr_start, 15529 expr_end, temp_result); 15530 vim_free(retval); 15531 retval = temp_result; 15532 } 15533 } 15534 15535 return retval; 15536 } 15537 15538 /* 15539 * Return TRUE if character "c" can be used in a variable or function name. 15540 * Does not include '{' or '}' for magic braces. 15541 */ 15542 static int 15543 eval_isnamec(c) 15544 int c; 15545 { 15546 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15547 } 15548 15549 /* 15550 * Return TRUE if character "c" can be used as the first character in a 15551 * variable or function name (excluding '{' and '}'). 15552 */ 15553 static int 15554 eval_isnamec1(c) 15555 int c; 15556 { 15557 return (ASCII_ISALPHA(c) || c == '_'); 15558 } 15559 15560 /* 15561 * Set number v: variable to "val". 15562 */ 15563 void 15564 set_vim_var_nr(idx, val) 15565 int idx; 15566 long val; 15567 { 15568 vimvars[idx].vv_nr = val; 15569 } 15570 15571 /* 15572 * Get number v: variable value. 15573 */ 15574 long 15575 get_vim_var_nr(idx) 15576 int idx; 15577 { 15578 return vimvars[idx].vv_nr; 15579 } 15580 15581 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15582 /* 15583 * Get string v: variable value. Uses a static buffer, can only be used once. 15584 */ 15585 char_u * 15586 get_vim_var_str(idx) 15587 int idx; 15588 { 15589 return get_tv_string(&vimvars[idx].vv_tv); 15590 } 15591 #endif 15592 15593 /* 15594 * Set v:count, v:count1 and v:prevcount. 15595 */ 15596 void 15597 set_vcount(count, count1) 15598 long count; 15599 long count1; 15600 { 15601 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15602 vimvars[VV_COUNT].vv_nr = count; 15603 vimvars[VV_COUNT1].vv_nr = count1; 15604 } 15605 15606 /* 15607 * Set string v: variable to a copy of "val". 15608 */ 15609 void 15610 set_vim_var_string(idx, val, len) 15611 int idx; 15612 char_u *val; 15613 int len; /* length of "val" to use or -1 (whole string) */ 15614 { 15615 /* Need to do this (at least) once, since we can't initialize a union. 15616 * Will always be invoked when "v:progname" is set. */ 15617 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15618 15619 vim_free(vimvars[idx].vv_str); 15620 if (val == NULL) 15621 vimvars[idx].vv_str = NULL; 15622 else if (len == -1) 15623 vimvars[idx].vv_str = vim_strsave(val); 15624 else 15625 vimvars[idx].vv_str = vim_strnsave(val, len); 15626 } 15627 15628 /* 15629 * Set v:register if needed. 15630 */ 15631 void 15632 set_reg_var(c) 15633 int c; 15634 { 15635 char_u regname; 15636 15637 if (c == 0 || c == ' ') 15638 regname = '"'; 15639 else 15640 regname = c; 15641 /* Avoid free/alloc when the value is already right. */ 15642 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15643 set_vim_var_string(VV_REG, ®name, 1); 15644 } 15645 15646 /* 15647 * Get or set v:exception. If "oldval" == NULL, return the current value. 15648 * Otherwise, restore the value to "oldval" and return NULL. 15649 * Must always be called in pairs to save and restore v:exception! Does not 15650 * take care of memory allocations. 15651 */ 15652 char_u * 15653 v_exception(oldval) 15654 char_u *oldval; 15655 { 15656 if (oldval == NULL) 15657 return vimvars[VV_EXCEPTION].vv_str; 15658 15659 vimvars[VV_EXCEPTION].vv_str = oldval; 15660 return NULL; 15661 } 15662 15663 /* 15664 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15665 * Otherwise, restore the value to "oldval" and return NULL. 15666 * Must always be called in pairs to save and restore v:throwpoint! Does not 15667 * take care of memory allocations. 15668 */ 15669 char_u * 15670 v_throwpoint(oldval) 15671 char_u *oldval; 15672 { 15673 if (oldval == NULL) 15674 return vimvars[VV_THROWPOINT].vv_str; 15675 15676 vimvars[VV_THROWPOINT].vv_str = oldval; 15677 return NULL; 15678 } 15679 15680 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15681 /* 15682 * Set v:cmdarg. 15683 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15684 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15685 * Must always be called in pairs! 15686 */ 15687 char_u * 15688 set_cmdarg(eap, oldarg) 15689 exarg_T *eap; 15690 char_u *oldarg; 15691 { 15692 char_u *oldval; 15693 char_u *newval; 15694 unsigned len; 15695 15696 oldval = vimvars[VV_CMDARG].vv_str; 15697 if (eap == NULL) 15698 { 15699 vim_free(oldval); 15700 vimvars[VV_CMDARG].vv_str = oldarg; 15701 return NULL; 15702 } 15703 15704 if (eap->force_bin == FORCE_BIN) 15705 len = 6; 15706 else if (eap->force_bin == FORCE_NOBIN) 15707 len = 8; 15708 else 15709 len = 0; 15710 if (eap->force_ff != 0) 15711 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15712 # ifdef FEAT_MBYTE 15713 if (eap->force_enc != 0) 15714 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15715 # endif 15716 15717 newval = alloc(len + 1); 15718 if (newval == NULL) 15719 return NULL; 15720 15721 if (eap->force_bin == FORCE_BIN) 15722 sprintf((char *)newval, " ++bin"); 15723 else if (eap->force_bin == FORCE_NOBIN) 15724 sprintf((char *)newval, " ++nobin"); 15725 else 15726 *newval = NUL; 15727 if (eap->force_ff != 0) 15728 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15729 eap->cmd + eap->force_ff); 15730 # ifdef FEAT_MBYTE 15731 if (eap->force_enc != 0) 15732 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15733 eap->cmd + eap->force_enc); 15734 # endif 15735 vimvars[VV_CMDARG].vv_str = newval; 15736 return oldval; 15737 } 15738 #endif 15739 15740 /* 15741 * Get the value of internal variable "name". 15742 * Return OK or FAIL. 15743 */ 15744 static int 15745 get_var_tv(name, len, rettv, verbose) 15746 char_u *name; 15747 int len; /* length of "name" */ 15748 typval_T *rettv; /* NULL when only checking existence */ 15749 int verbose; /* may give error message */ 15750 { 15751 int ret = OK; 15752 typval_T *tv = NULL; 15753 typval_T atv; 15754 dictitem_T *v; 15755 int cc; 15756 15757 /* truncate the name, so that we can use strcmp() */ 15758 cc = name[len]; 15759 name[len] = NUL; 15760 15761 /* 15762 * Check for "b:changedtick". 15763 */ 15764 if (STRCMP(name, "b:changedtick") == 0) 15765 { 15766 atv.v_type = VAR_NUMBER; 15767 atv.vval.v_number = curbuf->b_changedtick; 15768 tv = &atv; 15769 } 15770 15771 /* 15772 * Check for user-defined variables. 15773 */ 15774 else 15775 { 15776 v = find_var(name, NULL); 15777 if (v != NULL) 15778 tv = &v->di_tv; 15779 } 15780 15781 if (tv == NULL) 15782 { 15783 if (rettv != NULL && verbose) 15784 EMSG2(_(e_undefvar), name); 15785 ret = FAIL; 15786 } 15787 else if (rettv != NULL) 15788 copy_tv(tv, rettv); 15789 15790 name[len] = cc; 15791 15792 return ret; 15793 } 15794 15795 /* 15796 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15797 * Also handle function call with Funcref variable: func(expr) 15798 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15799 */ 15800 static int 15801 handle_subscript(arg, rettv, evaluate, verbose) 15802 char_u **arg; 15803 typval_T *rettv; 15804 int evaluate; /* do more than finding the end */ 15805 int verbose; /* give error messages */ 15806 { 15807 int ret = OK; 15808 dict_T *selfdict = NULL; 15809 char_u *s; 15810 int len; 15811 typval_T functv; 15812 15813 while (ret == OK 15814 && (**arg == '[' 15815 || (**arg == '.' && rettv->v_type == VAR_DICT) 15816 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15817 && !vim_iswhite(*(*arg - 1))) 15818 { 15819 if (**arg == '(') 15820 { 15821 /* need to copy the funcref so that we can clear rettv */ 15822 functv = *rettv; 15823 rettv->v_type = VAR_UNKNOWN; 15824 15825 /* Invoke the function. Recursive! */ 15826 s = functv.vval.v_string; 15827 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15828 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15829 &len, evaluate, selfdict); 15830 15831 /* Clear the funcref afterwards, so that deleting it while 15832 * evaluating the arguments is possible (see test55). */ 15833 clear_tv(&functv); 15834 15835 /* Stop the expression evaluation when immediately aborting on 15836 * error, or when an interrupt occurred or an exception was thrown 15837 * but not caught. */ 15838 if (aborting()) 15839 { 15840 if (ret == OK) 15841 clear_tv(rettv); 15842 ret = FAIL; 15843 } 15844 dict_unref(selfdict); 15845 selfdict = NULL; 15846 } 15847 else /* **arg == '[' || **arg == '.' */ 15848 { 15849 dict_unref(selfdict); 15850 if (rettv->v_type == VAR_DICT) 15851 { 15852 selfdict = rettv->vval.v_dict; 15853 if (selfdict != NULL) 15854 ++selfdict->dv_refcount; 15855 } 15856 else 15857 selfdict = NULL; 15858 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15859 { 15860 clear_tv(rettv); 15861 ret = FAIL; 15862 } 15863 } 15864 } 15865 dict_unref(selfdict); 15866 return ret; 15867 } 15868 15869 /* 15870 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15871 * value). 15872 */ 15873 static typval_T * 15874 alloc_tv() 15875 { 15876 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15877 } 15878 15879 /* 15880 * Allocate memory for a variable type-value, and assign a string to it. 15881 * The string "s" must have been allocated, it is consumed. 15882 * Return NULL for out of memory, the variable otherwise. 15883 */ 15884 static typval_T * 15885 alloc_string_tv(s) 15886 char_u *s; 15887 { 15888 typval_T *rettv; 15889 15890 rettv = alloc_tv(); 15891 if (rettv != NULL) 15892 { 15893 rettv->v_type = VAR_STRING; 15894 rettv->vval.v_string = s; 15895 } 15896 else 15897 vim_free(s); 15898 return rettv; 15899 } 15900 15901 /* 15902 * Free the memory for a variable type-value. 15903 */ 15904 static void 15905 free_tv(varp) 15906 typval_T *varp; 15907 { 15908 if (varp != NULL) 15909 { 15910 switch (varp->v_type) 15911 { 15912 case VAR_FUNC: 15913 func_unref(varp->vval.v_string); 15914 /*FALLTHROUGH*/ 15915 case VAR_STRING: 15916 vim_free(varp->vval.v_string); 15917 break; 15918 case VAR_LIST: 15919 list_unref(varp->vval.v_list); 15920 break; 15921 case VAR_DICT: 15922 dict_unref(varp->vval.v_dict); 15923 break; 15924 case VAR_NUMBER: 15925 case VAR_UNKNOWN: 15926 break; 15927 default: 15928 EMSG2(_(e_intern2), "free_tv()"); 15929 break; 15930 } 15931 vim_free(varp); 15932 } 15933 } 15934 15935 /* 15936 * Free the memory for a variable value and set the value to NULL or 0. 15937 */ 15938 void 15939 clear_tv(varp) 15940 typval_T *varp; 15941 { 15942 if (varp != NULL) 15943 { 15944 switch (varp->v_type) 15945 { 15946 case VAR_FUNC: 15947 func_unref(varp->vval.v_string); 15948 /*FALLTHROUGH*/ 15949 case VAR_STRING: 15950 vim_free(varp->vval.v_string); 15951 varp->vval.v_string = NULL; 15952 break; 15953 case VAR_LIST: 15954 list_unref(varp->vval.v_list); 15955 varp->vval.v_list = NULL; 15956 break; 15957 case VAR_DICT: 15958 dict_unref(varp->vval.v_dict); 15959 varp->vval.v_dict = NULL; 15960 break; 15961 case VAR_NUMBER: 15962 varp->vval.v_number = 0; 15963 break; 15964 case VAR_UNKNOWN: 15965 break; 15966 default: 15967 EMSG2(_(e_intern2), "clear_tv()"); 15968 } 15969 varp->v_lock = 0; 15970 } 15971 } 15972 15973 /* 15974 * Set the value of a variable to NULL without freeing items. 15975 */ 15976 static void 15977 init_tv(varp) 15978 typval_T *varp; 15979 { 15980 if (varp != NULL) 15981 vim_memset(varp, 0, sizeof(typval_T)); 15982 } 15983 15984 /* 15985 * Get the number value of a variable. 15986 * If it is a String variable, uses vim_str2nr(). 15987 * For incompatible types, return 0. 15988 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15989 * caller of incompatible types: it sets *denote to TRUE if "denote" 15990 * is not NULL or returns -1 otherwise. 15991 */ 15992 static long 15993 get_tv_number(varp) 15994 typval_T *varp; 15995 { 15996 int error = FALSE; 15997 15998 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15999 } 16000 16001 long 16002 get_tv_number_chk(varp, denote) 16003 typval_T *varp; 16004 int *denote; 16005 { 16006 long n = 0L; 16007 16008 switch (varp->v_type) 16009 { 16010 case VAR_NUMBER: 16011 return (long)(varp->vval.v_number); 16012 case VAR_FUNC: 16013 EMSG(_("E703: Using a Funcref as a number")); 16014 break; 16015 case VAR_STRING: 16016 if (varp->vval.v_string != NULL) 16017 vim_str2nr(varp->vval.v_string, NULL, NULL, 16018 TRUE, TRUE, &n, NULL); 16019 return n; 16020 case VAR_LIST: 16021 EMSG(_("E745: Using a List as a number")); 16022 break; 16023 case VAR_DICT: 16024 EMSG(_("E728: Using a Dictionary as a number")); 16025 break; 16026 default: 16027 EMSG2(_(e_intern2), "get_tv_number()"); 16028 break; 16029 } 16030 if (denote == NULL) /* useful for values that must be unsigned */ 16031 n = -1; 16032 else 16033 *denote = TRUE; 16034 return n; 16035 } 16036 16037 /* 16038 * Get the lnum from the first argument. 16039 * Also accepts ".", "$", etc., but that only works for the current buffer. 16040 * Returns -1 on error. 16041 */ 16042 static linenr_T 16043 get_tv_lnum(argvars) 16044 typval_T *argvars; 16045 { 16046 typval_T rettv; 16047 linenr_T lnum; 16048 16049 lnum = get_tv_number_chk(&argvars[0], NULL); 16050 if (lnum == 0) /* no valid number, try using line() */ 16051 { 16052 rettv.v_type = VAR_NUMBER; 16053 f_line(argvars, &rettv); 16054 lnum = rettv.vval.v_number; 16055 clear_tv(&rettv); 16056 } 16057 return lnum; 16058 } 16059 16060 /* 16061 * Get the lnum from the first argument. 16062 * Also accepts "$", then "buf" is used. 16063 * Returns 0 on error. 16064 */ 16065 static linenr_T 16066 get_tv_lnum_buf(argvars, buf) 16067 typval_T *argvars; 16068 buf_T *buf; 16069 { 16070 if (argvars[0].v_type == VAR_STRING 16071 && argvars[0].vval.v_string != NULL 16072 && argvars[0].vval.v_string[0] == '$' 16073 && buf != NULL) 16074 return buf->b_ml.ml_line_count; 16075 return get_tv_number_chk(&argvars[0], NULL); 16076 } 16077 16078 /* 16079 * Get the string value of a variable. 16080 * If it is a Number variable, the number is converted into a string. 16081 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 16082 * get_tv_string_buf() uses a given buffer. 16083 * If the String variable has never been set, return an empty string. 16084 * Never returns NULL; 16085 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 16086 * NULL on error. 16087 */ 16088 static char_u * 16089 get_tv_string(varp) 16090 typval_T *varp; 16091 { 16092 static char_u mybuf[NUMBUFLEN]; 16093 16094 return get_tv_string_buf(varp, mybuf); 16095 } 16096 16097 static char_u * 16098 get_tv_string_buf(varp, buf) 16099 typval_T *varp; 16100 char_u *buf; 16101 { 16102 char_u *res = get_tv_string_buf_chk(varp, buf); 16103 16104 return res != NULL ? res : (char_u *)""; 16105 } 16106 16107 char_u * 16108 get_tv_string_chk(varp) 16109 typval_T *varp; 16110 { 16111 static char_u mybuf[NUMBUFLEN]; 16112 16113 return get_tv_string_buf_chk(varp, mybuf); 16114 } 16115 16116 static char_u * 16117 get_tv_string_buf_chk(varp, buf) 16118 typval_T *varp; 16119 char_u *buf; 16120 { 16121 switch (varp->v_type) 16122 { 16123 case VAR_NUMBER: 16124 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 16125 return buf; 16126 case VAR_FUNC: 16127 EMSG(_("E729: using Funcref as a String")); 16128 break; 16129 case VAR_LIST: 16130 EMSG(_("E730: using List as a String")); 16131 break; 16132 case VAR_DICT: 16133 EMSG(_("E731: using Dictionary as a String")); 16134 break; 16135 case VAR_STRING: 16136 if (varp->vval.v_string != NULL) 16137 return varp->vval.v_string; 16138 return (char_u *)""; 16139 default: 16140 EMSG2(_(e_intern2), "get_tv_string_buf()"); 16141 break; 16142 } 16143 return NULL; 16144 } 16145 16146 /* 16147 * Find variable "name" in the list of variables. 16148 * Return a pointer to it if found, NULL if not found. 16149 * Careful: "a:0" variables don't have a name. 16150 * When "htp" is not NULL we are writing to the variable, set "htp" to the 16151 * hashtab_T used. 16152 */ 16153 static dictitem_T * 16154 find_var(name, htp) 16155 char_u *name; 16156 hashtab_T **htp; 16157 { 16158 char_u *varname; 16159 hashtab_T *ht; 16160 16161 ht = find_var_ht(name, &varname); 16162 if (htp != NULL) 16163 *htp = ht; 16164 if (ht == NULL) 16165 return NULL; 16166 return find_var_in_ht(ht, varname, htp != NULL); 16167 } 16168 16169 /* 16170 * Find variable "varname" in hashtab "ht". 16171 * Returns NULL if not found. 16172 */ 16173 static dictitem_T * 16174 find_var_in_ht(ht, varname, writing) 16175 hashtab_T *ht; 16176 char_u *varname; 16177 int writing; 16178 { 16179 hashitem_T *hi; 16180 16181 if (*varname == NUL) 16182 { 16183 /* Must be something like "s:", otherwise "ht" would be NULL. */ 16184 switch (varname[-2]) 16185 { 16186 case 's': return &SCRIPT_SV(current_SID).sv_var; 16187 case 'g': return &globvars_var; 16188 case 'v': return &vimvars_var; 16189 case 'b': return &curbuf->b_bufvar; 16190 case 'w': return &curwin->w_winvar; 16191 case 'l': return current_funccal == NULL 16192 ? NULL : ¤t_funccal->l_vars_var; 16193 case 'a': return current_funccal == NULL 16194 ? NULL : ¤t_funccal->l_avars_var; 16195 } 16196 return NULL; 16197 } 16198 16199 hi = hash_find(ht, varname); 16200 if (HASHITEM_EMPTY(hi)) 16201 { 16202 /* For global variables we may try auto-loading the script. If it 16203 * worked find the variable again. Don't auto-load a script if it was 16204 * loaded already, otherwise it would be loaded every time when 16205 * checking if a function name is a Funcref variable. */ 16206 if (ht == &globvarht && !writing 16207 && script_autoload(varname, FALSE) && !aborting()) 16208 hi = hash_find(ht, varname); 16209 if (HASHITEM_EMPTY(hi)) 16210 return NULL; 16211 } 16212 return HI2DI(hi); 16213 } 16214 16215 /* 16216 * Find the hashtab used for a variable name. 16217 * Set "varname" to the start of name without ':'. 16218 */ 16219 static hashtab_T * 16220 find_var_ht(name, varname) 16221 char_u *name; 16222 char_u **varname; 16223 { 16224 hashitem_T *hi; 16225 16226 if (name[1] != ':') 16227 { 16228 /* The name must not start with a colon or #. */ 16229 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16230 return NULL; 16231 *varname = name; 16232 16233 /* "version" is "v:version" in all scopes */ 16234 hi = hash_find(&compat_hashtab, name); 16235 if (!HASHITEM_EMPTY(hi)) 16236 return &compat_hashtab; 16237 16238 if (current_funccal == NULL) 16239 return &globvarht; /* global variable */ 16240 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16241 } 16242 *varname = name + 2; 16243 if (*name == 'g') /* global variable */ 16244 return &globvarht; 16245 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16246 */ 16247 if (vim_strchr(name + 2, ':') != NULL 16248 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16249 return NULL; 16250 if (*name == 'b') /* buffer variable */ 16251 return &curbuf->b_vars.dv_hashtab; 16252 if (*name == 'w') /* window variable */ 16253 return &curwin->w_vars.dv_hashtab; 16254 if (*name == 'v') /* v: variable */ 16255 return &vimvarht; 16256 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16257 return ¤t_funccal->l_avars.dv_hashtab; 16258 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16259 return ¤t_funccal->l_vars.dv_hashtab; 16260 if (*name == 's' /* script variable */ 16261 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16262 return &SCRIPT_VARS(current_SID); 16263 return NULL; 16264 } 16265 16266 /* 16267 * Get the string value of a (global/local) variable. 16268 * Returns NULL when it doesn't exist. 16269 */ 16270 char_u * 16271 get_var_value(name) 16272 char_u *name; 16273 { 16274 dictitem_T *v; 16275 16276 v = find_var(name, NULL); 16277 if (v == NULL) 16278 return NULL; 16279 return get_tv_string(&v->di_tv); 16280 } 16281 16282 /* 16283 * Allocate a new hashtab for a sourced script. It will be used while 16284 * sourcing this script and when executing functions defined in the script. 16285 */ 16286 void 16287 new_script_vars(id) 16288 scid_T id; 16289 { 16290 int i; 16291 hashtab_T *ht; 16292 scriptvar_T *sv; 16293 16294 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16295 { 16296 /* Re-allocating ga_data means that an ht_array pointing to 16297 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16298 * at its init value. Also reset "v_dict", it's always the same. */ 16299 for (i = 1; i <= ga_scripts.ga_len; ++i) 16300 { 16301 ht = &SCRIPT_VARS(i); 16302 if (ht->ht_mask == HT_INIT_SIZE - 1) 16303 ht->ht_array = ht->ht_smallarray; 16304 sv = &SCRIPT_SV(i); 16305 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16306 } 16307 16308 while (ga_scripts.ga_len < id) 16309 { 16310 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16311 init_var_dict(&sv->sv_dict, &sv->sv_var); 16312 ++ga_scripts.ga_len; 16313 } 16314 } 16315 } 16316 16317 /* 16318 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16319 * point to it. 16320 */ 16321 void 16322 init_var_dict(dict, dict_var) 16323 dict_T *dict; 16324 dictitem_T *dict_var; 16325 { 16326 hash_init(&dict->dv_hashtab); 16327 dict->dv_refcount = 99999; 16328 dict_var->di_tv.vval.v_dict = dict; 16329 dict_var->di_tv.v_type = VAR_DICT; 16330 dict_var->di_tv.v_lock = VAR_FIXED; 16331 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16332 dict_var->di_key[0] = NUL; 16333 } 16334 16335 /* 16336 * Clean up a list of internal variables. 16337 * Frees all allocated variables and the value they contain. 16338 * Clears hashtab "ht", does not free it. 16339 */ 16340 void 16341 vars_clear(ht) 16342 hashtab_T *ht; 16343 { 16344 vars_clear_ext(ht, TRUE); 16345 } 16346 16347 /* 16348 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16349 */ 16350 static void 16351 vars_clear_ext(ht, free_val) 16352 hashtab_T *ht; 16353 int free_val; 16354 { 16355 int todo; 16356 hashitem_T *hi; 16357 dictitem_T *v; 16358 16359 hash_lock(ht); 16360 todo = ht->ht_used; 16361 for (hi = ht->ht_array; todo > 0; ++hi) 16362 { 16363 if (!HASHITEM_EMPTY(hi)) 16364 { 16365 --todo; 16366 16367 /* Free the variable. Don't remove it from the hashtab, 16368 * ht_array might change then. hash_clear() takes care of it 16369 * later. */ 16370 v = HI2DI(hi); 16371 if (free_val) 16372 clear_tv(&v->di_tv); 16373 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16374 vim_free(v); 16375 } 16376 } 16377 hash_clear(ht); 16378 ht->ht_used = 0; 16379 } 16380 16381 /* 16382 * Delete a variable from hashtab "ht" at item "hi". 16383 * Clear the variable value and free the dictitem. 16384 */ 16385 static void 16386 delete_var(ht, hi) 16387 hashtab_T *ht; 16388 hashitem_T *hi; 16389 { 16390 dictitem_T *di = HI2DI(hi); 16391 16392 hash_remove(ht, hi); 16393 clear_tv(&di->di_tv); 16394 vim_free(di); 16395 } 16396 16397 /* 16398 * List the value of one internal variable. 16399 */ 16400 static void 16401 list_one_var(v, prefix) 16402 dictitem_T *v; 16403 char_u *prefix; 16404 { 16405 char_u *tofree; 16406 char_u *s; 16407 char_u numbuf[NUMBUFLEN]; 16408 16409 s = echo_string(&v->di_tv, &tofree, numbuf); 16410 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16411 s == NULL ? (char_u *)"" : s); 16412 vim_free(tofree); 16413 } 16414 16415 static void 16416 list_one_var_a(prefix, name, type, string) 16417 char_u *prefix; 16418 char_u *name; 16419 int type; 16420 char_u *string; 16421 { 16422 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16423 if (name != NULL) /* "a:" vars don't have a name stored */ 16424 msg_puts(name); 16425 msg_putchar(' '); 16426 msg_advance(22); 16427 if (type == VAR_NUMBER) 16428 msg_putchar('#'); 16429 else if (type == VAR_FUNC) 16430 msg_putchar('*'); 16431 else if (type == VAR_LIST) 16432 { 16433 msg_putchar('['); 16434 if (*string == '[') 16435 ++string; 16436 } 16437 else if (type == VAR_DICT) 16438 { 16439 msg_putchar('{'); 16440 if (*string == '{') 16441 ++string; 16442 } 16443 else 16444 msg_putchar(' '); 16445 16446 msg_outtrans(string); 16447 16448 if (type == VAR_FUNC) 16449 msg_puts((char_u *)"()"); 16450 } 16451 16452 /* 16453 * Set variable "name" to value in "tv". 16454 * If the variable already exists, the value is updated. 16455 * Otherwise the variable is created. 16456 */ 16457 static void 16458 set_var(name, tv, copy) 16459 char_u *name; 16460 typval_T *tv; 16461 int copy; /* make copy of value in "tv" */ 16462 { 16463 dictitem_T *v; 16464 char_u *varname; 16465 hashtab_T *ht; 16466 char_u *p; 16467 16468 if (tv->v_type == VAR_FUNC) 16469 { 16470 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16471 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16472 ? name[2] : name[0])) 16473 { 16474 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16475 return; 16476 } 16477 if (function_exists(name)) 16478 { 16479 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16480 name); 16481 return; 16482 } 16483 } 16484 16485 ht = find_var_ht(name, &varname); 16486 if (ht == NULL || *varname == NUL) 16487 { 16488 EMSG2(_(e_illvar), name); 16489 return; 16490 } 16491 16492 v = find_var_in_ht(ht, varname, TRUE); 16493 if (v != NULL) 16494 { 16495 /* existing variable, need to clear the value */ 16496 if (var_check_ro(v->di_flags, name) 16497 || tv_check_lock(v->di_tv.v_lock, name)) 16498 return; 16499 if (v->di_tv.v_type != tv->v_type 16500 && !((v->di_tv.v_type == VAR_STRING 16501 || v->di_tv.v_type == VAR_NUMBER) 16502 && (tv->v_type == VAR_STRING 16503 || tv->v_type == VAR_NUMBER))) 16504 { 16505 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16506 return; 16507 } 16508 16509 /* 16510 * Handle setting internal v: variables separately: we don't change 16511 * the type. 16512 */ 16513 if (ht == &vimvarht) 16514 { 16515 if (v->di_tv.v_type == VAR_STRING) 16516 { 16517 vim_free(v->di_tv.vval.v_string); 16518 if (copy || tv->v_type != VAR_STRING) 16519 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16520 else 16521 { 16522 /* Take over the string to avoid an extra alloc/free. */ 16523 v->di_tv.vval.v_string = tv->vval.v_string; 16524 tv->vval.v_string = NULL; 16525 } 16526 } 16527 else if (v->di_tv.v_type != VAR_NUMBER) 16528 EMSG2(_(e_intern2), "set_var()"); 16529 else 16530 v->di_tv.vval.v_number = get_tv_number(tv); 16531 return; 16532 } 16533 16534 clear_tv(&v->di_tv); 16535 } 16536 else /* add a new variable */ 16537 { 16538 /* Make sure the variable name is valid. */ 16539 for (p = varname; *p != NUL; ++p) 16540 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 16541 && *p != AUTOLOAD_CHAR) 16542 { 16543 EMSG2(_(e_illvar), varname); 16544 return; 16545 } 16546 16547 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16548 + STRLEN(varname))); 16549 if (v == NULL) 16550 return; 16551 STRCPY(v->di_key, varname); 16552 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16553 { 16554 vim_free(v); 16555 return; 16556 } 16557 v->di_flags = 0; 16558 } 16559 16560 if (copy || tv->v_type == VAR_NUMBER) 16561 copy_tv(tv, &v->di_tv); 16562 else 16563 { 16564 v->di_tv = *tv; 16565 v->di_tv.v_lock = 0; 16566 init_tv(tv); 16567 } 16568 } 16569 16570 /* 16571 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16572 * Also give an error message. 16573 */ 16574 static int 16575 var_check_ro(flags, name) 16576 int flags; 16577 char_u *name; 16578 { 16579 if (flags & DI_FLAGS_RO) 16580 { 16581 EMSG2(_(e_readonlyvar), name); 16582 return TRUE; 16583 } 16584 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16585 { 16586 EMSG2(_(e_readonlysbx), name); 16587 return TRUE; 16588 } 16589 return FALSE; 16590 } 16591 16592 /* 16593 * Return TRUE if typeval "tv" is set to be locked (immutable). 16594 * Also give an error message, using "name". 16595 */ 16596 static int 16597 tv_check_lock(lock, name) 16598 int lock; 16599 char_u *name; 16600 { 16601 if (lock & VAR_LOCKED) 16602 { 16603 EMSG2(_("E741: Value is locked: %s"), 16604 name == NULL ? (char_u *)_("Unknown") : name); 16605 return TRUE; 16606 } 16607 if (lock & VAR_FIXED) 16608 { 16609 EMSG2(_("E742: Cannot change value of %s"), 16610 name == NULL ? (char_u *)_("Unknown") : name); 16611 return TRUE; 16612 } 16613 return FALSE; 16614 } 16615 16616 /* 16617 * Copy the values from typval_T "from" to typval_T "to". 16618 * When needed allocates string or increases reference count. 16619 * Does not make a copy of a list or dict but copies the reference! 16620 */ 16621 static void 16622 copy_tv(from, to) 16623 typval_T *from; 16624 typval_T *to; 16625 { 16626 to->v_type = from->v_type; 16627 to->v_lock = 0; 16628 switch (from->v_type) 16629 { 16630 case VAR_NUMBER: 16631 to->vval.v_number = from->vval.v_number; 16632 break; 16633 case VAR_STRING: 16634 case VAR_FUNC: 16635 if (from->vval.v_string == NULL) 16636 to->vval.v_string = NULL; 16637 else 16638 { 16639 to->vval.v_string = vim_strsave(from->vval.v_string); 16640 if (from->v_type == VAR_FUNC) 16641 func_ref(to->vval.v_string); 16642 } 16643 break; 16644 case VAR_LIST: 16645 if (from->vval.v_list == NULL) 16646 to->vval.v_list = NULL; 16647 else 16648 { 16649 to->vval.v_list = from->vval.v_list; 16650 ++to->vval.v_list->lv_refcount; 16651 } 16652 break; 16653 case VAR_DICT: 16654 if (from->vval.v_dict == NULL) 16655 to->vval.v_dict = NULL; 16656 else 16657 { 16658 to->vval.v_dict = from->vval.v_dict; 16659 ++to->vval.v_dict->dv_refcount; 16660 } 16661 break; 16662 default: 16663 EMSG2(_(e_intern2), "copy_tv()"); 16664 break; 16665 } 16666 } 16667 16668 /* 16669 * Make a copy of an item. 16670 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16671 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16672 * reference to an already copied list/dict can be used. 16673 * Returns FAIL or OK. 16674 */ 16675 static int 16676 item_copy(from, to, deep, copyID) 16677 typval_T *from; 16678 typval_T *to; 16679 int deep; 16680 int copyID; 16681 { 16682 static int recurse = 0; 16683 int ret = OK; 16684 16685 if (recurse >= DICT_MAXNEST) 16686 { 16687 EMSG(_("E698: variable nested too deep for making a copy")); 16688 return FAIL; 16689 } 16690 ++recurse; 16691 16692 switch (from->v_type) 16693 { 16694 case VAR_NUMBER: 16695 case VAR_STRING: 16696 case VAR_FUNC: 16697 copy_tv(from, to); 16698 break; 16699 case VAR_LIST: 16700 to->v_type = VAR_LIST; 16701 to->v_lock = 0; 16702 if (from->vval.v_list == NULL) 16703 to->vval.v_list = NULL; 16704 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16705 { 16706 /* use the copy made earlier */ 16707 to->vval.v_list = from->vval.v_list->lv_copylist; 16708 ++to->vval.v_list->lv_refcount; 16709 } 16710 else 16711 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16712 if (to->vval.v_list == NULL) 16713 ret = FAIL; 16714 break; 16715 case VAR_DICT: 16716 to->v_type = VAR_DICT; 16717 to->v_lock = 0; 16718 if (from->vval.v_dict == NULL) 16719 to->vval.v_dict = NULL; 16720 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16721 { 16722 /* use the copy made earlier */ 16723 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16724 ++to->vval.v_dict->dv_refcount; 16725 } 16726 else 16727 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16728 if (to->vval.v_dict == NULL) 16729 ret = FAIL; 16730 break; 16731 default: 16732 EMSG2(_(e_intern2), "item_copy()"); 16733 ret = FAIL; 16734 } 16735 --recurse; 16736 return ret; 16737 } 16738 16739 /* 16740 * ":echo expr1 ..." print each argument separated with a space, add a 16741 * newline at the end. 16742 * ":echon expr1 ..." print each argument plain. 16743 */ 16744 void 16745 ex_echo(eap) 16746 exarg_T *eap; 16747 { 16748 char_u *arg = eap->arg; 16749 typval_T rettv; 16750 char_u *tofree; 16751 char_u *p; 16752 int needclr = TRUE; 16753 int atstart = TRUE; 16754 char_u numbuf[NUMBUFLEN]; 16755 16756 if (eap->skip) 16757 ++emsg_skip; 16758 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16759 { 16760 p = arg; 16761 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16762 { 16763 /* 16764 * Report the invalid expression unless the expression evaluation 16765 * has been cancelled due to an aborting error, an interrupt, or an 16766 * exception. 16767 */ 16768 if (!aborting()) 16769 EMSG2(_(e_invexpr2), p); 16770 break; 16771 } 16772 if (!eap->skip) 16773 { 16774 if (atstart) 16775 { 16776 atstart = FALSE; 16777 /* Call msg_start() after eval1(), evaluating the expression 16778 * may cause a message to appear. */ 16779 if (eap->cmdidx == CMD_echo) 16780 msg_start(); 16781 } 16782 else if (eap->cmdidx == CMD_echo) 16783 msg_puts_attr((char_u *)" ", echo_attr); 16784 p = echo_string(&rettv, &tofree, numbuf); 16785 if (p != NULL) 16786 for ( ; *p != NUL && !got_int; ++p) 16787 { 16788 if (*p == '\n' || *p == '\r' || *p == TAB) 16789 { 16790 if (*p != TAB && needclr) 16791 { 16792 /* remove any text still there from the command */ 16793 msg_clr_eos(); 16794 needclr = FALSE; 16795 } 16796 msg_putchar_attr(*p, echo_attr); 16797 } 16798 else 16799 { 16800 #ifdef FEAT_MBYTE 16801 if (has_mbyte) 16802 { 16803 int i = (*mb_ptr2len)(p); 16804 16805 (void)msg_outtrans_len_attr(p, i, echo_attr); 16806 p += i - 1; 16807 } 16808 else 16809 #endif 16810 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16811 } 16812 } 16813 vim_free(tofree); 16814 } 16815 clear_tv(&rettv); 16816 arg = skipwhite(arg); 16817 } 16818 eap->nextcmd = check_nextcmd(arg); 16819 16820 if (eap->skip) 16821 --emsg_skip; 16822 else 16823 { 16824 /* remove text that may still be there from the command */ 16825 if (needclr) 16826 msg_clr_eos(); 16827 if (eap->cmdidx == CMD_echo) 16828 msg_end(); 16829 } 16830 } 16831 16832 /* 16833 * ":echohl {name}". 16834 */ 16835 void 16836 ex_echohl(eap) 16837 exarg_T *eap; 16838 { 16839 int id; 16840 16841 id = syn_name2id(eap->arg); 16842 if (id == 0) 16843 echo_attr = 0; 16844 else 16845 echo_attr = syn_id2attr(id); 16846 } 16847 16848 /* 16849 * ":execute expr1 ..." execute the result of an expression. 16850 * ":echomsg expr1 ..." Print a message 16851 * ":echoerr expr1 ..." Print an error 16852 * Each gets spaces around each argument and a newline at the end for 16853 * echo commands 16854 */ 16855 void 16856 ex_execute(eap) 16857 exarg_T *eap; 16858 { 16859 char_u *arg = eap->arg; 16860 typval_T rettv; 16861 int ret = OK; 16862 char_u *p; 16863 garray_T ga; 16864 int len; 16865 int save_did_emsg; 16866 16867 ga_init2(&ga, 1, 80); 16868 16869 if (eap->skip) 16870 ++emsg_skip; 16871 while (*arg != NUL && *arg != '|' && *arg != '\n') 16872 { 16873 p = arg; 16874 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16875 { 16876 /* 16877 * Report the invalid expression unless the expression evaluation 16878 * has been cancelled due to an aborting error, an interrupt, or an 16879 * exception. 16880 */ 16881 if (!aborting()) 16882 EMSG2(_(e_invexpr2), p); 16883 ret = FAIL; 16884 break; 16885 } 16886 16887 if (!eap->skip) 16888 { 16889 p = get_tv_string(&rettv); 16890 len = (int)STRLEN(p); 16891 if (ga_grow(&ga, len + 2) == FAIL) 16892 { 16893 clear_tv(&rettv); 16894 ret = FAIL; 16895 break; 16896 } 16897 if (ga.ga_len) 16898 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16899 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16900 ga.ga_len += len; 16901 } 16902 16903 clear_tv(&rettv); 16904 arg = skipwhite(arg); 16905 } 16906 16907 if (ret != FAIL && ga.ga_data != NULL) 16908 { 16909 if (eap->cmdidx == CMD_echomsg) 16910 MSG_ATTR(ga.ga_data, echo_attr); 16911 else if (eap->cmdidx == CMD_echoerr) 16912 { 16913 /* We don't want to abort following commands, restore did_emsg. */ 16914 save_did_emsg = did_emsg; 16915 EMSG((char_u *)ga.ga_data); 16916 if (!force_abort) 16917 did_emsg = save_did_emsg; 16918 } 16919 else if (eap->cmdidx == CMD_execute) 16920 do_cmdline((char_u *)ga.ga_data, 16921 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16922 } 16923 16924 ga_clear(&ga); 16925 16926 if (eap->skip) 16927 --emsg_skip; 16928 16929 eap->nextcmd = check_nextcmd(arg); 16930 } 16931 16932 /* 16933 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16934 * "arg" points to the "&" or '+' when called, to "option" when returning. 16935 * Returns NULL when no option name found. Otherwise pointer to the char 16936 * after the option name. 16937 */ 16938 static char_u * 16939 find_option_end(arg, opt_flags) 16940 char_u **arg; 16941 int *opt_flags; 16942 { 16943 char_u *p = *arg; 16944 16945 ++p; 16946 if (*p == 'g' && p[1] == ':') 16947 { 16948 *opt_flags = OPT_GLOBAL; 16949 p += 2; 16950 } 16951 else if (*p == 'l' && p[1] == ':') 16952 { 16953 *opt_flags = OPT_LOCAL; 16954 p += 2; 16955 } 16956 else 16957 *opt_flags = 0; 16958 16959 if (!ASCII_ISALPHA(*p)) 16960 return NULL; 16961 *arg = p; 16962 16963 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16964 p += 4; /* termcap option */ 16965 else 16966 while (ASCII_ISALPHA(*p)) 16967 ++p; 16968 return p; 16969 } 16970 16971 /* 16972 * ":function" 16973 */ 16974 void 16975 ex_function(eap) 16976 exarg_T *eap; 16977 { 16978 char_u *theline; 16979 int j; 16980 int c; 16981 int saved_did_emsg; 16982 char_u *name = NULL; 16983 char_u *p; 16984 char_u *arg; 16985 garray_T newargs; 16986 garray_T newlines; 16987 int varargs = FALSE; 16988 int mustend = FALSE; 16989 int flags = 0; 16990 ufunc_T *fp; 16991 int indent; 16992 int nesting; 16993 char_u *skip_until = NULL; 16994 dictitem_T *v; 16995 funcdict_T fudi; 16996 static int func_nr = 0; /* number for nameless function */ 16997 int paren; 16998 hashtab_T *ht; 16999 int todo; 17000 hashitem_T *hi; 17001 17002 /* 17003 * ":function" without argument: list functions. 17004 */ 17005 if (ends_excmd(*eap->arg)) 17006 { 17007 if (!eap->skip) 17008 { 17009 todo = func_hashtab.ht_used; 17010 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17011 { 17012 if (!HASHITEM_EMPTY(hi)) 17013 { 17014 --todo; 17015 fp = HI2UF(hi); 17016 if (!isdigit(*fp->uf_name)) 17017 list_func_head(fp, FALSE); 17018 } 17019 } 17020 } 17021 eap->nextcmd = check_nextcmd(eap->arg); 17022 return; 17023 } 17024 17025 /* 17026 * ":function /pat": list functions matching pattern. 17027 */ 17028 if (*eap->arg == '/') 17029 { 17030 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 17031 if (!eap->skip) 17032 { 17033 regmatch_T regmatch; 17034 17035 c = *p; 17036 *p = NUL; 17037 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 17038 *p = c; 17039 if (regmatch.regprog != NULL) 17040 { 17041 regmatch.rm_ic = p_ic; 17042 17043 todo = func_hashtab.ht_used; 17044 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17045 { 17046 if (!HASHITEM_EMPTY(hi)) 17047 { 17048 --todo; 17049 fp = HI2UF(hi); 17050 if (!isdigit(*fp->uf_name) 17051 && vim_regexec(®match, fp->uf_name, 0)) 17052 list_func_head(fp, FALSE); 17053 } 17054 } 17055 } 17056 } 17057 if (*p == '/') 17058 ++p; 17059 eap->nextcmd = check_nextcmd(p); 17060 return; 17061 } 17062 17063 /* 17064 * Get the function name. There are these situations: 17065 * func normal function name 17066 * "name" == func, "fudi.fd_dict" == NULL 17067 * dict.func new dictionary entry 17068 * "name" == NULL, "fudi.fd_dict" set, 17069 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 17070 * dict.func existing dict entry with a Funcref 17071 * "name" == func, "fudi.fd_dict" set, 17072 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17073 * dict.func existing dict entry that's not a Funcref 17074 * "name" == NULL, "fudi.fd_dict" set, 17075 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17076 */ 17077 p = eap->arg; 17078 name = trans_function_name(&p, eap->skip, 0, &fudi); 17079 paren = (vim_strchr(p, '(') != NULL); 17080 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 17081 { 17082 /* 17083 * Return on an invalid expression in braces, unless the expression 17084 * evaluation has been cancelled due to an aborting error, an 17085 * interrupt, or an exception. 17086 */ 17087 if (!aborting()) 17088 { 17089 if (!eap->skip && fudi.fd_newkey != NULL) 17090 EMSG2(_(e_dictkey), fudi.fd_newkey); 17091 vim_free(fudi.fd_newkey); 17092 return; 17093 } 17094 else 17095 eap->skip = TRUE; 17096 } 17097 /* An error in a function call during evaluation of an expression in magic 17098 * braces should not cause the function not to be defined. */ 17099 saved_did_emsg = did_emsg; 17100 did_emsg = FALSE; 17101 17102 /* 17103 * ":function func" with only function name: list function. 17104 */ 17105 if (!paren) 17106 { 17107 if (!ends_excmd(*skipwhite(p))) 17108 { 17109 EMSG(_(e_trailing)); 17110 goto ret_free; 17111 } 17112 eap->nextcmd = check_nextcmd(p); 17113 if (eap->nextcmd != NULL) 17114 *p = NUL; 17115 if (!eap->skip && !got_int) 17116 { 17117 fp = find_func(name); 17118 if (fp != NULL) 17119 { 17120 list_func_head(fp, TRUE); 17121 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 17122 { 17123 msg_putchar('\n'); 17124 msg_outnum((long)(j + 1)); 17125 if (j < 9) 17126 msg_putchar(' '); 17127 if (j < 99) 17128 msg_putchar(' '); 17129 msg_prt_line(FUNCLINE(fp, j), FALSE); 17130 out_flush(); /* show a line at a time */ 17131 ui_breakcheck(); 17132 } 17133 if (!got_int) 17134 { 17135 msg_putchar('\n'); 17136 msg_puts((char_u *)" endfunction"); 17137 } 17138 } 17139 else 17140 emsg_funcname("E123: Undefined function: %s", name); 17141 } 17142 goto ret_free; 17143 } 17144 17145 /* 17146 * ":function name(arg1, arg2)" Define function. 17147 */ 17148 p = skipwhite(p); 17149 if (*p != '(') 17150 { 17151 if (!eap->skip) 17152 { 17153 EMSG2(_("E124: Missing '(': %s"), eap->arg); 17154 goto ret_free; 17155 } 17156 /* attempt to continue by skipping some text */ 17157 if (vim_strchr(p, '(') != NULL) 17158 p = vim_strchr(p, '('); 17159 } 17160 p = skipwhite(p + 1); 17161 17162 ga_init2(&newargs, (int)sizeof(char_u *), 3); 17163 ga_init2(&newlines, (int)sizeof(char_u *), 3); 17164 17165 if (!eap->skip) 17166 { 17167 /* Check the name of the function. */ 17168 if (name != NULL) 17169 arg = name; 17170 else 17171 arg = fudi.fd_newkey; 17172 if (arg != NULL) 17173 { 17174 if (*arg == K_SPECIAL) 17175 j = 3; 17176 else 17177 j = 0; 17178 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 17179 : eval_isnamec(arg[j]))) 17180 ++j; 17181 if (arg[j] != NUL) 17182 emsg_funcname(_(e_invarg2), arg); 17183 } 17184 } 17185 17186 /* 17187 * Isolate the arguments: "arg1, arg2, ...)" 17188 */ 17189 while (*p != ')') 17190 { 17191 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 17192 { 17193 varargs = TRUE; 17194 p += 3; 17195 mustend = TRUE; 17196 } 17197 else 17198 { 17199 arg = p; 17200 while (ASCII_ISALNUM(*p) || *p == '_') 17201 ++p; 17202 if (arg == p || isdigit(*arg) 17203 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 17204 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 17205 { 17206 if (!eap->skip) 17207 EMSG2(_("E125: Illegal argument: %s"), arg); 17208 break; 17209 } 17210 if (ga_grow(&newargs, 1) == FAIL) 17211 goto erret; 17212 c = *p; 17213 *p = NUL; 17214 arg = vim_strsave(arg); 17215 if (arg == NULL) 17216 goto erret; 17217 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 17218 *p = c; 17219 newargs.ga_len++; 17220 if (*p == ',') 17221 ++p; 17222 else 17223 mustend = TRUE; 17224 } 17225 p = skipwhite(p); 17226 if (mustend && *p != ')') 17227 { 17228 if (!eap->skip) 17229 EMSG2(_(e_invarg2), eap->arg); 17230 break; 17231 } 17232 } 17233 ++p; /* skip the ')' */ 17234 17235 /* find extra arguments "range", "dict" and "abort" */ 17236 for (;;) 17237 { 17238 p = skipwhite(p); 17239 if (STRNCMP(p, "range", 5) == 0) 17240 { 17241 flags |= FC_RANGE; 17242 p += 5; 17243 } 17244 else if (STRNCMP(p, "dict", 4) == 0) 17245 { 17246 flags |= FC_DICT; 17247 p += 4; 17248 } 17249 else if (STRNCMP(p, "abort", 5) == 0) 17250 { 17251 flags |= FC_ABORT; 17252 p += 5; 17253 } 17254 else 17255 break; 17256 } 17257 17258 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 17259 EMSG(_(e_trailing)); 17260 17261 /* 17262 * Read the body of the function, until ":endfunction" is found. 17263 */ 17264 if (KeyTyped) 17265 { 17266 /* Check if the function already exists, don't let the user type the 17267 * whole function before telling him it doesn't work! For a script we 17268 * need to skip the body to be able to find what follows. */ 17269 if (!eap->skip && !eap->forceit) 17270 { 17271 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 17272 EMSG(_(e_funcdict)); 17273 else if (name != NULL && find_func(name) != NULL) 17274 emsg_funcname(e_funcexts, name); 17275 } 17276 17277 if (!eap->skip && did_emsg) 17278 goto erret; 17279 17280 msg_putchar('\n'); /* don't overwrite the function name */ 17281 cmdline_row = msg_row; 17282 } 17283 17284 indent = 2; 17285 nesting = 0; 17286 for (;;) 17287 { 17288 msg_scroll = TRUE; 17289 need_wait_return = FALSE; 17290 if (eap->getline == NULL) 17291 theline = getcmdline(':', 0L, indent); 17292 else 17293 theline = eap->getline(':', eap->cookie, indent); 17294 if (KeyTyped) 17295 lines_left = Rows - 1; 17296 if (theline == NULL) 17297 { 17298 EMSG(_("E126: Missing :endfunction")); 17299 goto erret; 17300 } 17301 17302 if (skip_until != NULL) 17303 { 17304 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17305 * don't check for ":endfunc". */ 17306 if (STRCMP(theline, skip_until) == 0) 17307 { 17308 vim_free(skip_until); 17309 skip_until = NULL; 17310 } 17311 } 17312 else 17313 { 17314 /* skip ':' and blanks*/ 17315 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17316 ; 17317 17318 /* Check for "endfunction". */ 17319 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17320 { 17321 vim_free(theline); 17322 break; 17323 } 17324 17325 /* Increase indent inside "if", "while", "for" and "try", decrease 17326 * at "end". */ 17327 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17328 indent -= 2; 17329 else if (STRNCMP(p, "if", 2) == 0 17330 || STRNCMP(p, "wh", 2) == 0 17331 || STRNCMP(p, "for", 3) == 0 17332 || STRNCMP(p, "try", 3) == 0) 17333 indent += 2; 17334 17335 /* Check for defining a function inside this function. */ 17336 if (checkforcmd(&p, "function", 2)) 17337 { 17338 if (*p == '!') 17339 p = skipwhite(p + 1); 17340 p += eval_fname_script(p); 17341 if (ASCII_ISALPHA(*p)) 17342 { 17343 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17344 if (*skipwhite(p) == '(') 17345 { 17346 ++nesting; 17347 indent += 2; 17348 } 17349 } 17350 } 17351 17352 /* Check for ":append" or ":insert". */ 17353 p = skip_range(p, NULL); 17354 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17355 || (p[0] == 'i' 17356 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17357 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17358 skip_until = vim_strsave((char_u *)"."); 17359 17360 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17361 arg = skipwhite(skiptowhite(p)); 17362 if (arg[0] == '<' && arg[1] =='<' 17363 && ((p[0] == 'p' && p[1] == 'y' 17364 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17365 || (p[0] == 'p' && p[1] == 'e' 17366 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17367 || (p[0] == 't' && p[1] == 'c' 17368 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17369 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17370 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17371 || (p[0] == 'm' && p[1] == 'z' 17372 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17373 )) 17374 { 17375 /* ":python <<" continues until a dot, like ":append" */ 17376 p = skipwhite(arg + 2); 17377 if (*p == NUL) 17378 skip_until = vim_strsave((char_u *)"."); 17379 else 17380 skip_until = vim_strsave(p); 17381 } 17382 } 17383 17384 /* Add the line to the function. */ 17385 if (ga_grow(&newlines, 1) == FAIL) 17386 { 17387 vim_free(theline); 17388 goto erret; 17389 } 17390 17391 /* Copy the line to newly allocated memory. get_one_sourceline() 17392 * allocates 250 bytes per line, this saves 80% on average. The cost 17393 * is an extra alloc/free. */ 17394 p = vim_strsave(theline); 17395 if (p != NULL) 17396 { 17397 vim_free(theline); 17398 theline = p; 17399 } 17400 17401 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17402 newlines.ga_len++; 17403 } 17404 17405 /* Don't define the function when skipping commands or when an error was 17406 * detected. */ 17407 if (eap->skip || did_emsg) 17408 goto erret; 17409 17410 /* 17411 * If there are no errors, add the function 17412 */ 17413 if (fudi.fd_dict == NULL) 17414 { 17415 v = find_var(name, &ht); 17416 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17417 { 17418 emsg_funcname("E707: Function name conflicts with variable: %s", 17419 name); 17420 goto erret; 17421 } 17422 17423 fp = find_func(name); 17424 if (fp != NULL) 17425 { 17426 if (!eap->forceit) 17427 { 17428 emsg_funcname(e_funcexts, name); 17429 goto erret; 17430 } 17431 if (fp->uf_calls > 0) 17432 { 17433 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17434 name); 17435 goto erret; 17436 } 17437 /* redefine existing function */ 17438 ga_clear_strings(&(fp->uf_args)); 17439 ga_clear_strings(&(fp->uf_lines)); 17440 vim_free(name); 17441 name = NULL; 17442 } 17443 } 17444 else 17445 { 17446 char numbuf[20]; 17447 17448 fp = NULL; 17449 if (fudi.fd_newkey == NULL && !eap->forceit) 17450 { 17451 EMSG(_(e_funcdict)); 17452 goto erret; 17453 } 17454 if (fudi.fd_di == NULL) 17455 { 17456 /* Can't add a function to a locked dictionary */ 17457 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17458 goto erret; 17459 } 17460 /* Can't change an existing function if it is locked */ 17461 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17462 goto erret; 17463 17464 /* Give the function a sequential number. Can only be used with a 17465 * Funcref! */ 17466 vim_free(name); 17467 sprintf(numbuf, "%d", ++func_nr); 17468 name = vim_strsave((char_u *)numbuf); 17469 if (name == NULL) 17470 goto erret; 17471 } 17472 17473 if (fp == NULL) 17474 { 17475 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17476 { 17477 int slen, plen; 17478 char_u *scriptname; 17479 17480 /* Check that the autoload name matches the script name. */ 17481 j = FAIL; 17482 if (sourcing_name != NULL) 17483 { 17484 scriptname = autoload_name(name); 17485 if (scriptname != NULL) 17486 { 17487 p = vim_strchr(scriptname, '/'); 17488 plen = STRLEN(p); 17489 slen = STRLEN(sourcing_name); 17490 if (slen > plen && fnamecmp(p, 17491 sourcing_name + slen - plen) == 0) 17492 j = OK; 17493 vim_free(scriptname); 17494 } 17495 } 17496 if (j == FAIL) 17497 { 17498 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17499 goto erret; 17500 } 17501 } 17502 17503 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17504 if (fp == NULL) 17505 goto erret; 17506 17507 if (fudi.fd_dict != NULL) 17508 { 17509 if (fudi.fd_di == NULL) 17510 { 17511 /* add new dict entry */ 17512 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17513 if (fudi.fd_di == NULL) 17514 { 17515 vim_free(fp); 17516 goto erret; 17517 } 17518 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17519 { 17520 vim_free(fudi.fd_di); 17521 goto erret; 17522 } 17523 } 17524 else 17525 /* overwrite existing dict entry */ 17526 clear_tv(&fudi.fd_di->di_tv); 17527 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17528 fudi.fd_di->di_tv.v_lock = 0; 17529 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17530 fp->uf_refcount = 1; 17531 } 17532 17533 /* insert the new function in the function list */ 17534 STRCPY(fp->uf_name, name); 17535 hash_add(&func_hashtab, UF2HIKEY(fp)); 17536 } 17537 fp->uf_args = newargs; 17538 fp->uf_lines = newlines; 17539 #ifdef FEAT_PROFILE 17540 fp->uf_tml_count = NULL; 17541 fp->uf_tml_total = NULL; 17542 fp->uf_tml_self = NULL; 17543 fp->uf_profiling = FALSE; 17544 if (prof_def_func()) 17545 func_do_profile(fp); 17546 #endif 17547 fp->uf_varargs = varargs; 17548 fp->uf_flags = flags; 17549 fp->uf_calls = 0; 17550 fp->uf_script_ID = current_SID; 17551 goto ret_free; 17552 17553 erret: 17554 ga_clear_strings(&newargs); 17555 ga_clear_strings(&newlines); 17556 ret_free: 17557 vim_free(skip_until); 17558 vim_free(fudi.fd_newkey); 17559 vim_free(name); 17560 did_emsg |= saved_did_emsg; 17561 } 17562 17563 /* 17564 * Get a function name, translating "<SID>" and "<SNR>". 17565 * Also handles a Funcref in a List or Dictionary. 17566 * Returns the function name in allocated memory, or NULL for failure. 17567 * flags: 17568 * TFN_INT: internal function name OK 17569 * TFN_QUIET: be quiet 17570 * Advances "pp" to just after the function name (if no error). 17571 */ 17572 static char_u * 17573 trans_function_name(pp, skip, flags, fdp) 17574 char_u **pp; 17575 int skip; /* only find the end, don't evaluate */ 17576 int flags; 17577 funcdict_T *fdp; /* return: info about dictionary used */ 17578 { 17579 char_u *name = NULL; 17580 char_u *start; 17581 char_u *end; 17582 int lead; 17583 char_u sid_buf[20]; 17584 int len; 17585 lval_T lv; 17586 17587 if (fdp != NULL) 17588 vim_memset(fdp, 0, sizeof(funcdict_T)); 17589 start = *pp; 17590 17591 /* Check for hard coded <SNR>: already translated function ID (from a user 17592 * command). */ 17593 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17594 && (*pp)[2] == (int)KE_SNR) 17595 { 17596 *pp += 3; 17597 len = get_id_len(pp) + 3; 17598 return vim_strnsave(start, len); 17599 } 17600 17601 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17602 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17603 lead = eval_fname_script(start); 17604 if (lead > 2) 17605 start += lead; 17606 17607 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17608 lead > 2 ? 0 : FNE_CHECK_START); 17609 if (end == start) 17610 { 17611 if (!skip) 17612 EMSG(_("E129: Function name required")); 17613 goto theend; 17614 } 17615 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17616 { 17617 /* 17618 * Report an invalid expression in braces, unless the expression 17619 * evaluation has been cancelled due to an aborting error, an 17620 * interrupt, or an exception. 17621 */ 17622 if (!aborting()) 17623 { 17624 if (end != NULL) 17625 EMSG2(_(e_invarg2), start); 17626 } 17627 else 17628 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17629 goto theend; 17630 } 17631 17632 if (lv.ll_tv != NULL) 17633 { 17634 if (fdp != NULL) 17635 { 17636 fdp->fd_dict = lv.ll_dict; 17637 fdp->fd_newkey = lv.ll_newkey; 17638 lv.ll_newkey = NULL; 17639 fdp->fd_di = lv.ll_di; 17640 } 17641 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17642 { 17643 name = vim_strsave(lv.ll_tv->vval.v_string); 17644 *pp = end; 17645 } 17646 else 17647 { 17648 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17649 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17650 EMSG(_(e_funcref)); 17651 else 17652 *pp = end; 17653 name = NULL; 17654 } 17655 goto theend; 17656 } 17657 17658 if (lv.ll_name == NULL) 17659 { 17660 /* Error found, but continue after the function name. */ 17661 *pp = end; 17662 goto theend; 17663 } 17664 17665 if (lv.ll_exp_name != NULL) 17666 len = STRLEN(lv.ll_exp_name); 17667 else 17668 { 17669 if (lead == 2) /* skip over "s:" */ 17670 lv.ll_name += 2; 17671 len = (int)(end - lv.ll_name); 17672 } 17673 17674 /* 17675 * Copy the function name to allocated memory. 17676 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17677 * Accept <SNR>123_name() outside a script. 17678 */ 17679 if (skip) 17680 lead = 0; /* do nothing */ 17681 else if (lead > 0) 17682 { 17683 lead = 3; 17684 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17685 { 17686 if (current_SID <= 0) 17687 { 17688 EMSG(_(e_usingsid)); 17689 goto theend; 17690 } 17691 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17692 lead += (int)STRLEN(sid_buf); 17693 } 17694 } 17695 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17696 { 17697 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17698 goto theend; 17699 } 17700 name = alloc((unsigned)(len + lead + 1)); 17701 if (name != NULL) 17702 { 17703 if (lead > 0) 17704 { 17705 name[0] = K_SPECIAL; 17706 name[1] = KS_EXTRA; 17707 name[2] = (int)KE_SNR; 17708 if (lead > 3) /* If it's "<SID>" */ 17709 STRCPY(name + 3, sid_buf); 17710 } 17711 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17712 name[len + lead] = NUL; 17713 } 17714 *pp = end; 17715 17716 theend: 17717 clear_lval(&lv); 17718 return name; 17719 } 17720 17721 /* 17722 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17723 * Return 2 if "p" starts with "s:". 17724 * Return 0 otherwise. 17725 */ 17726 static int 17727 eval_fname_script(p) 17728 char_u *p; 17729 { 17730 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17731 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17732 return 5; 17733 if (p[0] == 's' && p[1] == ':') 17734 return 2; 17735 return 0; 17736 } 17737 17738 /* 17739 * Return TRUE if "p" starts with "<SID>" or "s:". 17740 * Only works if eval_fname_script() returned non-zero for "p"! 17741 */ 17742 static int 17743 eval_fname_sid(p) 17744 char_u *p; 17745 { 17746 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17747 } 17748 17749 /* 17750 * List the head of the function: "name(arg1, arg2)". 17751 */ 17752 static void 17753 list_func_head(fp, indent) 17754 ufunc_T *fp; 17755 int indent; 17756 { 17757 int j; 17758 17759 msg_start(); 17760 if (indent) 17761 MSG_PUTS(" "); 17762 MSG_PUTS("function "); 17763 if (fp->uf_name[0] == K_SPECIAL) 17764 { 17765 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17766 msg_puts(fp->uf_name + 3); 17767 } 17768 else 17769 msg_puts(fp->uf_name); 17770 msg_putchar('('); 17771 for (j = 0; j < fp->uf_args.ga_len; ++j) 17772 { 17773 if (j) 17774 MSG_PUTS(", "); 17775 msg_puts(FUNCARG(fp, j)); 17776 } 17777 if (fp->uf_varargs) 17778 { 17779 if (j) 17780 MSG_PUTS(", "); 17781 MSG_PUTS("..."); 17782 } 17783 msg_putchar(')'); 17784 msg_clr_eos(); 17785 if (p_verbose > 0) 17786 last_set_msg(fp->uf_script_ID); 17787 } 17788 17789 /* 17790 * Find a function by name, return pointer to it in ufuncs. 17791 * Return NULL for unknown function. 17792 */ 17793 static ufunc_T * 17794 find_func(name) 17795 char_u *name; 17796 { 17797 hashitem_T *hi; 17798 17799 hi = hash_find(&func_hashtab, name); 17800 if (!HASHITEM_EMPTY(hi)) 17801 return HI2UF(hi); 17802 return NULL; 17803 } 17804 17805 #if defined(EXITFREE) || defined(PROTO) 17806 void 17807 free_all_functions() 17808 { 17809 hashitem_T *hi; 17810 17811 /* Need to start all over every time, because func_free() may change the 17812 * hash table. */ 17813 while (func_hashtab.ht_used > 0) 17814 for (hi = func_hashtab.ht_array; ; ++hi) 17815 if (!HASHITEM_EMPTY(hi)) 17816 { 17817 func_free(HI2UF(hi)); 17818 break; 17819 } 17820 } 17821 #endif 17822 17823 /* 17824 * Return TRUE if a function "name" exists. 17825 */ 17826 static int 17827 function_exists(name) 17828 char_u *name; 17829 { 17830 char_u *p = name; 17831 int n = FALSE; 17832 17833 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17834 if (p != NULL) 17835 { 17836 if (builtin_function(p)) 17837 n = (find_internal_func(p) >= 0); 17838 else 17839 n = (find_func(p) != NULL); 17840 vim_free(p); 17841 } 17842 return n; 17843 } 17844 17845 /* 17846 * Return TRUE if "name" looks like a builtin function name: starts with a 17847 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17848 */ 17849 static int 17850 builtin_function(name) 17851 char_u *name; 17852 { 17853 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17854 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17855 } 17856 17857 #if defined(FEAT_PROFILE) || defined(PROTO) 17858 /* 17859 * Start profiling function "fp". 17860 */ 17861 static void 17862 func_do_profile(fp) 17863 ufunc_T *fp; 17864 { 17865 fp->uf_tm_count = 0; 17866 profile_zero(&fp->uf_tm_self); 17867 profile_zero(&fp->uf_tm_total); 17868 if (fp->uf_tml_count == NULL) 17869 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17870 (sizeof(int) * fp->uf_lines.ga_len)); 17871 if (fp->uf_tml_total == NULL) 17872 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17873 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17874 if (fp->uf_tml_self == NULL) 17875 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17876 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17877 fp->uf_tml_idx = -1; 17878 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17879 || fp->uf_tml_self == NULL) 17880 return; /* out of memory */ 17881 17882 fp->uf_profiling = TRUE; 17883 } 17884 17885 /* 17886 * Dump the profiling results for all functions in file "fd". 17887 */ 17888 void 17889 func_dump_profile(fd) 17890 FILE *fd; 17891 { 17892 hashitem_T *hi; 17893 int todo; 17894 ufunc_T *fp; 17895 int i; 17896 ufunc_T **sorttab; 17897 int st_len = 0; 17898 17899 todo = func_hashtab.ht_used; 17900 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17901 17902 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17903 { 17904 if (!HASHITEM_EMPTY(hi)) 17905 { 17906 --todo; 17907 fp = HI2UF(hi); 17908 if (fp->uf_profiling) 17909 { 17910 if (sorttab != NULL) 17911 sorttab[st_len++] = fp; 17912 17913 if (fp->uf_name[0] == K_SPECIAL) 17914 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17915 else 17916 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17917 if (fp->uf_tm_count == 1) 17918 fprintf(fd, "Called 1 time\n"); 17919 else 17920 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17921 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17922 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17923 fprintf(fd, "\n"); 17924 fprintf(fd, "count total (s) self (s)\n"); 17925 17926 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17927 { 17928 prof_func_line(fd, fp->uf_tml_count[i], 17929 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17930 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17931 } 17932 fprintf(fd, "\n"); 17933 } 17934 } 17935 } 17936 17937 if (sorttab != NULL && st_len > 0) 17938 { 17939 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17940 prof_total_cmp); 17941 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17942 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17943 prof_self_cmp); 17944 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17945 } 17946 } 17947 17948 static void 17949 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17950 FILE *fd; 17951 ufunc_T **sorttab; 17952 int st_len; 17953 char *title; 17954 int prefer_self; /* when equal print only self time */ 17955 { 17956 int i; 17957 ufunc_T *fp; 17958 17959 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17960 fprintf(fd, "count total (s) self (s) function\n"); 17961 for (i = 0; i < 20 && i < st_len; ++i) 17962 { 17963 fp = sorttab[i]; 17964 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17965 prefer_self); 17966 if (fp->uf_name[0] == K_SPECIAL) 17967 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17968 else 17969 fprintf(fd, " %s()\n", fp->uf_name); 17970 } 17971 fprintf(fd, "\n"); 17972 } 17973 17974 /* 17975 * Print the count and times for one function or function line. 17976 */ 17977 static void 17978 prof_func_line(fd, count, total, self, prefer_self) 17979 FILE *fd; 17980 int count; 17981 proftime_T *total; 17982 proftime_T *self; 17983 int prefer_self; /* when equal print only self time */ 17984 { 17985 if (count > 0) 17986 { 17987 fprintf(fd, "%5d ", count); 17988 if (prefer_self && profile_equal(total, self)) 17989 fprintf(fd, " "); 17990 else 17991 fprintf(fd, "%s ", profile_msg(total)); 17992 if (!prefer_self && profile_equal(total, self)) 17993 fprintf(fd, " "); 17994 else 17995 fprintf(fd, "%s ", profile_msg(self)); 17996 } 17997 else 17998 fprintf(fd, " "); 17999 } 18000 18001 /* 18002 * Compare function for total time sorting. 18003 */ 18004 static int 18005 #ifdef __BORLANDC__ 18006 _RTLENTRYF 18007 #endif 18008 prof_total_cmp(s1, s2) 18009 const void *s1; 18010 const void *s2; 18011 { 18012 ufunc_T *p1, *p2; 18013 18014 p1 = *(ufunc_T **)s1; 18015 p2 = *(ufunc_T **)s2; 18016 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 18017 } 18018 18019 /* 18020 * Compare function for self time sorting. 18021 */ 18022 static int 18023 #ifdef __BORLANDC__ 18024 _RTLENTRYF 18025 #endif 18026 prof_self_cmp(s1, s2) 18027 const void *s1; 18028 const void *s2; 18029 { 18030 ufunc_T *p1, *p2; 18031 18032 p1 = *(ufunc_T **)s1; 18033 p2 = *(ufunc_T **)s2; 18034 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 18035 } 18036 18037 #endif 18038 18039 /* The names of packages that once were loaded is remembered. */ 18040 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 18041 18042 /* 18043 * If "name" has a package name try autoloading the script for it. 18044 * Return TRUE if a package was loaded. 18045 */ 18046 static int 18047 script_autoload(name, reload) 18048 char_u *name; 18049 int reload; /* load script again when already loaded */ 18050 { 18051 char_u *p; 18052 char_u *scriptname, *tofree; 18053 int ret = FALSE; 18054 int i; 18055 18056 /* If there is no '#' after name[0] there is no package name. */ 18057 p = vim_strchr(name, AUTOLOAD_CHAR); 18058 if (p == NULL || p == name) 18059 return FALSE; 18060 18061 tofree = scriptname = autoload_name(name); 18062 18063 /* Find the name in the list of previously loaded package names. Skip 18064 * "autoload/", it's always the same. */ 18065 for (i = 0; i < ga_loaded.ga_len; ++i) 18066 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 18067 break; 18068 if (!reload && i < ga_loaded.ga_len) 18069 ret = FALSE; /* was loaded already */ 18070 else 18071 { 18072 /* Remember the name if it wasn't loaded already. */ 18073 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 18074 { 18075 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 18076 tofree = NULL; 18077 } 18078 18079 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 18080 if (source_runtime(scriptname, FALSE) == OK) 18081 ret = TRUE; 18082 } 18083 18084 vim_free(tofree); 18085 return ret; 18086 } 18087 18088 /* 18089 * Return the autoload script name for a function or variable name. 18090 * Returns NULL when out of memory. 18091 */ 18092 static char_u * 18093 autoload_name(name) 18094 char_u *name; 18095 { 18096 char_u *p; 18097 char_u *scriptname; 18098 18099 /* Get the script file name: replace '#' with '/', append ".vim". */ 18100 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 18101 if (scriptname == NULL) 18102 return FALSE; 18103 STRCPY(scriptname, "autoload/"); 18104 STRCAT(scriptname, name); 18105 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 18106 STRCAT(scriptname, ".vim"); 18107 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 18108 *p = '/'; 18109 return scriptname; 18110 } 18111 18112 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 18113 18114 /* 18115 * Function given to ExpandGeneric() to obtain the list of user defined 18116 * function names. 18117 */ 18118 char_u * 18119 get_user_func_name(xp, idx) 18120 expand_T *xp; 18121 int idx; 18122 { 18123 static long_u done; 18124 static hashitem_T *hi; 18125 ufunc_T *fp; 18126 18127 if (idx == 0) 18128 { 18129 done = 0; 18130 hi = func_hashtab.ht_array; 18131 } 18132 if (done < func_hashtab.ht_used) 18133 { 18134 if (done++ > 0) 18135 ++hi; 18136 while (HASHITEM_EMPTY(hi)) 18137 ++hi; 18138 fp = HI2UF(hi); 18139 18140 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 18141 return fp->uf_name; /* prevents overflow */ 18142 18143 cat_func_name(IObuff, fp); 18144 if (xp->xp_context != EXPAND_USER_FUNC) 18145 { 18146 STRCAT(IObuff, "("); 18147 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 18148 STRCAT(IObuff, ")"); 18149 } 18150 return IObuff; 18151 } 18152 return NULL; 18153 } 18154 18155 #endif /* FEAT_CMDL_COMPL */ 18156 18157 /* 18158 * Copy the function name of "fp" to buffer "buf". 18159 * "buf" must be able to hold the function name plus three bytes. 18160 * Takes care of script-local function names. 18161 */ 18162 static void 18163 cat_func_name(buf, fp) 18164 char_u *buf; 18165 ufunc_T *fp; 18166 { 18167 if (fp->uf_name[0] == K_SPECIAL) 18168 { 18169 STRCPY(buf, "<SNR>"); 18170 STRCAT(buf, fp->uf_name + 3); 18171 } 18172 else 18173 STRCPY(buf, fp->uf_name); 18174 } 18175 18176 /* 18177 * ":delfunction {name}" 18178 */ 18179 void 18180 ex_delfunction(eap) 18181 exarg_T *eap; 18182 { 18183 ufunc_T *fp = NULL; 18184 char_u *p; 18185 char_u *name; 18186 funcdict_T fudi; 18187 18188 p = eap->arg; 18189 name = trans_function_name(&p, eap->skip, 0, &fudi); 18190 vim_free(fudi.fd_newkey); 18191 if (name == NULL) 18192 { 18193 if (fudi.fd_dict != NULL && !eap->skip) 18194 EMSG(_(e_funcref)); 18195 return; 18196 } 18197 if (!ends_excmd(*skipwhite(p))) 18198 { 18199 vim_free(name); 18200 EMSG(_(e_trailing)); 18201 return; 18202 } 18203 eap->nextcmd = check_nextcmd(p); 18204 if (eap->nextcmd != NULL) 18205 *p = NUL; 18206 18207 if (!eap->skip) 18208 fp = find_func(name); 18209 vim_free(name); 18210 18211 if (!eap->skip) 18212 { 18213 if (fp == NULL) 18214 { 18215 EMSG2(_(e_nofunc), eap->arg); 18216 return; 18217 } 18218 if (fp->uf_calls > 0) 18219 { 18220 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 18221 return; 18222 } 18223 18224 if (fudi.fd_dict != NULL) 18225 { 18226 /* Delete the dict item that refers to the function, it will 18227 * invoke func_unref() and possibly delete the function. */ 18228 dictitem_remove(fudi.fd_dict, fudi.fd_di); 18229 } 18230 else 18231 func_free(fp); 18232 } 18233 } 18234 18235 /* 18236 * Free a function and remove it from the list of functions. 18237 */ 18238 static void 18239 func_free(fp) 18240 ufunc_T *fp; 18241 { 18242 hashitem_T *hi; 18243 18244 /* clear this function */ 18245 ga_clear_strings(&(fp->uf_args)); 18246 ga_clear_strings(&(fp->uf_lines)); 18247 #ifdef FEAT_PROFILE 18248 vim_free(fp->uf_tml_count); 18249 vim_free(fp->uf_tml_total); 18250 vim_free(fp->uf_tml_self); 18251 #endif 18252 18253 /* remove the function from the function hashtable */ 18254 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 18255 if (HASHITEM_EMPTY(hi)) 18256 EMSG2(_(e_intern2), "func_free()"); 18257 else 18258 hash_remove(&func_hashtab, hi); 18259 18260 vim_free(fp); 18261 } 18262 18263 /* 18264 * Unreference a Function: decrement the reference count and free it when it 18265 * becomes zero. Only for numbered functions. 18266 */ 18267 static void 18268 func_unref(name) 18269 char_u *name; 18270 { 18271 ufunc_T *fp; 18272 18273 if (name != NULL && isdigit(*name)) 18274 { 18275 fp = find_func(name); 18276 if (fp == NULL) 18277 EMSG2(_(e_intern2), "func_unref()"); 18278 else if (--fp->uf_refcount <= 0) 18279 { 18280 /* Only delete it when it's not being used. Otherwise it's done 18281 * when "uf_calls" becomes zero. */ 18282 if (fp->uf_calls == 0) 18283 func_free(fp); 18284 } 18285 } 18286 } 18287 18288 /* 18289 * Count a reference to a Function. 18290 */ 18291 static void 18292 func_ref(name) 18293 char_u *name; 18294 { 18295 ufunc_T *fp; 18296 18297 if (name != NULL && isdigit(*name)) 18298 { 18299 fp = find_func(name); 18300 if (fp == NULL) 18301 EMSG2(_(e_intern2), "func_ref()"); 18302 else 18303 ++fp->uf_refcount; 18304 } 18305 } 18306 18307 /* 18308 * Call a user function. 18309 */ 18310 static void 18311 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18312 ufunc_T *fp; /* pointer to function */ 18313 int argcount; /* nr of args */ 18314 typval_T *argvars; /* arguments */ 18315 typval_T *rettv; /* return value */ 18316 linenr_T firstline; /* first line of range */ 18317 linenr_T lastline; /* last line of range */ 18318 dict_T *selfdict; /* Dictionary for "self" */ 18319 { 18320 char_u *save_sourcing_name; 18321 linenr_T save_sourcing_lnum; 18322 scid_T save_current_SID; 18323 funccall_T fc; 18324 int save_did_emsg; 18325 static int depth = 0; 18326 dictitem_T *v; 18327 int fixvar_idx = 0; /* index in fixvar[] */ 18328 int i; 18329 int ai; 18330 char_u numbuf[NUMBUFLEN]; 18331 char_u *name; 18332 #ifdef FEAT_PROFILE 18333 proftime_T wait_start; 18334 #endif 18335 18336 /* If depth of calling is getting too high, don't execute the function */ 18337 if (depth >= p_mfd) 18338 { 18339 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18340 rettv->v_type = VAR_NUMBER; 18341 rettv->vval.v_number = -1; 18342 return; 18343 } 18344 ++depth; 18345 18346 line_breakcheck(); /* check for CTRL-C hit */ 18347 18348 fc.caller = current_funccal; 18349 current_funccal = &fc; 18350 fc.func = fp; 18351 fc.rettv = rettv; 18352 rettv->vval.v_number = 0; 18353 fc.linenr = 0; 18354 fc.returned = FALSE; 18355 fc.level = ex_nesting_level; 18356 /* Check if this function has a breakpoint. */ 18357 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18358 fc.dbg_tick = debug_tick; 18359 18360 /* 18361 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18362 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18363 * each argument variable and saves a lot of time. 18364 */ 18365 /* 18366 * Init l: variables. 18367 */ 18368 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18369 if (selfdict != NULL) 18370 { 18371 /* Set l:self to "selfdict". */ 18372 v = &fc.fixvar[fixvar_idx++].var; 18373 STRCPY(v->di_key, "self"); 18374 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18375 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18376 v->di_tv.v_type = VAR_DICT; 18377 v->di_tv.v_lock = 0; 18378 v->di_tv.vval.v_dict = selfdict; 18379 ++selfdict->dv_refcount; 18380 } 18381 18382 /* 18383 * Init a: variables. 18384 * Set a:0 to "argcount". 18385 * Set a:000 to a list with room for the "..." arguments. 18386 */ 18387 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18388 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18389 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18390 v = &fc.fixvar[fixvar_idx++].var; 18391 STRCPY(v->di_key, "000"); 18392 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18393 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18394 v->di_tv.v_type = VAR_LIST; 18395 v->di_tv.v_lock = VAR_FIXED; 18396 v->di_tv.vval.v_list = &fc.l_varlist; 18397 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18398 fc.l_varlist.lv_refcount = 99999; 18399 18400 /* 18401 * Set a:firstline to "firstline" and a:lastline to "lastline". 18402 * Set a:name to named arguments. 18403 * Set a:N to the "..." arguments. 18404 */ 18405 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18406 (varnumber_T)firstline); 18407 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18408 (varnumber_T)lastline); 18409 for (i = 0; i < argcount; ++i) 18410 { 18411 ai = i - fp->uf_args.ga_len; 18412 if (ai < 0) 18413 /* named argument a:name */ 18414 name = FUNCARG(fp, i); 18415 else 18416 { 18417 /* "..." argument a:1, a:2, etc. */ 18418 sprintf((char *)numbuf, "%d", ai + 1); 18419 name = numbuf; 18420 } 18421 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18422 { 18423 v = &fc.fixvar[fixvar_idx++].var; 18424 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18425 } 18426 else 18427 { 18428 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18429 + STRLEN(name))); 18430 if (v == NULL) 18431 break; 18432 v->di_flags = DI_FLAGS_RO; 18433 } 18434 STRCPY(v->di_key, name); 18435 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18436 18437 /* Note: the values are copied directly to avoid alloc/free. 18438 * "argvars" must have VAR_FIXED for v_lock. */ 18439 v->di_tv = argvars[i]; 18440 v->di_tv.v_lock = VAR_FIXED; 18441 18442 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18443 { 18444 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18445 fc.l_listitems[ai].li_tv = argvars[i]; 18446 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18447 } 18448 } 18449 18450 /* Don't redraw while executing the function. */ 18451 ++RedrawingDisabled; 18452 save_sourcing_name = sourcing_name; 18453 save_sourcing_lnum = sourcing_lnum; 18454 sourcing_lnum = 1; 18455 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18456 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18457 if (sourcing_name != NULL) 18458 { 18459 if (save_sourcing_name != NULL 18460 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18461 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18462 else 18463 STRCPY(sourcing_name, "function "); 18464 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18465 18466 if (p_verbose >= 12) 18467 { 18468 ++no_wait_return; 18469 verbose_enter_scroll(); 18470 18471 smsg((char_u *)_("calling %s"), sourcing_name); 18472 if (p_verbose >= 14) 18473 { 18474 char_u buf[MSG_BUF_LEN]; 18475 char_u numbuf[NUMBUFLEN]; 18476 char_u *tofree; 18477 18478 msg_puts((char_u *)"("); 18479 for (i = 0; i < argcount; ++i) 18480 { 18481 if (i > 0) 18482 msg_puts((char_u *)", "); 18483 if (argvars[i].v_type == VAR_NUMBER) 18484 msg_outnum((long)argvars[i].vval.v_number); 18485 else 18486 { 18487 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18488 buf, MSG_BUF_CLEN); 18489 msg_puts(buf); 18490 vim_free(tofree); 18491 } 18492 } 18493 msg_puts((char_u *)")"); 18494 } 18495 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18496 18497 verbose_leave_scroll(); 18498 --no_wait_return; 18499 } 18500 } 18501 #ifdef FEAT_PROFILE 18502 if (do_profiling) 18503 { 18504 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18505 func_do_profile(fp); 18506 if (fp->uf_profiling 18507 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18508 { 18509 ++fp->uf_tm_count; 18510 profile_start(&fp->uf_tm_start); 18511 profile_zero(&fp->uf_tm_children); 18512 } 18513 script_prof_save(&wait_start); 18514 } 18515 #endif 18516 18517 save_current_SID = current_SID; 18518 current_SID = fp->uf_script_ID; 18519 save_did_emsg = did_emsg; 18520 did_emsg = FALSE; 18521 18522 /* call do_cmdline() to execute the lines */ 18523 do_cmdline(NULL, get_func_line, (void *)&fc, 18524 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18525 18526 --RedrawingDisabled; 18527 18528 /* when the function was aborted because of an error, return -1 */ 18529 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18530 { 18531 clear_tv(rettv); 18532 rettv->v_type = VAR_NUMBER; 18533 rettv->vval.v_number = -1; 18534 } 18535 18536 #ifdef FEAT_PROFILE 18537 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18538 { 18539 profile_end(&fp->uf_tm_start); 18540 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18541 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18542 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18543 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18544 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18545 { 18546 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18547 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18548 } 18549 } 18550 #endif 18551 18552 /* when being verbose, mention the return value */ 18553 if (p_verbose >= 12) 18554 { 18555 ++no_wait_return; 18556 verbose_enter_scroll(); 18557 18558 if (aborting()) 18559 smsg((char_u *)_("%s aborted"), sourcing_name); 18560 else if (fc.rettv->v_type == VAR_NUMBER) 18561 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18562 (long)fc.rettv->vval.v_number); 18563 else 18564 { 18565 char_u buf[MSG_BUF_LEN]; 18566 char_u numbuf[NUMBUFLEN]; 18567 char_u *tofree; 18568 18569 /* The value may be very long. Skip the middle part, so that we 18570 * have some idea how it starts and ends. smsg() would always 18571 * truncate it at the end. */ 18572 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18573 buf, MSG_BUF_CLEN); 18574 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18575 vim_free(tofree); 18576 } 18577 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18578 18579 verbose_leave_scroll(); 18580 --no_wait_return; 18581 } 18582 18583 vim_free(sourcing_name); 18584 sourcing_name = save_sourcing_name; 18585 sourcing_lnum = save_sourcing_lnum; 18586 current_SID = save_current_SID; 18587 #ifdef FEAT_PROFILE 18588 if (do_profiling) 18589 script_prof_restore(&wait_start); 18590 #endif 18591 18592 if (p_verbose >= 12 && sourcing_name != NULL) 18593 { 18594 ++no_wait_return; 18595 verbose_enter_scroll(); 18596 18597 smsg((char_u *)_("continuing in %s"), sourcing_name); 18598 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18599 18600 verbose_leave_scroll(); 18601 --no_wait_return; 18602 } 18603 18604 did_emsg |= save_did_emsg; 18605 current_funccal = fc.caller; 18606 18607 /* The a: variables typevals were not alloced, only free the allocated 18608 * variables. */ 18609 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18610 18611 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18612 --depth; 18613 } 18614 18615 /* 18616 * Add a number variable "name" to dict "dp" with value "nr". 18617 */ 18618 static void 18619 add_nr_var(dp, v, name, nr) 18620 dict_T *dp; 18621 dictitem_T *v; 18622 char *name; 18623 varnumber_T nr; 18624 { 18625 STRCPY(v->di_key, name); 18626 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18627 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18628 v->di_tv.v_type = VAR_NUMBER; 18629 v->di_tv.v_lock = VAR_FIXED; 18630 v->di_tv.vval.v_number = nr; 18631 } 18632 18633 /* 18634 * ":return [expr]" 18635 */ 18636 void 18637 ex_return(eap) 18638 exarg_T *eap; 18639 { 18640 char_u *arg = eap->arg; 18641 typval_T rettv; 18642 int returning = FALSE; 18643 18644 if (current_funccal == NULL) 18645 { 18646 EMSG(_("E133: :return not inside a function")); 18647 return; 18648 } 18649 18650 if (eap->skip) 18651 ++emsg_skip; 18652 18653 eap->nextcmd = NULL; 18654 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18655 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18656 { 18657 if (!eap->skip) 18658 returning = do_return(eap, FALSE, TRUE, &rettv); 18659 else 18660 clear_tv(&rettv); 18661 } 18662 /* It's safer to return also on error. */ 18663 else if (!eap->skip) 18664 { 18665 /* 18666 * Return unless the expression evaluation has been cancelled due to an 18667 * aborting error, an interrupt, or an exception. 18668 */ 18669 if (!aborting()) 18670 returning = do_return(eap, FALSE, TRUE, NULL); 18671 } 18672 18673 /* When skipping or the return gets pending, advance to the next command 18674 * in this line (!returning). Otherwise, ignore the rest of the line. 18675 * Following lines will be ignored by get_func_line(). */ 18676 if (returning) 18677 eap->nextcmd = NULL; 18678 else if (eap->nextcmd == NULL) /* no argument */ 18679 eap->nextcmd = check_nextcmd(arg); 18680 18681 if (eap->skip) 18682 --emsg_skip; 18683 } 18684 18685 /* 18686 * Return from a function. Possibly makes the return pending. Also called 18687 * for a pending return at the ":endtry" or after returning from an extra 18688 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18689 * when called due to a ":return" command. "rettv" may point to a typval_T 18690 * with the return rettv. Returns TRUE when the return can be carried out, 18691 * FALSE when the return gets pending. 18692 */ 18693 int 18694 do_return(eap, reanimate, is_cmd, rettv) 18695 exarg_T *eap; 18696 int reanimate; 18697 int is_cmd; 18698 void *rettv; 18699 { 18700 int idx; 18701 struct condstack *cstack = eap->cstack; 18702 18703 if (reanimate) 18704 /* Undo the return. */ 18705 current_funccal->returned = FALSE; 18706 18707 /* 18708 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18709 * not in its finally clause (which then is to be executed next) is found. 18710 * In this case, make the ":return" pending for execution at the ":endtry". 18711 * Otherwise, return normally. 18712 */ 18713 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18714 if (idx >= 0) 18715 { 18716 cstack->cs_pending[idx] = CSTP_RETURN; 18717 18718 if (!is_cmd && !reanimate) 18719 /* A pending return again gets pending. "rettv" points to an 18720 * allocated variable with the rettv of the original ":return"'s 18721 * argument if present or is NULL else. */ 18722 cstack->cs_rettv[idx] = rettv; 18723 else 18724 { 18725 /* When undoing a return in order to make it pending, get the stored 18726 * return rettv. */ 18727 if (reanimate) 18728 rettv = current_funccal->rettv; 18729 18730 if (rettv != NULL) 18731 { 18732 /* Store the value of the pending return. */ 18733 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18734 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18735 else 18736 EMSG(_(e_outofmem)); 18737 } 18738 else 18739 cstack->cs_rettv[idx] = NULL; 18740 18741 if (reanimate) 18742 { 18743 /* The pending return value could be overwritten by a ":return" 18744 * without argument in a finally clause; reset the default 18745 * return value. */ 18746 current_funccal->rettv->v_type = VAR_NUMBER; 18747 current_funccal->rettv->vval.v_number = 0; 18748 } 18749 } 18750 report_make_pending(CSTP_RETURN, rettv); 18751 } 18752 else 18753 { 18754 current_funccal->returned = TRUE; 18755 18756 /* If the return is carried out now, store the return value. For 18757 * a return immediately after reanimation, the value is already 18758 * there. */ 18759 if (!reanimate && rettv != NULL) 18760 { 18761 clear_tv(current_funccal->rettv); 18762 *current_funccal->rettv = *(typval_T *)rettv; 18763 if (!is_cmd) 18764 vim_free(rettv); 18765 } 18766 } 18767 18768 return idx < 0; 18769 } 18770 18771 /* 18772 * Free the variable with a pending return value. 18773 */ 18774 void 18775 discard_pending_return(rettv) 18776 void *rettv; 18777 { 18778 free_tv((typval_T *)rettv); 18779 } 18780 18781 /* 18782 * Generate a return command for producing the value of "rettv". The result 18783 * is an allocated string. Used by report_pending() for verbose messages. 18784 */ 18785 char_u * 18786 get_return_cmd(rettv) 18787 void *rettv; 18788 { 18789 char_u *s = NULL; 18790 char_u *tofree = NULL; 18791 char_u numbuf[NUMBUFLEN]; 18792 18793 if (rettv != NULL) 18794 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18795 if (s == NULL) 18796 s = (char_u *)""; 18797 18798 STRCPY(IObuff, ":return "); 18799 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18800 if (STRLEN(s) + 8 >= IOSIZE) 18801 STRCPY(IObuff + IOSIZE - 4, "..."); 18802 vim_free(tofree); 18803 return vim_strsave(IObuff); 18804 } 18805 18806 /* 18807 * Get next function line. 18808 * Called by do_cmdline() to get the next line. 18809 * Returns allocated string, or NULL for end of function. 18810 */ 18811 /* ARGSUSED */ 18812 char_u * 18813 get_func_line(c, cookie, indent) 18814 int c; /* not used */ 18815 void *cookie; 18816 int indent; /* not used */ 18817 { 18818 funccall_T *fcp = (funccall_T *)cookie; 18819 ufunc_T *fp = fcp->func; 18820 char_u *retval; 18821 garray_T *gap; /* growarray with function lines */ 18822 18823 /* If breakpoints have been added/deleted need to check for it. */ 18824 if (fcp->dbg_tick != debug_tick) 18825 { 18826 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18827 sourcing_lnum); 18828 fcp->dbg_tick = debug_tick; 18829 } 18830 #ifdef FEAT_PROFILE 18831 if (do_profiling) 18832 func_line_end(cookie); 18833 #endif 18834 18835 gap = &fp->uf_lines; 18836 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18837 retval = NULL; 18838 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18839 retval = NULL; 18840 else 18841 { 18842 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18843 sourcing_lnum = fcp->linenr; 18844 #ifdef FEAT_PROFILE 18845 if (do_profiling) 18846 func_line_start(cookie); 18847 #endif 18848 } 18849 18850 /* Did we encounter a breakpoint? */ 18851 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18852 { 18853 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18854 /* Find next breakpoint. */ 18855 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18856 sourcing_lnum); 18857 fcp->dbg_tick = debug_tick; 18858 } 18859 18860 return retval; 18861 } 18862 18863 #if defined(FEAT_PROFILE) || defined(PROTO) 18864 /* 18865 * Called when starting to read a function line. 18866 * "sourcing_lnum" must be correct! 18867 * When skipping lines it may not actually be executed, but we won't find out 18868 * until later and we need to store the time now. 18869 */ 18870 void 18871 func_line_start(cookie) 18872 void *cookie; 18873 { 18874 funccall_T *fcp = (funccall_T *)cookie; 18875 ufunc_T *fp = fcp->func; 18876 18877 if (fp->uf_profiling && sourcing_lnum >= 1 18878 && sourcing_lnum <= fp->uf_lines.ga_len) 18879 { 18880 fp->uf_tml_idx = sourcing_lnum - 1; 18881 fp->uf_tml_execed = FALSE; 18882 profile_start(&fp->uf_tml_start); 18883 profile_zero(&fp->uf_tml_children); 18884 profile_get_wait(&fp->uf_tml_wait); 18885 } 18886 } 18887 18888 /* 18889 * Called when actually executing a function line. 18890 */ 18891 void 18892 func_line_exec(cookie) 18893 void *cookie; 18894 { 18895 funccall_T *fcp = (funccall_T *)cookie; 18896 ufunc_T *fp = fcp->func; 18897 18898 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18899 fp->uf_tml_execed = TRUE; 18900 } 18901 18902 /* 18903 * Called when done with a function line. 18904 */ 18905 void 18906 func_line_end(cookie) 18907 void *cookie; 18908 { 18909 funccall_T *fcp = (funccall_T *)cookie; 18910 ufunc_T *fp = fcp->func; 18911 18912 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18913 { 18914 if (fp->uf_tml_execed) 18915 { 18916 ++fp->uf_tml_count[fp->uf_tml_idx]; 18917 profile_end(&fp->uf_tml_start); 18918 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18919 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18920 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18921 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18922 } 18923 fp->uf_tml_idx = -1; 18924 } 18925 } 18926 #endif 18927 18928 /* 18929 * Return TRUE if the currently active function should be ended, because a 18930 * return was encountered or an error occured. Used inside a ":while". 18931 */ 18932 int 18933 func_has_ended(cookie) 18934 void *cookie; 18935 { 18936 funccall_T *fcp = (funccall_T *)cookie; 18937 18938 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18939 * an error inside a try conditional. */ 18940 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18941 || fcp->returned); 18942 } 18943 18944 /* 18945 * return TRUE if cookie indicates a function which "abort"s on errors. 18946 */ 18947 int 18948 func_has_abort(cookie) 18949 void *cookie; 18950 { 18951 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18952 } 18953 18954 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18955 typedef enum 18956 { 18957 VAR_FLAVOUR_DEFAULT, 18958 VAR_FLAVOUR_SESSION, 18959 VAR_FLAVOUR_VIMINFO 18960 } var_flavour_T; 18961 18962 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18963 18964 static var_flavour_T 18965 var_flavour(varname) 18966 char_u *varname; 18967 { 18968 char_u *p = varname; 18969 18970 if (ASCII_ISUPPER(*p)) 18971 { 18972 while (*(++p)) 18973 if (ASCII_ISLOWER(*p)) 18974 return VAR_FLAVOUR_SESSION; 18975 return VAR_FLAVOUR_VIMINFO; 18976 } 18977 else 18978 return VAR_FLAVOUR_DEFAULT; 18979 } 18980 #endif 18981 18982 #if defined(FEAT_VIMINFO) || defined(PROTO) 18983 /* 18984 * Restore global vars that start with a capital from the viminfo file 18985 */ 18986 int 18987 read_viminfo_varlist(virp, writing) 18988 vir_T *virp; 18989 int writing; 18990 { 18991 char_u *tab; 18992 int is_string = FALSE; 18993 typval_T tv; 18994 18995 if (!writing && (find_viminfo_parameter('!') != NULL)) 18996 { 18997 tab = vim_strchr(virp->vir_line + 1, '\t'); 18998 if (tab != NULL) 18999 { 19000 *tab++ = '\0'; /* isolate the variable name */ 19001 if (*tab == 'S') /* string var */ 19002 is_string = TRUE; 19003 19004 tab = vim_strchr(tab, '\t'); 19005 if (tab != NULL) 19006 { 19007 if (is_string) 19008 { 19009 tv.v_type = VAR_STRING; 19010 tv.vval.v_string = viminfo_readstring(virp, 19011 (int)(tab - virp->vir_line + 1), TRUE); 19012 } 19013 else 19014 { 19015 tv.v_type = VAR_NUMBER; 19016 tv.vval.v_number = atol((char *)tab + 1); 19017 } 19018 set_var(virp->vir_line + 1, &tv, FALSE); 19019 if (is_string) 19020 vim_free(tv.vval.v_string); 19021 } 19022 } 19023 } 19024 19025 return viminfo_readline(virp); 19026 } 19027 19028 /* 19029 * Write global vars that start with a capital to the viminfo file 19030 */ 19031 void 19032 write_viminfo_varlist(fp) 19033 FILE *fp; 19034 { 19035 hashitem_T *hi; 19036 dictitem_T *this_var; 19037 int todo; 19038 char *s; 19039 char_u *p; 19040 char_u *tofree; 19041 char_u numbuf[NUMBUFLEN]; 19042 19043 if (find_viminfo_parameter('!') == NULL) 19044 return; 19045 19046 fprintf(fp, _("\n# global variables:\n")); 19047 19048 todo = globvarht.ht_used; 19049 for (hi = globvarht.ht_array; todo > 0; ++hi) 19050 { 19051 if (!HASHITEM_EMPTY(hi)) 19052 { 19053 --todo; 19054 this_var = HI2DI(hi); 19055 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 19056 { 19057 switch (this_var->di_tv.v_type) 19058 { 19059 case VAR_STRING: s = "STR"; break; 19060 case VAR_NUMBER: s = "NUM"; break; 19061 default: continue; 19062 } 19063 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 19064 p = echo_string(&this_var->di_tv, &tofree, numbuf); 19065 if (p != NULL) 19066 viminfo_writestring(fp, p); 19067 vim_free(tofree); 19068 } 19069 } 19070 } 19071 } 19072 #endif 19073 19074 #if defined(FEAT_SESSION) || defined(PROTO) 19075 int 19076 store_session_globals(fd) 19077 FILE *fd; 19078 { 19079 hashitem_T *hi; 19080 dictitem_T *this_var; 19081 int todo; 19082 char_u *p, *t; 19083 19084 todo = globvarht.ht_used; 19085 for (hi = globvarht.ht_array; todo > 0; ++hi) 19086 { 19087 if (!HASHITEM_EMPTY(hi)) 19088 { 19089 --todo; 19090 this_var = HI2DI(hi); 19091 if ((this_var->di_tv.v_type == VAR_NUMBER 19092 || this_var->di_tv.v_type == VAR_STRING) 19093 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 19094 { 19095 /* Escape special characters with a backslash. Turn a LF and 19096 * CR into \n and \r. */ 19097 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 19098 (char_u *)"\\\"\n\r"); 19099 if (p == NULL) /* out of memory */ 19100 break; 19101 for (t = p; *t != NUL; ++t) 19102 if (*t == '\n') 19103 *t = 'n'; 19104 else if (*t == '\r') 19105 *t = 'r'; 19106 if ((fprintf(fd, "let %s = %c%s%c", 19107 this_var->di_key, 19108 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19109 : ' ', 19110 p, 19111 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19112 : ' ') < 0) 19113 || put_eol(fd) == FAIL) 19114 { 19115 vim_free(p); 19116 return FAIL; 19117 } 19118 vim_free(p); 19119 } 19120 } 19121 } 19122 return OK; 19123 } 19124 #endif 19125 19126 /* 19127 * Display script name where an item was last set. 19128 * Should only be invoked when 'verbose' is non-zero. 19129 */ 19130 void 19131 last_set_msg(scriptID) 19132 scid_T scriptID; 19133 { 19134 char_u *p; 19135 19136 if (scriptID != 0) 19137 { 19138 p = home_replace_save(NULL, get_scriptname(scriptID)); 19139 if (p != NULL) 19140 { 19141 verbose_enter(); 19142 MSG_PUTS(_("\n\tLast set from ")); 19143 MSG_PUTS(p); 19144 vim_free(p); 19145 verbose_leave(); 19146 } 19147 } 19148 } 19149 19150 #endif /* FEAT_EVAL */ 19151 19152 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 19153 19154 19155 #ifdef WIN3264 19156 /* 19157 * Functions for ":8" filename modifier: get 8.3 version of a filename. 19158 */ 19159 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19160 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 19161 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19162 19163 /* 19164 * Get the short pathname of a file. 19165 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 19166 */ 19167 static int 19168 get_short_pathname(fnamep, bufp, fnamelen) 19169 char_u **fnamep; 19170 char_u **bufp; 19171 int *fnamelen; 19172 { 19173 int l,len; 19174 char_u *newbuf; 19175 19176 len = *fnamelen; 19177 19178 l = GetShortPathName(*fnamep, *fnamep, len); 19179 if (l > len - 1) 19180 { 19181 /* If that doesn't work (not enough space), then save the string 19182 * and try again with a new buffer big enough 19183 */ 19184 newbuf = vim_strnsave(*fnamep, l); 19185 if (newbuf == NULL) 19186 return 0; 19187 19188 vim_free(*bufp); 19189 *fnamep = *bufp = newbuf; 19190 19191 l = GetShortPathName(*fnamep,*fnamep,l+1); 19192 19193 /* Really should always succeed, as the buffer is big enough */ 19194 } 19195 19196 *fnamelen = l; 19197 return 1; 19198 } 19199 19200 /* 19201 * Create a short path name. Returns the length of the buffer it needs. 19202 * Doesn't copy over the end of the buffer passed in. 19203 */ 19204 static int 19205 shortpath_for_invalid_fname(fname, bufp, fnamelen) 19206 char_u **fname; 19207 char_u **bufp; 19208 int *fnamelen; 19209 { 19210 char_u *s, *p, *pbuf2, *pbuf3; 19211 char_u ch; 19212 int len, len2, plen, slen; 19213 19214 /* Make a copy */ 19215 len2 = *fnamelen; 19216 pbuf2 = vim_strnsave(*fname, len2); 19217 pbuf3 = NULL; 19218 19219 s = pbuf2 + len2 - 1; /* Find the end */ 19220 slen = 1; 19221 plen = len2; 19222 19223 if (after_pathsep(pbuf2, s + 1)) 19224 { 19225 --s; 19226 ++slen; 19227 --plen; 19228 } 19229 19230 do 19231 { 19232 /* Go back one path-seperator */ 19233 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 19234 { 19235 --s; 19236 ++slen; 19237 --plen; 19238 } 19239 if (s <= pbuf2) 19240 break; 19241 19242 /* Remeber the character that is about to be blatted */ 19243 ch = *s; 19244 *s = 0; /* get_short_pathname requires a null-terminated string */ 19245 19246 /* Try it in situ */ 19247 p = pbuf2; 19248 if (!get_short_pathname(&p, &pbuf3, &plen)) 19249 { 19250 vim_free(pbuf2); 19251 return -1; 19252 } 19253 *s = ch; /* Preserve the string */ 19254 } while (plen == 0); 19255 19256 if (plen > 0) 19257 { 19258 /* Remeber the length of the new string. */ 19259 *fnamelen = len = plen + slen; 19260 vim_free(*bufp); 19261 if (len > len2) 19262 { 19263 /* If there's not enough space in the currently allocated string, 19264 * then copy it to a buffer big enough. 19265 */ 19266 *fname= *bufp = vim_strnsave(p, len); 19267 if (*fname == NULL) 19268 return -1; 19269 } 19270 else 19271 { 19272 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 19273 *fname = *bufp = pbuf2; 19274 if (p != pbuf2) 19275 strncpy(*fname, p, plen); 19276 pbuf2 = NULL; 19277 } 19278 /* Concat the next bit */ 19279 strncpy(*fname + plen, s, slen); 19280 (*fname)[len] = '\0'; 19281 } 19282 vim_free(pbuf3); 19283 vim_free(pbuf2); 19284 return 0; 19285 } 19286 19287 /* 19288 * Get a pathname for a partial path. 19289 */ 19290 static int 19291 shortpath_for_partial(fnamep, bufp, fnamelen) 19292 char_u **fnamep; 19293 char_u **bufp; 19294 int *fnamelen; 19295 { 19296 int sepcount, len, tflen; 19297 char_u *p; 19298 char_u *pbuf, *tfname; 19299 int hasTilde; 19300 19301 /* Count up the path seperators from the RHS.. so we know which part 19302 * of the path to return. 19303 */ 19304 sepcount = 0; 19305 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19306 if (vim_ispathsep(*p)) 19307 ++sepcount; 19308 19309 /* Need full path first (use expand_env() to remove a "~/") */ 19310 hasTilde = (**fnamep == '~'); 19311 if (hasTilde) 19312 pbuf = tfname = expand_env_save(*fnamep); 19313 else 19314 pbuf = tfname = FullName_save(*fnamep, FALSE); 19315 19316 len = tflen = STRLEN(tfname); 19317 19318 if (!get_short_pathname(&tfname, &pbuf, &len)) 19319 return -1; 19320 19321 if (len == 0) 19322 { 19323 /* Don't have a valid filename, so shorten the rest of the 19324 * path if we can. This CAN give us invalid 8.3 filenames, but 19325 * there's not a lot of point in guessing what it might be. 19326 */ 19327 len = tflen; 19328 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19329 return -1; 19330 } 19331 19332 /* Count the paths backward to find the beginning of the desired string. */ 19333 for (p = tfname + len - 1; p >= tfname; --p) 19334 { 19335 #ifdef FEAT_MBYTE 19336 if (has_mbyte) 19337 p -= mb_head_off(tfname, p); 19338 #endif 19339 if (vim_ispathsep(*p)) 19340 { 19341 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19342 break; 19343 else 19344 sepcount --; 19345 } 19346 } 19347 if (hasTilde) 19348 { 19349 --p; 19350 if (p >= tfname) 19351 *p = '~'; 19352 else 19353 return -1; 19354 } 19355 else 19356 ++p; 19357 19358 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19359 vim_free(*bufp); 19360 *fnamelen = (int)STRLEN(p); 19361 *bufp = pbuf; 19362 *fnamep = p; 19363 19364 return 0; 19365 } 19366 #endif /* WIN3264 */ 19367 19368 /* 19369 * Adjust a filename, according to a string of modifiers. 19370 * *fnamep must be NUL terminated when called. When returning, the length is 19371 * determined by *fnamelen. 19372 * Returns valid flags. 19373 * When there is an error, *fnamep is set to NULL. 19374 */ 19375 int 19376 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19377 char_u *src; /* string with modifiers */ 19378 int *usedlen; /* characters after src that are used */ 19379 char_u **fnamep; /* file name so far */ 19380 char_u **bufp; /* buffer for allocated file name or NULL */ 19381 int *fnamelen; /* length of fnamep */ 19382 { 19383 int valid = 0; 19384 char_u *tail; 19385 char_u *s, *p, *pbuf; 19386 char_u dirname[MAXPATHL]; 19387 int c; 19388 int has_fullname = 0; 19389 #ifdef WIN3264 19390 int has_shortname = 0; 19391 #endif 19392 19393 repeat: 19394 /* ":p" - full path/file_name */ 19395 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19396 { 19397 has_fullname = 1; 19398 19399 valid |= VALID_PATH; 19400 *usedlen += 2; 19401 19402 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19403 if ((*fnamep)[0] == '~' 19404 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19405 && ((*fnamep)[1] == '/' 19406 # ifdef BACKSLASH_IN_FILENAME 19407 || (*fnamep)[1] == '\\' 19408 # endif 19409 || (*fnamep)[1] == NUL) 19410 19411 #endif 19412 ) 19413 { 19414 *fnamep = expand_env_save(*fnamep); 19415 vim_free(*bufp); /* free any allocated file name */ 19416 *bufp = *fnamep; 19417 if (*fnamep == NULL) 19418 return -1; 19419 } 19420 19421 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19422 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19423 { 19424 if (vim_ispathsep(*p) 19425 && p[1] == '.' 19426 && (p[2] == NUL 19427 || vim_ispathsep(p[2]) 19428 || (p[2] == '.' 19429 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19430 break; 19431 } 19432 19433 /* FullName_save() is slow, don't use it when not needed. */ 19434 if (*p != NUL || !vim_isAbsName(*fnamep)) 19435 { 19436 *fnamep = FullName_save(*fnamep, *p != NUL); 19437 vim_free(*bufp); /* free any allocated file name */ 19438 *bufp = *fnamep; 19439 if (*fnamep == NULL) 19440 return -1; 19441 } 19442 19443 /* Append a path separator to a directory. */ 19444 if (mch_isdir(*fnamep)) 19445 { 19446 /* Make room for one or two extra characters. */ 19447 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19448 vim_free(*bufp); /* free any allocated file name */ 19449 *bufp = *fnamep; 19450 if (*fnamep == NULL) 19451 return -1; 19452 add_pathsep(*fnamep); 19453 } 19454 } 19455 19456 /* ":." - path relative to the current directory */ 19457 /* ":~" - path relative to the home directory */ 19458 /* ":8" - shortname path - postponed till after */ 19459 while (src[*usedlen] == ':' 19460 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19461 { 19462 *usedlen += 2; 19463 if (c == '8') 19464 { 19465 #ifdef WIN3264 19466 has_shortname = 1; /* Postpone this. */ 19467 #endif 19468 continue; 19469 } 19470 pbuf = NULL; 19471 /* Need full path first (use expand_env() to remove a "~/") */ 19472 if (!has_fullname) 19473 { 19474 if (c == '.' && **fnamep == '~') 19475 p = pbuf = expand_env_save(*fnamep); 19476 else 19477 p = pbuf = FullName_save(*fnamep, FALSE); 19478 } 19479 else 19480 p = *fnamep; 19481 19482 has_fullname = 0; 19483 19484 if (p != NULL) 19485 { 19486 if (c == '.') 19487 { 19488 mch_dirname(dirname, MAXPATHL); 19489 s = shorten_fname(p, dirname); 19490 if (s != NULL) 19491 { 19492 *fnamep = s; 19493 if (pbuf != NULL) 19494 { 19495 vim_free(*bufp); /* free any allocated file name */ 19496 *bufp = pbuf; 19497 pbuf = NULL; 19498 } 19499 } 19500 } 19501 else 19502 { 19503 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19504 /* Only replace it when it starts with '~' */ 19505 if (*dirname == '~') 19506 { 19507 s = vim_strsave(dirname); 19508 if (s != NULL) 19509 { 19510 *fnamep = s; 19511 vim_free(*bufp); 19512 *bufp = s; 19513 } 19514 } 19515 } 19516 vim_free(pbuf); 19517 } 19518 } 19519 19520 tail = gettail(*fnamep); 19521 *fnamelen = (int)STRLEN(*fnamep); 19522 19523 /* ":h" - head, remove "/file_name", can be repeated */ 19524 /* Don't remove the first "/" or "c:\" */ 19525 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19526 { 19527 valid |= VALID_HEAD; 19528 *usedlen += 2; 19529 s = get_past_head(*fnamep); 19530 while (tail > s && after_pathsep(s, tail)) 19531 --tail; 19532 *fnamelen = (int)(tail - *fnamep); 19533 #ifdef VMS 19534 if (*fnamelen > 0) 19535 *fnamelen += 1; /* the path separator is part of the path */ 19536 #endif 19537 while (tail > s && !after_pathsep(s, tail)) 19538 mb_ptr_back(*fnamep, tail); 19539 } 19540 19541 /* ":8" - shortname */ 19542 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19543 { 19544 *usedlen += 2; 19545 #ifdef WIN3264 19546 has_shortname = 1; 19547 #endif 19548 } 19549 19550 #ifdef WIN3264 19551 /* Check shortname after we have done 'heads' and before we do 'tails' 19552 */ 19553 if (has_shortname) 19554 { 19555 pbuf = NULL; 19556 /* Copy the string if it is shortened by :h */ 19557 if (*fnamelen < (int)STRLEN(*fnamep)) 19558 { 19559 p = vim_strnsave(*fnamep, *fnamelen); 19560 if (p == 0) 19561 return -1; 19562 vim_free(*bufp); 19563 *bufp = *fnamep = p; 19564 } 19565 19566 /* Split into two implementations - makes it easier. First is where 19567 * there isn't a full name already, second is where there is. 19568 */ 19569 if (!has_fullname && !vim_isAbsName(*fnamep)) 19570 { 19571 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19572 return -1; 19573 } 19574 else 19575 { 19576 int l; 19577 19578 /* Simple case, already have the full-name 19579 * Nearly always shorter, so try first time. */ 19580 l = *fnamelen; 19581 if (!get_short_pathname(fnamep, bufp, &l)) 19582 return -1; 19583 19584 if (l == 0) 19585 { 19586 /* Couldn't find the filename.. search the paths. 19587 */ 19588 l = *fnamelen; 19589 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19590 return -1; 19591 } 19592 *fnamelen = l; 19593 } 19594 } 19595 #endif /* WIN3264 */ 19596 19597 /* ":t" - tail, just the basename */ 19598 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19599 { 19600 *usedlen += 2; 19601 *fnamelen -= (int)(tail - *fnamep); 19602 *fnamep = tail; 19603 } 19604 19605 /* ":e" - extension, can be repeated */ 19606 /* ":r" - root, without extension, can be repeated */ 19607 while (src[*usedlen] == ':' 19608 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19609 { 19610 /* find a '.' in the tail: 19611 * - for second :e: before the current fname 19612 * - otherwise: The last '.' 19613 */ 19614 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19615 s = *fnamep - 2; 19616 else 19617 s = *fnamep + *fnamelen - 1; 19618 for ( ; s > tail; --s) 19619 if (s[0] == '.') 19620 break; 19621 if (src[*usedlen + 1] == 'e') /* :e */ 19622 { 19623 if (s > tail) 19624 { 19625 *fnamelen += (int)(*fnamep - (s + 1)); 19626 *fnamep = s + 1; 19627 #ifdef VMS 19628 /* cut version from the extension */ 19629 s = *fnamep + *fnamelen - 1; 19630 for ( ; s > *fnamep; --s) 19631 if (s[0] == ';') 19632 break; 19633 if (s > *fnamep) 19634 *fnamelen = s - *fnamep; 19635 #endif 19636 } 19637 else if (*fnamep <= tail) 19638 *fnamelen = 0; 19639 } 19640 else /* :r */ 19641 { 19642 if (s > tail) /* remove one extension */ 19643 *fnamelen = (int)(s - *fnamep); 19644 } 19645 *usedlen += 2; 19646 } 19647 19648 /* ":s?pat?foo?" - substitute */ 19649 /* ":gs?pat?foo?" - global substitute */ 19650 if (src[*usedlen] == ':' 19651 && (src[*usedlen + 1] == 's' 19652 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19653 { 19654 char_u *str; 19655 char_u *pat; 19656 char_u *sub; 19657 int sep; 19658 char_u *flags; 19659 int didit = FALSE; 19660 19661 flags = (char_u *)""; 19662 s = src + *usedlen + 2; 19663 if (src[*usedlen + 1] == 'g') 19664 { 19665 flags = (char_u *)"g"; 19666 ++s; 19667 } 19668 19669 sep = *s++; 19670 if (sep) 19671 { 19672 /* find end of pattern */ 19673 p = vim_strchr(s, sep); 19674 if (p != NULL) 19675 { 19676 pat = vim_strnsave(s, (int)(p - s)); 19677 if (pat != NULL) 19678 { 19679 s = p + 1; 19680 /* find end of substitution */ 19681 p = vim_strchr(s, sep); 19682 if (p != NULL) 19683 { 19684 sub = vim_strnsave(s, (int)(p - s)); 19685 str = vim_strnsave(*fnamep, *fnamelen); 19686 if (sub != NULL && str != NULL) 19687 { 19688 *usedlen = (int)(p + 1 - src); 19689 s = do_string_sub(str, pat, sub, flags); 19690 if (s != NULL) 19691 { 19692 *fnamep = s; 19693 *fnamelen = (int)STRLEN(s); 19694 vim_free(*bufp); 19695 *bufp = s; 19696 didit = TRUE; 19697 } 19698 } 19699 vim_free(sub); 19700 vim_free(str); 19701 } 19702 vim_free(pat); 19703 } 19704 } 19705 /* after using ":s", repeat all the modifiers */ 19706 if (didit) 19707 goto repeat; 19708 } 19709 } 19710 19711 return valid; 19712 } 19713 19714 /* 19715 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19716 * "flags" can be "g" to do a global substitute. 19717 * Returns an allocated string, NULL for error. 19718 */ 19719 char_u * 19720 do_string_sub(str, pat, sub, flags) 19721 char_u *str; 19722 char_u *pat; 19723 char_u *sub; 19724 char_u *flags; 19725 { 19726 int sublen; 19727 regmatch_T regmatch; 19728 int i; 19729 int do_all; 19730 char_u *tail; 19731 garray_T ga; 19732 char_u *ret; 19733 char_u *save_cpo; 19734 19735 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19736 save_cpo = p_cpo; 19737 p_cpo = (char_u *)""; 19738 19739 ga_init2(&ga, 1, 200); 19740 19741 do_all = (flags[0] == 'g'); 19742 19743 regmatch.rm_ic = p_ic; 19744 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19745 if (regmatch.regprog != NULL) 19746 { 19747 tail = str; 19748 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19749 { 19750 /* 19751 * Get some space for a temporary buffer to do the substitution 19752 * into. It will contain: 19753 * - The text up to where the match is. 19754 * - The substituted text. 19755 * - The text after the match. 19756 */ 19757 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19758 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19759 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19760 { 19761 ga_clear(&ga); 19762 break; 19763 } 19764 19765 /* copy the text up to where the match is */ 19766 i = (int)(regmatch.startp[0] - tail); 19767 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19768 /* add the substituted text */ 19769 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19770 + ga.ga_len + i, TRUE, TRUE, FALSE); 19771 ga.ga_len += i + sublen - 1; 19772 /* avoid getting stuck on a match with an empty string */ 19773 if (tail == regmatch.endp[0]) 19774 { 19775 if (*tail == NUL) 19776 break; 19777 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19778 ++ga.ga_len; 19779 } 19780 else 19781 { 19782 tail = regmatch.endp[0]; 19783 if (*tail == NUL) 19784 break; 19785 } 19786 if (!do_all) 19787 break; 19788 } 19789 19790 if (ga.ga_data != NULL) 19791 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19792 19793 vim_free(regmatch.regprog); 19794 } 19795 19796 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19797 ga_clear(&ga); 19798 p_cpo = save_cpo; 19799 19800 return ret; 19801 } 19802 19803 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19804