1 /* vi:set ts=8 sts=4 sw=4: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * eval.c: Expression evaluation. 12 */ 13 #if defined(MSDOS) || defined(MSWIN) 14 # include "vimio.h" /* for mch_open(), must be before vim.h */ 15 #endif 16 17 #include "vim.h" 18 19 #ifdef AMIGA 20 # include <time.h> /* for strftime() */ 21 #endif 22 23 #ifdef MACOS 24 # include <time.h> /* for time_t */ 25 #endif 26 27 #ifdef HAVE_FCNTL_H 28 # include <fcntl.h> 29 #endif 30 31 #if defined(FEAT_EVAL) || defined(PROTO) 32 33 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ 34 35 /* 36 * In a hashtab item "hi_key" points to "di_key" in a dictitem. 37 * This avoids adding a pointer to the hashtab item. 38 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. 39 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. 40 * HI2DI() converts a hashitem pointer to a dictitem pointer. 41 */ 42 static dictitem_T dumdi; 43 #define DI2HIKEY(di) ((di)->di_key) 44 #define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) 45 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) 46 47 /* 48 * Structure returned by get_lval() and used by set_var_lval(). 49 * For a plain name: 50 * "name" points to the variable name. 51 * "exp_name" is NULL. 52 * "tv" is NULL 53 * For a magic braces name: 54 * "name" points to the expanded variable name. 55 * "exp_name" is non-NULL, to be freed later. 56 * "tv" is NULL 57 * For an index in a list: 58 * "name" points to the (expanded) variable name. 59 * "exp_name" NULL or non-NULL, to be freed later. 60 * "tv" points to the (first) list item value 61 * "li" points to the (first) list item 62 * "range", "n1", "n2" and "empty2" indicate what items are used. 63 * For an existing Dict item: 64 * "name" points to the (expanded) variable name. 65 * "exp_name" NULL or non-NULL, to be freed later. 66 * "tv" points to the dict item value 67 * "newkey" is NULL 68 * For a non-existing Dict item: 69 * "name" points to the (expanded) variable name. 70 * "exp_name" NULL or non-NULL, to be freed later. 71 * "tv" points to the Dictionary typval_T 72 * "newkey" is the key for the new item. 73 */ 74 typedef struct lval_S 75 { 76 char_u *ll_name; /* start of variable name (can be NULL) */ 77 char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ 78 typval_T *ll_tv; /* Typeval of item being used. If "newkey" 79 isn't NULL it's the Dict to which to add 80 the item. */ 81 listitem_T *ll_li; /* The list item or NULL. */ 82 list_T *ll_list; /* The list or NULL. */ 83 int ll_range; /* TRUE when a [i:j] range was used */ 84 long ll_n1; /* First index for list */ 85 long ll_n2; /* Second index for list range */ 86 int ll_empty2; /* Second index is empty: [i:] */ 87 dict_T *ll_dict; /* The Dictionary or NULL */ 88 dictitem_T *ll_di; /* The dictitem or NULL */ 89 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 90 } lval_T; 91 92 93 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 94 static char *e_listidx = N_("E684: list index out of range: %ld"); 95 static char *e_undefvar = N_("E121: Undefined variable: %s"); 96 static char *e_missbrac = N_("E111: Missing ']'"); 97 static char *e_listarg = N_("E686: Argument of %s must be a List"); 98 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); 99 static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary"); 100 static char *e_listreq = N_("E714: List required"); 101 static char *e_dictreq = N_("E715: Dictionary required"); 102 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 103 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 104 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 105 static char *e_funcdict = N_("E717: Dictionary entry already exists"); 106 static char *e_funcref = N_("E718: Funcref required"); 107 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 108 static char *e_letwrong = N_("E734: Wrong variable type for %s="); 109 static char *e_nofunc = N_("E130: Unknown function: %s"); 110 static char *e_illvar = N_("E461: Illegal variable name: %s"); 111 /* 112 * All user-defined global variables are stored in dictionary "globvardict". 113 * "globvars_var" is the variable that is used for "g:". 114 */ 115 static dict_T globvardict; 116 static dictitem_T globvars_var; 117 #define globvarht globvardict.dv_hashtab 118 119 /* 120 * Old Vim variables such as "v:version" are also available without the "v:". 121 * Also in functions. We need a special hashtable for them. 122 */ 123 static hashtab_T compat_hashtab; 124 125 /* 126 * When recursively copying lists and dicts we need to remember which ones we 127 * have done to avoid endless recursiveness. This unique ID is used for that. 128 */ 129 static int current_copyID = 0; 130 131 /* 132 * Array to hold the hashtab with variables local to each sourced script. 133 * Each item holds a variable (nameless) that points to the dict_T. 134 */ 135 typedef struct 136 { 137 dictitem_T sv_var; 138 dict_T sv_dict; 139 } scriptvar_T; 140 141 static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T), 4, NULL}; 142 #define SCRIPT_SV(id) (((scriptvar_T *)ga_scripts.ga_data)[(id) - 1]) 143 #define SCRIPT_VARS(id) (SCRIPT_SV(id).sv_dict.dv_hashtab) 144 145 static int echo_attr = 0; /* attributes used for ":echo" */ 146 147 /* Values for trans_function_name() argument: */ 148 #define TFN_INT 1 /* internal function name OK */ 149 #define TFN_QUIET 2 /* no error messages */ 150 151 /* 152 * Structure to hold info for a user function. 153 */ 154 typedef struct ufunc ufunc_T; 155 156 struct ufunc 157 { 158 int uf_varargs; /* variable nr of arguments */ 159 int uf_flags; 160 int uf_calls; /* nr of active calls */ 161 garray_T uf_args; /* arguments */ 162 garray_T uf_lines; /* function lines */ 163 #ifdef FEAT_PROFILE 164 int uf_profiling; /* TRUE when func is being profiled */ 165 /* profiling the function as a whole */ 166 int uf_tm_count; /* nr of calls */ 167 proftime_T uf_tm_total; /* time spend in function + children */ 168 proftime_T uf_tm_self; /* time spend in function itself */ 169 proftime_T uf_tm_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 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 344 }; 345 346 /* shorthand */ 347 #define vv_type vv_di.di_tv.v_type 348 #define vv_nr vv_di.di_tv.vval.v_number 349 #define vv_str vv_di.di_tv.vval.v_string 350 #define vv_tv vv_di.di_tv 351 352 /* 353 * The v: variables are stored in dictionary "vimvardict". 354 * "vimvars_var" is the variable that is used for the "l:" scope. 355 */ 356 static dict_T vimvardict; 357 static dictitem_T vimvars_var; 358 #define vimvarht vimvardict.dv_hashtab 359 360 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 361 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 362 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 363 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 364 #endif 365 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 366 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 367 static char_u *skip_var_one __ARGS((char_u *arg)); 368 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 369 static void list_glob_vars __ARGS((void)); 370 static void list_buf_vars __ARGS((void)); 371 static void list_win_vars __ARGS((void)); 372 #ifdef FEAT_WINDOWS 373 static void list_tab_vars __ARGS((void)); 374 #endif 375 static void list_vim_vars __ARGS((void)); 376 static void list_script_vars __ARGS((void)); 377 static void list_func_vars __ARGS((void)); 378 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 379 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 380 static int check_changedtick __ARGS((char_u *arg)); 381 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 382 static void clear_lval __ARGS((lval_T *lp)); 383 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 384 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 385 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 386 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 387 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 388 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 389 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 390 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 391 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 392 static int tv_islocked __ARGS((typval_T *tv)); 393 394 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 395 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 396 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 397 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 398 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 399 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 400 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 401 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 402 403 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 404 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 405 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 406 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 407 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 408 static int rettv_list_alloc __ARGS((typval_T *rettv)); 409 static listitem_T *listitem_alloc __ARGS((void)); 410 static void listitem_free __ARGS((listitem_T *item)); 411 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 412 static long list_len __ARGS((list_T *l)); 413 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 414 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 415 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 416 static listitem_T *list_find __ARGS((list_T *l, long n)); 417 static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); 418 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 419 static void list_append __ARGS((list_T *l, listitem_T *item)); 420 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 421 static int list_append_string __ARGS((list_T *l, char_u *str, int len)); 422 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 423 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 424 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 425 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 426 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 427 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 428 static char_u *list2string __ARGS((typval_T *tv, int copyID)); 429 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 430 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 431 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 432 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 433 static void dict_unref __ARGS((dict_T *d)); 434 static void dict_free __ARGS((dict_T *d)); 435 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 436 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 437 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 438 static void dictitem_free __ARGS((dictitem_T *item)); 439 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 440 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 441 static long dict_len __ARGS((dict_T *d)); 442 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 443 static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 444 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 445 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 446 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 447 static char_u *string_quote __ARGS((char_u *str, int function)); 448 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 449 static int find_internal_func __ARGS((char_u *name)); 450 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 451 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)); 452 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)); 453 static void emsg_funcname __ARGS((char *msg, char_u *name)); 454 455 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 468 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 469 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 475 #if defined(FEAT_INS_EXPAND) 476 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 479 #endif 480 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 485 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 580 #ifdef vim_mkdir 581 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 582 #endif 583 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv)); 627 #ifdef HAVE_STRFTIME 628 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 629 #endif 630 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 636 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 637 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 640 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 641 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 642 static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 643 static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 644 static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 645 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 646 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 647 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 648 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 649 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 650 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 651 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 652 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 653 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 654 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 655 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 656 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 657 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 658 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 659 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 660 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 661 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 662 static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 663 static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 664 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 665 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 666 667 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); 668 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum)); 669 static int get_env_len __ARGS((char_u **arg)); 670 static int get_id_len __ARGS((char_u **arg)); 671 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 672 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 673 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 674 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 675 valid character */ 676 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 677 static int eval_isnamec __ARGS((int c)); 678 static int eval_isnamec1 __ARGS((int c)); 679 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 680 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 681 static typval_T *alloc_tv __ARGS((void)); 682 static typval_T *alloc_string_tv __ARGS((char_u *string)); 683 static void init_tv __ARGS((typval_T *varp)); 684 static long get_tv_number __ARGS((typval_T *varp)); 685 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 686 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 687 static char_u *get_tv_string __ARGS((typval_T *varp)); 688 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 689 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 690 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 691 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 692 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 693 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 694 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 695 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 696 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 697 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 698 static int var_check_ro __ARGS((int flags, char_u *name)); 699 static int tv_check_lock __ARGS((int lock, char_u *name)); 700 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 701 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 702 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 703 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 704 static int eval_fname_script __ARGS((char_u *p)); 705 static int eval_fname_sid __ARGS((char_u *p)); 706 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 707 static ufunc_T *find_func __ARGS((char_u *name)); 708 static int function_exists __ARGS((char_u *name)); 709 static int builtin_function __ARGS((char_u *name)); 710 #ifdef FEAT_PROFILE 711 static void func_do_profile __ARGS((ufunc_T *fp)); 712 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 713 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 714 static int 715 # ifdef __BORLANDC__ 716 _RTLENTRYF 717 # endif 718 prof_total_cmp __ARGS((const void *s1, const void *s2)); 719 static int 720 # ifdef __BORLANDC__ 721 _RTLENTRYF 722 # endif 723 prof_self_cmp __ARGS((const void *s1, const void *s2)); 724 #endif 725 static int script_autoload __ARGS((char_u *name, int reload)); 726 static char_u *autoload_name __ARGS((char_u *name)); 727 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 728 static void func_free __ARGS((ufunc_T *fp)); 729 static void func_unref __ARGS((char_u *name)); 730 static void func_ref __ARGS((char_u *name)); 731 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)); 732 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 733 static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); 734 static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 735 static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 736 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 737 static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 738 739 /* Character used as separated in autoload function/variable names. */ 740 #define AUTOLOAD_CHAR '#' 741 742 /* 743 * Initialize the global and v: variables. 744 */ 745 void 746 eval_init() 747 { 748 int i; 749 struct vimvar *p; 750 751 init_var_dict(&globvardict, &globvars_var); 752 init_var_dict(&vimvardict, &vimvars_var); 753 hash_init(&compat_hashtab); 754 hash_init(&func_hashtab); 755 756 for (i = 0; i < VV_LEN; ++i) 757 { 758 p = &vimvars[i]; 759 STRCPY(p->vv_di.di_key, p->vv_name); 760 if (p->vv_flags & VV_RO) 761 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 762 else if (p->vv_flags & VV_RO_SBX) 763 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 764 else 765 p->vv_di.di_flags = DI_FLAGS_FIX; 766 767 /* add to v: scope dict, unless the value is not always available */ 768 if (p->vv_type != VAR_UNKNOWN) 769 hash_add(&vimvarht, p->vv_di.di_key); 770 if (p->vv_flags & VV_COMPAT) 771 /* add to compat scope dict */ 772 hash_add(&compat_hashtab, p->vv_di.di_key); 773 } 774 } 775 776 #if defined(EXITFREE) || defined(PROTO) 777 void 778 eval_clear() 779 { 780 int i; 781 struct vimvar *p; 782 783 for (i = 0; i < VV_LEN; ++i) 784 { 785 p = &vimvars[i]; 786 if (p->vv_di.di_tv.v_type == VAR_STRING) 787 { 788 vim_free(p->vv_di.di_tv.vval.v_string); 789 p->vv_di.di_tv.vval.v_string = NULL; 790 } 791 } 792 hash_clear(&vimvarht); 793 hash_clear(&compat_hashtab); 794 795 /* script-local variables */ 796 for (i = 1; i <= ga_scripts.ga_len; ++i) 797 vars_clear(&SCRIPT_VARS(i)); 798 ga_clear(&ga_scripts); 799 free_scriptnames(); 800 801 /* global variables */ 802 vars_clear(&globvarht); 803 804 /* functions */ 805 free_all_functions(); 806 hash_clear(&func_hashtab); 807 808 /* unreferenced lists and dicts */ 809 (void)garbage_collect(); 810 } 811 #endif 812 813 /* 814 * Return the name of the executed function. 815 */ 816 char_u * 817 func_name(cookie) 818 void *cookie; 819 { 820 return ((funccall_T *)cookie)->func->uf_name; 821 } 822 823 /* 824 * Return the address holding the next breakpoint line for a funccall cookie. 825 */ 826 linenr_T * 827 func_breakpoint(cookie) 828 void *cookie; 829 { 830 return &((funccall_T *)cookie)->breakpoint; 831 } 832 833 /* 834 * Return the address holding the debug tick for a funccall cookie. 835 */ 836 int * 837 func_dbg_tick(cookie) 838 void *cookie; 839 { 840 return &((funccall_T *)cookie)->dbg_tick; 841 } 842 843 /* 844 * Return the nesting level for a funccall cookie. 845 */ 846 int 847 func_level(cookie) 848 void *cookie; 849 { 850 return ((funccall_T *)cookie)->level; 851 } 852 853 /* pointer to funccal for currently active function */ 854 funccall_T *current_funccal = NULL; 855 856 /* 857 * Return TRUE when a function was ended by a ":return" command. 858 */ 859 int 860 current_func_returned() 861 { 862 return current_funccal->returned; 863 } 864 865 866 /* 867 * Set an internal variable to a string value. Creates the variable if it does 868 * not already exist. 869 */ 870 void 871 set_internal_string_var(name, value) 872 char_u *name; 873 char_u *value; 874 { 875 char_u *val; 876 typval_T *tvp; 877 878 val = vim_strsave(value); 879 if (val != NULL) 880 { 881 tvp = alloc_string_tv(val); 882 if (tvp != NULL) 883 { 884 set_var(name, tvp, FALSE); 885 free_tv(tvp); 886 } 887 } 888 } 889 890 static lval_T *redir_lval = NULL; 891 static char_u *redir_endp = NULL; 892 static char_u *redir_varname = NULL; 893 894 /* 895 * Start recording command output to a variable 896 * Returns OK if successfully completed the setup. FAIL otherwise. 897 */ 898 int 899 var_redir_start(name, append) 900 char_u *name; 901 int append; /* append to an existing variable */ 902 { 903 int save_emsg; 904 int err; 905 typval_T tv; 906 907 /* Make sure a valid variable name is specified */ 908 if (!eval_isnamec1(*name)) 909 { 910 EMSG(_(e_invarg)); 911 return FAIL; 912 } 913 914 redir_varname = vim_strsave(name); 915 if (redir_varname == NULL) 916 return FAIL; 917 918 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 919 if (redir_lval == NULL) 920 { 921 var_redir_stop(); 922 return FAIL; 923 } 924 925 /* Parse the variable name (can be a dict or list entry). */ 926 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 927 FNE_CHECK_START); 928 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 929 { 930 if (redir_endp != NULL && *redir_endp != NUL) 931 /* Trailing characters are present after the variable name */ 932 EMSG(_(e_trailing)); 933 else 934 EMSG(_(e_invarg)); 935 var_redir_stop(); 936 return FAIL; 937 } 938 939 /* check if we can write to the variable: set it to or append an empty 940 * string */ 941 save_emsg = did_emsg; 942 did_emsg = FALSE; 943 tv.v_type = VAR_STRING; 944 tv.vval.v_string = (char_u *)""; 945 if (append) 946 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 947 else 948 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 949 err = did_emsg; 950 did_emsg |= save_emsg; 951 if (err) 952 { 953 var_redir_stop(); 954 return FAIL; 955 } 956 if (redir_lval->ll_newkey != NULL) 957 { 958 /* Dictionary item was created, don't do it again. */ 959 vim_free(redir_lval->ll_newkey); 960 redir_lval->ll_newkey = NULL; 961 } 962 963 return OK; 964 } 965 966 /* 967 * Append "value[len]" to the variable set by var_redir_start(). 968 */ 969 void 970 var_redir_str(value, len) 971 char_u *value; 972 int len; 973 { 974 char_u *val; 975 typval_T tv; 976 int save_emsg; 977 int err; 978 979 if (redir_lval == NULL) 980 return; 981 982 if (len == -1) 983 /* Append the entire string */ 984 val = vim_strsave(value); 985 else 986 /* Append only the specified number of characters */ 987 val = vim_strnsave(value, len); 988 if (val == NULL) 989 return; 990 991 tv.v_type = VAR_STRING; 992 tv.vval.v_string = val; 993 994 save_emsg = did_emsg; 995 did_emsg = FALSE; 996 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 997 err = did_emsg; 998 did_emsg |= save_emsg; 999 if (err) 1000 var_redir_stop(); 1001 1002 vim_free(tv.vval.v_string); 1003 } 1004 1005 /* 1006 * Stop redirecting command output to a variable. 1007 */ 1008 void 1009 var_redir_stop() 1010 { 1011 if (redir_lval != NULL) 1012 { 1013 clear_lval(redir_lval); 1014 vim_free(redir_lval); 1015 redir_lval = NULL; 1016 } 1017 vim_free(redir_varname); 1018 redir_varname = NULL; 1019 } 1020 1021 # if defined(FEAT_MBYTE) || defined(PROTO) 1022 int 1023 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1024 char_u *enc_from; 1025 char_u *enc_to; 1026 char_u *fname_from; 1027 char_u *fname_to; 1028 { 1029 int err = FALSE; 1030 1031 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1032 set_vim_var_string(VV_CC_TO, enc_to, -1); 1033 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1034 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1035 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1036 err = TRUE; 1037 set_vim_var_string(VV_CC_FROM, NULL, -1); 1038 set_vim_var_string(VV_CC_TO, NULL, -1); 1039 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1040 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1041 1042 if (err) 1043 return FAIL; 1044 return OK; 1045 } 1046 # endif 1047 1048 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1049 int 1050 eval_printexpr(fname, args) 1051 char_u *fname; 1052 char_u *args; 1053 { 1054 int err = FALSE; 1055 1056 set_vim_var_string(VV_FNAME_IN, fname, -1); 1057 set_vim_var_string(VV_CMDARG, args, -1); 1058 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1059 err = TRUE; 1060 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1061 set_vim_var_string(VV_CMDARG, NULL, -1); 1062 1063 if (err) 1064 { 1065 mch_remove(fname); 1066 return FAIL; 1067 } 1068 return OK; 1069 } 1070 # endif 1071 1072 # if defined(FEAT_DIFF) || defined(PROTO) 1073 void 1074 eval_diff(origfile, newfile, outfile) 1075 char_u *origfile; 1076 char_u *newfile; 1077 char_u *outfile; 1078 { 1079 int err = FALSE; 1080 1081 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1082 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1083 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1084 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1085 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1086 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1087 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1088 } 1089 1090 void 1091 eval_patch(origfile, difffile, outfile) 1092 char_u *origfile; 1093 char_u *difffile; 1094 char_u *outfile; 1095 { 1096 int err; 1097 1098 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1099 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1100 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1101 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1102 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1103 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1104 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1105 } 1106 # endif 1107 1108 /* 1109 * Top level evaluation function, returning a boolean. 1110 * Sets "error" to TRUE if there was an error. 1111 * Return TRUE or FALSE. 1112 */ 1113 int 1114 eval_to_bool(arg, error, nextcmd, skip) 1115 char_u *arg; 1116 int *error; 1117 char_u **nextcmd; 1118 int skip; /* only parse, don't execute */ 1119 { 1120 typval_T tv; 1121 int retval = FALSE; 1122 1123 if (skip) 1124 ++emsg_skip; 1125 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1126 *error = TRUE; 1127 else 1128 { 1129 *error = FALSE; 1130 if (!skip) 1131 { 1132 retval = (get_tv_number_chk(&tv, error) != 0); 1133 clear_tv(&tv); 1134 } 1135 } 1136 if (skip) 1137 --emsg_skip; 1138 1139 return retval; 1140 } 1141 1142 /* 1143 * Top level evaluation function, returning a string. If "skip" is TRUE, 1144 * only parsing to "nextcmd" is done, without reporting errors. Return 1145 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1146 */ 1147 char_u * 1148 eval_to_string_skip(arg, nextcmd, skip) 1149 char_u *arg; 1150 char_u **nextcmd; 1151 int skip; /* only parse, don't execute */ 1152 { 1153 typval_T tv; 1154 char_u *retval; 1155 1156 if (skip) 1157 ++emsg_skip; 1158 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1159 retval = NULL; 1160 else 1161 { 1162 retval = vim_strsave(get_tv_string(&tv)); 1163 clear_tv(&tv); 1164 } 1165 if (skip) 1166 --emsg_skip; 1167 1168 return retval; 1169 } 1170 1171 /* 1172 * Skip over an expression at "*pp". 1173 * Return FAIL for an error, OK otherwise. 1174 */ 1175 int 1176 skip_expr(pp) 1177 char_u **pp; 1178 { 1179 typval_T rettv; 1180 1181 *pp = skipwhite(*pp); 1182 return eval1(pp, &rettv, FALSE); 1183 } 1184 1185 /* 1186 * Top level evaluation function, returning a string. 1187 * Return pointer to allocated memory, or NULL for failure. 1188 */ 1189 char_u * 1190 eval_to_string(arg, nextcmd, dolist) 1191 char_u *arg; 1192 char_u **nextcmd; 1193 int dolist; /* turn List into sequence of lines */ 1194 { 1195 typval_T tv; 1196 char_u *retval; 1197 garray_T ga; 1198 1199 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1200 retval = NULL; 1201 else 1202 { 1203 if (dolist && tv.v_type == VAR_LIST) 1204 { 1205 ga_init2(&ga, (int)sizeof(char), 80); 1206 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1207 ga_append(&ga, NUL); 1208 retval = (char_u *)ga.ga_data; 1209 } 1210 else 1211 retval = vim_strsave(get_tv_string(&tv)); 1212 clear_tv(&tv); 1213 } 1214 1215 return retval; 1216 } 1217 1218 /* 1219 * Call eval_to_string() without using current local variables and using 1220 * textlock. When "use_sandbox" is TRUE use the sandbox. 1221 */ 1222 char_u * 1223 eval_to_string_safe(arg, nextcmd, use_sandbox) 1224 char_u *arg; 1225 char_u **nextcmd; 1226 int use_sandbox; 1227 { 1228 char_u *retval; 1229 void *save_funccalp; 1230 1231 save_funccalp = save_funccal(); 1232 if (use_sandbox) 1233 ++sandbox; 1234 ++textlock; 1235 retval = eval_to_string(arg, nextcmd, FALSE); 1236 if (use_sandbox) 1237 --sandbox; 1238 --textlock; 1239 restore_funccal(save_funccalp); 1240 return retval; 1241 } 1242 1243 /* 1244 * Top level evaluation function, returning a number. 1245 * Evaluates "expr" silently. 1246 * Returns -1 for an error. 1247 */ 1248 int 1249 eval_to_number(expr) 1250 char_u *expr; 1251 { 1252 typval_T rettv; 1253 int retval; 1254 char_u *p = skipwhite(expr); 1255 1256 ++emsg_off; 1257 1258 if (eval1(&p, &rettv, TRUE) == FAIL) 1259 retval = -1; 1260 else 1261 { 1262 retval = get_tv_number_chk(&rettv, NULL); 1263 clear_tv(&rettv); 1264 } 1265 --emsg_off; 1266 1267 return retval; 1268 } 1269 1270 /* 1271 * Prepare v: variable "idx" to be used. 1272 * Save the current typeval in "save_tv". 1273 * When not used yet add the variable to the v: hashtable. 1274 */ 1275 static void 1276 prepare_vimvar(idx, save_tv) 1277 int idx; 1278 typval_T *save_tv; 1279 { 1280 *save_tv = vimvars[idx].vv_tv; 1281 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1282 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1283 } 1284 1285 /* 1286 * Restore v: variable "idx" to typeval "save_tv". 1287 * When no longer defined, remove the variable from the v: hashtable. 1288 */ 1289 static void 1290 restore_vimvar(idx, save_tv) 1291 int idx; 1292 typval_T *save_tv; 1293 { 1294 hashitem_T *hi; 1295 1296 clear_tv(&vimvars[idx].vv_tv); 1297 vimvars[idx].vv_tv = *save_tv; 1298 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1299 { 1300 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1301 if (HASHITEM_EMPTY(hi)) 1302 EMSG2(_(e_intern2), "restore_vimvar()"); 1303 else 1304 hash_remove(&vimvarht, hi); 1305 } 1306 } 1307 1308 #if defined(FEAT_SPELL) || defined(PROTO) 1309 /* 1310 * Evaluate an expression to a list with suggestions. 1311 * For the "expr:" part of 'spellsuggest'. 1312 */ 1313 list_T * 1314 eval_spell_expr(badword, expr) 1315 char_u *badword; 1316 char_u *expr; 1317 { 1318 typval_T save_val; 1319 typval_T rettv; 1320 list_T *list = NULL; 1321 char_u *p = skipwhite(expr); 1322 1323 /* Set "v:val" to the bad word. */ 1324 prepare_vimvar(VV_VAL, &save_val); 1325 vimvars[VV_VAL].vv_type = VAR_STRING; 1326 vimvars[VV_VAL].vv_str = badword; 1327 if (p_verbose == 0) 1328 ++emsg_off; 1329 1330 if (eval1(&p, &rettv, TRUE) == OK) 1331 { 1332 if (rettv.v_type != VAR_LIST) 1333 clear_tv(&rettv); 1334 else 1335 list = rettv.vval.v_list; 1336 } 1337 1338 if (p_verbose == 0) 1339 --emsg_off; 1340 vimvars[VV_VAL].vv_str = NULL; 1341 restore_vimvar(VV_VAL, &save_val); 1342 1343 return list; 1344 } 1345 1346 /* 1347 * "list" is supposed to contain two items: a word and a number. Return the 1348 * word in "pp" and the number as the return value. 1349 * Return -1 if anything isn't right. 1350 * Used to get the good word and score from the eval_spell_expr() result. 1351 */ 1352 int 1353 get_spellword(list, pp) 1354 list_T *list; 1355 char_u **pp; 1356 { 1357 listitem_T *li; 1358 1359 li = list->lv_first; 1360 if (li == NULL) 1361 return -1; 1362 *pp = get_tv_string(&li->li_tv); 1363 1364 li = li->li_next; 1365 if (li == NULL) 1366 return -1; 1367 return get_tv_number(&li->li_tv); 1368 } 1369 #endif 1370 1371 /* 1372 * Top level evaluation function. 1373 * Returns an allocated typval_T with the result. 1374 * Returns NULL when there is an error. 1375 */ 1376 typval_T * 1377 eval_expr(arg, nextcmd) 1378 char_u *arg; 1379 char_u **nextcmd; 1380 { 1381 typval_T *tv; 1382 1383 tv = (typval_T *)alloc(sizeof(typval_T)); 1384 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1385 { 1386 vim_free(tv); 1387 tv = NULL; 1388 } 1389 1390 return tv; 1391 } 1392 1393 1394 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1395 /* 1396 * Call some vimL function and return the result in "*rettv". 1397 * Uses argv[argc] for the function arguments. 1398 * Returns OK or FAIL. 1399 */ 1400 static int 1401 call_vim_function(func, argc, argv, safe, rettv) 1402 char_u *func; 1403 int argc; 1404 char_u **argv; 1405 int safe; /* use the sandbox */ 1406 typval_T *rettv; 1407 { 1408 typval_T *argvars; 1409 long n; 1410 int len; 1411 int i; 1412 int doesrange; 1413 void *save_funccalp = NULL; 1414 int ret; 1415 1416 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1417 if (argvars == NULL) 1418 return FAIL; 1419 1420 for (i = 0; i < argc; i++) 1421 { 1422 /* Pass a NULL or empty argument as an empty string */ 1423 if (argv[i] == NULL || *argv[i] == NUL) 1424 { 1425 argvars[i].v_type = VAR_STRING; 1426 argvars[i].vval.v_string = (char_u *)""; 1427 continue; 1428 } 1429 1430 /* Recognize a number argument, the others must be strings. */ 1431 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1432 if (len != 0 && len == (int)STRLEN(argv[i])) 1433 { 1434 argvars[i].v_type = VAR_NUMBER; 1435 argvars[i].vval.v_number = n; 1436 } 1437 else 1438 { 1439 argvars[i].v_type = VAR_STRING; 1440 argvars[i].vval.v_string = argv[i]; 1441 } 1442 } 1443 1444 if (safe) 1445 { 1446 save_funccalp = save_funccal(); 1447 ++sandbox; 1448 } 1449 1450 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1451 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1452 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1453 &doesrange, TRUE, NULL); 1454 if (safe) 1455 { 1456 --sandbox; 1457 restore_funccal(save_funccalp); 1458 } 1459 vim_free(argvars); 1460 1461 if (ret == FAIL) 1462 clear_tv(rettv); 1463 1464 return ret; 1465 } 1466 1467 /* 1468 * Call vimL function "func" and return the result as a string. 1469 * Returns NULL when calling the function fails. 1470 * Uses argv[argc] for the function arguments. 1471 */ 1472 void * 1473 call_func_retstr(func, argc, argv, safe) 1474 char_u *func; 1475 int argc; 1476 char_u **argv; 1477 int safe; /* use the sandbox */ 1478 { 1479 typval_T rettv; 1480 char_u *retval; 1481 1482 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1483 return NULL; 1484 1485 retval = vim_strsave(get_tv_string(&rettv)); 1486 clear_tv(&rettv); 1487 return retval; 1488 } 1489 1490 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1491 /* 1492 * Call vimL function "func" and return the result as a number. 1493 * Returns -1 when calling the function fails. 1494 * Uses argv[argc] for the function arguments. 1495 */ 1496 long 1497 call_func_retnr(func, argc, argv, safe) 1498 char_u *func; 1499 int argc; 1500 char_u **argv; 1501 int safe; /* use the sandbox */ 1502 { 1503 typval_T rettv; 1504 long retval; 1505 1506 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1507 return -1; 1508 1509 retval = get_tv_number_chk(&rettv, NULL); 1510 clear_tv(&rettv); 1511 return retval; 1512 } 1513 #endif 1514 1515 /* 1516 * Call vimL function "func" and return the result as a list 1517 * Uses argv[argc] for the function arguments. 1518 */ 1519 void * 1520 call_func_retlist(func, argc, argv, safe) 1521 char_u *func; 1522 int argc; 1523 char_u **argv; 1524 int safe; /* use the sandbox */ 1525 { 1526 typval_T rettv; 1527 1528 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1529 return NULL; 1530 1531 if (rettv.v_type != VAR_LIST) 1532 { 1533 clear_tv(&rettv); 1534 return NULL; 1535 } 1536 1537 return rettv.vval.v_list; 1538 } 1539 1540 #endif 1541 1542 /* 1543 * Save the current function call pointer, and set it to NULL. 1544 * Used when executing autocommands and for ":source". 1545 */ 1546 void * 1547 save_funccal() 1548 { 1549 funccall_T *fc = current_funccal; 1550 1551 current_funccal = NULL; 1552 return (void *)fc; 1553 } 1554 1555 void 1556 restore_funccal(vfc) 1557 void *vfc; 1558 { 1559 funccall_T *fc = (funccall_T *)vfc; 1560 1561 current_funccal = fc; 1562 } 1563 1564 #if defined(FEAT_PROFILE) || defined(PROTO) 1565 /* 1566 * Prepare profiling for entering a child or something else that is not 1567 * counted for the script/function itself. 1568 * Should always be called in pair with prof_child_exit(). 1569 */ 1570 void 1571 prof_child_enter(tm) 1572 proftime_T *tm; /* place to store waittime */ 1573 { 1574 funccall_T *fc = current_funccal; 1575 1576 if (fc != NULL && fc->func->uf_profiling) 1577 profile_start(&fc->prof_child); 1578 script_prof_save(tm); 1579 } 1580 1581 /* 1582 * Take care of time spent in a child. 1583 * Should always be called after prof_child_enter(). 1584 */ 1585 void 1586 prof_child_exit(tm) 1587 proftime_T *tm; /* where waittime was stored */ 1588 { 1589 funccall_T *fc = current_funccal; 1590 1591 if (fc != NULL && fc->func->uf_profiling) 1592 { 1593 profile_end(&fc->prof_child); 1594 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1595 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1596 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1597 } 1598 script_prof_restore(tm); 1599 } 1600 #endif 1601 1602 1603 #ifdef FEAT_FOLDING 1604 /* 1605 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1606 * it in "*cp". Doesn't give error messages. 1607 */ 1608 int 1609 eval_foldexpr(arg, cp) 1610 char_u *arg; 1611 int *cp; 1612 { 1613 typval_T tv; 1614 int retval; 1615 char_u *s; 1616 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1617 OPT_LOCAL); 1618 1619 ++emsg_off; 1620 if (use_sandbox) 1621 ++sandbox; 1622 ++textlock; 1623 *cp = NUL; 1624 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1625 retval = 0; 1626 else 1627 { 1628 /* If the result is a number, just return the number. */ 1629 if (tv.v_type == VAR_NUMBER) 1630 retval = tv.vval.v_number; 1631 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1632 retval = 0; 1633 else 1634 { 1635 /* If the result is a string, check if there is a non-digit before 1636 * the number. */ 1637 s = tv.vval.v_string; 1638 if (!VIM_ISDIGIT(*s) && *s != '-') 1639 *cp = *s++; 1640 retval = atol((char *)s); 1641 } 1642 clear_tv(&tv); 1643 } 1644 --emsg_off; 1645 if (use_sandbox) 1646 --sandbox; 1647 --textlock; 1648 1649 return retval; 1650 } 1651 #endif 1652 1653 /* 1654 * ":let" list all variable values 1655 * ":let var1 var2" list variable values 1656 * ":let var = expr" assignment command. 1657 * ":let var += expr" assignment command. 1658 * ":let var -= expr" assignment command. 1659 * ":let var .= expr" assignment command. 1660 * ":let [var1, var2] = expr" unpack list. 1661 */ 1662 void 1663 ex_let(eap) 1664 exarg_T *eap; 1665 { 1666 char_u *arg = eap->arg; 1667 char_u *expr = NULL; 1668 typval_T rettv; 1669 int i; 1670 int var_count = 0; 1671 int semicolon = 0; 1672 char_u op[2]; 1673 char_u *argend; 1674 1675 argend = skip_var_list(arg, &var_count, &semicolon); 1676 if (argend == NULL) 1677 return; 1678 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1679 --argend; 1680 expr = vim_strchr(argend, '='); 1681 if (expr == NULL) 1682 { 1683 /* 1684 * ":let" without "=": list variables 1685 */ 1686 if (*arg == '[') 1687 EMSG(_(e_invarg)); 1688 else if (!ends_excmd(*arg)) 1689 /* ":let var1 var2" */ 1690 arg = list_arg_vars(eap, arg); 1691 else if (!eap->skip) 1692 { 1693 /* ":let" */ 1694 list_glob_vars(); 1695 list_buf_vars(); 1696 list_win_vars(); 1697 #ifdef FEAT_WINDOWS 1698 list_tab_vars(); 1699 #endif 1700 list_script_vars(); 1701 list_func_vars(); 1702 list_vim_vars(); 1703 } 1704 eap->nextcmd = check_nextcmd(arg); 1705 } 1706 else 1707 { 1708 op[0] = '='; 1709 op[1] = NUL; 1710 if (expr > argend) 1711 { 1712 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1713 op[0] = expr[-1]; /* +=, -= or .= */ 1714 } 1715 expr = skipwhite(expr + 1); 1716 1717 if (eap->skip) 1718 ++emsg_skip; 1719 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1720 if (eap->skip) 1721 { 1722 if (i != FAIL) 1723 clear_tv(&rettv); 1724 --emsg_skip; 1725 } 1726 else if (i != FAIL) 1727 { 1728 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1729 op); 1730 clear_tv(&rettv); 1731 } 1732 } 1733 } 1734 1735 /* 1736 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1737 * Handles both "var" with any type and "[var, var; var]" with a list type. 1738 * When "nextchars" is not NULL it points to a string with characters that 1739 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1740 * or concatenate. 1741 * Returns OK or FAIL; 1742 */ 1743 static int 1744 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1745 char_u *arg_start; 1746 typval_T *tv; 1747 int copy; /* copy values from "tv", don't move */ 1748 int semicolon; /* from skip_var_list() */ 1749 int var_count; /* from skip_var_list() */ 1750 char_u *nextchars; 1751 { 1752 char_u *arg = arg_start; 1753 list_T *l; 1754 int i; 1755 listitem_T *item; 1756 typval_T ltv; 1757 1758 if (*arg != '[') 1759 { 1760 /* 1761 * ":let var = expr" or ":for var in list" 1762 */ 1763 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1764 return FAIL; 1765 return OK; 1766 } 1767 1768 /* 1769 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1770 */ 1771 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1772 { 1773 EMSG(_(e_listreq)); 1774 return FAIL; 1775 } 1776 1777 i = list_len(l); 1778 if (semicolon == 0 && var_count < i) 1779 { 1780 EMSG(_("E687: Less targets than List items")); 1781 return FAIL; 1782 } 1783 if (var_count - semicolon > i) 1784 { 1785 EMSG(_("E688: More targets than List items")); 1786 return FAIL; 1787 } 1788 1789 item = l->lv_first; 1790 while (*arg != ']') 1791 { 1792 arg = skipwhite(arg + 1); 1793 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1794 item = item->li_next; 1795 if (arg == NULL) 1796 return FAIL; 1797 1798 arg = skipwhite(arg); 1799 if (*arg == ';') 1800 { 1801 /* Put the rest of the list (may be empty) in the var after ';'. 1802 * Create a new list for this. */ 1803 l = list_alloc(); 1804 if (l == NULL) 1805 return FAIL; 1806 while (item != NULL) 1807 { 1808 list_append_tv(l, &item->li_tv); 1809 item = item->li_next; 1810 } 1811 1812 ltv.v_type = VAR_LIST; 1813 ltv.v_lock = 0; 1814 ltv.vval.v_list = l; 1815 l->lv_refcount = 1; 1816 1817 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1818 (char_u *)"]", nextchars); 1819 clear_tv(<v); 1820 if (arg == NULL) 1821 return FAIL; 1822 break; 1823 } 1824 else if (*arg != ',' && *arg != ']') 1825 { 1826 EMSG2(_(e_intern2), "ex_let_vars()"); 1827 return FAIL; 1828 } 1829 } 1830 1831 return OK; 1832 } 1833 1834 /* 1835 * Skip over assignable variable "var" or list of variables "[var, var]". 1836 * Used for ":let varvar = expr" and ":for varvar in expr". 1837 * For "[var, var]" increment "*var_count" for each variable. 1838 * for "[var, var; var]" set "semicolon". 1839 * Return NULL for an error. 1840 */ 1841 static char_u * 1842 skip_var_list(arg, var_count, semicolon) 1843 char_u *arg; 1844 int *var_count; 1845 int *semicolon; 1846 { 1847 char_u *p, *s; 1848 1849 if (*arg == '[') 1850 { 1851 /* "[var, var]": find the matching ']'. */ 1852 p = arg; 1853 for (;;) 1854 { 1855 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1856 s = skip_var_one(p); 1857 if (s == p) 1858 { 1859 EMSG2(_(e_invarg2), p); 1860 return NULL; 1861 } 1862 ++*var_count; 1863 1864 p = skipwhite(s); 1865 if (*p == ']') 1866 break; 1867 else if (*p == ';') 1868 { 1869 if (*semicolon == 1) 1870 { 1871 EMSG(_("Double ; in list of variables")); 1872 return NULL; 1873 } 1874 *semicolon = 1; 1875 } 1876 else if (*p != ',') 1877 { 1878 EMSG2(_(e_invarg2), p); 1879 return NULL; 1880 } 1881 } 1882 return p + 1; 1883 } 1884 else 1885 return skip_var_one(arg); 1886 } 1887 1888 /* 1889 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1890 * l[idx]. 1891 */ 1892 static char_u * 1893 skip_var_one(arg) 1894 char_u *arg; 1895 { 1896 if (*arg == '@' && arg[1] != NUL) 1897 return arg + 2; 1898 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1899 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1900 } 1901 1902 /* 1903 * List variables for hashtab "ht" with prefix "prefix". 1904 * If "empty" is TRUE also list NULL strings as empty strings. 1905 */ 1906 static void 1907 list_hashtable_vars(ht, prefix, empty) 1908 hashtab_T *ht; 1909 char_u *prefix; 1910 int empty; 1911 { 1912 hashitem_T *hi; 1913 dictitem_T *di; 1914 int todo; 1915 1916 todo = (int)ht->ht_used; 1917 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1918 { 1919 if (!HASHITEM_EMPTY(hi)) 1920 { 1921 --todo; 1922 di = HI2DI(hi); 1923 if (empty || di->di_tv.v_type != VAR_STRING 1924 || di->di_tv.vval.v_string != NULL) 1925 list_one_var(di, prefix); 1926 } 1927 } 1928 } 1929 1930 /* 1931 * List global variables. 1932 */ 1933 static void 1934 list_glob_vars() 1935 { 1936 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1937 } 1938 1939 /* 1940 * List buffer variables. 1941 */ 1942 static void 1943 list_buf_vars() 1944 { 1945 char_u numbuf[NUMBUFLEN]; 1946 1947 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1948 1949 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1950 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1951 } 1952 1953 /* 1954 * List window variables. 1955 */ 1956 static void 1957 list_win_vars() 1958 { 1959 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1960 } 1961 1962 #ifdef FEAT_WINDOWS 1963 /* 1964 * List tab page variables. 1965 */ 1966 static void 1967 list_tab_vars() 1968 { 1969 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE); 1970 } 1971 #endif 1972 1973 /* 1974 * List Vim variables. 1975 */ 1976 static void 1977 list_vim_vars() 1978 { 1979 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1980 } 1981 1982 /* 1983 * List script-local variables, if there is a script. 1984 */ 1985 static void 1986 list_script_vars() 1987 { 1988 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 1989 list_hashtable_vars(&SCRIPT_VARS(current_SID), (char_u *)"s:", FALSE); 1990 } 1991 1992 /* 1993 * List function variables, if there is a function. 1994 */ 1995 static void 1996 list_func_vars() 1997 { 1998 if (current_funccal != NULL) 1999 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2000 (char_u *)"l:", FALSE); 2001 } 2002 2003 /* 2004 * List variables in "arg". 2005 */ 2006 static char_u * 2007 list_arg_vars(eap, arg) 2008 exarg_T *eap; 2009 char_u *arg; 2010 { 2011 int error = FALSE; 2012 int len; 2013 char_u *name; 2014 char_u *name_start; 2015 char_u *arg_subsc; 2016 char_u *tofree; 2017 typval_T tv; 2018 2019 while (!ends_excmd(*arg) && !got_int) 2020 { 2021 if (error || eap->skip) 2022 { 2023 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2024 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2025 { 2026 emsg_severe = TRUE; 2027 EMSG(_(e_trailing)); 2028 break; 2029 } 2030 } 2031 else 2032 { 2033 /* get_name_len() takes care of expanding curly braces */ 2034 name_start = name = arg; 2035 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2036 if (len <= 0) 2037 { 2038 /* This is mainly to keep test 49 working: when expanding 2039 * curly braces fails overrule the exception error message. */ 2040 if (len < 0 && !aborting()) 2041 { 2042 emsg_severe = TRUE; 2043 EMSG2(_(e_invarg2), arg); 2044 break; 2045 } 2046 error = TRUE; 2047 } 2048 else 2049 { 2050 if (tofree != NULL) 2051 name = tofree; 2052 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 2053 error = TRUE; 2054 else 2055 { 2056 /* handle d.key, l[idx], f(expr) */ 2057 arg_subsc = arg; 2058 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2059 error = TRUE; 2060 else 2061 { 2062 if (arg == arg_subsc && len == 2 && name[1] == ':') 2063 { 2064 switch (*name) 2065 { 2066 case 'g': list_glob_vars(); break; 2067 case 'b': list_buf_vars(); break; 2068 case 'w': list_win_vars(); break; 2069 #ifdef FEAT_WINDOWS 2070 case 't': list_tab_vars(); break; 2071 #endif 2072 case 'v': list_vim_vars(); break; 2073 case 's': list_script_vars(); break; 2074 case 'l': list_func_vars(); break; 2075 default: 2076 EMSG2(_("E738: Can't list variables for %s"), name); 2077 } 2078 } 2079 else 2080 { 2081 char_u numbuf[NUMBUFLEN]; 2082 char_u *tf; 2083 int c; 2084 char_u *s; 2085 2086 s = echo_string(&tv, &tf, numbuf, 0); 2087 c = *arg; 2088 *arg = NUL; 2089 list_one_var_a((char_u *)"", 2090 arg == arg_subsc ? name : name_start, 2091 tv.v_type, s == NULL ? (char_u *)"" : s); 2092 *arg = c; 2093 vim_free(tf); 2094 } 2095 clear_tv(&tv); 2096 } 2097 } 2098 } 2099 2100 vim_free(tofree); 2101 } 2102 2103 arg = skipwhite(arg); 2104 } 2105 2106 return arg; 2107 } 2108 2109 /* 2110 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2111 * Returns a pointer to the char just after the var name. 2112 * Returns NULL if there is an error. 2113 */ 2114 static char_u * 2115 ex_let_one(arg, tv, copy, endchars, op) 2116 char_u *arg; /* points to variable name */ 2117 typval_T *tv; /* value to assign to variable */ 2118 int copy; /* copy value from "tv" */ 2119 char_u *endchars; /* valid chars after variable name or NULL */ 2120 char_u *op; /* "+", "-", "." or NULL*/ 2121 { 2122 int c1; 2123 char_u *name; 2124 char_u *p; 2125 char_u *arg_end = NULL; 2126 int len; 2127 int opt_flags; 2128 char_u *tofree = NULL; 2129 2130 /* 2131 * ":let $VAR = expr": Set environment variable. 2132 */ 2133 if (*arg == '$') 2134 { 2135 /* Find the end of the name. */ 2136 ++arg; 2137 name = arg; 2138 len = get_env_len(&arg); 2139 if (len == 0) 2140 EMSG2(_(e_invarg2), name - 1); 2141 else 2142 { 2143 if (op != NULL && (*op == '+' || *op == '-')) 2144 EMSG2(_(e_letwrong), op); 2145 else if (endchars != NULL 2146 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2147 EMSG(_(e_letunexp)); 2148 else 2149 { 2150 c1 = name[len]; 2151 name[len] = NUL; 2152 p = get_tv_string_chk(tv); 2153 if (p != NULL && op != NULL && *op == '.') 2154 { 2155 int mustfree = FALSE; 2156 char_u *s = vim_getenv(name, &mustfree); 2157 2158 if (s != NULL) 2159 { 2160 p = tofree = concat_str(s, p); 2161 if (mustfree) 2162 vim_free(s); 2163 } 2164 } 2165 if (p != NULL) 2166 { 2167 vim_setenv(name, p); 2168 if (STRICMP(name, "HOME") == 0) 2169 init_homedir(); 2170 else if (didset_vim && STRICMP(name, "VIM") == 0) 2171 didset_vim = FALSE; 2172 else if (didset_vimruntime 2173 && STRICMP(name, "VIMRUNTIME") == 0) 2174 didset_vimruntime = FALSE; 2175 arg_end = arg; 2176 } 2177 name[len] = c1; 2178 vim_free(tofree); 2179 } 2180 } 2181 } 2182 2183 /* 2184 * ":let &option = expr": Set option value. 2185 * ":let &l:option = expr": Set local option value. 2186 * ":let &g:option = expr": Set global option value. 2187 */ 2188 else if (*arg == '&') 2189 { 2190 /* Find the end of the name. */ 2191 p = find_option_end(&arg, &opt_flags); 2192 if (p == NULL || (endchars != NULL 2193 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2194 EMSG(_(e_letunexp)); 2195 else 2196 { 2197 long n; 2198 int opt_type; 2199 long numval; 2200 char_u *stringval = NULL; 2201 char_u *s; 2202 2203 c1 = *p; 2204 *p = NUL; 2205 2206 n = get_tv_number(tv); 2207 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2208 if (s != NULL && op != NULL && *op != '=') 2209 { 2210 opt_type = get_option_value(arg, &numval, 2211 &stringval, opt_flags); 2212 if ((opt_type == 1 && *op == '.') 2213 || (opt_type == 0 && *op != '.')) 2214 EMSG2(_(e_letwrong), op); 2215 else 2216 { 2217 if (opt_type == 1) /* number */ 2218 { 2219 if (*op == '+') 2220 n = numval + n; 2221 else 2222 n = numval - n; 2223 } 2224 else if (opt_type == 0 && stringval != NULL) /* string */ 2225 { 2226 s = concat_str(stringval, s); 2227 vim_free(stringval); 2228 stringval = s; 2229 } 2230 } 2231 } 2232 if (s != NULL) 2233 { 2234 set_option_value(arg, n, s, opt_flags); 2235 arg_end = p; 2236 } 2237 *p = c1; 2238 vim_free(stringval); 2239 } 2240 } 2241 2242 /* 2243 * ":let @r = expr": Set register contents. 2244 */ 2245 else if (*arg == '@') 2246 { 2247 ++arg; 2248 if (op != NULL && (*op == '+' || *op == '-')) 2249 EMSG2(_(e_letwrong), op); 2250 else if (endchars != NULL 2251 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2252 EMSG(_(e_letunexp)); 2253 else 2254 { 2255 char_u *tofree = NULL; 2256 char_u *s; 2257 2258 p = get_tv_string_chk(tv); 2259 if (p != NULL && op != NULL && *op == '.') 2260 { 2261 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2262 if (s != NULL) 2263 { 2264 p = tofree = concat_str(s, p); 2265 vim_free(s); 2266 } 2267 } 2268 if (p != NULL) 2269 { 2270 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2271 arg_end = arg + 1; 2272 } 2273 vim_free(tofree); 2274 } 2275 } 2276 2277 /* 2278 * ":let var = expr": Set internal variable. 2279 * ":let {expr} = expr": Idem, name made with curly braces 2280 */ 2281 else if (eval_isnamec1(*arg) || *arg == '{') 2282 { 2283 lval_T lv; 2284 2285 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2286 if (p != NULL && lv.ll_name != NULL) 2287 { 2288 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2289 EMSG(_(e_letunexp)); 2290 else 2291 { 2292 set_var_lval(&lv, p, tv, copy, op); 2293 arg_end = p; 2294 } 2295 } 2296 clear_lval(&lv); 2297 } 2298 2299 else 2300 EMSG2(_(e_invarg2), arg); 2301 2302 return arg_end; 2303 } 2304 2305 /* 2306 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2307 */ 2308 static int 2309 check_changedtick(arg) 2310 char_u *arg; 2311 { 2312 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2313 { 2314 EMSG2(_(e_readonlyvar), arg); 2315 return TRUE; 2316 } 2317 return FALSE; 2318 } 2319 2320 /* 2321 * Get an lval: variable, Dict item or List item that can be assigned a value 2322 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2323 * "name.key", "name.key[expr]" etc. 2324 * Indexing only works if "name" is an existing List or Dictionary. 2325 * "name" points to the start of the name. 2326 * If "rettv" is not NULL it points to the value to be assigned. 2327 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2328 * wrong; must end in space or cmd separator. 2329 * 2330 * Returns a pointer to just after the name, including indexes. 2331 * When an evaluation error occurs "lp->ll_name" is NULL; 2332 * Returns NULL for a parsing error. Still need to free items in "lp"! 2333 */ 2334 static char_u * 2335 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2336 char_u *name; 2337 typval_T *rettv; 2338 lval_T *lp; 2339 int unlet; 2340 int skip; 2341 int quiet; /* don't give error messages */ 2342 int fne_flags; /* flags for find_name_end() */ 2343 { 2344 char_u *p; 2345 char_u *expr_start, *expr_end; 2346 int cc; 2347 dictitem_T *v; 2348 typval_T var1; 2349 typval_T var2; 2350 int empty1 = FALSE; 2351 listitem_T *ni; 2352 char_u *key = NULL; 2353 int len; 2354 hashtab_T *ht; 2355 2356 /* Clear everything in "lp". */ 2357 vim_memset(lp, 0, sizeof(lval_T)); 2358 2359 if (skip) 2360 { 2361 /* When skipping just find the end of the name. */ 2362 lp->ll_name = name; 2363 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2364 } 2365 2366 /* Find the end of the name. */ 2367 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2368 if (expr_start != NULL) 2369 { 2370 /* Don't expand the name when we already know there is an error. */ 2371 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2372 && *p != '[' && *p != '.') 2373 { 2374 EMSG(_(e_trailing)); 2375 return NULL; 2376 } 2377 2378 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2379 if (lp->ll_exp_name == NULL) 2380 { 2381 /* Report an invalid expression in braces, unless the 2382 * expression evaluation has been cancelled due to an 2383 * aborting error, an interrupt, or an exception. */ 2384 if (!aborting() && !quiet) 2385 { 2386 emsg_severe = TRUE; 2387 EMSG2(_(e_invarg2), name); 2388 return NULL; 2389 } 2390 } 2391 lp->ll_name = lp->ll_exp_name; 2392 } 2393 else 2394 lp->ll_name = name; 2395 2396 /* Without [idx] or .key we are done. */ 2397 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2398 return p; 2399 2400 cc = *p; 2401 *p = NUL; 2402 v = find_var(lp->ll_name, &ht); 2403 if (v == NULL && !quiet) 2404 EMSG2(_(e_undefvar), lp->ll_name); 2405 *p = cc; 2406 if (v == NULL) 2407 return NULL; 2408 2409 /* 2410 * Loop until no more [idx] or .key is following. 2411 */ 2412 lp->ll_tv = &v->di_tv; 2413 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2414 { 2415 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2416 && !(lp->ll_tv->v_type == VAR_DICT 2417 && lp->ll_tv->vval.v_dict != NULL)) 2418 { 2419 if (!quiet) 2420 EMSG(_("E689: Can only index a List or Dictionary")); 2421 return NULL; 2422 } 2423 if (lp->ll_range) 2424 { 2425 if (!quiet) 2426 EMSG(_("E708: [:] must come last")); 2427 return NULL; 2428 } 2429 2430 len = -1; 2431 if (*p == '.') 2432 { 2433 key = p + 1; 2434 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2435 ; 2436 if (len == 0) 2437 { 2438 if (!quiet) 2439 EMSG(_(e_emptykey)); 2440 return NULL; 2441 } 2442 p = key + len; 2443 } 2444 else 2445 { 2446 /* Get the index [expr] or the first index [expr: ]. */ 2447 p = skipwhite(p + 1); 2448 if (*p == ':') 2449 empty1 = TRUE; 2450 else 2451 { 2452 empty1 = FALSE; 2453 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2454 return NULL; 2455 if (get_tv_string_chk(&var1) == NULL) 2456 { 2457 /* not a number or string */ 2458 clear_tv(&var1); 2459 return NULL; 2460 } 2461 } 2462 2463 /* Optionally get the second index [ :expr]. */ 2464 if (*p == ':') 2465 { 2466 if (lp->ll_tv->v_type == VAR_DICT) 2467 { 2468 if (!quiet) 2469 EMSG(_(e_dictrange)); 2470 if (!empty1) 2471 clear_tv(&var1); 2472 return NULL; 2473 } 2474 if (rettv != NULL && (rettv->v_type != VAR_LIST 2475 || rettv->vval.v_list == NULL)) 2476 { 2477 if (!quiet) 2478 EMSG(_("E709: [:] requires a List value")); 2479 if (!empty1) 2480 clear_tv(&var1); 2481 return NULL; 2482 } 2483 p = skipwhite(p + 1); 2484 if (*p == ']') 2485 lp->ll_empty2 = TRUE; 2486 else 2487 { 2488 lp->ll_empty2 = FALSE; 2489 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2490 { 2491 if (!empty1) 2492 clear_tv(&var1); 2493 return NULL; 2494 } 2495 if (get_tv_string_chk(&var2) == NULL) 2496 { 2497 /* not a number or string */ 2498 if (!empty1) 2499 clear_tv(&var1); 2500 clear_tv(&var2); 2501 return NULL; 2502 } 2503 } 2504 lp->ll_range = TRUE; 2505 } 2506 else 2507 lp->ll_range = FALSE; 2508 2509 if (*p != ']') 2510 { 2511 if (!quiet) 2512 EMSG(_(e_missbrac)); 2513 if (!empty1) 2514 clear_tv(&var1); 2515 if (lp->ll_range && !lp->ll_empty2) 2516 clear_tv(&var2); 2517 return NULL; 2518 } 2519 2520 /* Skip to past ']'. */ 2521 ++p; 2522 } 2523 2524 if (lp->ll_tv->v_type == VAR_DICT) 2525 { 2526 if (len == -1) 2527 { 2528 /* "[key]": get key from "var1" */ 2529 key = get_tv_string(&var1); /* is number or string */ 2530 if (*key == NUL) 2531 { 2532 if (!quiet) 2533 EMSG(_(e_emptykey)); 2534 clear_tv(&var1); 2535 return NULL; 2536 } 2537 } 2538 lp->ll_list = NULL; 2539 lp->ll_dict = lp->ll_tv->vval.v_dict; 2540 lp->ll_di = dict_find(lp->ll_dict, key, len); 2541 if (lp->ll_di == NULL) 2542 { 2543 /* Key does not exist in dict: may need to add it. */ 2544 if (*p == '[' || *p == '.' || unlet) 2545 { 2546 if (!quiet) 2547 EMSG2(_(e_dictkey), key); 2548 if (len == -1) 2549 clear_tv(&var1); 2550 return NULL; 2551 } 2552 if (len == -1) 2553 lp->ll_newkey = vim_strsave(key); 2554 else 2555 lp->ll_newkey = vim_strnsave(key, len); 2556 if (len == -1) 2557 clear_tv(&var1); 2558 if (lp->ll_newkey == NULL) 2559 p = NULL; 2560 break; 2561 } 2562 if (len == -1) 2563 clear_tv(&var1); 2564 lp->ll_tv = &lp->ll_di->di_tv; 2565 } 2566 else 2567 { 2568 /* 2569 * Get the number and item for the only or first index of the List. 2570 */ 2571 if (empty1) 2572 lp->ll_n1 = 0; 2573 else 2574 { 2575 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2576 clear_tv(&var1); 2577 } 2578 lp->ll_dict = NULL; 2579 lp->ll_list = lp->ll_tv->vval.v_list; 2580 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2581 if (lp->ll_li == NULL) 2582 { 2583 if (!quiet) 2584 EMSGN(_(e_listidx), lp->ll_n1); 2585 if (lp->ll_range && !lp->ll_empty2) 2586 clear_tv(&var2); 2587 return NULL; 2588 } 2589 2590 /* 2591 * May need to find the item or absolute index for the second 2592 * index of a range. 2593 * When no index given: "lp->ll_empty2" is TRUE. 2594 * Otherwise "lp->ll_n2" is set to the second index. 2595 */ 2596 if (lp->ll_range && !lp->ll_empty2) 2597 { 2598 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2599 clear_tv(&var2); 2600 if (lp->ll_n2 < 0) 2601 { 2602 ni = list_find(lp->ll_list, lp->ll_n2); 2603 if (ni == NULL) 2604 { 2605 if (!quiet) 2606 EMSGN(_(e_listidx), lp->ll_n2); 2607 return NULL; 2608 } 2609 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2610 } 2611 2612 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2613 if (lp->ll_n1 < 0) 2614 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2615 if (lp->ll_n2 < lp->ll_n1) 2616 { 2617 if (!quiet) 2618 EMSGN(_(e_listidx), lp->ll_n2); 2619 return NULL; 2620 } 2621 } 2622 2623 lp->ll_tv = &lp->ll_li->li_tv; 2624 } 2625 } 2626 2627 return p; 2628 } 2629 2630 /* 2631 * Clear lval "lp" that was filled by get_lval(). 2632 */ 2633 static void 2634 clear_lval(lp) 2635 lval_T *lp; 2636 { 2637 vim_free(lp->ll_exp_name); 2638 vim_free(lp->ll_newkey); 2639 } 2640 2641 /* 2642 * Set a variable that was parsed by get_lval() to "rettv". 2643 * "endp" points to just after the parsed name. 2644 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2645 */ 2646 static void 2647 set_var_lval(lp, endp, rettv, copy, op) 2648 lval_T *lp; 2649 char_u *endp; 2650 typval_T *rettv; 2651 int copy; 2652 char_u *op; 2653 { 2654 int cc; 2655 listitem_T *ri; 2656 dictitem_T *di; 2657 2658 if (lp->ll_tv == NULL) 2659 { 2660 if (!check_changedtick(lp->ll_name)) 2661 { 2662 cc = *endp; 2663 *endp = NUL; 2664 if (op != NULL && *op != '=') 2665 { 2666 typval_T tv; 2667 2668 /* handle +=, -= and .= */ 2669 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2670 &tv, TRUE) == OK) 2671 { 2672 if (tv_op(&tv, rettv, op) == OK) 2673 set_var(lp->ll_name, &tv, FALSE); 2674 clear_tv(&tv); 2675 } 2676 } 2677 else 2678 set_var(lp->ll_name, rettv, copy); 2679 *endp = cc; 2680 } 2681 } 2682 else if (tv_check_lock(lp->ll_newkey == NULL 2683 ? lp->ll_tv->v_lock 2684 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2685 ; 2686 else if (lp->ll_range) 2687 { 2688 /* 2689 * Assign the List values to the list items. 2690 */ 2691 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2692 { 2693 if (op != NULL && *op != '=') 2694 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2695 else 2696 { 2697 clear_tv(&lp->ll_li->li_tv); 2698 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2699 } 2700 ri = ri->li_next; 2701 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2702 break; 2703 if (lp->ll_li->li_next == NULL) 2704 { 2705 /* Need to add an empty item. */ 2706 if (list_append_number(lp->ll_list, 0) == FAIL) 2707 { 2708 ri = NULL; 2709 break; 2710 } 2711 } 2712 lp->ll_li = lp->ll_li->li_next; 2713 ++lp->ll_n1; 2714 } 2715 if (ri != NULL) 2716 EMSG(_("E710: List value has more items than target")); 2717 else if (lp->ll_empty2 2718 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2719 : lp->ll_n1 != lp->ll_n2) 2720 EMSG(_("E711: List value has not enough items")); 2721 } 2722 else 2723 { 2724 /* 2725 * Assign to a List or Dictionary item. 2726 */ 2727 if (lp->ll_newkey != NULL) 2728 { 2729 if (op != NULL && *op != '=') 2730 { 2731 EMSG2(_(e_letwrong), op); 2732 return; 2733 } 2734 2735 /* Need to add an item to the Dictionary. */ 2736 di = dictitem_alloc(lp->ll_newkey); 2737 if (di == NULL) 2738 return; 2739 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2740 { 2741 vim_free(di); 2742 return; 2743 } 2744 lp->ll_tv = &di->di_tv; 2745 } 2746 else if (op != NULL && *op != '=') 2747 { 2748 tv_op(lp->ll_tv, rettv, op); 2749 return; 2750 } 2751 else 2752 clear_tv(lp->ll_tv); 2753 2754 /* 2755 * Assign the value to the variable or list item. 2756 */ 2757 if (copy) 2758 copy_tv(rettv, lp->ll_tv); 2759 else 2760 { 2761 *lp->ll_tv = *rettv; 2762 lp->ll_tv->v_lock = 0; 2763 init_tv(rettv); 2764 } 2765 } 2766 } 2767 2768 /* 2769 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2770 * Returns OK or FAIL. 2771 */ 2772 static int 2773 tv_op(tv1, tv2, op) 2774 typval_T *tv1; 2775 typval_T *tv2; 2776 char_u *op; 2777 { 2778 long n; 2779 char_u numbuf[NUMBUFLEN]; 2780 char_u *s; 2781 2782 /* Can't do anything with a Funcref or a Dict on the right. */ 2783 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2784 { 2785 switch (tv1->v_type) 2786 { 2787 case VAR_DICT: 2788 case VAR_FUNC: 2789 break; 2790 2791 case VAR_LIST: 2792 if (*op != '+' || tv2->v_type != VAR_LIST) 2793 break; 2794 /* List += List */ 2795 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2796 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2797 return OK; 2798 2799 case VAR_NUMBER: 2800 case VAR_STRING: 2801 if (tv2->v_type == VAR_LIST) 2802 break; 2803 if (*op == '+' || *op == '-') 2804 { 2805 /* nr += nr or nr -= nr*/ 2806 n = get_tv_number(tv1); 2807 if (*op == '+') 2808 n += get_tv_number(tv2); 2809 else 2810 n -= get_tv_number(tv2); 2811 clear_tv(tv1); 2812 tv1->v_type = VAR_NUMBER; 2813 tv1->vval.v_number = n; 2814 } 2815 else 2816 { 2817 /* str .= str */ 2818 s = get_tv_string(tv1); 2819 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2820 clear_tv(tv1); 2821 tv1->v_type = VAR_STRING; 2822 tv1->vval.v_string = s; 2823 } 2824 return OK; 2825 } 2826 } 2827 2828 EMSG2(_(e_letwrong), op); 2829 return FAIL; 2830 } 2831 2832 /* 2833 * Add a watcher to a list. 2834 */ 2835 static void 2836 list_add_watch(l, lw) 2837 list_T *l; 2838 listwatch_T *lw; 2839 { 2840 lw->lw_next = l->lv_watch; 2841 l->lv_watch = lw; 2842 } 2843 2844 /* 2845 * Remove a watcher from a list. 2846 * No warning when it isn't found... 2847 */ 2848 static void 2849 list_rem_watch(l, lwrem) 2850 list_T *l; 2851 listwatch_T *lwrem; 2852 { 2853 listwatch_T *lw, **lwp; 2854 2855 lwp = &l->lv_watch; 2856 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2857 { 2858 if (lw == lwrem) 2859 { 2860 *lwp = lw->lw_next; 2861 break; 2862 } 2863 lwp = &lw->lw_next; 2864 } 2865 } 2866 2867 /* 2868 * Just before removing an item from a list: advance watchers to the next 2869 * item. 2870 */ 2871 static void 2872 list_fix_watch(l, item) 2873 list_T *l; 2874 listitem_T *item; 2875 { 2876 listwatch_T *lw; 2877 2878 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2879 if (lw->lw_item == item) 2880 lw->lw_item = item->li_next; 2881 } 2882 2883 /* 2884 * Evaluate the expression used in a ":for var in expr" command. 2885 * "arg" points to "var". 2886 * Set "*errp" to TRUE for an error, FALSE otherwise; 2887 * Return a pointer that holds the info. Null when there is an error. 2888 */ 2889 void * 2890 eval_for_line(arg, errp, nextcmdp, skip) 2891 char_u *arg; 2892 int *errp; 2893 char_u **nextcmdp; 2894 int skip; 2895 { 2896 forinfo_T *fi; 2897 char_u *expr; 2898 typval_T tv; 2899 list_T *l; 2900 2901 *errp = TRUE; /* default: there is an error */ 2902 2903 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2904 if (fi == NULL) 2905 return NULL; 2906 2907 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2908 if (expr == NULL) 2909 return fi; 2910 2911 expr = skipwhite(expr); 2912 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2913 { 2914 EMSG(_("E690: Missing \"in\" after :for")); 2915 return fi; 2916 } 2917 2918 if (skip) 2919 ++emsg_skip; 2920 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2921 { 2922 *errp = FALSE; 2923 if (!skip) 2924 { 2925 l = tv.vval.v_list; 2926 if (tv.v_type != VAR_LIST || l == NULL) 2927 { 2928 EMSG(_(e_listreq)); 2929 clear_tv(&tv); 2930 } 2931 else 2932 { 2933 /* No need to increment the refcount, it's already set for the 2934 * list being used in "tv". */ 2935 fi->fi_list = l; 2936 list_add_watch(l, &fi->fi_lw); 2937 fi->fi_lw.lw_item = l->lv_first; 2938 } 2939 } 2940 } 2941 if (skip) 2942 --emsg_skip; 2943 2944 return fi; 2945 } 2946 2947 /* 2948 * Use the first item in a ":for" list. Advance to the next. 2949 * Assign the values to the variable (list). "arg" points to the first one. 2950 * Return TRUE when a valid item was found, FALSE when at end of list or 2951 * something wrong. 2952 */ 2953 int 2954 next_for_item(fi_void, arg) 2955 void *fi_void; 2956 char_u *arg; 2957 { 2958 forinfo_T *fi = (forinfo_T *)fi_void; 2959 int result; 2960 listitem_T *item; 2961 2962 item = fi->fi_lw.lw_item; 2963 if (item == NULL) 2964 result = FALSE; 2965 else 2966 { 2967 fi->fi_lw.lw_item = item->li_next; 2968 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2969 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2970 } 2971 return result; 2972 } 2973 2974 /* 2975 * Free the structure used to store info used by ":for". 2976 */ 2977 void 2978 free_for_info(fi_void) 2979 void *fi_void; 2980 { 2981 forinfo_T *fi = (forinfo_T *)fi_void; 2982 2983 if (fi != NULL && fi->fi_list != NULL) 2984 { 2985 list_rem_watch(fi->fi_list, &fi->fi_lw); 2986 list_unref(fi->fi_list); 2987 } 2988 vim_free(fi); 2989 } 2990 2991 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2992 2993 void 2994 set_context_for_expression(xp, arg, cmdidx) 2995 expand_T *xp; 2996 char_u *arg; 2997 cmdidx_T cmdidx; 2998 { 2999 int got_eq = FALSE; 3000 int c; 3001 char_u *p; 3002 3003 if (cmdidx == CMD_let) 3004 { 3005 xp->xp_context = EXPAND_USER_VARS; 3006 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3007 { 3008 /* ":let var1 var2 ...": find last space. */ 3009 for (p = arg + STRLEN(arg); p >= arg; ) 3010 { 3011 xp->xp_pattern = p; 3012 mb_ptr_back(arg, p); 3013 if (vim_iswhite(*p)) 3014 break; 3015 } 3016 return; 3017 } 3018 } 3019 else 3020 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3021 : EXPAND_EXPRESSION; 3022 while ((xp->xp_pattern = vim_strpbrk(arg, 3023 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3024 { 3025 c = *xp->xp_pattern; 3026 if (c == '&') 3027 { 3028 c = xp->xp_pattern[1]; 3029 if (c == '&') 3030 { 3031 ++xp->xp_pattern; 3032 xp->xp_context = cmdidx != CMD_let || got_eq 3033 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3034 } 3035 else if (c != ' ') 3036 { 3037 xp->xp_context = EXPAND_SETTINGS; 3038 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3039 xp->xp_pattern += 2; 3040 3041 } 3042 } 3043 else if (c == '$') 3044 { 3045 /* environment variable */ 3046 xp->xp_context = EXPAND_ENV_VARS; 3047 } 3048 else if (c == '=') 3049 { 3050 got_eq = TRUE; 3051 xp->xp_context = EXPAND_EXPRESSION; 3052 } 3053 else if (c == '<' 3054 && xp->xp_context == EXPAND_FUNCTIONS 3055 && vim_strchr(xp->xp_pattern, '(') == NULL) 3056 { 3057 /* Function name can start with "<SNR>" */ 3058 break; 3059 } 3060 else if (cmdidx != CMD_let || got_eq) 3061 { 3062 if (c == '"') /* string */ 3063 { 3064 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3065 if (c == '\\' && xp->xp_pattern[1] != NUL) 3066 ++xp->xp_pattern; 3067 xp->xp_context = EXPAND_NOTHING; 3068 } 3069 else if (c == '\'') /* literal string */ 3070 { 3071 /* Trick: '' is like stopping and starting a literal string. */ 3072 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3073 /* skip */ ; 3074 xp->xp_context = EXPAND_NOTHING; 3075 } 3076 else if (c == '|') 3077 { 3078 if (xp->xp_pattern[1] == '|') 3079 { 3080 ++xp->xp_pattern; 3081 xp->xp_context = EXPAND_EXPRESSION; 3082 } 3083 else 3084 xp->xp_context = EXPAND_COMMANDS; 3085 } 3086 else 3087 xp->xp_context = EXPAND_EXPRESSION; 3088 } 3089 else 3090 /* Doesn't look like something valid, expand as an expression 3091 * anyway. */ 3092 xp->xp_context = EXPAND_EXPRESSION; 3093 arg = xp->xp_pattern; 3094 if (*arg != NUL) 3095 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3096 /* skip */ ; 3097 } 3098 xp->xp_pattern = arg; 3099 } 3100 3101 #endif /* FEAT_CMDL_COMPL */ 3102 3103 /* 3104 * ":1,25call func(arg1, arg2)" function call. 3105 */ 3106 void 3107 ex_call(eap) 3108 exarg_T *eap; 3109 { 3110 char_u *arg = eap->arg; 3111 char_u *startarg; 3112 char_u *name; 3113 char_u *tofree; 3114 int len; 3115 typval_T rettv; 3116 linenr_T lnum; 3117 int doesrange; 3118 int failed = FALSE; 3119 funcdict_T fudi; 3120 3121 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3122 vim_free(fudi.fd_newkey); 3123 if (tofree == NULL) 3124 return; 3125 3126 /* Increase refcount on dictionary, it could get deleted when evaluating 3127 * the arguments. */ 3128 if (fudi.fd_dict != NULL) 3129 ++fudi.fd_dict->dv_refcount; 3130 3131 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3132 len = (int)STRLEN(tofree); 3133 name = deref_func_name(tofree, &len); 3134 3135 /* Skip white space to allow ":call func ()". Not good, but required for 3136 * backward compatibility. */ 3137 startarg = skipwhite(arg); 3138 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3139 3140 if (*startarg != '(') 3141 { 3142 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3143 goto end; 3144 } 3145 3146 /* 3147 * When skipping, evaluate the function once, to find the end of the 3148 * arguments. 3149 * When the function takes a range, this is discovered after the first 3150 * call, and the loop is broken. 3151 */ 3152 if (eap->skip) 3153 { 3154 ++emsg_skip; 3155 lnum = eap->line2; /* do it once, also with an invalid range */ 3156 } 3157 else 3158 lnum = eap->line1; 3159 for ( ; lnum <= eap->line2; ++lnum) 3160 { 3161 if (!eap->skip && eap->addr_count > 0) 3162 { 3163 curwin->w_cursor.lnum = lnum; 3164 curwin->w_cursor.col = 0; 3165 } 3166 arg = startarg; 3167 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3168 eap->line1, eap->line2, &doesrange, 3169 !eap->skip, fudi.fd_dict) == FAIL) 3170 { 3171 failed = TRUE; 3172 break; 3173 } 3174 clear_tv(&rettv); 3175 if (doesrange || eap->skip) 3176 break; 3177 /* Stop when immediately aborting on error, or when an interrupt 3178 * occurred or an exception was thrown but not caught. 3179 * get_func_tv() returned OK, so that the check for trailing 3180 * characters below is executed. */ 3181 if (aborting()) 3182 break; 3183 } 3184 if (eap->skip) 3185 --emsg_skip; 3186 3187 if (!failed) 3188 { 3189 /* Check for trailing illegal characters and a following command. */ 3190 if (!ends_excmd(*arg)) 3191 { 3192 emsg_severe = TRUE; 3193 EMSG(_(e_trailing)); 3194 } 3195 else 3196 eap->nextcmd = check_nextcmd(arg); 3197 } 3198 3199 end: 3200 dict_unref(fudi.fd_dict); 3201 vim_free(tofree); 3202 } 3203 3204 /* 3205 * ":unlet[!] var1 ... " command. 3206 */ 3207 void 3208 ex_unlet(eap) 3209 exarg_T *eap; 3210 { 3211 ex_unletlock(eap, eap->arg, 0); 3212 } 3213 3214 /* 3215 * ":lockvar" and ":unlockvar" commands 3216 */ 3217 void 3218 ex_lockvar(eap) 3219 exarg_T *eap; 3220 { 3221 char_u *arg = eap->arg; 3222 int deep = 2; 3223 3224 if (eap->forceit) 3225 deep = -1; 3226 else if (vim_isdigit(*arg)) 3227 { 3228 deep = getdigits(&arg); 3229 arg = skipwhite(arg); 3230 } 3231 3232 ex_unletlock(eap, arg, deep); 3233 } 3234 3235 /* 3236 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3237 */ 3238 static void 3239 ex_unletlock(eap, argstart, deep) 3240 exarg_T *eap; 3241 char_u *argstart; 3242 int deep; 3243 { 3244 char_u *arg = argstart; 3245 char_u *name_end; 3246 int error = FALSE; 3247 lval_T lv; 3248 3249 do 3250 { 3251 /* Parse the name and find the end. */ 3252 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3253 FNE_CHECK_START); 3254 if (lv.ll_name == NULL) 3255 error = TRUE; /* error but continue parsing */ 3256 if (name_end == NULL || (!vim_iswhite(*name_end) 3257 && !ends_excmd(*name_end))) 3258 { 3259 if (name_end != NULL) 3260 { 3261 emsg_severe = TRUE; 3262 EMSG(_(e_trailing)); 3263 } 3264 if (!(eap->skip || error)) 3265 clear_lval(&lv); 3266 break; 3267 } 3268 3269 if (!error && !eap->skip) 3270 { 3271 if (eap->cmdidx == CMD_unlet) 3272 { 3273 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3274 error = TRUE; 3275 } 3276 else 3277 { 3278 if (do_lock_var(&lv, name_end, deep, 3279 eap->cmdidx == CMD_lockvar) == FAIL) 3280 error = TRUE; 3281 } 3282 } 3283 3284 if (!eap->skip) 3285 clear_lval(&lv); 3286 3287 arg = skipwhite(name_end); 3288 } while (!ends_excmd(*arg)); 3289 3290 eap->nextcmd = check_nextcmd(arg); 3291 } 3292 3293 static int 3294 do_unlet_var(lp, name_end, forceit) 3295 lval_T *lp; 3296 char_u *name_end; 3297 int forceit; 3298 { 3299 int ret = OK; 3300 int cc; 3301 3302 if (lp->ll_tv == NULL) 3303 { 3304 cc = *name_end; 3305 *name_end = NUL; 3306 3307 /* Normal name or expanded name. */ 3308 if (check_changedtick(lp->ll_name)) 3309 ret = FAIL; 3310 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3311 ret = FAIL; 3312 *name_end = cc; 3313 } 3314 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3315 return FAIL; 3316 else if (lp->ll_range) 3317 { 3318 listitem_T *li; 3319 3320 /* Delete a range of List items. */ 3321 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3322 { 3323 li = lp->ll_li->li_next; 3324 listitem_remove(lp->ll_list, lp->ll_li); 3325 lp->ll_li = li; 3326 ++lp->ll_n1; 3327 } 3328 } 3329 else 3330 { 3331 if (lp->ll_list != NULL) 3332 /* unlet a List item. */ 3333 listitem_remove(lp->ll_list, lp->ll_li); 3334 else 3335 /* unlet a Dictionary item. */ 3336 dictitem_remove(lp->ll_dict, lp->ll_di); 3337 } 3338 3339 return ret; 3340 } 3341 3342 /* 3343 * "unlet" a variable. Return OK if it existed, FAIL if not. 3344 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3345 */ 3346 int 3347 do_unlet(name, forceit) 3348 char_u *name; 3349 int forceit; 3350 { 3351 hashtab_T *ht; 3352 hashitem_T *hi; 3353 char_u *varname; 3354 3355 ht = find_var_ht(name, &varname); 3356 if (ht != NULL && *varname != NUL) 3357 { 3358 hi = hash_find(ht, varname); 3359 if (!HASHITEM_EMPTY(hi)) 3360 { 3361 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3362 return FAIL; 3363 delete_var(ht, hi); 3364 return OK; 3365 } 3366 } 3367 if (forceit) 3368 return OK; 3369 EMSG2(_("E108: No such variable: \"%s\""), name); 3370 return FAIL; 3371 } 3372 3373 /* 3374 * Lock or unlock variable indicated by "lp". 3375 * "deep" is the levels to go (-1 for unlimited); 3376 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3377 */ 3378 static int 3379 do_lock_var(lp, name_end, deep, lock) 3380 lval_T *lp; 3381 char_u *name_end; 3382 int deep; 3383 int lock; 3384 { 3385 int ret = OK; 3386 int cc; 3387 dictitem_T *di; 3388 3389 if (deep == 0) /* nothing to do */ 3390 return OK; 3391 3392 if (lp->ll_tv == NULL) 3393 { 3394 cc = *name_end; 3395 *name_end = NUL; 3396 3397 /* Normal name or expanded name. */ 3398 if (check_changedtick(lp->ll_name)) 3399 ret = FAIL; 3400 else 3401 { 3402 di = find_var(lp->ll_name, NULL); 3403 if (di == NULL) 3404 ret = FAIL; 3405 else 3406 { 3407 if (lock) 3408 di->di_flags |= DI_FLAGS_LOCK; 3409 else 3410 di->di_flags &= ~DI_FLAGS_LOCK; 3411 item_lock(&di->di_tv, deep, lock); 3412 } 3413 } 3414 *name_end = cc; 3415 } 3416 else if (lp->ll_range) 3417 { 3418 listitem_T *li = lp->ll_li; 3419 3420 /* (un)lock a range of List items. */ 3421 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3422 { 3423 item_lock(&li->li_tv, deep, lock); 3424 li = li->li_next; 3425 ++lp->ll_n1; 3426 } 3427 } 3428 else if (lp->ll_list != NULL) 3429 /* (un)lock a List item. */ 3430 item_lock(&lp->ll_li->li_tv, deep, lock); 3431 else 3432 /* un(lock) a Dictionary item. */ 3433 item_lock(&lp->ll_di->di_tv, deep, lock); 3434 3435 return ret; 3436 } 3437 3438 /* 3439 * Lock or unlock an item. "deep" is nr of levels to go. 3440 */ 3441 static void 3442 item_lock(tv, deep, lock) 3443 typval_T *tv; 3444 int deep; 3445 int lock; 3446 { 3447 static int recurse = 0; 3448 list_T *l; 3449 listitem_T *li; 3450 dict_T *d; 3451 hashitem_T *hi; 3452 int todo; 3453 3454 if (recurse >= DICT_MAXNEST) 3455 { 3456 EMSG(_("E743: variable nested too deep for (un)lock")); 3457 return; 3458 } 3459 if (deep == 0) 3460 return; 3461 ++recurse; 3462 3463 /* lock/unlock the item itself */ 3464 if (lock) 3465 tv->v_lock |= VAR_LOCKED; 3466 else 3467 tv->v_lock &= ~VAR_LOCKED; 3468 3469 switch (tv->v_type) 3470 { 3471 case VAR_LIST: 3472 if ((l = tv->vval.v_list) != NULL) 3473 { 3474 if (lock) 3475 l->lv_lock |= VAR_LOCKED; 3476 else 3477 l->lv_lock &= ~VAR_LOCKED; 3478 if (deep < 0 || deep > 1) 3479 /* recursive: lock/unlock the items the List contains */ 3480 for (li = l->lv_first; li != NULL; li = li->li_next) 3481 item_lock(&li->li_tv, deep - 1, lock); 3482 } 3483 break; 3484 case VAR_DICT: 3485 if ((d = tv->vval.v_dict) != NULL) 3486 { 3487 if (lock) 3488 d->dv_lock |= VAR_LOCKED; 3489 else 3490 d->dv_lock &= ~VAR_LOCKED; 3491 if (deep < 0 || deep > 1) 3492 { 3493 /* recursive: lock/unlock the items the List contains */ 3494 todo = (int)d->dv_hashtab.ht_used; 3495 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3496 { 3497 if (!HASHITEM_EMPTY(hi)) 3498 { 3499 --todo; 3500 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3501 } 3502 } 3503 } 3504 } 3505 } 3506 --recurse; 3507 } 3508 3509 /* 3510 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3511 * it refers to a List or Dictionary that is locked. 3512 */ 3513 static int 3514 tv_islocked(tv) 3515 typval_T *tv; 3516 { 3517 return (tv->v_lock & VAR_LOCKED) 3518 || (tv->v_type == VAR_LIST 3519 && tv->vval.v_list != NULL 3520 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3521 || (tv->v_type == VAR_DICT 3522 && tv->vval.v_dict != NULL 3523 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3524 } 3525 3526 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3527 /* 3528 * Delete all "menutrans_" variables. 3529 */ 3530 void 3531 del_menutrans_vars() 3532 { 3533 hashitem_T *hi; 3534 int todo; 3535 3536 hash_lock(&globvarht); 3537 todo = (int)globvarht.ht_used; 3538 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3539 { 3540 if (!HASHITEM_EMPTY(hi)) 3541 { 3542 --todo; 3543 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3544 delete_var(&globvarht, hi); 3545 } 3546 } 3547 hash_unlock(&globvarht); 3548 } 3549 #endif 3550 3551 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3552 3553 /* 3554 * Local string buffer for the next two functions to store a variable name 3555 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3556 * get_user_var_name(). 3557 */ 3558 3559 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3560 3561 static char_u *varnamebuf = NULL; 3562 static int varnamebuflen = 0; 3563 3564 /* 3565 * Function to concatenate a prefix and a variable name. 3566 */ 3567 static char_u * 3568 cat_prefix_varname(prefix, name) 3569 int prefix; 3570 char_u *name; 3571 { 3572 int len; 3573 3574 len = (int)STRLEN(name) + 3; 3575 if (len > varnamebuflen) 3576 { 3577 vim_free(varnamebuf); 3578 len += 10; /* some additional space */ 3579 varnamebuf = alloc(len); 3580 if (varnamebuf == NULL) 3581 { 3582 varnamebuflen = 0; 3583 return NULL; 3584 } 3585 varnamebuflen = len; 3586 } 3587 *varnamebuf = prefix; 3588 varnamebuf[1] = ':'; 3589 STRCPY(varnamebuf + 2, name); 3590 return varnamebuf; 3591 } 3592 3593 /* 3594 * Function given to ExpandGeneric() to obtain the list of user defined 3595 * (global/buffer/window/built-in) variable names. 3596 */ 3597 /*ARGSUSED*/ 3598 char_u * 3599 get_user_var_name(xp, idx) 3600 expand_T *xp; 3601 int idx; 3602 { 3603 static long_u gdone; 3604 static long_u bdone; 3605 static long_u wdone; 3606 #ifdef FEAT_WINDOWS 3607 static long_u tdone; 3608 #endif 3609 static int vidx; 3610 static hashitem_T *hi; 3611 hashtab_T *ht; 3612 3613 if (idx == 0) 3614 { 3615 gdone = bdone = wdone = vidx = 0; 3616 #ifdef FEAT_WINDOWS 3617 tdone = 0; 3618 #endif 3619 } 3620 3621 /* Global variables */ 3622 if (gdone < globvarht.ht_used) 3623 { 3624 if (gdone++ == 0) 3625 hi = globvarht.ht_array; 3626 else 3627 ++hi; 3628 while (HASHITEM_EMPTY(hi)) 3629 ++hi; 3630 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3631 return cat_prefix_varname('g', hi->hi_key); 3632 return hi->hi_key; 3633 } 3634 3635 /* b: variables */ 3636 ht = &curbuf->b_vars.dv_hashtab; 3637 if (bdone < ht->ht_used) 3638 { 3639 if (bdone++ == 0) 3640 hi = ht->ht_array; 3641 else 3642 ++hi; 3643 while (HASHITEM_EMPTY(hi)) 3644 ++hi; 3645 return cat_prefix_varname('b', hi->hi_key); 3646 } 3647 if (bdone == ht->ht_used) 3648 { 3649 ++bdone; 3650 return (char_u *)"b:changedtick"; 3651 } 3652 3653 /* w: variables */ 3654 ht = &curwin->w_vars.dv_hashtab; 3655 if (wdone < ht->ht_used) 3656 { 3657 if (wdone++ == 0) 3658 hi = ht->ht_array; 3659 else 3660 ++hi; 3661 while (HASHITEM_EMPTY(hi)) 3662 ++hi; 3663 return cat_prefix_varname('w', hi->hi_key); 3664 } 3665 3666 #ifdef FEAT_WINDOWS 3667 /* t: variables */ 3668 ht = &curtab->tp_vars.dv_hashtab; 3669 if (tdone < ht->ht_used) 3670 { 3671 if (tdone++ == 0) 3672 hi = ht->ht_array; 3673 else 3674 ++hi; 3675 while (HASHITEM_EMPTY(hi)) 3676 ++hi; 3677 return cat_prefix_varname('t', hi->hi_key); 3678 } 3679 #endif 3680 3681 /* v: variables */ 3682 if (vidx < VV_LEN) 3683 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3684 3685 vim_free(varnamebuf); 3686 varnamebuf = NULL; 3687 varnamebuflen = 0; 3688 return NULL; 3689 } 3690 3691 #endif /* FEAT_CMDL_COMPL */ 3692 3693 /* 3694 * types for expressions. 3695 */ 3696 typedef enum 3697 { 3698 TYPE_UNKNOWN = 0 3699 , TYPE_EQUAL /* == */ 3700 , TYPE_NEQUAL /* != */ 3701 , TYPE_GREATER /* > */ 3702 , TYPE_GEQUAL /* >= */ 3703 , TYPE_SMALLER /* < */ 3704 , TYPE_SEQUAL /* <= */ 3705 , TYPE_MATCH /* =~ */ 3706 , TYPE_NOMATCH /* !~ */ 3707 } exptype_T; 3708 3709 /* 3710 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3711 * executed. The function may return OK, but the rettv will be of type 3712 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3713 */ 3714 3715 /* 3716 * Handle zero level expression. 3717 * This calls eval1() and handles error message and nextcmd. 3718 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3719 * Note: "rettv.v_lock" is not set. 3720 * Return OK or FAIL. 3721 */ 3722 static int 3723 eval0(arg, rettv, nextcmd, evaluate) 3724 char_u *arg; 3725 typval_T *rettv; 3726 char_u **nextcmd; 3727 int evaluate; 3728 { 3729 int ret; 3730 char_u *p; 3731 3732 p = skipwhite(arg); 3733 ret = eval1(&p, rettv, evaluate); 3734 if (ret == FAIL || !ends_excmd(*p)) 3735 { 3736 if (ret != FAIL) 3737 clear_tv(rettv); 3738 /* 3739 * Report the invalid expression unless the expression evaluation has 3740 * been cancelled due to an aborting error, an interrupt, or an 3741 * exception. 3742 */ 3743 if (!aborting()) 3744 EMSG2(_(e_invexpr2), arg); 3745 ret = FAIL; 3746 } 3747 if (nextcmd != NULL) 3748 *nextcmd = check_nextcmd(p); 3749 3750 return ret; 3751 } 3752 3753 /* 3754 * Handle top level expression: 3755 * expr1 ? expr0 : expr0 3756 * 3757 * "arg" must point to the first non-white of the expression. 3758 * "arg" is advanced to the next non-white after the recognized expression. 3759 * 3760 * Note: "rettv.v_lock" is not set. 3761 * 3762 * Return OK or FAIL. 3763 */ 3764 static int 3765 eval1(arg, rettv, evaluate) 3766 char_u **arg; 3767 typval_T *rettv; 3768 int evaluate; 3769 { 3770 int result; 3771 typval_T var2; 3772 3773 /* 3774 * Get the first variable. 3775 */ 3776 if (eval2(arg, rettv, evaluate) == FAIL) 3777 return FAIL; 3778 3779 if ((*arg)[0] == '?') 3780 { 3781 result = FALSE; 3782 if (evaluate) 3783 { 3784 int error = FALSE; 3785 3786 if (get_tv_number_chk(rettv, &error) != 0) 3787 result = TRUE; 3788 clear_tv(rettv); 3789 if (error) 3790 return FAIL; 3791 } 3792 3793 /* 3794 * Get the second variable. 3795 */ 3796 *arg = skipwhite(*arg + 1); 3797 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3798 return FAIL; 3799 3800 /* 3801 * Check for the ":". 3802 */ 3803 if ((*arg)[0] != ':') 3804 { 3805 EMSG(_("E109: Missing ':' after '?'")); 3806 if (evaluate && result) 3807 clear_tv(rettv); 3808 return FAIL; 3809 } 3810 3811 /* 3812 * Get the third variable. 3813 */ 3814 *arg = skipwhite(*arg + 1); 3815 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3816 { 3817 if (evaluate && result) 3818 clear_tv(rettv); 3819 return FAIL; 3820 } 3821 if (evaluate && !result) 3822 *rettv = var2; 3823 } 3824 3825 return OK; 3826 } 3827 3828 /* 3829 * Handle first level expression: 3830 * expr2 || expr2 || expr2 logical OR 3831 * 3832 * "arg" must point to the first non-white of the expression. 3833 * "arg" is advanced to the next non-white after the recognized expression. 3834 * 3835 * Return OK or FAIL. 3836 */ 3837 static int 3838 eval2(arg, rettv, evaluate) 3839 char_u **arg; 3840 typval_T *rettv; 3841 int evaluate; 3842 { 3843 typval_T var2; 3844 long result; 3845 int first; 3846 int error = FALSE; 3847 3848 /* 3849 * Get the first variable. 3850 */ 3851 if (eval3(arg, rettv, evaluate) == FAIL) 3852 return FAIL; 3853 3854 /* 3855 * Repeat until there is no following "||". 3856 */ 3857 first = TRUE; 3858 result = FALSE; 3859 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3860 { 3861 if (evaluate && first) 3862 { 3863 if (get_tv_number_chk(rettv, &error) != 0) 3864 result = TRUE; 3865 clear_tv(rettv); 3866 if (error) 3867 return FAIL; 3868 first = FALSE; 3869 } 3870 3871 /* 3872 * Get the second variable. 3873 */ 3874 *arg = skipwhite(*arg + 2); 3875 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3876 return FAIL; 3877 3878 /* 3879 * Compute the result. 3880 */ 3881 if (evaluate && !result) 3882 { 3883 if (get_tv_number_chk(&var2, &error) != 0) 3884 result = TRUE; 3885 clear_tv(&var2); 3886 if (error) 3887 return FAIL; 3888 } 3889 if (evaluate) 3890 { 3891 rettv->v_type = VAR_NUMBER; 3892 rettv->vval.v_number = result; 3893 } 3894 } 3895 3896 return OK; 3897 } 3898 3899 /* 3900 * Handle second level expression: 3901 * expr3 && expr3 && expr3 logical AND 3902 * 3903 * "arg" must point to the first non-white of the expression. 3904 * "arg" is advanced to the next non-white after the recognized expression. 3905 * 3906 * Return OK or FAIL. 3907 */ 3908 static int 3909 eval3(arg, rettv, evaluate) 3910 char_u **arg; 3911 typval_T *rettv; 3912 int evaluate; 3913 { 3914 typval_T var2; 3915 long result; 3916 int first; 3917 int error = FALSE; 3918 3919 /* 3920 * Get the first variable. 3921 */ 3922 if (eval4(arg, rettv, evaluate) == FAIL) 3923 return FAIL; 3924 3925 /* 3926 * Repeat until there is no following "&&". 3927 */ 3928 first = TRUE; 3929 result = TRUE; 3930 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3931 { 3932 if (evaluate && first) 3933 { 3934 if (get_tv_number_chk(rettv, &error) == 0) 3935 result = FALSE; 3936 clear_tv(rettv); 3937 if (error) 3938 return FAIL; 3939 first = FALSE; 3940 } 3941 3942 /* 3943 * Get the second variable. 3944 */ 3945 *arg = skipwhite(*arg + 2); 3946 if (eval4(arg, &var2, evaluate && result) == FAIL) 3947 return FAIL; 3948 3949 /* 3950 * Compute the result. 3951 */ 3952 if (evaluate && result) 3953 { 3954 if (get_tv_number_chk(&var2, &error) == 0) 3955 result = FALSE; 3956 clear_tv(&var2); 3957 if (error) 3958 return FAIL; 3959 } 3960 if (evaluate) 3961 { 3962 rettv->v_type = VAR_NUMBER; 3963 rettv->vval.v_number = result; 3964 } 3965 } 3966 3967 return OK; 3968 } 3969 3970 /* 3971 * Handle third level expression: 3972 * var1 == var2 3973 * var1 =~ var2 3974 * var1 != var2 3975 * var1 !~ var2 3976 * var1 > var2 3977 * var1 >= var2 3978 * var1 < var2 3979 * var1 <= var2 3980 * var1 is var2 3981 * var1 isnot var2 3982 * 3983 * "arg" must point to the first non-white of the expression. 3984 * "arg" is advanced to the next non-white after the recognized expression. 3985 * 3986 * Return OK or FAIL. 3987 */ 3988 static int 3989 eval4(arg, rettv, evaluate) 3990 char_u **arg; 3991 typval_T *rettv; 3992 int evaluate; 3993 { 3994 typval_T var2; 3995 char_u *p; 3996 int i; 3997 exptype_T type = TYPE_UNKNOWN; 3998 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3999 int len = 2; 4000 long n1, n2; 4001 char_u *s1, *s2; 4002 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4003 regmatch_T regmatch; 4004 int ic; 4005 char_u *save_cpo; 4006 4007 /* 4008 * Get the first variable. 4009 */ 4010 if (eval5(arg, rettv, evaluate) == FAIL) 4011 return FAIL; 4012 4013 p = *arg; 4014 switch (p[0]) 4015 { 4016 case '=': if (p[1] == '=') 4017 type = TYPE_EQUAL; 4018 else if (p[1] == '~') 4019 type = TYPE_MATCH; 4020 break; 4021 case '!': if (p[1] == '=') 4022 type = TYPE_NEQUAL; 4023 else if (p[1] == '~') 4024 type = TYPE_NOMATCH; 4025 break; 4026 case '>': if (p[1] != '=') 4027 { 4028 type = TYPE_GREATER; 4029 len = 1; 4030 } 4031 else 4032 type = TYPE_GEQUAL; 4033 break; 4034 case '<': if (p[1] != '=') 4035 { 4036 type = TYPE_SMALLER; 4037 len = 1; 4038 } 4039 else 4040 type = TYPE_SEQUAL; 4041 break; 4042 case 'i': if (p[1] == 's') 4043 { 4044 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4045 len = 5; 4046 if (!vim_isIDc(p[len])) 4047 { 4048 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4049 type_is = TRUE; 4050 } 4051 } 4052 break; 4053 } 4054 4055 /* 4056 * If there is a comparitive operator, use it. 4057 */ 4058 if (type != TYPE_UNKNOWN) 4059 { 4060 /* extra question mark appended: ignore case */ 4061 if (p[len] == '?') 4062 { 4063 ic = TRUE; 4064 ++len; 4065 } 4066 /* extra '#' appended: match case */ 4067 else if (p[len] == '#') 4068 { 4069 ic = FALSE; 4070 ++len; 4071 } 4072 /* nothing appened: use 'ignorecase' */ 4073 else 4074 ic = p_ic; 4075 4076 /* 4077 * Get the second variable. 4078 */ 4079 *arg = skipwhite(p + len); 4080 if (eval5(arg, &var2, evaluate) == FAIL) 4081 { 4082 clear_tv(rettv); 4083 return FAIL; 4084 } 4085 4086 if (evaluate) 4087 { 4088 if (type_is && rettv->v_type != var2.v_type) 4089 { 4090 /* For "is" a different type always means FALSE, for "notis" 4091 * it means TRUE. */ 4092 n1 = (type == TYPE_NEQUAL); 4093 } 4094 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4095 { 4096 if (type_is) 4097 { 4098 n1 = (rettv->v_type == var2.v_type 4099 && rettv->vval.v_list == var2.vval.v_list); 4100 if (type == TYPE_NEQUAL) 4101 n1 = !n1; 4102 } 4103 else if (rettv->v_type != var2.v_type 4104 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4105 { 4106 if (rettv->v_type != var2.v_type) 4107 EMSG(_("E691: Can only compare List with List")); 4108 else 4109 EMSG(_("E692: Invalid operation for Lists")); 4110 clear_tv(rettv); 4111 clear_tv(&var2); 4112 return FAIL; 4113 } 4114 else 4115 { 4116 /* Compare two Lists for being equal or unequal. */ 4117 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 4118 if (type == TYPE_NEQUAL) 4119 n1 = !n1; 4120 } 4121 } 4122 4123 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4124 { 4125 if (type_is) 4126 { 4127 n1 = (rettv->v_type == var2.v_type 4128 && rettv->vval.v_dict == var2.vval.v_dict); 4129 if (type == TYPE_NEQUAL) 4130 n1 = !n1; 4131 } 4132 else if (rettv->v_type != var2.v_type 4133 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4134 { 4135 if (rettv->v_type != var2.v_type) 4136 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4137 else 4138 EMSG(_("E736: Invalid operation for Dictionary")); 4139 clear_tv(rettv); 4140 clear_tv(&var2); 4141 return FAIL; 4142 } 4143 else 4144 { 4145 /* Compare two Dictionaries for being equal or unequal. */ 4146 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4147 if (type == TYPE_NEQUAL) 4148 n1 = !n1; 4149 } 4150 } 4151 4152 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4153 { 4154 if (rettv->v_type != var2.v_type 4155 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4156 { 4157 if (rettv->v_type != var2.v_type) 4158 EMSG(_("E693: Can only compare Funcref with Funcref")); 4159 else 4160 EMSG(_("E694: Invalid operation for Funcrefs")); 4161 clear_tv(rettv); 4162 clear_tv(&var2); 4163 return FAIL; 4164 } 4165 else 4166 { 4167 /* Compare two Funcrefs for being equal or unequal. */ 4168 if (rettv->vval.v_string == NULL 4169 || var2.vval.v_string == NULL) 4170 n1 = FALSE; 4171 else 4172 n1 = STRCMP(rettv->vval.v_string, 4173 var2.vval.v_string) == 0; 4174 if (type == TYPE_NEQUAL) 4175 n1 = !n1; 4176 } 4177 } 4178 4179 /* 4180 * If one of the two variables is a number, compare as a number. 4181 * When using "=~" or "!~", always compare as string. 4182 */ 4183 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4184 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4185 { 4186 n1 = get_tv_number(rettv); 4187 n2 = get_tv_number(&var2); 4188 switch (type) 4189 { 4190 case TYPE_EQUAL: n1 = (n1 == n2); break; 4191 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4192 case TYPE_GREATER: n1 = (n1 > n2); break; 4193 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4194 case TYPE_SMALLER: n1 = (n1 < n2); break; 4195 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4196 case TYPE_UNKNOWN: 4197 case TYPE_MATCH: 4198 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4199 } 4200 } 4201 else 4202 { 4203 s1 = get_tv_string_buf(rettv, buf1); 4204 s2 = get_tv_string_buf(&var2, buf2); 4205 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4206 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4207 else 4208 i = 0; 4209 n1 = FALSE; 4210 switch (type) 4211 { 4212 case TYPE_EQUAL: n1 = (i == 0); break; 4213 case TYPE_NEQUAL: n1 = (i != 0); break; 4214 case TYPE_GREATER: n1 = (i > 0); break; 4215 case TYPE_GEQUAL: n1 = (i >= 0); break; 4216 case TYPE_SMALLER: n1 = (i < 0); break; 4217 case TYPE_SEQUAL: n1 = (i <= 0); break; 4218 4219 case TYPE_MATCH: 4220 case TYPE_NOMATCH: 4221 /* avoid 'l' flag in 'cpoptions' */ 4222 save_cpo = p_cpo; 4223 p_cpo = (char_u *)""; 4224 regmatch.regprog = vim_regcomp(s2, 4225 RE_MAGIC + RE_STRING); 4226 regmatch.rm_ic = ic; 4227 if (regmatch.regprog != NULL) 4228 { 4229 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4230 vim_free(regmatch.regprog); 4231 if (type == TYPE_NOMATCH) 4232 n1 = !n1; 4233 } 4234 p_cpo = save_cpo; 4235 break; 4236 4237 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4238 } 4239 } 4240 clear_tv(rettv); 4241 clear_tv(&var2); 4242 rettv->v_type = VAR_NUMBER; 4243 rettv->vval.v_number = n1; 4244 } 4245 } 4246 4247 return OK; 4248 } 4249 4250 /* 4251 * Handle fourth level expression: 4252 * + number addition 4253 * - number subtraction 4254 * . string concatenation 4255 * 4256 * "arg" must point to the first non-white of the expression. 4257 * "arg" is advanced to the next non-white after the recognized expression. 4258 * 4259 * Return OK or FAIL. 4260 */ 4261 static int 4262 eval5(arg, rettv, evaluate) 4263 char_u **arg; 4264 typval_T *rettv; 4265 int evaluate; 4266 { 4267 typval_T var2; 4268 typval_T var3; 4269 int op; 4270 long n1, n2; 4271 char_u *s1, *s2; 4272 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4273 char_u *p; 4274 4275 /* 4276 * Get the first variable. 4277 */ 4278 if (eval6(arg, rettv, evaluate) == FAIL) 4279 return FAIL; 4280 4281 /* 4282 * Repeat computing, until no '+', '-' or '.' is following. 4283 */ 4284 for (;;) 4285 { 4286 op = **arg; 4287 if (op != '+' && op != '-' && op != '.') 4288 break; 4289 4290 if (op != '+' || rettv->v_type != VAR_LIST) 4291 { 4292 /* For "list + ...", an illegal use of the first operand as 4293 * a number cannot be determined before evaluating the 2nd 4294 * operand: if this is also a list, all is ok. 4295 * For "something . ...", "something - ..." or "non-list + ...", 4296 * we know that the first operand needs to be a string or number 4297 * without evaluating the 2nd operand. So check before to avoid 4298 * side effects after an error. */ 4299 if (evaluate && get_tv_string_chk(rettv) == NULL) 4300 { 4301 clear_tv(rettv); 4302 return FAIL; 4303 } 4304 } 4305 4306 /* 4307 * Get the second variable. 4308 */ 4309 *arg = skipwhite(*arg + 1); 4310 if (eval6(arg, &var2, evaluate) == FAIL) 4311 { 4312 clear_tv(rettv); 4313 return FAIL; 4314 } 4315 4316 if (evaluate) 4317 { 4318 /* 4319 * Compute the result. 4320 */ 4321 if (op == '.') 4322 { 4323 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4324 s2 = get_tv_string_buf_chk(&var2, buf2); 4325 if (s2 == NULL) /* type error ? */ 4326 { 4327 clear_tv(rettv); 4328 clear_tv(&var2); 4329 return FAIL; 4330 } 4331 p = concat_str(s1, s2); 4332 clear_tv(rettv); 4333 rettv->v_type = VAR_STRING; 4334 rettv->vval.v_string = p; 4335 } 4336 else if (op == '+' && rettv->v_type == VAR_LIST 4337 && var2.v_type == VAR_LIST) 4338 { 4339 /* concatenate Lists */ 4340 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4341 &var3) == FAIL) 4342 { 4343 clear_tv(rettv); 4344 clear_tv(&var2); 4345 return FAIL; 4346 } 4347 clear_tv(rettv); 4348 *rettv = var3; 4349 } 4350 else 4351 { 4352 int error = FALSE; 4353 4354 n1 = get_tv_number_chk(rettv, &error); 4355 if (error) 4356 { 4357 /* This can only happen for "list + non-list". 4358 * For "non-list + ..." or "something - ...", we returned 4359 * before evaluating the 2nd operand. */ 4360 clear_tv(rettv); 4361 return FAIL; 4362 } 4363 n2 = get_tv_number_chk(&var2, &error); 4364 if (error) 4365 { 4366 clear_tv(rettv); 4367 clear_tv(&var2); 4368 return FAIL; 4369 } 4370 clear_tv(rettv); 4371 if (op == '+') 4372 n1 = n1 + n2; 4373 else 4374 n1 = n1 - n2; 4375 rettv->v_type = VAR_NUMBER; 4376 rettv->vval.v_number = n1; 4377 } 4378 clear_tv(&var2); 4379 } 4380 } 4381 return OK; 4382 } 4383 4384 /* 4385 * Handle fifth level expression: 4386 * * number multiplication 4387 * / number division 4388 * % number modulo 4389 * 4390 * "arg" must point to the first non-white of the expression. 4391 * "arg" is advanced to the next non-white after the recognized expression. 4392 * 4393 * Return OK or FAIL. 4394 */ 4395 static int 4396 eval6(arg, rettv, evaluate) 4397 char_u **arg; 4398 typval_T *rettv; 4399 int evaluate; 4400 { 4401 typval_T var2; 4402 int op; 4403 long n1, n2; 4404 int error = FALSE; 4405 4406 /* 4407 * Get the first variable. 4408 */ 4409 if (eval7(arg, rettv, evaluate) == FAIL) 4410 return FAIL; 4411 4412 /* 4413 * Repeat computing, until no '*', '/' or '%' is following. 4414 */ 4415 for (;;) 4416 { 4417 op = **arg; 4418 if (op != '*' && op != '/' && op != '%') 4419 break; 4420 4421 if (evaluate) 4422 { 4423 n1 = get_tv_number_chk(rettv, &error); 4424 clear_tv(rettv); 4425 if (error) 4426 return FAIL; 4427 } 4428 else 4429 n1 = 0; 4430 4431 /* 4432 * Get the second variable. 4433 */ 4434 *arg = skipwhite(*arg + 1); 4435 if (eval7(arg, &var2, evaluate) == FAIL) 4436 return FAIL; 4437 4438 if (evaluate) 4439 { 4440 n2 = get_tv_number_chk(&var2, &error); 4441 clear_tv(&var2); 4442 if (error) 4443 return FAIL; 4444 4445 /* 4446 * Compute the result. 4447 */ 4448 if (op == '*') 4449 n1 = n1 * n2; 4450 else if (op == '/') 4451 { 4452 if (n2 == 0) /* give an error message? */ 4453 n1 = 0x7fffffffL; 4454 else 4455 n1 = n1 / n2; 4456 } 4457 else 4458 { 4459 if (n2 == 0) /* give an error message? */ 4460 n1 = 0; 4461 else 4462 n1 = n1 % n2; 4463 } 4464 rettv->v_type = VAR_NUMBER; 4465 rettv->vval.v_number = n1; 4466 } 4467 } 4468 4469 return OK; 4470 } 4471 4472 /* 4473 * Handle sixth level expression: 4474 * number number constant 4475 * "string" string contstant 4476 * 'string' literal string contstant 4477 * &option-name option value 4478 * @r register contents 4479 * identifier variable value 4480 * function() function call 4481 * $VAR environment variable 4482 * (expression) nested expression 4483 * [expr, expr] List 4484 * {key: val, key: val} Dictionary 4485 * 4486 * Also handle: 4487 * ! in front logical NOT 4488 * - in front unary minus 4489 * + in front unary plus (ignored) 4490 * trailing [] subscript in String or List 4491 * trailing .name entry in Dictionary 4492 * 4493 * "arg" must point to the first non-white of the expression. 4494 * "arg" is advanced to the next non-white after the recognized expression. 4495 * 4496 * Return OK or FAIL. 4497 */ 4498 static int 4499 eval7(arg, rettv, evaluate) 4500 char_u **arg; 4501 typval_T *rettv; 4502 int evaluate; 4503 { 4504 long n; 4505 int len; 4506 char_u *s; 4507 int val; 4508 char_u *start_leader, *end_leader; 4509 int ret = OK; 4510 char_u *alias; 4511 4512 /* 4513 * Initialise variable so that clear_tv() can't mistake this for a 4514 * string and free a string that isn't there. 4515 */ 4516 rettv->v_type = VAR_UNKNOWN; 4517 4518 /* 4519 * Skip '!' and '-' characters. They are handled later. 4520 */ 4521 start_leader = *arg; 4522 while (**arg == '!' || **arg == '-' || **arg == '+') 4523 *arg = skipwhite(*arg + 1); 4524 end_leader = *arg; 4525 4526 switch (**arg) 4527 { 4528 /* 4529 * Number constant. 4530 */ 4531 case '0': 4532 case '1': 4533 case '2': 4534 case '3': 4535 case '4': 4536 case '5': 4537 case '6': 4538 case '7': 4539 case '8': 4540 case '9': 4541 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4542 *arg += len; 4543 if (evaluate) 4544 { 4545 rettv->v_type = VAR_NUMBER; 4546 rettv->vval.v_number = n; 4547 } 4548 break; 4549 4550 /* 4551 * String constant: "string". 4552 */ 4553 case '"': ret = get_string_tv(arg, rettv, evaluate); 4554 break; 4555 4556 /* 4557 * Literal string constant: 'str''ing'. 4558 */ 4559 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4560 break; 4561 4562 /* 4563 * List: [expr, expr] 4564 */ 4565 case '[': ret = get_list_tv(arg, rettv, evaluate); 4566 break; 4567 4568 /* 4569 * Dictionary: {key: val, key: val} 4570 */ 4571 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4572 break; 4573 4574 /* 4575 * Option value: &name 4576 */ 4577 case '&': ret = get_option_tv(arg, rettv, evaluate); 4578 break; 4579 4580 /* 4581 * Environment variable: $VAR. 4582 */ 4583 case '$': ret = get_env_tv(arg, rettv, evaluate); 4584 break; 4585 4586 /* 4587 * Register contents: @r. 4588 */ 4589 case '@': ++*arg; 4590 if (evaluate) 4591 { 4592 rettv->v_type = VAR_STRING; 4593 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4594 } 4595 if (**arg != NUL) 4596 ++*arg; 4597 break; 4598 4599 /* 4600 * nested expression: (expression). 4601 */ 4602 case '(': *arg = skipwhite(*arg + 1); 4603 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4604 if (**arg == ')') 4605 ++*arg; 4606 else if (ret == OK) 4607 { 4608 EMSG(_("E110: Missing ')'")); 4609 clear_tv(rettv); 4610 ret = FAIL; 4611 } 4612 break; 4613 4614 default: ret = NOTDONE; 4615 break; 4616 } 4617 4618 if (ret == NOTDONE) 4619 { 4620 /* 4621 * Must be a variable or function name. 4622 * Can also be a curly-braces kind of name: {expr}. 4623 */ 4624 s = *arg; 4625 len = get_name_len(arg, &alias, evaluate, TRUE); 4626 if (alias != NULL) 4627 s = alias; 4628 4629 if (len <= 0) 4630 ret = FAIL; 4631 else 4632 { 4633 if (**arg == '(') /* recursive! */ 4634 { 4635 /* If "s" is the name of a variable of type VAR_FUNC 4636 * use its contents. */ 4637 s = deref_func_name(s, &len); 4638 4639 /* Invoke the function. */ 4640 ret = get_func_tv(s, len, rettv, arg, 4641 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4642 &len, evaluate, NULL); 4643 /* Stop the expression evaluation when immediately 4644 * aborting on error, or when an interrupt occurred or 4645 * an exception was thrown but not caught. */ 4646 if (aborting()) 4647 { 4648 if (ret == OK) 4649 clear_tv(rettv); 4650 ret = FAIL; 4651 } 4652 } 4653 else if (evaluate) 4654 ret = get_var_tv(s, len, rettv, TRUE); 4655 else 4656 ret = OK; 4657 } 4658 4659 if (alias != NULL) 4660 vim_free(alias); 4661 } 4662 4663 *arg = skipwhite(*arg); 4664 4665 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4666 * expr(expr). */ 4667 if (ret == OK) 4668 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4669 4670 /* 4671 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4672 */ 4673 if (ret == OK && evaluate && end_leader > start_leader) 4674 { 4675 int error = FALSE; 4676 4677 val = get_tv_number_chk(rettv, &error); 4678 if (error) 4679 { 4680 clear_tv(rettv); 4681 ret = FAIL; 4682 } 4683 else 4684 { 4685 while (end_leader > start_leader) 4686 { 4687 --end_leader; 4688 if (*end_leader == '!') 4689 val = !val; 4690 else if (*end_leader == '-') 4691 val = -val; 4692 } 4693 clear_tv(rettv); 4694 rettv->v_type = VAR_NUMBER; 4695 rettv->vval.v_number = val; 4696 } 4697 } 4698 4699 return ret; 4700 } 4701 4702 /* 4703 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 4704 * "*arg" points to the '[' or '.'. 4705 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4706 */ 4707 static int 4708 eval_index(arg, rettv, evaluate, verbose) 4709 char_u **arg; 4710 typval_T *rettv; 4711 int evaluate; 4712 int verbose; /* give error messages */ 4713 { 4714 int empty1 = FALSE, empty2 = FALSE; 4715 typval_T var1, var2; 4716 long n1, n2 = 0; 4717 long len = -1; 4718 int range = FALSE; 4719 char_u *s; 4720 char_u *key = NULL; 4721 4722 if (rettv->v_type == VAR_FUNC) 4723 { 4724 if (verbose) 4725 EMSG(_("E695: Cannot index a Funcref")); 4726 return FAIL; 4727 } 4728 4729 if (**arg == '.') 4730 { 4731 /* 4732 * dict.name 4733 */ 4734 key = *arg + 1; 4735 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4736 ; 4737 if (len == 0) 4738 return FAIL; 4739 *arg = skipwhite(key + len); 4740 } 4741 else 4742 { 4743 /* 4744 * something[idx] 4745 * 4746 * Get the (first) variable from inside the []. 4747 */ 4748 *arg = skipwhite(*arg + 1); 4749 if (**arg == ':') 4750 empty1 = TRUE; 4751 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4752 return FAIL; 4753 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4754 { 4755 /* not a number or string */ 4756 clear_tv(&var1); 4757 return FAIL; 4758 } 4759 4760 /* 4761 * Get the second variable from inside the [:]. 4762 */ 4763 if (**arg == ':') 4764 { 4765 range = TRUE; 4766 *arg = skipwhite(*arg + 1); 4767 if (**arg == ']') 4768 empty2 = TRUE; 4769 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4770 { 4771 if (!empty1) 4772 clear_tv(&var1); 4773 return FAIL; 4774 } 4775 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4776 { 4777 /* not a number or string */ 4778 if (!empty1) 4779 clear_tv(&var1); 4780 clear_tv(&var2); 4781 return FAIL; 4782 } 4783 } 4784 4785 /* Check for the ']'. */ 4786 if (**arg != ']') 4787 { 4788 if (verbose) 4789 EMSG(_(e_missbrac)); 4790 clear_tv(&var1); 4791 if (range) 4792 clear_tv(&var2); 4793 return FAIL; 4794 } 4795 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4796 } 4797 4798 if (evaluate) 4799 { 4800 n1 = 0; 4801 if (!empty1 && rettv->v_type != VAR_DICT) 4802 { 4803 n1 = get_tv_number(&var1); 4804 clear_tv(&var1); 4805 } 4806 if (range) 4807 { 4808 if (empty2) 4809 n2 = -1; 4810 else 4811 { 4812 n2 = get_tv_number(&var2); 4813 clear_tv(&var2); 4814 } 4815 } 4816 4817 switch (rettv->v_type) 4818 { 4819 case VAR_NUMBER: 4820 case VAR_STRING: 4821 s = get_tv_string(rettv); 4822 len = (long)STRLEN(s); 4823 if (range) 4824 { 4825 /* The resulting variable is a substring. If the indexes 4826 * are out of range the result is empty. */ 4827 if (n1 < 0) 4828 { 4829 n1 = len + n1; 4830 if (n1 < 0) 4831 n1 = 0; 4832 } 4833 if (n2 < 0) 4834 n2 = len + n2; 4835 else if (n2 >= len) 4836 n2 = len; 4837 if (n1 >= len || n2 < 0 || n1 > n2) 4838 s = NULL; 4839 else 4840 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4841 } 4842 else 4843 { 4844 /* The resulting variable is a string of a single 4845 * character. If the index is too big or negative the 4846 * result is empty. */ 4847 if (n1 >= len || n1 < 0) 4848 s = NULL; 4849 else 4850 s = vim_strnsave(s + n1, 1); 4851 } 4852 clear_tv(rettv); 4853 rettv->v_type = VAR_STRING; 4854 rettv->vval.v_string = s; 4855 break; 4856 4857 case VAR_LIST: 4858 len = list_len(rettv->vval.v_list); 4859 if (n1 < 0) 4860 n1 = len + n1; 4861 if (!empty1 && (n1 < 0 || n1 >= len)) 4862 { 4863 if (verbose) 4864 EMSGN(_(e_listidx), n1); 4865 return FAIL; 4866 } 4867 if (range) 4868 { 4869 list_T *l; 4870 listitem_T *item; 4871 4872 if (n2 < 0) 4873 n2 = len + n2; 4874 else if (n2 >= len) 4875 n2 = len - 1; 4876 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 4877 { 4878 if (verbose) 4879 EMSGN(_(e_listidx), n2); 4880 return FAIL; 4881 } 4882 l = list_alloc(); 4883 if (l == NULL) 4884 return FAIL; 4885 for (item = list_find(rettv->vval.v_list, n1); 4886 n1 <= n2; ++n1) 4887 { 4888 if (list_append_tv(l, &item->li_tv) == FAIL) 4889 { 4890 list_free(l); 4891 return FAIL; 4892 } 4893 item = item->li_next; 4894 } 4895 clear_tv(rettv); 4896 rettv->v_type = VAR_LIST; 4897 rettv->vval.v_list = l; 4898 ++l->lv_refcount; 4899 } 4900 else 4901 { 4902 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4903 &var1); 4904 clear_tv(rettv); 4905 *rettv = var1; 4906 } 4907 break; 4908 4909 case VAR_DICT: 4910 if (range) 4911 { 4912 if (verbose) 4913 EMSG(_(e_dictrange)); 4914 if (len == -1) 4915 clear_tv(&var1); 4916 return FAIL; 4917 } 4918 { 4919 dictitem_T *item; 4920 4921 if (len == -1) 4922 { 4923 key = get_tv_string(&var1); 4924 if (*key == NUL) 4925 { 4926 if (verbose) 4927 EMSG(_(e_emptykey)); 4928 clear_tv(&var1); 4929 return FAIL; 4930 } 4931 } 4932 4933 item = dict_find(rettv->vval.v_dict, key, (int)len); 4934 4935 if (item == NULL && verbose) 4936 EMSG2(_(e_dictkey), key); 4937 if (len == -1) 4938 clear_tv(&var1); 4939 if (item == NULL) 4940 return FAIL; 4941 4942 copy_tv(&item->di_tv, &var1); 4943 clear_tv(rettv); 4944 *rettv = var1; 4945 } 4946 break; 4947 } 4948 } 4949 4950 return OK; 4951 } 4952 4953 /* 4954 * Get an option value. 4955 * "arg" points to the '&' or '+' before the option name. 4956 * "arg" is advanced to character after the option name. 4957 * Return OK or FAIL. 4958 */ 4959 static int 4960 get_option_tv(arg, rettv, evaluate) 4961 char_u **arg; 4962 typval_T *rettv; /* when NULL, only check if option exists */ 4963 int evaluate; 4964 { 4965 char_u *option_end; 4966 long numval; 4967 char_u *stringval; 4968 int opt_type; 4969 int c; 4970 int working = (**arg == '+'); /* has("+option") */ 4971 int ret = OK; 4972 int opt_flags; 4973 4974 /* 4975 * Isolate the option name and find its value. 4976 */ 4977 option_end = find_option_end(arg, &opt_flags); 4978 if (option_end == NULL) 4979 { 4980 if (rettv != NULL) 4981 EMSG2(_("E112: Option name missing: %s"), *arg); 4982 return FAIL; 4983 } 4984 4985 if (!evaluate) 4986 { 4987 *arg = option_end; 4988 return OK; 4989 } 4990 4991 c = *option_end; 4992 *option_end = NUL; 4993 opt_type = get_option_value(*arg, &numval, 4994 rettv == NULL ? NULL : &stringval, opt_flags); 4995 4996 if (opt_type == -3) /* invalid name */ 4997 { 4998 if (rettv != NULL) 4999 EMSG2(_("E113: Unknown option: %s"), *arg); 5000 ret = FAIL; 5001 } 5002 else if (rettv != NULL) 5003 { 5004 if (opt_type == -2) /* hidden string option */ 5005 { 5006 rettv->v_type = VAR_STRING; 5007 rettv->vval.v_string = NULL; 5008 } 5009 else if (opt_type == -1) /* hidden number option */ 5010 { 5011 rettv->v_type = VAR_NUMBER; 5012 rettv->vval.v_number = 0; 5013 } 5014 else if (opt_type == 1) /* number option */ 5015 { 5016 rettv->v_type = VAR_NUMBER; 5017 rettv->vval.v_number = numval; 5018 } 5019 else /* string option */ 5020 { 5021 rettv->v_type = VAR_STRING; 5022 rettv->vval.v_string = stringval; 5023 } 5024 } 5025 else if (working && (opt_type == -2 || opt_type == -1)) 5026 ret = FAIL; 5027 5028 *option_end = c; /* put back for error messages */ 5029 *arg = option_end; 5030 5031 return ret; 5032 } 5033 5034 /* 5035 * Allocate a variable for a string constant. 5036 * Return OK or FAIL. 5037 */ 5038 static int 5039 get_string_tv(arg, rettv, evaluate) 5040 char_u **arg; 5041 typval_T *rettv; 5042 int evaluate; 5043 { 5044 char_u *p; 5045 char_u *name; 5046 int extra = 0; 5047 5048 /* 5049 * Find the end of the string, skipping backslashed characters. 5050 */ 5051 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5052 { 5053 if (*p == '\\' && p[1] != NUL) 5054 { 5055 ++p; 5056 /* A "\<x>" form occupies at least 4 characters, and produces up 5057 * to 6 characters: reserve space for 2 extra */ 5058 if (*p == '<') 5059 extra += 2; 5060 } 5061 } 5062 5063 if (*p != '"') 5064 { 5065 EMSG2(_("E114: Missing quote: %s"), *arg); 5066 return FAIL; 5067 } 5068 5069 /* If only parsing, set *arg and return here */ 5070 if (!evaluate) 5071 { 5072 *arg = p + 1; 5073 return OK; 5074 } 5075 5076 /* 5077 * Copy the string into allocated memory, handling backslashed 5078 * characters. 5079 */ 5080 name = alloc((unsigned)(p - *arg + extra)); 5081 if (name == NULL) 5082 return FAIL; 5083 rettv->v_type = VAR_STRING; 5084 rettv->vval.v_string = name; 5085 5086 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5087 { 5088 if (*p == '\\') 5089 { 5090 switch (*++p) 5091 { 5092 case 'b': *name++ = BS; ++p; break; 5093 case 'e': *name++ = ESC; ++p; break; 5094 case 'f': *name++ = FF; ++p; break; 5095 case 'n': *name++ = NL; ++p; break; 5096 case 'r': *name++ = CAR; ++p; break; 5097 case 't': *name++ = TAB; ++p; break; 5098 5099 case 'X': /* hex: "\x1", "\x12" */ 5100 case 'x': 5101 case 'u': /* Unicode: "\u0023" */ 5102 case 'U': 5103 if (vim_isxdigit(p[1])) 5104 { 5105 int n, nr; 5106 int c = toupper(*p); 5107 5108 if (c == 'X') 5109 n = 2; 5110 else 5111 n = 4; 5112 nr = 0; 5113 while (--n >= 0 && vim_isxdigit(p[1])) 5114 { 5115 ++p; 5116 nr = (nr << 4) + hex2nr(*p); 5117 } 5118 ++p; 5119 #ifdef FEAT_MBYTE 5120 /* For "\u" store the number according to 5121 * 'encoding'. */ 5122 if (c != 'X') 5123 name += (*mb_char2bytes)(nr, name); 5124 else 5125 #endif 5126 *name++ = nr; 5127 } 5128 break; 5129 5130 /* octal: "\1", "\12", "\123" */ 5131 case '0': 5132 case '1': 5133 case '2': 5134 case '3': 5135 case '4': 5136 case '5': 5137 case '6': 5138 case '7': *name = *p++ - '0'; 5139 if (*p >= '0' && *p <= '7') 5140 { 5141 *name = (*name << 3) + *p++ - '0'; 5142 if (*p >= '0' && *p <= '7') 5143 *name = (*name << 3) + *p++ - '0'; 5144 } 5145 ++name; 5146 break; 5147 5148 /* Special key, e.g.: "\<C-W>" */ 5149 case '<': extra = trans_special(&p, name, TRUE); 5150 if (extra != 0) 5151 { 5152 name += extra; 5153 break; 5154 } 5155 /* FALLTHROUGH */ 5156 5157 default: MB_COPY_CHAR(p, name); 5158 break; 5159 } 5160 } 5161 else 5162 MB_COPY_CHAR(p, name); 5163 5164 } 5165 *name = NUL; 5166 *arg = p + 1; 5167 5168 return OK; 5169 } 5170 5171 /* 5172 * Allocate a variable for a 'str''ing' constant. 5173 * Return OK or FAIL. 5174 */ 5175 static int 5176 get_lit_string_tv(arg, rettv, evaluate) 5177 char_u **arg; 5178 typval_T *rettv; 5179 int evaluate; 5180 { 5181 char_u *p; 5182 char_u *str; 5183 int reduce = 0; 5184 5185 /* 5186 * Find the end of the string, skipping ''. 5187 */ 5188 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5189 { 5190 if (*p == '\'') 5191 { 5192 if (p[1] != '\'') 5193 break; 5194 ++reduce; 5195 ++p; 5196 } 5197 } 5198 5199 if (*p != '\'') 5200 { 5201 EMSG2(_("E115: Missing quote: %s"), *arg); 5202 return FAIL; 5203 } 5204 5205 /* If only parsing return after setting "*arg" */ 5206 if (!evaluate) 5207 { 5208 *arg = p + 1; 5209 return OK; 5210 } 5211 5212 /* 5213 * Copy the string into allocated memory, handling '' to ' reduction. 5214 */ 5215 str = alloc((unsigned)((p - *arg) - reduce)); 5216 if (str == NULL) 5217 return FAIL; 5218 rettv->v_type = VAR_STRING; 5219 rettv->vval.v_string = str; 5220 5221 for (p = *arg + 1; *p != NUL; ) 5222 { 5223 if (*p == '\'') 5224 { 5225 if (p[1] != '\'') 5226 break; 5227 ++p; 5228 } 5229 MB_COPY_CHAR(p, str); 5230 } 5231 *str = NUL; 5232 *arg = p + 1; 5233 5234 return OK; 5235 } 5236 5237 /* 5238 * Allocate a variable for a List and fill it from "*arg". 5239 * Return OK or FAIL. 5240 */ 5241 static int 5242 get_list_tv(arg, rettv, evaluate) 5243 char_u **arg; 5244 typval_T *rettv; 5245 int evaluate; 5246 { 5247 list_T *l = NULL; 5248 typval_T tv; 5249 listitem_T *item; 5250 5251 if (evaluate) 5252 { 5253 l = list_alloc(); 5254 if (l == NULL) 5255 return FAIL; 5256 } 5257 5258 *arg = skipwhite(*arg + 1); 5259 while (**arg != ']' && **arg != NUL) 5260 { 5261 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5262 goto failret; 5263 if (evaluate) 5264 { 5265 item = listitem_alloc(); 5266 if (item != NULL) 5267 { 5268 item->li_tv = tv; 5269 item->li_tv.v_lock = 0; 5270 list_append(l, item); 5271 } 5272 else 5273 clear_tv(&tv); 5274 } 5275 5276 if (**arg == ']') 5277 break; 5278 if (**arg != ',') 5279 { 5280 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5281 goto failret; 5282 } 5283 *arg = skipwhite(*arg + 1); 5284 } 5285 5286 if (**arg != ']') 5287 { 5288 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5289 failret: 5290 if (evaluate) 5291 list_free(l); 5292 return FAIL; 5293 } 5294 5295 *arg = skipwhite(*arg + 1); 5296 if (evaluate) 5297 { 5298 rettv->v_type = VAR_LIST; 5299 rettv->vval.v_list = l; 5300 ++l->lv_refcount; 5301 } 5302 5303 return OK; 5304 } 5305 5306 /* 5307 * Allocate an empty header for a list. 5308 * Caller should take care of the reference count. 5309 */ 5310 list_T * 5311 list_alloc() 5312 { 5313 list_T *l; 5314 5315 l = (list_T *)alloc_clear(sizeof(list_T)); 5316 if (l != NULL) 5317 { 5318 /* Prepend the list to the list of lists for garbage collection. */ 5319 if (first_list != NULL) 5320 first_list->lv_used_prev = l; 5321 l->lv_used_prev = NULL; 5322 l->lv_used_next = first_list; 5323 first_list = l; 5324 } 5325 return l; 5326 } 5327 5328 /* 5329 * Allocate an empty list for a return value. 5330 * Returns OK or FAIL. 5331 */ 5332 static int 5333 rettv_list_alloc(rettv) 5334 typval_T *rettv; 5335 { 5336 list_T *l = list_alloc(); 5337 5338 if (l == NULL) 5339 return FAIL; 5340 5341 rettv->vval.v_list = l; 5342 rettv->v_type = VAR_LIST; 5343 ++l->lv_refcount; 5344 return OK; 5345 } 5346 5347 /* 5348 * Unreference a list: decrement the reference count and free it when it 5349 * becomes zero. 5350 */ 5351 void 5352 list_unref(l) 5353 list_T *l; 5354 { 5355 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5356 list_free(l); 5357 } 5358 5359 /* 5360 * Free a list, including all items it points to. 5361 * Ignores the reference count. 5362 */ 5363 void 5364 list_free(l) 5365 list_T *l; 5366 { 5367 listitem_T *item; 5368 5369 /* Avoid that recursive reference to the list frees us again. */ 5370 l->lv_refcount = DEL_REFCOUNT; 5371 5372 /* Remove the list from the list of lists for garbage collection. */ 5373 if (l->lv_used_prev == NULL) 5374 first_list = l->lv_used_next; 5375 else 5376 l->lv_used_prev->lv_used_next = l->lv_used_next; 5377 if (l->lv_used_next != NULL) 5378 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5379 5380 for (item = l->lv_first; item != NULL; item = l->lv_first) 5381 { 5382 /* Remove the item before deleting it. */ 5383 l->lv_first = item->li_next; 5384 listitem_free(item); 5385 } 5386 vim_free(l); 5387 } 5388 5389 /* 5390 * Allocate a list item. 5391 */ 5392 static listitem_T * 5393 listitem_alloc() 5394 { 5395 return (listitem_T *)alloc(sizeof(listitem_T)); 5396 } 5397 5398 /* 5399 * Free a list item. Also clears the value. Does not notify watchers. 5400 */ 5401 static void 5402 listitem_free(item) 5403 listitem_T *item; 5404 { 5405 clear_tv(&item->li_tv); 5406 vim_free(item); 5407 } 5408 5409 /* 5410 * Remove a list item from a List and free it. Also clears the value. 5411 */ 5412 static void 5413 listitem_remove(l, item) 5414 list_T *l; 5415 listitem_T *item; 5416 { 5417 list_remove(l, item, item); 5418 listitem_free(item); 5419 } 5420 5421 /* 5422 * Get the number of items in a list. 5423 */ 5424 static long 5425 list_len(l) 5426 list_T *l; 5427 { 5428 if (l == NULL) 5429 return 0L; 5430 return l->lv_len; 5431 } 5432 5433 /* 5434 * Return TRUE when two lists have exactly the same values. 5435 */ 5436 static int 5437 list_equal(l1, l2, ic) 5438 list_T *l1; 5439 list_T *l2; 5440 int ic; /* ignore case for strings */ 5441 { 5442 listitem_T *item1, *item2; 5443 5444 if (list_len(l1) != list_len(l2)) 5445 return FALSE; 5446 5447 for (item1 = l1->lv_first, item2 = l2->lv_first; 5448 item1 != NULL && item2 != NULL; 5449 item1 = item1->li_next, item2 = item2->li_next) 5450 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5451 return FALSE; 5452 return item1 == NULL && item2 == NULL; 5453 } 5454 5455 #if defined(FEAT_PYTHON) || defined(PROTO) 5456 /* 5457 * Return the dictitem that an entry in a hashtable points to. 5458 */ 5459 dictitem_T * 5460 dict_lookup(hi) 5461 hashitem_T *hi; 5462 { 5463 return HI2DI(hi); 5464 } 5465 #endif 5466 5467 /* 5468 * Return TRUE when two dictionaries have exactly the same key/values. 5469 */ 5470 static int 5471 dict_equal(d1, d2, ic) 5472 dict_T *d1; 5473 dict_T *d2; 5474 int ic; /* ignore case for strings */ 5475 { 5476 hashitem_T *hi; 5477 dictitem_T *item2; 5478 int todo; 5479 5480 if (dict_len(d1) != dict_len(d2)) 5481 return FALSE; 5482 5483 todo = (int)d1->dv_hashtab.ht_used; 5484 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5485 { 5486 if (!HASHITEM_EMPTY(hi)) 5487 { 5488 item2 = dict_find(d2, hi->hi_key, -1); 5489 if (item2 == NULL) 5490 return FALSE; 5491 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5492 return FALSE; 5493 --todo; 5494 } 5495 } 5496 return TRUE; 5497 } 5498 5499 /* 5500 * Return TRUE if "tv1" and "tv2" have the same value. 5501 * Compares the items just like "==" would compare them, but strings and 5502 * numbers are different. 5503 */ 5504 static int 5505 tv_equal(tv1, tv2, ic) 5506 typval_T *tv1; 5507 typval_T *tv2; 5508 int ic; /* ignore case */ 5509 { 5510 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5511 char_u *s1, *s2; 5512 5513 if (tv1->v_type != tv2->v_type) 5514 return FALSE; 5515 5516 switch (tv1->v_type) 5517 { 5518 case VAR_LIST: 5519 /* recursive! */ 5520 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5521 5522 case VAR_DICT: 5523 /* recursive! */ 5524 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5525 5526 case VAR_FUNC: 5527 return (tv1->vval.v_string != NULL 5528 && tv2->vval.v_string != NULL 5529 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5530 5531 case VAR_NUMBER: 5532 return tv1->vval.v_number == tv2->vval.v_number; 5533 5534 case VAR_STRING: 5535 s1 = get_tv_string_buf(tv1, buf1); 5536 s2 = get_tv_string_buf(tv2, buf2); 5537 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5538 } 5539 5540 EMSG2(_(e_intern2), "tv_equal()"); 5541 return TRUE; 5542 } 5543 5544 /* 5545 * Locate item with index "n" in list "l" and return it. 5546 * A negative index is counted from the end; -1 is the last item. 5547 * Returns NULL when "n" is out of range. 5548 */ 5549 static listitem_T * 5550 list_find(l, n) 5551 list_T *l; 5552 long n; 5553 { 5554 listitem_T *item; 5555 long idx; 5556 5557 if (l == NULL) 5558 return NULL; 5559 5560 /* Negative index is relative to the end. */ 5561 if (n < 0) 5562 n = l->lv_len + n; 5563 5564 /* Check for index out of range. */ 5565 if (n < 0 || n >= l->lv_len) 5566 return NULL; 5567 5568 /* When there is a cached index may start search from there. */ 5569 if (l->lv_idx_item != NULL) 5570 { 5571 if (n < l->lv_idx / 2) 5572 { 5573 /* closest to the start of the list */ 5574 item = l->lv_first; 5575 idx = 0; 5576 } 5577 else if (n > (l->lv_idx + l->lv_len) / 2) 5578 { 5579 /* closest to the end of the list */ 5580 item = l->lv_last; 5581 idx = l->lv_len - 1; 5582 } 5583 else 5584 { 5585 /* closest to the cached index */ 5586 item = l->lv_idx_item; 5587 idx = l->lv_idx; 5588 } 5589 } 5590 else 5591 { 5592 if (n < l->lv_len / 2) 5593 { 5594 /* closest to the start of the list */ 5595 item = l->lv_first; 5596 idx = 0; 5597 } 5598 else 5599 { 5600 /* closest to the end of the list */ 5601 item = l->lv_last; 5602 idx = l->lv_len - 1; 5603 } 5604 } 5605 5606 while (n > idx) 5607 { 5608 /* search forward */ 5609 item = item->li_next; 5610 ++idx; 5611 } 5612 while (n < idx) 5613 { 5614 /* search backward */ 5615 item = item->li_prev; 5616 --idx; 5617 } 5618 5619 /* cache the used index */ 5620 l->lv_idx = idx; 5621 l->lv_idx_item = item; 5622 5623 return item; 5624 } 5625 5626 /* 5627 * Get list item "l[idx]" as a number. 5628 */ 5629 static long 5630 list_find_nr(l, idx, errorp) 5631 list_T *l; 5632 long idx; 5633 int *errorp; /* set to TRUE when something wrong */ 5634 { 5635 listitem_T *li; 5636 5637 li = list_find(l, idx); 5638 if (li == NULL) 5639 { 5640 if (errorp != NULL) 5641 *errorp = TRUE; 5642 return -1L; 5643 } 5644 return get_tv_number_chk(&li->li_tv, errorp); 5645 } 5646 5647 /* 5648 * Locate "item" list "l" and return its index. 5649 * Returns -1 when "item" is not in the list. 5650 */ 5651 static long 5652 list_idx_of_item(l, item) 5653 list_T *l; 5654 listitem_T *item; 5655 { 5656 long idx = 0; 5657 listitem_T *li; 5658 5659 if (l == NULL) 5660 return -1; 5661 idx = 0; 5662 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5663 ++idx; 5664 if (li == NULL) 5665 return -1; 5666 return idx; 5667 } 5668 5669 /* 5670 * Append item "item" to the end of list "l". 5671 */ 5672 static void 5673 list_append(l, item) 5674 list_T *l; 5675 listitem_T *item; 5676 { 5677 if (l->lv_last == NULL) 5678 { 5679 /* empty list */ 5680 l->lv_first = item; 5681 l->lv_last = item; 5682 item->li_prev = NULL; 5683 } 5684 else 5685 { 5686 l->lv_last->li_next = item; 5687 item->li_prev = l->lv_last; 5688 l->lv_last = item; 5689 } 5690 ++l->lv_len; 5691 item->li_next = NULL; 5692 } 5693 5694 /* 5695 * Append typval_T "tv" to the end of list "l". 5696 * Return FAIL when out of memory. 5697 */ 5698 static int 5699 list_append_tv(l, tv) 5700 list_T *l; 5701 typval_T *tv; 5702 { 5703 listitem_T *li = listitem_alloc(); 5704 5705 if (li == NULL) 5706 return FAIL; 5707 copy_tv(tv, &li->li_tv); 5708 list_append(l, li); 5709 return OK; 5710 } 5711 5712 /* 5713 * Add a dictionary to a list. Used by getqflist(). 5714 * Return FAIL when out of memory. 5715 */ 5716 int 5717 list_append_dict(list, dict) 5718 list_T *list; 5719 dict_T *dict; 5720 { 5721 listitem_T *li = listitem_alloc(); 5722 5723 if (li == NULL) 5724 return FAIL; 5725 li->li_tv.v_type = VAR_DICT; 5726 li->li_tv.v_lock = 0; 5727 li->li_tv.vval.v_dict = dict; 5728 list_append(list, li); 5729 ++dict->dv_refcount; 5730 return OK; 5731 } 5732 5733 /* 5734 * Make a copy of "str" and append it as an item to list "l". 5735 * When "len" >= 0 use "str[len]". 5736 * Returns FAIL when out of memory. 5737 */ 5738 static int 5739 list_append_string(l, str, len) 5740 list_T *l; 5741 char_u *str; 5742 int len; 5743 { 5744 listitem_T *li = listitem_alloc(); 5745 5746 if (li == NULL) 5747 return FAIL; 5748 list_append(l, li); 5749 li->li_tv.v_type = VAR_STRING; 5750 li->li_tv.v_lock = 0; 5751 if (str == NULL) 5752 li->li_tv.vval.v_string = NULL; 5753 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 5754 : vim_strsave(str))) == NULL) 5755 return FAIL; 5756 return OK; 5757 } 5758 5759 /* 5760 * Append "n" to list "l". 5761 * Returns FAIL when out of memory. 5762 */ 5763 static int 5764 list_append_number(l, n) 5765 list_T *l; 5766 varnumber_T n; 5767 { 5768 listitem_T *li; 5769 5770 li = listitem_alloc(); 5771 if (li == NULL) 5772 return FAIL; 5773 li->li_tv.v_type = VAR_NUMBER; 5774 li->li_tv.v_lock = 0; 5775 li->li_tv.vval.v_number = n; 5776 list_append(l, li); 5777 return OK; 5778 } 5779 5780 /* 5781 * Insert typval_T "tv" in list "l" before "item". 5782 * If "item" is NULL append at the end. 5783 * Return FAIL when out of memory. 5784 */ 5785 static int 5786 list_insert_tv(l, tv, item) 5787 list_T *l; 5788 typval_T *tv; 5789 listitem_T *item; 5790 { 5791 listitem_T *ni = listitem_alloc(); 5792 5793 if (ni == NULL) 5794 return FAIL; 5795 copy_tv(tv, &ni->li_tv); 5796 if (item == NULL) 5797 /* Append new item at end of list. */ 5798 list_append(l, ni); 5799 else 5800 { 5801 /* Insert new item before existing item. */ 5802 ni->li_prev = item->li_prev; 5803 ni->li_next = item; 5804 if (item->li_prev == NULL) 5805 { 5806 l->lv_first = ni; 5807 ++l->lv_idx; 5808 } 5809 else 5810 { 5811 item->li_prev->li_next = ni; 5812 l->lv_idx_item = NULL; 5813 } 5814 item->li_prev = ni; 5815 ++l->lv_len; 5816 } 5817 return OK; 5818 } 5819 5820 /* 5821 * Extend "l1" with "l2". 5822 * If "bef" is NULL append at the end, otherwise insert before this item. 5823 * Returns FAIL when out of memory. 5824 */ 5825 static int 5826 list_extend(l1, l2, bef) 5827 list_T *l1; 5828 list_T *l2; 5829 listitem_T *bef; 5830 { 5831 listitem_T *item; 5832 5833 for (item = l2->lv_first; item != NULL; item = item->li_next) 5834 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5835 return FAIL; 5836 return OK; 5837 } 5838 5839 /* 5840 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5841 * Return FAIL when out of memory. 5842 */ 5843 static int 5844 list_concat(l1, l2, tv) 5845 list_T *l1; 5846 list_T *l2; 5847 typval_T *tv; 5848 { 5849 list_T *l; 5850 5851 /* make a copy of the first list. */ 5852 l = list_copy(l1, FALSE, 0); 5853 if (l == NULL) 5854 return FAIL; 5855 tv->v_type = VAR_LIST; 5856 tv->vval.v_list = l; 5857 5858 /* append all items from the second list */ 5859 return list_extend(l, l2, NULL); 5860 } 5861 5862 /* 5863 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5864 * The refcount of the new list is set to 1. 5865 * See item_copy() for "copyID". 5866 * Returns NULL when out of memory. 5867 */ 5868 static list_T * 5869 list_copy(orig, deep, copyID) 5870 list_T *orig; 5871 int deep; 5872 int copyID; 5873 { 5874 list_T *copy; 5875 listitem_T *item; 5876 listitem_T *ni; 5877 5878 if (orig == NULL) 5879 return NULL; 5880 5881 copy = list_alloc(); 5882 if (copy != NULL) 5883 { 5884 if (copyID != 0) 5885 { 5886 /* Do this before adding the items, because one of the items may 5887 * refer back to this list. */ 5888 orig->lv_copyID = copyID; 5889 orig->lv_copylist = copy; 5890 } 5891 for (item = orig->lv_first; item != NULL && !got_int; 5892 item = item->li_next) 5893 { 5894 ni = listitem_alloc(); 5895 if (ni == NULL) 5896 break; 5897 if (deep) 5898 { 5899 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5900 { 5901 vim_free(ni); 5902 break; 5903 } 5904 } 5905 else 5906 copy_tv(&item->li_tv, &ni->li_tv); 5907 list_append(copy, ni); 5908 } 5909 ++copy->lv_refcount; 5910 if (item != NULL) 5911 { 5912 list_unref(copy); 5913 copy = NULL; 5914 } 5915 } 5916 5917 return copy; 5918 } 5919 5920 /* 5921 * Remove items "item" to "item2" from list "l". 5922 * Does not free the listitem or the value! 5923 */ 5924 static void 5925 list_remove(l, item, item2) 5926 list_T *l; 5927 listitem_T *item; 5928 listitem_T *item2; 5929 { 5930 listitem_T *ip; 5931 5932 /* notify watchers */ 5933 for (ip = item; ip != NULL; ip = ip->li_next) 5934 { 5935 --l->lv_len; 5936 list_fix_watch(l, ip); 5937 if (ip == item2) 5938 break; 5939 } 5940 5941 if (item2->li_next == NULL) 5942 l->lv_last = item->li_prev; 5943 else 5944 item2->li_next->li_prev = item->li_prev; 5945 if (item->li_prev == NULL) 5946 l->lv_first = item2->li_next; 5947 else 5948 item->li_prev->li_next = item2->li_next; 5949 l->lv_idx_item = NULL; 5950 } 5951 5952 /* 5953 * Return an allocated string with the string representation of a list. 5954 * May return NULL. 5955 */ 5956 static char_u * 5957 list2string(tv, copyID) 5958 typval_T *tv; 5959 int copyID; 5960 { 5961 garray_T ga; 5962 5963 if (tv->vval.v_list == NULL) 5964 return NULL; 5965 ga_init2(&ga, (int)sizeof(char), 80); 5966 ga_append(&ga, '['); 5967 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 5968 { 5969 vim_free(ga.ga_data); 5970 return NULL; 5971 } 5972 ga_append(&ga, ']'); 5973 ga_append(&ga, NUL); 5974 return (char_u *)ga.ga_data; 5975 } 5976 5977 /* 5978 * Join list "l" into a string in "*gap", using separator "sep". 5979 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5980 * Return FAIL or OK. 5981 */ 5982 static int 5983 list_join(gap, l, sep, echo, copyID) 5984 garray_T *gap; 5985 list_T *l; 5986 char_u *sep; 5987 int echo; 5988 int copyID; 5989 { 5990 int first = TRUE; 5991 char_u *tofree; 5992 char_u numbuf[NUMBUFLEN]; 5993 listitem_T *item; 5994 char_u *s; 5995 5996 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5997 { 5998 if (first) 5999 first = FALSE; 6000 else 6001 ga_concat(gap, sep); 6002 6003 if (echo) 6004 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6005 else 6006 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6007 if (s != NULL) 6008 ga_concat(gap, s); 6009 vim_free(tofree); 6010 if (s == NULL) 6011 return FAIL; 6012 } 6013 return OK; 6014 } 6015 6016 /* 6017 * Garbage collection for lists and dictionaries. 6018 * 6019 * We use reference counts to be able to free most items right away when they 6020 * are no longer used. But for composite items it's possible that it becomes 6021 * unused while the reference count is > 0: When there is a recursive 6022 * reference. Example: 6023 * :let l = [1, 2, 3] 6024 * :let d = {9: l} 6025 * :let l[1] = d 6026 * 6027 * Since this is quite unusual we handle this with garbage collection: every 6028 * once in a while find out which lists and dicts are not referenced from any 6029 * variable. 6030 * 6031 * Here is a good reference text about garbage collection (refers to Python 6032 * but it applies to all reference-counting mechanisms): 6033 * http://python.ca/nas/python/gc/ 6034 */ 6035 6036 /* 6037 * Do garbage collection for lists and dicts. 6038 * Return TRUE if some memory was freed. 6039 */ 6040 int 6041 garbage_collect() 6042 { 6043 dict_T *dd; 6044 list_T *ll; 6045 int copyID = ++current_copyID; 6046 buf_T *buf; 6047 win_T *wp; 6048 int i; 6049 funccall_T *fc; 6050 int did_free = FALSE; 6051 #ifdef FEAT_WINDOWS 6052 tabpage_T *tp; 6053 #endif 6054 6055 /* 6056 * 1. Go through all accessible variables and mark all lists and dicts 6057 * with copyID. 6058 */ 6059 /* script-local variables */ 6060 for (i = 1; i <= ga_scripts.ga_len; ++i) 6061 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 6062 6063 /* buffer-local variables */ 6064 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6065 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 6066 6067 /* window-local variables */ 6068 FOR_ALL_TAB_WINDOWS(tp, wp) 6069 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 6070 6071 #ifdef FEAT_WINDOWS 6072 /* tabpage-local variables */ 6073 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6074 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); 6075 #endif 6076 6077 /* global variables */ 6078 set_ref_in_ht(&globvarht, copyID); 6079 6080 /* function-local variables */ 6081 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6082 { 6083 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 6084 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 6085 } 6086 6087 /* 6088 * 2. Go through the list of dicts and free items without the copyID. 6089 */ 6090 for (dd = first_dict; dd != NULL; ) 6091 if (dd->dv_copyID != copyID) 6092 { 6093 dict_free(dd); 6094 did_free = TRUE; 6095 6096 /* restart, next dict may also have been freed */ 6097 dd = first_dict; 6098 } 6099 else 6100 dd = dd->dv_used_next; 6101 6102 /* 6103 * 3. Go through the list of lists and free items without the copyID. 6104 * But don't free a list that has a watcher (used in a for loop), these 6105 * are not referenced anywhere. 6106 */ 6107 for (ll = first_list; ll != NULL; ) 6108 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 6109 { 6110 list_free(ll); 6111 did_free = TRUE; 6112 6113 /* restart, next list may also have been freed */ 6114 ll = first_list; 6115 } 6116 else 6117 ll = ll->lv_used_next; 6118 6119 return did_free; 6120 } 6121 6122 /* 6123 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6124 */ 6125 static void 6126 set_ref_in_ht(ht, copyID) 6127 hashtab_T *ht; 6128 int copyID; 6129 { 6130 int todo; 6131 hashitem_T *hi; 6132 6133 todo = (int)ht->ht_used; 6134 for (hi = ht->ht_array; todo > 0; ++hi) 6135 if (!HASHITEM_EMPTY(hi)) 6136 { 6137 --todo; 6138 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 6139 } 6140 } 6141 6142 /* 6143 * Mark all lists and dicts referenced through list "l" with "copyID". 6144 */ 6145 static void 6146 set_ref_in_list(l, copyID) 6147 list_T *l; 6148 int copyID; 6149 { 6150 listitem_T *li; 6151 6152 for (li = l->lv_first; li != NULL; li = li->li_next) 6153 set_ref_in_item(&li->li_tv, copyID); 6154 } 6155 6156 /* 6157 * Mark all lists and dicts referenced through typval "tv" with "copyID". 6158 */ 6159 static void 6160 set_ref_in_item(tv, copyID) 6161 typval_T *tv; 6162 int copyID; 6163 { 6164 dict_T *dd; 6165 list_T *ll; 6166 6167 switch (tv->v_type) 6168 { 6169 case VAR_DICT: 6170 dd = tv->vval.v_dict; 6171 if (dd->dv_copyID != copyID) 6172 { 6173 /* Didn't see this dict yet. */ 6174 dd->dv_copyID = copyID; 6175 set_ref_in_ht(&dd->dv_hashtab, copyID); 6176 } 6177 break; 6178 6179 case VAR_LIST: 6180 ll = tv->vval.v_list; 6181 if (ll->lv_copyID != copyID) 6182 { 6183 /* Didn't see this list yet. */ 6184 ll->lv_copyID = copyID; 6185 set_ref_in_list(ll, copyID); 6186 } 6187 break; 6188 } 6189 return; 6190 } 6191 6192 /* 6193 * Allocate an empty header for a dictionary. 6194 */ 6195 dict_T * 6196 dict_alloc() 6197 { 6198 dict_T *d; 6199 6200 d = (dict_T *)alloc(sizeof(dict_T)); 6201 if (d != NULL) 6202 { 6203 /* Add the list to the hashtable for garbage collection. */ 6204 if (first_dict != NULL) 6205 first_dict->dv_used_prev = d; 6206 d->dv_used_next = first_dict; 6207 d->dv_used_prev = NULL; 6208 6209 hash_init(&d->dv_hashtab); 6210 d->dv_lock = 0; 6211 d->dv_refcount = 0; 6212 d->dv_copyID = 0; 6213 } 6214 return d; 6215 } 6216 6217 /* 6218 * Unreference a Dictionary: decrement the reference count and free it when it 6219 * becomes zero. 6220 */ 6221 static void 6222 dict_unref(d) 6223 dict_T *d; 6224 { 6225 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6226 dict_free(d); 6227 } 6228 6229 /* 6230 * Free a Dictionary, including all items it contains. 6231 * Ignores the reference count. 6232 */ 6233 static void 6234 dict_free(d) 6235 dict_T *d; 6236 { 6237 int todo; 6238 hashitem_T *hi; 6239 dictitem_T *di; 6240 6241 /* Avoid that recursive reference to the dict frees us again. */ 6242 d->dv_refcount = DEL_REFCOUNT; 6243 6244 /* Remove the dict from the list of dicts for garbage collection. */ 6245 if (d->dv_used_prev == NULL) 6246 first_dict = d->dv_used_next; 6247 else 6248 d->dv_used_prev->dv_used_next = d->dv_used_next; 6249 if (d->dv_used_next != NULL) 6250 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6251 6252 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6253 hash_lock(&d->dv_hashtab); 6254 todo = (int)d->dv_hashtab.ht_used; 6255 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6256 { 6257 if (!HASHITEM_EMPTY(hi)) 6258 { 6259 /* Remove the item before deleting it, just in case there is 6260 * something recursive causing trouble. */ 6261 di = HI2DI(hi); 6262 hash_remove(&d->dv_hashtab, hi); 6263 dictitem_free(di); 6264 --todo; 6265 } 6266 } 6267 hash_clear(&d->dv_hashtab); 6268 vim_free(d); 6269 } 6270 6271 /* 6272 * Allocate a Dictionary item. 6273 * The "key" is copied to the new item. 6274 * Note that the value of the item "di_tv" still needs to be initialized! 6275 * Returns NULL when out of memory. 6276 */ 6277 static dictitem_T * 6278 dictitem_alloc(key) 6279 char_u *key; 6280 { 6281 dictitem_T *di; 6282 6283 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 6284 if (di != NULL) 6285 { 6286 STRCPY(di->di_key, key); 6287 di->di_flags = 0; 6288 } 6289 return di; 6290 } 6291 6292 /* 6293 * Make a copy of a Dictionary item. 6294 */ 6295 static dictitem_T * 6296 dictitem_copy(org) 6297 dictitem_T *org; 6298 { 6299 dictitem_T *di; 6300 6301 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 6302 + STRLEN(org->di_key))); 6303 if (di != NULL) 6304 { 6305 STRCPY(di->di_key, org->di_key); 6306 di->di_flags = 0; 6307 copy_tv(&org->di_tv, &di->di_tv); 6308 } 6309 return di; 6310 } 6311 6312 /* 6313 * Remove item "item" from Dictionary "dict" and free it. 6314 */ 6315 static void 6316 dictitem_remove(dict, item) 6317 dict_T *dict; 6318 dictitem_T *item; 6319 { 6320 hashitem_T *hi; 6321 6322 hi = hash_find(&dict->dv_hashtab, item->di_key); 6323 if (HASHITEM_EMPTY(hi)) 6324 EMSG2(_(e_intern2), "dictitem_remove()"); 6325 else 6326 hash_remove(&dict->dv_hashtab, hi); 6327 dictitem_free(item); 6328 } 6329 6330 /* 6331 * Free a dict item. Also clears the value. 6332 */ 6333 static void 6334 dictitem_free(item) 6335 dictitem_T *item; 6336 { 6337 clear_tv(&item->di_tv); 6338 vim_free(item); 6339 } 6340 6341 /* 6342 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6343 * The refcount of the new dict is set to 1. 6344 * See item_copy() for "copyID". 6345 * Returns NULL when out of memory. 6346 */ 6347 static dict_T * 6348 dict_copy(orig, deep, copyID) 6349 dict_T *orig; 6350 int deep; 6351 int copyID; 6352 { 6353 dict_T *copy; 6354 dictitem_T *di; 6355 int todo; 6356 hashitem_T *hi; 6357 6358 if (orig == NULL) 6359 return NULL; 6360 6361 copy = dict_alloc(); 6362 if (copy != NULL) 6363 { 6364 if (copyID != 0) 6365 { 6366 orig->dv_copyID = copyID; 6367 orig->dv_copydict = copy; 6368 } 6369 todo = (int)orig->dv_hashtab.ht_used; 6370 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6371 { 6372 if (!HASHITEM_EMPTY(hi)) 6373 { 6374 --todo; 6375 6376 di = dictitem_alloc(hi->hi_key); 6377 if (di == NULL) 6378 break; 6379 if (deep) 6380 { 6381 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6382 copyID) == FAIL) 6383 { 6384 vim_free(di); 6385 break; 6386 } 6387 } 6388 else 6389 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6390 if (dict_add(copy, di) == FAIL) 6391 { 6392 dictitem_free(di); 6393 break; 6394 } 6395 } 6396 } 6397 6398 ++copy->dv_refcount; 6399 if (todo > 0) 6400 { 6401 dict_unref(copy); 6402 copy = NULL; 6403 } 6404 } 6405 6406 return copy; 6407 } 6408 6409 /* 6410 * Add item "item" to Dictionary "d". 6411 * Returns FAIL when out of memory and when key already existed. 6412 */ 6413 static int 6414 dict_add(d, item) 6415 dict_T *d; 6416 dictitem_T *item; 6417 { 6418 return hash_add(&d->dv_hashtab, item->di_key); 6419 } 6420 6421 /* 6422 * Add a number or string entry to dictionary "d". 6423 * When "str" is NULL use number "nr", otherwise use "str". 6424 * Returns FAIL when out of memory and when key already exists. 6425 */ 6426 int 6427 dict_add_nr_str(d, key, nr, str) 6428 dict_T *d; 6429 char *key; 6430 long nr; 6431 char_u *str; 6432 { 6433 dictitem_T *item; 6434 6435 item = dictitem_alloc((char_u *)key); 6436 if (item == NULL) 6437 return FAIL; 6438 item->di_tv.v_lock = 0; 6439 if (str == NULL) 6440 { 6441 item->di_tv.v_type = VAR_NUMBER; 6442 item->di_tv.vval.v_number = nr; 6443 } 6444 else 6445 { 6446 item->di_tv.v_type = VAR_STRING; 6447 item->di_tv.vval.v_string = vim_strsave(str); 6448 } 6449 if (dict_add(d, item) == FAIL) 6450 { 6451 dictitem_free(item); 6452 return FAIL; 6453 } 6454 return OK; 6455 } 6456 6457 /* 6458 * Get the number of items in a Dictionary. 6459 */ 6460 static long 6461 dict_len(d) 6462 dict_T *d; 6463 { 6464 if (d == NULL) 6465 return 0L; 6466 return (long)d->dv_hashtab.ht_used; 6467 } 6468 6469 /* 6470 * Find item "key[len]" in Dictionary "d". 6471 * If "len" is negative use strlen(key). 6472 * Returns NULL when not found. 6473 */ 6474 static dictitem_T * 6475 dict_find(d, key, len) 6476 dict_T *d; 6477 char_u *key; 6478 int len; 6479 { 6480 #define AKEYLEN 200 6481 char_u buf[AKEYLEN]; 6482 char_u *akey; 6483 char_u *tofree = NULL; 6484 hashitem_T *hi; 6485 6486 if (len < 0) 6487 akey = key; 6488 else if (len >= AKEYLEN) 6489 { 6490 tofree = akey = vim_strnsave(key, len); 6491 if (akey == NULL) 6492 return NULL; 6493 } 6494 else 6495 { 6496 /* Avoid a malloc/free by using buf[]. */ 6497 vim_strncpy(buf, key, len); 6498 akey = buf; 6499 } 6500 6501 hi = hash_find(&d->dv_hashtab, akey); 6502 vim_free(tofree); 6503 if (HASHITEM_EMPTY(hi)) 6504 return NULL; 6505 return HI2DI(hi); 6506 } 6507 6508 /* 6509 * Get a string item from a dictionary. 6510 * When "save" is TRUE allocate memory for it. 6511 * Returns NULL if the entry doesn't exist or out of memory. 6512 */ 6513 char_u * 6514 get_dict_string(d, key, save) 6515 dict_T *d; 6516 char_u *key; 6517 int save; 6518 { 6519 dictitem_T *di; 6520 char_u *s; 6521 6522 di = dict_find(d, key, -1); 6523 if (di == NULL) 6524 return NULL; 6525 s = get_tv_string(&di->di_tv); 6526 if (save && s != NULL) 6527 s = vim_strsave(s); 6528 return s; 6529 } 6530 6531 /* 6532 * Get a number item from a dictionary. 6533 * Returns 0 if the entry doesn't exist or out of memory. 6534 */ 6535 long 6536 get_dict_number(d, key) 6537 dict_T *d; 6538 char_u *key; 6539 { 6540 dictitem_T *di; 6541 6542 di = dict_find(d, key, -1); 6543 if (di == NULL) 6544 return 0; 6545 return get_tv_number(&di->di_tv); 6546 } 6547 6548 /* 6549 * Return an allocated string with the string representation of a Dictionary. 6550 * May return NULL. 6551 */ 6552 static char_u * 6553 dict2string(tv, copyID) 6554 typval_T *tv; 6555 int copyID; 6556 { 6557 garray_T ga; 6558 int first = TRUE; 6559 char_u *tofree; 6560 char_u numbuf[NUMBUFLEN]; 6561 hashitem_T *hi; 6562 char_u *s; 6563 dict_T *d; 6564 int todo; 6565 6566 if ((d = tv->vval.v_dict) == NULL) 6567 return NULL; 6568 ga_init2(&ga, (int)sizeof(char), 80); 6569 ga_append(&ga, '{'); 6570 6571 todo = (int)d->dv_hashtab.ht_used; 6572 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6573 { 6574 if (!HASHITEM_EMPTY(hi)) 6575 { 6576 --todo; 6577 6578 if (first) 6579 first = FALSE; 6580 else 6581 ga_concat(&ga, (char_u *)", "); 6582 6583 tofree = string_quote(hi->hi_key, FALSE); 6584 if (tofree != NULL) 6585 { 6586 ga_concat(&ga, tofree); 6587 vim_free(tofree); 6588 } 6589 ga_concat(&ga, (char_u *)": "); 6590 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 6591 if (s != NULL) 6592 ga_concat(&ga, s); 6593 vim_free(tofree); 6594 if (s == NULL) 6595 break; 6596 } 6597 } 6598 if (todo > 0) 6599 { 6600 vim_free(ga.ga_data); 6601 return NULL; 6602 } 6603 6604 ga_append(&ga, '}'); 6605 ga_append(&ga, NUL); 6606 return (char_u *)ga.ga_data; 6607 } 6608 6609 /* 6610 * Allocate a variable for a Dictionary and fill it from "*arg". 6611 * Return OK or FAIL. Returns NOTDONE for {expr}. 6612 */ 6613 static int 6614 get_dict_tv(arg, rettv, evaluate) 6615 char_u **arg; 6616 typval_T *rettv; 6617 int evaluate; 6618 { 6619 dict_T *d = NULL; 6620 typval_T tvkey; 6621 typval_T tv; 6622 char_u *key; 6623 dictitem_T *item; 6624 char_u *start = skipwhite(*arg + 1); 6625 char_u buf[NUMBUFLEN]; 6626 6627 /* 6628 * First check if it's not a curly-braces thing: {expr}. 6629 * Must do this without evaluating, otherwise a function may be called 6630 * twice. Unfortunately this means we need to call eval1() twice for the 6631 * first item. 6632 * But {} is an empty Dictionary. 6633 */ 6634 if (*start != '}') 6635 { 6636 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6637 return FAIL; 6638 if (*start == '}') 6639 return NOTDONE; 6640 } 6641 6642 if (evaluate) 6643 { 6644 d = dict_alloc(); 6645 if (d == NULL) 6646 return FAIL; 6647 } 6648 tvkey.v_type = VAR_UNKNOWN; 6649 tv.v_type = VAR_UNKNOWN; 6650 6651 *arg = skipwhite(*arg + 1); 6652 while (**arg != '}' && **arg != NUL) 6653 { 6654 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6655 goto failret; 6656 if (**arg != ':') 6657 { 6658 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6659 clear_tv(&tvkey); 6660 goto failret; 6661 } 6662 key = get_tv_string_buf_chk(&tvkey, buf); 6663 if (key == NULL || *key == NUL) 6664 { 6665 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6666 if (key != NULL) 6667 EMSG(_(e_emptykey)); 6668 clear_tv(&tvkey); 6669 goto failret; 6670 } 6671 6672 *arg = skipwhite(*arg + 1); 6673 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6674 { 6675 clear_tv(&tvkey); 6676 goto failret; 6677 } 6678 if (evaluate) 6679 { 6680 item = dict_find(d, key, -1); 6681 if (item != NULL) 6682 { 6683 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6684 clear_tv(&tvkey); 6685 clear_tv(&tv); 6686 goto failret; 6687 } 6688 item = dictitem_alloc(key); 6689 clear_tv(&tvkey); 6690 if (item != NULL) 6691 { 6692 item->di_tv = tv; 6693 item->di_tv.v_lock = 0; 6694 if (dict_add(d, item) == FAIL) 6695 dictitem_free(item); 6696 } 6697 } 6698 6699 if (**arg == '}') 6700 break; 6701 if (**arg != ',') 6702 { 6703 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6704 goto failret; 6705 } 6706 *arg = skipwhite(*arg + 1); 6707 } 6708 6709 if (**arg != '}') 6710 { 6711 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6712 failret: 6713 if (evaluate) 6714 dict_free(d); 6715 return FAIL; 6716 } 6717 6718 *arg = skipwhite(*arg + 1); 6719 if (evaluate) 6720 { 6721 rettv->v_type = VAR_DICT; 6722 rettv->vval.v_dict = d; 6723 ++d->dv_refcount; 6724 } 6725 6726 return OK; 6727 } 6728 6729 /* 6730 * Return a string with the string representation of a variable. 6731 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6732 * "numbuf" is used for a number. 6733 * Does not put quotes around strings, as ":echo" displays values. 6734 * When "copyID" is not NULL replace recursive lists and dicts with "...". 6735 * May return NULL; 6736 */ 6737 static char_u * 6738 echo_string(tv, tofree, numbuf, copyID) 6739 typval_T *tv; 6740 char_u **tofree; 6741 char_u *numbuf; 6742 int copyID; 6743 { 6744 static int recurse = 0; 6745 char_u *r = NULL; 6746 6747 if (recurse >= DICT_MAXNEST) 6748 { 6749 EMSG(_("E724: variable nested too deep for displaying")); 6750 *tofree = NULL; 6751 return NULL; 6752 } 6753 ++recurse; 6754 6755 switch (tv->v_type) 6756 { 6757 case VAR_FUNC: 6758 *tofree = NULL; 6759 r = tv->vval.v_string; 6760 break; 6761 6762 case VAR_LIST: 6763 if (tv->vval.v_list == NULL) 6764 { 6765 *tofree = NULL; 6766 r = NULL; 6767 } 6768 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 6769 { 6770 *tofree = NULL; 6771 r = (char_u *)"[...]"; 6772 } 6773 else 6774 { 6775 tv->vval.v_list->lv_copyID = copyID; 6776 *tofree = list2string(tv, copyID); 6777 r = *tofree; 6778 } 6779 break; 6780 6781 case VAR_DICT: 6782 if (tv->vval.v_dict == NULL) 6783 { 6784 *tofree = NULL; 6785 r = NULL; 6786 } 6787 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 6788 { 6789 *tofree = NULL; 6790 r = (char_u *)"{...}"; 6791 } 6792 else 6793 { 6794 tv->vval.v_dict->dv_copyID = copyID; 6795 *tofree = dict2string(tv, copyID); 6796 r = *tofree; 6797 } 6798 break; 6799 6800 case VAR_STRING: 6801 case VAR_NUMBER: 6802 *tofree = NULL; 6803 r = get_tv_string_buf(tv, numbuf); 6804 break; 6805 6806 default: 6807 EMSG2(_(e_intern2), "echo_string()"); 6808 *tofree = NULL; 6809 } 6810 6811 --recurse; 6812 return r; 6813 } 6814 6815 /* 6816 * Return a string with the string representation of a variable. 6817 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6818 * "numbuf" is used for a number. 6819 * Puts quotes around strings, so that they can be parsed back by eval(). 6820 * May return NULL; 6821 */ 6822 static char_u * 6823 tv2string(tv, tofree, numbuf, copyID) 6824 typval_T *tv; 6825 char_u **tofree; 6826 char_u *numbuf; 6827 int copyID; 6828 { 6829 switch (tv->v_type) 6830 { 6831 case VAR_FUNC: 6832 *tofree = string_quote(tv->vval.v_string, TRUE); 6833 return *tofree; 6834 case VAR_STRING: 6835 *tofree = string_quote(tv->vval.v_string, FALSE); 6836 return *tofree; 6837 case VAR_NUMBER: 6838 case VAR_LIST: 6839 case VAR_DICT: 6840 break; 6841 default: 6842 EMSG2(_(e_intern2), "tv2string()"); 6843 } 6844 return echo_string(tv, tofree, numbuf, copyID); 6845 } 6846 6847 /* 6848 * Return string "str" in ' quotes, doubling ' characters. 6849 * If "str" is NULL an empty string is assumed. 6850 * If "function" is TRUE make it function('string'). 6851 */ 6852 static char_u * 6853 string_quote(str, function) 6854 char_u *str; 6855 int function; 6856 { 6857 unsigned len; 6858 char_u *p, *r, *s; 6859 6860 len = (function ? 13 : 3); 6861 if (str != NULL) 6862 { 6863 len += (unsigned)STRLEN(str); 6864 for (p = str; *p != NUL; mb_ptr_adv(p)) 6865 if (*p == '\'') 6866 ++len; 6867 } 6868 s = r = alloc(len); 6869 if (r != NULL) 6870 { 6871 if (function) 6872 { 6873 STRCPY(r, "function('"); 6874 r += 10; 6875 } 6876 else 6877 *r++ = '\''; 6878 if (str != NULL) 6879 for (p = str; *p != NUL; ) 6880 { 6881 if (*p == '\'') 6882 *r++ = '\''; 6883 MB_COPY_CHAR(p, r); 6884 } 6885 *r++ = '\''; 6886 if (function) 6887 *r++ = ')'; 6888 *r++ = NUL; 6889 } 6890 return s; 6891 } 6892 6893 /* 6894 * Get the value of an environment variable. 6895 * "arg" is pointing to the '$'. It is advanced to after the name. 6896 * If the environment variable was not set, silently assume it is empty. 6897 * Always return OK. 6898 */ 6899 static int 6900 get_env_tv(arg, rettv, evaluate) 6901 char_u **arg; 6902 typval_T *rettv; 6903 int evaluate; 6904 { 6905 char_u *string = NULL; 6906 int len; 6907 int cc; 6908 char_u *name; 6909 int mustfree = FALSE; 6910 6911 ++*arg; 6912 name = *arg; 6913 len = get_env_len(arg); 6914 if (evaluate) 6915 { 6916 if (len != 0) 6917 { 6918 cc = name[len]; 6919 name[len] = NUL; 6920 /* first try vim_getenv(), fast for normal environment vars */ 6921 string = vim_getenv(name, &mustfree); 6922 if (string != NULL && *string != NUL) 6923 { 6924 if (!mustfree) 6925 string = vim_strsave(string); 6926 } 6927 else 6928 { 6929 if (mustfree) 6930 vim_free(string); 6931 6932 /* next try expanding things like $VIM and ${HOME} */ 6933 string = expand_env_save(name - 1); 6934 if (string != NULL && *string == '$') 6935 { 6936 vim_free(string); 6937 string = NULL; 6938 } 6939 } 6940 name[len] = cc; 6941 } 6942 rettv->v_type = VAR_STRING; 6943 rettv->vval.v_string = string; 6944 } 6945 6946 return OK; 6947 } 6948 6949 /* 6950 * Array with names and number of arguments of all internal functions 6951 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6952 */ 6953 static struct fst 6954 { 6955 char *f_name; /* function name */ 6956 char f_min_argc; /* minimal number of arguments */ 6957 char f_max_argc; /* maximal number of arguments */ 6958 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6959 /* implemenation of function */ 6960 } functions[] = 6961 { 6962 {"add", 2, 2, f_add}, 6963 {"append", 2, 2, f_append}, 6964 {"argc", 0, 0, f_argc}, 6965 {"argidx", 0, 0, f_argidx}, 6966 {"argv", 0, 1, f_argv}, 6967 {"browse", 4, 4, f_browse}, 6968 {"browsedir", 2, 2, f_browsedir}, 6969 {"bufexists", 1, 1, f_bufexists}, 6970 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6971 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6972 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6973 {"buflisted", 1, 1, f_buflisted}, 6974 {"bufloaded", 1, 1, f_bufloaded}, 6975 {"bufname", 1, 1, f_bufname}, 6976 {"bufnr", 1, 2, f_bufnr}, 6977 {"bufwinnr", 1, 1, f_bufwinnr}, 6978 {"byte2line", 1, 1, f_byte2line}, 6979 {"byteidx", 2, 2, f_byteidx}, 6980 {"call", 2, 3, f_call}, 6981 {"changenr", 0, 0, f_changenr}, 6982 {"char2nr", 1, 1, f_char2nr}, 6983 {"cindent", 1, 1, f_cindent}, 6984 {"col", 1, 1, f_col}, 6985 #if defined(FEAT_INS_EXPAND) 6986 {"complete", 2, 2, f_complete}, 6987 {"complete_add", 1, 1, f_complete_add}, 6988 {"complete_check", 0, 0, f_complete_check}, 6989 #endif 6990 {"confirm", 1, 4, f_confirm}, 6991 {"copy", 1, 1, f_copy}, 6992 {"count", 2, 4, f_count}, 6993 {"cscope_connection",0,3, f_cscope_connection}, 6994 {"cursor", 1, 3, f_cursor}, 6995 {"deepcopy", 1, 2, f_deepcopy}, 6996 {"delete", 1, 1, f_delete}, 6997 {"did_filetype", 0, 0, f_did_filetype}, 6998 {"diff_filler", 1, 1, f_diff_filler}, 6999 {"diff_hlID", 2, 2, f_diff_hlID}, 7000 {"empty", 1, 1, f_empty}, 7001 {"escape", 2, 2, f_escape}, 7002 {"eval", 1, 1, f_eval}, 7003 {"eventhandler", 0, 0, f_eventhandler}, 7004 {"executable", 1, 1, f_executable}, 7005 {"exists", 1, 1, f_exists}, 7006 {"expand", 1, 2, f_expand}, 7007 {"extend", 2, 3, f_extend}, 7008 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 7009 {"filereadable", 1, 1, f_filereadable}, 7010 {"filewritable", 1, 1, f_filewritable}, 7011 {"filter", 2, 2, f_filter}, 7012 {"finddir", 1, 3, f_finddir}, 7013 {"findfile", 1, 3, f_findfile}, 7014 {"fnamemodify", 2, 2, f_fnamemodify}, 7015 {"foldclosed", 1, 1, f_foldclosed}, 7016 {"foldclosedend", 1, 1, f_foldclosedend}, 7017 {"foldlevel", 1, 1, f_foldlevel}, 7018 {"foldtext", 0, 0, f_foldtext}, 7019 {"foldtextresult", 1, 1, f_foldtextresult}, 7020 {"foreground", 0, 0, f_foreground}, 7021 {"function", 1, 1, f_function}, 7022 {"garbagecollect", 0, 0, f_garbagecollect}, 7023 {"get", 2, 3, f_get}, 7024 {"getbufline", 2, 3, f_getbufline}, 7025 {"getbufvar", 2, 2, f_getbufvar}, 7026 {"getchar", 0, 1, f_getchar}, 7027 {"getcharmod", 0, 0, f_getcharmod}, 7028 {"getcmdline", 0, 0, f_getcmdline}, 7029 {"getcmdpos", 0, 0, f_getcmdpos}, 7030 {"getcmdtype", 0, 0, f_getcmdtype}, 7031 {"getcwd", 0, 0, f_getcwd}, 7032 {"getfontname", 0, 1, f_getfontname}, 7033 {"getfperm", 1, 1, f_getfperm}, 7034 {"getfsize", 1, 1, f_getfsize}, 7035 {"getftime", 1, 1, f_getftime}, 7036 {"getftype", 1, 1, f_getftype}, 7037 {"getline", 1, 2, f_getline}, 7038 {"getloclist", 1, 1, f_getqflist}, 7039 {"getpos", 1, 1, f_getpos}, 7040 {"getqflist", 0, 0, f_getqflist}, 7041 {"getreg", 0, 2, f_getreg}, 7042 {"getregtype", 0, 1, f_getregtype}, 7043 {"gettabwinvar", 3, 3, f_gettabwinvar}, 7044 {"getwinposx", 0, 0, f_getwinposx}, 7045 {"getwinposy", 0, 0, f_getwinposy}, 7046 {"getwinvar", 2, 2, f_getwinvar}, 7047 {"glob", 1, 1, f_glob}, 7048 {"globpath", 2, 2, f_globpath}, 7049 {"has", 1, 1, f_has}, 7050 {"has_key", 2, 2, f_has_key}, 7051 {"hasmapto", 1, 3, f_hasmapto}, 7052 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 7053 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 7054 {"histadd", 2, 2, f_histadd}, 7055 {"histdel", 1, 2, f_histdel}, 7056 {"histget", 1, 2, f_histget}, 7057 {"histnr", 1, 1, f_histnr}, 7058 {"hlID", 1, 1, f_hlID}, 7059 {"hlexists", 1, 1, f_hlexists}, 7060 {"hostname", 0, 0, f_hostname}, 7061 {"iconv", 3, 3, f_iconv}, 7062 {"indent", 1, 1, f_indent}, 7063 {"index", 2, 4, f_index}, 7064 {"input", 1, 3, f_input}, 7065 {"inputdialog", 1, 3, f_inputdialog}, 7066 {"inputlist", 1, 1, f_inputlist}, 7067 {"inputrestore", 0, 0, f_inputrestore}, 7068 {"inputsave", 0, 0, f_inputsave}, 7069 {"inputsecret", 1, 2, f_inputsecret}, 7070 {"insert", 2, 3, f_insert}, 7071 {"isdirectory", 1, 1, f_isdirectory}, 7072 {"islocked", 1, 1, f_islocked}, 7073 {"items", 1, 1, f_items}, 7074 {"join", 1, 2, f_join}, 7075 {"keys", 1, 1, f_keys}, 7076 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 7077 {"len", 1, 1, f_len}, 7078 {"libcall", 3, 3, f_libcall}, 7079 {"libcallnr", 3, 3, f_libcallnr}, 7080 {"line", 1, 1, f_line}, 7081 {"line2byte", 1, 1, f_line2byte}, 7082 {"lispindent", 1, 1, f_lispindent}, 7083 {"localtime", 0, 0, f_localtime}, 7084 {"map", 2, 2, f_map}, 7085 {"maparg", 1, 3, f_maparg}, 7086 {"mapcheck", 1, 3, f_mapcheck}, 7087 {"match", 2, 4, f_match}, 7088 {"matcharg", 1, 1, f_matcharg}, 7089 {"matchend", 2, 4, f_matchend}, 7090 {"matchlist", 2, 4, f_matchlist}, 7091 {"matchstr", 2, 4, f_matchstr}, 7092 {"max", 1, 1, f_max}, 7093 {"min", 1, 1, f_min}, 7094 #ifdef vim_mkdir 7095 {"mkdir", 1, 3, f_mkdir}, 7096 #endif 7097 {"mode", 0, 0, f_mode}, 7098 {"nextnonblank", 1, 1, f_nextnonblank}, 7099 {"nr2char", 1, 1, f_nr2char}, 7100 {"pathshorten", 1, 1, f_pathshorten}, 7101 {"prevnonblank", 1, 1, f_prevnonblank}, 7102 {"printf", 2, 19, f_printf}, 7103 {"pumvisible", 0, 0, f_pumvisible}, 7104 {"range", 1, 3, f_range}, 7105 {"readfile", 1, 3, f_readfile}, 7106 {"reltime", 0, 2, f_reltime}, 7107 {"reltimestr", 1, 1, f_reltimestr}, 7108 {"remote_expr", 2, 3, f_remote_expr}, 7109 {"remote_foreground", 1, 1, f_remote_foreground}, 7110 {"remote_peek", 1, 2, f_remote_peek}, 7111 {"remote_read", 1, 1, f_remote_read}, 7112 {"remote_send", 2, 3, f_remote_send}, 7113 {"remove", 2, 3, f_remove}, 7114 {"rename", 2, 2, f_rename}, 7115 {"repeat", 2, 2, f_repeat}, 7116 {"resolve", 1, 1, f_resolve}, 7117 {"reverse", 1, 1, f_reverse}, 7118 {"search", 1, 3, f_search}, 7119 {"searchdecl", 1, 3, f_searchdecl}, 7120 {"searchpair", 3, 6, f_searchpair}, 7121 {"searchpairpos", 3, 6, f_searchpairpos}, 7122 {"searchpos", 1, 3, f_searchpos}, 7123 {"server2client", 2, 2, f_server2client}, 7124 {"serverlist", 0, 0, f_serverlist}, 7125 {"setbufvar", 3, 3, f_setbufvar}, 7126 {"setcmdpos", 1, 1, f_setcmdpos}, 7127 {"setline", 2, 2, f_setline}, 7128 {"setloclist", 2, 3, f_setloclist}, 7129 {"setpos", 2, 2, f_setpos}, 7130 {"setqflist", 1, 2, f_setqflist}, 7131 {"setreg", 2, 3, f_setreg}, 7132 {"settabwinvar", 4, 4, f_settabwinvar}, 7133 {"setwinvar", 3, 3, f_setwinvar}, 7134 {"simplify", 1, 1, f_simplify}, 7135 {"sort", 1, 2, f_sort}, 7136 {"soundfold", 1, 1, f_soundfold}, 7137 {"spellbadword", 0, 1, f_spellbadword}, 7138 {"spellsuggest", 1, 3, f_spellsuggest}, 7139 {"split", 1, 3, f_split}, 7140 {"str2nr", 1, 2, f_str2nr}, 7141 #ifdef HAVE_STRFTIME 7142 {"strftime", 1, 2, f_strftime}, 7143 #endif 7144 {"stridx", 2, 3, f_stridx}, 7145 {"string", 1, 1, f_string}, 7146 {"strlen", 1, 1, f_strlen}, 7147 {"strpart", 2, 3, f_strpart}, 7148 {"strridx", 2, 3, f_strridx}, 7149 {"strtrans", 1, 1, f_strtrans}, 7150 {"submatch", 1, 1, f_submatch}, 7151 {"substitute", 4, 4, f_substitute}, 7152 {"synID", 3, 3, f_synID}, 7153 {"synIDattr", 2, 3, f_synIDattr}, 7154 {"synIDtrans", 1, 1, f_synIDtrans}, 7155 {"system", 1, 2, f_system}, 7156 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 7157 {"tabpagenr", 0, 1, f_tabpagenr}, 7158 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 7159 {"tagfiles", 0, 0, f_tagfiles}, 7160 {"taglist", 1, 1, f_taglist}, 7161 {"tempname", 0, 0, f_tempname}, 7162 {"test", 1, 1, f_test}, 7163 {"tolower", 1, 1, f_tolower}, 7164 {"toupper", 1, 1, f_toupper}, 7165 {"tr", 3, 3, f_tr}, 7166 {"type", 1, 1, f_type}, 7167 {"values", 1, 1, f_values}, 7168 {"virtcol", 1, 1, f_virtcol}, 7169 {"visualmode", 0, 1, f_visualmode}, 7170 {"winbufnr", 1, 1, f_winbufnr}, 7171 {"wincol", 0, 0, f_wincol}, 7172 {"winheight", 1, 1, f_winheight}, 7173 {"winline", 0, 0, f_winline}, 7174 {"winnr", 0, 1, f_winnr}, 7175 {"winrestcmd", 0, 0, f_winrestcmd}, 7176 {"winrestview", 1, 1, f_winrestview}, 7177 {"winsaveview", 0, 0, f_winsaveview}, 7178 {"winwidth", 1, 1, f_winwidth}, 7179 {"writefile", 2, 3, f_writefile}, 7180 }; 7181 7182 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 7183 7184 /* 7185 * Function given to ExpandGeneric() to obtain the list of internal 7186 * or user defined function names. 7187 */ 7188 char_u * 7189 get_function_name(xp, idx) 7190 expand_T *xp; 7191 int idx; 7192 { 7193 static int intidx = -1; 7194 char_u *name; 7195 7196 if (idx == 0) 7197 intidx = -1; 7198 if (intidx < 0) 7199 { 7200 name = get_user_func_name(xp, idx); 7201 if (name != NULL) 7202 return name; 7203 } 7204 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 7205 { 7206 STRCPY(IObuff, functions[intidx].f_name); 7207 STRCAT(IObuff, "("); 7208 if (functions[intidx].f_max_argc == 0) 7209 STRCAT(IObuff, ")"); 7210 return IObuff; 7211 } 7212 7213 return NULL; 7214 } 7215 7216 /* 7217 * Function given to ExpandGeneric() to obtain the list of internal or 7218 * user defined variable or function names. 7219 */ 7220 /*ARGSUSED*/ 7221 char_u * 7222 get_expr_name(xp, idx) 7223 expand_T *xp; 7224 int idx; 7225 { 7226 static int intidx = -1; 7227 char_u *name; 7228 7229 if (idx == 0) 7230 intidx = -1; 7231 if (intidx < 0) 7232 { 7233 name = get_function_name(xp, idx); 7234 if (name != NULL) 7235 return name; 7236 } 7237 return get_user_var_name(xp, ++intidx); 7238 } 7239 7240 #endif /* FEAT_CMDL_COMPL */ 7241 7242 /* 7243 * Find internal function in table above. 7244 * Return index, or -1 if not found 7245 */ 7246 static int 7247 find_internal_func(name) 7248 char_u *name; /* name of the function */ 7249 { 7250 int first = 0; 7251 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 7252 int cmp; 7253 int x; 7254 7255 /* 7256 * Find the function name in the table. Binary search. 7257 */ 7258 while (first <= last) 7259 { 7260 x = first + ((unsigned)(last - first) >> 1); 7261 cmp = STRCMP(name, functions[x].f_name); 7262 if (cmp < 0) 7263 last = x - 1; 7264 else if (cmp > 0) 7265 first = x + 1; 7266 else 7267 return x; 7268 } 7269 return -1; 7270 } 7271 7272 /* 7273 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7274 * name it contains, otherwise return "name". 7275 */ 7276 static char_u * 7277 deref_func_name(name, lenp) 7278 char_u *name; 7279 int *lenp; 7280 { 7281 dictitem_T *v; 7282 int cc; 7283 7284 cc = name[*lenp]; 7285 name[*lenp] = NUL; 7286 v = find_var(name, NULL); 7287 name[*lenp] = cc; 7288 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7289 { 7290 if (v->di_tv.vval.v_string == NULL) 7291 { 7292 *lenp = 0; 7293 return (char_u *)""; /* just in case */ 7294 } 7295 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 7296 return v->di_tv.vval.v_string; 7297 } 7298 7299 return name; 7300 } 7301 7302 /* 7303 * Allocate a variable for the result of a function. 7304 * Return OK or FAIL. 7305 */ 7306 static int 7307 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7308 evaluate, selfdict) 7309 char_u *name; /* name of the function */ 7310 int len; /* length of "name" */ 7311 typval_T *rettv; 7312 char_u **arg; /* argument, pointing to the '(' */ 7313 linenr_T firstline; /* first line of range */ 7314 linenr_T lastline; /* last line of range */ 7315 int *doesrange; /* return: function handled range */ 7316 int evaluate; 7317 dict_T *selfdict; /* Dictionary for "self" */ 7318 { 7319 char_u *argp; 7320 int ret = OK; 7321 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7322 int argcount = 0; /* number of arguments found */ 7323 7324 /* 7325 * Get the arguments. 7326 */ 7327 argp = *arg; 7328 while (argcount < MAX_FUNC_ARGS) 7329 { 7330 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7331 if (*argp == ')' || *argp == ',' || *argp == NUL) 7332 break; 7333 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7334 { 7335 ret = FAIL; 7336 break; 7337 } 7338 ++argcount; 7339 if (*argp != ',') 7340 break; 7341 } 7342 if (*argp == ')') 7343 ++argp; 7344 else 7345 ret = FAIL; 7346 7347 if (ret == OK) 7348 ret = call_func(name, len, rettv, argcount, argvars, 7349 firstline, lastline, doesrange, evaluate, selfdict); 7350 else if (!aborting()) 7351 { 7352 if (argcount == MAX_FUNC_ARGS) 7353 emsg_funcname("E740: Too many arguments for function %s", name); 7354 else 7355 emsg_funcname("E116: Invalid arguments for function %s", name); 7356 } 7357 7358 while (--argcount >= 0) 7359 clear_tv(&argvars[argcount]); 7360 7361 *arg = skipwhite(argp); 7362 return ret; 7363 } 7364 7365 7366 /* 7367 * Call a function with its resolved parameters 7368 * Return OK when the function can't be called, FAIL otherwise. 7369 * Also returns OK when an error was encountered while executing the function. 7370 */ 7371 static int 7372 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7373 doesrange, evaluate, selfdict) 7374 char_u *name; /* name of the function */ 7375 int len; /* length of "name" */ 7376 typval_T *rettv; /* return value goes here */ 7377 int argcount; /* number of "argvars" */ 7378 typval_T *argvars; /* vars for arguments */ 7379 linenr_T firstline; /* first line of range */ 7380 linenr_T lastline; /* last line of range */ 7381 int *doesrange; /* return: function handled range */ 7382 int evaluate; 7383 dict_T *selfdict; /* Dictionary for "self" */ 7384 { 7385 int ret = FAIL; 7386 #define ERROR_UNKNOWN 0 7387 #define ERROR_TOOMANY 1 7388 #define ERROR_TOOFEW 2 7389 #define ERROR_SCRIPT 3 7390 #define ERROR_DICT 4 7391 #define ERROR_NONE 5 7392 #define ERROR_OTHER 6 7393 int error = ERROR_NONE; 7394 int i; 7395 int llen; 7396 ufunc_T *fp; 7397 int cc; 7398 #define FLEN_FIXED 40 7399 char_u fname_buf[FLEN_FIXED + 1]; 7400 char_u *fname; 7401 7402 /* 7403 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7404 * Change <SNR>123_name() to K_SNR 123_name(). 7405 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7406 */ 7407 cc = name[len]; 7408 name[len] = NUL; 7409 llen = eval_fname_script(name); 7410 if (llen > 0) 7411 { 7412 fname_buf[0] = K_SPECIAL; 7413 fname_buf[1] = KS_EXTRA; 7414 fname_buf[2] = (int)KE_SNR; 7415 i = 3; 7416 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7417 { 7418 if (current_SID <= 0) 7419 error = ERROR_SCRIPT; 7420 else 7421 { 7422 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7423 i = (int)STRLEN(fname_buf); 7424 } 7425 } 7426 if (i + STRLEN(name + llen) < FLEN_FIXED) 7427 { 7428 STRCPY(fname_buf + i, name + llen); 7429 fname = fname_buf; 7430 } 7431 else 7432 { 7433 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7434 if (fname == NULL) 7435 error = ERROR_OTHER; 7436 else 7437 { 7438 mch_memmove(fname, fname_buf, (size_t)i); 7439 STRCPY(fname + i, name + llen); 7440 } 7441 } 7442 } 7443 else 7444 fname = name; 7445 7446 *doesrange = FALSE; 7447 7448 7449 /* execute the function if no errors detected and executing */ 7450 if (evaluate && error == ERROR_NONE) 7451 { 7452 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7453 error = ERROR_UNKNOWN; 7454 7455 if (!builtin_function(fname)) 7456 { 7457 /* 7458 * User defined function. 7459 */ 7460 fp = find_func(fname); 7461 7462 #ifdef FEAT_AUTOCMD 7463 /* Trigger FuncUndefined event, may load the function. */ 7464 if (fp == NULL 7465 && apply_autocmds(EVENT_FUNCUNDEFINED, 7466 fname, fname, TRUE, NULL) 7467 && !aborting()) 7468 { 7469 /* executed an autocommand, search for the function again */ 7470 fp = find_func(fname); 7471 } 7472 #endif 7473 /* Try loading a package. */ 7474 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7475 { 7476 /* loaded a package, search for the function again */ 7477 fp = find_func(fname); 7478 } 7479 7480 if (fp != NULL) 7481 { 7482 if (fp->uf_flags & FC_RANGE) 7483 *doesrange = TRUE; 7484 if (argcount < fp->uf_args.ga_len) 7485 error = ERROR_TOOFEW; 7486 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7487 error = ERROR_TOOMANY; 7488 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7489 error = ERROR_DICT; 7490 else 7491 { 7492 /* 7493 * Call the user function. 7494 * Save and restore search patterns, script variables and 7495 * redo buffer. 7496 */ 7497 save_search_patterns(); 7498 saveRedobuff(); 7499 ++fp->uf_calls; 7500 call_user_func(fp, argcount, argvars, rettv, 7501 firstline, lastline, 7502 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7503 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7504 && fp->uf_refcount <= 0) 7505 /* Function was unreferenced while being used, free it 7506 * now. */ 7507 func_free(fp); 7508 restoreRedobuff(); 7509 restore_search_patterns(); 7510 error = ERROR_NONE; 7511 } 7512 } 7513 } 7514 else 7515 { 7516 /* 7517 * Find the function name in the table, call its implementation. 7518 */ 7519 i = find_internal_func(fname); 7520 if (i >= 0) 7521 { 7522 if (argcount < functions[i].f_min_argc) 7523 error = ERROR_TOOFEW; 7524 else if (argcount > functions[i].f_max_argc) 7525 error = ERROR_TOOMANY; 7526 else 7527 { 7528 argvars[argcount].v_type = VAR_UNKNOWN; 7529 functions[i].f_func(argvars, rettv); 7530 error = ERROR_NONE; 7531 } 7532 } 7533 } 7534 /* 7535 * The function call (or "FuncUndefined" autocommand sequence) might 7536 * have been aborted by an error, an interrupt, or an explicitly thrown 7537 * exception that has not been caught so far. This situation can be 7538 * tested for by calling aborting(). For an error in an internal 7539 * function or for the "E132" error in call_user_func(), however, the 7540 * throw point at which the "force_abort" flag (temporarily reset by 7541 * emsg()) is normally updated has not been reached yet. We need to 7542 * update that flag first to make aborting() reliable. 7543 */ 7544 update_force_abort(); 7545 } 7546 if (error == ERROR_NONE) 7547 ret = OK; 7548 7549 /* 7550 * Report an error unless the argument evaluation or function call has been 7551 * cancelled due to an aborting error, an interrupt, or an exception. 7552 */ 7553 if (!aborting()) 7554 { 7555 switch (error) 7556 { 7557 case ERROR_UNKNOWN: 7558 emsg_funcname(N_("E117: Unknown function: %s"), name); 7559 break; 7560 case ERROR_TOOMANY: 7561 emsg_funcname(e_toomanyarg, name); 7562 break; 7563 case ERROR_TOOFEW: 7564 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 7565 name); 7566 break; 7567 case ERROR_SCRIPT: 7568 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 7569 name); 7570 break; 7571 case ERROR_DICT: 7572 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 7573 name); 7574 break; 7575 } 7576 } 7577 7578 name[len] = cc; 7579 if (fname != name && fname != fname_buf) 7580 vim_free(fname); 7581 7582 return ret; 7583 } 7584 7585 /* 7586 * Give an error message with a function name. Handle <SNR> things. 7587 */ 7588 static void 7589 emsg_funcname(msg, name) 7590 char *msg; 7591 char_u *name; 7592 { 7593 char_u *p; 7594 7595 if (*name == K_SPECIAL) 7596 p = concat_str((char_u *)"<SNR>", name + 3); 7597 else 7598 p = name; 7599 EMSG2(_(msg), p); 7600 if (p != name) 7601 vim_free(p); 7602 } 7603 7604 /********************************************* 7605 * Implementation of the built-in functions 7606 */ 7607 7608 /* 7609 * "add(list, item)" function 7610 */ 7611 static void 7612 f_add(argvars, rettv) 7613 typval_T *argvars; 7614 typval_T *rettv; 7615 { 7616 list_T *l; 7617 7618 rettv->vval.v_number = 1; /* Default: Failed */ 7619 if (argvars[0].v_type == VAR_LIST) 7620 { 7621 if ((l = argvars[0].vval.v_list) != NULL 7622 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7623 && list_append_tv(l, &argvars[1]) == OK) 7624 copy_tv(&argvars[0], rettv); 7625 } 7626 else 7627 EMSG(_(e_listreq)); 7628 } 7629 7630 /* 7631 * "append(lnum, string/list)" function 7632 */ 7633 static void 7634 f_append(argvars, rettv) 7635 typval_T *argvars; 7636 typval_T *rettv; 7637 { 7638 long lnum; 7639 char_u *line; 7640 list_T *l = NULL; 7641 listitem_T *li = NULL; 7642 typval_T *tv; 7643 long added = 0; 7644 7645 lnum = get_tv_lnum(argvars); 7646 if (lnum >= 0 7647 && lnum <= curbuf->b_ml.ml_line_count 7648 && u_save(lnum, lnum + 1) == OK) 7649 { 7650 if (argvars[1].v_type == VAR_LIST) 7651 { 7652 l = argvars[1].vval.v_list; 7653 if (l == NULL) 7654 return; 7655 li = l->lv_first; 7656 } 7657 rettv->vval.v_number = 0; /* Default: Success */ 7658 for (;;) 7659 { 7660 if (l == NULL) 7661 tv = &argvars[1]; /* append a string */ 7662 else if (li == NULL) 7663 break; /* end of list */ 7664 else 7665 tv = &li->li_tv; /* append item from list */ 7666 line = get_tv_string_chk(tv); 7667 if (line == NULL) /* type error */ 7668 { 7669 rettv->vval.v_number = 1; /* Failed */ 7670 break; 7671 } 7672 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7673 ++added; 7674 if (l == NULL) 7675 break; 7676 li = li->li_next; 7677 } 7678 7679 appended_lines_mark(lnum, added); 7680 if (curwin->w_cursor.lnum > lnum) 7681 curwin->w_cursor.lnum += added; 7682 } 7683 else 7684 rettv->vval.v_number = 1; /* Failed */ 7685 } 7686 7687 /* 7688 * "argc()" function 7689 */ 7690 /* ARGSUSED */ 7691 static void 7692 f_argc(argvars, rettv) 7693 typval_T *argvars; 7694 typval_T *rettv; 7695 { 7696 rettv->vval.v_number = ARGCOUNT; 7697 } 7698 7699 /* 7700 * "argidx()" function 7701 */ 7702 /* ARGSUSED */ 7703 static void 7704 f_argidx(argvars, rettv) 7705 typval_T *argvars; 7706 typval_T *rettv; 7707 { 7708 rettv->vval.v_number = curwin->w_arg_idx; 7709 } 7710 7711 /* 7712 * "argv(nr)" function 7713 */ 7714 static void 7715 f_argv(argvars, rettv) 7716 typval_T *argvars; 7717 typval_T *rettv; 7718 { 7719 int idx; 7720 7721 if (argvars[0].v_type != VAR_UNKNOWN) 7722 { 7723 idx = get_tv_number_chk(&argvars[0], NULL); 7724 if (idx >= 0 && idx < ARGCOUNT) 7725 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7726 else 7727 rettv->vval.v_string = NULL; 7728 rettv->v_type = VAR_STRING; 7729 } 7730 else if (rettv_list_alloc(rettv) == OK) 7731 for (idx = 0; idx < ARGCOUNT; ++idx) 7732 list_append_string(rettv->vval.v_list, 7733 alist_name(&ARGLIST[idx]), -1); 7734 } 7735 7736 /* 7737 * "browse(save, title, initdir, default)" function 7738 */ 7739 /* ARGSUSED */ 7740 static void 7741 f_browse(argvars, rettv) 7742 typval_T *argvars; 7743 typval_T *rettv; 7744 { 7745 #ifdef FEAT_BROWSE 7746 int save; 7747 char_u *title; 7748 char_u *initdir; 7749 char_u *defname; 7750 char_u buf[NUMBUFLEN]; 7751 char_u buf2[NUMBUFLEN]; 7752 int error = FALSE; 7753 7754 save = get_tv_number_chk(&argvars[0], &error); 7755 title = get_tv_string_chk(&argvars[1]); 7756 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7757 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7758 7759 if (error || title == NULL || initdir == NULL || defname == NULL) 7760 rettv->vval.v_string = NULL; 7761 else 7762 rettv->vval.v_string = 7763 do_browse(save ? BROWSE_SAVE : 0, 7764 title, defname, NULL, initdir, NULL, curbuf); 7765 #else 7766 rettv->vval.v_string = NULL; 7767 #endif 7768 rettv->v_type = VAR_STRING; 7769 } 7770 7771 /* 7772 * "browsedir(title, initdir)" function 7773 */ 7774 /* ARGSUSED */ 7775 static void 7776 f_browsedir(argvars, rettv) 7777 typval_T *argvars; 7778 typval_T *rettv; 7779 { 7780 #ifdef FEAT_BROWSE 7781 char_u *title; 7782 char_u *initdir; 7783 char_u buf[NUMBUFLEN]; 7784 7785 title = get_tv_string_chk(&argvars[0]); 7786 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7787 7788 if (title == NULL || initdir == NULL) 7789 rettv->vval.v_string = NULL; 7790 else 7791 rettv->vval.v_string = do_browse(BROWSE_DIR, 7792 title, NULL, NULL, initdir, NULL, curbuf); 7793 #else 7794 rettv->vval.v_string = NULL; 7795 #endif 7796 rettv->v_type = VAR_STRING; 7797 } 7798 7799 static buf_T *find_buffer __ARGS((typval_T *avar)); 7800 7801 /* 7802 * Find a buffer by number or exact name. 7803 */ 7804 static buf_T * 7805 find_buffer(avar) 7806 typval_T *avar; 7807 { 7808 buf_T *buf = NULL; 7809 7810 if (avar->v_type == VAR_NUMBER) 7811 buf = buflist_findnr((int)avar->vval.v_number); 7812 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7813 { 7814 buf = buflist_findname_exp(avar->vval.v_string); 7815 if (buf == NULL) 7816 { 7817 /* No full path name match, try a match with a URL or a "nofile" 7818 * buffer, these don't use the full path. */ 7819 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7820 if (buf->b_fname != NULL 7821 && (path_with_url(buf->b_fname) 7822 #ifdef FEAT_QUICKFIX 7823 || bt_nofile(buf) 7824 #endif 7825 ) 7826 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7827 break; 7828 } 7829 } 7830 return buf; 7831 } 7832 7833 /* 7834 * "bufexists(expr)" function 7835 */ 7836 static void 7837 f_bufexists(argvars, rettv) 7838 typval_T *argvars; 7839 typval_T *rettv; 7840 { 7841 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7842 } 7843 7844 /* 7845 * "buflisted(expr)" function 7846 */ 7847 static void 7848 f_buflisted(argvars, rettv) 7849 typval_T *argvars; 7850 typval_T *rettv; 7851 { 7852 buf_T *buf; 7853 7854 buf = find_buffer(&argvars[0]); 7855 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7856 } 7857 7858 /* 7859 * "bufloaded(expr)" function 7860 */ 7861 static void 7862 f_bufloaded(argvars, rettv) 7863 typval_T *argvars; 7864 typval_T *rettv; 7865 { 7866 buf_T *buf; 7867 7868 buf = find_buffer(&argvars[0]); 7869 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7870 } 7871 7872 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7873 7874 /* 7875 * Get buffer by number or pattern. 7876 */ 7877 static buf_T * 7878 get_buf_tv(tv) 7879 typval_T *tv; 7880 { 7881 char_u *name = tv->vval.v_string; 7882 int save_magic; 7883 char_u *save_cpo; 7884 buf_T *buf; 7885 7886 if (tv->v_type == VAR_NUMBER) 7887 return buflist_findnr((int)tv->vval.v_number); 7888 if (tv->v_type != VAR_STRING) 7889 return NULL; 7890 if (name == NULL || *name == NUL) 7891 return curbuf; 7892 if (name[0] == '$' && name[1] == NUL) 7893 return lastbuf; 7894 7895 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7896 save_magic = p_magic; 7897 p_magic = TRUE; 7898 save_cpo = p_cpo; 7899 p_cpo = (char_u *)""; 7900 7901 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7902 TRUE, FALSE)); 7903 7904 p_magic = save_magic; 7905 p_cpo = save_cpo; 7906 7907 /* If not found, try expanding the name, like done for bufexists(). */ 7908 if (buf == NULL) 7909 buf = find_buffer(tv); 7910 7911 return buf; 7912 } 7913 7914 /* 7915 * "bufname(expr)" function 7916 */ 7917 static void 7918 f_bufname(argvars, rettv) 7919 typval_T *argvars; 7920 typval_T *rettv; 7921 { 7922 buf_T *buf; 7923 7924 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7925 ++emsg_off; 7926 buf = get_buf_tv(&argvars[0]); 7927 rettv->v_type = VAR_STRING; 7928 if (buf != NULL && buf->b_fname != NULL) 7929 rettv->vval.v_string = vim_strsave(buf->b_fname); 7930 else 7931 rettv->vval.v_string = NULL; 7932 --emsg_off; 7933 } 7934 7935 /* 7936 * "bufnr(expr)" function 7937 */ 7938 static void 7939 f_bufnr(argvars, rettv) 7940 typval_T *argvars; 7941 typval_T *rettv; 7942 { 7943 buf_T *buf; 7944 int error = FALSE; 7945 char_u *name; 7946 7947 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7948 ++emsg_off; 7949 buf = get_buf_tv(&argvars[0]); 7950 --emsg_off; 7951 7952 /* If the buffer isn't found and the second argument is not zero create a 7953 * new buffer. */ 7954 if (buf == NULL 7955 && argvars[1].v_type != VAR_UNKNOWN 7956 && get_tv_number_chk(&argvars[1], &error) != 0 7957 && !error 7958 && (name = get_tv_string_chk(&argvars[0])) != NULL 7959 && !error) 7960 buf = buflist_new(name, NULL, (linenr_T)1, 0); 7961 7962 if (buf != NULL) 7963 rettv->vval.v_number = buf->b_fnum; 7964 else 7965 rettv->vval.v_number = -1; 7966 } 7967 7968 /* 7969 * "bufwinnr(nr)" function 7970 */ 7971 static void 7972 f_bufwinnr(argvars, rettv) 7973 typval_T *argvars; 7974 typval_T *rettv; 7975 { 7976 #ifdef FEAT_WINDOWS 7977 win_T *wp; 7978 int winnr = 0; 7979 #endif 7980 buf_T *buf; 7981 7982 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7983 ++emsg_off; 7984 buf = get_buf_tv(&argvars[0]); 7985 #ifdef FEAT_WINDOWS 7986 for (wp = firstwin; wp; wp = wp->w_next) 7987 { 7988 ++winnr; 7989 if (wp->w_buffer == buf) 7990 break; 7991 } 7992 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7993 #else 7994 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7995 #endif 7996 --emsg_off; 7997 } 7998 7999 /* 8000 * "byte2line(byte)" function 8001 */ 8002 /*ARGSUSED*/ 8003 static void 8004 f_byte2line(argvars, rettv) 8005 typval_T *argvars; 8006 typval_T *rettv; 8007 { 8008 #ifndef FEAT_BYTEOFF 8009 rettv->vval.v_number = -1; 8010 #else 8011 long boff = 0; 8012 8013 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 8014 if (boff < 0) 8015 rettv->vval.v_number = -1; 8016 else 8017 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 8018 (linenr_T)0, &boff); 8019 #endif 8020 } 8021 8022 /* 8023 * "byteidx()" function 8024 */ 8025 /*ARGSUSED*/ 8026 static void 8027 f_byteidx(argvars, rettv) 8028 typval_T *argvars; 8029 typval_T *rettv; 8030 { 8031 #ifdef FEAT_MBYTE 8032 char_u *t; 8033 #endif 8034 char_u *str; 8035 long idx; 8036 8037 str = get_tv_string_chk(&argvars[0]); 8038 idx = get_tv_number_chk(&argvars[1], NULL); 8039 rettv->vval.v_number = -1; 8040 if (str == NULL || idx < 0) 8041 return; 8042 8043 #ifdef FEAT_MBYTE 8044 t = str; 8045 for ( ; idx > 0; idx--) 8046 { 8047 if (*t == NUL) /* EOL reached */ 8048 return; 8049 t += (*mb_ptr2len)(t); 8050 } 8051 rettv->vval.v_number = (varnumber_T)(t - str); 8052 #else 8053 if (idx <= STRLEN(str)) 8054 rettv->vval.v_number = idx; 8055 #endif 8056 } 8057 8058 /* 8059 * "call(func, arglist)" function 8060 */ 8061 static void 8062 f_call(argvars, rettv) 8063 typval_T *argvars; 8064 typval_T *rettv; 8065 { 8066 char_u *func; 8067 typval_T argv[MAX_FUNC_ARGS]; 8068 int argc = 0; 8069 listitem_T *item; 8070 int dummy; 8071 dict_T *selfdict = NULL; 8072 8073 rettv->vval.v_number = 0; 8074 if (argvars[1].v_type != VAR_LIST) 8075 { 8076 EMSG(_(e_listreq)); 8077 return; 8078 } 8079 if (argvars[1].vval.v_list == NULL) 8080 return; 8081 8082 if (argvars[0].v_type == VAR_FUNC) 8083 func = argvars[0].vval.v_string; 8084 else 8085 func = get_tv_string(&argvars[0]); 8086 if (*func == NUL) 8087 return; /* type error or empty name */ 8088 8089 if (argvars[2].v_type != VAR_UNKNOWN) 8090 { 8091 if (argvars[2].v_type != VAR_DICT) 8092 { 8093 EMSG(_(e_dictreq)); 8094 return; 8095 } 8096 selfdict = argvars[2].vval.v_dict; 8097 } 8098 8099 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 8100 item = item->li_next) 8101 { 8102 if (argc == MAX_FUNC_ARGS) 8103 { 8104 EMSG(_("E699: Too many arguments")); 8105 break; 8106 } 8107 /* Make a copy of each argument. This is needed to be able to set 8108 * v_lock to VAR_FIXED in the copy without changing the original list. 8109 */ 8110 copy_tv(&item->li_tv, &argv[argc++]); 8111 } 8112 8113 if (item == NULL) 8114 (void)call_func(func, (int)STRLEN(func), rettv, argc, argv, 8115 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 8116 &dummy, TRUE, selfdict); 8117 8118 /* Free the arguments. */ 8119 while (argc > 0) 8120 clear_tv(&argv[--argc]); 8121 } 8122 8123 /* 8124 * "changenr()" function 8125 */ 8126 /*ARGSUSED*/ 8127 static void 8128 f_changenr(argvars, rettv) 8129 typval_T *argvars; 8130 typval_T *rettv; 8131 { 8132 rettv->vval.v_number = curbuf->b_u_seq_cur; 8133 } 8134 8135 /* 8136 * "char2nr(string)" function 8137 */ 8138 static void 8139 f_char2nr(argvars, rettv) 8140 typval_T *argvars; 8141 typval_T *rettv; 8142 { 8143 #ifdef FEAT_MBYTE 8144 if (has_mbyte) 8145 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 8146 else 8147 #endif 8148 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 8149 } 8150 8151 /* 8152 * "cindent(lnum)" function 8153 */ 8154 static void 8155 f_cindent(argvars, rettv) 8156 typval_T *argvars; 8157 typval_T *rettv; 8158 { 8159 #ifdef FEAT_CINDENT 8160 pos_T pos; 8161 linenr_T lnum; 8162 8163 pos = curwin->w_cursor; 8164 lnum = get_tv_lnum(argvars); 8165 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8166 { 8167 curwin->w_cursor.lnum = lnum; 8168 rettv->vval.v_number = get_c_indent(); 8169 curwin->w_cursor = pos; 8170 } 8171 else 8172 #endif 8173 rettv->vval.v_number = -1; 8174 } 8175 8176 /* 8177 * "col(string)" function 8178 */ 8179 static void 8180 f_col(argvars, rettv) 8181 typval_T *argvars; 8182 typval_T *rettv; 8183 { 8184 colnr_T col = 0; 8185 pos_T *fp; 8186 int fnum = curbuf->b_fnum; 8187 8188 fp = var2fpos(&argvars[0], FALSE, &fnum); 8189 if (fp != NULL && fnum == curbuf->b_fnum) 8190 { 8191 if (fp->col == MAXCOL) 8192 { 8193 /* '> can be MAXCOL, get the length of the line then */ 8194 if (fp->lnum <= curbuf->b_ml.ml_line_count) 8195 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 8196 else 8197 col = MAXCOL; 8198 } 8199 else 8200 { 8201 col = fp->col + 1; 8202 #ifdef FEAT_VIRTUALEDIT 8203 /* col(".") when the cursor is on the NUL at the end of the line 8204 * because of "coladd" can be seen as an extra column. */ 8205 if (virtual_active() && fp == &curwin->w_cursor) 8206 { 8207 char_u *p = ml_get_cursor(); 8208 8209 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 8210 curwin->w_virtcol - curwin->w_cursor.coladd)) 8211 { 8212 # ifdef FEAT_MBYTE 8213 int l; 8214 8215 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 8216 col += l; 8217 # else 8218 if (*p != NUL && p[1] == NUL) 8219 ++col; 8220 # endif 8221 } 8222 } 8223 #endif 8224 } 8225 } 8226 rettv->vval.v_number = col; 8227 } 8228 8229 #if defined(FEAT_INS_EXPAND) 8230 /* 8231 * "complete()" function 8232 */ 8233 /*ARGSUSED*/ 8234 static void 8235 f_complete(argvars, rettv) 8236 typval_T *argvars; 8237 typval_T *rettv; 8238 { 8239 int startcol; 8240 8241 if ((State & INSERT) == 0) 8242 { 8243 EMSG(_("E785: complete() can only be used in Insert mode")); 8244 return; 8245 } 8246 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 8247 { 8248 EMSG(_(e_invarg)); 8249 return; 8250 } 8251 8252 startcol = get_tv_number_chk(&argvars[0], NULL); 8253 if (startcol <= 0) 8254 return; 8255 8256 set_completion(startcol - 1, argvars[1].vval.v_list); 8257 } 8258 8259 /* 8260 * "complete_add()" function 8261 */ 8262 /*ARGSUSED*/ 8263 static void 8264 f_complete_add(argvars, rettv) 8265 typval_T *argvars; 8266 typval_T *rettv; 8267 { 8268 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 8269 } 8270 8271 /* 8272 * "complete_check()" function 8273 */ 8274 /*ARGSUSED*/ 8275 static void 8276 f_complete_check(argvars, rettv) 8277 typval_T *argvars; 8278 typval_T *rettv; 8279 { 8280 int saved = RedrawingDisabled; 8281 8282 RedrawingDisabled = 0; 8283 ins_compl_check_keys(0); 8284 rettv->vval.v_number = compl_interrupted; 8285 RedrawingDisabled = saved; 8286 } 8287 #endif 8288 8289 /* 8290 * "confirm(message, buttons[, default [, type]])" function 8291 */ 8292 /*ARGSUSED*/ 8293 static void 8294 f_confirm(argvars, rettv) 8295 typval_T *argvars; 8296 typval_T *rettv; 8297 { 8298 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 8299 char_u *message; 8300 char_u *buttons = NULL; 8301 char_u buf[NUMBUFLEN]; 8302 char_u buf2[NUMBUFLEN]; 8303 int def = 1; 8304 int type = VIM_GENERIC; 8305 char_u *typestr; 8306 int error = FALSE; 8307 8308 message = get_tv_string_chk(&argvars[0]); 8309 if (message == NULL) 8310 error = TRUE; 8311 if (argvars[1].v_type != VAR_UNKNOWN) 8312 { 8313 buttons = get_tv_string_buf_chk(&argvars[1], buf); 8314 if (buttons == NULL) 8315 error = TRUE; 8316 if (argvars[2].v_type != VAR_UNKNOWN) 8317 { 8318 def = get_tv_number_chk(&argvars[2], &error); 8319 if (argvars[3].v_type != VAR_UNKNOWN) 8320 { 8321 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 8322 if (typestr == NULL) 8323 error = TRUE; 8324 else 8325 { 8326 switch (TOUPPER_ASC(*typestr)) 8327 { 8328 case 'E': type = VIM_ERROR; break; 8329 case 'Q': type = VIM_QUESTION; break; 8330 case 'I': type = VIM_INFO; break; 8331 case 'W': type = VIM_WARNING; break; 8332 case 'G': type = VIM_GENERIC; break; 8333 } 8334 } 8335 } 8336 } 8337 } 8338 8339 if (buttons == NULL || *buttons == NUL) 8340 buttons = (char_u *)_("&Ok"); 8341 8342 if (error) 8343 rettv->vval.v_number = 0; 8344 else 8345 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8346 def, NULL); 8347 #else 8348 rettv->vval.v_number = 0; 8349 #endif 8350 } 8351 8352 /* 8353 * "copy()" function 8354 */ 8355 static void 8356 f_copy(argvars, rettv) 8357 typval_T *argvars; 8358 typval_T *rettv; 8359 { 8360 item_copy(&argvars[0], rettv, FALSE, 0); 8361 } 8362 8363 /* 8364 * "count()" function 8365 */ 8366 static void 8367 f_count(argvars, rettv) 8368 typval_T *argvars; 8369 typval_T *rettv; 8370 { 8371 long n = 0; 8372 int ic = FALSE; 8373 8374 if (argvars[0].v_type == VAR_LIST) 8375 { 8376 listitem_T *li; 8377 list_T *l; 8378 long idx; 8379 8380 if ((l = argvars[0].vval.v_list) != NULL) 8381 { 8382 li = l->lv_first; 8383 if (argvars[2].v_type != VAR_UNKNOWN) 8384 { 8385 int error = FALSE; 8386 8387 ic = get_tv_number_chk(&argvars[2], &error); 8388 if (argvars[3].v_type != VAR_UNKNOWN) 8389 { 8390 idx = get_tv_number_chk(&argvars[3], &error); 8391 if (!error) 8392 { 8393 li = list_find(l, idx); 8394 if (li == NULL) 8395 EMSGN(_(e_listidx), idx); 8396 } 8397 } 8398 if (error) 8399 li = NULL; 8400 } 8401 8402 for ( ; li != NULL; li = li->li_next) 8403 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8404 ++n; 8405 } 8406 } 8407 else if (argvars[0].v_type == VAR_DICT) 8408 { 8409 int todo; 8410 dict_T *d; 8411 hashitem_T *hi; 8412 8413 if ((d = argvars[0].vval.v_dict) != NULL) 8414 { 8415 int error = FALSE; 8416 8417 if (argvars[2].v_type != VAR_UNKNOWN) 8418 { 8419 ic = get_tv_number_chk(&argvars[2], &error); 8420 if (argvars[3].v_type != VAR_UNKNOWN) 8421 EMSG(_(e_invarg)); 8422 } 8423 8424 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 8425 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8426 { 8427 if (!HASHITEM_EMPTY(hi)) 8428 { 8429 --todo; 8430 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8431 ++n; 8432 } 8433 } 8434 } 8435 } 8436 else 8437 EMSG2(_(e_listdictarg), "count()"); 8438 rettv->vval.v_number = n; 8439 } 8440 8441 /* 8442 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8443 * 8444 * Checks the existence of a cscope connection. 8445 */ 8446 /*ARGSUSED*/ 8447 static void 8448 f_cscope_connection(argvars, rettv) 8449 typval_T *argvars; 8450 typval_T *rettv; 8451 { 8452 #ifdef FEAT_CSCOPE 8453 int num = 0; 8454 char_u *dbpath = NULL; 8455 char_u *prepend = NULL; 8456 char_u buf[NUMBUFLEN]; 8457 8458 if (argvars[0].v_type != VAR_UNKNOWN 8459 && argvars[1].v_type != VAR_UNKNOWN) 8460 { 8461 num = (int)get_tv_number(&argvars[0]); 8462 dbpath = get_tv_string(&argvars[1]); 8463 if (argvars[2].v_type != VAR_UNKNOWN) 8464 prepend = get_tv_string_buf(&argvars[2], buf); 8465 } 8466 8467 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8468 #else 8469 rettv->vval.v_number = 0; 8470 #endif 8471 } 8472 8473 /* 8474 * "cursor(lnum, col)" function 8475 * 8476 * Moves the cursor to the specified line and column 8477 */ 8478 /*ARGSUSED*/ 8479 static void 8480 f_cursor(argvars, rettv) 8481 typval_T *argvars; 8482 typval_T *rettv; 8483 { 8484 long line, col; 8485 #ifdef FEAT_VIRTUALEDIT 8486 long coladd = 0; 8487 #endif 8488 8489 if (argvars[1].v_type == VAR_UNKNOWN) 8490 { 8491 pos_T pos; 8492 8493 if (list2fpos(argvars, &pos, NULL) == FAIL) 8494 return; 8495 line = pos.lnum; 8496 col = pos.col; 8497 #ifdef FEAT_VIRTUALEDIT 8498 coladd = pos.coladd; 8499 #endif 8500 } 8501 else 8502 { 8503 line = get_tv_lnum(argvars); 8504 col = get_tv_number_chk(&argvars[1], NULL); 8505 #ifdef FEAT_VIRTUALEDIT 8506 if (argvars[2].v_type != VAR_UNKNOWN) 8507 coladd = get_tv_number_chk(&argvars[2], NULL); 8508 #endif 8509 } 8510 if (line < 0 || col < 0 8511 #ifdef FEAT_VIRTUALEDIT 8512 || coladd < 0 8513 #endif 8514 ) 8515 return; /* type error; errmsg already given */ 8516 if (line > 0) 8517 curwin->w_cursor.lnum = line; 8518 if (col > 0) 8519 curwin->w_cursor.col = col - 1; 8520 #ifdef FEAT_VIRTUALEDIT 8521 curwin->w_cursor.coladd = coladd; 8522 #endif 8523 8524 /* Make sure the cursor is in a valid position. */ 8525 check_cursor(); 8526 #ifdef FEAT_MBYTE 8527 /* Correct cursor for multi-byte character. */ 8528 if (has_mbyte) 8529 mb_adjust_cursor(); 8530 #endif 8531 8532 curwin->w_set_curswant = TRUE; 8533 } 8534 8535 /* 8536 * "deepcopy()" function 8537 */ 8538 static void 8539 f_deepcopy(argvars, rettv) 8540 typval_T *argvars; 8541 typval_T *rettv; 8542 { 8543 int noref = 0; 8544 8545 if (argvars[1].v_type != VAR_UNKNOWN) 8546 noref = get_tv_number_chk(&argvars[1], NULL); 8547 if (noref < 0 || noref > 1) 8548 EMSG(_(e_invarg)); 8549 else 8550 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8551 } 8552 8553 /* 8554 * "delete()" function 8555 */ 8556 static void 8557 f_delete(argvars, rettv) 8558 typval_T *argvars; 8559 typval_T *rettv; 8560 { 8561 if (check_restricted() || check_secure()) 8562 rettv->vval.v_number = -1; 8563 else 8564 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8565 } 8566 8567 /* 8568 * "did_filetype()" function 8569 */ 8570 /*ARGSUSED*/ 8571 static void 8572 f_did_filetype(argvars, rettv) 8573 typval_T *argvars; 8574 typval_T *rettv; 8575 { 8576 #ifdef FEAT_AUTOCMD 8577 rettv->vval.v_number = did_filetype; 8578 #else 8579 rettv->vval.v_number = 0; 8580 #endif 8581 } 8582 8583 /* 8584 * "diff_filler()" function 8585 */ 8586 /*ARGSUSED*/ 8587 static void 8588 f_diff_filler(argvars, rettv) 8589 typval_T *argvars; 8590 typval_T *rettv; 8591 { 8592 #ifdef FEAT_DIFF 8593 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8594 #endif 8595 } 8596 8597 /* 8598 * "diff_hlID()" function 8599 */ 8600 /*ARGSUSED*/ 8601 static void 8602 f_diff_hlID(argvars, rettv) 8603 typval_T *argvars; 8604 typval_T *rettv; 8605 { 8606 #ifdef FEAT_DIFF 8607 linenr_T lnum = get_tv_lnum(argvars); 8608 static linenr_T prev_lnum = 0; 8609 static int changedtick = 0; 8610 static int fnum = 0; 8611 static int change_start = 0; 8612 static int change_end = 0; 8613 static hlf_T hlID = 0; 8614 int filler_lines; 8615 int col; 8616 8617 if (lnum < 0) /* ignore type error in {lnum} arg */ 8618 lnum = 0; 8619 if (lnum != prev_lnum 8620 || changedtick != curbuf->b_changedtick 8621 || fnum != curbuf->b_fnum) 8622 { 8623 /* New line, buffer, change: need to get the values. */ 8624 filler_lines = diff_check(curwin, lnum); 8625 if (filler_lines < 0) 8626 { 8627 if (filler_lines == -1) 8628 { 8629 change_start = MAXCOL; 8630 change_end = -1; 8631 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8632 hlID = HLF_ADD; /* added line */ 8633 else 8634 hlID = HLF_CHD; /* changed line */ 8635 } 8636 else 8637 hlID = HLF_ADD; /* added line */ 8638 } 8639 else 8640 hlID = (hlf_T)0; 8641 prev_lnum = lnum; 8642 changedtick = curbuf->b_changedtick; 8643 fnum = curbuf->b_fnum; 8644 } 8645 8646 if (hlID == HLF_CHD || hlID == HLF_TXD) 8647 { 8648 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8649 if (col >= change_start && col <= change_end) 8650 hlID = HLF_TXD; /* changed text */ 8651 else 8652 hlID = HLF_CHD; /* changed line */ 8653 } 8654 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 8655 #endif 8656 } 8657 8658 /* 8659 * "empty({expr})" function 8660 */ 8661 static void 8662 f_empty(argvars, rettv) 8663 typval_T *argvars; 8664 typval_T *rettv; 8665 { 8666 int n; 8667 8668 switch (argvars[0].v_type) 8669 { 8670 case VAR_STRING: 8671 case VAR_FUNC: 8672 n = argvars[0].vval.v_string == NULL 8673 || *argvars[0].vval.v_string == NUL; 8674 break; 8675 case VAR_NUMBER: 8676 n = argvars[0].vval.v_number == 0; 8677 break; 8678 case VAR_LIST: 8679 n = argvars[0].vval.v_list == NULL 8680 || argvars[0].vval.v_list->lv_first == NULL; 8681 break; 8682 case VAR_DICT: 8683 n = argvars[0].vval.v_dict == NULL 8684 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8685 break; 8686 default: 8687 EMSG2(_(e_intern2), "f_empty()"); 8688 n = 0; 8689 } 8690 8691 rettv->vval.v_number = n; 8692 } 8693 8694 /* 8695 * "escape({string}, {chars})" function 8696 */ 8697 static void 8698 f_escape(argvars, rettv) 8699 typval_T *argvars; 8700 typval_T *rettv; 8701 { 8702 char_u buf[NUMBUFLEN]; 8703 8704 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8705 get_tv_string_buf(&argvars[1], buf)); 8706 rettv->v_type = VAR_STRING; 8707 } 8708 8709 /* 8710 * "eval()" function 8711 */ 8712 /*ARGSUSED*/ 8713 static void 8714 f_eval(argvars, rettv) 8715 typval_T *argvars; 8716 typval_T *rettv; 8717 { 8718 char_u *s; 8719 8720 s = get_tv_string_chk(&argvars[0]); 8721 if (s != NULL) 8722 s = skipwhite(s); 8723 8724 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8725 { 8726 rettv->v_type = VAR_NUMBER; 8727 rettv->vval.v_number = 0; 8728 } 8729 else if (*s != NUL) 8730 EMSG(_(e_trailing)); 8731 } 8732 8733 /* 8734 * "eventhandler()" function 8735 */ 8736 /*ARGSUSED*/ 8737 static void 8738 f_eventhandler(argvars, rettv) 8739 typval_T *argvars; 8740 typval_T *rettv; 8741 { 8742 rettv->vval.v_number = vgetc_busy; 8743 } 8744 8745 /* 8746 * "executable()" function 8747 */ 8748 static void 8749 f_executable(argvars, rettv) 8750 typval_T *argvars; 8751 typval_T *rettv; 8752 { 8753 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8754 } 8755 8756 /* 8757 * "exists()" function 8758 */ 8759 static void 8760 f_exists(argvars, rettv) 8761 typval_T *argvars; 8762 typval_T *rettv; 8763 { 8764 char_u *p; 8765 char_u *name; 8766 int n = FALSE; 8767 int len = 0; 8768 8769 p = get_tv_string(&argvars[0]); 8770 if (*p == '$') /* environment variable */ 8771 { 8772 /* first try "normal" environment variables (fast) */ 8773 if (mch_getenv(p + 1) != NULL) 8774 n = TRUE; 8775 else 8776 { 8777 /* try expanding things like $VIM and ${HOME} */ 8778 p = expand_env_save(p); 8779 if (p != NULL && *p != '$') 8780 n = TRUE; 8781 vim_free(p); 8782 } 8783 } 8784 else if (*p == '&' || *p == '+') /* option */ 8785 n = (get_option_tv(&p, NULL, TRUE) == OK); 8786 else if (*p == '*') /* internal or user defined function */ 8787 { 8788 n = function_exists(p + 1); 8789 } 8790 else if (*p == ':') 8791 { 8792 n = cmd_exists(p + 1); 8793 } 8794 else if (*p == '#') 8795 { 8796 #ifdef FEAT_AUTOCMD 8797 if (p[1] == '#') 8798 n = autocmd_supported(p + 2); 8799 else 8800 n = au_exists(p + 1); 8801 #endif 8802 } 8803 else /* internal variable */ 8804 { 8805 char_u *tofree; 8806 typval_T tv; 8807 8808 /* get_name_len() takes care of expanding curly braces */ 8809 name = p; 8810 len = get_name_len(&p, &tofree, TRUE, FALSE); 8811 if (len > 0) 8812 { 8813 if (tofree != NULL) 8814 name = tofree; 8815 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8816 if (n) 8817 { 8818 /* handle d.key, l[idx], f(expr) */ 8819 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8820 if (n) 8821 clear_tv(&tv); 8822 } 8823 } 8824 8825 vim_free(tofree); 8826 } 8827 8828 rettv->vval.v_number = n; 8829 } 8830 8831 /* 8832 * "expand()" function 8833 */ 8834 static void 8835 f_expand(argvars, rettv) 8836 typval_T *argvars; 8837 typval_T *rettv; 8838 { 8839 char_u *s; 8840 int len; 8841 char_u *errormsg; 8842 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8843 expand_T xpc; 8844 int error = FALSE; 8845 8846 rettv->v_type = VAR_STRING; 8847 s = get_tv_string(&argvars[0]); 8848 if (*s == '%' || *s == '#' || *s == '<') 8849 { 8850 ++emsg_off; 8851 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8852 --emsg_off; 8853 } 8854 else 8855 { 8856 /* When the optional second argument is non-zero, don't remove matches 8857 * for 'suffixes' and 'wildignore' */ 8858 if (argvars[1].v_type != VAR_UNKNOWN 8859 && get_tv_number_chk(&argvars[1], &error)) 8860 flags |= WILD_KEEP_ALL; 8861 if (!error) 8862 { 8863 ExpandInit(&xpc); 8864 xpc.xp_context = EXPAND_FILES; 8865 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8866 } 8867 else 8868 rettv->vval.v_string = NULL; 8869 } 8870 } 8871 8872 /* 8873 * "extend(list, list [, idx])" function 8874 * "extend(dict, dict [, action])" function 8875 */ 8876 static void 8877 f_extend(argvars, rettv) 8878 typval_T *argvars; 8879 typval_T *rettv; 8880 { 8881 rettv->vval.v_number = 0; 8882 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8883 { 8884 list_T *l1, *l2; 8885 listitem_T *item; 8886 long before; 8887 int error = FALSE; 8888 8889 l1 = argvars[0].vval.v_list; 8890 l2 = argvars[1].vval.v_list; 8891 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8892 && l2 != NULL) 8893 { 8894 if (argvars[2].v_type != VAR_UNKNOWN) 8895 { 8896 before = get_tv_number_chk(&argvars[2], &error); 8897 if (error) 8898 return; /* type error; errmsg already given */ 8899 8900 if (before == l1->lv_len) 8901 item = NULL; 8902 else 8903 { 8904 item = list_find(l1, before); 8905 if (item == NULL) 8906 { 8907 EMSGN(_(e_listidx), before); 8908 return; 8909 } 8910 } 8911 } 8912 else 8913 item = NULL; 8914 list_extend(l1, l2, item); 8915 8916 copy_tv(&argvars[0], rettv); 8917 } 8918 } 8919 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8920 { 8921 dict_T *d1, *d2; 8922 dictitem_T *di1; 8923 char_u *action; 8924 int i; 8925 hashitem_T *hi2; 8926 int todo; 8927 8928 d1 = argvars[0].vval.v_dict; 8929 d2 = argvars[1].vval.v_dict; 8930 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8931 && d2 != NULL) 8932 { 8933 /* Check the third argument. */ 8934 if (argvars[2].v_type != VAR_UNKNOWN) 8935 { 8936 static char *(av[]) = {"keep", "force", "error"}; 8937 8938 action = get_tv_string_chk(&argvars[2]); 8939 if (action == NULL) 8940 return; /* type error; errmsg already given */ 8941 for (i = 0; i < 3; ++i) 8942 if (STRCMP(action, av[i]) == 0) 8943 break; 8944 if (i == 3) 8945 { 8946 EMSGN(_(e_invarg2), action); 8947 return; 8948 } 8949 } 8950 else 8951 action = (char_u *)"force"; 8952 8953 /* Go over all entries in the second dict and add them to the 8954 * first dict. */ 8955 todo = (int)d2->dv_hashtab.ht_used; 8956 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8957 { 8958 if (!HASHITEM_EMPTY(hi2)) 8959 { 8960 --todo; 8961 di1 = dict_find(d1, hi2->hi_key, -1); 8962 if (di1 == NULL) 8963 { 8964 di1 = dictitem_copy(HI2DI(hi2)); 8965 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8966 dictitem_free(di1); 8967 } 8968 else if (*action == 'e') 8969 { 8970 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8971 break; 8972 } 8973 else if (*action == 'f') 8974 { 8975 clear_tv(&di1->di_tv); 8976 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8977 } 8978 } 8979 } 8980 8981 copy_tv(&argvars[0], rettv); 8982 } 8983 } 8984 else 8985 EMSG2(_(e_listdictarg), "extend()"); 8986 } 8987 8988 /* 8989 * "filereadable()" function 8990 */ 8991 static void 8992 f_filereadable(argvars, rettv) 8993 typval_T *argvars; 8994 typval_T *rettv; 8995 { 8996 FILE *fd; 8997 char_u *p; 8998 int n; 8999 9000 p = get_tv_string(&argvars[0]); 9001 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 9002 { 9003 n = TRUE; 9004 fclose(fd); 9005 } 9006 else 9007 n = FALSE; 9008 9009 rettv->vval.v_number = n; 9010 } 9011 9012 /* 9013 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 9014 * rights to write into. 9015 */ 9016 static void 9017 f_filewritable(argvars, rettv) 9018 typval_T *argvars; 9019 typval_T *rettv; 9020 { 9021 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 9022 } 9023 9024 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 9025 9026 static void 9027 findfilendir(argvars, rettv, dir) 9028 typval_T *argvars; 9029 typval_T *rettv; 9030 int dir; 9031 { 9032 #ifdef FEAT_SEARCHPATH 9033 char_u *fname; 9034 char_u *fresult = NULL; 9035 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 9036 char_u *p; 9037 char_u pathbuf[NUMBUFLEN]; 9038 int count = 1; 9039 int first = TRUE; 9040 int error = FALSE; 9041 #endif 9042 9043 rettv->vval.v_string = NULL; 9044 rettv->v_type = VAR_STRING; 9045 9046 #ifdef FEAT_SEARCHPATH 9047 fname = get_tv_string(&argvars[0]); 9048 9049 if (argvars[1].v_type != VAR_UNKNOWN) 9050 { 9051 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 9052 if (p == NULL) 9053 error = TRUE; 9054 else 9055 { 9056 if (*p != NUL) 9057 path = p; 9058 9059 if (argvars[2].v_type != VAR_UNKNOWN) 9060 count = get_tv_number_chk(&argvars[2], &error); 9061 } 9062 } 9063 9064 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 9065 error = TRUE; 9066 9067 if (*fname != NUL && !error) 9068 { 9069 do 9070 { 9071 if (rettv->v_type == VAR_STRING) 9072 vim_free(fresult); 9073 fresult = find_file_in_path_option(first ? fname : NULL, 9074 first ? (int)STRLEN(fname) : 0, 9075 0, first, path, dir, NULL, 9076 dir ? (char_u *)"" : curbuf->b_p_sua); 9077 first = FALSE; 9078 9079 if (fresult != NULL && rettv->v_type == VAR_LIST) 9080 list_append_string(rettv->vval.v_list, fresult, -1); 9081 9082 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 9083 } 9084 9085 if (rettv->v_type == VAR_STRING) 9086 rettv->vval.v_string = fresult; 9087 #endif 9088 } 9089 9090 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 9091 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 9092 9093 /* 9094 * Implementation of map() and filter(). 9095 */ 9096 static void 9097 filter_map(argvars, rettv, map) 9098 typval_T *argvars; 9099 typval_T *rettv; 9100 int map; 9101 { 9102 char_u buf[NUMBUFLEN]; 9103 char_u *expr; 9104 listitem_T *li, *nli; 9105 list_T *l = NULL; 9106 dictitem_T *di; 9107 hashtab_T *ht; 9108 hashitem_T *hi; 9109 dict_T *d = NULL; 9110 typval_T save_val; 9111 typval_T save_key; 9112 int rem; 9113 int todo; 9114 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 9115 int save_did_emsg; 9116 9117 rettv->vval.v_number = 0; 9118 if (argvars[0].v_type == VAR_LIST) 9119 { 9120 if ((l = argvars[0].vval.v_list) == NULL 9121 || (map && tv_check_lock(l->lv_lock, msg))) 9122 return; 9123 } 9124 else if (argvars[0].v_type == VAR_DICT) 9125 { 9126 if ((d = argvars[0].vval.v_dict) == NULL 9127 || (map && tv_check_lock(d->dv_lock, msg))) 9128 return; 9129 } 9130 else 9131 { 9132 EMSG2(_(e_listdictarg), msg); 9133 return; 9134 } 9135 9136 expr = get_tv_string_buf_chk(&argvars[1], buf); 9137 /* On type errors, the preceding call has already displayed an error 9138 * message. Avoid a misleading error message for an empty string that 9139 * was not passed as argument. */ 9140 if (expr != NULL) 9141 { 9142 prepare_vimvar(VV_VAL, &save_val); 9143 expr = skipwhite(expr); 9144 9145 /* We reset "did_emsg" to be able to detect whether an error 9146 * occurred during evaluation of the expression. */ 9147 save_did_emsg = did_emsg; 9148 did_emsg = FALSE; 9149 9150 if (argvars[0].v_type == VAR_DICT) 9151 { 9152 prepare_vimvar(VV_KEY, &save_key); 9153 vimvars[VV_KEY].vv_type = VAR_STRING; 9154 9155 ht = &d->dv_hashtab; 9156 hash_lock(ht); 9157 todo = (int)ht->ht_used; 9158 for (hi = ht->ht_array; todo > 0; ++hi) 9159 { 9160 if (!HASHITEM_EMPTY(hi)) 9161 { 9162 --todo; 9163 di = HI2DI(hi); 9164 if (tv_check_lock(di->di_tv.v_lock, msg)) 9165 break; 9166 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 9167 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL 9168 || did_emsg) 9169 break; 9170 if (!map && rem) 9171 dictitem_remove(d, di); 9172 clear_tv(&vimvars[VV_KEY].vv_tv); 9173 } 9174 } 9175 hash_unlock(ht); 9176 9177 restore_vimvar(VV_KEY, &save_key); 9178 } 9179 else 9180 { 9181 for (li = l->lv_first; li != NULL; li = nli) 9182 { 9183 if (tv_check_lock(li->li_tv.v_lock, msg)) 9184 break; 9185 nli = li->li_next; 9186 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 9187 || did_emsg) 9188 break; 9189 if (!map && rem) 9190 listitem_remove(l, li); 9191 } 9192 } 9193 9194 restore_vimvar(VV_VAL, &save_val); 9195 9196 did_emsg |= save_did_emsg; 9197 } 9198 9199 copy_tv(&argvars[0], rettv); 9200 } 9201 9202 static int 9203 filter_map_one(tv, expr, map, remp) 9204 typval_T *tv; 9205 char_u *expr; 9206 int map; 9207 int *remp; 9208 { 9209 typval_T rettv; 9210 char_u *s; 9211 9212 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 9213 s = expr; 9214 if (eval1(&s, &rettv, TRUE) == FAIL) 9215 return FAIL; 9216 if (*s != NUL) /* check for trailing chars after expr */ 9217 { 9218 EMSG2(_(e_invexpr2), s); 9219 return FAIL; 9220 } 9221 if (map) 9222 { 9223 /* map(): replace the list item value */ 9224 clear_tv(tv); 9225 rettv.v_lock = 0; 9226 *tv = rettv; 9227 } 9228 else 9229 { 9230 int error = FALSE; 9231 9232 /* filter(): when expr is zero remove the item */ 9233 *remp = (get_tv_number_chk(&rettv, &error) == 0); 9234 clear_tv(&rettv); 9235 /* On type error, nothing has been removed; return FAIL to stop the 9236 * loop. The error message was given by get_tv_number_chk(). */ 9237 if (error) 9238 return FAIL; 9239 } 9240 clear_tv(&vimvars[VV_VAL].vv_tv); 9241 return OK; 9242 } 9243 9244 /* 9245 * "filter()" function 9246 */ 9247 static void 9248 f_filter(argvars, rettv) 9249 typval_T *argvars; 9250 typval_T *rettv; 9251 { 9252 filter_map(argvars, rettv, FALSE); 9253 } 9254 9255 /* 9256 * "finddir({fname}[, {path}[, {count}]])" function 9257 */ 9258 static void 9259 f_finddir(argvars, rettv) 9260 typval_T *argvars; 9261 typval_T *rettv; 9262 { 9263 findfilendir(argvars, rettv, TRUE); 9264 } 9265 9266 /* 9267 * "findfile({fname}[, {path}[, {count}]])" function 9268 */ 9269 static void 9270 f_findfile(argvars, rettv) 9271 typval_T *argvars; 9272 typval_T *rettv; 9273 { 9274 findfilendir(argvars, rettv, FALSE); 9275 } 9276 9277 /* 9278 * "fnamemodify({fname}, {mods})" function 9279 */ 9280 static void 9281 f_fnamemodify(argvars, rettv) 9282 typval_T *argvars; 9283 typval_T *rettv; 9284 { 9285 char_u *fname; 9286 char_u *mods; 9287 int usedlen = 0; 9288 int len; 9289 char_u *fbuf = NULL; 9290 char_u buf[NUMBUFLEN]; 9291 9292 fname = get_tv_string_chk(&argvars[0]); 9293 mods = get_tv_string_buf_chk(&argvars[1], buf); 9294 if (fname == NULL || mods == NULL) 9295 fname = NULL; 9296 else 9297 { 9298 len = (int)STRLEN(fname); 9299 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 9300 } 9301 9302 rettv->v_type = VAR_STRING; 9303 if (fname == NULL) 9304 rettv->vval.v_string = NULL; 9305 else 9306 rettv->vval.v_string = vim_strnsave(fname, len); 9307 vim_free(fbuf); 9308 } 9309 9310 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 9311 9312 /* 9313 * "foldclosed()" function 9314 */ 9315 static void 9316 foldclosed_both(argvars, rettv, end) 9317 typval_T *argvars; 9318 typval_T *rettv; 9319 int end; 9320 { 9321 #ifdef FEAT_FOLDING 9322 linenr_T lnum; 9323 linenr_T first, last; 9324 9325 lnum = get_tv_lnum(argvars); 9326 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9327 { 9328 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 9329 { 9330 if (end) 9331 rettv->vval.v_number = (varnumber_T)last; 9332 else 9333 rettv->vval.v_number = (varnumber_T)first; 9334 return; 9335 } 9336 } 9337 #endif 9338 rettv->vval.v_number = -1; 9339 } 9340 9341 /* 9342 * "foldclosed()" function 9343 */ 9344 static void 9345 f_foldclosed(argvars, rettv) 9346 typval_T *argvars; 9347 typval_T *rettv; 9348 { 9349 foldclosed_both(argvars, rettv, FALSE); 9350 } 9351 9352 /* 9353 * "foldclosedend()" function 9354 */ 9355 static void 9356 f_foldclosedend(argvars, rettv) 9357 typval_T *argvars; 9358 typval_T *rettv; 9359 { 9360 foldclosed_both(argvars, rettv, TRUE); 9361 } 9362 9363 /* 9364 * "foldlevel()" function 9365 */ 9366 static void 9367 f_foldlevel(argvars, rettv) 9368 typval_T *argvars; 9369 typval_T *rettv; 9370 { 9371 #ifdef FEAT_FOLDING 9372 linenr_T lnum; 9373 9374 lnum = get_tv_lnum(argvars); 9375 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9376 rettv->vval.v_number = foldLevel(lnum); 9377 else 9378 #endif 9379 rettv->vval.v_number = 0; 9380 } 9381 9382 /* 9383 * "foldtext()" function 9384 */ 9385 /*ARGSUSED*/ 9386 static void 9387 f_foldtext(argvars, rettv) 9388 typval_T *argvars; 9389 typval_T *rettv; 9390 { 9391 #ifdef FEAT_FOLDING 9392 linenr_T lnum; 9393 char_u *s; 9394 char_u *r; 9395 int len; 9396 char *txt; 9397 #endif 9398 9399 rettv->v_type = VAR_STRING; 9400 rettv->vval.v_string = NULL; 9401 #ifdef FEAT_FOLDING 9402 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9403 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9404 <= curbuf->b_ml.ml_line_count 9405 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9406 { 9407 /* Find first non-empty line in the fold. */ 9408 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9409 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9410 { 9411 if (!linewhite(lnum)) 9412 break; 9413 ++lnum; 9414 } 9415 9416 /* Find interesting text in this line. */ 9417 s = skipwhite(ml_get(lnum)); 9418 /* skip C comment-start */ 9419 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9420 { 9421 s = skipwhite(s + 2); 9422 if (*skipwhite(s) == NUL 9423 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9424 { 9425 s = skipwhite(ml_get(lnum + 1)); 9426 if (*s == '*') 9427 s = skipwhite(s + 1); 9428 } 9429 } 9430 txt = _("+-%s%3ld lines: "); 9431 r = alloc((unsigned)(STRLEN(txt) 9432 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9433 + 20 /* for %3ld */ 9434 + STRLEN(s))); /* concatenated */ 9435 if (r != NULL) 9436 { 9437 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9438 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9439 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9440 len = (int)STRLEN(r); 9441 STRCAT(r, s); 9442 /* remove 'foldmarker' and 'commentstring' */ 9443 foldtext_cleanup(r + len); 9444 rettv->vval.v_string = r; 9445 } 9446 } 9447 #endif 9448 } 9449 9450 /* 9451 * "foldtextresult(lnum)" function 9452 */ 9453 /*ARGSUSED*/ 9454 static void 9455 f_foldtextresult(argvars, rettv) 9456 typval_T *argvars; 9457 typval_T *rettv; 9458 { 9459 #ifdef FEAT_FOLDING 9460 linenr_T lnum; 9461 char_u *text; 9462 char_u buf[51]; 9463 foldinfo_T foldinfo; 9464 int fold_count; 9465 #endif 9466 9467 rettv->v_type = VAR_STRING; 9468 rettv->vval.v_string = NULL; 9469 #ifdef FEAT_FOLDING 9470 lnum = get_tv_lnum(argvars); 9471 /* treat illegal types and illegal string values for {lnum} the same */ 9472 if (lnum < 0) 9473 lnum = 0; 9474 fold_count = foldedCount(curwin, lnum, &foldinfo); 9475 if (fold_count > 0) 9476 { 9477 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9478 &foldinfo, buf); 9479 if (text == buf) 9480 text = vim_strsave(text); 9481 rettv->vval.v_string = text; 9482 } 9483 #endif 9484 } 9485 9486 /* 9487 * "foreground()" function 9488 */ 9489 /*ARGSUSED*/ 9490 static void 9491 f_foreground(argvars, rettv) 9492 typval_T *argvars; 9493 typval_T *rettv; 9494 { 9495 rettv->vval.v_number = 0; 9496 #ifdef FEAT_GUI 9497 if (gui.in_use) 9498 gui_mch_set_foreground(); 9499 #else 9500 # ifdef WIN32 9501 win32_set_foreground(); 9502 # endif 9503 #endif 9504 } 9505 9506 /* 9507 * "function()" function 9508 */ 9509 /*ARGSUSED*/ 9510 static void 9511 f_function(argvars, rettv) 9512 typval_T *argvars; 9513 typval_T *rettv; 9514 { 9515 char_u *s; 9516 9517 rettv->vval.v_number = 0; 9518 s = get_tv_string(&argvars[0]); 9519 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9520 EMSG2(_(e_invarg2), s); 9521 else if (!function_exists(s)) 9522 EMSG2(_("E700: Unknown function: %s"), s); 9523 else 9524 { 9525 rettv->vval.v_string = vim_strsave(s); 9526 rettv->v_type = VAR_FUNC; 9527 } 9528 } 9529 9530 /* 9531 * "garbagecollect()" function 9532 */ 9533 /*ARGSUSED*/ 9534 static void 9535 f_garbagecollect(argvars, rettv) 9536 typval_T *argvars; 9537 typval_T *rettv; 9538 { 9539 garbage_collect(); 9540 } 9541 9542 /* 9543 * "get()" function 9544 */ 9545 static void 9546 f_get(argvars, rettv) 9547 typval_T *argvars; 9548 typval_T *rettv; 9549 { 9550 listitem_T *li; 9551 list_T *l; 9552 dictitem_T *di; 9553 dict_T *d; 9554 typval_T *tv = NULL; 9555 9556 if (argvars[0].v_type == VAR_LIST) 9557 { 9558 if ((l = argvars[0].vval.v_list) != NULL) 9559 { 9560 int error = FALSE; 9561 9562 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9563 if (!error && li != NULL) 9564 tv = &li->li_tv; 9565 } 9566 } 9567 else if (argvars[0].v_type == VAR_DICT) 9568 { 9569 if ((d = argvars[0].vval.v_dict) != NULL) 9570 { 9571 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9572 if (di != NULL) 9573 tv = &di->di_tv; 9574 } 9575 } 9576 else 9577 EMSG2(_(e_listdictarg), "get()"); 9578 9579 if (tv == NULL) 9580 { 9581 if (argvars[2].v_type == VAR_UNKNOWN) 9582 rettv->vval.v_number = 0; 9583 else 9584 copy_tv(&argvars[2], rettv); 9585 } 9586 else 9587 copy_tv(tv, rettv); 9588 } 9589 9590 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9591 9592 /* 9593 * Get line or list of lines from buffer "buf" into "rettv". 9594 * Return a range (from start to end) of lines in rettv from the specified 9595 * buffer. 9596 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9597 */ 9598 static void 9599 get_buffer_lines(buf, start, end, retlist, rettv) 9600 buf_T *buf; 9601 linenr_T start; 9602 linenr_T end; 9603 int retlist; 9604 typval_T *rettv; 9605 { 9606 char_u *p; 9607 9608 if (retlist) 9609 { 9610 if (rettv_list_alloc(rettv) == FAIL) 9611 return; 9612 } 9613 else 9614 rettv->vval.v_number = 0; 9615 9616 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9617 return; 9618 9619 if (!retlist) 9620 { 9621 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9622 p = ml_get_buf(buf, start, FALSE); 9623 else 9624 p = (char_u *)""; 9625 9626 rettv->v_type = VAR_STRING; 9627 rettv->vval.v_string = vim_strsave(p); 9628 } 9629 else 9630 { 9631 if (end < start) 9632 return; 9633 9634 if (start < 1) 9635 start = 1; 9636 if (end > buf->b_ml.ml_line_count) 9637 end = buf->b_ml.ml_line_count; 9638 while (start <= end) 9639 if (list_append_string(rettv->vval.v_list, 9640 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 9641 break; 9642 } 9643 } 9644 9645 /* 9646 * "getbufline()" function 9647 */ 9648 static void 9649 f_getbufline(argvars, rettv) 9650 typval_T *argvars; 9651 typval_T *rettv; 9652 { 9653 linenr_T lnum; 9654 linenr_T end; 9655 buf_T *buf; 9656 9657 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9658 ++emsg_off; 9659 buf = get_buf_tv(&argvars[0]); 9660 --emsg_off; 9661 9662 lnum = get_tv_lnum_buf(&argvars[1], buf); 9663 if (argvars[2].v_type == VAR_UNKNOWN) 9664 end = lnum; 9665 else 9666 end = get_tv_lnum_buf(&argvars[2], buf); 9667 9668 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9669 } 9670 9671 /* 9672 * "getbufvar()" function 9673 */ 9674 static void 9675 f_getbufvar(argvars, rettv) 9676 typval_T *argvars; 9677 typval_T *rettv; 9678 { 9679 buf_T *buf; 9680 buf_T *save_curbuf; 9681 char_u *varname; 9682 dictitem_T *v; 9683 9684 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9685 varname = get_tv_string_chk(&argvars[1]); 9686 ++emsg_off; 9687 buf = get_buf_tv(&argvars[0]); 9688 9689 rettv->v_type = VAR_STRING; 9690 rettv->vval.v_string = NULL; 9691 9692 if (buf != NULL && varname != NULL) 9693 { 9694 if (*varname == '&') /* buffer-local-option */ 9695 { 9696 /* set curbuf to be our buf, temporarily */ 9697 save_curbuf = curbuf; 9698 curbuf = buf; 9699 9700 get_option_tv(&varname, rettv, TRUE); 9701 9702 /* restore previous notion of curbuf */ 9703 curbuf = save_curbuf; 9704 } 9705 else 9706 { 9707 if (*varname == NUL) 9708 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9709 * scope prefix before the NUL byte is required by 9710 * find_var_in_ht(). */ 9711 varname = (char_u *)"b:" + 2; 9712 /* look up the variable */ 9713 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9714 if (v != NULL) 9715 copy_tv(&v->di_tv, rettv); 9716 } 9717 } 9718 9719 --emsg_off; 9720 } 9721 9722 /* 9723 * "getchar()" function 9724 */ 9725 static void 9726 f_getchar(argvars, rettv) 9727 typval_T *argvars; 9728 typval_T *rettv; 9729 { 9730 varnumber_T n; 9731 int error = FALSE; 9732 9733 ++no_mapping; 9734 ++allow_keys; 9735 if (argvars[0].v_type == VAR_UNKNOWN) 9736 /* getchar(): blocking wait. */ 9737 n = safe_vgetc(); 9738 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9739 /* getchar(1): only check if char avail */ 9740 n = vpeekc(); 9741 else if (error || vpeekc() == NUL) 9742 /* illegal argument or getchar(0) and no char avail: return zero */ 9743 n = 0; 9744 else 9745 /* getchar(0) and char avail: return char */ 9746 n = safe_vgetc(); 9747 --no_mapping; 9748 --allow_keys; 9749 9750 rettv->vval.v_number = n; 9751 if (IS_SPECIAL(n) || mod_mask != 0) 9752 { 9753 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9754 int i = 0; 9755 9756 /* Turn a special key into three bytes, plus modifier. */ 9757 if (mod_mask != 0) 9758 { 9759 temp[i++] = K_SPECIAL; 9760 temp[i++] = KS_MODIFIER; 9761 temp[i++] = mod_mask; 9762 } 9763 if (IS_SPECIAL(n)) 9764 { 9765 temp[i++] = K_SPECIAL; 9766 temp[i++] = K_SECOND(n); 9767 temp[i++] = K_THIRD(n); 9768 } 9769 #ifdef FEAT_MBYTE 9770 else if (has_mbyte) 9771 i += (*mb_char2bytes)(n, temp + i); 9772 #endif 9773 else 9774 temp[i++] = n; 9775 temp[i++] = NUL; 9776 rettv->v_type = VAR_STRING; 9777 rettv->vval.v_string = vim_strsave(temp); 9778 } 9779 } 9780 9781 /* 9782 * "getcharmod()" function 9783 */ 9784 /*ARGSUSED*/ 9785 static void 9786 f_getcharmod(argvars, rettv) 9787 typval_T *argvars; 9788 typval_T *rettv; 9789 { 9790 rettv->vval.v_number = mod_mask; 9791 } 9792 9793 /* 9794 * "getcmdline()" function 9795 */ 9796 /*ARGSUSED*/ 9797 static void 9798 f_getcmdline(argvars, rettv) 9799 typval_T *argvars; 9800 typval_T *rettv; 9801 { 9802 rettv->v_type = VAR_STRING; 9803 rettv->vval.v_string = get_cmdline_str(); 9804 } 9805 9806 /* 9807 * "getcmdpos()" function 9808 */ 9809 /*ARGSUSED*/ 9810 static void 9811 f_getcmdpos(argvars, rettv) 9812 typval_T *argvars; 9813 typval_T *rettv; 9814 { 9815 rettv->vval.v_number = get_cmdline_pos() + 1; 9816 } 9817 9818 /* 9819 * "getcmdtype()" function 9820 */ 9821 /*ARGSUSED*/ 9822 static void 9823 f_getcmdtype(argvars, rettv) 9824 typval_T *argvars; 9825 typval_T *rettv; 9826 { 9827 rettv->v_type = VAR_STRING; 9828 rettv->vval.v_string = alloc(2); 9829 if (rettv->vval.v_string != NULL) 9830 { 9831 rettv->vval.v_string[0] = get_cmdline_type(); 9832 rettv->vval.v_string[1] = NUL; 9833 } 9834 } 9835 9836 /* 9837 * "getcwd()" function 9838 */ 9839 /*ARGSUSED*/ 9840 static void 9841 f_getcwd(argvars, rettv) 9842 typval_T *argvars; 9843 typval_T *rettv; 9844 { 9845 char_u cwd[MAXPATHL]; 9846 9847 rettv->v_type = VAR_STRING; 9848 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9849 rettv->vval.v_string = NULL; 9850 else 9851 { 9852 rettv->vval.v_string = vim_strsave(cwd); 9853 #ifdef BACKSLASH_IN_FILENAME 9854 if (rettv->vval.v_string != NULL) 9855 slash_adjust(rettv->vval.v_string); 9856 #endif 9857 } 9858 } 9859 9860 /* 9861 * "getfontname()" function 9862 */ 9863 /*ARGSUSED*/ 9864 static void 9865 f_getfontname(argvars, rettv) 9866 typval_T *argvars; 9867 typval_T *rettv; 9868 { 9869 rettv->v_type = VAR_STRING; 9870 rettv->vval.v_string = NULL; 9871 #ifdef FEAT_GUI 9872 if (gui.in_use) 9873 { 9874 GuiFont font; 9875 char_u *name = NULL; 9876 9877 if (argvars[0].v_type == VAR_UNKNOWN) 9878 { 9879 /* Get the "Normal" font. Either the name saved by 9880 * hl_set_font_name() or from the font ID. */ 9881 font = gui.norm_font; 9882 name = hl_get_font_name(); 9883 } 9884 else 9885 { 9886 name = get_tv_string(&argvars[0]); 9887 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9888 return; 9889 font = gui_mch_get_font(name, FALSE); 9890 if (font == NOFONT) 9891 return; /* Invalid font name, return empty string. */ 9892 } 9893 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9894 if (argvars[0].v_type != VAR_UNKNOWN) 9895 gui_mch_free_font(font); 9896 } 9897 #endif 9898 } 9899 9900 /* 9901 * "getfperm({fname})" function 9902 */ 9903 static void 9904 f_getfperm(argvars, rettv) 9905 typval_T *argvars; 9906 typval_T *rettv; 9907 { 9908 char_u *fname; 9909 struct stat st; 9910 char_u *perm = NULL; 9911 char_u flags[] = "rwx"; 9912 int i; 9913 9914 fname = get_tv_string(&argvars[0]); 9915 9916 rettv->v_type = VAR_STRING; 9917 if (mch_stat((char *)fname, &st) >= 0) 9918 { 9919 perm = vim_strsave((char_u *)"---------"); 9920 if (perm != NULL) 9921 { 9922 for (i = 0; i < 9; i++) 9923 { 9924 if (st.st_mode & (1 << (8 - i))) 9925 perm[i] = flags[i % 3]; 9926 } 9927 } 9928 } 9929 rettv->vval.v_string = perm; 9930 } 9931 9932 /* 9933 * "getfsize({fname})" function 9934 */ 9935 static void 9936 f_getfsize(argvars, rettv) 9937 typval_T *argvars; 9938 typval_T *rettv; 9939 { 9940 char_u *fname; 9941 struct stat st; 9942 9943 fname = get_tv_string(&argvars[0]); 9944 9945 rettv->v_type = VAR_NUMBER; 9946 9947 if (mch_stat((char *)fname, &st) >= 0) 9948 { 9949 if (mch_isdir(fname)) 9950 rettv->vval.v_number = 0; 9951 else 9952 rettv->vval.v_number = (varnumber_T)st.st_size; 9953 } 9954 else 9955 rettv->vval.v_number = -1; 9956 } 9957 9958 /* 9959 * "getftime({fname})" function 9960 */ 9961 static void 9962 f_getftime(argvars, rettv) 9963 typval_T *argvars; 9964 typval_T *rettv; 9965 { 9966 char_u *fname; 9967 struct stat st; 9968 9969 fname = get_tv_string(&argvars[0]); 9970 9971 if (mch_stat((char *)fname, &st) >= 0) 9972 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9973 else 9974 rettv->vval.v_number = -1; 9975 } 9976 9977 /* 9978 * "getftype({fname})" function 9979 */ 9980 static void 9981 f_getftype(argvars, rettv) 9982 typval_T *argvars; 9983 typval_T *rettv; 9984 { 9985 char_u *fname; 9986 struct stat st; 9987 char_u *type = NULL; 9988 char *t; 9989 9990 fname = get_tv_string(&argvars[0]); 9991 9992 rettv->v_type = VAR_STRING; 9993 if (mch_lstat((char *)fname, &st) >= 0) 9994 { 9995 #ifdef S_ISREG 9996 if (S_ISREG(st.st_mode)) 9997 t = "file"; 9998 else if (S_ISDIR(st.st_mode)) 9999 t = "dir"; 10000 # ifdef S_ISLNK 10001 else if (S_ISLNK(st.st_mode)) 10002 t = "link"; 10003 # endif 10004 # ifdef S_ISBLK 10005 else if (S_ISBLK(st.st_mode)) 10006 t = "bdev"; 10007 # endif 10008 # ifdef S_ISCHR 10009 else if (S_ISCHR(st.st_mode)) 10010 t = "cdev"; 10011 # endif 10012 # ifdef S_ISFIFO 10013 else if (S_ISFIFO(st.st_mode)) 10014 t = "fifo"; 10015 # endif 10016 # ifdef S_ISSOCK 10017 else if (S_ISSOCK(st.st_mode)) 10018 t = "fifo"; 10019 # endif 10020 else 10021 t = "other"; 10022 #else 10023 # ifdef S_IFMT 10024 switch (st.st_mode & S_IFMT) 10025 { 10026 case S_IFREG: t = "file"; break; 10027 case S_IFDIR: t = "dir"; break; 10028 # ifdef S_IFLNK 10029 case S_IFLNK: t = "link"; break; 10030 # endif 10031 # ifdef S_IFBLK 10032 case S_IFBLK: t = "bdev"; break; 10033 # endif 10034 # ifdef S_IFCHR 10035 case S_IFCHR: t = "cdev"; break; 10036 # endif 10037 # ifdef S_IFIFO 10038 case S_IFIFO: t = "fifo"; break; 10039 # endif 10040 # ifdef S_IFSOCK 10041 case S_IFSOCK: t = "socket"; break; 10042 # endif 10043 default: t = "other"; 10044 } 10045 # else 10046 if (mch_isdir(fname)) 10047 t = "dir"; 10048 else 10049 t = "file"; 10050 # endif 10051 #endif 10052 type = vim_strsave((char_u *)t); 10053 } 10054 rettv->vval.v_string = type; 10055 } 10056 10057 /* 10058 * "getline(lnum, [end])" function 10059 */ 10060 static void 10061 f_getline(argvars, rettv) 10062 typval_T *argvars; 10063 typval_T *rettv; 10064 { 10065 linenr_T lnum; 10066 linenr_T end; 10067 int retlist; 10068 10069 lnum = get_tv_lnum(argvars); 10070 if (argvars[1].v_type == VAR_UNKNOWN) 10071 { 10072 end = 0; 10073 retlist = FALSE; 10074 } 10075 else 10076 { 10077 end = get_tv_lnum(&argvars[1]); 10078 retlist = TRUE; 10079 } 10080 10081 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 10082 } 10083 10084 /* 10085 * "getpos(string)" function 10086 */ 10087 static void 10088 f_getpos(argvars, rettv) 10089 typval_T *argvars; 10090 typval_T *rettv; 10091 { 10092 pos_T *fp; 10093 list_T *l; 10094 int fnum = -1; 10095 10096 if (rettv_list_alloc(rettv) == OK) 10097 { 10098 l = rettv->vval.v_list; 10099 fp = var2fpos(&argvars[0], TRUE, &fnum); 10100 if (fnum != -1) 10101 list_append_number(l, (varnumber_T)fnum); 10102 else 10103 list_append_number(l, (varnumber_T)0); 10104 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 10105 : (varnumber_T)0); 10106 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->col + 1 10107 : (varnumber_T)0); 10108 list_append_number(l, 10109 #ifdef FEAT_VIRTUALEDIT 10110 (fp != NULL) ? (varnumber_T)fp->coladd : 10111 #endif 10112 (varnumber_T)0); 10113 } 10114 else 10115 rettv->vval.v_number = FALSE; 10116 } 10117 10118 /* 10119 * "getqflist()" and "getloclist()" functions 10120 */ 10121 /*ARGSUSED*/ 10122 static void 10123 f_getqflist(argvars, rettv) 10124 typval_T *argvars; 10125 typval_T *rettv; 10126 { 10127 #ifdef FEAT_QUICKFIX 10128 win_T *wp; 10129 #endif 10130 10131 rettv->vval.v_number = FALSE; 10132 #ifdef FEAT_QUICKFIX 10133 if (rettv_list_alloc(rettv) == OK) 10134 { 10135 wp = NULL; 10136 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 10137 { 10138 wp = find_win_by_nr(&argvars[0], NULL); 10139 if (wp == NULL) 10140 return; 10141 } 10142 10143 (void)get_errorlist(wp, rettv->vval.v_list); 10144 } 10145 #endif 10146 } 10147 10148 /* 10149 * "getreg()" function 10150 */ 10151 static void 10152 f_getreg(argvars, rettv) 10153 typval_T *argvars; 10154 typval_T *rettv; 10155 { 10156 char_u *strregname; 10157 int regname; 10158 int arg2 = FALSE; 10159 int error = FALSE; 10160 10161 if (argvars[0].v_type != VAR_UNKNOWN) 10162 { 10163 strregname = get_tv_string_chk(&argvars[0]); 10164 error = strregname == NULL; 10165 if (argvars[1].v_type != VAR_UNKNOWN) 10166 arg2 = get_tv_number_chk(&argvars[1], &error); 10167 } 10168 else 10169 strregname = vimvars[VV_REG].vv_str; 10170 regname = (strregname == NULL ? '"' : *strregname); 10171 if (regname == 0) 10172 regname = '"'; 10173 10174 rettv->v_type = VAR_STRING; 10175 rettv->vval.v_string = error ? NULL : 10176 get_reg_contents(regname, TRUE, arg2); 10177 } 10178 10179 /* 10180 * "getregtype()" function 10181 */ 10182 static void 10183 f_getregtype(argvars, rettv) 10184 typval_T *argvars; 10185 typval_T *rettv; 10186 { 10187 char_u *strregname; 10188 int regname; 10189 char_u buf[NUMBUFLEN + 2]; 10190 long reglen = 0; 10191 10192 if (argvars[0].v_type != VAR_UNKNOWN) 10193 { 10194 strregname = get_tv_string_chk(&argvars[0]); 10195 if (strregname == NULL) /* type error; errmsg already given */ 10196 { 10197 rettv->v_type = VAR_STRING; 10198 rettv->vval.v_string = NULL; 10199 return; 10200 } 10201 } 10202 else 10203 /* Default to v:register */ 10204 strregname = vimvars[VV_REG].vv_str; 10205 10206 regname = (strregname == NULL ? '"' : *strregname); 10207 if (regname == 0) 10208 regname = '"'; 10209 10210 buf[0] = NUL; 10211 buf[1] = NUL; 10212 switch (get_reg_type(regname, ®len)) 10213 { 10214 case MLINE: buf[0] = 'V'; break; 10215 case MCHAR: buf[0] = 'v'; break; 10216 #ifdef FEAT_VISUAL 10217 case MBLOCK: 10218 buf[0] = Ctrl_V; 10219 sprintf((char *)buf + 1, "%ld", reglen + 1); 10220 break; 10221 #endif 10222 } 10223 rettv->v_type = VAR_STRING; 10224 rettv->vval.v_string = vim_strsave(buf); 10225 } 10226 10227 /* 10228 * "gettabwinvar()" function 10229 */ 10230 static void 10231 f_gettabwinvar(argvars, rettv) 10232 typval_T *argvars; 10233 typval_T *rettv; 10234 { 10235 getwinvar(argvars, rettv, 1); 10236 } 10237 10238 /* 10239 * "getwinposx()" function 10240 */ 10241 /*ARGSUSED*/ 10242 static void 10243 f_getwinposx(argvars, rettv) 10244 typval_T *argvars; 10245 typval_T *rettv; 10246 { 10247 rettv->vval.v_number = -1; 10248 #ifdef FEAT_GUI 10249 if (gui.in_use) 10250 { 10251 int x, y; 10252 10253 if (gui_mch_get_winpos(&x, &y) == OK) 10254 rettv->vval.v_number = x; 10255 } 10256 #endif 10257 } 10258 10259 /* 10260 * "getwinposy()" function 10261 */ 10262 /*ARGSUSED*/ 10263 static void 10264 f_getwinposy(argvars, rettv) 10265 typval_T *argvars; 10266 typval_T *rettv; 10267 { 10268 rettv->vval.v_number = -1; 10269 #ifdef FEAT_GUI 10270 if (gui.in_use) 10271 { 10272 int x, y; 10273 10274 if (gui_mch_get_winpos(&x, &y) == OK) 10275 rettv->vval.v_number = y; 10276 } 10277 #endif 10278 } 10279 10280 /* 10281 * Find window specifed by "vp" in tabpage "tp". 10282 */ 10283 static win_T * 10284 find_win_by_nr(vp, tp) 10285 typval_T *vp; 10286 tabpage_T *tp; /* NULL for current tab page */ 10287 { 10288 #ifdef FEAT_WINDOWS 10289 win_T *wp; 10290 #endif 10291 int nr; 10292 10293 nr = get_tv_number_chk(vp, NULL); 10294 10295 #ifdef FEAT_WINDOWS 10296 if (nr < 0) 10297 return NULL; 10298 if (nr == 0) 10299 return curwin; 10300 10301 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 10302 wp != NULL; wp = wp->w_next) 10303 if (--nr <= 0) 10304 break; 10305 return wp; 10306 #else 10307 if (nr == 0 || nr == 1) 10308 return curwin; 10309 return NULL; 10310 #endif 10311 } 10312 10313 /* 10314 * "getwinvar()" function 10315 */ 10316 static void 10317 f_getwinvar(argvars, rettv) 10318 typval_T *argvars; 10319 typval_T *rettv; 10320 { 10321 getwinvar(argvars, rettv, 0); 10322 } 10323 10324 /* 10325 * getwinvar() and gettabwinvar() 10326 */ 10327 static void 10328 getwinvar(argvars, rettv, off) 10329 typval_T *argvars; 10330 typval_T *rettv; 10331 int off; /* 1 for gettabwinvar() */ 10332 { 10333 win_T *win, *oldcurwin; 10334 char_u *varname; 10335 dictitem_T *v; 10336 tabpage_T *tp; 10337 10338 #ifdef FEAT_WINDOWS 10339 if (off == 1) 10340 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 10341 else 10342 tp = curtab; 10343 #endif 10344 win = find_win_by_nr(&argvars[off], tp); 10345 varname = get_tv_string_chk(&argvars[off + 1]); 10346 ++emsg_off; 10347 10348 rettv->v_type = VAR_STRING; 10349 rettv->vval.v_string = NULL; 10350 10351 if (win != NULL && varname != NULL) 10352 { 10353 if (*varname == '&') /* window-local-option */ 10354 { 10355 /* Set curwin to be our win, temporarily. Also set curbuf, so 10356 * that we can get buffer-local options. */ 10357 oldcurwin = curwin; 10358 curwin = win; 10359 curbuf = win->w_buffer; 10360 10361 get_option_tv(&varname, rettv, 1); 10362 10363 /* restore previous notion of curwin */ 10364 curwin = oldcurwin; 10365 curbuf = curwin->w_buffer; 10366 } 10367 else 10368 { 10369 if (*varname == NUL) 10370 /* let getwinvar({nr}, "") return the "w:" dictionary. The 10371 * scope prefix before the NUL byte is required by 10372 * find_var_in_ht(). */ 10373 varname = (char_u *)"w:" + 2; 10374 /* look up the variable */ 10375 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 10376 if (v != NULL) 10377 copy_tv(&v->di_tv, rettv); 10378 } 10379 } 10380 10381 --emsg_off; 10382 } 10383 10384 /* 10385 * "glob()" function 10386 */ 10387 static void 10388 f_glob(argvars, rettv) 10389 typval_T *argvars; 10390 typval_T *rettv; 10391 { 10392 expand_T xpc; 10393 10394 ExpandInit(&xpc); 10395 xpc.xp_context = EXPAND_FILES; 10396 rettv->v_type = VAR_STRING; 10397 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 10398 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 10399 } 10400 10401 /* 10402 * "globpath()" function 10403 */ 10404 static void 10405 f_globpath(argvars, rettv) 10406 typval_T *argvars; 10407 typval_T *rettv; 10408 { 10409 char_u buf1[NUMBUFLEN]; 10410 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 10411 10412 rettv->v_type = VAR_STRING; 10413 if (file == NULL) 10414 rettv->vval.v_string = NULL; 10415 else 10416 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 10417 } 10418 10419 /* 10420 * "has()" function 10421 */ 10422 static void 10423 f_has(argvars, rettv) 10424 typval_T *argvars; 10425 typval_T *rettv; 10426 { 10427 int i; 10428 char_u *name; 10429 int n = FALSE; 10430 static char *(has_list[]) = 10431 { 10432 #ifdef AMIGA 10433 "amiga", 10434 # ifdef FEAT_ARP 10435 "arp", 10436 # endif 10437 #endif 10438 #ifdef __BEOS__ 10439 "beos", 10440 #endif 10441 #ifdef MSDOS 10442 # ifdef DJGPP 10443 "dos32", 10444 # else 10445 "dos16", 10446 # endif 10447 #endif 10448 #ifdef MACOS 10449 "mac", 10450 #endif 10451 #if defined(MACOS_X_UNIX) 10452 "macunix", 10453 #endif 10454 #ifdef OS2 10455 "os2", 10456 #endif 10457 #ifdef __QNX__ 10458 "qnx", 10459 #endif 10460 #ifdef RISCOS 10461 "riscos", 10462 #endif 10463 #ifdef UNIX 10464 "unix", 10465 #endif 10466 #ifdef VMS 10467 "vms", 10468 #endif 10469 #ifdef WIN16 10470 "win16", 10471 #endif 10472 #ifdef WIN32 10473 "win32", 10474 #endif 10475 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10476 "win32unix", 10477 #endif 10478 #ifdef WIN64 10479 "win64", 10480 #endif 10481 #ifdef EBCDIC 10482 "ebcdic", 10483 #endif 10484 #ifndef CASE_INSENSITIVE_FILENAME 10485 "fname_case", 10486 #endif 10487 #ifdef FEAT_ARABIC 10488 "arabic", 10489 #endif 10490 #ifdef FEAT_AUTOCMD 10491 "autocmd", 10492 #endif 10493 #ifdef FEAT_BEVAL 10494 "balloon_eval", 10495 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10496 "balloon_multiline", 10497 # endif 10498 #endif 10499 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10500 "builtin_terms", 10501 # ifdef ALL_BUILTIN_TCAPS 10502 "all_builtin_terms", 10503 # endif 10504 #endif 10505 #ifdef FEAT_BYTEOFF 10506 "byte_offset", 10507 #endif 10508 #ifdef FEAT_CINDENT 10509 "cindent", 10510 #endif 10511 #ifdef FEAT_CLIENTSERVER 10512 "clientserver", 10513 #endif 10514 #ifdef FEAT_CLIPBOARD 10515 "clipboard", 10516 #endif 10517 #ifdef FEAT_CMDL_COMPL 10518 "cmdline_compl", 10519 #endif 10520 #ifdef FEAT_CMDHIST 10521 "cmdline_hist", 10522 #endif 10523 #ifdef FEAT_COMMENTS 10524 "comments", 10525 #endif 10526 #ifdef FEAT_CRYPT 10527 "cryptv", 10528 #endif 10529 #ifdef FEAT_CSCOPE 10530 "cscope", 10531 #endif 10532 #ifdef CURSOR_SHAPE 10533 "cursorshape", 10534 #endif 10535 #ifdef DEBUG 10536 "debug", 10537 #endif 10538 #ifdef FEAT_CON_DIALOG 10539 "dialog_con", 10540 #endif 10541 #ifdef FEAT_GUI_DIALOG 10542 "dialog_gui", 10543 #endif 10544 #ifdef FEAT_DIFF 10545 "diff", 10546 #endif 10547 #ifdef FEAT_DIGRAPHS 10548 "digraphs", 10549 #endif 10550 #ifdef FEAT_DND 10551 "dnd", 10552 #endif 10553 #ifdef FEAT_EMACS_TAGS 10554 "emacs_tags", 10555 #endif 10556 "eval", /* always present, of course! */ 10557 #ifdef FEAT_EX_EXTRA 10558 "ex_extra", 10559 #endif 10560 #ifdef FEAT_SEARCH_EXTRA 10561 "extra_search", 10562 #endif 10563 #ifdef FEAT_FKMAP 10564 "farsi", 10565 #endif 10566 #ifdef FEAT_SEARCHPATH 10567 "file_in_path", 10568 #endif 10569 #if defined(UNIX) && !defined(USE_SYSTEM) 10570 "filterpipe", 10571 #endif 10572 #ifdef FEAT_FIND_ID 10573 "find_in_path", 10574 #endif 10575 #ifdef FEAT_FOLDING 10576 "folding", 10577 #endif 10578 #ifdef FEAT_FOOTER 10579 "footer", 10580 #endif 10581 #if !defined(USE_SYSTEM) && defined(UNIX) 10582 "fork", 10583 #endif 10584 #ifdef FEAT_GETTEXT 10585 "gettext", 10586 #endif 10587 #ifdef FEAT_GUI 10588 "gui", 10589 #endif 10590 #ifdef FEAT_GUI_ATHENA 10591 # ifdef FEAT_GUI_NEXTAW 10592 "gui_neXtaw", 10593 # else 10594 "gui_athena", 10595 # endif 10596 #endif 10597 #ifdef FEAT_GUI_GTK 10598 "gui_gtk", 10599 # ifdef HAVE_GTK2 10600 "gui_gtk2", 10601 # endif 10602 #endif 10603 #ifdef FEAT_GUI_MAC 10604 "gui_mac", 10605 #endif 10606 #ifdef FEAT_GUI_MOTIF 10607 "gui_motif", 10608 #endif 10609 #ifdef FEAT_GUI_PHOTON 10610 "gui_photon", 10611 #endif 10612 #ifdef FEAT_GUI_W16 10613 "gui_win16", 10614 #endif 10615 #ifdef FEAT_GUI_W32 10616 "gui_win32", 10617 #endif 10618 #ifdef FEAT_HANGULIN 10619 "hangul_input", 10620 #endif 10621 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10622 "iconv", 10623 #endif 10624 #ifdef FEAT_INS_EXPAND 10625 "insert_expand", 10626 #endif 10627 #ifdef FEAT_JUMPLIST 10628 "jumplist", 10629 #endif 10630 #ifdef FEAT_KEYMAP 10631 "keymap", 10632 #endif 10633 #ifdef FEAT_LANGMAP 10634 "langmap", 10635 #endif 10636 #ifdef FEAT_LIBCALL 10637 "libcall", 10638 #endif 10639 #ifdef FEAT_LINEBREAK 10640 "linebreak", 10641 #endif 10642 #ifdef FEAT_LISP 10643 "lispindent", 10644 #endif 10645 #ifdef FEAT_LISTCMDS 10646 "listcmds", 10647 #endif 10648 #ifdef FEAT_LOCALMAP 10649 "localmap", 10650 #endif 10651 #ifdef FEAT_MENU 10652 "menu", 10653 #endif 10654 #ifdef FEAT_SESSION 10655 "mksession", 10656 #endif 10657 #ifdef FEAT_MODIFY_FNAME 10658 "modify_fname", 10659 #endif 10660 #ifdef FEAT_MOUSE 10661 "mouse", 10662 #endif 10663 #ifdef FEAT_MOUSESHAPE 10664 "mouseshape", 10665 #endif 10666 #if defined(UNIX) || defined(VMS) 10667 # ifdef FEAT_MOUSE_DEC 10668 "mouse_dec", 10669 # endif 10670 # ifdef FEAT_MOUSE_GPM 10671 "mouse_gpm", 10672 # endif 10673 # ifdef FEAT_MOUSE_JSB 10674 "mouse_jsbterm", 10675 # endif 10676 # ifdef FEAT_MOUSE_NET 10677 "mouse_netterm", 10678 # endif 10679 # ifdef FEAT_MOUSE_PTERM 10680 "mouse_pterm", 10681 # endif 10682 # ifdef FEAT_MOUSE_XTERM 10683 "mouse_xterm", 10684 # endif 10685 #endif 10686 #ifdef FEAT_MBYTE 10687 "multi_byte", 10688 #endif 10689 #ifdef FEAT_MBYTE_IME 10690 "multi_byte_ime", 10691 #endif 10692 #ifdef FEAT_MULTI_LANG 10693 "multi_lang", 10694 #endif 10695 #ifdef FEAT_MZSCHEME 10696 #ifndef DYNAMIC_MZSCHEME 10697 "mzscheme", 10698 #endif 10699 #endif 10700 #ifdef FEAT_OLE 10701 "ole", 10702 #endif 10703 #ifdef FEAT_OSFILETYPE 10704 "osfiletype", 10705 #endif 10706 #ifdef FEAT_PATH_EXTRA 10707 "path_extra", 10708 #endif 10709 #ifdef FEAT_PERL 10710 #ifndef DYNAMIC_PERL 10711 "perl", 10712 #endif 10713 #endif 10714 #ifdef FEAT_PYTHON 10715 #ifndef DYNAMIC_PYTHON 10716 "python", 10717 #endif 10718 #endif 10719 #ifdef FEAT_POSTSCRIPT 10720 "postscript", 10721 #endif 10722 #ifdef FEAT_PRINTER 10723 "printer", 10724 #endif 10725 #ifdef FEAT_PROFILE 10726 "profile", 10727 #endif 10728 #ifdef FEAT_RELTIME 10729 "reltime", 10730 #endif 10731 #ifdef FEAT_QUICKFIX 10732 "quickfix", 10733 #endif 10734 #ifdef FEAT_RIGHTLEFT 10735 "rightleft", 10736 #endif 10737 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10738 "ruby", 10739 #endif 10740 #ifdef FEAT_SCROLLBIND 10741 "scrollbind", 10742 #endif 10743 #ifdef FEAT_CMDL_INFO 10744 "showcmd", 10745 "cmdline_info", 10746 #endif 10747 #ifdef FEAT_SIGNS 10748 "signs", 10749 #endif 10750 #ifdef FEAT_SMARTINDENT 10751 "smartindent", 10752 #endif 10753 #ifdef FEAT_SNIFF 10754 "sniff", 10755 #endif 10756 #ifdef FEAT_STL_OPT 10757 "statusline", 10758 #endif 10759 #ifdef FEAT_SUN_WORKSHOP 10760 "sun_workshop", 10761 #endif 10762 #ifdef FEAT_NETBEANS_INTG 10763 "netbeans_intg", 10764 #endif 10765 #ifdef FEAT_SPELL 10766 "spell", 10767 #endif 10768 #ifdef FEAT_SYN_HL 10769 "syntax", 10770 #endif 10771 #if defined(USE_SYSTEM) || !defined(UNIX) 10772 "system", 10773 #endif 10774 #ifdef FEAT_TAG_BINS 10775 "tag_binary", 10776 #endif 10777 #ifdef FEAT_TAG_OLDSTATIC 10778 "tag_old_static", 10779 #endif 10780 #ifdef FEAT_TAG_ANYWHITE 10781 "tag_any_white", 10782 #endif 10783 #ifdef FEAT_TCL 10784 # ifndef DYNAMIC_TCL 10785 "tcl", 10786 # endif 10787 #endif 10788 #ifdef TERMINFO 10789 "terminfo", 10790 #endif 10791 #ifdef FEAT_TERMRESPONSE 10792 "termresponse", 10793 #endif 10794 #ifdef FEAT_TEXTOBJ 10795 "textobjects", 10796 #endif 10797 #ifdef HAVE_TGETENT 10798 "tgetent", 10799 #endif 10800 #ifdef FEAT_TITLE 10801 "title", 10802 #endif 10803 #ifdef FEAT_TOOLBAR 10804 "toolbar", 10805 #endif 10806 #ifdef FEAT_USR_CMDS 10807 "user-commands", /* was accidentally included in 5.4 */ 10808 "user_commands", 10809 #endif 10810 #ifdef FEAT_VIMINFO 10811 "viminfo", 10812 #endif 10813 #ifdef FEAT_VERTSPLIT 10814 "vertsplit", 10815 #endif 10816 #ifdef FEAT_VIRTUALEDIT 10817 "virtualedit", 10818 #endif 10819 #ifdef FEAT_VISUAL 10820 "visual", 10821 #endif 10822 #ifdef FEAT_VISUALEXTRA 10823 "visualextra", 10824 #endif 10825 #ifdef FEAT_VREPLACE 10826 "vreplace", 10827 #endif 10828 #ifdef FEAT_WILDIGN 10829 "wildignore", 10830 #endif 10831 #ifdef FEAT_WILDMENU 10832 "wildmenu", 10833 #endif 10834 #ifdef FEAT_WINDOWS 10835 "windows", 10836 #endif 10837 #ifdef FEAT_WAK 10838 "winaltkeys", 10839 #endif 10840 #ifdef FEAT_WRITEBACKUP 10841 "writebackup", 10842 #endif 10843 #ifdef FEAT_XIM 10844 "xim", 10845 #endif 10846 #ifdef FEAT_XFONTSET 10847 "xfontset", 10848 #endif 10849 #ifdef USE_XSMP 10850 "xsmp", 10851 #endif 10852 #ifdef USE_XSMP_INTERACT 10853 "xsmp_interact", 10854 #endif 10855 #ifdef FEAT_XCLIPBOARD 10856 "xterm_clipboard", 10857 #endif 10858 #ifdef FEAT_XTERM_SAVE 10859 "xterm_save", 10860 #endif 10861 #if defined(UNIX) && defined(FEAT_X11) 10862 "X11", 10863 #endif 10864 NULL 10865 }; 10866 10867 name = get_tv_string(&argvars[0]); 10868 for (i = 0; has_list[i] != NULL; ++i) 10869 if (STRICMP(name, has_list[i]) == 0) 10870 { 10871 n = TRUE; 10872 break; 10873 } 10874 10875 if (n == FALSE) 10876 { 10877 if (STRNICMP(name, "patch", 5) == 0) 10878 n = has_patch(atoi((char *)name + 5)); 10879 else if (STRICMP(name, "vim_starting") == 0) 10880 n = (starting != 0); 10881 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10882 else if (STRICMP(name, "balloon_multiline") == 0) 10883 n = multiline_balloon_available(); 10884 #endif 10885 #ifdef DYNAMIC_TCL 10886 else if (STRICMP(name, "tcl") == 0) 10887 n = tcl_enabled(FALSE); 10888 #endif 10889 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10890 else if (STRICMP(name, "iconv") == 0) 10891 n = iconv_enabled(FALSE); 10892 #endif 10893 #ifdef DYNAMIC_MZSCHEME 10894 else if (STRICMP(name, "mzscheme") == 0) 10895 n = mzscheme_enabled(FALSE); 10896 #endif 10897 #ifdef DYNAMIC_RUBY 10898 else if (STRICMP(name, "ruby") == 0) 10899 n = ruby_enabled(FALSE); 10900 #endif 10901 #ifdef DYNAMIC_PYTHON 10902 else if (STRICMP(name, "python") == 0) 10903 n = python_enabled(FALSE); 10904 #endif 10905 #ifdef DYNAMIC_PERL 10906 else if (STRICMP(name, "perl") == 0) 10907 n = perl_enabled(FALSE); 10908 #endif 10909 #ifdef FEAT_GUI 10910 else if (STRICMP(name, "gui_running") == 0) 10911 n = (gui.in_use || gui.starting); 10912 # ifdef FEAT_GUI_W32 10913 else if (STRICMP(name, "gui_win32s") == 0) 10914 n = gui_is_win32s(); 10915 # endif 10916 # ifdef FEAT_BROWSE 10917 else if (STRICMP(name, "browse") == 0) 10918 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10919 # endif 10920 #endif 10921 #ifdef FEAT_SYN_HL 10922 else if (STRICMP(name, "syntax_items") == 0) 10923 n = syntax_present(curbuf); 10924 #endif 10925 #if defined(WIN3264) 10926 else if (STRICMP(name, "win95") == 0) 10927 n = mch_windows95(); 10928 #endif 10929 #ifdef FEAT_NETBEANS_INTG 10930 else if (STRICMP(name, "netbeans_enabled") == 0) 10931 n = usingNetbeans; 10932 #endif 10933 } 10934 10935 rettv->vval.v_number = n; 10936 } 10937 10938 /* 10939 * "has_key()" function 10940 */ 10941 static void 10942 f_has_key(argvars, rettv) 10943 typval_T *argvars; 10944 typval_T *rettv; 10945 { 10946 rettv->vval.v_number = 0; 10947 if (argvars[0].v_type != VAR_DICT) 10948 { 10949 EMSG(_(e_dictreq)); 10950 return; 10951 } 10952 if (argvars[0].vval.v_dict == NULL) 10953 return; 10954 10955 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10956 get_tv_string(&argvars[1]), -1) != NULL; 10957 } 10958 10959 /* 10960 * "hasmapto()" function 10961 */ 10962 static void 10963 f_hasmapto(argvars, rettv) 10964 typval_T *argvars; 10965 typval_T *rettv; 10966 { 10967 char_u *name; 10968 char_u *mode; 10969 char_u buf[NUMBUFLEN]; 10970 int abbr = FALSE; 10971 10972 name = get_tv_string(&argvars[0]); 10973 if (argvars[1].v_type == VAR_UNKNOWN) 10974 mode = (char_u *)"nvo"; 10975 else 10976 { 10977 mode = get_tv_string_buf(&argvars[1], buf); 10978 if (argvars[2].v_type != VAR_UNKNOWN) 10979 abbr = get_tv_number(&argvars[2]); 10980 } 10981 10982 if (map_to_exists(name, mode, abbr)) 10983 rettv->vval.v_number = TRUE; 10984 else 10985 rettv->vval.v_number = FALSE; 10986 } 10987 10988 /* 10989 * "histadd()" function 10990 */ 10991 /*ARGSUSED*/ 10992 static void 10993 f_histadd(argvars, rettv) 10994 typval_T *argvars; 10995 typval_T *rettv; 10996 { 10997 #ifdef FEAT_CMDHIST 10998 int histype; 10999 char_u *str; 11000 char_u buf[NUMBUFLEN]; 11001 #endif 11002 11003 rettv->vval.v_number = FALSE; 11004 if (check_restricted() || check_secure()) 11005 return; 11006 #ifdef FEAT_CMDHIST 11007 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11008 histype = str != NULL ? get_histtype(str) : -1; 11009 if (histype >= 0) 11010 { 11011 str = get_tv_string_buf(&argvars[1], buf); 11012 if (*str != NUL) 11013 { 11014 add_to_history(histype, str, FALSE, NUL); 11015 rettv->vval.v_number = TRUE; 11016 return; 11017 } 11018 } 11019 #endif 11020 } 11021 11022 /* 11023 * "histdel()" function 11024 */ 11025 /*ARGSUSED*/ 11026 static void 11027 f_histdel(argvars, rettv) 11028 typval_T *argvars; 11029 typval_T *rettv; 11030 { 11031 #ifdef FEAT_CMDHIST 11032 int n; 11033 char_u buf[NUMBUFLEN]; 11034 char_u *str; 11035 11036 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11037 if (str == NULL) 11038 n = 0; 11039 else if (argvars[1].v_type == VAR_UNKNOWN) 11040 /* only one argument: clear entire history */ 11041 n = clr_history(get_histtype(str)); 11042 else if (argvars[1].v_type == VAR_NUMBER) 11043 /* index given: remove that entry */ 11044 n = del_history_idx(get_histtype(str), 11045 (int)get_tv_number(&argvars[1])); 11046 else 11047 /* string given: remove all matching entries */ 11048 n = del_history_entry(get_histtype(str), 11049 get_tv_string_buf(&argvars[1], buf)); 11050 rettv->vval.v_number = n; 11051 #else 11052 rettv->vval.v_number = 0; 11053 #endif 11054 } 11055 11056 /* 11057 * "histget()" function 11058 */ 11059 /*ARGSUSED*/ 11060 static void 11061 f_histget(argvars, rettv) 11062 typval_T *argvars; 11063 typval_T *rettv; 11064 { 11065 #ifdef FEAT_CMDHIST 11066 int type; 11067 int idx; 11068 char_u *str; 11069 11070 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11071 if (str == NULL) 11072 rettv->vval.v_string = NULL; 11073 else 11074 { 11075 type = get_histtype(str); 11076 if (argvars[1].v_type == VAR_UNKNOWN) 11077 idx = get_history_idx(type); 11078 else 11079 idx = (int)get_tv_number_chk(&argvars[1], NULL); 11080 /* -1 on type error */ 11081 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 11082 } 11083 #else 11084 rettv->vval.v_string = NULL; 11085 #endif 11086 rettv->v_type = VAR_STRING; 11087 } 11088 11089 /* 11090 * "histnr()" function 11091 */ 11092 /*ARGSUSED*/ 11093 static void 11094 f_histnr(argvars, rettv) 11095 typval_T *argvars; 11096 typval_T *rettv; 11097 { 11098 int i; 11099 11100 #ifdef FEAT_CMDHIST 11101 char_u *history = get_tv_string_chk(&argvars[0]); 11102 11103 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 11104 if (i >= HIST_CMD && i < HIST_COUNT) 11105 i = get_history_idx(i); 11106 else 11107 #endif 11108 i = -1; 11109 rettv->vval.v_number = i; 11110 } 11111 11112 /* 11113 * "highlightID(name)" function 11114 */ 11115 static void 11116 f_hlID(argvars, rettv) 11117 typval_T *argvars; 11118 typval_T *rettv; 11119 { 11120 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 11121 } 11122 11123 /* 11124 * "highlight_exists()" function 11125 */ 11126 static void 11127 f_hlexists(argvars, rettv) 11128 typval_T *argvars; 11129 typval_T *rettv; 11130 { 11131 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 11132 } 11133 11134 /* 11135 * "hostname()" function 11136 */ 11137 /*ARGSUSED*/ 11138 static void 11139 f_hostname(argvars, rettv) 11140 typval_T *argvars; 11141 typval_T *rettv; 11142 { 11143 char_u hostname[256]; 11144 11145 mch_get_host_name(hostname, 256); 11146 rettv->v_type = VAR_STRING; 11147 rettv->vval.v_string = vim_strsave(hostname); 11148 } 11149 11150 /* 11151 * iconv() function 11152 */ 11153 /*ARGSUSED*/ 11154 static void 11155 f_iconv(argvars, rettv) 11156 typval_T *argvars; 11157 typval_T *rettv; 11158 { 11159 #ifdef FEAT_MBYTE 11160 char_u buf1[NUMBUFLEN]; 11161 char_u buf2[NUMBUFLEN]; 11162 char_u *from, *to, *str; 11163 vimconv_T vimconv; 11164 #endif 11165 11166 rettv->v_type = VAR_STRING; 11167 rettv->vval.v_string = NULL; 11168 11169 #ifdef FEAT_MBYTE 11170 str = get_tv_string(&argvars[0]); 11171 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 11172 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 11173 vimconv.vc_type = CONV_NONE; 11174 convert_setup(&vimconv, from, to); 11175 11176 /* If the encodings are equal, no conversion needed. */ 11177 if (vimconv.vc_type == CONV_NONE) 11178 rettv->vval.v_string = vim_strsave(str); 11179 else 11180 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 11181 11182 convert_setup(&vimconv, NULL, NULL); 11183 vim_free(from); 11184 vim_free(to); 11185 #endif 11186 } 11187 11188 /* 11189 * "indent()" function 11190 */ 11191 static void 11192 f_indent(argvars, rettv) 11193 typval_T *argvars; 11194 typval_T *rettv; 11195 { 11196 linenr_T lnum; 11197 11198 lnum = get_tv_lnum(argvars); 11199 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11200 rettv->vval.v_number = get_indent_lnum(lnum); 11201 else 11202 rettv->vval.v_number = -1; 11203 } 11204 11205 /* 11206 * "index()" function 11207 */ 11208 static void 11209 f_index(argvars, rettv) 11210 typval_T *argvars; 11211 typval_T *rettv; 11212 { 11213 list_T *l; 11214 listitem_T *item; 11215 long idx = 0; 11216 int ic = FALSE; 11217 11218 rettv->vval.v_number = -1; 11219 if (argvars[0].v_type != VAR_LIST) 11220 { 11221 EMSG(_(e_listreq)); 11222 return; 11223 } 11224 l = argvars[0].vval.v_list; 11225 if (l != NULL) 11226 { 11227 item = l->lv_first; 11228 if (argvars[2].v_type != VAR_UNKNOWN) 11229 { 11230 int error = FALSE; 11231 11232 /* Start at specified item. Use the cached index that list_find() 11233 * sets, so that a negative number also works. */ 11234 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 11235 idx = l->lv_idx; 11236 if (argvars[3].v_type != VAR_UNKNOWN) 11237 ic = get_tv_number_chk(&argvars[3], &error); 11238 if (error) 11239 item = NULL; 11240 } 11241 11242 for ( ; item != NULL; item = item->li_next, ++idx) 11243 if (tv_equal(&item->li_tv, &argvars[1], ic)) 11244 { 11245 rettv->vval.v_number = idx; 11246 break; 11247 } 11248 } 11249 } 11250 11251 static int inputsecret_flag = 0; 11252 11253 /* 11254 * "input()" function 11255 * Also handles inputsecret() when inputsecret is set. 11256 */ 11257 static void 11258 f_input(argvars, rettv) 11259 typval_T *argvars; 11260 typval_T *rettv; 11261 { 11262 char_u *prompt = get_tv_string_chk(&argvars[0]); 11263 char_u *p = NULL; 11264 int c; 11265 char_u buf[NUMBUFLEN]; 11266 int cmd_silent_save = cmd_silent; 11267 char_u *defstr = (char_u *)""; 11268 int xp_type = EXPAND_NOTHING; 11269 char_u *xp_arg = NULL; 11270 11271 rettv->v_type = VAR_STRING; 11272 11273 #ifdef NO_CONSOLE_INPUT 11274 /* While starting up, there is no place to enter text. */ 11275 if (no_console_input()) 11276 { 11277 rettv->vval.v_string = NULL; 11278 return; 11279 } 11280 #endif 11281 11282 cmd_silent = FALSE; /* Want to see the prompt. */ 11283 if (prompt != NULL) 11284 { 11285 /* Only the part of the message after the last NL is considered as 11286 * prompt for the command line */ 11287 p = vim_strrchr(prompt, '\n'); 11288 if (p == NULL) 11289 p = prompt; 11290 else 11291 { 11292 ++p; 11293 c = *p; 11294 *p = NUL; 11295 msg_start(); 11296 msg_clr_eos(); 11297 msg_puts_attr(prompt, echo_attr); 11298 msg_didout = FALSE; 11299 msg_starthere(); 11300 *p = c; 11301 } 11302 cmdline_row = msg_row; 11303 11304 if (argvars[1].v_type != VAR_UNKNOWN) 11305 { 11306 defstr = get_tv_string_buf_chk(&argvars[1], buf); 11307 if (defstr != NULL) 11308 stuffReadbuffSpec(defstr); 11309 11310 if (argvars[2].v_type != VAR_UNKNOWN) 11311 { 11312 char_u *xp_name; 11313 int xp_namelen; 11314 long argt; 11315 11316 rettv->vval.v_string = NULL; 11317 11318 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 11319 if (xp_name == NULL) 11320 return; 11321 11322 xp_namelen = (int)STRLEN(xp_name); 11323 11324 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 11325 &xp_arg) == FAIL) 11326 return; 11327 } 11328 } 11329 11330 if (defstr != NULL) 11331 rettv->vval.v_string = 11332 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 11333 xp_type, xp_arg); 11334 11335 vim_free(xp_arg); 11336 11337 /* since the user typed this, no need to wait for return */ 11338 need_wait_return = FALSE; 11339 msg_didout = FALSE; 11340 } 11341 cmd_silent = cmd_silent_save; 11342 } 11343 11344 /* 11345 * "inputdialog()" function 11346 */ 11347 static void 11348 f_inputdialog(argvars, rettv) 11349 typval_T *argvars; 11350 typval_T *rettv; 11351 { 11352 #if defined(FEAT_GUI_TEXTDIALOG) 11353 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 11354 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 11355 { 11356 char_u *message; 11357 char_u buf[NUMBUFLEN]; 11358 char_u *defstr = (char_u *)""; 11359 11360 message = get_tv_string_chk(&argvars[0]); 11361 if (argvars[1].v_type != VAR_UNKNOWN 11362 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 11363 vim_strncpy(IObuff, defstr, IOSIZE - 1); 11364 else 11365 IObuff[0] = NUL; 11366 if (message != NULL && defstr != NULL 11367 && do_dialog(VIM_QUESTION, NULL, message, 11368 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 11369 rettv->vval.v_string = vim_strsave(IObuff); 11370 else 11371 { 11372 if (message != NULL && defstr != NULL 11373 && argvars[1].v_type != VAR_UNKNOWN 11374 && argvars[2].v_type != VAR_UNKNOWN) 11375 rettv->vval.v_string = vim_strsave( 11376 get_tv_string_buf(&argvars[2], buf)); 11377 else 11378 rettv->vval.v_string = NULL; 11379 } 11380 rettv->v_type = VAR_STRING; 11381 } 11382 else 11383 #endif 11384 f_input(argvars, rettv); 11385 } 11386 11387 /* 11388 * "inputlist()" function 11389 */ 11390 static void 11391 f_inputlist(argvars, rettv) 11392 typval_T *argvars; 11393 typval_T *rettv; 11394 { 11395 listitem_T *li; 11396 int selected; 11397 int mouse_used; 11398 11399 rettv->vval.v_number = 0; 11400 #ifdef NO_CONSOLE_INPUT 11401 /* While starting up, there is no place to enter text. */ 11402 if (no_console_input()) 11403 return; 11404 #endif 11405 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 11406 { 11407 EMSG2(_(e_listarg), "inputlist()"); 11408 return; 11409 } 11410 11411 msg_start(); 11412 lines_left = Rows; /* avoid more prompt */ 11413 msg_scroll = TRUE; 11414 msg_clr_eos(); 11415 11416 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 11417 { 11418 msg_puts(get_tv_string(&li->li_tv)); 11419 msg_putchar('\n'); 11420 } 11421 11422 /* Ask for choice. */ 11423 selected = prompt_for_number(&mouse_used); 11424 if (mouse_used) 11425 selected -= lines_left; 11426 11427 rettv->vval.v_number = selected; 11428 } 11429 11430 11431 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 11432 11433 /* 11434 * "inputrestore()" function 11435 */ 11436 /*ARGSUSED*/ 11437 static void 11438 f_inputrestore(argvars, rettv) 11439 typval_T *argvars; 11440 typval_T *rettv; 11441 { 11442 if (ga_userinput.ga_len > 0) 11443 { 11444 --ga_userinput.ga_len; 11445 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 11446 + ga_userinput.ga_len); 11447 rettv->vval.v_number = 0; /* OK */ 11448 } 11449 else if (p_verbose > 1) 11450 { 11451 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11452 rettv->vval.v_number = 1; /* Failed */ 11453 } 11454 } 11455 11456 /* 11457 * "inputsave()" function 11458 */ 11459 /*ARGSUSED*/ 11460 static void 11461 f_inputsave(argvars, rettv) 11462 typval_T *argvars; 11463 typval_T *rettv; 11464 { 11465 /* Add an entry to the stack of typehead storage. */ 11466 if (ga_grow(&ga_userinput, 1) == OK) 11467 { 11468 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11469 + ga_userinput.ga_len); 11470 ++ga_userinput.ga_len; 11471 rettv->vval.v_number = 0; /* OK */ 11472 } 11473 else 11474 rettv->vval.v_number = 1; /* Failed */ 11475 } 11476 11477 /* 11478 * "inputsecret()" function 11479 */ 11480 static void 11481 f_inputsecret(argvars, rettv) 11482 typval_T *argvars; 11483 typval_T *rettv; 11484 { 11485 ++cmdline_star; 11486 ++inputsecret_flag; 11487 f_input(argvars, rettv); 11488 --cmdline_star; 11489 --inputsecret_flag; 11490 } 11491 11492 /* 11493 * "insert()" function 11494 */ 11495 static void 11496 f_insert(argvars, rettv) 11497 typval_T *argvars; 11498 typval_T *rettv; 11499 { 11500 long before = 0; 11501 listitem_T *item; 11502 list_T *l; 11503 int error = FALSE; 11504 11505 rettv->vval.v_number = 0; 11506 if (argvars[0].v_type != VAR_LIST) 11507 EMSG2(_(e_listarg), "insert()"); 11508 else if ((l = argvars[0].vval.v_list) != NULL 11509 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11510 { 11511 if (argvars[2].v_type != VAR_UNKNOWN) 11512 before = get_tv_number_chk(&argvars[2], &error); 11513 if (error) 11514 return; /* type error; errmsg already given */ 11515 11516 if (before == l->lv_len) 11517 item = NULL; 11518 else 11519 { 11520 item = list_find(l, before); 11521 if (item == NULL) 11522 { 11523 EMSGN(_(e_listidx), before); 11524 l = NULL; 11525 } 11526 } 11527 if (l != NULL) 11528 { 11529 list_insert_tv(l, &argvars[1], item); 11530 copy_tv(&argvars[0], rettv); 11531 } 11532 } 11533 } 11534 11535 /* 11536 * "isdirectory()" function 11537 */ 11538 static void 11539 f_isdirectory(argvars, rettv) 11540 typval_T *argvars; 11541 typval_T *rettv; 11542 { 11543 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11544 } 11545 11546 /* 11547 * "islocked()" function 11548 */ 11549 static void 11550 f_islocked(argvars, rettv) 11551 typval_T *argvars; 11552 typval_T *rettv; 11553 { 11554 lval_T lv; 11555 char_u *end; 11556 dictitem_T *di; 11557 11558 rettv->vval.v_number = -1; 11559 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11560 FNE_CHECK_START); 11561 if (end != NULL && lv.ll_name != NULL) 11562 { 11563 if (*end != NUL) 11564 EMSG(_(e_trailing)); 11565 else 11566 { 11567 if (lv.ll_tv == NULL) 11568 { 11569 if (check_changedtick(lv.ll_name)) 11570 rettv->vval.v_number = 1; /* always locked */ 11571 else 11572 { 11573 di = find_var(lv.ll_name, NULL); 11574 if (di != NULL) 11575 { 11576 /* Consider a variable locked when: 11577 * 1. the variable itself is locked 11578 * 2. the value of the variable is locked. 11579 * 3. the List or Dict value is locked. 11580 */ 11581 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11582 || tv_islocked(&di->di_tv)); 11583 } 11584 } 11585 } 11586 else if (lv.ll_range) 11587 EMSG(_("E786: Range not allowed")); 11588 else if (lv.ll_newkey != NULL) 11589 EMSG2(_(e_dictkey), lv.ll_newkey); 11590 else if (lv.ll_list != NULL) 11591 /* List item. */ 11592 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11593 else 11594 /* Dictionary item. */ 11595 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11596 } 11597 } 11598 11599 clear_lval(&lv); 11600 } 11601 11602 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11603 11604 /* 11605 * Turn a dict into a list: 11606 * "what" == 0: list of keys 11607 * "what" == 1: list of values 11608 * "what" == 2: list of items 11609 */ 11610 static void 11611 dict_list(argvars, rettv, what) 11612 typval_T *argvars; 11613 typval_T *rettv; 11614 int what; 11615 { 11616 list_T *l2; 11617 dictitem_T *di; 11618 hashitem_T *hi; 11619 listitem_T *li; 11620 listitem_T *li2; 11621 dict_T *d; 11622 int todo; 11623 11624 rettv->vval.v_number = 0; 11625 if (argvars[0].v_type != VAR_DICT) 11626 { 11627 EMSG(_(e_dictreq)); 11628 return; 11629 } 11630 if ((d = argvars[0].vval.v_dict) == NULL) 11631 return; 11632 11633 if (rettv_list_alloc(rettv) == FAIL) 11634 return; 11635 11636 todo = (int)d->dv_hashtab.ht_used; 11637 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11638 { 11639 if (!HASHITEM_EMPTY(hi)) 11640 { 11641 --todo; 11642 di = HI2DI(hi); 11643 11644 li = listitem_alloc(); 11645 if (li == NULL) 11646 break; 11647 list_append(rettv->vval.v_list, li); 11648 11649 if (what == 0) 11650 { 11651 /* keys() */ 11652 li->li_tv.v_type = VAR_STRING; 11653 li->li_tv.v_lock = 0; 11654 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11655 } 11656 else if (what == 1) 11657 { 11658 /* values() */ 11659 copy_tv(&di->di_tv, &li->li_tv); 11660 } 11661 else 11662 { 11663 /* items() */ 11664 l2 = list_alloc(); 11665 li->li_tv.v_type = VAR_LIST; 11666 li->li_tv.v_lock = 0; 11667 li->li_tv.vval.v_list = l2; 11668 if (l2 == NULL) 11669 break; 11670 ++l2->lv_refcount; 11671 11672 li2 = listitem_alloc(); 11673 if (li2 == NULL) 11674 break; 11675 list_append(l2, li2); 11676 li2->li_tv.v_type = VAR_STRING; 11677 li2->li_tv.v_lock = 0; 11678 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11679 11680 li2 = listitem_alloc(); 11681 if (li2 == NULL) 11682 break; 11683 list_append(l2, li2); 11684 copy_tv(&di->di_tv, &li2->li_tv); 11685 } 11686 } 11687 } 11688 } 11689 11690 /* 11691 * "items(dict)" function 11692 */ 11693 static void 11694 f_items(argvars, rettv) 11695 typval_T *argvars; 11696 typval_T *rettv; 11697 { 11698 dict_list(argvars, rettv, 2); 11699 } 11700 11701 /* 11702 * "join()" function 11703 */ 11704 static void 11705 f_join(argvars, rettv) 11706 typval_T *argvars; 11707 typval_T *rettv; 11708 { 11709 garray_T ga; 11710 char_u *sep; 11711 11712 rettv->vval.v_number = 0; 11713 if (argvars[0].v_type != VAR_LIST) 11714 { 11715 EMSG(_(e_listreq)); 11716 return; 11717 } 11718 if (argvars[0].vval.v_list == NULL) 11719 return; 11720 if (argvars[1].v_type == VAR_UNKNOWN) 11721 sep = (char_u *)" "; 11722 else 11723 sep = get_tv_string_chk(&argvars[1]); 11724 11725 rettv->v_type = VAR_STRING; 11726 11727 if (sep != NULL) 11728 { 11729 ga_init2(&ga, (int)sizeof(char), 80); 11730 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 11731 ga_append(&ga, NUL); 11732 rettv->vval.v_string = (char_u *)ga.ga_data; 11733 } 11734 else 11735 rettv->vval.v_string = NULL; 11736 } 11737 11738 /* 11739 * "keys()" function 11740 */ 11741 static void 11742 f_keys(argvars, rettv) 11743 typval_T *argvars; 11744 typval_T *rettv; 11745 { 11746 dict_list(argvars, rettv, 0); 11747 } 11748 11749 /* 11750 * "last_buffer_nr()" function. 11751 */ 11752 /*ARGSUSED*/ 11753 static void 11754 f_last_buffer_nr(argvars, rettv) 11755 typval_T *argvars; 11756 typval_T *rettv; 11757 { 11758 int n = 0; 11759 buf_T *buf; 11760 11761 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11762 if (n < buf->b_fnum) 11763 n = buf->b_fnum; 11764 11765 rettv->vval.v_number = n; 11766 } 11767 11768 /* 11769 * "len()" function 11770 */ 11771 static void 11772 f_len(argvars, rettv) 11773 typval_T *argvars; 11774 typval_T *rettv; 11775 { 11776 switch (argvars[0].v_type) 11777 { 11778 case VAR_STRING: 11779 case VAR_NUMBER: 11780 rettv->vval.v_number = (varnumber_T)STRLEN( 11781 get_tv_string(&argvars[0])); 11782 break; 11783 case VAR_LIST: 11784 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11785 break; 11786 case VAR_DICT: 11787 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11788 break; 11789 default: 11790 EMSG(_("E701: Invalid type for len()")); 11791 break; 11792 } 11793 } 11794 11795 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11796 11797 static void 11798 libcall_common(argvars, rettv, type) 11799 typval_T *argvars; 11800 typval_T *rettv; 11801 int type; 11802 { 11803 #ifdef FEAT_LIBCALL 11804 char_u *string_in; 11805 char_u **string_result; 11806 int nr_result; 11807 #endif 11808 11809 rettv->v_type = type; 11810 if (type == VAR_NUMBER) 11811 rettv->vval.v_number = 0; 11812 else 11813 rettv->vval.v_string = NULL; 11814 11815 if (check_restricted() || check_secure()) 11816 return; 11817 11818 #ifdef FEAT_LIBCALL 11819 /* The first two args must be strings, otherwise its meaningless */ 11820 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11821 { 11822 string_in = NULL; 11823 if (argvars[2].v_type == VAR_STRING) 11824 string_in = argvars[2].vval.v_string; 11825 if (type == VAR_NUMBER) 11826 string_result = NULL; 11827 else 11828 string_result = &rettv->vval.v_string; 11829 if (mch_libcall(argvars[0].vval.v_string, 11830 argvars[1].vval.v_string, 11831 string_in, 11832 argvars[2].vval.v_number, 11833 string_result, 11834 &nr_result) == OK 11835 && type == VAR_NUMBER) 11836 rettv->vval.v_number = nr_result; 11837 } 11838 #endif 11839 } 11840 11841 /* 11842 * "libcall()" function 11843 */ 11844 static void 11845 f_libcall(argvars, rettv) 11846 typval_T *argvars; 11847 typval_T *rettv; 11848 { 11849 libcall_common(argvars, rettv, VAR_STRING); 11850 } 11851 11852 /* 11853 * "libcallnr()" function 11854 */ 11855 static void 11856 f_libcallnr(argvars, rettv) 11857 typval_T *argvars; 11858 typval_T *rettv; 11859 { 11860 libcall_common(argvars, rettv, VAR_NUMBER); 11861 } 11862 11863 /* 11864 * "line(string)" function 11865 */ 11866 static void 11867 f_line(argvars, rettv) 11868 typval_T *argvars; 11869 typval_T *rettv; 11870 { 11871 linenr_T lnum = 0; 11872 pos_T *fp; 11873 int fnum; 11874 11875 fp = var2fpos(&argvars[0], TRUE, &fnum); 11876 if (fp != NULL) 11877 lnum = fp->lnum; 11878 rettv->vval.v_number = lnum; 11879 } 11880 11881 /* 11882 * "line2byte(lnum)" function 11883 */ 11884 /*ARGSUSED*/ 11885 static void 11886 f_line2byte(argvars, rettv) 11887 typval_T *argvars; 11888 typval_T *rettv; 11889 { 11890 #ifndef FEAT_BYTEOFF 11891 rettv->vval.v_number = -1; 11892 #else 11893 linenr_T lnum; 11894 11895 lnum = get_tv_lnum(argvars); 11896 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11897 rettv->vval.v_number = -1; 11898 else 11899 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11900 if (rettv->vval.v_number >= 0) 11901 ++rettv->vval.v_number; 11902 #endif 11903 } 11904 11905 /* 11906 * "lispindent(lnum)" function 11907 */ 11908 static void 11909 f_lispindent(argvars, rettv) 11910 typval_T *argvars; 11911 typval_T *rettv; 11912 { 11913 #ifdef FEAT_LISP 11914 pos_T pos; 11915 linenr_T lnum; 11916 11917 pos = curwin->w_cursor; 11918 lnum = get_tv_lnum(argvars); 11919 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11920 { 11921 curwin->w_cursor.lnum = lnum; 11922 rettv->vval.v_number = get_lisp_indent(); 11923 curwin->w_cursor = pos; 11924 } 11925 else 11926 #endif 11927 rettv->vval.v_number = -1; 11928 } 11929 11930 /* 11931 * "localtime()" function 11932 */ 11933 /*ARGSUSED*/ 11934 static void 11935 f_localtime(argvars, rettv) 11936 typval_T *argvars; 11937 typval_T *rettv; 11938 { 11939 rettv->vval.v_number = (varnumber_T)time(NULL); 11940 } 11941 11942 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11943 11944 static void 11945 get_maparg(argvars, rettv, exact) 11946 typval_T *argvars; 11947 typval_T *rettv; 11948 int exact; 11949 { 11950 char_u *keys; 11951 char_u *which; 11952 char_u buf[NUMBUFLEN]; 11953 char_u *keys_buf = NULL; 11954 char_u *rhs; 11955 int mode; 11956 garray_T ga; 11957 int abbr = FALSE; 11958 11959 /* return empty string for failure */ 11960 rettv->v_type = VAR_STRING; 11961 rettv->vval.v_string = NULL; 11962 11963 keys = get_tv_string(&argvars[0]); 11964 if (*keys == NUL) 11965 return; 11966 11967 if (argvars[1].v_type != VAR_UNKNOWN) 11968 { 11969 which = get_tv_string_buf_chk(&argvars[1], buf); 11970 if (argvars[2].v_type != VAR_UNKNOWN) 11971 abbr = get_tv_number(&argvars[2]); 11972 } 11973 else 11974 which = (char_u *)""; 11975 if (which == NULL) 11976 return; 11977 11978 mode = get_map_mode(&which, 0); 11979 11980 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11981 rhs = check_map(keys, mode, exact, FALSE, abbr); 11982 vim_free(keys_buf); 11983 if (rhs != NULL) 11984 { 11985 ga_init(&ga); 11986 ga.ga_itemsize = 1; 11987 ga.ga_growsize = 40; 11988 11989 while (*rhs != NUL) 11990 ga_concat(&ga, str2special(&rhs, FALSE)); 11991 11992 ga_append(&ga, NUL); 11993 rettv->vval.v_string = (char_u *)ga.ga_data; 11994 } 11995 } 11996 11997 /* 11998 * "map()" function 11999 */ 12000 static void 12001 f_map(argvars, rettv) 12002 typval_T *argvars; 12003 typval_T *rettv; 12004 { 12005 filter_map(argvars, rettv, TRUE); 12006 } 12007 12008 /* 12009 * "maparg()" function 12010 */ 12011 static void 12012 f_maparg(argvars, rettv) 12013 typval_T *argvars; 12014 typval_T *rettv; 12015 { 12016 get_maparg(argvars, rettv, TRUE); 12017 } 12018 12019 /* 12020 * "mapcheck()" function 12021 */ 12022 static void 12023 f_mapcheck(argvars, rettv) 12024 typval_T *argvars; 12025 typval_T *rettv; 12026 { 12027 get_maparg(argvars, rettv, FALSE); 12028 } 12029 12030 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 12031 12032 static void 12033 find_some_match(argvars, rettv, type) 12034 typval_T *argvars; 12035 typval_T *rettv; 12036 int type; 12037 { 12038 char_u *str = NULL; 12039 char_u *expr = NULL; 12040 char_u *pat; 12041 regmatch_T regmatch; 12042 char_u patbuf[NUMBUFLEN]; 12043 char_u strbuf[NUMBUFLEN]; 12044 char_u *save_cpo; 12045 long start = 0; 12046 long nth = 1; 12047 colnr_T startcol = 0; 12048 int match = 0; 12049 list_T *l = NULL; 12050 listitem_T *li = NULL; 12051 long idx = 0; 12052 char_u *tofree = NULL; 12053 12054 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 12055 save_cpo = p_cpo; 12056 p_cpo = (char_u *)""; 12057 12058 rettv->vval.v_number = -1; 12059 if (type == 3) 12060 { 12061 /* return empty list when there are no matches */ 12062 if (rettv_list_alloc(rettv) == FAIL) 12063 goto theend; 12064 } 12065 else if (type == 2) 12066 { 12067 rettv->v_type = VAR_STRING; 12068 rettv->vval.v_string = NULL; 12069 } 12070 12071 if (argvars[0].v_type == VAR_LIST) 12072 { 12073 if ((l = argvars[0].vval.v_list) == NULL) 12074 goto theend; 12075 li = l->lv_first; 12076 } 12077 else 12078 expr = str = get_tv_string(&argvars[0]); 12079 12080 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 12081 if (pat == NULL) 12082 goto theend; 12083 12084 if (argvars[2].v_type != VAR_UNKNOWN) 12085 { 12086 int error = FALSE; 12087 12088 start = get_tv_number_chk(&argvars[2], &error); 12089 if (error) 12090 goto theend; 12091 if (l != NULL) 12092 { 12093 li = list_find(l, start); 12094 if (li == NULL) 12095 goto theend; 12096 idx = l->lv_idx; /* use the cached index */ 12097 } 12098 else 12099 { 12100 if (start < 0) 12101 start = 0; 12102 if (start > (long)STRLEN(str)) 12103 goto theend; 12104 /* When "count" argument is there ignore matches before "start", 12105 * otherwise skip part of the string. Differs when pattern is "^" 12106 * or "\<". */ 12107 if (argvars[3].v_type != VAR_UNKNOWN) 12108 startcol = start; 12109 else 12110 str += start; 12111 } 12112 12113 if (argvars[3].v_type != VAR_UNKNOWN) 12114 nth = get_tv_number_chk(&argvars[3], &error); 12115 if (error) 12116 goto theend; 12117 } 12118 12119 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 12120 if (regmatch.regprog != NULL) 12121 { 12122 regmatch.rm_ic = p_ic; 12123 12124 for (;;) 12125 { 12126 if (l != NULL) 12127 { 12128 if (li == NULL) 12129 { 12130 match = FALSE; 12131 break; 12132 } 12133 vim_free(tofree); 12134 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 12135 if (str == NULL) 12136 break; 12137 } 12138 12139 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 12140 12141 if (match && --nth <= 0) 12142 break; 12143 if (l == NULL && !match) 12144 break; 12145 12146 /* Advance to just after the match. */ 12147 if (l != NULL) 12148 { 12149 li = li->li_next; 12150 ++idx; 12151 } 12152 else 12153 { 12154 #ifdef FEAT_MBYTE 12155 startcol = (colnr_T)(regmatch.startp[0] 12156 + (*mb_ptr2len)(regmatch.startp[0]) - str); 12157 #else 12158 startcol = regmatch.startp[0] + 1 - str; 12159 #endif 12160 } 12161 } 12162 12163 if (match) 12164 { 12165 if (type == 3) 12166 { 12167 int i; 12168 12169 /* return list with matched string and submatches */ 12170 for (i = 0; i < NSUBEXP; ++i) 12171 { 12172 if (regmatch.endp[i] == NULL) 12173 break; 12174 if (list_append_string(rettv->vval.v_list, 12175 regmatch.startp[i], 12176 (int)(regmatch.endp[i] - regmatch.startp[i])) 12177 == FAIL) 12178 break; 12179 } 12180 } 12181 else if (type == 2) 12182 { 12183 /* return matched string */ 12184 if (l != NULL) 12185 copy_tv(&li->li_tv, rettv); 12186 else 12187 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 12188 (int)(regmatch.endp[0] - regmatch.startp[0])); 12189 } 12190 else if (l != NULL) 12191 rettv->vval.v_number = idx; 12192 else 12193 { 12194 if (type != 0) 12195 rettv->vval.v_number = 12196 (varnumber_T)(regmatch.startp[0] - str); 12197 else 12198 rettv->vval.v_number = 12199 (varnumber_T)(regmatch.endp[0] - str); 12200 rettv->vval.v_number += (varnumber_T)(str - expr); 12201 } 12202 } 12203 vim_free(regmatch.regprog); 12204 } 12205 12206 theend: 12207 vim_free(tofree); 12208 p_cpo = save_cpo; 12209 } 12210 12211 /* 12212 * "match()" function 12213 */ 12214 static void 12215 f_match(argvars, rettv) 12216 typval_T *argvars; 12217 typval_T *rettv; 12218 { 12219 find_some_match(argvars, rettv, 1); 12220 } 12221 12222 /* 12223 * "matcharg()" function 12224 */ 12225 static void 12226 f_matcharg(argvars, rettv) 12227 typval_T *argvars; 12228 typval_T *rettv; 12229 { 12230 if (rettv_list_alloc(rettv) == OK) 12231 { 12232 #ifdef FEAT_SEARCH_EXTRA 12233 int mi = get_tv_number(&argvars[0]); 12234 12235 if (mi >= 1 && mi <= 3) 12236 { 12237 list_append_string(rettv->vval.v_list, 12238 syn_id2name(curwin->w_match_id[mi - 1]), -1); 12239 list_append_string(rettv->vval.v_list, 12240 curwin->w_match_pat[mi - 1], -1); 12241 } 12242 #endif 12243 } 12244 } 12245 12246 /* 12247 * "matchend()" function 12248 */ 12249 static void 12250 f_matchend(argvars, rettv) 12251 typval_T *argvars; 12252 typval_T *rettv; 12253 { 12254 find_some_match(argvars, rettv, 0); 12255 } 12256 12257 /* 12258 * "matchlist()" function 12259 */ 12260 static void 12261 f_matchlist(argvars, rettv) 12262 typval_T *argvars; 12263 typval_T *rettv; 12264 { 12265 find_some_match(argvars, rettv, 3); 12266 } 12267 12268 /* 12269 * "matchstr()" function 12270 */ 12271 static void 12272 f_matchstr(argvars, rettv) 12273 typval_T *argvars; 12274 typval_T *rettv; 12275 { 12276 find_some_match(argvars, rettv, 2); 12277 } 12278 12279 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 12280 12281 static void 12282 max_min(argvars, rettv, domax) 12283 typval_T *argvars; 12284 typval_T *rettv; 12285 int domax; 12286 { 12287 long n = 0; 12288 long i; 12289 int error = FALSE; 12290 12291 if (argvars[0].v_type == VAR_LIST) 12292 { 12293 list_T *l; 12294 listitem_T *li; 12295 12296 l = argvars[0].vval.v_list; 12297 if (l != NULL) 12298 { 12299 li = l->lv_first; 12300 if (li != NULL) 12301 { 12302 n = get_tv_number_chk(&li->li_tv, &error); 12303 for (;;) 12304 { 12305 li = li->li_next; 12306 if (li == NULL) 12307 break; 12308 i = get_tv_number_chk(&li->li_tv, &error); 12309 if (domax ? i > n : i < n) 12310 n = i; 12311 } 12312 } 12313 } 12314 } 12315 else if (argvars[0].v_type == VAR_DICT) 12316 { 12317 dict_T *d; 12318 int first = TRUE; 12319 hashitem_T *hi; 12320 int todo; 12321 12322 d = argvars[0].vval.v_dict; 12323 if (d != NULL) 12324 { 12325 todo = (int)d->dv_hashtab.ht_used; 12326 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 12327 { 12328 if (!HASHITEM_EMPTY(hi)) 12329 { 12330 --todo; 12331 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 12332 if (first) 12333 { 12334 n = i; 12335 first = FALSE; 12336 } 12337 else if (domax ? i > n : i < n) 12338 n = i; 12339 } 12340 } 12341 } 12342 } 12343 else 12344 EMSG(_(e_listdictarg)); 12345 rettv->vval.v_number = error ? 0 : n; 12346 } 12347 12348 /* 12349 * "max()" function 12350 */ 12351 static void 12352 f_max(argvars, rettv) 12353 typval_T *argvars; 12354 typval_T *rettv; 12355 { 12356 max_min(argvars, rettv, TRUE); 12357 } 12358 12359 /* 12360 * "min()" function 12361 */ 12362 static void 12363 f_min(argvars, rettv) 12364 typval_T *argvars; 12365 typval_T *rettv; 12366 { 12367 max_min(argvars, rettv, FALSE); 12368 } 12369 12370 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 12371 12372 /* 12373 * Create the directory in which "dir" is located, and higher levels when 12374 * needed. 12375 */ 12376 static int 12377 mkdir_recurse(dir, prot) 12378 char_u *dir; 12379 int prot; 12380 { 12381 char_u *p; 12382 char_u *updir; 12383 int r = FAIL; 12384 12385 /* Get end of directory name in "dir". 12386 * We're done when it's "/" or "c:/". */ 12387 p = gettail_sep(dir); 12388 if (p <= get_past_head(dir)) 12389 return OK; 12390 12391 /* If the directory exists we're done. Otherwise: create it.*/ 12392 updir = vim_strnsave(dir, (int)(p - dir)); 12393 if (updir == NULL) 12394 return FAIL; 12395 if (mch_isdir(updir)) 12396 r = OK; 12397 else if (mkdir_recurse(updir, prot) == OK) 12398 r = vim_mkdir_emsg(updir, prot); 12399 vim_free(updir); 12400 return r; 12401 } 12402 12403 #ifdef vim_mkdir 12404 /* 12405 * "mkdir()" function 12406 */ 12407 static void 12408 f_mkdir(argvars, rettv) 12409 typval_T *argvars; 12410 typval_T *rettv; 12411 { 12412 char_u *dir; 12413 char_u buf[NUMBUFLEN]; 12414 int prot = 0755; 12415 12416 rettv->vval.v_number = FAIL; 12417 if (check_restricted() || check_secure()) 12418 return; 12419 12420 dir = get_tv_string_buf(&argvars[0], buf); 12421 if (argvars[1].v_type != VAR_UNKNOWN) 12422 { 12423 if (argvars[2].v_type != VAR_UNKNOWN) 12424 prot = get_tv_number_chk(&argvars[2], NULL); 12425 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 12426 mkdir_recurse(dir, prot); 12427 } 12428 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 12429 } 12430 #endif 12431 12432 /* 12433 * "mode()" function 12434 */ 12435 /*ARGSUSED*/ 12436 static void 12437 f_mode(argvars, rettv) 12438 typval_T *argvars; 12439 typval_T *rettv; 12440 { 12441 char_u buf[2]; 12442 12443 #ifdef FEAT_VISUAL 12444 if (VIsual_active) 12445 { 12446 if (VIsual_select) 12447 buf[0] = VIsual_mode + 's' - 'v'; 12448 else 12449 buf[0] = VIsual_mode; 12450 } 12451 else 12452 #endif 12453 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 12454 buf[0] = 'r'; 12455 else if (State & INSERT) 12456 { 12457 if (State & REPLACE_FLAG) 12458 buf[0] = 'R'; 12459 else 12460 buf[0] = 'i'; 12461 } 12462 else if (State & CMDLINE) 12463 buf[0] = 'c'; 12464 else 12465 buf[0] = 'n'; 12466 12467 buf[1] = NUL; 12468 rettv->vval.v_string = vim_strsave(buf); 12469 rettv->v_type = VAR_STRING; 12470 } 12471 12472 /* 12473 * "nextnonblank()" function 12474 */ 12475 static void 12476 f_nextnonblank(argvars, rettv) 12477 typval_T *argvars; 12478 typval_T *rettv; 12479 { 12480 linenr_T lnum; 12481 12482 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12483 { 12484 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12485 { 12486 lnum = 0; 12487 break; 12488 } 12489 if (*skipwhite(ml_get(lnum)) != NUL) 12490 break; 12491 } 12492 rettv->vval.v_number = lnum; 12493 } 12494 12495 /* 12496 * "nr2char()" function 12497 */ 12498 static void 12499 f_nr2char(argvars, rettv) 12500 typval_T *argvars; 12501 typval_T *rettv; 12502 { 12503 char_u buf[NUMBUFLEN]; 12504 12505 #ifdef FEAT_MBYTE 12506 if (has_mbyte) 12507 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12508 else 12509 #endif 12510 { 12511 buf[0] = (char_u)get_tv_number(&argvars[0]); 12512 buf[1] = NUL; 12513 } 12514 rettv->v_type = VAR_STRING; 12515 rettv->vval.v_string = vim_strsave(buf); 12516 } 12517 12518 /* 12519 * "pathshorten()" function 12520 */ 12521 static void 12522 f_pathshorten(argvars, rettv) 12523 typval_T *argvars; 12524 typval_T *rettv; 12525 { 12526 char_u *p; 12527 12528 rettv->v_type = VAR_STRING; 12529 p = get_tv_string_chk(&argvars[0]); 12530 if (p == NULL) 12531 rettv->vval.v_string = NULL; 12532 else 12533 { 12534 p = vim_strsave(p); 12535 rettv->vval.v_string = p; 12536 if (p != NULL) 12537 shorten_dir(p); 12538 } 12539 } 12540 12541 /* 12542 * "prevnonblank()" function 12543 */ 12544 static void 12545 f_prevnonblank(argvars, rettv) 12546 typval_T *argvars; 12547 typval_T *rettv; 12548 { 12549 linenr_T lnum; 12550 12551 lnum = get_tv_lnum(argvars); 12552 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12553 lnum = 0; 12554 else 12555 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12556 --lnum; 12557 rettv->vval.v_number = lnum; 12558 } 12559 12560 #ifdef HAVE_STDARG_H 12561 /* This dummy va_list is here because: 12562 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12563 * - locally in the function results in a "used before set" warning 12564 * - using va_start() to initialize it gives "function with fixed args" error */ 12565 static va_list ap; 12566 #endif 12567 12568 /* 12569 * "printf()" function 12570 */ 12571 static void 12572 f_printf(argvars, rettv) 12573 typval_T *argvars; 12574 typval_T *rettv; 12575 { 12576 rettv->v_type = VAR_STRING; 12577 rettv->vval.v_string = NULL; 12578 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12579 { 12580 char_u buf[NUMBUFLEN]; 12581 int len; 12582 char_u *s; 12583 int saved_did_emsg = did_emsg; 12584 char *fmt; 12585 12586 /* Get the required length, allocate the buffer and do it for real. */ 12587 did_emsg = FALSE; 12588 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12589 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12590 if (!did_emsg) 12591 { 12592 s = alloc(len + 1); 12593 if (s != NULL) 12594 { 12595 rettv->vval.v_string = s; 12596 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12597 } 12598 } 12599 did_emsg |= saved_did_emsg; 12600 } 12601 #endif 12602 } 12603 12604 /* 12605 * "pumvisible()" function 12606 */ 12607 /*ARGSUSED*/ 12608 static void 12609 f_pumvisible(argvars, rettv) 12610 typval_T *argvars; 12611 typval_T *rettv; 12612 { 12613 rettv->vval.v_number = 0; 12614 #ifdef FEAT_INS_EXPAND 12615 if (pum_visible()) 12616 rettv->vval.v_number = 1; 12617 #endif 12618 } 12619 12620 /* 12621 * "range()" function 12622 */ 12623 static void 12624 f_range(argvars, rettv) 12625 typval_T *argvars; 12626 typval_T *rettv; 12627 { 12628 long start; 12629 long end; 12630 long stride = 1; 12631 long i; 12632 int error = FALSE; 12633 12634 start = get_tv_number_chk(&argvars[0], &error); 12635 if (argvars[1].v_type == VAR_UNKNOWN) 12636 { 12637 end = start - 1; 12638 start = 0; 12639 } 12640 else 12641 { 12642 end = get_tv_number_chk(&argvars[1], &error); 12643 if (argvars[2].v_type != VAR_UNKNOWN) 12644 stride = get_tv_number_chk(&argvars[2], &error); 12645 } 12646 12647 rettv->vval.v_number = 0; 12648 if (error) 12649 return; /* type error; errmsg already given */ 12650 if (stride == 0) 12651 EMSG(_("E726: Stride is zero")); 12652 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12653 EMSG(_("E727: Start past end")); 12654 else 12655 { 12656 if (rettv_list_alloc(rettv) == OK) 12657 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12658 if (list_append_number(rettv->vval.v_list, 12659 (varnumber_T)i) == FAIL) 12660 break; 12661 } 12662 } 12663 12664 /* 12665 * "readfile()" function 12666 */ 12667 static void 12668 f_readfile(argvars, rettv) 12669 typval_T *argvars; 12670 typval_T *rettv; 12671 { 12672 int binary = FALSE; 12673 char_u *fname; 12674 FILE *fd; 12675 listitem_T *li; 12676 #define FREAD_SIZE 200 /* optimized for text lines */ 12677 char_u buf[FREAD_SIZE]; 12678 int readlen; /* size of last fread() */ 12679 int buflen; /* nr of valid chars in buf[] */ 12680 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12681 int tolist; /* first byte in buf[] still to be put in list */ 12682 int chop; /* how many CR to chop off */ 12683 char_u *prev = NULL; /* previously read bytes, if any */ 12684 int prevlen = 0; /* length of "prev" if not NULL */ 12685 char_u *s; 12686 int len; 12687 long maxline = MAXLNUM; 12688 long cnt = 0; 12689 12690 if (argvars[1].v_type != VAR_UNKNOWN) 12691 { 12692 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12693 binary = TRUE; 12694 if (argvars[2].v_type != VAR_UNKNOWN) 12695 maxline = get_tv_number(&argvars[2]); 12696 } 12697 12698 if (rettv_list_alloc(rettv) == FAIL) 12699 return; 12700 12701 /* Always open the file in binary mode, library functions have a mind of 12702 * their own about CR-LF conversion. */ 12703 fname = get_tv_string(&argvars[0]); 12704 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12705 { 12706 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12707 return; 12708 } 12709 12710 filtd = 0; 12711 while (cnt < maxline || maxline < 0) 12712 { 12713 readlen = (int)fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12714 buflen = filtd + readlen; 12715 tolist = 0; 12716 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12717 { 12718 if (buf[filtd] == '\n' || readlen <= 0) 12719 { 12720 /* Only when in binary mode add an empty list item when the 12721 * last line ends in a '\n'. */ 12722 if (!binary && readlen == 0 && filtd == 0) 12723 break; 12724 12725 /* Found end-of-line or end-of-file: add a text line to the 12726 * list. */ 12727 chop = 0; 12728 if (!binary) 12729 while (filtd - chop - 1 >= tolist 12730 && buf[filtd - chop - 1] == '\r') 12731 ++chop; 12732 len = filtd - tolist - chop; 12733 if (prev == NULL) 12734 s = vim_strnsave(buf + tolist, len); 12735 else 12736 { 12737 s = alloc((unsigned)(prevlen + len + 1)); 12738 if (s != NULL) 12739 { 12740 mch_memmove(s, prev, prevlen); 12741 vim_free(prev); 12742 prev = NULL; 12743 mch_memmove(s + prevlen, buf + tolist, len); 12744 s[prevlen + len] = NUL; 12745 } 12746 } 12747 tolist = filtd + 1; 12748 12749 li = listitem_alloc(); 12750 if (li == NULL) 12751 { 12752 vim_free(s); 12753 break; 12754 } 12755 li->li_tv.v_type = VAR_STRING; 12756 li->li_tv.v_lock = 0; 12757 li->li_tv.vval.v_string = s; 12758 list_append(rettv->vval.v_list, li); 12759 12760 if (++cnt >= maxline && maxline >= 0) 12761 break; 12762 if (readlen <= 0) 12763 break; 12764 } 12765 else if (buf[filtd] == NUL) 12766 buf[filtd] = '\n'; 12767 } 12768 if (readlen <= 0) 12769 break; 12770 12771 if (tolist == 0) 12772 { 12773 /* "buf" is full, need to move text to an allocated buffer */ 12774 if (prev == NULL) 12775 { 12776 prev = vim_strnsave(buf, buflen); 12777 prevlen = buflen; 12778 } 12779 else 12780 { 12781 s = alloc((unsigned)(prevlen + buflen)); 12782 if (s != NULL) 12783 { 12784 mch_memmove(s, prev, prevlen); 12785 mch_memmove(s + prevlen, buf, buflen); 12786 vim_free(prev); 12787 prev = s; 12788 prevlen += buflen; 12789 } 12790 } 12791 filtd = 0; 12792 } 12793 else 12794 { 12795 mch_memmove(buf, buf + tolist, buflen - tolist); 12796 filtd -= tolist; 12797 } 12798 } 12799 12800 /* 12801 * For a negative line count use only the lines at the end of the file, 12802 * free the rest. 12803 */ 12804 if (maxline < 0) 12805 while (cnt > -maxline) 12806 { 12807 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 12808 --cnt; 12809 } 12810 12811 vim_free(prev); 12812 fclose(fd); 12813 } 12814 12815 #if defined(FEAT_RELTIME) 12816 static int list2proftime __ARGS((typval_T *arg, proftime_T *tm)); 12817 12818 /* 12819 * Convert a List to proftime_T. 12820 * Return FAIL when there is something wrong. 12821 */ 12822 static int 12823 list2proftime(arg, tm) 12824 typval_T *arg; 12825 proftime_T *tm; 12826 { 12827 long n1, n2; 12828 int error = FALSE; 12829 12830 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 12831 || arg->vval.v_list->lv_len != 2) 12832 return FAIL; 12833 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 12834 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 12835 # ifdef WIN3264 12836 tm->HighPart = n1; 12837 tm->LowPart = n2; 12838 # else 12839 tm->tv_sec = n1; 12840 tm->tv_usec = n2; 12841 # endif 12842 return error ? FAIL : OK; 12843 } 12844 #endif /* FEAT_RELTIME */ 12845 12846 /* 12847 * "reltime()" function 12848 */ 12849 static void 12850 f_reltime(argvars, rettv) 12851 typval_T *argvars; 12852 typval_T *rettv; 12853 { 12854 #ifdef FEAT_RELTIME 12855 proftime_T res; 12856 proftime_T start; 12857 12858 if (argvars[0].v_type == VAR_UNKNOWN) 12859 { 12860 /* No arguments: get current time. */ 12861 profile_start(&res); 12862 } 12863 else if (argvars[1].v_type == VAR_UNKNOWN) 12864 { 12865 if (list2proftime(&argvars[0], &res) == FAIL) 12866 return; 12867 profile_end(&res); 12868 } 12869 else 12870 { 12871 /* Two arguments: compute the difference. */ 12872 if (list2proftime(&argvars[0], &start) == FAIL 12873 || list2proftime(&argvars[1], &res) == FAIL) 12874 return; 12875 profile_sub(&res, &start); 12876 } 12877 12878 if (rettv_list_alloc(rettv) == OK) 12879 { 12880 long n1, n2; 12881 12882 # ifdef WIN3264 12883 n1 = res.HighPart; 12884 n2 = res.LowPart; 12885 # else 12886 n1 = res.tv_sec; 12887 n2 = res.tv_usec; 12888 # endif 12889 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 12890 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 12891 } 12892 #endif 12893 } 12894 12895 /* 12896 * "reltimestr()" function 12897 */ 12898 static void 12899 f_reltimestr(argvars, rettv) 12900 typval_T *argvars; 12901 typval_T *rettv; 12902 { 12903 #ifdef FEAT_RELTIME 12904 proftime_T tm; 12905 #endif 12906 12907 rettv->v_type = VAR_STRING; 12908 rettv->vval.v_string = NULL; 12909 #ifdef FEAT_RELTIME 12910 if (list2proftime(&argvars[0], &tm) == OK) 12911 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 12912 #endif 12913 } 12914 12915 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12916 static void make_connection __ARGS((void)); 12917 static int check_connection __ARGS((void)); 12918 12919 static void 12920 make_connection() 12921 { 12922 if (X_DISPLAY == NULL 12923 # ifdef FEAT_GUI 12924 && !gui.in_use 12925 # endif 12926 ) 12927 { 12928 x_force_connect = TRUE; 12929 setup_term_clip(); 12930 x_force_connect = FALSE; 12931 } 12932 } 12933 12934 static int 12935 check_connection() 12936 { 12937 make_connection(); 12938 if (X_DISPLAY == NULL) 12939 { 12940 EMSG(_("E240: No connection to Vim server")); 12941 return FAIL; 12942 } 12943 return OK; 12944 } 12945 #endif 12946 12947 #ifdef FEAT_CLIENTSERVER 12948 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12949 12950 static void 12951 remote_common(argvars, rettv, expr) 12952 typval_T *argvars; 12953 typval_T *rettv; 12954 int expr; 12955 { 12956 char_u *server_name; 12957 char_u *keys; 12958 char_u *r = NULL; 12959 char_u buf[NUMBUFLEN]; 12960 # ifdef WIN32 12961 HWND w; 12962 # else 12963 Window w; 12964 # endif 12965 12966 if (check_restricted() || check_secure()) 12967 return; 12968 12969 # ifdef FEAT_X11 12970 if (check_connection() == FAIL) 12971 return; 12972 # endif 12973 12974 server_name = get_tv_string_chk(&argvars[0]); 12975 if (server_name == NULL) 12976 return; /* type error; errmsg already given */ 12977 keys = get_tv_string_buf(&argvars[1], buf); 12978 # ifdef WIN32 12979 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12980 # else 12981 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12982 < 0) 12983 # endif 12984 { 12985 if (r != NULL) 12986 EMSG(r); /* sending worked but evaluation failed */ 12987 else 12988 EMSG2(_("E241: Unable to send to %s"), server_name); 12989 return; 12990 } 12991 12992 rettv->vval.v_string = r; 12993 12994 if (argvars[2].v_type != VAR_UNKNOWN) 12995 { 12996 dictitem_T v; 12997 char_u str[30]; 12998 char_u *idvar; 12999 13000 sprintf((char *)str, "0x%x", (unsigned int)w); 13001 v.di_tv.v_type = VAR_STRING; 13002 v.di_tv.vval.v_string = vim_strsave(str); 13003 idvar = get_tv_string_chk(&argvars[2]); 13004 if (idvar != NULL) 13005 set_var(idvar, &v.di_tv, FALSE); 13006 vim_free(v.di_tv.vval.v_string); 13007 } 13008 } 13009 #endif 13010 13011 /* 13012 * "remote_expr()" function 13013 */ 13014 /*ARGSUSED*/ 13015 static void 13016 f_remote_expr(argvars, rettv) 13017 typval_T *argvars; 13018 typval_T *rettv; 13019 { 13020 rettv->v_type = VAR_STRING; 13021 rettv->vval.v_string = NULL; 13022 #ifdef FEAT_CLIENTSERVER 13023 remote_common(argvars, rettv, TRUE); 13024 #endif 13025 } 13026 13027 /* 13028 * "remote_foreground()" function 13029 */ 13030 /*ARGSUSED*/ 13031 static void 13032 f_remote_foreground(argvars, rettv) 13033 typval_T *argvars; 13034 typval_T *rettv; 13035 { 13036 rettv->vval.v_number = 0; 13037 #ifdef FEAT_CLIENTSERVER 13038 # ifdef WIN32 13039 /* On Win32 it's done in this application. */ 13040 { 13041 char_u *server_name = get_tv_string_chk(&argvars[0]); 13042 13043 if (server_name != NULL) 13044 serverForeground(server_name); 13045 } 13046 # else 13047 /* Send a foreground() expression to the server. */ 13048 argvars[1].v_type = VAR_STRING; 13049 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 13050 argvars[2].v_type = VAR_UNKNOWN; 13051 remote_common(argvars, rettv, TRUE); 13052 vim_free(argvars[1].vval.v_string); 13053 # endif 13054 #endif 13055 } 13056 13057 /*ARGSUSED*/ 13058 static void 13059 f_remote_peek(argvars, rettv) 13060 typval_T *argvars; 13061 typval_T *rettv; 13062 { 13063 #ifdef FEAT_CLIENTSERVER 13064 dictitem_T v; 13065 char_u *s = NULL; 13066 # ifdef WIN32 13067 int n = 0; 13068 # endif 13069 char_u *serverid; 13070 13071 if (check_restricted() || check_secure()) 13072 { 13073 rettv->vval.v_number = -1; 13074 return; 13075 } 13076 serverid = get_tv_string_chk(&argvars[0]); 13077 if (serverid == NULL) 13078 { 13079 rettv->vval.v_number = -1; 13080 return; /* type error; errmsg already given */ 13081 } 13082 # ifdef WIN32 13083 sscanf(serverid, "%x", &n); 13084 if (n == 0) 13085 rettv->vval.v_number = -1; 13086 else 13087 { 13088 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 13089 rettv->vval.v_number = (s != NULL); 13090 } 13091 # else 13092 rettv->vval.v_number = 0; 13093 if (check_connection() == FAIL) 13094 return; 13095 13096 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 13097 serverStrToWin(serverid), &s); 13098 # endif 13099 13100 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 13101 { 13102 char_u *retvar; 13103 13104 v.di_tv.v_type = VAR_STRING; 13105 v.di_tv.vval.v_string = vim_strsave(s); 13106 retvar = get_tv_string_chk(&argvars[1]); 13107 if (retvar != NULL) 13108 set_var(retvar, &v.di_tv, FALSE); 13109 vim_free(v.di_tv.vval.v_string); 13110 } 13111 #else 13112 rettv->vval.v_number = -1; 13113 #endif 13114 } 13115 13116 /*ARGSUSED*/ 13117 static void 13118 f_remote_read(argvars, rettv) 13119 typval_T *argvars; 13120 typval_T *rettv; 13121 { 13122 char_u *r = NULL; 13123 13124 #ifdef FEAT_CLIENTSERVER 13125 char_u *serverid = get_tv_string_chk(&argvars[0]); 13126 13127 if (serverid != NULL && !check_restricted() && !check_secure()) 13128 { 13129 # ifdef WIN32 13130 /* The server's HWND is encoded in the 'id' parameter */ 13131 int n = 0; 13132 13133 sscanf(serverid, "%x", &n); 13134 if (n != 0) 13135 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 13136 if (r == NULL) 13137 # else 13138 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 13139 serverStrToWin(serverid), &r, FALSE) < 0) 13140 # endif 13141 EMSG(_("E277: Unable to read a server reply")); 13142 } 13143 #endif 13144 rettv->v_type = VAR_STRING; 13145 rettv->vval.v_string = r; 13146 } 13147 13148 /* 13149 * "remote_send()" function 13150 */ 13151 /*ARGSUSED*/ 13152 static void 13153 f_remote_send(argvars, rettv) 13154 typval_T *argvars; 13155 typval_T *rettv; 13156 { 13157 rettv->v_type = VAR_STRING; 13158 rettv->vval.v_string = NULL; 13159 #ifdef FEAT_CLIENTSERVER 13160 remote_common(argvars, rettv, FALSE); 13161 #endif 13162 } 13163 13164 /* 13165 * "remove()" function 13166 */ 13167 static void 13168 f_remove(argvars, rettv) 13169 typval_T *argvars; 13170 typval_T *rettv; 13171 { 13172 list_T *l; 13173 listitem_T *item, *item2; 13174 listitem_T *li; 13175 long idx; 13176 long end; 13177 char_u *key; 13178 dict_T *d; 13179 dictitem_T *di; 13180 13181 rettv->vval.v_number = 0; 13182 if (argvars[0].v_type == VAR_DICT) 13183 { 13184 if (argvars[2].v_type != VAR_UNKNOWN) 13185 EMSG2(_(e_toomanyarg), "remove()"); 13186 else if ((d = argvars[0].vval.v_dict) != NULL 13187 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 13188 { 13189 key = get_tv_string_chk(&argvars[1]); 13190 if (key != NULL) 13191 { 13192 di = dict_find(d, key, -1); 13193 if (di == NULL) 13194 EMSG2(_(e_dictkey), key); 13195 else 13196 { 13197 *rettv = di->di_tv; 13198 init_tv(&di->di_tv); 13199 dictitem_remove(d, di); 13200 } 13201 } 13202 } 13203 } 13204 else if (argvars[0].v_type != VAR_LIST) 13205 EMSG2(_(e_listdictarg), "remove()"); 13206 else if ((l = argvars[0].vval.v_list) != NULL 13207 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 13208 { 13209 int error = FALSE; 13210 13211 idx = get_tv_number_chk(&argvars[1], &error); 13212 if (error) 13213 ; /* type error: do nothing, errmsg already given */ 13214 else if ((item = list_find(l, idx)) == NULL) 13215 EMSGN(_(e_listidx), idx); 13216 else 13217 { 13218 if (argvars[2].v_type == VAR_UNKNOWN) 13219 { 13220 /* Remove one item, return its value. */ 13221 list_remove(l, item, item); 13222 *rettv = item->li_tv; 13223 vim_free(item); 13224 } 13225 else 13226 { 13227 /* Remove range of items, return list with values. */ 13228 end = get_tv_number_chk(&argvars[2], &error); 13229 if (error) 13230 ; /* type error: do nothing */ 13231 else if ((item2 = list_find(l, end)) == NULL) 13232 EMSGN(_(e_listidx), end); 13233 else 13234 { 13235 int cnt = 0; 13236 13237 for (li = item; li != NULL; li = li->li_next) 13238 { 13239 ++cnt; 13240 if (li == item2) 13241 break; 13242 } 13243 if (li == NULL) /* didn't find "item2" after "item" */ 13244 EMSG(_(e_invrange)); 13245 else 13246 { 13247 list_remove(l, item, item2); 13248 if (rettv_list_alloc(rettv) == OK) 13249 { 13250 l = rettv->vval.v_list; 13251 l->lv_first = item; 13252 l->lv_last = item2; 13253 item->li_prev = NULL; 13254 item2->li_next = NULL; 13255 l->lv_len = cnt; 13256 } 13257 } 13258 } 13259 } 13260 } 13261 } 13262 } 13263 13264 /* 13265 * "rename({from}, {to})" function 13266 */ 13267 static void 13268 f_rename(argvars, rettv) 13269 typval_T *argvars; 13270 typval_T *rettv; 13271 { 13272 char_u buf[NUMBUFLEN]; 13273 13274 if (check_restricted() || check_secure()) 13275 rettv->vval.v_number = -1; 13276 else 13277 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 13278 get_tv_string_buf(&argvars[1], buf)); 13279 } 13280 13281 /* 13282 * "repeat()" function 13283 */ 13284 /*ARGSUSED*/ 13285 static void 13286 f_repeat(argvars, rettv) 13287 typval_T *argvars; 13288 typval_T *rettv; 13289 { 13290 char_u *p; 13291 int n; 13292 int slen; 13293 int len; 13294 char_u *r; 13295 int i; 13296 13297 n = get_tv_number(&argvars[1]); 13298 if (argvars[0].v_type == VAR_LIST) 13299 { 13300 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 13301 while (n-- > 0) 13302 if (list_extend(rettv->vval.v_list, 13303 argvars[0].vval.v_list, NULL) == FAIL) 13304 break; 13305 } 13306 else 13307 { 13308 p = get_tv_string(&argvars[0]); 13309 rettv->v_type = VAR_STRING; 13310 rettv->vval.v_string = NULL; 13311 13312 slen = (int)STRLEN(p); 13313 len = slen * n; 13314 if (len <= 0) 13315 return; 13316 13317 r = alloc(len + 1); 13318 if (r != NULL) 13319 { 13320 for (i = 0; i < n; i++) 13321 mch_memmove(r + i * slen, p, (size_t)slen); 13322 r[len] = NUL; 13323 } 13324 13325 rettv->vval.v_string = r; 13326 } 13327 } 13328 13329 /* 13330 * "resolve()" function 13331 */ 13332 static void 13333 f_resolve(argvars, rettv) 13334 typval_T *argvars; 13335 typval_T *rettv; 13336 { 13337 char_u *p; 13338 13339 p = get_tv_string(&argvars[0]); 13340 #ifdef FEAT_SHORTCUT 13341 { 13342 char_u *v = NULL; 13343 13344 v = mch_resolve_shortcut(p); 13345 if (v != NULL) 13346 rettv->vval.v_string = v; 13347 else 13348 rettv->vval.v_string = vim_strsave(p); 13349 } 13350 #else 13351 # ifdef HAVE_READLINK 13352 { 13353 char_u buf[MAXPATHL + 1]; 13354 char_u *cpy; 13355 int len; 13356 char_u *remain = NULL; 13357 char_u *q; 13358 int is_relative_to_current = FALSE; 13359 int has_trailing_pathsep = FALSE; 13360 int limit = 100; 13361 13362 p = vim_strsave(p); 13363 13364 if (p[0] == '.' && (vim_ispathsep(p[1]) 13365 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 13366 is_relative_to_current = TRUE; 13367 13368 len = STRLEN(p); 13369 if (len > 0 && after_pathsep(p, p + len)) 13370 has_trailing_pathsep = TRUE; 13371 13372 q = getnextcomp(p); 13373 if (*q != NUL) 13374 { 13375 /* Separate the first path component in "p", and keep the 13376 * remainder (beginning with the path separator). */ 13377 remain = vim_strsave(q - 1); 13378 q[-1] = NUL; 13379 } 13380 13381 for (;;) 13382 { 13383 for (;;) 13384 { 13385 len = readlink((char *)p, (char *)buf, MAXPATHL); 13386 if (len <= 0) 13387 break; 13388 buf[len] = NUL; 13389 13390 if (limit-- == 0) 13391 { 13392 vim_free(p); 13393 vim_free(remain); 13394 EMSG(_("E655: Too many symbolic links (cycle?)")); 13395 rettv->vval.v_string = NULL; 13396 goto fail; 13397 } 13398 13399 /* Ensure that the result will have a trailing path separator 13400 * if the argument has one. */ 13401 if (remain == NULL && has_trailing_pathsep) 13402 add_pathsep(buf); 13403 13404 /* Separate the first path component in the link value and 13405 * concatenate the remainders. */ 13406 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 13407 if (*q != NUL) 13408 { 13409 if (remain == NULL) 13410 remain = vim_strsave(q - 1); 13411 else 13412 { 13413 cpy = concat_str(q - 1, remain); 13414 if (cpy != NULL) 13415 { 13416 vim_free(remain); 13417 remain = cpy; 13418 } 13419 } 13420 q[-1] = NUL; 13421 } 13422 13423 q = gettail(p); 13424 if (q > p && *q == NUL) 13425 { 13426 /* Ignore trailing path separator. */ 13427 q[-1] = NUL; 13428 q = gettail(p); 13429 } 13430 if (q > p && !mch_isFullName(buf)) 13431 { 13432 /* symlink is relative to directory of argument */ 13433 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 13434 if (cpy != NULL) 13435 { 13436 STRCPY(cpy, p); 13437 STRCPY(gettail(cpy), buf); 13438 vim_free(p); 13439 p = cpy; 13440 } 13441 } 13442 else 13443 { 13444 vim_free(p); 13445 p = vim_strsave(buf); 13446 } 13447 } 13448 13449 if (remain == NULL) 13450 break; 13451 13452 /* Append the first path component of "remain" to "p". */ 13453 q = getnextcomp(remain + 1); 13454 len = q - remain - (*q != NUL); 13455 cpy = vim_strnsave(p, STRLEN(p) + len); 13456 if (cpy != NULL) 13457 { 13458 STRNCAT(cpy, remain, len); 13459 vim_free(p); 13460 p = cpy; 13461 } 13462 /* Shorten "remain". */ 13463 if (*q != NUL) 13464 STRCPY(remain, q - 1); 13465 else 13466 { 13467 vim_free(remain); 13468 remain = NULL; 13469 } 13470 } 13471 13472 /* If the result is a relative path name, make it explicitly relative to 13473 * the current directory if and only if the argument had this form. */ 13474 if (!vim_ispathsep(*p)) 13475 { 13476 if (is_relative_to_current 13477 && *p != NUL 13478 && !(p[0] == '.' 13479 && (p[1] == NUL 13480 || vim_ispathsep(p[1]) 13481 || (p[1] == '.' 13482 && (p[2] == NUL 13483 || vim_ispathsep(p[2])))))) 13484 { 13485 /* Prepend "./". */ 13486 cpy = concat_str((char_u *)"./", p); 13487 if (cpy != NULL) 13488 { 13489 vim_free(p); 13490 p = cpy; 13491 } 13492 } 13493 else if (!is_relative_to_current) 13494 { 13495 /* Strip leading "./". */ 13496 q = p; 13497 while (q[0] == '.' && vim_ispathsep(q[1])) 13498 q += 2; 13499 if (q > p) 13500 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 13501 } 13502 } 13503 13504 /* Ensure that the result will have no trailing path separator 13505 * if the argument had none. But keep "/" or "//". */ 13506 if (!has_trailing_pathsep) 13507 { 13508 q = p + STRLEN(p); 13509 if (after_pathsep(p, q)) 13510 *gettail_sep(p) = NUL; 13511 } 13512 13513 rettv->vval.v_string = p; 13514 } 13515 # else 13516 rettv->vval.v_string = vim_strsave(p); 13517 # endif 13518 #endif 13519 13520 simplify_filename(rettv->vval.v_string); 13521 13522 #ifdef HAVE_READLINK 13523 fail: 13524 #endif 13525 rettv->v_type = VAR_STRING; 13526 } 13527 13528 /* 13529 * "reverse({list})" function 13530 */ 13531 static void 13532 f_reverse(argvars, rettv) 13533 typval_T *argvars; 13534 typval_T *rettv; 13535 { 13536 list_T *l; 13537 listitem_T *li, *ni; 13538 13539 rettv->vval.v_number = 0; 13540 if (argvars[0].v_type != VAR_LIST) 13541 EMSG2(_(e_listarg), "reverse()"); 13542 else if ((l = argvars[0].vval.v_list) != NULL 13543 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 13544 { 13545 li = l->lv_last; 13546 l->lv_first = l->lv_last = NULL; 13547 l->lv_len = 0; 13548 while (li != NULL) 13549 { 13550 ni = li->li_prev; 13551 list_append(l, li); 13552 li = ni; 13553 } 13554 rettv->vval.v_list = l; 13555 rettv->v_type = VAR_LIST; 13556 ++l->lv_refcount; 13557 } 13558 } 13559 13560 #define SP_NOMOVE 0x01 /* don't move cursor */ 13561 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 13562 #define SP_RETCOUNT 0x04 /* return matchcount */ 13563 #define SP_SETPCMARK 0x08 /* set previous context mark */ 13564 #define SP_START 0x10 /* accept match at start position */ 13565 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 13566 #define SP_END 0x40 /* leave cursor at end of match */ 13567 13568 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 13569 13570 /* 13571 * Get flags for a search function. 13572 * Possibly sets "p_ws". 13573 * Returns BACKWARD, FORWARD or zero (for an error). 13574 */ 13575 static int 13576 get_search_arg(varp, flagsp) 13577 typval_T *varp; 13578 int *flagsp; 13579 { 13580 int dir = FORWARD; 13581 char_u *flags; 13582 char_u nbuf[NUMBUFLEN]; 13583 int mask; 13584 13585 if (varp->v_type != VAR_UNKNOWN) 13586 { 13587 flags = get_tv_string_buf_chk(varp, nbuf); 13588 if (flags == NULL) 13589 return 0; /* type error; errmsg already given */ 13590 while (*flags != NUL) 13591 { 13592 switch (*flags) 13593 { 13594 case 'b': dir = BACKWARD; break; 13595 case 'w': p_ws = TRUE; break; 13596 case 'W': p_ws = FALSE; break; 13597 default: mask = 0; 13598 if (flagsp != NULL) 13599 switch (*flags) 13600 { 13601 case 'c': mask = SP_START; break; 13602 case 'e': mask = SP_END; break; 13603 case 'm': mask = SP_RETCOUNT; break; 13604 case 'n': mask = SP_NOMOVE; break; 13605 case 'p': mask = SP_SUBPAT; break; 13606 case 'r': mask = SP_REPEAT; break; 13607 case 's': mask = SP_SETPCMARK; break; 13608 } 13609 if (mask == 0) 13610 { 13611 EMSG2(_(e_invarg2), flags); 13612 dir = 0; 13613 } 13614 else 13615 *flagsp |= mask; 13616 } 13617 if (dir == 0) 13618 break; 13619 ++flags; 13620 } 13621 } 13622 return dir; 13623 } 13624 13625 /* 13626 * Shared by search() and searchpos() functions 13627 */ 13628 static int 13629 search_cmn(argvars, match_pos, flagsp) 13630 typval_T *argvars; 13631 pos_T *match_pos; 13632 int *flagsp; 13633 { 13634 int flags; 13635 char_u *pat; 13636 pos_T pos; 13637 pos_T save_cursor; 13638 int save_p_ws = p_ws; 13639 int dir; 13640 int retval = 0; /* default: FAIL */ 13641 long lnum_stop = 0; 13642 int options = SEARCH_KEEP; 13643 int subpatnum; 13644 13645 pat = get_tv_string(&argvars[0]); 13646 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 13647 if (dir == 0) 13648 goto theend; 13649 flags = *flagsp; 13650 if (flags & SP_START) 13651 options |= SEARCH_START; 13652 if (flags & SP_END) 13653 options |= SEARCH_END; 13654 13655 /* Optional extra argument: line number to stop searching. */ 13656 if (argvars[1].v_type != VAR_UNKNOWN 13657 && argvars[2].v_type != VAR_UNKNOWN) 13658 { 13659 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 13660 if (lnum_stop < 0) 13661 goto theend; 13662 } 13663 13664 /* 13665 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 13666 * Check to make sure only those flags are set. 13667 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13668 * flags cannot be set. Check for that condition also. 13669 */ 13670 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 13671 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13672 { 13673 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13674 goto theend; 13675 } 13676 13677 pos = save_cursor = curwin->w_cursor; 13678 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13679 options, RE_SEARCH, (linenr_T)lnum_stop); 13680 if (subpatnum != FAIL) 13681 { 13682 if (flags & SP_SUBPAT) 13683 retval = subpatnum; 13684 else 13685 retval = pos.lnum; 13686 if (flags & SP_SETPCMARK) 13687 setpcmark(); 13688 curwin->w_cursor = pos; 13689 if (match_pos != NULL) 13690 { 13691 /* Store the match cursor position */ 13692 match_pos->lnum = pos.lnum; 13693 match_pos->col = pos.col + 1; 13694 } 13695 /* "/$" will put the cursor after the end of the line, may need to 13696 * correct that here */ 13697 check_cursor(); 13698 } 13699 13700 /* If 'n' flag is used: restore cursor position. */ 13701 if (flags & SP_NOMOVE) 13702 curwin->w_cursor = save_cursor; 13703 theend: 13704 p_ws = save_p_ws; 13705 13706 return retval; 13707 } 13708 13709 /* 13710 * "search()" function 13711 */ 13712 static void 13713 f_search(argvars, rettv) 13714 typval_T *argvars; 13715 typval_T *rettv; 13716 { 13717 int flags = 0; 13718 13719 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 13720 } 13721 13722 /* 13723 * "searchdecl()" function 13724 */ 13725 static void 13726 f_searchdecl(argvars, rettv) 13727 typval_T *argvars; 13728 typval_T *rettv; 13729 { 13730 int locally = 1; 13731 int thisblock = 0; 13732 int error = FALSE; 13733 char_u *name; 13734 13735 rettv->vval.v_number = 1; /* default: FAIL */ 13736 13737 name = get_tv_string_chk(&argvars[0]); 13738 if (argvars[1].v_type != VAR_UNKNOWN) 13739 { 13740 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13741 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13742 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13743 } 13744 if (!error && name != NULL) 13745 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13746 locally, thisblock, SEARCH_KEEP) == FAIL; 13747 } 13748 13749 /* 13750 * Used by searchpair() and searchpairpos() 13751 */ 13752 static int 13753 searchpair_cmn(argvars, match_pos) 13754 typval_T *argvars; 13755 pos_T *match_pos; 13756 { 13757 char_u *spat, *mpat, *epat; 13758 char_u *skip; 13759 int save_p_ws = p_ws; 13760 int dir; 13761 int flags = 0; 13762 char_u nbuf1[NUMBUFLEN]; 13763 char_u nbuf2[NUMBUFLEN]; 13764 char_u nbuf3[NUMBUFLEN]; 13765 int retval = 0; /* default: FAIL */ 13766 long lnum_stop = 0; 13767 13768 /* Get the three pattern arguments: start, middle, end. */ 13769 spat = get_tv_string_chk(&argvars[0]); 13770 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13771 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13772 if (spat == NULL || mpat == NULL || epat == NULL) 13773 goto theend; /* type error */ 13774 13775 /* Handle the optional fourth argument: flags */ 13776 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13777 if (dir == 0) 13778 goto theend; 13779 13780 /* Don't accept SP_END or SP_SUBPAT. 13781 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13782 */ 13783 if ((flags & (SP_END | SP_SUBPAT)) != 0 13784 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13785 { 13786 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 13787 goto theend; 13788 } 13789 13790 /* Optional fifth argument: skip expression */ 13791 if (argvars[3].v_type == VAR_UNKNOWN 13792 || argvars[4].v_type == VAR_UNKNOWN) 13793 skip = (char_u *)""; 13794 else 13795 { 13796 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13797 if (argvars[5].v_type != VAR_UNKNOWN) 13798 { 13799 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 13800 if (lnum_stop < 0) 13801 goto theend; 13802 } 13803 } 13804 if (skip == NULL) 13805 goto theend; /* type error */ 13806 13807 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 13808 match_pos, lnum_stop); 13809 13810 theend: 13811 p_ws = save_p_ws; 13812 13813 return retval; 13814 } 13815 13816 /* 13817 * "searchpair()" function 13818 */ 13819 static void 13820 f_searchpair(argvars, rettv) 13821 typval_T *argvars; 13822 typval_T *rettv; 13823 { 13824 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 13825 } 13826 13827 /* 13828 * "searchpairpos()" function 13829 */ 13830 static void 13831 f_searchpairpos(argvars, rettv) 13832 typval_T *argvars; 13833 typval_T *rettv; 13834 { 13835 pos_T match_pos; 13836 int lnum = 0; 13837 int col = 0; 13838 13839 rettv->vval.v_number = 0; 13840 13841 if (rettv_list_alloc(rettv) == FAIL) 13842 return; 13843 13844 if (searchpair_cmn(argvars, &match_pos) > 0) 13845 { 13846 lnum = match_pos.lnum; 13847 col = match_pos.col; 13848 } 13849 13850 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 13851 list_append_number(rettv->vval.v_list, (varnumber_T)col); 13852 } 13853 13854 /* 13855 * Search for a start/middle/end thing. 13856 * Used by searchpair(), see its documentation for the details. 13857 * Returns 0 or -1 for no match, 13858 */ 13859 long 13860 do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, lnum_stop) 13861 char_u *spat; /* start pattern */ 13862 char_u *mpat; /* middle pattern */ 13863 char_u *epat; /* end pattern */ 13864 int dir; /* BACKWARD or FORWARD */ 13865 char_u *skip; /* skip expression */ 13866 int flags; /* SP_SETPCMARK and other SP_ values */ 13867 pos_T *match_pos; 13868 linenr_T lnum_stop; /* stop at this line if not zero */ 13869 { 13870 char_u *save_cpo; 13871 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13872 long retval = 0; 13873 pos_T pos; 13874 pos_T firstpos; 13875 pos_T foundpos; 13876 pos_T save_cursor; 13877 pos_T save_pos; 13878 int n; 13879 int r; 13880 int nest = 1; 13881 int err; 13882 int options = SEARCH_KEEP; 13883 13884 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13885 save_cpo = p_cpo; 13886 p_cpo = (char_u *)""; 13887 13888 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13889 * start/middle/end (pat3, for the top pair). */ 13890 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13891 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13892 if (pat2 == NULL || pat3 == NULL) 13893 goto theend; 13894 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13895 if (*mpat == NUL) 13896 STRCPY(pat3, pat2); 13897 else 13898 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13899 spat, epat, mpat); 13900 if (flags & SP_START) 13901 options |= SEARCH_START; 13902 13903 save_cursor = curwin->w_cursor; 13904 pos = curwin->w_cursor; 13905 clearpos(&firstpos); 13906 clearpos(&foundpos); 13907 pat = pat3; 13908 for (;;) 13909 { 13910 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13911 options, RE_SEARCH, lnum_stop); 13912 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13913 /* didn't find it or found the first match again: FAIL */ 13914 break; 13915 13916 if (firstpos.lnum == 0) 13917 firstpos = pos; 13918 if (equalpos(pos, foundpos)) 13919 { 13920 /* Found the same position again. Can happen with a pattern that 13921 * has "\zs" at the end and searching backwards. Advance one 13922 * character and try again. */ 13923 if (dir == BACKWARD) 13924 decl(&pos); 13925 else 13926 incl(&pos); 13927 } 13928 foundpos = pos; 13929 13930 /* If the skip pattern matches, ignore this match. */ 13931 if (*skip != NUL) 13932 { 13933 save_pos = curwin->w_cursor; 13934 curwin->w_cursor = pos; 13935 r = eval_to_bool(skip, &err, NULL, FALSE); 13936 curwin->w_cursor = save_pos; 13937 if (err) 13938 { 13939 /* Evaluating {skip} caused an error, break here. */ 13940 curwin->w_cursor = save_cursor; 13941 retval = -1; 13942 break; 13943 } 13944 if (r) 13945 continue; 13946 } 13947 13948 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13949 { 13950 /* Found end when searching backwards or start when searching 13951 * forward: nested pair. */ 13952 ++nest; 13953 pat = pat2; /* nested, don't search for middle */ 13954 } 13955 else 13956 { 13957 /* Found end when searching forward or start when searching 13958 * backward: end of (nested) pair; or found middle in outer pair. */ 13959 if (--nest == 1) 13960 pat = pat3; /* outer level, search for middle */ 13961 } 13962 13963 if (nest == 0) 13964 { 13965 /* Found the match: return matchcount or line number. */ 13966 if (flags & SP_RETCOUNT) 13967 ++retval; 13968 else 13969 retval = pos.lnum; 13970 if (flags & SP_SETPCMARK) 13971 setpcmark(); 13972 curwin->w_cursor = pos; 13973 if (!(flags & SP_REPEAT)) 13974 break; 13975 nest = 1; /* search for next unmatched */ 13976 } 13977 } 13978 13979 if (match_pos != NULL) 13980 { 13981 /* Store the match cursor position */ 13982 match_pos->lnum = curwin->w_cursor.lnum; 13983 match_pos->col = curwin->w_cursor.col + 1; 13984 } 13985 13986 /* If 'n' flag is used or search failed: restore cursor position. */ 13987 if ((flags & SP_NOMOVE) || retval == 0) 13988 curwin->w_cursor = save_cursor; 13989 13990 theend: 13991 vim_free(pat2); 13992 vim_free(pat3); 13993 p_cpo = save_cpo; 13994 13995 return retval; 13996 } 13997 13998 /* 13999 * "searchpos()" function 14000 */ 14001 static void 14002 f_searchpos(argvars, rettv) 14003 typval_T *argvars; 14004 typval_T *rettv; 14005 { 14006 pos_T match_pos; 14007 int lnum = 0; 14008 int col = 0; 14009 int n; 14010 int flags = 0; 14011 14012 rettv->vval.v_number = 0; 14013 14014 if (rettv_list_alloc(rettv) == FAIL) 14015 return; 14016 14017 n = search_cmn(argvars, &match_pos, &flags); 14018 if (n > 0) 14019 { 14020 lnum = match_pos.lnum; 14021 col = match_pos.col; 14022 } 14023 14024 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 14025 list_append_number(rettv->vval.v_list, (varnumber_T)col); 14026 if (flags & SP_SUBPAT) 14027 list_append_number(rettv->vval.v_list, (varnumber_T)n); 14028 } 14029 14030 14031 /*ARGSUSED*/ 14032 static void 14033 f_server2client(argvars, rettv) 14034 typval_T *argvars; 14035 typval_T *rettv; 14036 { 14037 #ifdef FEAT_CLIENTSERVER 14038 char_u buf[NUMBUFLEN]; 14039 char_u *server = get_tv_string_chk(&argvars[0]); 14040 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 14041 14042 rettv->vval.v_number = -1; 14043 if (server == NULL || reply == NULL) 14044 return; 14045 if (check_restricted() || check_secure()) 14046 return; 14047 # ifdef FEAT_X11 14048 if (check_connection() == FAIL) 14049 return; 14050 # endif 14051 14052 if (serverSendReply(server, reply) < 0) 14053 { 14054 EMSG(_("E258: Unable to send to client")); 14055 return; 14056 } 14057 rettv->vval.v_number = 0; 14058 #else 14059 rettv->vval.v_number = -1; 14060 #endif 14061 } 14062 14063 /*ARGSUSED*/ 14064 static void 14065 f_serverlist(argvars, rettv) 14066 typval_T *argvars; 14067 typval_T *rettv; 14068 { 14069 char_u *r = NULL; 14070 14071 #ifdef FEAT_CLIENTSERVER 14072 # ifdef WIN32 14073 r = serverGetVimNames(); 14074 # else 14075 make_connection(); 14076 if (X_DISPLAY != NULL) 14077 r = serverGetVimNames(X_DISPLAY); 14078 # endif 14079 #endif 14080 rettv->v_type = VAR_STRING; 14081 rettv->vval.v_string = r; 14082 } 14083 14084 /* 14085 * "setbufvar()" function 14086 */ 14087 /*ARGSUSED*/ 14088 static void 14089 f_setbufvar(argvars, rettv) 14090 typval_T *argvars; 14091 typval_T *rettv; 14092 { 14093 buf_T *buf; 14094 #ifdef FEAT_AUTOCMD 14095 aco_save_T aco; 14096 #else 14097 buf_T *save_curbuf; 14098 #endif 14099 char_u *varname, *bufvarname; 14100 typval_T *varp; 14101 char_u nbuf[NUMBUFLEN]; 14102 14103 rettv->vval.v_number = 0; 14104 14105 if (check_restricted() || check_secure()) 14106 return; 14107 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 14108 varname = get_tv_string_chk(&argvars[1]); 14109 buf = get_buf_tv(&argvars[0]); 14110 varp = &argvars[2]; 14111 14112 if (buf != NULL && varname != NULL && varp != NULL) 14113 { 14114 /* set curbuf to be our buf, temporarily */ 14115 #ifdef FEAT_AUTOCMD 14116 aucmd_prepbuf(&aco, buf); 14117 #else 14118 save_curbuf = curbuf; 14119 curbuf = buf; 14120 #endif 14121 14122 if (*varname == '&') 14123 { 14124 long numval; 14125 char_u *strval; 14126 int error = FALSE; 14127 14128 ++varname; 14129 numval = get_tv_number_chk(varp, &error); 14130 strval = get_tv_string_buf_chk(varp, nbuf); 14131 if (!error && strval != NULL) 14132 set_option_value(varname, numval, strval, OPT_LOCAL); 14133 } 14134 else 14135 { 14136 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 14137 if (bufvarname != NULL) 14138 { 14139 STRCPY(bufvarname, "b:"); 14140 STRCPY(bufvarname + 2, varname); 14141 set_var(bufvarname, varp, TRUE); 14142 vim_free(bufvarname); 14143 } 14144 } 14145 14146 /* reset notion of buffer */ 14147 #ifdef FEAT_AUTOCMD 14148 aucmd_restbuf(&aco); 14149 #else 14150 curbuf = save_curbuf; 14151 #endif 14152 } 14153 } 14154 14155 /* 14156 * "setcmdpos()" function 14157 */ 14158 static void 14159 f_setcmdpos(argvars, rettv) 14160 typval_T *argvars; 14161 typval_T *rettv; 14162 { 14163 int pos = (int)get_tv_number(&argvars[0]) - 1; 14164 14165 if (pos >= 0) 14166 rettv->vval.v_number = set_cmdline_pos(pos); 14167 } 14168 14169 /* 14170 * "setline()" function 14171 */ 14172 static void 14173 f_setline(argvars, rettv) 14174 typval_T *argvars; 14175 typval_T *rettv; 14176 { 14177 linenr_T lnum; 14178 char_u *line = NULL; 14179 list_T *l = NULL; 14180 listitem_T *li = NULL; 14181 long added = 0; 14182 linenr_T lcount = curbuf->b_ml.ml_line_count; 14183 14184 lnum = get_tv_lnum(&argvars[0]); 14185 if (argvars[1].v_type == VAR_LIST) 14186 { 14187 l = argvars[1].vval.v_list; 14188 li = l->lv_first; 14189 } 14190 else 14191 line = get_tv_string_chk(&argvars[1]); 14192 14193 rettv->vval.v_number = 0; /* OK */ 14194 for (;;) 14195 { 14196 if (l != NULL) 14197 { 14198 /* list argument, get next string */ 14199 if (li == NULL) 14200 break; 14201 line = get_tv_string_chk(&li->li_tv); 14202 li = li->li_next; 14203 } 14204 14205 rettv->vval.v_number = 1; /* FAIL */ 14206 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 14207 break; 14208 if (lnum <= curbuf->b_ml.ml_line_count) 14209 { 14210 /* existing line, replace it */ 14211 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 14212 { 14213 changed_bytes(lnum, 0); 14214 check_cursor_col(); 14215 rettv->vval.v_number = 0; /* OK */ 14216 } 14217 } 14218 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 14219 { 14220 /* lnum is one past the last line, append the line */ 14221 ++added; 14222 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 14223 rettv->vval.v_number = 0; /* OK */ 14224 } 14225 14226 if (l == NULL) /* only one string argument */ 14227 break; 14228 ++lnum; 14229 } 14230 14231 if (added > 0) 14232 appended_lines_mark(lcount, added); 14233 } 14234 14235 /* 14236 * Used by "setqflist()" and "setloclist()" functions 14237 */ 14238 /*ARGSUSED*/ 14239 static void 14240 set_qf_ll_list(wp, list_arg, action_arg, rettv) 14241 win_T *wp; 14242 typval_T *list_arg; 14243 typval_T *action_arg; 14244 typval_T *rettv; 14245 { 14246 #ifdef FEAT_QUICKFIX 14247 char_u *act; 14248 int action = ' '; 14249 #endif 14250 14251 rettv->vval.v_number = -1; 14252 14253 #ifdef FEAT_QUICKFIX 14254 if (list_arg->v_type != VAR_LIST) 14255 EMSG(_(e_listreq)); 14256 else 14257 { 14258 list_T *l = list_arg->vval.v_list; 14259 14260 if (action_arg->v_type == VAR_STRING) 14261 { 14262 act = get_tv_string_chk(action_arg); 14263 if (act == NULL) 14264 return; /* type error; errmsg already given */ 14265 if (*act == 'a' || *act == 'r') 14266 action = *act; 14267 } 14268 14269 if (l != NULL && set_errorlist(wp, l, action) == OK) 14270 rettv->vval.v_number = 0; 14271 } 14272 #endif 14273 } 14274 14275 /* 14276 * "setloclist()" function 14277 */ 14278 /*ARGSUSED*/ 14279 static void 14280 f_setloclist(argvars, rettv) 14281 typval_T *argvars; 14282 typval_T *rettv; 14283 { 14284 win_T *win; 14285 14286 rettv->vval.v_number = -1; 14287 14288 win = find_win_by_nr(&argvars[0], NULL); 14289 if (win != NULL) 14290 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 14291 } 14292 14293 /* 14294 * "setpos()" function 14295 */ 14296 /*ARGSUSED*/ 14297 static void 14298 f_setpos(argvars, rettv) 14299 typval_T *argvars; 14300 typval_T *rettv; 14301 { 14302 pos_T pos; 14303 int fnum; 14304 char_u *name; 14305 14306 name = get_tv_string_chk(argvars); 14307 if (name != NULL) 14308 { 14309 if (list2fpos(&argvars[1], &pos, &fnum) == OK) 14310 { 14311 --pos.col; 14312 if (name[0] == '.') /* cursor */ 14313 { 14314 if (fnum == curbuf->b_fnum) 14315 { 14316 curwin->w_cursor = pos; 14317 check_cursor(); 14318 } 14319 else 14320 EMSG(_(e_invarg)); 14321 } 14322 else if (name[0] == '\'') /* mark */ 14323 (void)setmark_pos(name[1], &pos, fnum); 14324 else 14325 EMSG(_(e_invarg)); 14326 } 14327 } 14328 } 14329 14330 /* 14331 * "setqflist()" function 14332 */ 14333 /*ARGSUSED*/ 14334 static void 14335 f_setqflist(argvars, rettv) 14336 typval_T *argvars; 14337 typval_T *rettv; 14338 { 14339 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 14340 } 14341 14342 /* 14343 * "setreg()" function 14344 */ 14345 static void 14346 f_setreg(argvars, rettv) 14347 typval_T *argvars; 14348 typval_T *rettv; 14349 { 14350 int regname; 14351 char_u *strregname; 14352 char_u *stropt; 14353 char_u *strval; 14354 int append; 14355 char_u yank_type; 14356 long block_len; 14357 14358 block_len = -1; 14359 yank_type = MAUTO; 14360 append = FALSE; 14361 14362 strregname = get_tv_string_chk(argvars); 14363 rettv->vval.v_number = 1; /* FAIL is default */ 14364 14365 if (strregname == NULL) 14366 return; /* type error; errmsg already given */ 14367 regname = *strregname; 14368 if (regname == 0 || regname == '@') 14369 regname = '"'; 14370 else if (regname == '=') 14371 return; 14372 14373 if (argvars[2].v_type != VAR_UNKNOWN) 14374 { 14375 stropt = get_tv_string_chk(&argvars[2]); 14376 if (stropt == NULL) 14377 return; /* type error */ 14378 for (; *stropt != NUL; ++stropt) 14379 switch (*stropt) 14380 { 14381 case 'a': case 'A': /* append */ 14382 append = TRUE; 14383 break; 14384 case 'v': case 'c': /* character-wise selection */ 14385 yank_type = MCHAR; 14386 break; 14387 case 'V': case 'l': /* line-wise selection */ 14388 yank_type = MLINE; 14389 break; 14390 #ifdef FEAT_VISUAL 14391 case 'b': case Ctrl_V: /* block-wise selection */ 14392 yank_type = MBLOCK; 14393 if (VIM_ISDIGIT(stropt[1])) 14394 { 14395 ++stropt; 14396 block_len = getdigits(&stropt) - 1; 14397 --stropt; 14398 } 14399 break; 14400 #endif 14401 } 14402 } 14403 14404 strval = get_tv_string_chk(&argvars[1]); 14405 if (strval != NULL) 14406 write_reg_contents_ex(regname, strval, -1, 14407 append, yank_type, block_len); 14408 rettv->vval.v_number = 0; 14409 } 14410 14411 /* 14412 * "settabwinvar()" function 14413 */ 14414 static void 14415 f_settabwinvar(argvars, rettv) 14416 typval_T *argvars; 14417 typval_T *rettv; 14418 { 14419 setwinvar(argvars, rettv, 1); 14420 } 14421 14422 /* 14423 * "setwinvar()" function 14424 */ 14425 static void 14426 f_setwinvar(argvars, rettv) 14427 typval_T *argvars; 14428 typval_T *rettv; 14429 { 14430 setwinvar(argvars, rettv, 0); 14431 } 14432 14433 /* 14434 * "setwinvar()" and "settabwinvar()" functions 14435 */ 14436 static void 14437 setwinvar(argvars, rettv, off) 14438 typval_T *argvars; 14439 typval_T *rettv; 14440 int off; 14441 { 14442 win_T *win; 14443 #ifdef FEAT_WINDOWS 14444 win_T *save_curwin; 14445 tabpage_T *save_curtab; 14446 #endif 14447 char_u *varname, *winvarname; 14448 typval_T *varp; 14449 char_u nbuf[NUMBUFLEN]; 14450 tabpage_T *tp; 14451 14452 rettv->vval.v_number = 0; 14453 14454 if (check_restricted() || check_secure()) 14455 return; 14456 14457 #ifdef FEAT_WINDOWS 14458 if (off == 1) 14459 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 14460 else 14461 tp = curtab; 14462 #endif 14463 win = find_win_by_nr(&argvars[off], tp); 14464 varname = get_tv_string_chk(&argvars[off + 1]); 14465 varp = &argvars[off + 2]; 14466 14467 if (win != NULL && varname != NULL && varp != NULL) 14468 { 14469 #ifdef FEAT_WINDOWS 14470 /* set curwin to be our win, temporarily */ 14471 save_curwin = curwin; 14472 save_curtab = curtab; 14473 goto_tabpage_tp(tp); 14474 if (!win_valid(win)) 14475 return; 14476 curwin = win; 14477 curbuf = curwin->w_buffer; 14478 #endif 14479 14480 if (*varname == '&') 14481 { 14482 long numval; 14483 char_u *strval; 14484 int error = FALSE; 14485 14486 ++varname; 14487 numval = get_tv_number_chk(varp, &error); 14488 strval = get_tv_string_buf_chk(varp, nbuf); 14489 if (!error && strval != NULL) 14490 set_option_value(varname, numval, strval, OPT_LOCAL); 14491 } 14492 else 14493 { 14494 winvarname = alloc((unsigned)STRLEN(varname) + 3); 14495 if (winvarname != NULL) 14496 { 14497 STRCPY(winvarname, "w:"); 14498 STRCPY(winvarname + 2, varname); 14499 set_var(winvarname, varp, TRUE); 14500 vim_free(winvarname); 14501 } 14502 } 14503 14504 #ifdef FEAT_WINDOWS 14505 /* Restore current tabpage and window, if still valid (autocomands can 14506 * make them invalid). */ 14507 if (valid_tabpage(save_curtab)) 14508 goto_tabpage_tp(save_curtab); 14509 if (win_valid(save_curwin)) 14510 { 14511 curwin = save_curwin; 14512 curbuf = curwin->w_buffer; 14513 } 14514 #endif 14515 } 14516 } 14517 14518 /* 14519 * "simplify()" function 14520 */ 14521 static void 14522 f_simplify(argvars, rettv) 14523 typval_T *argvars; 14524 typval_T *rettv; 14525 { 14526 char_u *p; 14527 14528 p = get_tv_string(&argvars[0]); 14529 rettv->vval.v_string = vim_strsave(p); 14530 simplify_filename(rettv->vval.v_string); /* simplify in place */ 14531 rettv->v_type = VAR_STRING; 14532 } 14533 14534 static int 14535 #ifdef __BORLANDC__ 14536 _RTLENTRYF 14537 #endif 14538 item_compare __ARGS((const void *s1, const void *s2)); 14539 static int 14540 #ifdef __BORLANDC__ 14541 _RTLENTRYF 14542 #endif 14543 item_compare2 __ARGS((const void *s1, const void *s2)); 14544 14545 static int item_compare_ic; 14546 static char_u *item_compare_func; 14547 static int item_compare_func_err; 14548 #define ITEM_COMPARE_FAIL 999 14549 14550 /* 14551 * Compare functions for f_sort() below. 14552 */ 14553 static int 14554 #ifdef __BORLANDC__ 14555 _RTLENTRYF 14556 #endif 14557 item_compare(s1, s2) 14558 const void *s1; 14559 const void *s2; 14560 { 14561 char_u *p1, *p2; 14562 char_u *tofree1, *tofree2; 14563 int res; 14564 char_u numbuf1[NUMBUFLEN]; 14565 char_u numbuf2[NUMBUFLEN]; 14566 14567 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0); 14568 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0); 14569 if (item_compare_ic) 14570 res = STRICMP(p1, p2); 14571 else 14572 res = STRCMP(p1, p2); 14573 vim_free(tofree1); 14574 vim_free(tofree2); 14575 return res; 14576 } 14577 14578 static int 14579 #ifdef __BORLANDC__ 14580 _RTLENTRYF 14581 #endif 14582 item_compare2(s1, s2) 14583 const void *s1; 14584 const void *s2; 14585 { 14586 int res; 14587 typval_T rettv; 14588 typval_T argv[2]; 14589 int dummy; 14590 14591 /* shortcut after failure in previous call; compare all items equal */ 14592 if (item_compare_func_err) 14593 return 0; 14594 14595 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 14596 * in the copy without changing the original list items. */ 14597 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 14598 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 14599 14600 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 14601 res = call_func(item_compare_func, (int)STRLEN(item_compare_func), 14602 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 14603 clear_tv(&argv[0]); 14604 clear_tv(&argv[1]); 14605 14606 if (res == FAIL) 14607 res = ITEM_COMPARE_FAIL; 14608 else 14609 /* return value has wrong type */ 14610 res = get_tv_number_chk(&rettv, &item_compare_func_err); 14611 if (item_compare_func_err) 14612 res = ITEM_COMPARE_FAIL; 14613 clear_tv(&rettv); 14614 return res; 14615 } 14616 14617 /* 14618 * "sort({list})" function 14619 */ 14620 static void 14621 f_sort(argvars, rettv) 14622 typval_T *argvars; 14623 typval_T *rettv; 14624 { 14625 list_T *l; 14626 listitem_T *li; 14627 listitem_T **ptrs; 14628 long len; 14629 long i; 14630 14631 rettv->vval.v_number = 0; 14632 if (argvars[0].v_type != VAR_LIST) 14633 EMSG2(_(e_listarg), "sort()"); 14634 else 14635 { 14636 l = argvars[0].vval.v_list; 14637 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 14638 return; 14639 rettv->vval.v_list = l; 14640 rettv->v_type = VAR_LIST; 14641 ++l->lv_refcount; 14642 14643 len = list_len(l); 14644 if (len <= 1) 14645 return; /* short list sorts pretty quickly */ 14646 14647 item_compare_ic = FALSE; 14648 item_compare_func = NULL; 14649 if (argvars[1].v_type != VAR_UNKNOWN) 14650 { 14651 if (argvars[1].v_type == VAR_FUNC) 14652 item_compare_func = argvars[1].vval.v_string; 14653 else 14654 { 14655 int error = FALSE; 14656 14657 i = get_tv_number_chk(&argvars[1], &error); 14658 if (error) 14659 return; /* type error; errmsg already given */ 14660 if (i == 1) 14661 item_compare_ic = TRUE; 14662 else 14663 item_compare_func = get_tv_string(&argvars[1]); 14664 } 14665 } 14666 14667 /* Make an array with each entry pointing to an item in the List. */ 14668 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 14669 if (ptrs == NULL) 14670 return; 14671 i = 0; 14672 for (li = l->lv_first; li != NULL; li = li->li_next) 14673 ptrs[i++] = li; 14674 14675 item_compare_func_err = FALSE; 14676 /* test the compare function */ 14677 if (item_compare_func != NULL 14678 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 14679 == ITEM_COMPARE_FAIL) 14680 EMSG(_("E702: Sort compare function failed")); 14681 else 14682 { 14683 /* Sort the array with item pointers. */ 14684 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 14685 item_compare_func == NULL ? item_compare : item_compare2); 14686 14687 if (!item_compare_func_err) 14688 { 14689 /* Clear the List and append the items in the sorted order. */ 14690 l->lv_first = l->lv_last = NULL; 14691 l->lv_len = 0; 14692 for (i = 0; i < len; ++i) 14693 list_append(l, ptrs[i]); 14694 } 14695 } 14696 14697 vim_free(ptrs); 14698 } 14699 } 14700 14701 /* 14702 * "soundfold({word})" function 14703 */ 14704 static void 14705 f_soundfold(argvars, rettv) 14706 typval_T *argvars; 14707 typval_T *rettv; 14708 { 14709 char_u *s; 14710 14711 rettv->v_type = VAR_STRING; 14712 s = get_tv_string(&argvars[0]); 14713 #ifdef FEAT_SPELL 14714 rettv->vval.v_string = eval_soundfold(s); 14715 #else 14716 rettv->vval.v_string = vim_strsave(s); 14717 #endif 14718 } 14719 14720 /* 14721 * "spellbadword()" function 14722 */ 14723 /* ARGSUSED */ 14724 static void 14725 f_spellbadword(argvars, rettv) 14726 typval_T *argvars; 14727 typval_T *rettv; 14728 { 14729 char_u *word = (char_u *)""; 14730 hlf_T attr = HLF_COUNT; 14731 int len = 0; 14732 14733 if (rettv_list_alloc(rettv) == FAIL) 14734 return; 14735 14736 #ifdef FEAT_SPELL 14737 if (argvars[0].v_type == VAR_UNKNOWN) 14738 { 14739 /* Find the start and length of the badly spelled word. */ 14740 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 14741 if (len != 0) 14742 word = ml_get_cursor(); 14743 } 14744 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 14745 { 14746 char_u *str = get_tv_string_chk(&argvars[0]); 14747 int capcol = -1; 14748 14749 if (str != NULL) 14750 { 14751 /* Check the argument for spelling. */ 14752 while (*str != NUL) 14753 { 14754 len = spell_check(curwin, str, &attr, &capcol, FALSE); 14755 if (attr != HLF_COUNT) 14756 { 14757 word = str; 14758 break; 14759 } 14760 str += len; 14761 } 14762 } 14763 } 14764 #endif 14765 14766 list_append_string(rettv->vval.v_list, word, len); 14767 list_append_string(rettv->vval.v_list, (char_u *)( 14768 attr == HLF_SPB ? "bad" : 14769 attr == HLF_SPR ? "rare" : 14770 attr == HLF_SPL ? "local" : 14771 attr == HLF_SPC ? "caps" : 14772 ""), -1); 14773 } 14774 14775 /* 14776 * "spellsuggest()" function 14777 */ 14778 /*ARGSUSED*/ 14779 static void 14780 f_spellsuggest(argvars, rettv) 14781 typval_T *argvars; 14782 typval_T *rettv; 14783 { 14784 #ifdef FEAT_SPELL 14785 char_u *str; 14786 int typeerr = FALSE; 14787 int maxcount; 14788 garray_T ga; 14789 int i; 14790 listitem_T *li; 14791 int need_capital = FALSE; 14792 #endif 14793 14794 if (rettv_list_alloc(rettv) == FAIL) 14795 return; 14796 14797 #ifdef FEAT_SPELL 14798 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 14799 { 14800 str = get_tv_string(&argvars[0]); 14801 if (argvars[1].v_type != VAR_UNKNOWN) 14802 { 14803 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 14804 if (maxcount <= 0) 14805 return; 14806 if (argvars[2].v_type != VAR_UNKNOWN) 14807 { 14808 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 14809 if (typeerr) 14810 return; 14811 } 14812 } 14813 else 14814 maxcount = 25; 14815 14816 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 14817 14818 for (i = 0; i < ga.ga_len; ++i) 14819 { 14820 str = ((char_u **)ga.ga_data)[i]; 14821 14822 li = listitem_alloc(); 14823 if (li == NULL) 14824 vim_free(str); 14825 else 14826 { 14827 li->li_tv.v_type = VAR_STRING; 14828 li->li_tv.v_lock = 0; 14829 li->li_tv.vval.v_string = str; 14830 list_append(rettv->vval.v_list, li); 14831 } 14832 } 14833 ga_clear(&ga); 14834 } 14835 #endif 14836 } 14837 14838 static void 14839 f_split(argvars, rettv) 14840 typval_T *argvars; 14841 typval_T *rettv; 14842 { 14843 char_u *str; 14844 char_u *end; 14845 char_u *pat = NULL; 14846 regmatch_T regmatch; 14847 char_u patbuf[NUMBUFLEN]; 14848 char_u *save_cpo; 14849 int match; 14850 colnr_T col = 0; 14851 int keepempty = FALSE; 14852 int typeerr = FALSE; 14853 14854 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14855 save_cpo = p_cpo; 14856 p_cpo = (char_u *)""; 14857 14858 str = get_tv_string(&argvars[0]); 14859 if (argvars[1].v_type != VAR_UNKNOWN) 14860 { 14861 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14862 if (pat == NULL) 14863 typeerr = TRUE; 14864 if (argvars[2].v_type != VAR_UNKNOWN) 14865 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 14866 } 14867 if (pat == NULL || *pat == NUL) 14868 pat = (char_u *)"[\\x01- ]\\+"; 14869 14870 if (rettv_list_alloc(rettv) == FAIL) 14871 return; 14872 if (typeerr) 14873 return; 14874 14875 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14876 if (regmatch.regprog != NULL) 14877 { 14878 regmatch.rm_ic = FALSE; 14879 while (*str != NUL || keepempty) 14880 { 14881 if (*str == NUL) 14882 match = FALSE; /* empty item at the end */ 14883 else 14884 match = vim_regexec_nl(®match, str, col); 14885 if (match) 14886 end = regmatch.startp[0]; 14887 else 14888 end = str + STRLEN(str); 14889 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 14890 && *str != NUL && match && end < regmatch.endp[0])) 14891 { 14892 if (list_append_string(rettv->vval.v_list, str, 14893 (int)(end - str)) == FAIL) 14894 break; 14895 } 14896 if (!match) 14897 break; 14898 /* Advance to just after the match. */ 14899 if (regmatch.endp[0] > str) 14900 col = 0; 14901 else 14902 { 14903 /* Don't get stuck at the same match. */ 14904 #ifdef FEAT_MBYTE 14905 col = (*mb_ptr2len)(regmatch.endp[0]); 14906 #else 14907 col = 1; 14908 #endif 14909 } 14910 str = regmatch.endp[0]; 14911 } 14912 14913 vim_free(regmatch.regprog); 14914 } 14915 14916 p_cpo = save_cpo; 14917 } 14918 14919 /* 14920 * "str2nr()" function 14921 */ 14922 static void 14923 f_str2nr(argvars, rettv) 14924 typval_T *argvars; 14925 typval_T *rettv; 14926 { 14927 int base = 10; 14928 char_u *p; 14929 long n; 14930 14931 if (argvars[1].v_type != VAR_UNKNOWN) 14932 { 14933 base = get_tv_number(&argvars[1]); 14934 if (base != 8 && base != 10 && base != 16) 14935 { 14936 EMSG(_(e_invarg)); 14937 return; 14938 } 14939 } 14940 14941 p = skipwhite(get_tv_string(&argvars[0])); 14942 vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL); 14943 rettv->vval.v_number = n; 14944 } 14945 14946 #ifdef HAVE_STRFTIME 14947 /* 14948 * "strftime({format}[, {time}])" function 14949 */ 14950 static void 14951 f_strftime(argvars, rettv) 14952 typval_T *argvars; 14953 typval_T *rettv; 14954 { 14955 char_u result_buf[256]; 14956 struct tm *curtime; 14957 time_t seconds; 14958 char_u *p; 14959 14960 rettv->v_type = VAR_STRING; 14961 14962 p = get_tv_string(&argvars[0]); 14963 if (argvars[1].v_type == VAR_UNKNOWN) 14964 seconds = time(NULL); 14965 else 14966 seconds = (time_t)get_tv_number(&argvars[1]); 14967 curtime = localtime(&seconds); 14968 /* MSVC returns NULL for an invalid value of seconds. */ 14969 if (curtime == NULL) 14970 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 14971 else 14972 { 14973 # ifdef FEAT_MBYTE 14974 vimconv_T conv; 14975 char_u *enc; 14976 14977 conv.vc_type = CONV_NONE; 14978 enc = enc_locale(); 14979 convert_setup(&conv, p_enc, enc); 14980 if (conv.vc_type != CONV_NONE) 14981 p = string_convert(&conv, p, NULL); 14982 # endif 14983 if (p != NULL) 14984 (void)strftime((char *)result_buf, sizeof(result_buf), 14985 (char *)p, curtime); 14986 else 14987 result_buf[0] = NUL; 14988 14989 # ifdef FEAT_MBYTE 14990 if (conv.vc_type != CONV_NONE) 14991 vim_free(p); 14992 convert_setup(&conv, enc, p_enc); 14993 if (conv.vc_type != CONV_NONE) 14994 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 14995 else 14996 # endif 14997 rettv->vval.v_string = vim_strsave(result_buf); 14998 14999 # ifdef FEAT_MBYTE 15000 /* Release conversion descriptors */ 15001 convert_setup(&conv, NULL, NULL); 15002 vim_free(enc); 15003 # endif 15004 } 15005 } 15006 #endif 15007 15008 /* 15009 * "stridx()" function 15010 */ 15011 static void 15012 f_stridx(argvars, rettv) 15013 typval_T *argvars; 15014 typval_T *rettv; 15015 { 15016 char_u buf[NUMBUFLEN]; 15017 char_u *needle; 15018 char_u *haystack; 15019 char_u *save_haystack; 15020 char_u *pos; 15021 int start_idx; 15022 15023 needle = get_tv_string_chk(&argvars[1]); 15024 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 15025 rettv->vval.v_number = -1; 15026 if (needle == NULL || haystack == NULL) 15027 return; /* type error; errmsg already given */ 15028 15029 if (argvars[2].v_type != VAR_UNKNOWN) 15030 { 15031 int error = FALSE; 15032 15033 start_idx = get_tv_number_chk(&argvars[2], &error); 15034 if (error || start_idx >= (int)STRLEN(haystack)) 15035 return; 15036 if (start_idx >= 0) 15037 haystack += start_idx; 15038 } 15039 15040 pos = (char_u *)strstr((char *)haystack, (char *)needle); 15041 if (pos != NULL) 15042 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 15043 } 15044 15045 /* 15046 * "string()" function 15047 */ 15048 static void 15049 f_string(argvars, rettv) 15050 typval_T *argvars; 15051 typval_T *rettv; 15052 { 15053 char_u *tofree; 15054 char_u numbuf[NUMBUFLEN]; 15055 15056 rettv->v_type = VAR_STRING; 15057 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 15058 if (tofree == NULL) 15059 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 15060 } 15061 15062 /* 15063 * "strlen()" function 15064 */ 15065 static void 15066 f_strlen(argvars, rettv) 15067 typval_T *argvars; 15068 typval_T *rettv; 15069 { 15070 rettv->vval.v_number = (varnumber_T)(STRLEN( 15071 get_tv_string(&argvars[0]))); 15072 } 15073 15074 /* 15075 * "strpart()" function 15076 */ 15077 static void 15078 f_strpart(argvars, rettv) 15079 typval_T *argvars; 15080 typval_T *rettv; 15081 { 15082 char_u *p; 15083 int n; 15084 int len; 15085 int slen; 15086 int error = FALSE; 15087 15088 p = get_tv_string(&argvars[0]); 15089 slen = (int)STRLEN(p); 15090 15091 n = get_tv_number_chk(&argvars[1], &error); 15092 if (error) 15093 len = 0; 15094 else if (argvars[2].v_type != VAR_UNKNOWN) 15095 len = get_tv_number(&argvars[2]); 15096 else 15097 len = slen - n; /* default len: all bytes that are available. */ 15098 15099 /* 15100 * Only return the overlap between the specified part and the actual 15101 * string. 15102 */ 15103 if (n < 0) 15104 { 15105 len += n; 15106 n = 0; 15107 } 15108 else if (n > slen) 15109 n = slen; 15110 if (len < 0) 15111 len = 0; 15112 else if (n + len > slen) 15113 len = slen - n; 15114 15115 rettv->v_type = VAR_STRING; 15116 rettv->vval.v_string = vim_strnsave(p + n, len); 15117 } 15118 15119 /* 15120 * "strridx()" function 15121 */ 15122 static void 15123 f_strridx(argvars, rettv) 15124 typval_T *argvars; 15125 typval_T *rettv; 15126 { 15127 char_u buf[NUMBUFLEN]; 15128 char_u *needle; 15129 char_u *haystack; 15130 char_u *rest; 15131 char_u *lastmatch = NULL; 15132 int haystack_len, end_idx; 15133 15134 needle = get_tv_string_chk(&argvars[1]); 15135 haystack = get_tv_string_buf_chk(&argvars[0], buf); 15136 haystack_len = (int)STRLEN(haystack); 15137 15138 rettv->vval.v_number = -1; 15139 if (needle == NULL || haystack == NULL) 15140 return; /* type error; errmsg already given */ 15141 if (argvars[2].v_type != VAR_UNKNOWN) 15142 { 15143 /* Third argument: upper limit for index */ 15144 end_idx = get_tv_number_chk(&argvars[2], NULL); 15145 if (end_idx < 0) 15146 return; /* can never find a match */ 15147 } 15148 else 15149 end_idx = haystack_len; 15150 15151 if (*needle == NUL) 15152 { 15153 /* Empty string matches past the end. */ 15154 lastmatch = haystack + end_idx; 15155 } 15156 else 15157 { 15158 for (rest = haystack; *rest != '\0'; ++rest) 15159 { 15160 rest = (char_u *)strstr((char *)rest, (char *)needle); 15161 if (rest == NULL || rest > haystack + end_idx) 15162 break; 15163 lastmatch = rest; 15164 } 15165 } 15166 15167 if (lastmatch == NULL) 15168 rettv->vval.v_number = -1; 15169 else 15170 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 15171 } 15172 15173 /* 15174 * "strtrans()" function 15175 */ 15176 static void 15177 f_strtrans(argvars, rettv) 15178 typval_T *argvars; 15179 typval_T *rettv; 15180 { 15181 rettv->v_type = VAR_STRING; 15182 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 15183 } 15184 15185 /* 15186 * "submatch()" function 15187 */ 15188 static void 15189 f_submatch(argvars, rettv) 15190 typval_T *argvars; 15191 typval_T *rettv; 15192 { 15193 rettv->v_type = VAR_STRING; 15194 rettv->vval.v_string = 15195 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 15196 } 15197 15198 /* 15199 * "substitute()" function 15200 */ 15201 static void 15202 f_substitute(argvars, rettv) 15203 typval_T *argvars; 15204 typval_T *rettv; 15205 { 15206 char_u patbuf[NUMBUFLEN]; 15207 char_u subbuf[NUMBUFLEN]; 15208 char_u flagsbuf[NUMBUFLEN]; 15209 15210 char_u *str = get_tv_string_chk(&argvars[0]); 15211 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 15212 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 15213 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 15214 15215 rettv->v_type = VAR_STRING; 15216 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 15217 rettv->vval.v_string = NULL; 15218 else 15219 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 15220 } 15221 15222 /* 15223 * "synID(lnum, col, trans)" function 15224 */ 15225 /*ARGSUSED*/ 15226 static void 15227 f_synID(argvars, rettv) 15228 typval_T *argvars; 15229 typval_T *rettv; 15230 { 15231 int id = 0; 15232 #ifdef FEAT_SYN_HL 15233 long lnum; 15234 long col; 15235 int trans; 15236 int transerr = FALSE; 15237 15238 lnum = get_tv_lnum(argvars); /* -1 on type error */ 15239 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 15240 trans = get_tv_number_chk(&argvars[2], &transerr); 15241 15242 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 15243 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 15244 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 15245 #endif 15246 15247 rettv->vval.v_number = id; 15248 } 15249 15250 /* 15251 * "synIDattr(id, what [, mode])" function 15252 */ 15253 /*ARGSUSED*/ 15254 static void 15255 f_synIDattr(argvars, rettv) 15256 typval_T *argvars; 15257 typval_T *rettv; 15258 { 15259 char_u *p = NULL; 15260 #ifdef FEAT_SYN_HL 15261 int id; 15262 char_u *what; 15263 char_u *mode; 15264 char_u modebuf[NUMBUFLEN]; 15265 int modec; 15266 15267 id = get_tv_number(&argvars[0]); 15268 what = get_tv_string(&argvars[1]); 15269 if (argvars[2].v_type != VAR_UNKNOWN) 15270 { 15271 mode = get_tv_string_buf(&argvars[2], modebuf); 15272 modec = TOLOWER_ASC(mode[0]); 15273 if (modec != 't' && modec != 'c' 15274 #ifdef FEAT_GUI 15275 && modec != 'g' 15276 #endif 15277 ) 15278 modec = 0; /* replace invalid with current */ 15279 } 15280 else 15281 { 15282 #ifdef FEAT_GUI 15283 if (gui.in_use) 15284 modec = 'g'; 15285 else 15286 #endif 15287 if (t_colors > 1) 15288 modec = 'c'; 15289 else 15290 modec = 't'; 15291 } 15292 15293 15294 switch (TOLOWER_ASC(what[0])) 15295 { 15296 case 'b': 15297 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 15298 p = highlight_color(id, what, modec); 15299 else /* bold */ 15300 p = highlight_has_attr(id, HL_BOLD, modec); 15301 break; 15302 15303 case 'f': /* fg[#] */ 15304 p = highlight_color(id, what, modec); 15305 break; 15306 15307 case 'i': 15308 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 15309 p = highlight_has_attr(id, HL_INVERSE, modec); 15310 else /* italic */ 15311 p = highlight_has_attr(id, HL_ITALIC, modec); 15312 break; 15313 15314 case 'n': /* name */ 15315 p = get_highlight_name(NULL, id - 1); 15316 break; 15317 15318 case 'r': /* reverse */ 15319 p = highlight_has_attr(id, HL_INVERSE, modec); 15320 break; 15321 15322 case 's': /* standout */ 15323 p = highlight_has_attr(id, HL_STANDOUT, modec); 15324 break; 15325 15326 case 'u': 15327 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 15328 /* underline */ 15329 p = highlight_has_attr(id, HL_UNDERLINE, modec); 15330 else 15331 /* undercurl */ 15332 p = highlight_has_attr(id, HL_UNDERCURL, modec); 15333 break; 15334 } 15335 15336 if (p != NULL) 15337 p = vim_strsave(p); 15338 #endif 15339 rettv->v_type = VAR_STRING; 15340 rettv->vval.v_string = p; 15341 } 15342 15343 /* 15344 * "synIDtrans(id)" function 15345 */ 15346 /*ARGSUSED*/ 15347 static void 15348 f_synIDtrans(argvars, rettv) 15349 typval_T *argvars; 15350 typval_T *rettv; 15351 { 15352 int id; 15353 15354 #ifdef FEAT_SYN_HL 15355 id = get_tv_number(&argvars[0]); 15356 15357 if (id > 0) 15358 id = syn_get_final_id(id); 15359 else 15360 #endif 15361 id = 0; 15362 15363 rettv->vval.v_number = id; 15364 } 15365 15366 /* 15367 * "system()" function 15368 */ 15369 static void 15370 f_system(argvars, rettv) 15371 typval_T *argvars; 15372 typval_T *rettv; 15373 { 15374 char_u *res = NULL; 15375 char_u *p; 15376 char_u *infile = NULL; 15377 char_u buf[NUMBUFLEN]; 15378 int err = FALSE; 15379 FILE *fd; 15380 15381 if (argvars[1].v_type != VAR_UNKNOWN) 15382 { 15383 /* 15384 * Write the string to a temp file, to be used for input of the shell 15385 * command. 15386 */ 15387 if ((infile = vim_tempname('i')) == NULL) 15388 { 15389 EMSG(_(e_notmp)); 15390 return; 15391 } 15392 15393 fd = mch_fopen((char *)infile, WRITEBIN); 15394 if (fd == NULL) 15395 { 15396 EMSG2(_(e_notopen), infile); 15397 goto done; 15398 } 15399 p = get_tv_string_buf_chk(&argvars[1], buf); 15400 if (p == NULL) 15401 goto done; /* type error; errmsg already given */ 15402 if (fwrite(p, STRLEN(p), 1, fd) != 1) 15403 err = TRUE; 15404 if (fclose(fd) != 0) 15405 err = TRUE; 15406 if (err) 15407 { 15408 EMSG(_("E677: Error writing temp file")); 15409 goto done; 15410 } 15411 } 15412 15413 res = get_cmd_output(get_tv_string(&argvars[0]), infile, 15414 SHELL_SILENT | SHELL_COOKED); 15415 15416 #ifdef USE_CR 15417 /* translate <CR> into <NL> */ 15418 if (res != NULL) 15419 { 15420 char_u *s; 15421 15422 for (s = res; *s; ++s) 15423 { 15424 if (*s == CAR) 15425 *s = NL; 15426 } 15427 } 15428 #else 15429 # ifdef USE_CRNL 15430 /* translate <CR><NL> into <NL> */ 15431 if (res != NULL) 15432 { 15433 char_u *s, *d; 15434 15435 d = res; 15436 for (s = res; *s; ++s) 15437 { 15438 if (s[0] == CAR && s[1] == NL) 15439 ++s; 15440 *d++ = *s; 15441 } 15442 *d = NUL; 15443 } 15444 # endif 15445 #endif 15446 15447 done: 15448 if (infile != NULL) 15449 { 15450 mch_remove(infile); 15451 vim_free(infile); 15452 } 15453 rettv->v_type = VAR_STRING; 15454 rettv->vval.v_string = res; 15455 } 15456 15457 /* 15458 * "tabpagebuflist()" function 15459 */ 15460 /* ARGSUSED */ 15461 static void 15462 f_tabpagebuflist(argvars, rettv) 15463 typval_T *argvars; 15464 typval_T *rettv; 15465 { 15466 #ifndef FEAT_WINDOWS 15467 rettv->vval.v_number = 0; 15468 #else 15469 tabpage_T *tp; 15470 win_T *wp = NULL; 15471 15472 if (argvars[0].v_type == VAR_UNKNOWN) 15473 wp = firstwin; 15474 else 15475 { 15476 tp = find_tabpage((int)get_tv_number(&argvars[0])); 15477 if (tp != NULL) 15478 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 15479 } 15480 if (wp == NULL) 15481 rettv->vval.v_number = 0; 15482 else 15483 { 15484 if (rettv_list_alloc(rettv) == FAIL) 15485 rettv->vval.v_number = 0; 15486 else 15487 { 15488 for (; wp != NULL; wp = wp->w_next) 15489 if (list_append_number(rettv->vval.v_list, 15490 wp->w_buffer->b_fnum) == FAIL) 15491 break; 15492 } 15493 } 15494 #endif 15495 } 15496 15497 15498 /* 15499 * "tabpagenr()" function 15500 */ 15501 /* ARGSUSED */ 15502 static void 15503 f_tabpagenr(argvars, rettv) 15504 typval_T *argvars; 15505 typval_T *rettv; 15506 { 15507 int nr = 1; 15508 #ifdef FEAT_WINDOWS 15509 char_u *arg; 15510 15511 if (argvars[0].v_type != VAR_UNKNOWN) 15512 { 15513 arg = get_tv_string_chk(&argvars[0]); 15514 nr = 0; 15515 if (arg != NULL) 15516 { 15517 if (STRCMP(arg, "$") == 0) 15518 nr = tabpage_index(NULL) - 1; 15519 else 15520 EMSG2(_(e_invexpr2), arg); 15521 } 15522 } 15523 else 15524 nr = tabpage_index(curtab); 15525 #endif 15526 rettv->vval.v_number = nr; 15527 } 15528 15529 15530 #ifdef FEAT_WINDOWS 15531 static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 15532 15533 /* 15534 * Common code for tabpagewinnr() and winnr(). 15535 */ 15536 static int 15537 get_winnr(tp, argvar) 15538 tabpage_T *tp; 15539 typval_T *argvar; 15540 { 15541 win_T *twin; 15542 int nr = 1; 15543 win_T *wp; 15544 char_u *arg; 15545 15546 twin = (tp == curtab) ? curwin : tp->tp_curwin; 15547 if (argvar->v_type != VAR_UNKNOWN) 15548 { 15549 arg = get_tv_string_chk(argvar); 15550 if (arg == NULL) 15551 nr = 0; /* type error; errmsg already given */ 15552 else if (STRCMP(arg, "$") == 0) 15553 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 15554 else if (STRCMP(arg, "#") == 0) 15555 { 15556 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 15557 if (twin == NULL) 15558 nr = 0; 15559 } 15560 else 15561 { 15562 EMSG2(_(e_invexpr2), arg); 15563 nr = 0; 15564 } 15565 } 15566 15567 if (nr > 0) 15568 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 15569 wp != twin; wp = wp->w_next) 15570 ++nr; 15571 return nr; 15572 } 15573 #endif 15574 15575 /* 15576 * "tabpagewinnr()" function 15577 */ 15578 /* ARGSUSED */ 15579 static void 15580 f_tabpagewinnr(argvars, rettv) 15581 typval_T *argvars; 15582 typval_T *rettv; 15583 { 15584 int nr = 1; 15585 #ifdef FEAT_WINDOWS 15586 tabpage_T *tp; 15587 15588 tp = find_tabpage((int)get_tv_number(&argvars[0])); 15589 if (tp == NULL) 15590 nr = 0; 15591 else 15592 nr = get_winnr(tp, &argvars[1]); 15593 #endif 15594 rettv->vval.v_number = nr; 15595 } 15596 15597 15598 /* 15599 * "tagfiles()" function 15600 */ 15601 /*ARGSUSED*/ 15602 static void 15603 f_tagfiles(argvars, rettv) 15604 typval_T *argvars; 15605 typval_T *rettv; 15606 { 15607 char_u fname[MAXPATHL + 1]; 15608 tagname_T tn; 15609 int first; 15610 15611 if (rettv_list_alloc(rettv) == FAIL) 15612 { 15613 rettv->vval.v_number = 0; 15614 return; 15615 } 15616 15617 for (first = TRUE; ; first = FALSE) 15618 if (get_tagfname(&tn, first, fname) == FAIL 15619 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 15620 break; 15621 tagname_free(&tn); 15622 } 15623 15624 /* 15625 * "taglist()" function 15626 */ 15627 static void 15628 f_taglist(argvars, rettv) 15629 typval_T *argvars; 15630 typval_T *rettv; 15631 { 15632 char_u *tag_pattern; 15633 15634 tag_pattern = get_tv_string(&argvars[0]); 15635 15636 rettv->vval.v_number = FALSE; 15637 if (*tag_pattern == NUL) 15638 return; 15639 15640 if (rettv_list_alloc(rettv) == OK) 15641 (void)get_tags(rettv->vval.v_list, tag_pattern); 15642 } 15643 15644 /* 15645 * "tempname()" function 15646 */ 15647 /*ARGSUSED*/ 15648 static void 15649 f_tempname(argvars, rettv) 15650 typval_T *argvars; 15651 typval_T *rettv; 15652 { 15653 static int x = 'A'; 15654 15655 rettv->v_type = VAR_STRING; 15656 rettv->vval.v_string = vim_tempname(x); 15657 15658 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 15659 * names. Skip 'I' and 'O', they are used for shell redirection. */ 15660 do 15661 { 15662 if (x == 'Z') 15663 x = '0'; 15664 else if (x == '9') 15665 x = 'A'; 15666 else 15667 { 15668 #ifdef EBCDIC 15669 if (x == 'I') 15670 x = 'J'; 15671 else if (x == 'R') 15672 x = 'S'; 15673 else 15674 #endif 15675 ++x; 15676 } 15677 } while (x == 'I' || x == 'O'); 15678 } 15679 15680 /* 15681 * "test(list)" function: Just checking the walls... 15682 */ 15683 /*ARGSUSED*/ 15684 static void 15685 f_test(argvars, rettv) 15686 typval_T *argvars; 15687 typval_T *rettv; 15688 { 15689 /* Used for unit testing. Change the code below to your liking. */ 15690 #if 0 15691 listitem_T *li; 15692 list_T *l; 15693 char_u *bad, *good; 15694 15695 if (argvars[0].v_type != VAR_LIST) 15696 return; 15697 l = argvars[0].vval.v_list; 15698 if (l == NULL) 15699 return; 15700 li = l->lv_first; 15701 if (li == NULL) 15702 return; 15703 bad = get_tv_string(&li->li_tv); 15704 li = li->li_next; 15705 if (li == NULL) 15706 return; 15707 good = get_tv_string(&li->li_tv); 15708 rettv->vval.v_number = test_edit_score(bad, good); 15709 #endif 15710 } 15711 15712 /* 15713 * "tolower(string)" function 15714 */ 15715 static void 15716 f_tolower(argvars, rettv) 15717 typval_T *argvars; 15718 typval_T *rettv; 15719 { 15720 char_u *p; 15721 15722 p = vim_strsave(get_tv_string(&argvars[0])); 15723 rettv->v_type = VAR_STRING; 15724 rettv->vval.v_string = p; 15725 15726 if (p != NULL) 15727 while (*p != NUL) 15728 { 15729 #ifdef FEAT_MBYTE 15730 int l; 15731 15732 if (enc_utf8) 15733 { 15734 int c, lc; 15735 15736 c = utf_ptr2char(p); 15737 lc = utf_tolower(c); 15738 l = utf_ptr2len(p); 15739 /* TODO: reallocate string when byte count changes. */ 15740 if (utf_char2len(lc) == l) 15741 utf_char2bytes(lc, p); 15742 p += l; 15743 } 15744 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 15745 p += l; /* skip multi-byte character */ 15746 else 15747 #endif 15748 { 15749 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 15750 ++p; 15751 } 15752 } 15753 } 15754 15755 /* 15756 * "toupper(string)" function 15757 */ 15758 static void 15759 f_toupper(argvars, rettv) 15760 typval_T *argvars; 15761 typval_T *rettv; 15762 { 15763 rettv->v_type = VAR_STRING; 15764 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 15765 } 15766 15767 /* 15768 * "tr(string, fromstr, tostr)" function 15769 */ 15770 static void 15771 f_tr(argvars, rettv) 15772 typval_T *argvars; 15773 typval_T *rettv; 15774 { 15775 char_u *instr; 15776 char_u *fromstr; 15777 char_u *tostr; 15778 char_u *p; 15779 #ifdef FEAT_MBYTE 15780 int inlen; 15781 int fromlen; 15782 int tolen; 15783 int idx; 15784 char_u *cpstr; 15785 int cplen; 15786 int first = TRUE; 15787 #endif 15788 char_u buf[NUMBUFLEN]; 15789 char_u buf2[NUMBUFLEN]; 15790 garray_T ga; 15791 15792 instr = get_tv_string(&argvars[0]); 15793 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 15794 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 15795 15796 /* Default return value: empty string. */ 15797 rettv->v_type = VAR_STRING; 15798 rettv->vval.v_string = NULL; 15799 if (fromstr == NULL || tostr == NULL) 15800 return; /* type error; errmsg already given */ 15801 ga_init2(&ga, (int)sizeof(char), 80); 15802 15803 #ifdef FEAT_MBYTE 15804 if (!has_mbyte) 15805 #endif 15806 /* not multi-byte: fromstr and tostr must be the same length */ 15807 if (STRLEN(fromstr) != STRLEN(tostr)) 15808 { 15809 #ifdef FEAT_MBYTE 15810 error: 15811 #endif 15812 EMSG2(_(e_invarg2), fromstr); 15813 ga_clear(&ga); 15814 return; 15815 } 15816 15817 /* fromstr and tostr have to contain the same number of chars */ 15818 while (*instr != NUL) 15819 { 15820 #ifdef FEAT_MBYTE 15821 if (has_mbyte) 15822 { 15823 inlen = (*mb_ptr2len)(instr); 15824 cpstr = instr; 15825 cplen = inlen; 15826 idx = 0; 15827 for (p = fromstr; *p != NUL; p += fromlen) 15828 { 15829 fromlen = (*mb_ptr2len)(p); 15830 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 15831 { 15832 for (p = tostr; *p != NUL; p += tolen) 15833 { 15834 tolen = (*mb_ptr2len)(p); 15835 if (idx-- == 0) 15836 { 15837 cplen = tolen; 15838 cpstr = p; 15839 break; 15840 } 15841 } 15842 if (*p == NUL) /* tostr is shorter than fromstr */ 15843 goto error; 15844 break; 15845 } 15846 ++idx; 15847 } 15848 15849 if (first && cpstr == instr) 15850 { 15851 /* Check that fromstr and tostr have the same number of 15852 * (multi-byte) characters. Done only once when a character 15853 * of instr doesn't appear in fromstr. */ 15854 first = FALSE; 15855 for (p = tostr; *p != NUL; p += tolen) 15856 { 15857 tolen = (*mb_ptr2len)(p); 15858 --idx; 15859 } 15860 if (idx != 0) 15861 goto error; 15862 } 15863 15864 ga_grow(&ga, cplen); 15865 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 15866 ga.ga_len += cplen; 15867 15868 instr += inlen; 15869 } 15870 else 15871 #endif 15872 { 15873 /* When not using multi-byte chars we can do it faster. */ 15874 p = vim_strchr(fromstr, *instr); 15875 if (p != NULL) 15876 ga_append(&ga, tostr[p - fromstr]); 15877 else 15878 ga_append(&ga, *instr); 15879 ++instr; 15880 } 15881 } 15882 15883 rettv->vval.v_string = ga.ga_data; 15884 } 15885 15886 /* 15887 * "type(expr)" function 15888 */ 15889 static void 15890 f_type(argvars, rettv) 15891 typval_T *argvars; 15892 typval_T *rettv; 15893 { 15894 int n; 15895 15896 switch (argvars[0].v_type) 15897 { 15898 case VAR_NUMBER: n = 0; break; 15899 case VAR_STRING: n = 1; break; 15900 case VAR_FUNC: n = 2; break; 15901 case VAR_LIST: n = 3; break; 15902 case VAR_DICT: n = 4; break; 15903 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 15904 } 15905 rettv->vval.v_number = n; 15906 } 15907 15908 /* 15909 * "values(dict)" function 15910 */ 15911 static void 15912 f_values(argvars, rettv) 15913 typval_T *argvars; 15914 typval_T *rettv; 15915 { 15916 dict_list(argvars, rettv, 1); 15917 } 15918 15919 /* 15920 * "virtcol(string)" function 15921 */ 15922 static void 15923 f_virtcol(argvars, rettv) 15924 typval_T *argvars; 15925 typval_T *rettv; 15926 { 15927 colnr_T vcol = 0; 15928 pos_T *fp; 15929 int fnum = curbuf->b_fnum; 15930 15931 fp = var2fpos(&argvars[0], FALSE, &fnum); 15932 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 15933 && fnum == curbuf->b_fnum) 15934 { 15935 getvvcol(curwin, fp, NULL, NULL, &vcol); 15936 ++vcol; 15937 } 15938 15939 rettv->vval.v_number = vcol; 15940 } 15941 15942 /* 15943 * "visualmode()" function 15944 */ 15945 /*ARGSUSED*/ 15946 static void 15947 f_visualmode(argvars, rettv) 15948 typval_T *argvars; 15949 typval_T *rettv; 15950 { 15951 #ifdef FEAT_VISUAL 15952 char_u str[2]; 15953 15954 rettv->v_type = VAR_STRING; 15955 str[0] = curbuf->b_visual_mode_eval; 15956 str[1] = NUL; 15957 rettv->vval.v_string = vim_strsave(str); 15958 15959 /* A non-zero number or non-empty string argument: reset mode. */ 15960 if ((argvars[0].v_type == VAR_NUMBER 15961 && argvars[0].vval.v_number != 0) 15962 || (argvars[0].v_type == VAR_STRING 15963 && *get_tv_string(&argvars[0]) != NUL)) 15964 curbuf->b_visual_mode_eval = NUL; 15965 #else 15966 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 15967 #endif 15968 } 15969 15970 /* 15971 * "winbufnr(nr)" function 15972 */ 15973 static void 15974 f_winbufnr(argvars, rettv) 15975 typval_T *argvars; 15976 typval_T *rettv; 15977 { 15978 win_T *wp; 15979 15980 wp = find_win_by_nr(&argvars[0], NULL); 15981 if (wp == NULL) 15982 rettv->vval.v_number = -1; 15983 else 15984 rettv->vval.v_number = wp->w_buffer->b_fnum; 15985 } 15986 15987 /* 15988 * "wincol()" function 15989 */ 15990 /*ARGSUSED*/ 15991 static void 15992 f_wincol(argvars, rettv) 15993 typval_T *argvars; 15994 typval_T *rettv; 15995 { 15996 validate_cursor(); 15997 rettv->vval.v_number = curwin->w_wcol + 1; 15998 } 15999 16000 /* 16001 * "winheight(nr)" function 16002 */ 16003 static void 16004 f_winheight(argvars, rettv) 16005 typval_T *argvars; 16006 typval_T *rettv; 16007 { 16008 win_T *wp; 16009 16010 wp = find_win_by_nr(&argvars[0], NULL); 16011 if (wp == NULL) 16012 rettv->vval.v_number = -1; 16013 else 16014 rettv->vval.v_number = wp->w_height; 16015 } 16016 16017 /* 16018 * "winline()" function 16019 */ 16020 /*ARGSUSED*/ 16021 static void 16022 f_winline(argvars, rettv) 16023 typval_T *argvars; 16024 typval_T *rettv; 16025 { 16026 validate_cursor(); 16027 rettv->vval.v_number = curwin->w_wrow + 1; 16028 } 16029 16030 /* 16031 * "winnr()" function 16032 */ 16033 /* ARGSUSED */ 16034 static void 16035 f_winnr(argvars, rettv) 16036 typval_T *argvars; 16037 typval_T *rettv; 16038 { 16039 int nr = 1; 16040 16041 #ifdef FEAT_WINDOWS 16042 nr = get_winnr(curtab, &argvars[0]); 16043 #endif 16044 rettv->vval.v_number = nr; 16045 } 16046 16047 /* 16048 * "winrestcmd()" function 16049 */ 16050 /* ARGSUSED */ 16051 static void 16052 f_winrestcmd(argvars, rettv) 16053 typval_T *argvars; 16054 typval_T *rettv; 16055 { 16056 #ifdef FEAT_WINDOWS 16057 win_T *wp; 16058 int winnr = 1; 16059 garray_T ga; 16060 char_u buf[50]; 16061 16062 ga_init2(&ga, (int)sizeof(char), 70); 16063 for (wp = firstwin; wp != NULL; wp = wp->w_next) 16064 { 16065 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 16066 ga_concat(&ga, buf); 16067 # ifdef FEAT_VERTSPLIT 16068 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 16069 ga_concat(&ga, buf); 16070 # endif 16071 ++winnr; 16072 } 16073 ga_append(&ga, NUL); 16074 16075 rettv->vval.v_string = ga.ga_data; 16076 #else 16077 rettv->vval.v_string = NULL; 16078 #endif 16079 rettv->v_type = VAR_STRING; 16080 } 16081 16082 /* 16083 * "winrestview()" function 16084 */ 16085 /* ARGSUSED */ 16086 static void 16087 f_winrestview(argvars, rettv) 16088 typval_T *argvars; 16089 typval_T *rettv; 16090 { 16091 dict_T *dict; 16092 16093 if (argvars[0].v_type != VAR_DICT 16094 || (dict = argvars[0].vval.v_dict) == NULL) 16095 EMSG(_(e_invarg)); 16096 else 16097 { 16098 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 16099 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 16100 #ifdef FEAT_VIRTUALEDIT 16101 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 16102 #endif 16103 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 16104 curwin->w_set_curswant = FALSE; 16105 16106 curwin->w_topline = get_dict_number(dict, (char_u *)"topline"); 16107 #ifdef FEAT_DIFF 16108 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 16109 #endif 16110 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 16111 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 16112 16113 check_cursor(); 16114 changed_cline_bef_curs(); 16115 invalidate_botline(); 16116 redraw_later(VALID); 16117 16118 if (curwin->w_topline == 0) 16119 curwin->w_topline = 1; 16120 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 16121 curwin->w_topline = curbuf->b_ml.ml_line_count; 16122 #ifdef FEAT_DIFF 16123 check_topfill(curwin, TRUE); 16124 #endif 16125 } 16126 } 16127 16128 /* 16129 * "winsaveview()" function 16130 */ 16131 /* ARGSUSED */ 16132 static void 16133 f_winsaveview(argvars, rettv) 16134 typval_T *argvars; 16135 typval_T *rettv; 16136 { 16137 dict_T *dict; 16138 16139 dict = dict_alloc(); 16140 if (dict == NULL) 16141 return; 16142 rettv->v_type = VAR_DICT; 16143 rettv->vval.v_dict = dict; 16144 ++dict->dv_refcount; 16145 16146 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 16147 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 16148 #ifdef FEAT_VIRTUALEDIT 16149 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 16150 #endif 16151 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 16152 16153 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 16154 #ifdef FEAT_DIFF 16155 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 16156 #endif 16157 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 16158 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 16159 } 16160 16161 /* 16162 * "winwidth(nr)" function 16163 */ 16164 static void 16165 f_winwidth(argvars, rettv) 16166 typval_T *argvars; 16167 typval_T *rettv; 16168 { 16169 win_T *wp; 16170 16171 wp = find_win_by_nr(&argvars[0], NULL); 16172 if (wp == NULL) 16173 rettv->vval.v_number = -1; 16174 else 16175 #ifdef FEAT_VERTSPLIT 16176 rettv->vval.v_number = wp->w_width; 16177 #else 16178 rettv->vval.v_number = Columns; 16179 #endif 16180 } 16181 16182 /* 16183 * "writefile()" function 16184 */ 16185 static void 16186 f_writefile(argvars, rettv) 16187 typval_T *argvars; 16188 typval_T *rettv; 16189 { 16190 int binary = FALSE; 16191 char_u *fname; 16192 FILE *fd; 16193 listitem_T *li; 16194 char_u *s; 16195 int ret = 0; 16196 int c; 16197 16198 if (argvars[0].v_type != VAR_LIST) 16199 { 16200 EMSG2(_(e_listarg), "writefile()"); 16201 return; 16202 } 16203 if (argvars[0].vval.v_list == NULL) 16204 return; 16205 16206 if (argvars[2].v_type != VAR_UNKNOWN 16207 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 16208 binary = TRUE; 16209 16210 /* Always open the file in binary mode, library functions have a mind of 16211 * their own about CR-LF conversion. */ 16212 fname = get_tv_string(&argvars[1]); 16213 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 16214 { 16215 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 16216 ret = -1; 16217 } 16218 else 16219 { 16220 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 16221 li = li->li_next) 16222 { 16223 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 16224 { 16225 if (*s == '\n') 16226 c = putc(NUL, fd); 16227 else 16228 c = putc(*s, fd); 16229 if (c == EOF) 16230 { 16231 ret = -1; 16232 break; 16233 } 16234 } 16235 if (!binary || li->li_next != NULL) 16236 if (putc('\n', fd) == EOF) 16237 { 16238 ret = -1; 16239 break; 16240 } 16241 if (ret < 0) 16242 { 16243 EMSG(_(e_write)); 16244 break; 16245 } 16246 } 16247 fclose(fd); 16248 } 16249 16250 rettv->vval.v_number = ret; 16251 } 16252 16253 /* 16254 * Translate a String variable into a position. 16255 * Returns NULL when there is an error. 16256 */ 16257 static pos_T * 16258 var2fpos(varp, lnum, fnum) 16259 typval_T *varp; 16260 int lnum; /* TRUE when $ is last line */ 16261 int *fnum; /* set to fnum for '0, 'A, etc. */ 16262 { 16263 char_u *name; 16264 static pos_T pos; 16265 pos_T *pp; 16266 16267 /* Argument can be [lnum, col, coladd]. */ 16268 if (varp->v_type == VAR_LIST) 16269 { 16270 list_T *l; 16271 int len; 16272 int error = FALSE; 16273 16274 l = varp->vval.v_list; 16275 if (l == NULL) 16276 return NULL; 16277 16278 /* Get the line number */ 16279 pos.lnum = list_find_nr(l, 0L, &error); 16280 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 16281 return NULL; /* invalid line number */ 16282 16283 /* Get the column number */ 16284 pos.col = list_find_nr(l, 1L, &error); 16285 if (error) 16286 return NULL; 16287 len = (long)STRLEN(ml_get(pos.lnum)); 16288 /* Accept a position up to the NUL after the line. */ 16289 if (pos.col == 0 || (int)pos.col > len + 1) 16290 return NULL; /* invalid column number */ 16291 --pos.col; 16292 16293 #ifdef FEAT_VIRTUALEDIT 16294 /* Get the virtual offset. Defaults to zero. */ 16295 pos.coladd = list_find_nr(l, 2L, &error); 16296 if (error) 16297 pos.coladd = 0; 16298 #endif 16299 16300 return &pos; 16301 } 16302 16303 name = get_tv_string_chk(varp); 16304 if (name == NULL) 16305 return NULL; 16306 if (name[0] == '.') /* cursor */ 16307 return &curwin->w_cursor; 16308 if (name[0] == '\'') /* mark */ 16309 { 16310 pp = getmark_fnum(name[1], FALSE, fnum); 16311 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 16312 return NULL; 16313 return pp; 16314 } 16315 16316 #ifdef FEAT_VIRTUALEDIT 16317 pos.coladd = 0; 16318 #endif 16319 16320 if (name[0] == 'w' && lnum) 16321 { 16322 pos.col = 0; 16323 if (name[1] == '0') /* "w0": first visible line */ 16324 { 16325 update_topline(); 16326 pos.lnum = curwin->w_topline; 16327 return &pos; 16328 } 16329 else if (name[1] == '$') /* "w$": last visible line */ 16330 { 16331 validate_botline(); 16332 pos.lnum = curwin->w_botline - 1; 16333 return &pos; 16334 } 16335 } 16336 else if (name[0] == '$') /* last column or line */ 16337 { 16338 if (lnum) 16339 { 16340 pos.lnum = curbuf->b_ml.ml_line_count; 16341 pos.col = 0; 16342 } 16343 else 16344 { 16345 pos.lnum = curwin->w_cursor.lnum; 16346 pos.col = (colnr_T)STRLEN(ml_get_curline()); 16347 } 16348 return &pos; 16349 } 16350 return NULL; 16351 } 16352 16353 /* 16354 * Convert list in "arg" into a position and optional file number. 16355 * When "fnump" is NULL there is no file number, only 3 items. 16356 * Note that the column is passed on as-is, the caller may want to decrement 16357 * it to use 1 for the first column. 16358 * Return FAIL when conversion is not possible, doesn't check the position for 16359 * validity. 16360 */ 16361 static int 16362 list2fpos(arg, posp, fnump) 16363 typval_T *arg; 16364 pos_T *posp; 16365 int *fnump; 16366 { 16367 list_T *l = arg->vval.v_list; 16368 long i = 0; 16369 long n; 16370 16371 /* List must be: [fnum, lnum, col, coladd] */ 16372 if (arg->v_type != VAR_LIST || l == NULL 16373 || l->lv_len != (fnump == NULL ? 3 : 4)) 16374 return FAIL; 16375 16376 if (fnump != NULL) 16377 { 16378 n = list_find_nr(l, i++, NULL); /* fnum */ 16379 if (n < 0) 16380 return FAIL; 16381 if (n == 0) 16382 n = curbuf->b_fnum; /* current buffer */ 16383 *fnump = n; 16384 } 16385 16386 n = list_find_nr(l, i++, NULL); /* lnum */ 16387 if (n < 0) 16388 return FAIL; 16389 posp->lnum = n; 16390 16391 n = list_find_nr(l, i++, NULL); /* col */ 16392 if (n < 0) 16393 return FAIL; 16394 posp->col = n; 16395 16396 #ifdef FEAT_VIRTUALEDIT 16397 n = list_find_nr(l, i, NULL); 16398 if (n < 0) 16399 return FAIL; 16400 posp->coladd = n; 16401 #endif 16402 16403 return OK; 16404 } 16405 16406 /* 16407 * Get the length of an environment variable name. 16408 * Advance "arg" to the first character after the name. 16409 * Return 0 for error. 16410 */ 16411 static int 16412 get_env_len(arg) 16413 char_u **arg; 16414 { 16415 char_u *p; 16416 int len; 16417 16418 for (p = *arg; vim_isIDc(*p); ++p) 16419 ; 16420 if (p == *arg) /* no name found */ 16421 return 0; 16422 16423 len = (int)(p - *arg); 16424 *arg = p; 16425 return len; 16426 } 16427 16428 /* 16429 * Get the length of the name of a function or internal variable. 16430 * "arg" is advanced to the first non-white character after the name. 16431 * Return 0 if something is wrong. 16432 */ 16433 static int 16434 get_id_len(arg) 16435 char_u **arg; 16436 { 16437 char_u *p; 16438 int len; 16439 16440 /* Find the end of the name. */ 16441 for (p = *arg; eval_isnamec(*p); ++p) 16442 ; 16443 if (p == *arg) /* no name found */ 16444 return 0; 16445 16446 len = (int)(p - *arg); 16447 *arg = skipwhite(p); 16448 16449 return len; 16450 } 16451 16452 /* 16453 * Get the length of the name of a variable or function. 16454 * Only the name is recognized, does not handle ".key" or "[idx]". 16455 * "arg" is advanced to the first non-white character after the name. 16456 * Return -1 if curly braces expansion failed. 16457 * Return 0 if something else is wrong. 16458 * If the name contains 'magic' {}'s, expand them and return the 16459 * expanded name in an allocated string via 'alias' - caller must free. 16460 */ 16461 static int 16462 get_name_len(arg, alias, evaluate, verbose) 16463 char_u **arg; 16464 char_u **alias; 16465 int evaluate; 16466 int verbose; 16467 { 16468 int len; 16469 char_u *p; 16470 char_u *expr_start; 16471 char_u *expr_end; 16472 16473 *alias = NULL; /* default to no alias */ 16474 16475 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 16476 && (*arg)[2] == (int)KE_SNR) 16477 { 16478 /* hard coded <SNR>, already translated */ 16479 *arg += 3; 16480 return get_id_len(arg) + 3; 16481 } 16482 len = eval_fname_script(*arg); 16483 if (len > 0) 16484 { 16485 /* literal "<SID>", "s:" or "<SNR>" */ 16486 *arg += len; 16487 } 16488 16489 /* 16490 * Find the end of the name; check for {} construction. 16491 */ 16492 p = find_name_end(*arg, &expr_start, &expr_end, 16493 len > 0 ? 0 : FNE_CHECK_START); 16494 if (expr_start != NULL) 16495 { 16496 char_u *temp_string; 16497 16498 if (!evaluate) 16499 { 16500 len += (int)(p - *arg); 16501 *arg = skipwhite(p); 16502 return len; 16503 } 16504 16505 /* 16506 * Include any <SID> etc in the expanded string: 16507 * Thus the -len here. 16508 */ 16509 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 16510 if (temp_string == NULL) 16511 return -1; 16512 *alias = temp_string; 16513 *arg = skipwhite(p); 16514 return (int)STRLEN(temp_string); 16515 } 16516 16517 len += get_id_len(arg); 16518 if (len == 0 && verbose) 16519 EMSG2(_(e_invexpr2), *arg); 16520 16521 return len; 16522 } 16523 16524 /* 16525 * Find the end of a variable or function name, taking care of magic braces. 16526 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 16527 * start and end of the first magic braces item. 16528 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 16529 * Return a pointer to just after the name. Equal to "arg" if there is no 16530 * valid name. 16531 */ 16532 static char_u * 16533 find_name_end(arg, expr_start, expr_end, flags) 16534 char_u *arg; 16535 char_u **expr_start; 16536 char_u **expr_end; 16537 int flags; 16538 { 16539 int mb_nest = 0; 16540 int br_nest = 0; 16541 char_u *p; 16542 16543 if (expr_start != NULL) 16544 { 16545 *expr_start = NULL; 16546 *expr_end = NULL; 16547 } 16548 16549 /* Quick check for valid starting character. */ 16550 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 16551 return arg; 16552 16553 for (p = arg; *p != NUL 16554 && (eval_isnamec(*p) 16555 || *p == '{' 16556 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 16557 || mb_nest != 0 16558 || br_nest != 0); mb_ptr_adv(p)) 16559 { 16560 if (*p == '\'') 16561 { 16562 /* skip over 'string' to avoid counting [ and ] inside it. */ 16563 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 16564 ; 16565 if (*p == NUL) 16566 break; 16567 } 16568 else if (*p == '"') 16569 { 16570 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 16571 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 16572 if (*p == '\\' && p[1] != NUL) 16573 ++p; 16574 if (*p == NUL) 16575 break; 16576 } 16577 16578 if (mb_nest == 0) 16579 { 16580 if (*p == '[') 16581 ++br_nest; 16582 else if (*p == ']') 16583 --br_nest; 16584 } 16585 16586 if (br_nest == 0) 16587 { 16588 if (*p == '{') 16589 { 16590 mb_nest++; 16591 if (expr_start != NULL && *expr_start == NULL) 16592 *expr_start = p; 16593 } 16594 else if (*p == '}') 16595 { 16596 mb_nest--; 16597 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 16598 *expr_end = p; 16599 } 16600 } 16601 } 16602 16603 return p; 16604 } 16605 16606 /* 16607 * Expands out the 'magic' {}'s in a variable/function name. 16608 * Note that this can call itself recursively, to deal with 16609 * constructs like foo{bar}{baz}{bam} 16610 * The four pointer arguments point to "foo{expre}ss{ion}bar" 16611 * "in_start" ^ 16612 * "expr_start" ^ 16613 * "expr_end" ^ 16614 * "in_end" ^ 16615 * 16616 * Returns a new allocated string, which the caller must free. 16617 * Returns NULL for failure. 16618 */ 16619 static char_u * 16620 make_expanded_name(in_start, expr_start, expr_end, in_end) 16621 char_u *in_start; 16622 char_u *expr_start; 16623 char_u *expr_end; 16624 char_u *in_end; 16625 { 16626 char_u c1; 16627 char_u *retval = NULL; 16628 char_u *temp_result; 16629 char_u *nextcmd = NULL; 16630 16631 if (expr_end == NULL || in_end == NULL) 16632 return NULL; 16633 *expr_start = NUL; 16634 *expr_end = NUL; 16635 c1 = *in_end; 16636 *in_end = NUL; 16637 16638 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 16639 if (temp_result != NULL && nextcmd == NULL) 16640 { 16641 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 16642 + (in_end - expr_end) + 1)); 16643 if (retval != NULL) 16644 { 16645 STRCPY(retval, in_start); 16646 STRCAT(retval, temp_result); 16647 STRCAT(retval, expr_end + 1); 16648 } 16649 } 16650 vim_free(temp_result); 16651 16652 *in_end = c1; /* put char back for error messages */ 16653 *expr_start = '{'; 16654 *expr_end = '}'; 16655 16656 if (retval != NULL) 16657 { 16658 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 16659 if (expr_start != NULL) 16660 { 16661 /* Further expansion! */ 16662 temp_result = make_expanded_name(retval, expr_start, 16663 expr_end, temp_result); 16664 vim_free(retval); 16665 retval = temp_result; 16666 } 16667 } 16668 16669 return retval; 16670 } 16671 16672 /* 16673 * Return TRUE if character "c" can be used in a variable or function name. 16674 * Does not include '{' or '}' for magic braces. 16675 */ 16676 static int 16677 eval_isnamec(c) 16678 int c; 16679 { 16680 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 16681 } 16682 16683 /* 16684 * Return TRUE if character "c" can be used as the first character in a 16685 * variable or function name (excluding '{' and '}'). 16686 */ 16687 static int 16688 eval_isnamec1(c) 16689 int c; 16690 { 16691 return (ASCII_ISALPHA(c) || c == '_'); 16692 } 16693 16694 /* 16695 * Set number v: variable to "val". 16696 */ 16697 void 16698 set_vim_var_nr(idx, val) 16699 int idx; 16700 long val; 16701 { 16702 vimvars[idx].vv_nr = val; 16703 } 16704 16705 /* 16706 * Get number v: variable value. 16707 */ 16708 long 16709 get_vim_var_nr(idx) 16710 int idx; 16711 { 16712 return vimvars[idx].vv_nr; 16713 } 16714 16715 #if defined(FEAT_AUTOCMD) || defined(PROTO) 16716 /* 16717 * Get string v: variable value. Uses a static buffer, can only be used once. 16718 */ 16719 char_u * 16720 get_vim_var_str(idx) 16721 int idx; 16722 { 16723 return get_tv_string(&vimvars[idx].vv_tv); 16724 } 16725 #endif 16726 16727 /* 16728 * Set v:count, v:count1 and v:prevcount. 16729 */ 16730 void 16731 set_vcount(count, count1) 16732 long count; 16733 long count1; 16734 { 16735 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 16736 vimvars[VV_COUNT].vv_nr = count; 16737 vimvars[VV_COUNT1].vv_nr = count1; 16738 } 16739 16740 /* 16741 * Set string v: variable to a copy of "val". 16742 */ 16743 void 16744 set_vim_var_string(idx, val, len) 16745 int idx; 16746 char_u *val; 16747 int len; /* length of "val" to use or -1 (whole string) */ 16748 { 16749 /* Need to do this (at least) once, since we can't initialize a union. 16750 * Will always be invoked when "v:progname" is set. */ 16751 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 16752 16753 vim_free(vimvars[idx].vv_str); 16754 if (val == NULL) 16755 vimvars[idx].vv_str = NULL; 16756 else if (len == -1) 16757 vimvars[idx].vv_str = vim_strsave(val); 16758 else 16759 vimvars[idx].vv_str = vim_strnsave(val, len); 16760 } 16761 16762 /* 16763 * Set v:register if needed. 16764 */ 16765 void 16766 set_reg_var(c) 16767 int c; 16768 { 16769 char_u regname; 16770 16771 if (c == 0 || c == ' ') 16772 regname = '"'; 16773 else 16774 regname = c; 16775 /* Avoid free/alloc when the value is already right. */ 16776 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 16777 set_vim_var_string(VV_REG, ®name, 1); 16778 } 16779 16780 /* 16781 * Get or set v:exception. If "oldval" == NULL, return the current value. 16782 * Otherwise, restore the value to "oldval" and return NULL. 16783 * Must always be called in pairs to save and restore v:exception! Does not 16784 * take care of memory allocations. 16785 */ 16786 char_u * 16787 v_exception(oldval) 16788 char_u *oldval; 16789 { 16790 if (oldval == NULL) 16791 return vimvars[VV_EXCEPTION].vv_str; 16792 16793 vimvars[VV_EXCEPTION].vv_str = oldval; 16794 return NULL; 16795 } 16796 16797 /* 16798 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 16799 * Otherwise, restore the value to "oldval" and return NULL. 16800 * Must always be called in pairs to save and restore v:throwpoint! Does not 16801 * take care of memory allocations. 16802 */ 16803 char_u * 16804 v_throwpoint(oldval) 16805 char_u *oldval; 16806 { 16807 if (oldval == NULL) 16808 return vimvars[VV_THROWPOINT].vv_str; 16809 16810 vimvars[VV_THROWPOINT].vv_str = oldval; 16811 return NULL; 16812 } 16813 16814 #if defined(FEAT_AUTOCMD) || defined(PROTO) 16815 /* 16816 * Set v:cmdarg. 16817 * If "eap" != NULL, use "eap" to generate the value and return the old value. 16818 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 16819 * Must always be called in pairs! 16820 */ 16821 char_u * 16822 set_cmdarg(eap, oldarg) 16823 exarg_T *eap; 16824 char_u *oldarg; 16825 { 16826 char_u *oldval; 16827 char_u *newval; 16828 unsigned len; 16829 16830 oldval = vimvars[VV_CMDARG].vv_str; 16831 if (eap == NULL) 16832 { 16833 vim_free(oldval); 16834 vimvars[VV_CMDARG].vv_str = oldarg; 16835 return NULL; 16836 } 16837 16838 if (eap->force_bin == FORCE_BIN) 16839 len = 6; 16840 else if (eap->force_bin == FORCE_NOBIN) 16841 len = 8; 16842 else 16843 len = 0; 16844 16845 if (eap->read_edit) 16846 len += 7; 16847 16848 if (eap->force_ff != 0) 16849 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 16850 # ifdef FEAT_MBYTE 16851 if (eap->force_enc != 0) 16852 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 16853 if (eap->bad_char != 0) 16854 len += (unsigned)STRLEN(eap->cmd + eap->bad_char) + 7; 16855 # endif 16856 16857 newval = alloc(len + 1); 16858 if (newval == NULL) 16859 return NULL; 16860 16861 if (eap->force_bin == FORCE_BIN) 16862 sprintf((char *)newval, " ++bin"); 16863 else if (eap->force_bin == FORCE_NOBIN) 16864 sprintf((char *)newval, " ++nobin"); 16865 else 16866 *newval = NUL; 16867 16868 if (eap->read_edit) 16869 STRCAT(newval, " ++edit"); 16870 16871 if (eap->force_ff != 0) 16872 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 16873 eap->cmd + eap->force_ff); 16874 # ifdef FEAT_MBYTE 16875 if (eap->force_enc != 0) 16876 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 16877 eap->cmd + eap->force_enc); 16878 if (eap->bad_char != 0) 16879 sprintf((char *)newval + STRLEN(newval), " ++bad=%s", 16880 eap->cmd + eap->bad_char); 16881 # endif 16882 vimvars[VV_CMDARG].vv_str = newval; 16883 return oldval; 16884 } 16885 #endif 16886 16887 /* 16888 * Get the value of internal variable "name". 16889 * Return OK or FAIL. 16890 */ 16891 static int 16892 get_var_tv(name, len, rettv, verbose) 16893 char_u *name; 16894 int len; /* length of "name" */ 16895 typval_T *rettv; /* NULL when only checking existence */ 16896 int verbose; /* may give error message */ 16897 { 16898 int ret = OK; 16899 typval_T *tv = NULL; 16900 typval_T atv; 16901 dictitem_T *v; 16902 int cc; 16903 16904 /* truncate the name, so that we can use strcmp() */ 16905 cc = name[len]; 16906 name[len] = NUL; 16907 16908 /* 16909 * Check for "b:changedtick". 16910 */ 16911 if (STRCMP(name, "b:changedtick") == 0) 16912 { 16913 atv.v_type = VAR_NUMBER; 16914 atv.vval.v_number = curbuf->b_changedtick; 16915 tv = &atv; 16916 } 16917 16918 /* 16919 * Check for user-defined variables. 16920 */ 16921 else 16922 { 16923 v = find_var(name, NULL); 16924 if (v != NULL) 16925 tv = &v->di_tv; 16926 } 16927 16928 if (tv == NULL) 16929 { 16930 if (rettv != NULL && verbose) 16931 EMSG2(_(e_undefvar), name); 16932 ret = FAIL; 16933 } 16934 else if (rettv != NULL) 16935 copy_tv(tv, rettv); 16936 16937 name[len] = cc; 16938 16939 return ret; 16940 } 16941 16942 /* 16943 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 16944 * Also handle function call with Funcref variable: func(expr) 16945 * Can all be combined: dict.func(expr)[idx]['func'](expr) 16946 */ 16947 static int 16948 handle_subscript(arg, rettv, evaluate, verbose) 16949 char_u **arg; 16950 typval_T *rettv; 16951 int evaluate; /* do more than finding the end */ 16952 int verbose; /* give error messages */ 16953 { 16954 int ret = OK; 16955 dict_T *selfdict = NULL; 16956 char_u *s; 16957 int len; 16958 typval_T functv; 16959 16960 while (ret == OK 16961 && (**arg == '[' 16962 || (**arg == '.' && rettv->v_type == VAR_DICT) 16963 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 16964 && !vim_iswhite(*(*arg - 1))) 16965 { 16966 if (**arg == '(') 16967 { 16968 /* need to copy the funcref so that we can clear rettv */ 16969 functv = *rettv; 16970 rettv->v_type = VAR_UNKNOWN; 16971 16972 /* Invoke the function. Recursive! */ 16973 s = functv.vval.v_string; 16974 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 16975 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 16976 &len, evaluate, selfdict); 16977 16978 /* Clear the funcref afterwards, so that deleting it while 16979 * evaluating the arguments is possible (see test55). */ 16980 clear_tv(&functv); 16981 16982 /* Stop the expression evaluation when immediately aborting on 16983 * error, or when an interrupt occurred or an exception was thrown 16984 * but not caught. */ 16985 if (aborting()) 16986 { 16987 if (ret == OK) 16988 clear_tv(rettv); 16989 ret = FAIL; 16990 } 16991 dict_unref(selfdict); 16992 selfdict = NULL; 16993 } 16994 else /* **arg == '[' || **arg == '.' */ 16995 { 16996 dict_unref(selfdict); 16997 if (rettv->v_type == VAR_DICT) 16998 { 16999 selfdict = rettv->vval.v_dict; 17000 if (selfdict != NULL) 17001 ++selfdict->dv_refcount; 17002 } 17003 else 17004 selfdict = NULL; 17005 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 17006 { 17007 clear_tv(rettv); 17008 ret = FAIL; 17009 } 17010 } 17011 } 17012 dict_unref(selfdict); 17013 return ret; 17014 } 17015 17016 /* 17017 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 17018 * value). 17019 */ 17020 static typval_T * 17021 alloc_tv() 17022 { 17023 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 17024 } 17025 17026 /* 17027 * Allocate memory for a variable type-value, and assign a string to it. 17028 * The string "s" must have been allocated, it is consumed. 17029 * Return NULL for out of memory, the variable otherwise. 17030 */ 17031 static typval_T * 17032 alloc_string_tv(s) 17033 char_u *s; 17034 { 17035 typval_T *rettv; 17036 17037 rettv = alloc_tv(); 17038 if (rettv != NULL) 17039 { 17040 rettv->v_type = VAR_STRING; 17041 rettv->vval.v_string = s; 17042 } 17043 else 17044 vim_free(s); 17045 return rettv; 17046 } 17047 17048 /* 17049 * Free the memory for a variable type-value. 17050 */ 17051 void 17052 free_tv(varp) 17053 typval_T *varp; 17054 { 17055 if (varp != NULL) 17056 { 17057 switch (varp->v_type) 17058 { 17059 case VAR_FUNC: 17060 func_unref(varp->vval.v_string); 17061 /*FALLTHROUGH*/ 17062 case VAR_STRING: 17063 vim_free(varp->vval.v_string); 17064 break; 17065 case VAR_LIST: 17066 list_unref(varp->vval.v_list); 17067 break; 17068 case VAR_DICT: 17069 dict_unref(varp->vval.v_dict); 17070 break; 17071 case VAR_NUMBER: 17072 case VAR_UNKNOWN: 17073 break; 17074 default: 17075 EMSG2(_(e_intern2), "free_tv()"); 17076 break; 17077 } 17078 vim_free(varp); 17079 } 17080 } 17081 17082 /* 17083 * Free the memory for a variable value and set the value to NULL or 0. 17084 */ 17085 void 17086 clear_tv(varp) 17087 typval_T *varp; 17088 { 17089 if (varp != NULL) 17090 { 17091 switch (varp->v_type) 17092 { 17093 case VAR_FUNC: 17094 func_unref(varp->vval.v_string); 17095 /*FALLTHROUGH*/ 17096 case VAR_STRING: 17097 vim_free(varp->vval.v_string); 17098 varp->vval.v_string = NULL; 17099 break; 17100 case VAR_LIST: 17101 list_unref(varp->vval.v_list); 17102 varp->vval.v_list = NULL; 17103 break; 17104 case VAR_DICT: 17105 dict_unref(varp->vval.v_dict); 17106 varp->vval.v_dict = NULL; 17107 break; 17108 case VAR_NUMBER: 17109 varp->vval.v_number = 0; 17110 break; 17111 case VAR_UNKNOWN: 17112 break; 17113 default: 17114 EMSG2(_(e_intern2), "clear_tv()"); 17115 } 17116 varp->v_lock = 0; 17117 } 17118 } 17119 17120 /* 17121 * Set the value of a variable to NULL without freeing items. 17122 */ 17123 static void 17124 init_tv(varp) 17125 typval_T *varp; 17126 { 17127 if (varp != NULL) 17128 vim_memset(varp, 0, sizeof(typval_T)); 17129 } 17130 17131 /* 17132 * Get the number value of a variable. 17133 * If it is a String variable, uses vim_str2nr(). 17134 * For incompatible types, return 0. 17135 * get_tv_number_chk() is similar to get_tv_number(), but informs the 17136 * caller of incompatible types: it sets *denote to TRUE if "denote" 17137 * is not NULL or returns -1 otherwise. 17138 */ 17139 static long 17140 get_tv_number(varp) 17141 typval_T *varp; 17142 { 17143 int error = FALSE; 17144 17145 return get_tv_number_chk(varp, &error); /* return 0L on error */ 17146 } 17147 17148 long 17149 get_tv_number_chk(varp, denote) 17150 typval_T *varp; 17151 int *denote; 17152 { 17153 long n = 0L; 17154 17155 switch (varp->v_type) 17156 { 17157 case VAR_NUMBER: 17158 return (long)(varp->vval.v_number); 17159 case VAR_FUNC: 17160 EMSG(_("E703: Using a Funcref as a number")); 17161 break; 17162 case VAR_STRING: 17163 if (varp->vval.v_string != NULL) 17164 vim_str2nr(varp->vval.v_string, NULL, NULL, 17165 TRUE, TRUE, &n, NULL); 17166 return n; 17167 case VAR_LIST: 17168 EMSG(_("E745: Using a List as a number")); 17169 break; 17170 case VAR_DICT: 17171 EMSG(_("E728: Using a Dictionary as a number")); 17172 break; 17173 default: 17174 EMSG2(_(e_intern2), "get_tv_number()"); 17175 break; 17176 } 17177 if (denote == NULL) /* useful for values that must be unsigned */ 17178 n = -1; 17179 else 17180 *denote = TRUE; 17181 return n; 17182 } 17183 17184 /* 17185 * Get the lnum from the first argument. 17186 * Also accepts ".", "$", etc., but that only works for the current buffer. 17187 * Returns -1 on error. 17188 */ 17189 static linenr_T 17190 get_tv_lnum(argvars) 17191 typval_T *argvars; 17192 { 17193 typval_T rettv; 17194 linenr_T lnum; 17195 17196 lnum = get_tv_number_chk(&argvars[0], NULL); 17197 if (lnum == 0) /* no valid number, try using line() */ 17198 { 17199 rettv.v_type = VAR_NUMBER; 17200 f_line(argvars, &rettv); 17201 lnum = rettv.vval.v_number; 17202 clear_tv(&rettv); 17203 } 17204 return lnum; 17205 } 17206 17207 /* 17208 * Get the lnum from the first argument. 17209 * Also accepts "$", then "buf" is used. 17210 * Returns 0 on error. 17211 */ 17212 static linenr_T 17213 get_tv_lnum_buf(argvars, buf) 17214 typval_T *argvars; 17215 buf_T *buf; 17216 { 17217 if (argvars[0].v_type == VAR_STRING 17218 && argvars[0].vval.v_string != NULL 17219 && argvars[0].vval.v_string[0] == '$' 17220 && buf != NULL) 17221 return buf->b_ml.ml_line_count; 17222 return get_tv_number_chk(&argvars[0], NULL); 17223 } 17224 17225 /* 17226 * Get the string value of a variable. 17227 * If it is a Number variable, the number is converted into a string. 17228 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 17229 * get_tv_string_buf() uses a given buffer. 17230 * If the String variable has never been set, return an empty string. 17231 * Never returns NULL; 17232 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 17233 * NULL on error. 17234 */ 17235 static char_u * 17236 get_tv_string(varp) 17237 typval_T *varp; 17238 { 17239 static char_u mybuf[NUMBUFLEN]; 17240 17241 return get_tv_string_buf(varp, mybuf); 17242 } 17243 17244 static char_u * 17245 get_tv_string_buf(varp, buf) 17246 typval_T *varp; 17247 char_u *buf; 17248 { 17249 char_u *res = get_tv_string_buf_chk(varp, buf); 17250 17251 return res != NULL ? res : (char_u *)""; 17252 } 17253 17254 char_u * 17255 get_tv_string_chk(varp) 17256 typval_T *varp; 17257 { 17258 static char_u mybuf[NUMBUFLEN]; 17259 17260 return get_tv_string_buf_chk(varp, mybuf); 17261 } 17262 17263 static char_u * 17264 get_tv_string_buf_chk(varp, buf) 17265 typval_T *varp; 17266 char_u *buf; 17267 { 17268 switch (varp->v_type) 17269 { 17270 case VAR_NUMBER: 17271 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 17272 return buf; 17273 case VAR_FUNC: 17274 EMSG(_("E729: using Funcref as a String")); 17275 break; 17276 case VAR_LIST: 17277 EMSG(_("E730: using List as a String")); 17278 break; 17279 case VAR_DICT: 17280 EMSG(_("E731: using Dictionary as a String")); 17281 break; 17282 case VAR_STRING: 17283 if (varp->vval.v_string != NULL) 17284 return varp->vval.v_string; 17285 return (char_u *)""; 17286 default: 17287 EMSG2(_(e_intern2), "get_tv_string_buf()"); 17288 break; 17289 } 17290 return NULL; 17291 } 17292 17293 /* 17294 * Find variable "name" in the list of variables. 17295 * Return a pointer to it if found, NULL if not found. 17296 * Careful: "a:0" variables don't have a name. 17297 * When "htp" is not NULL we are writing to the variable, set "htp" to the 17298 * hashtab_T used. 17299 */ 17300 static dictitem_T * 17301 find_var(name, htp) 17302 char_u *name; 17303 hashtab_T **htp; 17304 { 17305 char_u *varname; 17306 hashtab_T *ht; 17307 17308 ht = find_var_ht(name, &varname); 17309 if (htp != NULL) 17310 *htp = ht; 17311 if (ht == NULL) 17312 return NULL; 17313 return find_var_in_ht(ht, varname, htp != NULL); 17314 } 17315 17316 /* 17317 * Find variable "varname" in hashtab "ht". 17318 * Returns NULL if not found. 17319 */ 17320 static dictitem_T * 17321 find_var_in_ht(ht, varname, writing) 17322 hashtab_T *ht; 17323 char_u *varname; 17324 int writing; 17325 { 17326 hashitem_T *hi; 17327 17328 if (*varname == NUL) 17329 { 17330 /* Must be something like "s:", otherwise "ht" would be NULL. */ 17331 switch (varname[-2]) 17332 { 17333 case 's': return &SCRIPT_SV(current_SID).sv_var; 17334 case 'g': return &globvars_var; 17335 case 'v': return &vimvars_var; 17336 case 'b': return &curbuf->b_bufvar; 17337 case 'w': return &curwin->w_winvar; 17338 #ifdef FEAT_WINDOWS 17339 case 't': return &curtab->tp_winvar; 17340 #endif 17341 case 'l': return current_funccal == NULL 17342 ? NULL : ¤t_funccal->l_vars_var; 17343 case 'a': return current_funccal == NULL 17344 ? NULL : ¤t_funccal->l_avars_var; 17345 } 17346 return NULL; 17347 } 17348 17349 hi = hash_find(ht, varname); 17350 if (HASHITEM_EMPTY(hi)) 17351 { 17352 /* For global variables we may try auto-loading the script. If it 17353 * worked find the variable again. Don't auto-load a script if it was 17354 * loaded already, otherwise it would be loaded every time when 17355 * checking if a function name is a Funcref variable. */ 17356 if (ht == &globvarht && !writing 17357 && script_autoload(varname, FALSE) && !aborting()) 17358 hi = hash_find(ht, varname); 17359 if (HASHITEM_EMPTY(hi)) 17360 return NULL; 17361 } 17362 return HI2DI(hi); 17363 } 17364 17365 /* 17366 * Find the hashtab used for a variable name. 17367 * Set "varname" to the start of name without ':'. 17368 */ 17369 static hashtab_T * 17370 find_var_ht(name, varname) 17371 char_u *name; 17372 char_u **varname; 17373 { 17374 hashitem_T *hi; 17375 17376 if (name[1] != ':') 17377 { 17378 /* The name must not start with a colon or #. */ 17379 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 17380 return NULL; 17381 *varname = name; 17382 17383 /* "version" is "v:version" in all scopes */ 17384 hi = hash_find(&compat_hashtab, name); 17385 if (!HASHITEM_EMPTY(hi)) 17386 return &compat_hashtab; 17387 17388 if (current_funccal == NULL) 17389 return &globvarht; /* global variable */ 17390 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 17391 } 17392 *varname = name + 2; 17393 if (*name == 'g') /* global variable */ 17394 return &globvarht; 17395 /* There must be no ':' or '#' in the rest of the name, unless g: is used 17396 */ 17397 if (vim_strchr(name + 2, ':') != NULL 17398 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 17399 return NULL; 17400 if (*name == 'b') /* buffer variable */ 17401 return &curbuf->b_vars.dv_hashtab; 17402 if (*name == 'w') /* window variable */ 17403 return &curwin->w_vars.dv_hashtab; 17404 #ifdef FEAT_WINDOWS 17405 if (*name == 't') /* tab page variable */ 17406 return &curtab->tp_vars.dv_hashtab; 17407 #endif 17408 if (*name == 'v') /* v: variable */ 17409 return &vimvarht; 17410 if (*name == 'a' && current_funccal != NULL) /* function argument */ 17411 return ¤t_funccal->l_avars.dv_hashtab; 17412 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 17413 return ¤t_funccal->l_vars.dv_hashtab; 17414 if (*name == 's' /* script variable */ 17415 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 17416 return &SCRIPT_VARS(current_SID); 17417 return NULL; 17418 } 17419 17420 /* 17421 * Get the string value of a (global/local) variable. 17422 * Returns NULL when it doesn't exist. 17423 */ 17424 char_u * 17425 get_var_value(name) 17426 char_u *name; 17427 { 17428 dictitem_T *v; 17429 17430 v = find_var(name, NULL); 17431 if (v == NULL) 17432 return NULL; 17433 return get_tv_string(&v->di_tv); 17434 } 17435 17436 /* 17437 * Allocate a new hashtab for a sourced script. It will be used while 17438 * sourcing this script and when executing functions defined in the script. 17439 */ 17440 void 17441 new_script_vars(id) 17442 scid_T id; 17443 { 17444 int i; 17445 hashtab_T *ht; 17446 scriptvar_T *sv; 17447 17448 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 17449 { 17450 /* Re-allocating ga_data means that an ht_array pointing to 17451 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 17452 * at its init value. Also reset "v_dict", it's always the same. */ 17453 for (i = 1; i <= ga_scripts.ga_len; ++i) 17454 { 17455 ht = &SCRIPT_VARS(i); 17456 if (ht->ht_mask == HT_INIT_SIZE - 1) 17457 ht->ht_array = ht->ht_smallarray; 17458 sv = &SCRIPT_SV(i); 17459 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 17460 } 17461 17462 while (ga_scripts.ga_len < id) 17463 { 17464 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 17465 init_var_dict(&sv->sv_dict, &sv->sv_var); 17466 ++ga_scripts.ga_len; 17467 } 17468 } 17469 } 17470 17471 /* 17472 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 17473 * point to it. 17474 */ 17475 void 17476 init_var_dict(dict, dict_var) 17477 dict_T *dict; 17478 dictitem_T *dict_var; 17479 { 17480 hash_init(&dict->dv_hashtab); 17481 dict->dv_refcount = 99999; 17482 dict_var->di_tv.vval.v_dict = dict; 17483 dict_var->di_tv.v_type = VAR_DICT; 17484 dict_var->di_tv.v_lock = VAR_FIXED; 17485 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 17486 dict_var->di_key[0] = NUL; 17487 } 17488 17489 /* 17490 * Clean up a list of internal variables. 17491 * Frees all allocated variables and the value they contain. 17492 * Clears hashtab "ht", does not free it. 17493 */ 17494 void 17495 vars_clear(ht) 17496 hashtab_T *ht; 17497 { 17498 vars_clear_ext(ht, TRUE); 17499 } 17500 17501 /* 17502 * Like vars_clear(), but only free the value if "free_val" is TRUE. 17503 */ 17504 static void 17505 vars_clear_ext(ht, free_val) 17506 hashtab_T *ht; 17507 int free_val; 17508 { 17509 int todo; 17510 hashitem_T *hi; 17511 dictitem_T *v; 17512 17513 hash_lock(ht); 17514 todo = (int)ht->ht_used; 17515 for (hi = ht->ht_array; todo > 0; ++hi) 17516 { 17517 if (!HASHITEM_EMPTY(hi)) 17518 { 17519 --todo; 17520 17521 /* Free the variable. Don't remove it from the hashtab, 17522 * ht_array might change then. hash_clear() takes care of it 17523 * later. */ 17524 v = HI2DI(hi); 17525 if (free_val) 17526 clear_tv(&v->di_tv); 17527 if ((v->di_flags & DI_FLAGS_FIX) == 0) 17528 vim_free(v); 17529 } 17530 } 17531 hash_clear(ht); 17532 ht->ht_used = 0; 17533 } 17534 17535 /* 17536 * Delete a variable from hashtab "ht" at item "hi". 17537 * Clear the variable value and free the dictitem. 17538 */ 17539 static void 17540 delete_var(ht, hi) 17541 hashtab_T *ht; 17542 hashitem_T *hi; 17543 { 17544 dictitem_T *di = HI2DI(hi); 17545 17546 hash_remove(ht, hi); 17547 clear_tv(&di->di_tv); 17548 vim_free(di); 17549 } 17550 17551 /* 17552 * List the value of one internal variable. 17553 */ 17554 static void 17555 list_one_var(v, prefix) 17556 dictitem_T *v; 17557 char_u *prefix; 17558 { 17559 char_u *tofree; 17560 char_u *s; 17561 char_u numbuf[NUMBUFLEN]; 17562 17563 s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID); 17564 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 17565 s == NULL ? (char_u *)"" : s); 17566 vim_free(tofree); 17567 } 17568 17569 static void 17570 list_one_var_a(prefix, name, type, string) 17571 char_u *prefix; 17572 char_u *name; 17573 int type; 17574 char_u *string; 17575 { 17576 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 17577 if (name != NULL) /* "a:" vars don't have a name stored */ 17578 msg_puts(name); 17579 msg_putchar(' '); 17580 msg_advance(22); 17581 if (type == VAR_NUMBER) 17582 msg_putchar('#'); 17583 else if (type == VAR_FUNC) 17584 msg_putchar('*'); 17585 else if (type == VAR_LIST) 17586 { 17587 msg_putchar('['); 17588 if (*string == '[') 17589 ++string; 17590 } 17591 else if (type == VAR_DICT) 17592 { 17593 msg_putchar('{'); 17594 if (*string == '{') 17595 ++string; 17596 } 17597 else 17598 msg_putchar(' '); 17599 17600 msg_outtrans(string); 17601 17602 if (type == VAR_FUNC) 17603 msg_puts((char_u *)"()"); 17604 } 17605 17606 /* 17607 * Set variable "name" to value in "tv". 17608 * If the variable already exists, the value is updated. 17609 * Otherwise the variable is created. 17610 */ 17611 static void 17612 set_var(name, tv, copy) 17613 char_u *name; 17614 typval_T *tv; 17615 int copy; /* make copy of value in "tv" */ 17616 { 17617 dictitem_T *v; 17618 char_u *varname; 17619 hashtab_T *ht; 17620 char_u *p; 17621 17622 if (tv->v_type == VAR_FUNC) 17623 { 17624 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 17625 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 17626 ? name[2] : name[0])) 17627 { 17628 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 17629 return; 17630 } 17631 if (function_exists(name)) 17632 { 17633 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 17634 name); 17635 return; 17636 } 17637 } 17638 17639 ht = find_var_ht(name, &varname); 17640 if (ht == NULL || *varname == NUL) 17641 { 17642 EMSG2(_(e_illvar), name); 17643 return; 17644 } 17645 17646 v = find_var_in_ht(ht, varname, TRUE); 17647 if (v != NULL) 17648 { 17649 /* existing variable, need to clear the value */ 17650 if (var_check_ro(v->di_flags, name) 17651 || tv_check_lock(v->di_tv.v_lock, name)) 17652 return; 17653 if (v->di_tv.v_type != tv->v_type 17654 && !((v->di_tv.v_type == VAR_STRING 17655 || v->di_tv.v_type == VAR_NUMBER) 17656 && (tv->v_type == VAR_STRING 17657 || tv->v_type == VAR_NUMBER))) 17658 { 17659 EMSG2(_("E706: Variable type mismatch for: %s"), name); 17660 return; 17661 } 17662 17663 /* 17664 * Handle setting internal v: variables separately: we don't change 17665 * the type. 17666 */ 17667 if (ht == &vimvarht) 17668 { 17669 if (v->di_tv.v_type == VAR_STRING) 17670 { 17671 vim_free(v->di_tv.vval.v_string); 17672 if (copy || tv->v_type != VAR_STRING) 17673 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 17674 else 17675 { 17676 /* Take over the string to avoid an extra alloc/free. */ 17677 v->di_tv.vval.v_string = tv->vval.v_string; 17678 tv->vval.v_string = NULL; 17679 } 17680 } 17681 else if (v->di_tv.v_type != VAR_NUMBER) 17682 EMSG2(_(e_intern2), "set_var()"); 17683 else 17684 v->di_tv.vval.v_number = get_tv_number(tv); 17685 return; 17686 } 17687 17688 clear_tv(&v->di_tv); 17689 } 17690 else /* add a new variable */ 17691 { 17692 /* Make sure the variable name is valid. */ 17693 for (p = varname; *p != NUL; ++p) 17694 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 17695 && *p != AUTOLOAD_CHAR) 17696 { 17697 EMSG2(_(e_illvar), varname); 17698 return; 17699 } 17700 17701 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 17702 + STRLEN(varname))); 17703 if (v == NULL) 17704 return; 17705 STRCPY(v->di_key, varname); 17706 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 17707 { 17708 vim_free(v); 17709 return; 17710 } 17711 v->di_flags = 0; 17712 } 17713 17714 if (copy || tv->v_type == VAR_NUMBER) 17715 copy_tv(tv, &v->di_tv); 17716 else 17717 { 17718 v->di_tv = *tv; 17719 v->di_tv.v_lock = 0; 17720 init_tv(tv); 17721 } 17722 } 17723 17724 /* 17725 * Return TRUE if di_flags "flags" indicate read-only variable "name". 17726 * Also give an error message. 17727 */ 17728 static int 17729 var_check_ro(flags, name) 17730 int flags; 17731 char_u *name; 17732 { 17733 if (flags & DI_FLAGS_RO) 17734 { 17735 EMSG2(_(e_readonlyvar), name); 17736 return TRUE; 17737 } 17738 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 17739 { 17740 EMSG2(_(e_readonlysbx), name); 17741 return TRUE; 17742 } 17743 return FALSE; 17744 } 17745 17746 /* 17747 * Return TRUE if typeval "tv" is set to be locked (immutable). 17748 * Also give an error message, using "name". 17749 */ 17750 static int 17751 tv_check_lock(lock, name) 17752 int lock; 17753 char_u *name; 17754 { 17755 if (lock & VAR_LOCKED) 17756 { 17757 EMSG2(_("E741: Value is locked: %s"), 17758 name == NULL ? (char_u *)_("Unknown") : name); 17759 return TRUE; 17760 } 17761 if (lock & VAR_FIXED) 17762 { 17763 EMSG2(_("E742: Cannot change value of %s"), 17764 name == NULL ? (char_u *)_("Unknown") : name); 17765 return TRUE; 17766 } 17767 return FALSE; 17768 } 17769 17770 /* 17771 * Copy the values from typval_T "from" to typval_T "to". 17772 * When needed allocates string or increases reference count. 17773 * Does not make a copy of a list or dict but copies the reference! 17774 */ 17775 static void 17776 copy_tv(from, to) 17777 typval_T *from; 17778 typval_T *to; 17779 { 17780 to->v_type = from->v_type; 17781 to->v_lock = 0; 17782 switch (from->v_type) 17783 { 17784 case VAR_NUMBER: 17785 to->vval.v_number = from->vval.v_number; 17786 break; 17787 case VAR_STRING: 17788 case VAR_FUNC: 17789 if (from->vval.v_string == NULL) 17790 to->vval.v_string = NULL; 17791 else 17792 { 17793 to->vval.v_string = vim_strsave(from->vval.v_string); 17794 if (from->v_type == VAR_FUNC) 17795 func_ref(to->vval.v_string); 17796 } 17797 break; 17798 case VAR_LIST: 17799 if (from->vval.v_list == NULL) 17800 to->vval.v_list = NULL; 17801 else 17802 { 17803 to->vval.v_list = from->vval.v_list; 17804 ++to->vval.v_list->lv_refcount; 17805 } 17806 break; 17807 case VAR_DICT: 17808 if (from->vval.v_dict == NULL) 17809 to->vval.v_dict = NULL; 17810 else 17811 { 17812 to->vval.v_dict = from->vval.v_dict; 17813 ++to->vval.v_dict->dv_refcount; 17814 } 17815 break; 17816 default: 17817 EMSG2(_(e_intern2), "copy_tv()"); 17818 break; 17819 } 17820 } 17821 17822 /* 17823 * Make a copy of an item. 17824 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 17825 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 17826 * reference to an already copied list/dict can be used. 17827 * Returns FAIL or OK. 17828 */ 17829 static int 17830 item_copy(from, to, deep, copyID) 17831 typval_T *from; 17832 typval_T *to; 17833 int deep; 17834 int copyID; 17835 { 17836 static int recurse = 0; 17837 int ret = OK; 17838 17839 if (recurse >= DICT_MAXNEST) 17840 { 17841 EMSG(_("E698: variable nested too deep for making a copy")); 17842 return FAIL; 17843 } 17844 ++recurse; 17845 17846 switch (from->v_type) 17847 { 17848 case VAR_NUMBER: 17849 case VAR_STRING: 17850 case VAR_FUNC: 17851 copy_tv(from, to); 17852 break; 17853 case VAR_LIST: 17854 to->v_type = VAR_LIST; 17855 to->v_lock = 0; 17856 if (from->vval.v_list == NULL) 17857 to->vval.v_list = NULL; 17858 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 17859 { 17860 /* use the copy made earlier */ 17861 to->vval.v_list = from->vval.v_list->lv_copylist; 17862 ++to->vval.v_list->lv_refcount; 17863 } 17864 else 17865 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 17866 if (to->vval.v_list == NULL) 17867 ret = FAIL; 17868 break; 17869 case VAR_DICT: 17870 to->v_type = VAR_DICT; 17871 to->v_lock = 0; 17872 if (from->vval.v_dict == NULL) 17873 to->vval.v_dict = NULL; 17874 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 17875 { 17876 /* use the copy made earlier */ 17877 to->vval.v_dict = from->vval.v_dict->dv_copydict; 17878 ++to->vval.v_dict->dv_refcount; 17879 } 17880 else 17881 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 17882 if (to->vval.v_dict == NULL) 17883 ret = FAIL; 17884 break; 17885 default: 17886 EMSG2(_(e_intern2), "item_copy()"); 17887 ret = FAIL; 17888 } 17889 --recurse; 17890 return ret; 17891 } 17892 17893 /* 17894 * ":echo expr1 ..." print each argument separated with a space, add a 17895 * newline at the end. 17896 * ":echon expr1 ..." print each argument plain. 17897 */ 17898 void 17899 ex_echo(eap) 17900 exarg_T *eap; 17901 { 17902 char_u *arg = eap->arg; 17903 typval_T rettv; 17904 char_u *tofree; 17905 char_u *p; 17906 int needclr = TRUE; 17907 int atstart = TRUE; 17908 char_u numbuf[NUMBUFLEN]; 17909 17910 if (eap->skip) 17911 ++emsg_skip; 17912 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 17913 { 17914 p = arg; 17915 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 17916 { 17917 /* 17918 * Report the invalid expression unless the expression evaluation 17919 * has been cancelled due to an aborting error, an interrupt, or an 17920 * exception. 17921 */ 17922 if (!aborting()) 17923 EMSG2(_(e_invexpr2), p); 17924 break; 17925 } 17926 if (!eap->skip) 17927 { 17928 if (atstart) 17929 { 17930 atstart = FALSE; 17931 /* Call msg_start() after eval1(), evaluating the expression 17932 * may cause a message to appear. */ 17933 if (eap->cmdidx == CMD_echo) 17934 msg_start(); 17935 } 17936 else if (eap->cmdidx == CMD_echo) 17937 msg_puts_attr((char_u *)" ", echo_attr); 17938 p = echo_string(&rettv, &tofree, numbuf, ++current_copyID); 17939 if (p != NULL) 17940 for ( ; *p != NUL && !got_int; ++p) 17941 { 17942 if (*p == '\n' || *p == '\r' || *p == TAB) 17943 { 17944 if (*p != TAB && needclr) 17945 { 17946 /* remove any text still there from the command */ 17947 msg_clr_eos(); 17948 needclr = FALSE; 17949 } 17950 msg_putchar_attr(*p, echo_attr); 17951 } 17952 else 17953 { 17954 #ifdef FEAT_MBYTE 17955 if (has_mbyte) 17956 { 17957 int i = (*mb_ptr2len)(p); 17958 17959 (void)msg_outtrans_len_attr(p, i, echo_attr); 17960 p += i - 1; 17961 } 17962 else 17963 #endif 17964 (void)msg_outtrans_len_attr(p, 1, echo_attr); 17965 } 17966 } 17967 vim_free(tofree); 17968 } 17969 clear_tv(&rettv); 17970 arg = skipwhite(arg); 17971 } 17972 eap->nextcmd = check_nextcmd(arg); 17973 17974 if (eap->skip) 17975 --emsg_skip; 17976 else 17977 { 17978 /* remove text that may still be there from the command */ 17979 if (needclr) 17980 msg_clr_eos(); 17981 if (eap->cmdidx == CMD_echo) 17982 msg_end(); 17983 } 17984 } 17985 17986 /* 17987 * ":echohl {name}". 17988 */ 17989 void 17990 ex_echohl(eap) 17991 exarg_T *eap; 17992 { 17993 int id; 17994 17995 id = syn_name2id(eap->arg); 17996 if (id == 0) 17997 echo_attr = 0; 17998 else 17999 echo_attr = syn_id2attr(id); 18000 } 18001 18002 /* 18003 * ":execute expr1 ..." execute the result of an expression. 18004 * ":echomsg expr1 ..." Print a message 18005 * ":echoerr expr1 ..." Print an error 18006 * Each gets spaces around each argument and a newline at the end for 18007 * echo commands 18008 */ 18009 void 18010 ex_execute(eap) 18011 exarg_T *eap; 18012 { 18013 char_u *arg = eap->arg; 18014 typval_T rettv; 18015 int ret = OK; 18016 char_u *p; 18017 garray_T ga; 18018 int len; 18019 int save_did_emsg; 18020 18021 ga_init2(&ga, 1, 80); 18022 18023 if (eap->skip) 18024 ++emsg_skip; 18025 while (*arg != NUL && *arg != '|' && *arg != '\n') 18026 { 18027 p = arg; 18028 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 18029 { 18030 /* 18031 * Report the invalid expression unless the expression evaluation 18032 * has been cancelled due to an aborting error, an interrupt, or an 18033 * exception. 18034 */ 18035 if (!aborting()) 18036 EMSG2(_(e_invexpr2), p); 18037 ret = FAIL; 18038 break; 18039 } 18040 18041 if (!eap->skip) 18042 { 18043 p = get_tv_string(&rettv); 18044 len = (int)STRLEN(p); 18045 if (ga_grow(&ga, len + 2) == FAIL) 18046 { 18047 clear_tv(&rettv); 18048 ret = FAIL; 18049 break; 18050 } 18051 if (ga.ga_len) 18052 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 18053 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 18054 ga.ga_len += len; 18055 } 18056 18057 clear_tv(&rettv); 18058 arg = skipwhite(arg); 18059 } 18060 18061 if (ret != FAIL && ga.ga_data != NULL) 18062 { 18063 if (eap->cmdidx == CMD_echomsg) 18064 { 18065 MSG_ATTR(ga.ga_data, echo_attr); 18066 out_flush(); 18067 } 18068 else if (eap->cmdidx == CMD_echoerr) 18069 { 18070 /* We don't want to abort following commands, restore did_emsg. */ 18071 save_did_emsg = did_emsg; 18072 EMSG((char_u *)ga.ga_data); 18073 if (!force_abort) 18074 did_emsg = save_did_emsg; 18075 } 18076 else if (eap->cmdidx == CMD_execute) 18077 do_cmdline((char_u *)ga.ga_data, 18078 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 18079 } 18080 18081 ga_clear(&ga); 18082 18083 if (eap->skip) 18084 --emsg_skip; 18085 18086 eap->nextcmd = check_nextcmd(arg); 18087 } 18088 18089 /* 18090 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 18091 * "arg" points to the "&" or '+' when called, to "option" when returning. 18092 * Returns NULL when no option name found. Otherwise pointer to the char 18093 * after the option name. 18094 */ 18095 static char_u * 18096 find_option_end(arg, opt_flags) 18097 char_u **arg; 18098 int *opt_flags; 18099 { 18100 char_u *p = *arg; 18101 18102 ++p; 18103 if (*p == 'g' && p[1] == ':') 18104 { 18105 *opt_flags = OPT_GLOBAL; 18106 p += 2; 18107 } 18108 else if (*p == 'l' && p[1] == ':') 18109 { 18110 *opt_flags = OPT_LOCAL; 18111 p += 2; 18112 } 18113 else 18114 *opt_flags = 0; 18115 18116 if (!ASCII_ISALPHA(*p)) 18117 return NULL; 18118 *arg = p; 18119 18120 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 18121 p += 4; /* termcap option */ 18122 else 18123 while (ASCII_ISALPHA(*p)) 18124 ++p; 18125 return p; 18126 } 18127 18128 /* 18129 * ":function" 18130 */ 18131 void 18132 ex_function(eap) 18133 exarg_T *eap; 18134 { 18135 char_u *theline; 18136 int j; 18137 int c; 18138 int saved_did_emsg; 18139 char_u *name = NULL; 18140 char_u *p; 18141 char_u *arg; 18142 char_u *line_arg = NULL; 18143 garray_T newargs; 18144 garray_T newlines; 18145 int varargs = FALSE; 18146 int mustend = FALSE; 18147 int flags = 0; 18148 ufunc_T *fp; 18149 int indent; 18150 int nesting; 18151 char_u *skip_until = NULL; 18152 dictitem_T *v; 18153 funcdict_T fudi; 18154 static int func_nr = 0; /* number for nameless function */ 18155 int paren; 18156 hashtab_T *ht; 18157 int todo; 18158 hashitem_T *hi; 18159 int sourcing_lnum_off; 18160 18161 /* 18162 * ":function" without argument: list functions. 18163 */ 18164 if (ends_excmd(*eap->arg)) 18165 { 18166 if (!eap->skip) 18167 { 18168 todo = (int)func_hashtab.ht_used; 18169 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 18170 { 18171 if (!HASHITEM_EMPTY(hi)) 18172 { 18173 --todo; 18174 fp = HI2UF(hi); 18175 if (!isdigit(*fp->uf_name)) 18176 list_func_head(fp, FALSE); 18177 } 18178 } 18179 } 18180 eap->nextcmd = check_nextcmd(eap->arg); 18181 return; 18182 } 18183 18184 /* 18185 * ":function /pat": list functions matching pattern. 18186 */ 18187 if (*eap->arg == '/') 18188 { 18189 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 18190 if (!eap->skip) 18191 { 18192 regmatch_T regmatch; 18193 18194 c = *p; 18195 *p = NUL; 18196 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 18197 *p = c; 18198 if (regmatch.regprog != NULL) 18199 { 18200 regmatch.rm_ic = p_ic; 18201 18202 todo = (int)func_hashtab.ht_used; 18203 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 18204 { 18205 if (!HASHITEM_EMPTY(hi)) 18206 { 18207 --todo; 18208 fp = HI2UF(hi); 18209 if (!isdigit(*fp->uf_name) 18210 && vim_regexec(®match, fp->uf_name, 0)) 18211 list_func_head(fp, FALSE); 18212 } 18213 } 18214 } 18215 } 18216 if (*p == '/') 18217 ++p; 18218 eap->nextcmd = check_nextcmd(p); 18219 return; 18220 } 18221 18222 /* 18223 * Get the function name. There are these situations: 18224 * func normal function name 18225 * "name" == func, "fudi.fd_dict" == NULL 18226 * dict.func new dictionary entry 18227 * "name" == NULL, "fudi.fd_dict" set, 18228 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 18229 * dict.func existing dict entry with a Funcref 18230 * "name" == func, "fudi.fd_dict" set, 18231 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 18232 * dict.func existing dict entry that's not a Funcref 18233 * "name" == NULL, "fudi.fd_dict" set, 18234 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 18235 */ 18236 p = eap->arg; 18237 name = trans_function_name(&p, eap->skip, 0, &fudi); 18238 paren = (vim_strchr(p, '(') != NULL); 18239 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 18240 { 18241 /* 18242 * Return on an invalid expression in braces, unless the expression 18243 * evaluation has been cancelled due to an aborting error, an 18244 * interrupt, or an exception. 18245 */ 18246 if (!aborting()) 18247 { 18248 if (!eap->skip && fudi.fd_newkey != NULL) 18249 EMSG2(_(e_dictkey), fudi.fd_newkey); 18250 vim_free(fudi.fd_newkey); 18251 return; 18252 } 18253 else 18254 eap->skip = TRUE; 18255 } 18256 18257 /* An error in a function call during evaluation of an expression in magic 18258 * braces should not cause the function not to be defined. */ 18259 saved_did_emsg = did_emsg; 18260 did_emsg = FALSE; 18261 18262 /* 18263 * ":function func" with only function name: list function. 18264 */ 18265 if (!paren) 18266 { 18267 if (!ends_excmd(*skipwhite(p))) 18268 { 18269 EMSG(_(e_trailing)); 18270 goto ret_free; 18271 } 18272 eap->nextcmd = check_nextcmd(p); 18273 if (eap->nextcmd != NULL) 18274 *p = NUL; 18275 if (!eap->skip && !got_int) 18276 { 18277 fp = find_func(name); 18278 if (fp != NULL) 18279 { 18280 list_func_head(fp, TRUE); 18281 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 18282 { 18283 if (FUNCLINE(fp, j) == NULL) 18284 continue; 18285 msg_putchar('\n'); 18286 msg_outnum((long)(j + 1)); 18287 if (j < 9) 18288 msg_putchar(' '); 18289 if (j < 99) 18290 msg_putchar(' '); 18291 msg_prt_line(FUNCLINE(fp, j), FALSE); 18292 out_flush(); /* show a line at a time */ 18293 ui_breakcheck(); 18294 } 18295 if (!got_int) 18296 { 18297 msg_putchar('\n'); 18298 msg_puts((char_u *)" endfunction"); 18299 } 18300 } 18301 else 18302 emsg_funcname("E123: Undefined function: %s", name); 18303 } 18304 goto ret_free; 18305 } 18306 18307 /* 18308 * ":function name(arg1, arg2)" Define function. 18309 */ 18310 p = skipwhite(p); 18311 if (*p != '(') 18312 { 18313 if (!eap->skip) 18314 { 18315 EMSG2(_("E124: Missing '(': %s"), eap->arg); 18316 goto ret_free; 18317 } 18318 /* attempt to continue by skipping some text */ 18319 if (vim_strchr(p, '(') != NULL) 18320 p = vim_strchr(p, '('); 18321 } 18322 p = skipwhite(p + 1); 18323 18324 ga_init2(&newargs, (int)sizeof(char_u *), 3); 18325 ga_init2(&newlines, (int)sizeof(char_u *), 3); 18326 18327 if (!eap->skip) 18328 { 18329 /* Check the name of the function. */ 18330 if (name != NULL) 18331 arg = name; 18332 else 18333 arg = fudi.fd_newkey; 18334 if (arg != NULL) 18335 { 18336 if (*arg == K_SPECIAL) 18337 j = 3; 18338 else 18339 j = 0; 18340 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 18341 : eval_isnamec(arg[j]))) 18342 ++j; 18343 if (arg[j] != NUL) 18344 emsg_funcname(_(e_invarg2), arg); 18345 } 18346 } 18347 18348 /* 18349 * Isolate the arguments: "arg1, arg2, ...)" 18350 */ 18351 while (*p != ')') 18352 { 18353 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 18354 { 18355 varargs = TRUE; 18356 p += 3; 18357 mustend = TRUE; 18358 } 18359 else 18360 { 18361 arg = p; 18362 while (ASCII_ISALNUM(*p) || *p == '_') 18363 ++p; 18364 if (arg == p || isdigit(*arg) 18365 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 18366 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 18367 { 18368 if (!eap->skip) 18369 EMSG2(_("E125: Illegal argument: %s"), arg); 18370 break; 18371 } 18372 if (ga_grow(&newargs, 1) == FAIL) 18373 goto erret; 18374 c = *p; 18375 *p = NUL; 18376 arg = vim_strsave(arg); 18377 if (arg == NULL) 18378 goto erret; 18379 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 18380 *p = c; 18381 newargs.ga_len++; 18382 if (*p == ',') 18383 ++p; 18384 else 18385 mustend = TRUE; 18386 } 18387 p = skipwhite(p); 18388 if (mustend && *p != ')') 18389 { 18390 if (!eap->skip) 18391 EMSG2(_(e_invarg2), eap->arg); 18392 break; 18393 } 18394 } 18395 ++p; /* skip the ')' */ 18396 18397 /* find extra arguments "range", "dict" and "abort" */ 18398 for (;;) 18399 { 18400 p = skipwhite(p); 18401 if (STRNCMP(p, "range", 5) == 0) 18402 { 18403 flags |= FC_RANGE; 18404 p += 5; 18405 } 18406 else if (STRNCMP(p, "dict", 4) == 0) 18407 { 18408 flags |= FC_DICT; 18409 p += 4; 18410 } 18411 else if (STRNCMP(p, "abort", 5) == 0) 18412 { 18413 flags |= FC_ABORT; 18414 p += 5; 18415 } 18416 else 18417 break; 18418 } 18419 18420 /* When there is a line break use what follows for the function body. 18421 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 18422 if (*p == '\n') 18423 line_arg = p + 1; 18424 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 18425 EMSG(_(e_trailing)); 18426 18427 /* 18428 * Read the body of the function, until ":endfunction" is found. 18429 */ 18430 if (KeyTyped) 18431 { 18432 /* Check if the function already exists, don't let the user type the 18433 * whole function before telling him it doesn't work! For a script we 18434 * need to skip the body to be able to find what follows. */ 18435 if (!eap->skip && !eap->forceit) 18436 { 18437 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 18438 EMSG(_(e_funcdict)); 18439 else if (name != NULL && find_func(name) != NULL) 18440 emsg_funcname(e_funcexts, name); 18441 } 18442 18443 if (!eap->skip && did_emsg) 18444 goto erret; 18445 18446 msg_putchar('\n'); /* don't overwrite the function name */ 18447 cmdline_row = msg_row; 18448 } 18449 18450 indent = 2; 18451 nesting = 0; 18452 for (;;) 18453 { 18454 msg_scroll = TRUE; 18455 need_wait_return = FALSE; 18456 sourcing_lnum_off = sourcing_lnum; 18457 18458 if (line_arg != NULL) 18459 { 18460 /* Use eap->arg, split up in parts by line breaks. */ 18461 theline = line_arg; 18462 p = vim_strchr(theline, '\n'); 18463 if (p == NULL) 18464 line_arg += STRLEN(line_arg); 18465 else 18466 { 18467 *p = NUL; 18468 line_arg = p + 1; 18469 } 18470 } 18471 else if (eap->getline == NULL) 18472 theline = getcmdline(':', 0L, indent); 18473 else 18474 theline = eap->getline(':', eap->cookie, indent); 18475 if (KeyTyped) 18476 lines_left = Rows - 1; 18477 if (theline == NULL) 18478 { 18479 EMSG(_("E126: Missing :endfunction")); 18480 goto erret; 18481 } 18482 18483 /* Detect line continuation: sourcing_lnum increased more than one. */ 18484 if (sourcing_lnum > sourcing_lnum_off + 1) 18485 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 18486 else 18487 sourcing_lnum_off = 0; 18488 18489 if (skip_until != NULL) 18490 { 18491 /* between ":append" and "." and between ":python <<EOF" and "EOF" 18492 * don't check for ":endfunc". */ 18493 if (STRCMP(theline, skip_until) == 0) 18494 { 18495 vim_free(skip_until); 18496 skip_until = NULL; 18497 } 18498 } 18499 else 18500 { 18501 /* skip ':' and blanks*/ 18502 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 18503 ; 18504 18505 /* Check for "endfunction". */ 18506 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 18507 { 18508 if (line_arg == NULL) 18509 vim_free(theline); 18510 break; 18511 } 18512 18513 /* Increase indent inside "if", "while", "for" and "try", decrease 18514 * at "end". */ 18515 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 18516 indent -= 2; 18517 else if (STRNCMP(p, "if", 2) == 0 18518 || STRNCMP(p, "wh", 2) == 0 18519 || STRNCMP(p, "for", 3) == 0 18520 || STRNCMP(p, "try", 3) == 0) 18521 indent += 2; 18522 18523 /* Check for defining a function inside this function. */ 18524 if (checkforcmd(&p, "function", 2)) 18525 { 18526 if (*p == '!') 18527 p = skipwhite(p + 1); 18528 p += eval_fname_script(p); 18529 if (ASCII_ISALPHA(*p)) 18530 { 18531 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 18532 if (*skipwhite(p) == '(') 18533 { 18534 ++nesting; 18535 indent += 2; 18536 } 18537 } 18538 } 18539 18540 /* Check for ":append" or ":insert". */ 18541 p = skip_range(p, NULL); 18542 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 18543 || (p[0] == 'i' 18544 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 18545 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 18546 skip_until = vim_strsave((char_u *)"."); 18547 18548 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 18549 arg = skipwhite(skiptowhite(p)); 18550 if (arg[0] == '<' && arg[1] =='<' 18551 && ((p[0] == 'p' && p[1] == 'y' 18552 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 18553 || (p[0] == 'p' && p[1] == 'e' 18554 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 18555 || (p[0] == 't' && p[1] == 'c' 18556 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 18557 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 18558 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 18559 || (p[0] == 'm' && p[1] == 'z' 18560 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 18561 )) 18562 { 18563 /* ":python <<" continues until a dot, like ":append" */ 18564 p = skipwhite(arg + 2); 18565 if (*p == NUL) 18566 skip_until = vim_strsave((char_u *)"."); 18567 else 18568 skip_until = vim_strsave(p); 18569 } 18570 } 18571 18572 /* Add the line to the function. */ 18573 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 18574 { 18575 if (line_arg == NULL) 18576 vim_free(theline); 18577 goto erret; 18578 } 18579 18580 /* Copy the line to newly allocated memory. get_one_sourceline() 18581 * allocates 250 bytes per line, this saves 80% on average. The cost 18582 * is an extra alloc/free. */ 18583 p = vim_strsave(theline); 18584 if (p != NULL) 18585 { 18586 if (line_arg == NULL) 18587 vim_free(theline); 18588 theline = p; 18589 } 18590 18591 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 18592 18593 /* Add NULL lines for continuation lines, so that the line count is 18594 * equal to the index in the growarray. */ 18595 while (sourcing_lnum_off-- > 0) 18596 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 18597 18598 /* Check for end of eap->arg. */ 18599 if (line_arg != NULL && *line_arg == NUL) 18600 line_arg = NULL; 18601 } 18602 18603 /* Don't define the function when skipping commands or when an error was 18604 * detected. */ 18605 if (eap->skip || did_emsg) 18606 goto erret; 18607 18608 /* 18609 * If there are no errors, add the function 18610 */ 18611 if (fudi.fd_dict == NULL) 18612 { 18613 v = find_var(name, &ht); 18614 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 18615 { 18616 emsg_funcname("E707: Function name conflicts with variable: %s", 18617 name); 18618 goto erret; 18619 } 18620 18621 fp = find_func(name); 18622 if (fp != NULL) 18623 { 18624 if (!eap->forceit) 18625 { 18626 emsg_funcname(e_funcexts, name); 18627 goto erret; 18628 } 18629 if (fp->uf_calls > 0) 18630 { 18631 emsg_funcname("E127: Cannot redefine function %s: It is in use", 18632 name); 18633 goto erret; 18634 } 18635 /* redefine existing function */ 18636 ga_clear_strings(&(fp->uf_args)); 18637 ga_clear_strings(&(fp->uf_lines)); 18638 vim_free(name); 18639 name = NULL; 18640 } 18641 } 18642 else 18643 { 18644 char numbuf[20]; 18645 18646 fp = NULL; 18647 if (fudi.fd_newkey == NULL && !eap->forceit) 18648 { 18649 EMSG(_(e_funcdict)); 18650 goto erret; 18651 } 18652 if (fudi.fd_di == NULL) 18653 { 18654 /* Can't add a function to a locked dictionary */ 18655 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 18656 goto erret; 18657 } 18658 /* Can't change an existing function if it is locked */ 18659 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 18660 goto erret; 18661 18662 /* Give the function a sequential number. Can only be used with a 18663 * Funcref! */ 18664 vim_free(name); 18665 sprintf(numbuf, "%d", ++func_nr); 18666 name = vim_strsave((char_u *)numbuf); 18667 if (name == NULL) 18668 goto erret; 18669 } 18670 18671 if (fp == NULL) 18672 { 18673 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 18674 { 18675 int slen, plen; 18676 char_u *scriptname; 18677 18678 /* Check that the autoload name matches the script name. */ 18679 j = FAIL; 18680 if (sourcing_name != NULL) 18681 { 18682 scriptname = autoload_name(name); 18683 if (scriptname != NULL) 18684 { 18685 p = vim_strchr(scriptname, '/'); 18686 plen = (int)STRLEN(p); 18687 slen = (int)STRLEN(sourcing_name); 18688 if (slen > plen && fnamecmp(p, 18689 sourcing_name + slen - plen) == 0) 18690 j = OK; 18691 vim_free(scriptname); 18692 } 18693 } 18694 if (j == FAIL) 18695 { 18696 EMSG2(_("E746: Function name does not match script file name: %s"), name); 18697 goto erret; 18698 } 18699 } 18700 18701 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 18702 if (fp == NULL) 18703 goto erret; 18704 18705 if (fudi.fd_dict != NULL) 18706 { 18707 if (fudi.fd_di == NULL) 18708 { 18709 /* add new dict entry */ 18710 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 18711 if (fudi.fd_di == NULL) 18712 { 18713 vim_free(fp); 18714 goto erret; 18715 } 18716 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 18717 { 18718 vim_free(fudi.fd_di); 18719 goto erret; 18720 } 18721 } 18722 else 18723 /* overwrite existing dict entry */ 18724 clear_tv(&fudi.fd_di->di_tv); 18725 fudi.fd_di->di_tv.v_type = VAR_FUNC; 18726 fudi.fd_di->di_tv.v_lock = 0; 18727 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 18728 fp->uf_refcount = 1; 18729 18730 /* behave like "dict" was used */ 18731 flags |= FC_DICT; 18732 } 18733 18734 /* insert the new function in the function list */ 18735 STRCPY(fp->uf_name, name); 18736 hash_add(&func_hashtab, UF2HIKEY(fp)); 18737 } 18738 fp->uf_args = newargs; 18739 fp->uf_lines = newlines; 18740 #ifdef FEAT_PROFILE 18741 fp->uf_tml_count = NULL; 18742 fp->uf_tml_total = NULL; 18743 fp->uf_tml_self = NULL; 18744 fp->uf_profiling = FALSE; 18745 if (prof_def_func()) 18746 func_do_profile(fp); 18747 #endif 18748 fp->uf_varargs = varargs; 18749 fp->uf_flags = flags; 18750 fp->uf_calls = 0; 18751 fp->uf_script_ID = current_SID; 18752 goto ret_free; 18753 18754 erret: 18755 ga_clear_strings(&newargs); 18756 ga_clear_strings(&newlines); 18757 ret_free: 18758 vim_free(skip_until); 18759 vim_free(fudi.fd_newkey); 18760 vim_free(name); 18761 did_emsg |= saved_did_emsg; 18762 } 18763 18764 /* 18765 * Get a function name, translating "<SID>" and "<SNR>". 18766 * Also handles a Funcref in a List or Dictionary. 18767 * Returns the function name in allocated memory, or NULL for failure. 18768 * flags: 18769 * TFN_INT: internal function name OK 18770 * TFN_QUIET: be quiet 18771 * Advances "pp" to just after the function name (if no error). 18772 */ 18773 static char_u * 18774 trans_function_name(pp, skip, flags, fdp) 18775 char_u **pp; 18776 int skip; /* only find the end, don't evaluate */ 18777 int flags; 18778 funcdict_T *fdp; /* return: info about dictionary used */ 18779 { 18780 char_u *name = NULL; 18781 char_u *start; 18782 char_u *end; 18783 int lead; 18784 char_u sid_buf[20]; 18785 int len; 18786 lval_T lv; 18787 18788 if (fdp != NULL) 18789 vim_memset(fdp, 0, sizeof(funcdict_T)); 18790 start = *pp; 18791 18792 /* Check for hard coded <SNR>: already translated function ID (from a user 18793 * command). */ 18794 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 18795 && (*pp)[2] == (int)KE_SNR) 18796 { 18797 *pp += 3; 18798 len = get_id_len(pp) + 3; 18799 return vim_strnsave(start, len); 18800 } 18801 18802 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 18803 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 18804 lead = eval_fname_script(start); 18805 if (lead > 2) 18806 start += lead; 18807 18808 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 18809 lead > 2 ? 0 : FNE_CHECK_START); 18810 if (end == start) 18811 { 18812 if (!skip) 18813 EMSG(_("E129: Function name required")); 18814 goto theend; 18815 } 18816 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 18817 { 18818 /* 18819 * Report an invalid expression in braces, unless the expression 18820 * evaluation has been cancelled due to an aborting error, an 18821 * interrupt, or an exception. 18822 */ 18823 if (!aborting()) 18824 { 18825 if (end != NULL) 18826 EMSG2(_(e_invarg2), start); 18827 } 18828 else 18829 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 18830 goto theend; 18831 } 18832 18833 if (lv.ll_tv != NULL) 18834 { 18835 if (fdp != NULL) 18836 { 18837 fdp->fd_dict = lv.ll_dict; 18838 fdp->fd_newkey = lv.ll_newkey; 18839 lv.ll_newkey = NULL; 18840 fdp->fd_di = lv.ll_di; 18841 } 18842 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 18843 { 18844 name = vim_strsave(lv.ll_tv->vval.v_string); 18845 *pp = end; 18846 } 18847 else 18848 { 18849 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 18850 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 18851 EMSG(_(e_funcref)); 18852 else 18853 *pp = end; 18854 name = NULL; 18855 } 18856 goto theend; 18857 } 18858 18859 if (lv.ll_name == NULL) 18860 { 18861 /* Error found, but continue after the function name. */ 18862 *pp = end; 18863 goto theend; 18864 } 18865 18866 if (lv.ll_exp_name != NULL) 18867 { 18868 len = (int)STRLEN(lv.ll_exp_name); 18869 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 18870 && STRNCMP(lv.ll_name, "s:", 2) == 0) 18871 { 18872 /* When there was "s:" already or the name expanded to get a 18873 * leading "s:" then remove it. */ 18874 lv.ll_name += 2; 18875 len -= 2; 18876 lead = 2; 18877 } 18878 } 18879 else 18880 { 18881 if (lead == 2) /* skip over "s:" */ 18882 lv.ll_name += 2; 18883 len = (int)(end - lv.ll_name); 18884 } 18885 18886 /* 18887 * Copy the function name to allocated memory. 18888 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 18889 * Accept <SNR>123_name() outside a script. 18890 */ 18891 if (skip) 18892 lead = 0; /* do nothing */ 18893 else if (lead > 0) 18894 { 18895 lead = 3; 18896 if (eval_fname_sid(lv.ll_exp_name != NULL ? lv.ll_exp_name : *pp)) 18897 { 18898 /* It's "s:" or "<SID>" */ 18899 if (current_SID <= 0) 18900 { 18901 EMSG(_(e_usingsid)); 18902 goto theend; 18903 } 18904 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 18905 lead += (int)STRLEN(sid_buf); 18906 } 18907 } 18908 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 18909 { 18910 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 18911 goto theend; 18912 } 18913 name = alloc((unsigned)(len + lead + 1)); 18914 if (name != NULL) 18915 { 18916 if (lead > 0) 18917 { 18918 name[0] = K_SPECIAL; 18919 name[1] = KS_EXTRA; 18920 name[2] = (int)KE_SNR; 18921 if (lead > 3) /* If it's "<SID>" */ 18922 STRCPY(name + 3, sid_buf); 18923 } 18924 mch_memmove(name + lead, lv.ll_name, (size_t)len); 18925 name[len + lead] = NUL; 18926 } 18927 *pp = end; 18928 18929 theend: 18930 clear_lval(&lv); 18931 return name; 18932 } 18933 18934 /* 18935 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 18936 * Return 2 if "p" starts with "s:". 18937 * Return 0 otherwise. 18938 */ 18939 static int 18940 eval_fname_script(p) 18941 char_u *p; 18942 { 18943 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 18944 || STRNICMP(p + 1, "SNR>", 4) == 0)) 18945 return 5; 18946 if (p[0] == 's' && p[1] == ':') 18947 return 2; 18948 return 0; 18949 } 18950 18951 /* 18952 * Return TRUE if "p" starts with "<SID>" or "s:". 18953 * Only works if eval_fname_script() returned non-zero for "p"! 18954 */ 18955 static int 18956 eval_fname_sid(p) 18957 char_u *p; 18958 { 18959 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 18960 } 18961 18962 /* 18963 * List the head of the function: "name(arg1, arg2)". 18964 */ 18965 static void 18966 list_func_head(fp, indent) 18967 ufunc_T *fp; 18968 int indent; 18969 { 18970 int j; 18971 18972 msg_start(); 18973 if (indent) 18974 MSG_PUTS(" "); 18975 MSG_PUTS("function "); 18976 if (fp->uf_name[0] == K_SPECIAL) 18977 { 18978 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 18979 msg_puts(fp->uf_name + 3); 18980 } 18981 else 18982 msg_puts(fp->uf_name); 18983 msg_putchar('('); 18984 for (j = 0; j < fp->uf_args.ga_len; ++j) 18985 { 18986 if (j) 18987 MSG_PUTS(", "); 18988 msg_puts(FUNCARG(fp, j)); 18989 } 18990 if (fp->uf_varargs) 18991 { 18992 if (j) 18993 MSG_PUTS(", "); 18994 MSG_PUTS("..."); 18995 } 18996 msg_putchar(')'); 18997 msg_clr_eos(); 18998 if (p_verbose > 0) 18999 last_set_msg(fp->uf_script_ID); 19000 } 19001 19002 /* 19003 * Find a function by name, return pointer to it in ufuncs. 19004 * Return NULL for unknown function. 19005 */ 19006 static ufunc_T * 19007 find_func(name) 19008 char_u *name; 19009 { 19010 hashitem_T *hi; 19011 19012 hi = hash_find(&func_hashtab, name); 19013 if (!HASHITEM_EMPTY(hi)) 19014 return HI2UF(hi); 19015 return NULL; 19016 } 19017 19018 #if defined(EXITFREE) || defined(PROTO) 19019 void 19020 free_all_functions() 19021 { 19022 hashitem_T *hi; 19023 19024 /* Need to start all over every time, because func_free() may change the 19025 * hash table. */ 19026 while (func_hashtab.ht_used > 0) 19027 for (hi = func_hashtab.ht_array; ; ++hi) 19028 if (!HASHITEM_EMPTY(hi)) 19029 { 19030 func_free(HI2UF(hi)); 19031 break; 19032 } 19033 } 19034 #endif 19035 19036 /* 19037 * Return TRUE if a function "name" exists. 19038 */ 19039 static int 19040 function_exists(name) 19041 char_u *name; 19042 { 19043 char_u *p = name; 19044 int n = FALSE; 19045 19046 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 19047 if (p != NULL) 19048 { 19049 if (builtin_function(p)) 19050 n = (find_internal_func(p) >= 0); 19051 else 19052 n = (find_func(p) != NULL); 19053 vim_free(p); 19054 } 19055 return n; 19056 } 19057 19058 /* 19059 * Return TRUE if "name" looks like a builtin function name: starts with a 19060 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 19061 */ 19062 static int 19063 builtin_function(name) 19064 char_u *name; 19065 { 19066 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 19067 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 19068 } 19069 19070 #if defined(FEAT_PROFILE) || defined(PROTO) 19071 /* 19072 * Start profiling function "fp". 19073 */ 19074 static void 19075 func_do_profile(fp) 19076 ufunc_T *fp; 19077 { 19078 fp->uf_tm_count = 0; 19079 profile_zero(&fp->uf_tm_self); 19080 profile_zero(&fp->uf_tm_total); 19081 if (fp->uf_tml_count == NULL) 19082 fp->uf_tml_count = (int *)alloc_clear((unsigned) 19083 (sizeof(int) * fp->uf_lines.ga_len)); 19084 if (fp->uf_tml_total == NULL) 19085 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 19086 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 19087 if (fp->uf_tml_self == NULL) 19088 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 19089 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 19090 fp->uf_tml_idx = -1; 19091 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 19092 || fp->uf_tml_self == NULL) 19093 return; /* out of memory */ 19094 19095 fp->uf_profiling = TRUE; 19096 } 19097 19098 /* 19099 * Dump the profiling results for all functions in file "fd". 19100 */ 19101 void 19102 func_dump_profile(fd) 19103 FILE *fd; 19104 { 19105 hashitem_T *hi; 19106 int todo; 19107 ufunc_T *fp; 19108 int i; 19109 ufunc_T **sorttab; 19110 int st_len = 0; 19111 19112 todo = (int)func_hashtab.ht_used; 19113 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 19114 19115 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 19116 { 19117 if (!HASHITEM_EMPTY(hi)) 19118 { 19119 --todo; 19120 fp = HI2UF(hi); 19121 if (fp->uf_profiling) 19122 { 19123 if (sorttab != NULL) 19124 sorttab[st_len++] = fp; 19125 19126 if (fp->uf_name[0] == K_SPECIAL) 19127 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 19128 else 19129 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 19130 if (fp->uf_tm_count == 1) 19131 fprintf(fd, "Called 1 time\n"); 19132 else 19133 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 19134 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 19135 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 19136 fprintf(fd, "\n"); 19137 fprintf(fd, "count total (s) self (s)\n"); 19138 19139 for (i = 0; i < fp->uf_lines.ga_len; ++i) 19140 { 19141 if (FUNCLINE(fp, i) == NULL) 19142 continue; 19143 prof_func_line(fd, fp->uf_tml_count[i], 19144 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 19145 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 19146 } 19147 fprintf(fd, "\n"); 19148 } 19149 } 19150 } 19151 19152 if (sorttab != NULL && st_len > 0) 19153 { 19154 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 19155 prof_total_cmp); 19156 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 19157 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 19158 prof_self_cmp); 19159 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 19160 } 19161 } 19162 19163 static void 19164 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 19165 FILE *fd; 19166 ufunc_T **sorttab; 19167 int st_len; 19168 char *title; 19169 int prefer_self; /* when equal print only self time */ 19170 { 19171 int i; 19172 ufunc_T *fp; 19173 19174 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 19175 fprintf(fd, "count total (s) self (s) function\n"); 19176 for (i = 0; i < 20 && i < st_len; ++i) 19177 { 19178 fp = sorttab[i]; 19179 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 19180 prefer_self); 19181 if (fp->uf_name[0] == K_SPECIAL) 19182 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 19183 else 19184 fprintf(fd, " %s()\n", fp->uf_name); 19185 } 19186 fprintf(fd, "\n"); 19187 } 19188 19189 /* 19190 * Print the count and times for one function or function line. 19191 */ 19192 static void 19193 prof_func_line(fd, count, total, self, prefer_self) 19194 FILE *fd; 19195 int count; 19196 proftime_T *total; 19197 proftime_T *self; 19198 int prefer_self; /* when equal print only self time */ 19199 { 19200 if (count > 0) 19201 { 19202 fprintf(fd, "%5d ", count); 19203 if (prefer_self && profile_equal(total, self)) 19204 fprintf(fd, " "); 19205 else 19206 fprintf(fd, "%s ", profile_msg(total)); 19207 if (!prefer_self && profile_equal(total, self)) 19208 fprintf(fd, " "); 19209 else 19210 fprintf(fd, "%s ", profile_msg(self)); 19211 } 19212 else 19213 fprintf(fd, " "); 19214 } 19215 19216 /* 19217 * Compare function for total time sorting. 19218 */ 19219 static int 19220 #ifdef __BORLANDC__ 19221 _RTLENTRYF 19222 #endif 19223 prof_total_cmp(s1, s2) 19224 const void *s1; 19225 const void *s2; 19226 { 19227 ufunc_T *p1, *p2; 19228 19229 p1 = *(ufunc_T **)s1; 19230 p2 = *(ufunc_T **)s2; 19231 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 19232 } 19233 19234 /* 19235 * Compare function for self time sorting. 19236 */ 19237 static int 19238 #ifdef __BORLANDC__ 19239 _RTLENTRYF 19240 #endif 19241 prof_self_cmp(s1, s2) 19242 const void *s1; 19243 const void *s2; 19244 { 19245 ufunc_T *p1, *p2; 19246 19247 p1 = *(ufunc_T **)s1; 19248 p2 = *(ufunc_T **)s2; 19249 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 19250 } 19251 19252 #endif 19253 19254 /* The names of packages that once were loaded is remembered. */ 19255 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 19256 19257 /* 19258 * If "name" has a package name try autoloading the script for it. 19259 * Return TRUE if a package was loaded. 19260 */ 19261 static int 19262 script_autoload(name, reload) 19263 char_u *name; 19264 int reload; /* load script again when already loaded */ 19265 { 19266 char_u *p; 19267 char_u *scriptname, *tofree; 19268 int ret = FALSE; 19269 int i; 19270 19271 /* If there is no '#' after name[0] there is no package name. */ 19272 p = vim_strchr(name, AUTOLOAD_CHAR); 19273 if (p == NULL || p == name) 19274 return FALSE; 19275 19276 tofree = scriptname = autoload_name(name); 19277 19278 /* Find the name in the list of previously loaded package names. Skip 19279 * "autoload/", it's always the same. */ 19280 for (i = 0; i < ga_loaded.ga_len; ++i) 19281 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 19282 break; 19283 if (!reload && i < ga_loaded.ga_len) 19284 ret = FALSE; /* was loaded already */ 19285 else 19286 { 19287 /* Remember the name if it wasn't loaded already. */ 19288 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 19289 { 19290 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 19291 tofree = NULL; 19292 } 19293 19294 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 19295 if (source_runtime(scriptname, FALSE) == OK) 19296 ret = TRUE; 19297 } 19298 19299 vim_free(tofree); 19300 return ret; 19301 } 19302 19303 /* 19304 * Return the autoload script name for a function or variable name. 19305 * Returns NULL when out of memory. 19306 */ 19307 static char_u * 19308 autoload_name(name) 19309 char_u *name; 19310 { 19311 char_u *p; 19312 char_u *scriptname; 19313 19314 /* Get the script file name: replace '#' with '/', append ".vim". */ 19315 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 19316 if (scriptname == NULL) 19317 return FALSE; 19318 STRCPY(scriptname, "autoload/"); 19319 STRCAT(scriptname, name); 19320 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 19321 STRCAT(scriptname, ".vim"); 19322 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 19323 *p = '/'; 19324 return scriptname; 19325 } 19326 19327 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 19328 19329 /* 19330 * Function given to ExpandGeneric() to obtain the list of user defined 19331 * function names. 19332 */ 19333 char_u * 19334 get_user_func_name(xp, idx) 19335 expand_T *xp; 19336 int idx; 19337 { 19338 static long_u done; 19339 static hashitem_T *hi; 19340 ufunc_T *fp; 19341 19342 if (idx == 0) 19343 { 19344 done = 0; 19345 hi = func_hashtab.ht_array; 19346 } 19347 if (done < func_hashtab.ht_used) 19348 { 19349 if (done++ > 0) 19350 ++hi; 19351 while (HASHITEM_EMPTY(hi)) 19352 ++hi; 19353 fp = HI2UF(hi); 19354 19355 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 19356 return fp->uf_name; /* prevents overflow */ 19357 19358 cat_func_name(IObuff, fp); 19359 if (xp->xp_context != EXPAND_USER_FUNC) 19360 { 19361 STRCAT(IObuff, "("); 19362 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 19363 STRCAT(IObuff, ")"); 19364 } 19365 return IObuff; 19366 } 19367 return NULL; 19368 } 19369 19370 #endif /* FEAT_CMDL_COMPL */ 19371 19372 /* 19373 * Copy the function name of "fp" to buffer "buf". 19374 * "buf" must be able to hold the function name plus three bytes. 19375 * Takes care of script-local function names. 19376 */ 19377 static void 19378 cat_func_name(buf, fp) 19379 char_u *buf; 19380 ufunc_T *fp; 19381 { 19382 if (fp->uf_name[0] == K_SPECIAL) 19383 { 19384 STRCPY(buf, "<SNR>"); 19385 STRCAT(buf, fp->uf_name + 3); 19386 } 19387 else 19388 STRCPY(buf, fp->uf_name); 19389 } 19390 19391 /* 19392 * ":delfunction {name}" 19393 */ 19394 void 19395 ex_delfunction(eap) 19396 exarg_T *eap; 19397 { 19398 ufunc_T *fp = NULL; 19399 char_u *p; 19400 char_u *name; 19401 funcdict_T fudi; 19402 19403 p = eap->arg; 19404 name = trans_function_name(&p, eap->skip, 0, &fudi); 19405 vim_free(fudi.fd_newkey); 19406 if (name == NULL) 19407 { 19408 if (fudi.fd_dict != NULL && !eap->skip) 19409 EMSG(_(e_funcref)); 19410 return; 19411 } 19412 if (!ends_excmd(*skipwhite(p))) 19413 { 19414 vim_free(name); 19415 EMSG(_(e_trailing)); 19416 return; 19417 } 19418 eap->nextcmd = check_nextcmd(p); 19419 if (eap->nextcmd != NULL) 19420 *p = NUL; 19421 19422 if (!eap->skip) 19423 fp = find_func(name); 19424 vim_free(name); 19425 19426 if (!eap->skip) 19427 { 19428 if (fp == NULL) 19429 { 19430 EMSG2(_(e_nofunc), eap->arg); 19431 return; 19432 } 19433 if (fp->uf_calls > 0) 19434 { 19435 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 19436 return; 19437 } 19438 19439 if (fudi.fd_dict != NULL) 19440 { 19441 /* Delete the dict item that refers to the function, it will 19442 * invoke func_unref() and possibly delete the function. */ 19443 dictitem_remove(fudi.fd_dict, fudi.fd_di); 19444 } 19445 else 19446 func_free(fp); 19447 } 19448 } 19449 19450 /* 19451 * Free a function and remove it from the list of functions. 19452 */ 19453 static void 19454 func_free(fp) 19455 ufunc_T *fp; 19456 { 19457 hashitem_T *hi; 19458 19459 /* clear this function */ 19460 ga_clear_strings(&(fp->uf_args)); 19461 ga_clear_strings(&(fp->uf_lines)); 19462 #ifdef FEAT_PROFILE 19463 vim_free(fp->uf_tml_count); 19464 vim_free(fp->uf_tml_total); 19465 vim_free(fp->uf_tml_self); 19466 #endif 19467 19468 /* remove the function from the function hashtable */ 19469 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 19470 if (HASHITEM_EMPTY(hi)) 19471 EMSG2(_(e_intern2), "func_free()"); 19472 else 19473 hash_remove(&func_hashtab, hi); 19474 19475 vim_free(fp); 19476 } 19477 19478 /* 19479 * Unreference a Function: decrement the reference count and free it when it 19480 * becomes zero. Only for numbered functions. 19481 */ 19482 static void 19483 func_unref(name) 19484 char_u *name; 19485 { 19486 ufunc_T *fp; 19487 19488 if (name != NULL && isdigit(*name)) 19489 { 19490 fp = find_func(name); 19491 if (fp == NULL) 19492 EMSG2(_(e_intern2), "func_unref()"); 19493 else if (--fp->uf_refcount <= 0) 19494 { 19495 /* Only delete it when it's not being used. Otherwise it's done 19496 * when "uf_calls" becomes zero. */ 19497 if (fp->uf_calls == 0) 19498 func_free(fp); 19499 } 19500 } 19501 } 19502 19503 /* 19504 * Count a reference to a Function. 19505 */ 19506 static void 19507 func_ref(name) 19508 char_u *name; 19509 { 19510 ufunc_T *fp; 19511 19512 if (name != NULL && isdigit(*name)) 19513 { 19514 fp = find_func(name); 19515 if (fp == NULL) 19516 EMSG2(_(e_intern2), "func_ref()"); 19517 else 19518 ++fp->uf_refcount; 19519 } 19520 } 19521 19522 /* 19523 * Call a user function. 19524 */ 19525 static void 19526 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 19527 ufunc_T *fp; /* pointer to function */ 19528 int argcount; /* nr of args */ 19529 typval_T *argvars; /* arguments */ 19530 typval_T *rettv; /* return value */ 19531 linenr_T firstline; /* first line of range */ 19532 linenr_T lastline; /* last line of range */ 19533 dict_T *selfdict; /* Dictionary for "self" */ 19534 { 19535 char_u *save_sourcing_name; 19536 linenr_T save_sourcing_lnum; 19537 scid_T save_current_SID; 19538 funccall_T fc; 19539 int save_did_emsg; 19540 static int depth = 0; 19541 dictitem_T *v; 19542 int fixvar_idx = 0; /* index in fixvar[] */ 19543 int i; 19544 int ai; 19545 char_u numbuf[NUMBUFLEN]; 19546 char_u *name; 19547 #ifdef FEAT_PROFILE 19548 proftime_T wait_start; 19549 #endif 19550 19551 /* If depth of calling is getting too high, don't execute the function */ 19552 if (depth >= p_mfd) 19553 { 19554 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 19555 rettv->v_type = VAR_NUMBER; 19556 rettv->vval.v_number = -1; 19557 return; 19558 } 19559 ++depth; 19560 19561 line_breakcheck(); /* check for CTRL-C hit */ 19562 19563 fc.caller = current_funccal; 19564 current_funccal = &fc; 19565 fc.func = fp; 19566 fc.rettv = rettv; 19567 rettv->vval.v_number = 0; 19568 fc.linenr = 0; 19569 fc.returned = FALSE; 19570 fc.level = ex_nesting_level; 19571 /* Check if this function has a breakpoint. */ 19572 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 19573 fc.dbg_tick = debug_tick; 19574 19575 /* 19576 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 19577 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 19578 * each argument variable and saves a lot of time. 19579 */ 19580 /* 19581 * Init l: variables. 19582 */ 19583 init_var_dict(&fc.l_vars, &fc.l_vars_var); 19584 if (selfdict != NULL) 19585 { 19586 /* Set l:self to "selfdict". Use "name" to avoid a warning from 19587 * some compiler that checks the destination size. */ 19588 v = &fc.fixvar[fixvar_idx++].var; 19589 name = v->di_key; 19590 STRCPY(name, "self"); 19591 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 19592 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 19593 v->di_tv.v_type = VAR_DICT; 19594 v->di_tv.v_lock = 0; 19595 v->di_tv.vval.v_dict = selfdict; 19596 ++selfdict->dv_refcount; 19597 } 19598 19599 /* 19600 * Init a: variables. 19601 * Set a:0 to "argcount". 19602 * Set a:000 to a list with room for the "..." arguments. 19603 */ 19604 init_var_dict(&fc.l_avars, &fc.l_avars_var); 19605 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 19606 (varnumber_T)(argcount - fp->uf_args.ga_len)); 19607 v = &fc.fixvar[fixvar_idx++].var; 19608 STRCPY(v->di_key, "000"); 19609 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19610 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 19611 v->di_tv.v_type = VAR_LIST; 19612 v->di_tv.v_lock = VAR_FIXED; 19613 v->di_tv.vval.v_list = &fc.l_varlist; 19614 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 19615 fc.l_varlist.lv_refcount = 99999; 19616 19617 /* 19618 * Set a:firstline to "firstline" and a:lastline to "lastline". 19619 * Set a:name to named arguments. 19620 * Set a:N to the "..." arguments. 19621 */ 19622 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 19623 (varnumber_T)firstline); 19624 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 19625 (varnumber_T)lastline); 19626 for (i = 0; i < argcount; ++i) 19627 { 19628 ai = i - fp->uf_args.ga_len; 19629 if (ai < 0) 19630 /* named argument a:name */ 19631 name = FUNCARG(fp, i); 19632 else 19633 { 19634 /* "..." argument a:1, a:2, etc. */ 19635 sprintf((char *)numbuf, "%d", ai + 1); 19636 name = numbuf; 19637 } 19638 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 19639 { 19640 v = &fc.fixvar[fixvar_idx++].var; 19641 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19642 } 19643 else 19644 { 19645 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19646 + STRLEN(name))); 19647 if (v == NULL) 19648 break; 19649 v->di_flags = DI_FLAGS_RO; 19650 } 19651 STRCPY(v->di_key, name); 19652 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 19653 19654 /* Note: the values are copied directly to avoid alloc/free. 19655 * "argvars" must have VAR_FIXED for v_lock. */ 19656 v->di_tv = argvars[i]; 19657 v->di_tv.v_lock = VAR_FIXED; 19658 19659 if (ai >= 0 && ai < MAX_FUNC_ARGS) 19660 { 19661 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 19662 fc.l_listitems[ai].li_tv = argvars[i]; 19663 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 19664 } 19665 } 19666 19667 /* Don't redraw while executing the function. */ 19668 ++RedrawingDisabled; 19669 save_sourcing_name = sourcing_name; 19670 save_sourcing_lnum = sourcing_lnum; 19671 sourcing_lnum = 1; 19672 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 19673 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 19674 if (sourcing_name != NULL) 19675 { 19676 if (save_sourcing_name != NULL 19677 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 19678 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 19679 else 19680 STRCPY(sourcing_name, "function "); 19681 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 19682 19683 if (p_verbose >= 12) 19684 { 19685 ++no_wait_return; 19686 verbose_enter_scroll(); 19687 19688 smsg((char_u *)_("calling %s"), sourcing_name); 19689 if (p_verbose >= 14) 19690 { 19691 char_u buf[MSG_BUF_LEN]; 19692 char_u numbuf[NUMBUFLEN]; 19693 char_u *tofree; 19694 19695 msg_puts((char_u *)"("); 19696 for (i = 0; i < argcount; ++i) 19697 { 19698 if (i > 0) 19699 msg_puts((char_u *)", "); 19700 if (argvars[i].v_type == VAR_NUMBER) 19701 msg_outnum((long)argvars[i].vval.v_number); 19702 else 19703 { 19704 trunc_string(tv2string(&argvars[i], &tofree, numbuf, 0), 19705 buf, MSG_BUF_CLEN); 19706 msg_puts(buf); 19707 vim_free(tofree); 19708 } 19709 } 19710 msg_puts((char_u *)")"); 19711 } 19712 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19713 19714 verbose_leave_scroll(); 19715 --no_wait_return; 19716 } 19717 } 19718 #ifdef FEAT_PROFILE 19719 if (do_profiling == PROF_YES) 19720 { 19721 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 19722 func_do_profile(fp); 19723 if (fp->uf_profiling 19724 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 19725 { 19726 ++fp->uf_tm_count; 19727 profile_start(&fp->uf_tm_start); 19728 profile_zero(&fp->uf_tm_children); 19729 } 19730 script_prof_save(&wait_start); 19731 } 19732 #endif 19733 19734 save_current_SID = current_SID; 19735 current_SID = fp->uf_script_ID; 19736 save_did_emsg = did_emsg; 19737 did_emsg = FALSE; 19738 19739 /* call do_cmdline() to execute the lines */ 19740 do_cmdline(NULL, get_func_line, (void *)&fc, 19741 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 19742 19743 --RedrawingDisabled; 19744 19745 /* when the function was aborted because of an error, return -1 */ 19746 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 19747 { 19748 clear_tv(rettv); 19749 rettv->v_type = VAR_NUMBER; 19750 rettv->vval.v_number = -1; 19751 } 19752 19753 #ifdef FEAT_PROFILE 19754 if (do_profiling == PROF_YES && (fp->uf_profiling 19755 || (fc.caller != NULL && &fc.caller->func->uf_profiling))) 19756 { 19757 profile_end(&fp->uf_tm_start); 19758 profile_sub_wait(&wait_start, &fp->uf_tm_start); 19759 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 19760 profile_self(&fp->uf_tm_self, &fp->uf_tm_start, &fp->uf_tm_children); 19761 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 19762 { 19763 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 19764 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 19765 } 19766 } 19767 #endif 19768 19769 /* when being verbose, mention the return value */ 19770 if (p_verbose >= 12) 19771 { 19772 ++no_wait_return; 19773 verbose_enter_scroll(); 19774 19775 if (aborting()) 19776 smsg((char_u *)_("%s aborted"), sourcing_name); 19777 else if (fc.rettv->v_type == VAR_NUMBER) 19778 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 19779 (long)fc.rettv->vval.v_number); 19780 else 19781 { 19782 char_u buf[MSG_BUF_LEN]; 19783 char_u numbuf[NUMBUFLEN]; 19784 char_u *tofree; 19785 19786 /* The value may be very long. Skip the middle part, so that we 19787 * have some idea how it starts and ends. smsg() would always 19788 * truncate it at the end. */ 19789 trunc_string(tv2string(fc.rettv, &tofree, numbuf, 0), 19790 buf, MSG_BUF_CLEN); 19791 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 19792 vim_free(tofree); 19793 } 19794 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19795 19796 verbose_leave_scroll(); 19797 --no_wait_return; 19798 } 19799 19800 vim_free(sourcing_name); 19801 sourcing_name = save_sourcing_name; 19802 sourcing_lnum = save_sourcing_lnum; 19803 current_SID = save_current_SID; 19804 #ifdef FEAT_PROFILE 19805 if (do_profiling == PROF_YES) 19806 script_prof_restore(&wait_start); 19807 #endif 19808 19809 if (p_verbose >= 12 && sourcing_name != NULL) 19810 { 19811 ++no_wait_return; 19812 verbose_enter_scroll(); 19813 19814 smsg((char_u *)_("continuing in %s"), sourcing_name); 19815 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19816 19817 verbose_leave_scroll(); 19818 --no_wait_return; 19819 } 19820 19821 did_emsg |= save_did_emsg; 19822 current_funccal = fc.caller; 19823 19824 /* The a: variables typevals were not alloced, only free the allocated 19825 * variables. */ 19826 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 19827 19828 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 19829 --depth; 19830 } 19831 19832 /* 19833 * Add a number variable "name" to dict "dp" with value "nr". 19834 */ 19835 static void 19836 add_nr_var(dp, v, name, nr) 19837 dict_T *dp; 19838 dictitem_T *v; 19839 char *name; 19840 varnumber_T nr; 19841 { 19842 STRCPY(v->di_key, name); 19843 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19844 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 19845 v->di_tv.v_type = VAR_NUMBER; 19846 v->di_tv.v_lock = VAR_FIXED; 19847 v->di_tv.vval.v_number = nr; 19848 } 19849 19850 /* 19851 * ":return [expr]" 19852 */ 19853 void 19854 ex_return(eap) 19855 exarg_T *eap; 19856 { 19857 char_u *arg = eap->arg; 19858 typval_T rettv; 19859 int returning = FALSE; 19860 19861 if (current_funccal == NULL) 19862 { 19863 EMSG(_("E133: :return not inside a function")); 19864 return; 19865 } 19866 19867 if (eap->skip) 19868 ++emsg_skip; 19869 19870 eap->nextcmd = NULL; 19871 if ((*arg != NUL && *arg != '|' && *arg != '\n') 19872 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 19873 { 19874 if (!eap->skip) 19875 returning = do_return(eap, FALSE, TRUE, &rettv); 19876 else 19877 clear_tv(&rettv); 19878 } 19879 /* It's safer to return also on error. */ 19880 else if (!eap->skip) 19881 { 19882 /* 19883 * Return unless the expression evaluation has been cancelled due to an 19884 * aborting error, an interrupt, or an exception. 19885 */ 19886 if (!aborting()) 19887 returning = do_return(eap, FALSE, TRUE, NULL); 19888 } 19889 19890 /* When skipping or the return gets pending, advance to the next command 19891 * in this line (!returning). Otherwise, ignore the rest of the line. 19892 * Following lines will be ignored by get_func_line(). */ 19893 if (returning) 19894 eap->nextcmd = NULL; 19895 else if (eap->nextcmd == NULL) /* no argument */ 19896 eap->nextcmd = check_nextcmd(arg); 19897 19898 if (eap->skip) 19899 --emsg_skip; 19900 } 19901 19902 /* 19903 * Return from a function. Possibly makes the return pending. Also called 19904 * for a pending return at the ":endtry" or after returning from an extra 19905 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 19906 * when called due to a ":return" command. "rettv" may point to a typval_T 19907 * with the return rettv. Returns TRUE when the return can be carried out, 19908 * FALSE when the return gets pending. 19909 */ 19910 int 19911 do_return(eap, reanimate, is_cmd, rettv) 19912 exarg_T *eap; 19913 int reanimate; 19914 int is_cmd; 19915 void *rettv; 19916 { 19917 int idx; 19918 struct condstack *cstack = eap->cstack; 19919 19920 if (reanimate) 19921 /* Undo the return. */ 19922 current_funccal->returned = FALSE; 19923 19924 /* 19925 * Cleanup (and inactivate) conditionals, but stop when a try conditional 19926 * not in its finally clause (which then is to be executed next) is found. 19927 * In this case, make the ":return" pending for execution at the ":endtry". 19928 * Otherwise, return normally. 19929 */ 19930 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 19931 if (idx >= 0) 19932 { 19933 cstack->cs_pending[idx] = CSTP_RETURN; 19934 19935 if (!is_cmd && !reanimate) 19936 /* A pending return again gets pending. "rettv" points to an 19937 * allocated variable with the rettv of the original ":return"'s 19938 * argument if present or is NULL else. */ 19939 cstack->cs_rettv[idx] = rettv; 19940 else 19941 { 19942 /* When undoing a return in order to make it pending, get the stored 19943 * return rettv. */ 19944 if (reanimate) 19945 rettv = current_funccal->rettv; 19946 19947 if (rettv != NULL) 19948 { 19949 /* Store the value of the pending return. */ 19950 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 19951 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 19952 else 19953 EMSG(_(e_outofmem)); 19954 } 19955 else 19956 cstack->cs_rettv[idx] = NULL; 19957 19958 if (reanimate) 19959 { 19960 /* The pending return value could be overwritten by a ":return" 19961 * without argument in a finally clause; reset the default 19962 * return value. */ 19963 current_funccal->rettv->v_type = VAR_NUMBER; 19964 current_funccal->rettv->vval.v_number = 0; 19965 } 19966 } 19967 report_make_pending(CSTP_RETURN, rettv); 19968 } 19969 else 19970 { 19971 current_funccal->returned = TRUE; 19972 19973 /* If the return is carried out now, store the return value. For 19974 * a return immediately after reanimation, the value is already 19975 * there. */ 19976 if (!reanimate && rettv != NULL) 19977 { 19978 clear_tv(current_funccal->rettv); 19979 *current_funccal->rettv = *(typval_T *)rettv; 19980 if (!is_cmd) 19981 vim_free(rettv); 19982 } 19983 } 19984 19985 return idx < 0; 19986 } 19987 19988 /* 19989 * Free the variable with a pending return value. 19990 */ 19991 void 19992 discard_pending_return(rettv) 19993 void *rettv; 19994 { 19995 free_tv((typval_T *)rettv); 19996 } 19997 19998 /* 19999 * Generate a return command for producing the value of "rettv". The result 20000 * is an allocated string. Used by report_pending() for verbose messages. 20001 */ 20002 char_u * 20003 get_return_cmd(rettv) 20004 void *rettv; 20005 { 20006 char_u *s = NULL; 20007 char_u *tofree = NULL; 20008 char_u numbuf[NUMBUFLEN]; 20009 20010 if (rettv != NULL) 20011 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 20012 if (s == NULL) 20013 s = (char_u *)""; 20014 20015 STRCPY(IObuff, ":return "); 20016 STRNCPY(IObuff + 8, s, IOSIZE - 8); 20017 if (STRLEN(s) + 8 >= IOSIZE) 20018 STRCPY(IObuff + IOSIZE - 4, "..."); 20019 vim_free(tofree); 20020 return vim_strsave(IObuff); 20021 } 20022 20023 /* 20024 * Get next function line. 20025 * Called by do_cmdline() to get the next line. 20026 * Returns allocated string, or NULL for end of function. 20027 */ 20028 /* ARGSUSED */ 20029 char_u * 20030 get_func_line(c, cookie, indent) 20031 int c; /* not used */ 20032 void *cookie; 20033 int indent; /* not used */ 20034 { 20035 funccall_T *fcp = (funccall_T *)cookie; 20036 ufunc_T *fp = fcp->func; 20037 char_u *retval; 20038 garray_T *gap; /* growarray with function lines */ 20039 20040 /* If breakpoints have been added/deleted need to check for it. */ 20041 if (fcp->dbg_tick != debug_tick) 20042 { 20043 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 20044 sourcing_lnum); 20045 fcp->dbg_tick = debug_tick; 20046 } 20047 #ifdef FEAT_PROFILE 20048 if (do_profiling == PROF_YES) 20049 func_line_end(cookie); 20050 #endif 20051 20052 gap = &fp->uf_lines; 20053 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 20054 || fcp->returned) 20055 retval = NULL; 20056 else 20057 { 20058 /* Skip NULL lines (continuation lines). */ 20059 while (fcp->linenr < gap->ga_len 20060 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 20061 ++fcp->linenr; 20062 if (fcp->linenr >= gap->ga_len) 20063 retval = NULL; 20064 else 20065 { 20066 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 20067 sourcing_lnum = fcp->linenr; 20068 #ifdef FEAT_PROFILE 20069 if (do_profiling == PROF_YES) 20070 func_line_start(cookie); 20071 #endif 20072 } 20073 } 20074 20075 /* Did we encounter a breakpoint? */ 20076 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 20077 { 20078 dbg_breakpoint(fp->uf_name, sourcing_lnum); 20079 /* Find next breakpoint. */ 20080 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 20081 sourcing_lnum); 20082 fcp->dbg_tick = debug_tick; 20083 } 20084 20085 return retval; 20086 } 20087 20088 #if defined(FEAT_PROFILE) || defined(PROTO) 20089 /* 20090 * Called when starting to read a function line. 20091 * "sourcing_lnum" must be correct! 20092 * When skipping lines it may not actually be executed, but we won't find out 20093 * until later and we need to store the time now. 20094 */ 20095 void 20096 func_line_start(cookie) 20097 void *cookie; 20098 { 20099 funccall_T *fcp = (funccall_T *)cookie; 20100 ufunc_T *fp = fcp->func; 20101 20102 if (fp->uf_profiling && sourcing_lnum >= 1 20103 && sourcing_lnum <= fp->uf_lines.ga_len) 20104 { 20105 fp->uf_tml_idx = sourcing_lnum - 1; 20106 /* Skip continuation lines. */ 20107 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 20108 --fp->uf_tml_idx; 20109 fp->uf_tml_execed = FALSE; 20110 profile_start(&fp->uf_tml_start); 20111 profile_zero(&fp->uf_tml_children); 20112 profile_get_wait(&fp->uf_tml_wait); 20113 } 20114 } 20115 20116 /* 20117 * Called when actually executing a function line. 20118 */ 20119 void 20120 func_line_exec(cookie) 20121 void *cookie; 20122 { 20123 funccall_T *fcp = (funccall_T *)cookie; 20124 ufunc_T *fp = fcp->func; 20125 20126 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 20127 fp->uf_tml_execed = TRUE; 20128 } 20129 20130 /* 20131 * Called when done with a function line. 20132 */ 20133 void 20134 func_line_end(cookie) 20135 void *cookie; 20136 { 20137 funccall_T *fcp = (funccall_T *)cookie; 20138 ufunc_T *fp = fcp->func; 20139 20140 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 20141 { 20142 if (fp->uf_tml_execed) 20143 { 20144 ++fp->uf_tml_count[fp->uf_tml_idx]; 20145 profile_end(&fp->uf_tml_start); 20146 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 20147 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 20148 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 20149 &fp->uf_tml_children); 20150 } 20151 fp->uf_tml_idx = -1; 20152 } 20153 } 20154 #endif 20155 20156 /* 20157 * Return TRUE if the currently active function should be ended, because a 20158 * return was encountered or an error occured. Used inside a ":while". 20159 */ 20160 int 20161 func_has_ended(cookie) 20162 void *cookie; 20163 { 20164 funccall_T *fcp = (funccall_T *)cookie; 20165 20166 /* Ignore the "abort" flag if the abortion behavior has been changed due to 20167 * an error inside a try conditional. */ 20168 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 20169 || fcp->returned); 20170 } 20171 20172 /* 20173 * return TRUE if cookie indicates a function which "abort"s on errors. 20174 */ 20175 int 20176 func_has_abort(cookie) 20177 void *cookie; 20178 { 20179 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 20180 } 20181 20182 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 20183 typedef enum 20184 { 20185 VAR_FLAVOUR_DEFAULT, 20186 VAR_FLAVOUR_SESSION, 20187 VAR_FLAVOUR_VIMINFO 20188 } var_flavour_T; 20189 20190 static var_flavour_T var_flavour __ARGS((char_u *varname)); 20191 20192 static var_flavour_T 20193 var_flavour(varname) 20194 char_u *varname; 20195 { 20196 char_u *p = varname; 20197 20198 if (ASCII_ISUPPER(*p)) 20199 { 20200 while (*(++p)) 20201 if (ASCII_ISLOWER(*p)) 20202 return VAR_FLAVOUR_SESSION; 20203 return VAR_FLAVOUR_VIMINFO; 20204 } 20205 else 20206 return VAR_FLAVOUR_DEFAULT; 20207 } 20208 #endif 20209 20210 #if defined(FEAT_VIMINFO) || defined(PROTO) 20211 /* 20212 * Restore global vars that start with a capital from the viminfo file 20213 */ 20214 int 20215 read_viminfo_varlist(virp, writing) 20216 vir_T *virp; 20217 int writing; 20218 { 20219 char_u *tab; 20220 int is_string = FALSE; 20221 typval_T tv; 20222 20223 if (!writing && (find_viminfo_parameter('!') != NULL)) 20224 { 20225 tab = vim_strchr(virp->vir_line + 1, '\t'); 20226 if (tab != NULL) 20227 { 20228 *tab++ = '\0'; /* isolate the variable name */ 20229 if (*tab == 'S') /* string var */ 20230 is_string = TRUE; 20231 20232 tab = vim_strchr(tab, '\t'); 20233 if (tab != NULL) 20234 { 20235 if (is_string) 20236 { 20237 tv.v_type = VAR_STRING; 20238 tv.vval.v_string = viminfo_readstring(virp, 20239 (int)(tab - virp->vir_line + 1), TRUE); 20240 } 20241 else 20242 { 20243 tv.v_type = VAR_NUMBER; 20244 tv.vval.v_number = atol((char *)tab + 1); 20245 } 20246 set_var(virp->vir_line + 1, &tv, FALSE); 20247 if (is_string) 20248 vim_free(tv.vval.v_string); 20249 } 20250 } 20251 } 20252 20253 return viminfo_readline(virp); 20254 } 20255 20256 /* 20257 * Write global vars that start with a capital to the viminfo file 20258 */ 20259 void 20260 write_viminfo_varlist(fp) 20261 FILE *fp; 20262 { 20263 hashitem_T *hi; 20264 dictitem_T *this_var; 20265 int todo; 20266 char *s; 20267 char_u *p; 20268 char_u *tofree; 20269 char_u numbuf[NUMBUFLEN]; 20270 20271 if (find_viminfo_parameter('!') == NULL) 20272 return; 20273 20274 fprintf(fp, _("\n# global variables:\n")); 20275 20276 todo = (int)globvarht.ht_used; 20277 for (hi = globvarht.ht_array; todo > 0; ++hi) 20278 { 20279 if (!HASHITEM_EMPTY(hi)) 20280 { 20281 --todo; 20282 this_var = HI2DI(hi); 20283 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 20284 { 20285 switch (this_var->di_tv.v_type) 20286 { 20287 case VAR_STRING: s = "STR"; break; 20288 case VAR_NUMBER: s = "NUM"; break; 20289 default: continue; 20290 } 20291 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 20292 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 20293 if (p != NULL) 20294 viminfo_writestring(fp, p); 20295 vim_free(tofree); 20296 } 20297 } 20298 } 20299 } 20300 #endif 20301 20302 #if defined(FEAT_SESSION) || defined(PROTO) 20303 int 20304 store_session_globals(fd) 20305 FILE *fd; 20306 { 20307 hashitem_T *hi; 20308 dictitem_T *this_var; 20309 int todo; 20310 char_u *p, *t; 20311 20312 todo = (int)globvarht.ht_used; 20313 for (hi = globvarht.ht_array; todo > 0; ++hi) 20314 { 20315 if (!HASHITEM_EMPTY(hi)) 20316 { 20317 --todo; 20318 this_var = HI2DI(hi); 20319 if ((this_var->di_tv.v_type == VAR_NUMBER 20320 || this_var->di_tv.v_type == VAR_STRING) 20321 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 20322 { 20323 /* Escape special characters with a backslash. Turn a LF and 20324 * CR into \n and \r. */ 20325 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 20326 (char_u *)"\\\"\n\r"); 20327 if (p == NULL) /* out of memory */ 20328 break; 20329 for (t = p; *t != NUL; ++t) 20330 if (*t == '\n') 20331 *t = 'n'; 20332 else if (*t == '\r') 20333 *t = 'r'; 20334 if ((fprintf(fd, "let %s = %c%s%c", 20335 this_var->di_key, 20336 (this_var->di_tv.v_type == VAR_STRING) ? '"' 20337 : ' ', 20338 p, 20339 (this_var->di_tv.v_type == VAR_STRING) ? '"' 20340 : ' ') < 0) 20341 || put_eol(fd) == FAIL) 20342 { 20343 vim_free(p); 20344 return FAIL; 20345 } 20346 vim_free(p); 20347 } 20348 } 20349 } 20350 return OK; 20351 } 20352 #endif 20353 20354 /* 20355 * Display script name where an item was last set. 20356 * Should only be invoked when 'verbose' is non-zero. 20357 */ 20358 void 20359 last_set_msg(scriptID) 20360 scid_T scriptID; 20361 { 20362 char_u *p; 20363 20364 if (scriptID != 0) 20365 { 20366 p = home_replace_save(NULL, get_scriptname(scriptID)); 20367 if (p != NULL) 20368 { 20369 verbose_enter(); 20370 MSG_PUTS(_("\n\tLast set from ")); 20371 MSG_PUTS(p); 20372 vim_free(p); 20373 verbose_leave(); 20374 } 20375 } 20376 } 20377 20378 #endif /* FEAT_EVAL */ 20379 20380 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 20381 20382 20383 #ifdef WIN3264 20384 /* 20385 * Functions for ":8" filename modifier: get 8.3 version of a filename. 20386 */ 20387 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 20388 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 20389 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 20390 20391 /* 20392 * Get the short pathname of a file. 20393 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 20394 */ 20395 static int 20396 get_short_pathname(fnamep, bufp, fnamelen) 20397 char_u **fnamep; 20398 char_u **bufp; 20399 int *fnamelen; 20400 { 20401 int l,len; 20402 char_u *newbuf; 20403 20404 len = *fnamelen; 20405 20406 l = GetShortPathName(*fnamep, *fnamep, len); 20407 if (l > len - 1) 20408 { 20409 /* If that doesn't work (not enough space), then save the string 20410 * and try again with a new buffer big enough 20411 */ 20412 newbuf = vim_strnsave(*fnamep, l); 20413 if (newbuf == NULL) 20414 return 0; 20415 20416 vim_free(*bufp); 20417 *fnamep = *bufp = newbuf; 20418 20419 l = GetShortPathName(*fnamep,*fnamep,l+1); 20420 20421 /* Really should always succeed, as the buffer is big enough */ 20422 } 20423 20424 *fnamelen = l; 20425 return 1; 20426 } 20427 20428 /* 20429 * Create a short path name. Returns the length of the buffer it needs. 20430 * Doesn't copy over the end of the buffer passed in. 20431 */ 20432 static int 20433 shortpath_for_invalid_fname(fname, bufp, fnamelen) 20434 char_u **fname; 20435 char_u **bufp; 20436 int *fnamelen; 20437 { 20438 char_u *s, *p, *pbuf2, *pbuf3; 20439 char_u ch; 20440 int len, len2, plen, slen; 20441 20442 /* Make a copy */ 20443 len2 = *fnamelen; 20444 pbuf2 = vim_strnsave(*fname, len2); 20445 pbuf3 = NULL; 20446 20447 s = pbuf2 + len2 - 1; /* Find the end */ 20448 slen = 1; 20449 plen = len2; 20450 20451 if (after_pathsep(pbuf2, s + 1)) 20452 { 20453 --s; 20454 ++slen; 20455 --plen; 20456 } 20457 20458 do 20459 { 20460 /* Go back one path-seperator */ 20461 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 20462 { 20463 --s; 20464 ++slen; 20465 --plen; 20466 } 20467 if (s <= pbuf2) 20468 break; 20469 20470 /* Remeber the character that is about to be blatted */ 20471 ch = *s; 20472 *s = 0; /* get_short_pathname requires a null-terminated string */ 20473 20474 /* Try it in situ */ 20475 p = pbuf2; 20476 if (!get_short_pathname(&p, &pbuf3, &plen)) 20477 { 20478 vim_free(pbuf2); 20479 return -1; 20480 } 20481 *s = ch; /* Preserve the string */ 20482 } while (plen == 0); 20483 20484 if (plen > 0) 20485 { 20486 /* Remeber the length of the new string. */ 20487 *fnamelen = len = plen + slen; 20488 vim_free(*bufp); 20489 if (len > len2) 20490 { 20491 /* If there's not enough space in the currently allocated string, 20492 * then copy it to a buffer big enough. 20493 */ 20494 *fname= *bufp = vim_strnsave(p, len); 20495 if (*fname == NULL) 20496 return -1; 20497 } 20498 else 20499 { 20500 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 20501 *fname = *bufp = pbuf2; 20502 if (p != pbuf2) 20503 strncpy(*fname, p, plen); 20504 pbuf2 = NULL; 20505 } 20506 /* Concat the next bit */ 20507 strncpy(*fname + plen, s, slen); 20508 (*fname)[len] = '\0'; 20509 } 20510 vim_free(pbuf3); 20511 vim_free(pbuf2); 20512 return 0; 20513 } 20514 20515 /* 20516 * Get a pathname for a partial path. 20517 */ 20518 static int 20519 shortpath_for_partial(fnamep, bufp, fnamelen) 20520 char_u **fnamep; 20521 char_u **bufp; 20522 int *fnamelen; 20523 { 20524 int sepcount, len, tflen; 20525 char_u *p; 20526 char_u *pbuf, *tfname; 20527 int hasTilde; 20528 20529 /* Count up the path seperators from the RHS.. so we know which part 20530 * of the path to return. 20531 */ 20532 sepcount = 0; 20533 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 20534 if (vim_ispathsep(*p)) 20535 ++sepcount; 20536 20537 /* Need full path first (use expand_env() to remove a "~/") */ 20538 hasTilde = (**fnamep == '~'); 20539 if (hasTilde) 20540 pbuf = tfname = expand_env_save(*fnamep); 20541 else 20542 pbuf = tfname = FullName_save(*fnamep, FALSE); 20543 20544 len = tflen = (int)STRLEN(tfname); 20545 20546 if (!get_short_pathname(&tfname, &pbuf, &len)) 20547 return -1; 20548 20549 if (len == 0) 20550 { 20551 /* Don't have a valid filename, so shorten the rest of the 20552 * path if we can. This CAN give us invalid 8.3 filenames, but 20553 * there's not a lot of point in guessing what it might be. 20554 */ 20555 len = tflen; 20556 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 20557 return -1; 20558 } 20559 20560 /* Count the paths backward to find the beginning of the desired string. */ 20561 for (p = tfname + len - 1; p >= tfname; --p) 20562 { 20563 #ifdef FEAT_MBYTE 20564 if (has_mbyte) 20565 p -= mb_head_off(tfname, p); 20566 #endif 20567 if (vim_ispathsep(*p)) 20568 { 20569 if (sepcount == 0 || (hasTilde && sepcount == 1)) 20570 break; 20571 else 20572 sepcount --; 20573 } 20574 } 20575 if (hasTilde) 20576 { 20577 --p; 20578 if (p >= tfname) 20579 *p = '~'; 20580 else 20581 return -1; 20582 } 20583 else 20584 ++p; 20585 20586 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 20587 vim_free(*bufp); 20588 *fnamelen = (int)STRLEN(p); 20589 *bufp = pbuf; 20590 *fnamep = p; 20591 20592 return 0; 20593 } 20594 #endif /* WIN3264 */ 20595 20596 /* 20597 * Adjust a filename, according to a string of modifiers. 20598 * *fnamep must be NUL terminated when called. When returning, the length is 20599 * determined by *fnamelen. 20600 * Returns valid flags. 20601 * When there is an error, *fnamep is set to NULL. 20602 */ 20603 int 20604 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 20605 char_u *src; /* string with modifiers */ 20606 int *usedlen; /* characters after src that are used */ 20607 char_u **fnamep; /* file name so far */ 20608 char_u **bufp; /* buffer for allocated file name or NULL */ 20609 int *fnamelen; /* length of fnamep */ 20610 { 20611 int valid = 0; 20612 char_u *tail; 20613 char_u *s, *p, *pbuf; 20614 char_u dirname[MAXPATHL]; 20615 int c; 20616 int has_fullname = 0; 20617 #ifdef WIN3264 20618 int has_shortname = 0; 20619 #endif 20620 20621 repeat: 20622 /* ":p" - full path/file_name */ 20623 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 20624 { 20625 has_fullname = 1; 20626 20627 valid |= VALID_PATH; 20628 *usedlen += 2; 20629 20630 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 20631 if ((*fnamep)[0] == '~' 20632 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 20633 && ((*fnamep)[1] == '/' 20634 # ifdef BACKSLASH_IN_FILENAME 20635 || (*fnamep)[1] == '\\' 20636 # endif 20637 || (*fnamep)[1] == NUL) 20638 20639 #endif 20640 ) 20641 { 20642 *fnamep = expand_env_save(*fnamep); 20643 vim_free(*bufp); /* free any allocated file name */ 20644 *bufp = *fnamep; 20645 if (*fnamep == NULL) 20646 return -1; 20647 } 20648 20649 /* When "/." or "/.." is used: force expansion to get rid of it. */ 20650 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 20651 { 20652 if (vim_ispathsep(*p) 20653 && p[1] == '.' 20654 && (p[2] == NUL 20655 || vim_ispathsep(p[2]) 20656 || (p[2] == '.' 20657 && (p[3] == NUL || vim_ispathsep(p[3]))))) 20658 break; 20659 } 20660 20661 /* FullName_save() is slow, don't use it when not needed. */ 20662 if (*p != NUL || !vim_isAbsName(*fnamep)) 20663 { 20664 *fnamep = FullName_save(*fnamep, *p != NUL); 20665 vim_free(*bufp); /* free any allocated file name */ 20666 *bufp = *fnamep; 20667 if (*fnamep == NULL) 20668 return -1; 20669 } 20670 20671 /* Append a path separator to a directory. */ 20672 if (mch_isdir(*fnamep)) 20673 { 20674 /* Make room for one or two extra characters. */ 20675 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 20676 vim_free(*bufp); /* free any allocated file name */ 20677 *bufp = *fnamep; 20678 if (*fnamep == NULL) 20679 return -1; 20680 add_pathsep(*fnamep); 20681 } 20682 } 20683 20684 /* ":." - path relative to the current directory */ 20685 /* ":~" - path relative to the home directory */ 20686 /* ":8" - shortname path - postponed till after */ 20687 while (src[*usedlen] == ':' 20688 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 20689 { 20690 *usedlen += 2; 20691 if (c == '8') 20692 { 20693 #ifdef WIN3264 20694 has_shortname = 1; /* Postpone this. */ 20695 #endif 20696 continue; 20697 } 20698 pbuf = NULL; 20699 /* Need full path first (use expand_env() to remove a "~/") */ 20700 if (!has_fullname) 20701 { 20702 if (c == '.' && **fnamep == '~') 20703 p = pbuf = expand_env_save(*fnamep); 20704 else 20705 p = pbuf = FullName_save(*fnamep, FALSE); 20706 } 20707 else 20708 p = *fnamep; 20709 20710 has_fullname = 0; 20711 20712 if (p != NULL) 20713 { 20714 if (c == '.') 20715 { 20716 mch_dirname(dirname, MAXPATHL); 20717 s = shorten_fname(p, dirname); 20718 if (s != NULL) 20719 { 20720 *fnamep = s; 20721 if (pbuf != NULL) 20722 { 20723 vim_free(*bufp); /* free any allocated file name */ 20724 *bufp = pbuf; 20725 pbuf = NULL; 20726 } 20727 } 20728 } 20729 else 20730 { 20731 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 20732 /* Only replace it when it starts with '~' */ 20733 if (*dirname == '~') 20734 { 20735 s = vim_strsave(dirname); 20736 if (s != NULL) 20737 { 20738 *fnamep = s; 20739 vim_free(*bufp); 20740 *bufp = s; 20741 } 20742 } 20743 } 20744 vim_free(pbuf); 20745 } 20746 } 20747 20748 tail = gettail(*fnamep); 20749 *fnamelen = (int)STRLEN(*fnamep); 20750 20751 /* ":h" - head, remove "/file_name", can be repeated */ 20752 /* Don't remove the first "/" or "c:\" */ 20753 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 20754 { 20755 valid |= VALID_HEAD; 20756 *usedlen += 2; 20757 s = get_past_head(*fnamep); 20758 while (tail > s && after_pathsep(s, tail)) 20759 --tail; 20760 *fnamelen = (int)(tail - *fnamep); 20761 #ifdef VMS 20762 if (*fnamelen > 0) 20763 *fnamelen += 1; /* the path separator is part of the path */ 20764 #endif 20765 while (tail > s && !after_pathsep(s, tail)) 20766 mb_ptr_back(*fnamep, tail); 20767 } 20768 20769 /* ":8" - shortname */ 20770 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 20771 { 20772 *usedlen += 2; 20773 #ifdef WIN3264 20774 has_shortname = 1; 20775 #endif 20776 } 20777 20778 #ifdef WIN3264 20779 /* Check shortname after we have done 'heads' and before we do 'tails' 20780 */ 20781 if (has_shortname) 20782 { 20783 pbuf = NULL; 20784 /* Copy the string if it is shortened by :h */ 20785 if (*fnamelen < (int)STRLEN(*fnamep)) 20786 { 20787 p = vim_strnsave(*fnamep, *fnamelen); 20788 if (p == 0) 20789 return -1; 20790 vim_free(*bufp); 20791 *bufp = *fnamep = p; 20792 } 20793 20794 /* Split into two implementations - makes it easier. First is where 20795 * there isn't a full name already, second is where there is. 20796 */ 20797 if (!has_fullname && !vim_isAbsName(*fnamep)) 20798 { 20799 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 20800 return -1; 20801 } 20802 else 20803 { 20804 int l; 20805 20806 /* Simple case, already have the full-name 20807 * Nearly always shorter, so try first time. */ 20808 l = *fnamelen; 20809 if (!get_short_pathname(fnamep, bufp, &l)) 20810 return -1; 20811 20812 if (l == 0) 20813 { 20814 /* Couldn't find the filename.. search the paths. 20815 */ 20816 l = *fnamelen; 20817 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 20818 return -1; 20819 } 20820 *fnamelen = l; 20821 } 20822 } 20823 #endif /* WIN3264 */ 20824 20825 /* ":t" - tail, just the basename */ 20826 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 20827 { 20828 *usedlen += 2; 20829 *fnamelen -= (int)(tail - *fnamep); 20830 *fnamep = tail; 20831 } 20832 20833 /* ":e" - extension, can be repeated */ 20834 /* ":r" - root, without extension, can be repeated */ 20835 while (src[*usedlen] == ':' 20836 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 20837 { 20838 /* find a '.' in the tail: 20839 * - for second :e: before the current fname 20840 * - otherwise: The last '.' 20841 */ 20842 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 20843 s = *fnamep - 2; 20844 else 20845 s = *fnamep + *fnamelen - 1; 20846 for ( ; s > tail; --s) 20847 if (s[0] == '.') 20848 break; 20849 if (src[*usedlen + 1] == 'e') /* :e */ 20850 { 20851 if (s > tail) 20852 { 20853 *fnamelen += (int)(*fnamep - (s + 1)); 20854 *fnamep = s + 1; 20855 #ifdef VMS 20856 /* cut version from the extension */ 20857 s = *fnamep + *fnamelen - 1; 20858 for ( ; s > *fnamep; --s) 20859 if (s[0] == ';') 20860 break; 20861 if (s > *fnamep) 20862 *fnamelen = s - *fnamep; 20863 #endif 20864 } 20865 else if (*fnamep <= tail) 20866 *fnamelen = 0; 20867 } 20868 else /* :r */ 20869 { 20870 if (s > tail) /* remove one extension */ 20871 *fnamelen = (int)(s - *fnamep); 20872 } 20873 *usedlen += 2; 20874 } 20875 20876 /* ":s?pat?foo?" - substitute */ 20877 /* ":gs?pat?foo?" - global substitute */ 20878 if (src[*usedlen] == ':' 20879 && (src[*usedlen + 1] == 's' 20880 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 20881 { 20882 char_u *str; 20883 char_u *pat; 20884 char_u *sub; 20885 int sep; 20886 char_u *flags; 20887 int didit = FALSE; 20888 20889 flags = (char_u *)""; 20890 s = src + *usedlen + 2; 20891 if (src[*usedlen + 1] == 'g') 20892 { 20893 flags = (char_u *)"g"; 20894 ++s; 20895 } 20896 20897 sep = *s++; 20898 if (sep) 20899 { 20900 /* find end of pattern */ 20901 p = vim_strchr(s, sep); 20902 if (p != NULL) 20903 { 20904 pat = vim_strnsave(s, (int)(p - s)); 20905 if (pat != NULL) 20906 { 20907 s = p + 1; 20908 /* find end of substitution */ 20909 p = vim_strchr(s, sep); 20910 if (p != NULL) 20911 { 20912 sub = vim_strnsave(s, (int)(p - s)); 20913 str = vim_strnsave(*fnamep, *fnamelen); 20914 if (sub != NULL && str != NULL) 20915 { 20916 *usedlen = (int)(p + 1 - src); 20917 s = do_string_sub(str, pat, sub, flags); 20918 if (s != NULL) 20919 { 20920 *fnamep = s; 20921 *fnamelen = (int)STRLEN(s); 20922 vim_free(*bufp); 20923 *bufp = s; 20924 didit = TRUE; 20925 } 20926 } 20927 vim_free(sub); 20928 vim_free(str); 20929 } 20930 vim_free(pat); 20931 } 20932 } 20933 /* after using ":s", repeat all the modifiers */ 20934 if (didit) 20935 goto repeat; 20936 } 20937 } 20938 20939 return valid; 20940 } 20941 20942 /* 20943 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 20944 * "flags" can be "g" to do a global substitute. 20945 * Returns an allocated string, NULL for error. 20946 */ 20947 char_u * 20948 do_string_sub(str, pat, sub, flags) 20949 char_u *str; 20950 char_u *pat; 20951 char_u *sub; 20952 char_u *flags; 20953 { 20954 int sublen; 20955 regmatch_T regmatch; 20956 int i; 20957 int do_all; 20958 char_u *tail; 20959 garray_T ga; 20960 char_u *ret; 20961 char_u *save_cpo; 20962 20963 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 20964 save_cpo = p_cpo; 20965 p_cpo = (char_u *)""; 20966 20967 ga_init2(&ga, 1, 200); 20968 20969 do_all = (flags[0] == 'g'); 20970 20971 regmatch.rm_ic = p_ic; 20972 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 20973 if (regmatch.regprog != NULL) 20974 { 20975 tail = str; 20976 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 20977 { 20978 /* 20979 * Get some space for a temporary buffer to do the substitution 20980 * into. It will contain: 20981 * - The text up to where the match is. 20982 * - The substituted text. 20983 * - The text after the match. 20984 */ 20985 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 20986 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 20987 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 20988 { 20989 ga_clear(&ga); 20990 break; 20991 } 20992 20993 /* copy the text up to where the match is */ 20994 i = (int)(regmatch.startp[0] - tail); 20995 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 20996 /* add the substituted text */ 20997 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 20998 + ga.ga_len + i, TRUE, TRUE, FALSE); 20999 ga.ga_len += i + sublen - 1; 21000 /* avoid getting stuck on a match with an empty string */ 21001 if (tail == regmatch.endp[0]) 21002 { 21003 if (*tail == NUL) 21004 break; 21005 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 21006 ++ga.ga_len; 21007 } 21008 else 21009 { 21010 tail = regmatch.endp[0]; 21011 if (*tail == NUL) 21012 break; 21013 } 21014 if (!do_all) 21015 break; 21016 } 21017 21018 if (ga.ga_data != NULL) 21019 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 21020 21021 vim_free(regmatch.regprog); 21022 } 21023 21024 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 21025 ga_clear(&ga); 21026 p_cpo = save_cpo; 21027 21028 return ret; 21029 } 21030 21031 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 21032