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(WIN16) || defined(WIN32) || defined(_WIN64) 14 # include "vimio.h" /* for mch_open(), must be before vim.h */ 15 #endif 16 17 #include "vim.h" 18 19 #if defined(FEAT_EVAL) || defined(PROTO) 20 21 #ifdef AMIGA 22 # include <time.h> /* for strftime() */ 23 #endif 24 25 #ifdef MACOS 26 # include <time.h> /* for time_t */ 27 #endif 28 29 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 30 # include <math.h> 31 #endif 32 33 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ 34 35 #define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not 36 be freed. */ 37 38 /* 39 * In a hashtab item "hi_key" points to "di_key" in a dictitem. 40 * This avoids adding a pointer to the hashtab item. 41 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. 42 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. 43 * HI2DI() converts a hashitem pointer to a dictitem pointer. 44 */ 45 static dictitem_T dumdi; 46 #define DI2HIKEY(di) ((di)->di_key) 47 #define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) 48 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) 49 50 /* 51 * Structure returned by get_lval() and used by set_var_lval(). 52 * For a plain name: 53 * "name" points to the variable name. 54 * "exp_name" is NULL. 55 * "tv" is NULL 56 * For a magic braces name: 57 * "name" points to the expanded variable name. 58 * "exp_name" is non-NULL, to be freed later. 59 * "tv" is NULL 60 * For an index in a list: 61 * "name" points to the (expanded) variable name. 62 * "exp_name" NULL or non-NULL, to be freed later. 63 * "tv" points to the (first) list item value 64 * "li" points to the (first) list item 65 * "range", "n1", "n2" and "empty2" indicate what items are used. 66 * For an existing Dict item: 67 * "name" points to the (expanded) variable name. 68 * "exp_name" NULL or non-NULL, to be freed later. 69 * "tv" points to the dict item value 70 * "newkey" is NULL 71 * For a non-existing Dict item: 72 * "name" points to the (expanded) variable name. 73 * "exp_name" NULL or non-NULL, to be freed later. 74 * "tv" points to the Dictionary typval_T 75 * "newkey" is the key for the new item. 76 */ 77 typedef struct lval_S 78 { 79 char_u *ll_name; /* start of variable name (can be NULL) */ 80 char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ 81 typval_T *ll_tv; /* Typeval of item being used. If "newkey" 82 isn't NULL it's the Dict to which to add 83 the item. */ 84 listitem_T *ll_li; /* The list item or NULL. */ 85 list_T *ll_list; /* The list or NULL. */ 86 int ll_range; /* TRUE when a [i:j] range was used */ 87 long ll_n1; /* First index for list */ 88 long ll_n2; /* Second index for list range */ 89 int ll_empty2; /* Second index is empty: [i:] */ 90 dict_T *ll_dict; /* The Dictionary or NULL */ 91 dictitem_T *ll_di; /* The dictitem or NULL */ 92 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 93 } lval_T; 94 95 96 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 97 static char *e_listidx = N_("E684: list index out of range: %ld"); 98 static char *e_undefvar = N_("E121: Undefined variable: %s"); 99 static char *e_missbrac = N_("E111: Missing ']'"); 100 static char *e_listarg = N_("E686: Argument of %s must be a List"); 101 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); 102 static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary"); 103 static char *e_listreq = N_("E714: List required"); 104 static char *e_dictreq = N_("E715: Dictionary required"); 105 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 106 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 107 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 108 static char *e_funcdict = N_("E717: Dictionary entry already exists"); 109 static char *e_funcref = N_("E718: Funcref required"); 110 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 111 static char *e_letwrong = N_("E734: Wrong variable type for %s="); 112 static char *e_nofunc = N_("E130: Unknown function: %s"); 113 static char *e_illvar = N_("E461: Illegal variable name: %s"); 114 115 /* 116 * All user-defined global variables are stored in dictionary "globvardict". 117 * "globvars_var" is the variable that is used for "g:". 118 */ 119 static dict_T globvardict; 120 static dictitem_T globvars_var; 121 #define globvarht globvardict.dv_hashtab 122 123 /* 124 * Old Vim variables such as "v:version" are also available without the "v:". 125 * Also in functions. We need a special hashtable for them. 126 */ 127 static hashtab_T compat_hashtab; 128 129 /* 130 * When recursively copying lists and dicts we need to remember which ones we 131 * have done to avoid endless recursiveness. This unique ID is used for that. 132 * The last bit is used for previous_funccal, ignored when comparing. 133 */ 134 static int current_copyID = 0; 135 #define COPYID_INC 2 136 #define COPYID_MASK (~0x1) 137 138 /* 139 * Array to hold the hashtab with variables local to each sourced script. 140 * Each item holds a variable (nameless) that points to the dict_T. 141 */ 142 typedef struct 143 { 144 dictitem_T sv_var; 145 dict_T sv_dict; 146 } scriptvar_T; 147 148 static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL}; 149 #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1]) 150 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) 151 152 static int echo_attr = 0; /* attributes used for ":echo" */ 153 154 /* Values for trans_function_name() argument: */ 155 #define TFN_INT 1 /* internal function name OK */ 156 #define TFN_QUIET 2 /* no error messages */ 157 158 /* 159 * Structure to hold info for a user function. 160 */ 161 typedef struct ufunc ufunc_T; 162 163 struct ufunc 164 { 165 int uf_varargs; /* variable nr of arguments */ 166 int uf_flags; 167 int uf_calls; /* nr of active calls */ 168 garray_T uf_args; /* arguments */ 169 garray_T uf_lines; /* function lines */ 170 #ifdef FEAT_PROFILE 171 int uf_profiling; /* TRUE when func is being profiled */ 172 /* profiling the function as a whole */ 173 int uf_tm_count; /* nr of calls */ 174 proftime_T uf_tm_total; /* time spent in function + children */ 175 proftime_T uf_tm_self; /* time spent in function itself */ 176 proftime_T uf_tm_children; /* time spent in children this call */ 177 /* profiling the function per line */ 178 int *uf_tml_count; /* nr of times line was executed */ 179 proftime_T *uf_tml_total; /* time spent in a line + children */ 180 proftime_T *uf_tml_self; /* time spent in a line itself */ 181 proftime_T uf_tml_start; /* start time for current line */ 182 proftime_T uf_tml_children; /* time spent in children for this line */ 183 proftime_T uf_tml_wait; /* start wait time for current line */ 184 int uf_tml_idx; /* index of line being timed; -1 if none */ 185 int uf_tml_execed; /* line being timed was executed */ 186 #endif 187 scid_T uf_script_ID; /* ID of script where function was defined, 188 used for s: variables */ 189 int uf_refcount; /* for numbered function: reference count */ 190 char_u uf_name[1]; /* name of function (actually longer); can 191 start with <SNR>123_ (<SNR> is K_SPECIAL 192 KS_EXTRA KE_SNR) */ 193 }; 194 195 /* function flags */ 196 #define FC_ABORT 1 /* abort function on error */ 197 #define FC_RANGE 2 /* function accepts range */ 198 #define FC_DICT 4 /* Dict function, uses "self" */ 199 200 /* 201 * All user-defined functions are found in this hashtable. 202 */ 203 static hashtab_T func_hashtab; 204 205 /* The names of packages that once were loaded are remembered. */ 206 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 207 208 /* list heads for garbage collection */ 209 static dict_T *first_dict = NULL; /* list of all dicts */ 210 static list_T *first_list = NULL; /* list of all lists */ 211 212 /* From user function to hashitem and back. */ 213 static ufunc_T dumuf; 214 #define UF2HIKEY(fp) ((fp)->uf_name) 215 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 216 #define HI2UF(hi) HIKEY2UF((hi)->hi_key) 217 218 #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 219 #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 220 221 #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 222 #define VAR_SHORT_LEN 20 /* short variable name length */ 223 #define FIXVAR_CNT 12 /* number of fixed variables */ 224 225 /* structure to hold info for a function that is currently being executed. */ 226 typedef struct funccall_S funccall_T; 227 228 struct funccall_S 229 { 230 ufunc_T *func; /* function being called */ 231 int linenr; /* next line to be executed */ 232 int returned; /* ":return" used */ 233 struct /* fixed variables for arguments */ 234 { 235 dictitem_T var; /* variable (without room for name) */ 236 char_u room[VAR_SHORT_LEN]; /* room for the name */ 237 } fixvar[FIXVAR_CNT]; 238 dict_T l_vars; /* l: local function variables */ 239 dictitem_T l_vars_var; /* variable for l: scope */ 240 dict_T l_avars; /* a: argument variables */ 241 dictitem_T l_avars_var; /* variable for a: scope */ 242 list_T l_varlist; /* list for a:000 */ 243 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 244 typval_T *rettv; /* return value */ 245 linenr_T breakpoint; /* next line with breakpoint or zero */ 246 int dbg_tick; /* debug_tick when breakpoint was set */ 247 int level; /* top nesting level of executed function */ 248 #ifdef FEAT_PROFILE 249 proftime_T prof_child; /* time spent in a child */ 250 #endif 251 funccall_T *caller; /* calling function or NULL */ 252 }; 253 254 /* 255 * Info used by a ":for" loop. 256 */ 257 typedef struct 258 { 259 int fi_semicolon; /* TRUE if ending in '; var]' */ 260 int fi_varcount; /* nr of variables in the list */ 261 listwatch_T fi_lw; /* keep an eye on the item used. */ 262 list_T *fi_list; /* list being used */ 263 } forinfo_T; 264 265 /* 266 * Struct used by trans_function_name() 267 */ 268 typedef struct 269 { 270 dict_T *fd_dict; /* Dictionary used */ 271 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 272 dictitem_T *fd_di; /* Dictionary item used */ 273 } funcdict_T; 274 275 276 /* 277 * Array to hold the value of v: variables. 278 * The value is in a dictitem, so that it can also be used in the v: scope. 279 * The reason to use this table anyway is for very quick access to the 280 * variables with the VV_ defines. 281 */ 282 #include "version.h" 283 284 /* values for vv_flags: */ 285 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 286 #define VV_RO 2 /* read-only */ 287 #define VV_RO_SBX 4 /* read-only in the sandbox */ 288 289 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}}, {0} 290 291 static struct vimvar 292 { 293 char *vv_name; /* name of variable, without v: */ 294 dictitem_T vv_di; /* value and name for key */ 295 char vv_filler[16]; /* space for LONGEST name below!!! */ 296 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 297 } vimvars[VV_LEN] = 298 { 299 /* 300 * The order here must match the VV_ defines in vim.h! 301 * Initializing a union does not work, leave tv.vval empty to get zero's. 302 */ 303 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 304 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 305 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 306 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 307 {VV_NAME("warningmsg", VAR_STRING), 0}, 308 {VV_NAME("statusmsg", VAR_STRING), 0}, 309 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 310 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 311 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 312 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 313 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 314 {VV_NAME("fname", VAR_STRING), VV_RO}, 315 {VV_NAME("lang", VAR_STRING), VV_RO}, 316 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 317 {VV_NAME("ctype", VAR_STRING), VV_RO}, 318 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 319 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 320 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 321 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 322 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 323 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 324 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 325 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 326 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 327 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 328 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 329 {VV_NAME("progname", VAR_STRING), VV_RO}, 330 {VV_NAME("servername", VAR_STRING), VV_RO}, 331 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 332 {VV_NAME("exception", VAR_STRING), VV_RO}, 333 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 334 {VV_NAME("register", VAR_STRING), VV_RO}, 335 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 336 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 337 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 338 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 339 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 340 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 341 {VV_NAME("fcs_choice", VAR_STRING), 0}, 342 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 343 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 344 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 345 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 346 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 347 {VV_NAME("scrollstart", VAR_STRING), 0}, 348 {VV_NAME("swapname", VAR_STRING), VV_RO}, 349 {VV_NAME("swapchoice", VAR_STRING), 0}, 350 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 351 {VV_NAME("char", VAR_STRING), VV_RO}, 352 {VV_NAME("mouse_win", VAR_NUMBER), 0}, 353 {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, 354 {VV_NAME("mouse_col", VAR_NUMBER), 0}, 355 {VV_NAME("operator", VAR_STRING), VV_RO}, 356 {VV_NAME("searchforward", VAR_NUMBER), 0}, 357 {VV_NAME("oldfiles", VAR_LIST), 0}, 358 }; 359 360 /* shorthand */ 361 #define vv_type vv_di.di_tv.v_type 362 #define vv_nr vv_di.di_tv.vval.v_number 363 #define vv_float vv_di.di_tv.vval.v_float 364 #define vv_str vv_di.di_tv.vval.v_string 365 #define vv_list vv_di.di_tv.vval.v_list 366 #define vv_tv vv_di.di_tv 367 368 /* 369 * The v: variables are stored in dictionary "vimvardict". 370 * "vimvars_var" is the variable that is used for the "l:" scope. 371 */ 372 static dict_T vimvardict; 373 static dictitem_T vimvars_var; 374 #define vimvarht vimvardict.dv_hashtab 375 376 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 377 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 378 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 379 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 380 #endif 381 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 382 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 383 static char_u *skip_var_one __ARGS((char_u *arg)); 384 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty, int *first)); 385 static void list_glob_vars __ARGS((int *first)); 386 static void list_buf_vars __ARGS((int *first)); 387 static void list_win_vars __ARGS((int *first)); 388 #ifdef FEAT_WINDOWS 389 static void list_tab_vars __ARGS((int *first)); 390 #endif 391 static void list_vim_vars __ARGS((int *first)); 392 static void list_script_vars __ARGS((int *first)); 393 static void list_func_vars __ARGS((int *first)); 394 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first)); 395 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 396 static int check_changedtick __ARGS((char_u *arg)); 397 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 398 static void clear_lval __ARGS((lval_T *lp)); 399 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 400 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 401 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 402 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 403 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 404 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 405 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 406 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 407 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 408 static int tv_islocked __ARGS((typval_T *tv)); 409 410 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 411 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 412 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 413 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 414 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 415 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 416 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate, int want_string)); 417 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate, int want_string)); 418 419 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 420 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 421 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 422 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 423 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 424 static int rettv_list_alloc __ARGS((typval_T *rettv)); 425 static listitem_T *listitem_alloc __ARGS((void)); 426 static void listitem_free __ARGS((listitem_T *item)); 427 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 428 static long list_len __ARGS((list_T *l)); 429 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 430 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 431 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 432 static listitem_T *list_find __ARGS((list_T *l, long n)); 433 static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); 434 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 435 static void list_append __ARGS((list_T *l, listitem_T *item)); 436 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 437 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 438 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 439 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 440 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 441 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 442 static char_u *list2string __ARGS((typval_T *tv, int copyID)); 443 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 444 static int free_unref_items __ARGS((int copyID)); 445 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 446 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 447 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 448 static void dict_unref __ARGS((dict_T *d)); 449 static void dict_free __ARGS((dict_T *d, int recurse)); 450 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 451 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 452 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 453 static long dict_len __ARGS((dict_T *d)); 454 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 455 static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 456 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 457 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 458 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 459 static char_u *string_quote __ARGS((char_u *str, int function)); 460 #ifdef FEAT_FLOAT 461 static int string2float __ARGS((char_u *text, float_T *value)); 462 #endif 463 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 464 static int find_internal_func __ARGS((char_u *name)); 465 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 466 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)); 467 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)); 468 static void emsg_funcname __ARGS((char *ermsg, char_u *name)); 469 static int non_zero_arg __ARGS((typval_T *argvars)); 470 471 #ifdef FEAT_FLOAT 472 static void f_abs __ARGS((typval_T *argvars, typval_T *rettv)); 473 #endif 474 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 479 #ifdef FEAT_FLOAT 480 static void f_atan __ARGS((typval_T *argvars, typval_T *rettv)); 481 #endif 482 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 493 #ifdef FEAT_FLOAT 494 static void f_ceil __ARGS((typval_T *argvars, typval_T *rettv)); 495 #endif 496 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 501 #if defined(FEAT_INS_EXPAND) 502 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 505 #endif 506 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 508 #ifdef FEAT_FLOAT 509 static void f_cos __ARGS((typval_T *argvars, typval_T *rettv)); 510 #endif 511 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 514 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 533 #ifdef FEAT_FLOAT 534 static void f_float2nr __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_floor __ARGS((typval_T *argvars, typval_T *rettv)); 536 #endif 537 static void f_fnameescape __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_haslocaldir __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 608 #ifdef FEAT_FLOAT 609 static void f_log10 __ARGS((typval_T *argvars, typval_T *rettv)); 610 #endif 611 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 623 #ifdef vim_mkdir 624 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 625 #endif 626 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 627 #ifdef FEAT_MZSCHEME 628 static void f_mzeval __ARGS((typval_T *argvars, typval_T *rettv)); 629 #endif 630 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); 633 #ifdef FEAT_FLOAT 634 static void f_pow __ARGS((typval_T *argvars, typval_T *rettv)); 635 #endif 636 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 637 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 640 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 641 static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); 642 static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv)); 643 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 644 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 645 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 646 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 647 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 648 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 649 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 650 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 651 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 652 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 653 #ifdef FEAT_FLOAT 654 static void f_round __ARGS((typval_T *argvars, typval_T *rettv)); 655 #endif 656 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 657 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 658 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 659 static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 660 static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 661 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 662 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 663 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 664 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 665 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 666 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 667 static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv)); 668 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 669 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 670 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 671 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 672 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 673 static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv)); 674 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 675 #ifdef FEAT_FLOAT 676 static void f_sin __ARGS((typval_T *argvars, typval_T *rettv)); 677 #endif 678 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 679 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 680 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 681 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 682 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 683 #ifdef FEAT_FLOAT 684 static void f_sqrt __ARGS((typval_T *argvars, typval_T *rettv)); 685 static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv)); 686 #endif 687 static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv)); 688 #ifdef HAVE_STRFTIME 689 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 690 #endif 691 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 692 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 693 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 694 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 695 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 696 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 697 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 698 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 699 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 700 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 701 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 702 static void f_synstack __ARGS((typval_T *argvars, typval_T *rettv)); 703 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 704 static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 705 static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 706 static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 707 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 708 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 709 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 710 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 711 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 712 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 713 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 714 #ifdef FEAT_FLOAT 715 static void f_trunc __ARGS((typval_T *argvars, typval_T *rettv)); 716 #endif 717 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 718 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 719 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 720 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 721 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 722 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 723 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 724 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 725 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 726 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 727 static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 728 static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 729 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 730 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 731 732 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); 733 static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum)); 734 static int get_env_len __ARGS((char_u **arg)); 735 static int get_id_len __ARGS((char_u **arg)); 736 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 737 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 738 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 739 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 740 valid character */ 741 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 742 static int eval_isnamec __ARGS((int c)); 743 static int eval_isnamec1 __ARGS((int c)); 744 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 745 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 746 static typval_T *alloc_tv __ARGS((void)); 747 static typval_T *alloc_string_tv __ARGS((char_u *string)); 748 static void init_tv __ARGS((typval_T *varp)); 749 static long get_tv_number __ARGS((typval_T *varp)); 750 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 751 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 752 static char_u *get_tv_string __ARGS((typval_T *varp)); 753 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 754 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 755 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 756 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 757 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 758 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 759 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 760 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first)); 761 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first)); 762 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 763 static int var_check_ro __ARGS((int flags, char_u *name)); 764 static int var_check_fixed __ARGS((int flags, char_u *name)); 765 static int tv_check_lock __ARGS((int lock, char_u *name)); 766 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 767 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 768 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 769 static int eval_fname_script __ARGS((char_u *p)); 770 static int eval_fname_sid __ARGS((char_u *p)); 771 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 772 static ufunc_T *find_func __ARGS((char_u *name)); 773 static int function_exists __ARGS((char_u *name)); 774 static int builtin_function __ARGS((char_u *name)); 775 #ifdef FEAT_PROFILE 776 static void func_do_profile __ARGS((ufunc_T *fp)); 777 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 778 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 779 static int 780 # ifdef __BORLANDC__ 781 _RTLENTRYF 782 # endif 783 prof_total_cmp __ARGS((const void *s1, const void *s2)); 784 static int 785 # ifdef __BORLANDC__ 786 _RTLENTRYF 787 # endif 788 prof_self_cmp __ARGS((const void *s1, const void *s2)); 789 #endif 790 static int script_autoload __ARGS((char_u *name, int reload)); 791 static char_u *autoload_name __ARGS((char_u *name)); 792 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 793 static void func_free __ARGS((ufunc_T *fp)); 794 static void func_unref __ARGS((char_u *name)); 795 static void func_ref __ARGS((char_u *name)); 796 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)); 797 static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ; 798 static void free_funccal __ARGS((funccall_T *fc, int free_val)); 799 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 800 static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); 801 static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 802 static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 803 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 804 static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 805 806 /* Character used as separated in autoload function/variable names. */ 807 #define AUTOLOAD_CHAR '#' 808 809 /* 810 * Initialize the global and v: variables. 811 */ 812 void 813 eval_init() 814 { 815 int i; 816 struct vimvar *p; 817 818 init_var_dict(&globvardict, &globvars_var); 819 init_var_dict(&vimvardict, &vimvars_var); 820 hash_init(&compat_hashtab); 821 hash_init(&func_hashtab); 822 823 for (i = 0; i < VV_LEN; ++i) 824 { 825 p = &vimvars[i]; 826 STRCPY(p->vv_di.di_key, p->vv_name); 827 if (p->vv_flags & VV_RO) 828 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 829 else if (p->vv_flags & VV_RO_SBX) 830 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 831 else 832 p->vv_di.di_flags = DI_FLAGS_FIX; 833 834 /* add to v: scope dict, unless the value is not always available */ 835 if (p->vv_type != VAR_UNKNOWN) 836 hash_add(&vimvarht, p->vv_di.di_key); 837 if (p->vv_flags & VV_COMPAT) 838 /* add to compat scope dict */ 839 hash_add(&compat_hashtab, p->vv_di.di_key); 840 } 841 set_vim_var_nr(VV_SEARCHFORWARD, 1L); 842 } 843 844 #if defined(EXITFREE) || defined(PROTO) 845 void 846 eval_clear() 847 { 848 int i; 849 struct vimvar *p; 850 851 for (i = 0; i < VV_LEN; ++i) 852 { 853 p = &vimvars[i]; 854 if (p->vv_di.di_tv.v_type == VAR_STRING) 855 { 856 vim_free(p->vv_str); 857 p->vv_str = NULL; 858 } 859 else if (p->vv_di.di_tv.v_type == VAR_LIST) 860 { 861 list_unref(p->vv_list); 862 p->vv_list = NULL; 863 } 864 } 865 hash_clear(&vimvarht); 866 hash_init(&vimvarht); /* garbage_collect() will access it */ 867 hash_clear(&compat_hashtab); 868 869 free_scriptnames(); 870 871 /* global variables */ 872 vars_clear(&globvarht); 873 874 /* autoloaded script names */ 875 ga_clear_strings(&ga_loaded); 876 877 /* script-local variables */ 878 for (i = 1; i <= ga_scripts.ga_len; ++i) 879 { 880 vars_clear(&SCRIPT_VARS(i)); 881 vim_free(SCRIPT_SV(i)); 882 } 883 ga_clear(&ga_scripts); 884 885 /* unreferenced lists and dicts */ 886 (void)garbage_collect(); 887 888 /* functions */ 889 free_all_functions(); 890 hash_clear(&func_hashtab); 891 } 892 #endif 893 894 /* 895 * Return the name of the executed function. 896 */ 897 char_u * 898 func_name(cookie) 899 void *cookie; 900 { 901 return ((funccall_T *)cookie)->func->uf_name; 902 } 903 904 /* 905 * Return the address holding the next breakpoint line for a funccall cookie. 906 */ 907 linenr_T * 908 func_breakpoint(cookie) 909 void *cookie; 910 { 911 return &((funccall_T *)cookie)->breakpoint; 912 } 913 914 /* 915 * Return the address holding the debug tick for a funccall cookie. 916 */ 917 int * 918 func_dbg_tick(cookie) 919 void *cookie; 920 { 921 return &((funccall_T *)cookie)->dbg_tick; 922 } 923 924 /* 925 * Return the nesting level for a funccall cookie. 926 */ 927 int 928 func_level(cookie) 929 void *cookie; 930 { 931 return ((funccall_T *)cookie)->level; 932 } 933 934 /* pointer to funccal for currently active function */ 935 funccall_T *current_funccal = NULL; 936 937 /* pointer to list of previously used funccal, still around because some 938 * item in it is still being used. */ 939 funccall_T *previous_funccal = NULL; 940 941 /* 942 * Return TRUE when a function was ended by a ":return" command. 943 */ 944 int 945 current_func_returned() 946 { 947 return current_funccal->returned; 948 } 949 950 951 /* 952 * Set an internal variable to a string value. Creates the variable if it does 953 * not already exist. 954 */ 955 void 956 set_internal_string_var(name, value) 957 char_u *name; 958 char_u *value; 959 { 960 char_u *val; 961 typval_T *tvp; 962 963 val = vim_strsave(value); 964 if (val != NULL) 965 { 966 tvp = alloc_string_tv(val); 967 if (tvp != NULL) 968 { 969 set_var(name, tvp, FALSE); 970 free_tv(tvp); 971 } 972 } 973 } 974 975 static lval_T *redir_lval = NULL; 976 static garray_T redir_ga; /* only valid when redir_lval is not NULL */ 977 static char_u *redir_endp = NULL; 978 static char_u *redir_varname = NULL; 979 980 /* 981 * Start recording command output to a variable 982 * Returns OK if successfully completed the setup. FAIL otherwise. 983 */ 984 int 985 var_redir_start(name, append) 986 char_u *name; 987 int append; /* append to an existing variable */ 988 { 989 int save_emsg; 990 int err; 991 typval_T tv; 992 993 /* Catch a bad name early. */ 994 if (!eval_isnamec1(*name)) 995 { 996 EMSG(_(e_invarg)); 997 return FAIL; 998 } 999 1000 /* Make a copy of the name, it is used in redir_lval until redir ends. */ 1001 redir_varname = vim_strsave(name); 1002 if (redir_varname == NULL) 1003 return FAIL; 1004 1005 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 1006 if (redir_lval == NULL) 1007 { 1008 var_redir_stop(); 1009 return FAIL; 1010 } 1011 1012 /* The output is stored in growarray "redir_ga" until redirection ends. */ 1013 ga_init2(&redir_ga, (int)sizeof(char), 500); 1014 1015 /* Parse the variable name (can be a dict or list entry). */ 1016 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 1017 FNE_CHECK_START); 1018 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 1019 { 1020 if (redir_endp != NULL && *redir_endp != NUL) 1021 /* Trailing characters are present after the variable name */ 1022 EMSG(_(e_trailing)); 1023 else 1024 EMSG(_(e_invarg)); 1025 redir_endp = NULL; /* don't store a value, only cleanup */ 1026 var_redir_stop(); 1027 return FAIL; 1028 } 1029 1030 /* check if we can write to the variable: set it to or append an empty 1031 * string */ 1032 save_emsg = did_emsg; 1033 did_emsg = FALSE; 1034 tv.v_type = VAR_STRING; 1035 tv.vval.v_string = (char_u *)""; 1036 if (append) 1037 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 1038 else 1039 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 1040 err = did_emsg; 1041 did_emsg |= save_emsg; 1042 if (err) 1043 { 1044 redir_endp = NULL; /* don't store a value, only cleanup */ 1045 var_redir_stop(); 1046 return FAIL; 1047 } 1048 if (redir_lval->ll_newkey != NULL) 1049 { 1050 /* Dictionary item was created, don't do it again. */ 1051 vim_free(redir_lval->ll_newkey); 1052 redir_lval->ll_newkey = NULL; 1053 } 1054 1055 return OK; 1056 } 1057 1058 /* 1059 * Append "value[value_len]" to the variable set by var_redir_start(). 1060 * The actual appending is postponed until redirection ends, because the value 1061 * appended may in fact be the string we write to, changing it may cause freed 1062 * memory to be used: 1063 * :redir => foo 1064 * :let foo 1065 * :redir END 1066 */ 1067 void 1068 var_redir_str(value, value_len) 1069 char_u *value; 1070 int value_len; 1071 { 1072 int len; 1073 1074 if (redir_lval == NULL) 1075 return; 1076 1077 if (value_len == -1) 1078 len = (int)STRLEN(value); /* Append the entire string */ 1079 else 1080 len = value_len; /* Append only "value_len" characters */ 1081 1082 if (ga_grow(&redir_ga, len) == OK) 1083 { 1084 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 1085 redir_ga.ga_len += len; 1086 } 1087 else 1088 var_redir_stop(); 1089 } 1090 1091 /* 1092 * Stop redirecting command output to a variable. 1093 * Frees the allocated memory. 1094 */ 1095 void 1096 var_redir_stop() 1097 { 1098 typval_T tv; 1099 1100 if (redir_lval != NULL) 1101 { 1102 /* If there was no error: assign the text to the variable. */ 1103 if (redir_endp != NULL) 1104 { 1105 ga_append(&redir_ga, NUL); /* Append the trailing NUL. */ 1106 tv.v_type = VAR_STRING; 1107 tv.vval.v_string = redir_ga.ga_data; 1108 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 1109 } 1110 1111 /* free the collected output */ 1112 vim_free(redir_ga.ga_data); 1113 redir_ga.ga_data = NULL; 1114 1115 clear_lval(redir_lval); 1116 vim_free(redir_lval); 1117 redir_lval = NULL; 1118 } 1119 vim_free(redir_varname); 1120 redir_varname = NULL; 1121 } 1122 1123 # if defined(FEAT_MBYTE) || defined(PROTO) 1124 int 1125 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1126 char_u *enc_from; 1127 char_u *enc_to; 1128 char_u *fname_from; 1129 char_u *fname_to; 1130 { 1131 int err = FALSE; 1132 1133 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1134 set_vim_var_string(VV_CC_TO, enc_to, -1); 1135 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1136 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1137 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1138 err = TRUE; 1139 set_vim_var_string(VV_CC_FROM, NULL, -1); 1140 set_vim_var_string(VV_CC_TO, NULL, -1); 1141 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1142 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1143 1144 if (err) 1145 return FAIL; 1146 return OK; 1147 } 1148 # endif 1149 1150 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1151 int 1152 eval_printexpr(fname, args) 1153 char_u *fname; 1154 char_u *args; 1155 { 1156 int err = FALSE; 1157 1158 set_vim_var_string(VV_FNAME_IN, fname, -1); 1159 set_vim_var_string(VV_CMDARG, args, -1); 1160 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1161 err = TRUE; 1162 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1163 set_vim_var_string(VV_CMDARG, NULL, -1); 1164 1165 if (err) 1166 { 1167 mch_remove(fname); 1168 return FAIL; 1169 } 1170 return OK; 1171 } 1172 # endif 1173 1174 # if defined(FEAT_DIFF) || defined(PROTO) 1175 void 1176 eval_diff(origfile, newfile, outfile) 1177 char_u *origfile; 1178 char_u *newfile; 1179 char_u *outfile; 1180 { 1181 int err = FALSE; 1182 1183 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1184 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1185 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1186 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1187 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1188 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1189 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1190 } 1191 1192 void 1193 eval_patch(origfile, difffile, outfile) 1194 char_u *origfile; 1195 char_u *difffile; 1196 char_u *outfile; 1197 { 1198 int err; 1199 1200 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1201 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1202 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1203 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1204 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1205 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1206 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1207 } 1208 # endif 1209 1210 /* 1211 * Top level evaluation function, returning a boolean. 1212 * Sets "error" to TRUE if there was an error. 1213 * Return TRUE or FALSE. 1214 */ 1215 int 1216 eval_to_bool(arg, error, nextcmd, skip) 1217 char_u *arg; 1218 int *error; 1219 char_u **nextcmd; 1220 int skip; /* only parse, don't execute */ 1221 { 1222 typval_T tv; 1223 int retval = FALSE; 1224 1225 if (skip) 1226 ++emsg_skip; 1227 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1228 *error = TRUE; 1229 else 1230 { 1231 *error = FALSE; 1232 if (!skip) 1233 { 1234 retval = (get_tv_number_chk(&tv, error) != 0); 1235 clear_tv(&tv); 1236 } 1237 } 1238 if (skip) 1239 --emsg_skip; 1240 1241 return retval; 1242 } 1243 1244 /* 1245 * Top level evaluation function, returning a string. If "skip" is TRUE, 1246 * only parsing to "nextcmd" is done, without reporting errors. Return 1247 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1248 */ 1249 char_u * 1250 eval_to_string_skip(arg, nextcmd, skip) 1251 char_u *arg; 1252 char_u **nextcmd; 1253 int skip; /* only parse, don't execute */ 1254 { 1255 typval_T tv; 1256 char_u *retval; 1257 1258 if (skip) 1259 ++emsg_skip; 1260 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1261 retval = NULL; 1262 else 1263 { 1264 retval = vim_strsave(get_tv_string(&tv)); 1265 clear_tv(&tv); 1266 } 1267 if (skip) 1268 --emsg_skip; 1269 1270 return retval; 1271 } 1272 1273 /* 1274 * Skip over an expression at "*pp". 1275 * Return FAIL for an error, OK otherwise. 1276 */ 1277 int 1278 skip_expr(pp) 1279 char_u **pp; 1280 { 1281 typval_T rettv; 1282 1283 *pp = skipwhite(*pp); 1284 return eval1(pp, &rettv, FALSE); 1285 } 1286 1287 /* 1288 * Top level evaluation function, returning a string. 1289 * When "convert" is TRUE convert a List into a sequence of lines and convert 1290 * a Float to a String. 1291 * Return pointer to allocated memory, or NULL for failure. 1292 */ 1293 char_u * 1294 eval_to_string(arg, nextcmd, convert) 1295 char_u *arg; 1296 char_u **nextcmd; 1297 int convert; 1298 { 1299 typval_T tv; 1300 char_u *retval; 1301 garray_T ga; 1302 #ifdef FEAT_FLOAT 1303 char_u numbuf[NUMBUFLEN]; 1304 #endif 1305 1306 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1307 retval = NULL; 1308 else 1309 { 1310 if (convert && tv.v_type == VAR_LIST) 1311 { 1312 ga_init2(&ga, (int)sizeof(char), 80); 1313 if (tv.vval.v_list != NULL) 1314 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1315 ga_append(&ga, NUL); 1316 retval = (char_u *)ga.ga_data; 1317 } 1318 #ifdef FEAT_FLOAT 1319 else if (convert && tv.v_type == VAR_FLOAT) 1320 { 1321 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float); 1322 retval = vim_strsave(numbuf); 1323 } 1324 #endif 1325 else 1326 retval = vim_strsave(get_tv_string(&tv)); 1327 clear_tv(&tv); 1328 } 1329 1330 return retval; 1331 } 1332 1333 /* 1334 * Call eval_to_string() without using current local variables and using 1335 * textlock. When "use_sandbox" is TRUE use the sandbox. 1336 */ 1337 char_u * 1338 eval_to_string_safe(arg, nextcmd, use_sandbox) 1339 char_u *arg; 1340 char_u **nextcmd; 1341 int use_sandbox; 1342 { 1343 char_u *retval; 1344 void *save_funccalp; 1345 1346 save_funccalp = save_funccal(); 1347 if (use_sandbox) 1348 ++sandbox; 1349 ++textlock; 1350 retval = eval_to_string(arg, nextcmd, FALSE); 1351 if (use_sandbox) 1352 --sandbox; 1353 --textlock; 1354 restore_funccal(save_funccalp); 1355 return retval; 1356 } 1357 1358 /* 1359 * Top level evaluation function, returning a number. 1360 * Evaluates "expr" silently. 1361 * Returns -1 for an error. 1362 */ 1363 int 1364 eval_to_number(expr) 1365 char_u *expr; 1366 { 1367 typval_T rettv; 1368 int retval; 1369 char_u *p = skipwhite(expr); 1370 1371 ++emsg_off; 1372 1373 if (eval1(&p, &rettv, TRUE) == FAIL) 1374 retval = -1; 1375 else 1376 { 1377 retval = get_tv_number_chk(&rettv, NULL); 1378 clear_tv(&rettv); 1379 } 1380 --emsg_off; 1381 1382 return retval; 1383 } 1384 1385 /* 1386 * Prepare v: variable "idx" to be used. 1387 * Save the current typeval in "save_tv". 1388 * When not used yet add the variable to the v: hashtable. 1389 */ 1390 static void 1391 prepare_vimvar(idx, save_tv) 1392 int idx; 1393 typval_T *save_tv; 1394 { 1395 *save_tv = vimvars[idx].vv_tv; 1396 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1397 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1398 } 1399 1400 /* 1401 * Restore v: variable "idx" to typeval "save_tv". 1402 * When no longer defined, remove the variable from the v: hashtable. 1403 */ 1404 static void 1405 restore_vimvar(idx, save_tv) 1406 int idx; 1407 typval_T *save_tv; 1408 { 1409 hashitem_T *hi; 1410 1411 vimvars[idx].vv_tv = *save_tv; 1412 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1413 { 1414 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1415 if (HASHITEM_EMPTY(hi)) 1416 EMSG2(_(e_intern2), "restore_vimvar()"); 1417 else 1418 hash_remove(&vimvarht, hi); 1419 } 1420 } 1421 1422 #if defined(FEAT_SPELL) || defined(PROTO) 1423 /* 1424 * Evaluate an expression to a list with suggestions. 1425 * For the "expr:" part of 'spellsuggest'. 1426 * Returns NULL when there is an error. 1427 */ 1428 list_T * 1429 eval_spell_expr(badword, expr) 1430 char_u *badword; 1431 char_u *expr; 1432 { 1433 typval_T save_val; 1434 typval_T rettv; 1435 list_T *list = NULL; 1436 char_u *p = skipwhite(expr); 1437 1438 /* Set "v:val" to the bad word. */ 1439 prepare_vimvar(VV_VAL, &save_val); 1440 vimvars[VV_VAL].vv_type = VAR_STRING; 1441 vimvars[VV_VAL].vv_str = badword; 1442 if (p_verbose == 0) 1443 ++emsg_off; 1444 1445 if (eval1(&p, &rettv, TRUE) == OK) 1446 { 1447 if (rettv.v_type != VAR_LIST) 1448 clear_tv(&rettv); 1449 else 1450 list = rettv.vval.v_list; 1451 } 1452 1453 if (p_verbose == 0) 1454 --emsg_off; 1455 restore_vimvar(VV_VAL, &save_val); 1456 1457 return list; 1458 } 1459 1460 /* 1461 * "list" is supposed to contain two items: a word and a number. Return the 1462 * word in "pp" and the number as the return value. 1463 * Return -1 if anything isn't right. 1464 * Used to get the good word and score from the eval_spell_expr() result. 1465 */ 1466 int 1467 get_spellword(list, pp) 1468 list_T *list; 1469 char_u **pp; 1470 { 1471 listitem_T *li; 1472 1473 li = list->lv_first; 1474 if (li == NULL) 1475 return -1; 1476 *pp = get_tv_string(&li->li_tv); 1477 1478 li = li->li_next; 1479 if (li == NULL) 1480 return -1; 1481 return get_tv_number(&li->li_tv); 1482 } 1483 #endif 1484 1485 /* 1486 * Top level evaluation function. 1487 * Returns an allocated typval_T with the result. 1488 * Returns NULL when there is an error. 1489 */ 1490 typval_T * 1491 eval_expr(arg, nextcmd) 1492 char_u *arg; 1493 char_u **nextcmd; 1494 { 1495 typval_T *tv; 1496 1497 tv = (typval_T *)alloc(sizeof(typval_T)); 1498 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1499 { 1500 vim_free(tv); 1501 tv = NULL; 1502 } 1503 1504 return tv; 1505 } 1506 1507 1508 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \ 1509 || defined(FEAT_COMPL_FUNC) || defined(PROTO) 1510 /* 1511 * Call some vimL function and return the result in "*rettv". 1512 * Uses argv[argc] for the function arguments. Only Number and String 1513 * arguments are currently supported. 1514 * Returns OK or FAIL. 1515 */ 1516 static int 1517 call_vim_function(func, argc, argv, safe, rettv) 1518 char_u *func; 1519 int argc; 1520 char_u **argv; 1521 int safe; /* use the sandbox */ 1522 typval_T *rettv; 1523 { 1524 typval_T *argvars; 1525 long n; 1526 int len; 1527 int i; 1528 int doesrange; 1529 void *save_funccalp = NULL; 1530 int ret; 1531 1532 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1533 if (argvars == NULL) 1534 return FAIL; 1535 1536 for (i = 0; i < argc; i++) 1537 { 1538 /* Pass a NULL or empty argument as an empty string */ 1539 if (argv[i] == NULL || *argv[i] == NUL) 1540 { 1541 argvars[i].v_type = VAR_STRING; 1542 argvars[i].vval.v_string = (char_u *)""; 1543 continue; 1544 } 1545 1546 /* Recognize a number argument, the others must be strings. */ 1547 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1548 if (len != 0 && len == (int)STRLEN(argv[i])) 1549 { 1550 argvars[i].v_type = VAR_NUMBER; 1551 argvars[i].vval.v_number = n; 1552 } 1553 else 1554 { 1555 argvars[i].v_type = VAR_STRING; 1556 argvars[i].vval.v_string = argv[i]; 1557 } 1558 } 1559 1560 if (safe) 1561 { 1562 save_funccalp = save_funccal(); 1563 ++sandbox; 1564 } 1565 1566 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1567 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1568 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1569 &doesrange, TRUE, NULL); 1570 if (safe) 1571 { 1572 --sandbox; 1573 restore_funccal(save_funccalp); 1574 } 1575 vim_free(argvars); 1576 1577 if (ret == FAIL) 1578 clear_tv(rettv); 1579 1580 return ret; 1581 } 1582 1583 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1584 /* 1585 * Call vimL function "func" and return the result as a string. 1586 * Returns NULL when calling the function fails. 1587 * Uses argv[argc] for the function arguments. 1588 */ 1589 void * 1590 call_func_retstr(func, argc, argv, safe) 1591 char_u *func; 1592 int argc; 1593 char_u **argv; 1594 int safe; /* use the sandbox */ 1595 { 1596 typval_T rettv; 1597 char_u *retval; 1598 1599 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1600 return NULL; 1601 1602 retval = vim_strsave(get_tv_string(&rettv)); 1603 clear_tv(&rettv); 1604 return retval; 1605 } 1606 # endif 1607 1608 # if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1609 /* 1610 * Call vimL function "func" and return the result as a number. 1611 * Returns -1 when calling the function fails. 1612 * Uses argv[argc] for the function arguments. 1613 */ 1614 long 1615 call_func_retnr(func, argc, argv, safe) 1616 char_u *func; 1617 int argc; 1618 char_u **argv; 1619 int safe; /* use the sandbox */ 1620 { 1621 typval_T rettv; 1622 long retval; 1623 1624 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1625 return -1; 1626 1627 retval = get_tv_number_chk(&rettv, NULL); 1628 clear_tv(&rettv); 1629 return retval; 1630 } 1631 # endif 1632 1633 /* 1634 * Call vimL function "func" and return the result as a List. 1635 * Uses argv[argc] for the function arguments. 1636 * Returns NULL when there is something wrong. 1637 */ 1638 void * 1639 call_func_retlist(func, argc, argv, safe) 1640 char_u *func; 1641 int argc; 1642 char_u **argv; 1643 int safe; /* use the sandbox */ 1644 { 1645 typval_T rettv; 1646 1647 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1648 return NULL; 1649 1650 if (rettv.v_type != VAR_LIST) 1651 { 1652 clear_tv(&rettv); 1653 return NULL; 1654 } 1655 1656 return rettv.vval.v_list; 1657 } 1658 #endif 1659 1660 1661 /* 1662 * Save the current function call pointer, and set it to NULL. 1663 * Used when executing autocommands and for ":source". 1664 */ 1665 void * 1666 save_funccal() 1667 { 1668 funccall_T *fc = current_funccal; 1669 1670 current_funccal = NULL; 1671 return (void *)fc; 1672 } 1673 1674 void 1675 restore_funccal(vfc) 1676 void *vfc; 1677 { 1678 funccall_T *fc = (funccall_T *)vfc; 1679 1680 current_funccal = fc; 1681 } 1682 1683 #if defined(FEAT_PROFILE) || defined(PROTO) 1684 /* 1685 * Prepare profiling for entering a child or something else that is not 1686 * counted for the script/function itself. 1687 * Should always be called in pair with prof_child_exit(). 1688 */ 1689 void 1690 prof_child_enter(tm) 1691 proftime_T *tm; /* place to store waittime */ 1692 { 1693 funccall_T *fc = current_funccal; 1694 1695 if (fc != NULL && fc->func->uf_profiling) 1696 profile_start(&fc->prof_child); 1697 script_prof_save(tm); 1698 } 1699 1700 /* 1701 * Take care of time spent in a child. 1702 * Should always be called after prof_child_enter(). 1703 */ 1704 void 1705 prof_child_exit(tm) 1706 proftime_T *tm; /* where waittime was stored */ 1707 { 1708 funccall_T *fc = current_funccal; 1709 1710 if (fc != NULL && fc->func->uf_profiling) 1711 { 1712 profile_end(&fc->prof_child); 1713 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1714 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1715 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1716 } 1717 script_prof_restore(tm); 1718 } 1719 #endif 1720 1721 1722 #ifdef FEAT_FOLDING 1723 /* 1724 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1725 * it in "*cp". Doesn't give error messages. 1726 */ 1727 int 1728 eval_foldexpr(arg, cp) 1729 char_u *arg; 1730 int *cp; 1731 { 1732 typval_T tv; 1733 int retval; 1734 char_u *s; 1735 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1736 OPT_LOCAL); 1737 1738 ++emsg_off; 1739 if (use_sandbox) 1740 ++sandbox; 1741 ++textlock; 1742 *cp = NUL; 1743 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1744 retval = 0; 1745 else 1746 { 1747 /* If the result is a number, just return the number. */ 1748 if (tv.v_type == VAR_NUMBER) 1749 retval = tv.vval.v_number; 1750 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1751 retval = 0; 1752 else 1753 { 1754 /* If the result is a string, check if there is a non-digit before 1755 * the number. */ 1756 s = tv.vval.v_string; 1757 if (!VIM_ISDIGIT(*s) && *s != '-') 1758 *cp = *s++; 1759 retval = atol((char *)s); 1760 } 1761 clear_tv(&tv); 1762 } 1763 --emsg_off; 1764 if (use_sandbox) 1765 --sandbox; 1766 --textlock; 1767 1768 return retval; 1769 } 1770 #endif 1771 1772 /* 1773 * ":let" list all variable values 1774 * ":let var1 var2" list variable values 1775 * ":let var = expr" assignment command. 1776 * ":let var += expr" assignment command. 1777 * ":let var -= expr" assignment command. 1778 * ":let var .= expr" assignment command. 1779 * ":let [var1, var2] = expr" unpack list. 1780 */ 1781 void 1782 ex_let(eap) 1783 exarg_T *eap; 1784 { 1785 char_u *arg = eap->arg; 1786 char_u *expr = NULL; 1787 typval_T rettv; 1788 int i; 1789 int var_count = 0; 1790 int semicolon = 0; 1791 char_u op[2]; 1792 char_u *argend; 1793 int first = TRUE; 1794 1795 argend = skip_var_list(arg, &var_count, &semicolon); 1796 if (argend == NULL) 1797 return; 1798 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1799 --argend; 1800 expr = vim_strchr(argend, '='); 1801 if (expr == NULL) 1802 { 1803 /* 1804 * ":let" without "=": list variables 1805 */ 1806 if (*arg == '[') 1807 EMSG(_(e_invarg)); 1808 else if (!ends_excmd(*arg)) 1809 /* ":let var1 var2" */ 1810 arg = list_arg_vars(eap, arg, &first); 1811 else if (!eap->skip) 1812 { 1813 /* ":let" */ 1814 list_glob_vars(&first); 1815 list_buf_vars(&first); 1816 list_win_vars(&first); 1817 #ifdef FEAT_WINDOWS 1818 list_tab_vars(&first); 1819 #endif 1820 list_script_vars(&first); 1821 list_func_vars(&first); 1822 list_vim_vars(&first); 1823 } 1824 eap->nextcmd = check_nextcmd(arg); 1825 } 1826 else 1827 { 1828 op[0] = '='; 1829 op[1] = NUL; 1830 if (expr > argend) 1831 { 1832 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1833 op[0] = expr[-1]; /* +=, -= or .= */ 1834 } 1835 expr = skipwhite(expr + 1); 1836 1837 if (eap->skip) 1838 ++emsg_skip; 1839 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1840 if (eap->skip) 1841 { 1842 if (i != FAIL) 1843 clear_tv(&rettv); 1844 --emsg_skip; 1845 } 1846 else if (i != FAIL) 1847 { 1848 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1849 op); 1850 clear_tv(&rettv); 1851 } 1852 } 1853 } 1854 1855 /* 1856 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1857 * Handles both "var" with any type and "[var, var; var]" with a list type. 1858 * When "nextchars" is not NULL it points to a string with characters that 1859 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1860 * or concatenate. 1861 * Returns OK or FAIL; 1862 */ 1863 static int 1864 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1865 char_u *arg_start; 1866 typval_T *tv; 1867 int copy; /* copy values from "tv", don't move */ 1868 int semicolon; /* from skip_var_list() */ 1869 int var_count; /* from skip_var_list() */ 1870 char_u *nextchars; 1871 { 1872 char_u *arg = arg_start; 1873 list_T *l; 1874 int i; 1875 listitem_T *item; 1876 typval_T ltv; 1877 1878 if (*arg != '[') 1879 { 1880 /* 1881 * ":let var = expr" or ":for var in list" 1882 */ 1883 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1884 return FAIL; 1885 return OK; 1886 } 1887 1888 /* 1889 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1890 */ 1891 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1892 { 1893 EMSG(_(e_listreq)); 1894 return FAIL; 1895 } 1896 1897 i = list_len(l); 1898 if (semicolon == 0 && var_count < i) 1899 { 1900 EMSG(_("E687: Less targets than List items")); 1901 return FAIL; 1902 } 1903 if (var_count - semicolon > i) 1904 { 1905 EMSG(_("E688: More targets than List items")); 1906 return FAIL; 1907 } 1908 1909 item = l->lv_first; 1910 while (*arg != ']') 1911 { 1912 arg = skipwhite(arg + 1); 1913 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1914 item = item->li_next; 1915 if (arg == NULL) 1916 return FAIL; 1917 1918 arg = skipwhite(arg); 1919 if (*arg == ';') 1920 { 1921 /* Put the rest of the list (may be empty) in the var after ';'. 1922 * Create a new list for this. */ 1923 l = list_alloc(); 1924 if (l == NULL) 1925 return FAIL; 1926 while (item != NULL) 1927 { 1928 list_append_tv(l, &item->li_tv); 1929 item = item->li_next; 1930 } 1931 1932 ltv.v_type = VAR_LIST; 1933 ltv.v_lock = 0; 1934 ltv.vval.v_list = l; 1935 l->lv_refcount = 1; 1936 1937 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1938 (char_u *)"]", nextchars); 1939 clear_tv(<v); 1940 if (arg == NULL) 1941 return FAIL; 1942 break; 1943 } 1944 else if (*arg != ',' && *arg != ']') 1945 { 1946 EMSG2(_(e_intern2), "ex_let_vars()"); 1947 return FAIL; 1948 } 1949 } 1950 1951 return OK; 1952 } 1953 1954 /* 1955 * Skip over assignable variable "var" or list of variables "[var, var]". 1956 * Used for ":let varvar = expr" and ":for varvar in expr". 1957 * For "[var, var]" increment "*var_count" for each variable. 1958 * for "[var, var; var]" set "semicolon". 1959 * Return NULL for an error. 1960 */ 1961 static char_u * 1962 skip_var_list(arg, var_count, semicolon) 1963 char_u *arg; 1964 int *var_count; 1965 int *semicolon; 1966 { 1967 char_u *p, *s; 1968 1969 if (*arg == '[') 1970 { 1971 /* "[var, var]": find the matching ']'. */ 1972 p = arg; 1973 for (;;) 1974 { 1975 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1976 s = skip_var_one(p); 1977 if (s == p) 1978 { 1979 EMSG2(_(e_invarg2), p); 1980 return NULL; 1981 } 1982 ++*var_count; 1983 1984 p = skipwhite(s); 1985 if (*p == ']') 1986 break; 1987 else if (*p == ';') 1988 { 1989 if (*semicolon == 1) 1990 { 1991 EMSG(_("Double ; in list of variables")); 1992 return NULL; 1993 } 1994 *semicolon = 1; 1995 } 1996 else if (*p != ',') 1997 { 1998 EMSG2(_(e_invarg2), p); 1999 return NULL; 2000 } 2001 } 2002 return p + 1; 2003 } 2004 else 2005 return skip_var_one(arg); 2006 } 2007 2008 /* 2009 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 2010 * l[idx]. 2011 */ 2012 static char_u * 2013 skip_var_one(arg) 2014 char_u *arg; 2015 { 2016 if (*arg == '@' && arg[1] != NUL) 2017 return arg + 2; 2018 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 2019 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2020 } 2021 2022 /* 2023 * List variables for hashtab "ht" with prefix "prefix". 2024 * If "empty" is TRUE also list NULL strings as empty strings. 2025 */ 2026 static void 2027 list_hashtable_vars(ht, prefix, empty, first) 2028 hashtab_T *ht; 2029 char_u *prefix; 2030 int empty; 2031 int *first; 2032 { 2033 hashitem_T *hi; 2034 dictitem_T *di; 2035 int todo; 2036 2037 todo = (int)ht->ht_used; 2038 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 2039 { 2040 if (!HASHITEM_EMPTY(hi)) 2041 { 2042 --todo; 2043 di = HI2DI(hi); 2044 if (empty || di->di_tv.v_type != VAR_STRING 2045 || di->di_tv.vval.v_string != NULL) 2046 list_one_var(di, prefix, first); 2047 } 2048 } 2049 } 2050 2051 /* 2052 * List global variables. 2053 */ 2054 static void 2055 list_glob_vars(first) 2056 int *first; 2057 { 2058 list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first); 2059 } 2060 2061 /* 2062 * List buffer variables. 2063 */ 2064 static void 2065 list_buf_vars(first) 2066 int *first; 2067 { 2068 char_u numbuf[NUMBUFLEN]; 2069 2070 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", 2071 TRUE, first); 2072 2073 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 2074 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, 2075 numbuf, first); 2076 } 2077 2078 /* 2079 * List window variables. 2080 */ 2081 static void 2082 list_win_vars(first) 2083 int *first; 2084 { 2085 list_hashtable_vars(&curwin->w_vars.dv_hashtab, 2086 (char_u *)"w:", TRUE, first); 2087 } 2088 2089 #ifdef FEAT_WINDOWS 2090 /* 2091 * List tab page variables. 2092 */ 2093 static void 2094 list_tab_vars(first) 2095 int *first; 2096 { 2097 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, 2098 (char_u *)"t:", TRUE, first); 2099 } 2100 #endif 2101 2102 /* 2103 * List Vim variables. 2104 */ 2105 static void 2106 list_vim_vars(first) 2107 int *first; 2108 { 2109 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first); 2110 } 2111 2112 /* 2113 * List script-local variables, if there is a script. 2114 */ 2115 static void 2116 list_script_vars(first) 2117 int *first; 2118 { 2119 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 2120 list_hashtable_vars(&SCRIPT_VARS(current_SID), 2121 (char_u *)"s:", FALSE, first); 2122 } 2123 2124 /* 2125 * List function variables, if there is a function. 2126 */ 2127 static void 2128 list_func_vars(first) 2129 int *first; 2130 { 2131 if (current_funccal != NULL) 2132 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2133 (char_u *)"l:", FALSE, first); 2134 } 2135 2136 /* 2137 * List variables in "arg". 2138 */ 2139 static char_u * 2140 list_arg_vars(eap, arg, first) 2141 exarg_T *eap; 2142 char_u *arg; 2143 int *first; 2144 { 2145 int error = FALSE; 2146 int len; 2147 char_u *name; 2148 char_u *name_start; 2149 char_u *arg_subsc; 2150 char_u *tofree; 2151 typval_T tv; 2152 2153 while (!ends_excmd(*arg) && !got_int) 2154 { 2155 if (error || eap->skip) 2156 { 2157 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2158 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2159 { 2160 emsg_severe = TRUE; 2161 EMSG(_(e_trailing)); 2162 break; 2163 } 2164 } 2165 else 2166 { 2167 /* get_name_len() takes care of expanding curly braces */ 2168 name_start = name = arg; 2169 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2170 if (len <= 0) 2171 { 2172 /* This is mainly to keep test 49 working: when expanding 2173 * curly braces fails overrule the exception error message. */ 2174 if (len < 0 && !aborting()) 2175 { 2176 emsg_severe = TRUE; 2177 EMSG2(_(e_invarg2), arg); 2178 break; 2179 } 2180 error = TRUE; 2181 } 2182 else 2183 { 2184 if (tofree != NULL) 2185 name = tofree; 2186 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 2187 error = TRUE; 2188 else 2189 { 2190 /* handle d.key, l[idx], f(expr) */ 2191 arg_subsc = arg; 2192 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2193 error = TRUE; 2194 else 2195 { 2196 if (arg == arg_subsc && len == 2 && name[1] == ':') 2197 { 2198 switch (*name) 2199 { 2200 case 'g': list_glob_vars(first); break; 2201 case 'b': list_buf_vars(first); break; 2202 case 'w': list_win_vars(first); break; 2203 #ifdef FEAT_WINDOWS 2204 case 't': list_tab_vars(first); break; 2205 #endif 2206 case 'v': list_vim_vars(first); break; 2207 case 's': list_script_vars(first); break; 2208 case 'l': list_func_vars(first); break; 2209 default: 2210 EMSG2(_("E738: Can't list variables for %s"), name); 2211 } 2212 } 2213 else 2214 { 2215 char_u numbuf[NUMBUFLEN]; 2216 char_u *tf; 2217 int c; 2218 char_u *s; 2219 2220 s = echo_string(&tv, &tf, numbuf, 0); 2221 c = *arg; 2222 *arg = NUL; 2223 list_one_var_a((char_u *)"", 2224 arg == arg_subsc ? name : name_start, 2225 tv.v_type, 2226 s == NULL ? (char_u *)"" : s, 2227 first); 2228 *arg = c; 2229 vim_free(tf); 2230 } 2231 clear_tv(&tv); 2232 } 2233 } 2234 } 2235 2236 vim_free(tofree); 2237 } 2238 2239 arg = skipwhite(arg); 2240 } 2241 2242 return arg; 2243 } 2244 2245 /* 2246 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2247 * Returns a pointer to the char just after the var name. 2248 * Returns NULL if there is an error. 2249 */ 2250 static char_u * 2251 ex_let_one(arg, tv, copy, endchars, op) 2252 char_u *arg; /* points to variable name */ 2253 typval_T *tv; /* value to assign to variable */ 2254 int copy; /* copy value from "tv" */ 2255 char_u *endchars; /* valid chars after variable name or NULL */ 2256 char_u *op; /* "+", "-", "." or NULL*/ 2257 { 2258 int c1; 2259 char_u *name; 2260 char_u *p; 2261 char_u *arg_end = NULL; 2262 int len; 2263 int opt_flags; 2264 char_u *tofree = NULL; 2265 2266 /* 2267 * ":let $VAR = expr": Set environment variable. 2268 */ 2269 if (*arg == '$') 2270 { 2271 /* Find the end of the name. */ 2272 ++arg; 2273 name = arg; 2274 len = get_env_len(&arg); 2275 if (len == 0) 2276 EMSG2(_(e_invarg2), name - 1); 2277 else 2278 { 2279 if (op != NULL && (*op == '+' || *op == '-')) 2280 EMSG2(_(e_letwrong), op); 2281 else if (endchars != NULL 2282 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2283 EMSG(_(e_letunexp)); 2284 else 2285 { 2286 c1 = name[len]; 2287 name[len] = NUL; 2288 p = get_tv_string_chk(tv); 2289 if (p != NULL && op != NULL && *op == '.') 2290 { 2291 int mustfree = FALSE; 2292 char_u *s = vim_getenv(name, &mustfree); 2293 2294 if (s != NULL) 2295 { 2296 p = tofree = concat_str(s, p); 2297 if (mustfree) 2298 vim_free(s); 2299 } 2300 } 2301 if (p != NULL) 2302 { 2303 vim_setenv(name, p); 2304 if (STRICMP(name, "HOME") == 0) 2305 init_homedir(); 2306 else if (didset_vim && STRICMP(name, "VIM") == 0) 2307 didset_vim = FALSE; 2308 else if (didset_vimruntime 2309 && STRICMP(name, "VIMRUNTIME") == 0) 2310 didset_vimruntime = FALSE; 2311 arg_end = arg; 2312 } 2313 name[len] = c1; 2314 vim_free(tofree); 2315 } 2316 } 2317 } 2318 2319 /* 2320 * ":let &option = expr": Set option value. 2321 * ":let &l:option = expr": Set local option value. 2322 * ":let &g:option = expr": Set global option value. 2323 */ 2324 else if (*arg == '&') 2325 { 2326 /* Find the end of the name. */ 2327 p = find_option_end(&arg, &opt_flags); 2328 if (p == NULL || (endchars != NULL 2329 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2330 EMSG(_(e_letunexp)); 2331 else 2332 { 2333 long n; 2334 int opt_type; 2335 long numval; 2336 char_u *stringval = NULL; 2337 char_u *s; 2338 2339 c1 = *p; 2340 *p = NUL; 2341 2342 n = get_tv_number(tv); 2343 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2344 if (s != NULL && op != NULL && *op != '=') 2345 { 2346 opt_type = get_option_value(arg, &numval, 2347 &stringval, opt_flags); 2348 if ((opt_type == 1 && *op == '.') 2349 || (opt_type == 0 && *op != '.')) 2350 EMSG2(_(e_letwrong), op); 2351 else 2352 { 2353 if (opt_type == 1) /* number */ 2354 { 2355 if (*op == '+') 2356 n = numval + n; 2357 else 2358 n = numval - n; 2359 } 2360 else if (opt_type == 0 && stringval != NULL) /* string */ 2361 { 2362 s = concat_str(stringval, s); 2363 vim_free(stringval); 2364 stringval = s; 2365 } 2366 } 2367 } 2368 if (s != NULL) 2369 { 2370 set_option_value(arg, n, s, opt_flags); 2371 arg_end = p; 2372 } 2373 *p = c1; 2374 vim_free(stringval); 2375 } 2376 } 2377 2378 /* 2379 * ":let @r = expr": Set register contents. 2380 */ 2381 else if (*arg == '@') 2382 { 2383 ++arg; 2384 if (op != NULL && (*op == '+' || *op == '-')) 2385 EMSG2(_(e_letwrong), op); 2386 else if (endchars != NULL 2387 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2388 EMSG(_(e_letunexp)); 2389 else 2390 { 2391 char_u *ptofree = NULL; 2392 char_u *s; 2393 2394 p = get_tv_string_chk(tv); 2395 if (p != NULL && op != NULL && *op == '.') 2396 { 2397 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2398 if (s != NULL) 2399 { 2400 p = ptofree = concat_str(s, p); 2401 vim_free(s); 2402 } 2403 } 2404 if (p != NULL) 2405 { 2406 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2407 arg_end = arg + 1; 2408 } 2409 vim_free(ptofree); 2410 } 2411 } 2412 2413 /* 2414 * ":let var = expr": Set internal variable. 2415 * ":let {expr} = expr": Idem, name made with curly braces 2416 */ 2417 else if (eval_isnamec1(*arg) || *arg == '{') 2418 { 2419 lval_T lv; 2420 2421 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2422 if (p != NULL && lv.ll_name != NULL) 2423 { 2424 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2425 EMSG(_(e_letunexp)); 2426 else 2427 { 2428 set_var_lval(&lv, p, tv, copy, op); 2429 arg_end = p; 2430 } 2431 } 2432 clear_lval(&lv); 2433 } 2434 2435 else 2436 EMSG2(_(e_invarg2), arg); 2437 2438 return arg_end; 2439 } 2440 2441 /* 2442 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2443 */ 2444 static int 2445 check_changedtick(arg) 2446 char_u *arg; 2447 { 2448 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2449 { 2450 EMSG2(_(e_readonlyvar), arg); 2451 return TRUE; 2452 } 2453 return FALSE; 2454 } 2455 2456 /* 2457 * Get an lval: variable, Dict item or List item that can be assigned a value 2458 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2459 * "name.key", "name.key[expr]" etc. 2460 * Indexing only works if "name" is an existing List or Dictionary. 2461 * "name" points to the start of the name. 2462 * If "rettv" is not NULL it points to the value to be assigned. 2463 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2464 * wrong; must end in space or cmd separator. 2465 * 2466 * Returns a pointer to just after the name, including indexes. 2467 * When an evaluation error occurs "lp->ll_name" is NULL; 2468 * Returns NULL for a parsing error. Still need to free items in "lp"! 2469 */ 2470 static char_u * 2471 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2472 char_u *name; 2473 typval_T *rettv; 2474 lval_T *lp; 2475 int unlet; 2476 int skip; 2477 int quiet; /* don't give error messages */ 2478 int fne_flags; /* flags for find_name_end() */ 2479 { 2480 char_u *p; 2481 char_u *expr_start, *expr_end; 2482 int cc; 2483 dictitem_T *v; 2484 typval_T var1; 2485 typval_T var2; 2486 int empty1 = FALSE; 2487 listitem_T *ni; 2488 char_u *key = NULL; 2489 int len; 2490 hashtab_T *ht; 2491 2492 /* Clear everything in "lp". */ 2493 vim_memset(lp, 0, sizeof(lval_T)); 2494 2495 if (skip) 2496 { 2497 /* When skipping just find the end of the name. */ 2498 lp->ll_name = name; 2499 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2500 } 2501 2502 /* Find the end of the name. */ 2503 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2504 if (expr_start != NULL) 2505 { 2506 /* Don't expand the name when we already know there is an error. */ 2507 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2508 && *p != '[' && *p != '.') 2509 { 2510 EMSG(_(e_trailing)); 2511 return NULL; 2512 } 2513 2514 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2515 if (lp->ll_exp_name == NULL) 2516 { 2517 /* Report an invalid expression in braces, unless the 2518 * expression evaluation has been cancelled due to an 2519 * aborting error, an interrupt, or an exception. */ 2520 if (!aborting() && !quiet) 2521 { 2522 emsg_severe = TRUE; 2523 EMSG2(_(e_invarg2), name); 2524 return NULL; 2525 } 2526 } 2527 lp->ll_name = lp->ll_exp_name; 2528 } 2529 else 2530 lp->ll_name = name; 2531 2532 /* Without [idx] or .key we are done. */ 2533 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2534 return p; 2535 2536 cc = *p; 2537 *p = NUL; 2538 v = find_var(lp->ll_name, &ht); 2539 if (v == NULL && !quiet) 2540 EMSG2(_(e_undefvar), lp->ll_name); 2541 *p = cc; 2542 if (v == NULL) 2543 return NULL; 2544 2545 /* 2546 * Loop until no more [idx] or .key is following. 2547 */ 2548 lp->ll_tv = &v->di_tv; 2549 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2550 { 2551 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2552 && !(lp->ll_tv->v_type == VAR_DICT 2553 && lp->ll_tv->vval.v_dict != NULL)) 2554 { 2555 if (!quiet) 2556 EMSG(_("E689: Can only index a List or Dictionary")); 2557 return NULL; 2558 } 2559 if (lp->ll_range) 2560 { 2561 if (!quiet) 2562 EMSG(_("E708: [:] must come last")); 2563 return NULL; 2564 } 2565 2566 len = -1; 2567 if (*p == '.') 2568 { 2569 key = p + 1; 2570 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2571 ; 2572 if (len == 0) 2573 { 2574 if (!quiet) 2575 EMSG(_(e_emptykey)); 2576 return NULL; 2577 } 2578 p = key + len; 2579 } 2580 else 2581 { 2582 /* Get the index [expr] or the first index [expr: ]. */ 2583 p = skipwhite(p + 1); 2584 if (*p == ':') 2585 empty1 = TRUE; 2586 else 2587 { 2588 empty1 = FALSE; 2589 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2590 return NULL; 2591 if (get_tv_string_chk(&var1) == NULL) 2592 { 2593 /* not a number or string */ 2594 clear_tv(&var1); 2595 return NULL; 2596 } 2597 } 2598 2599 /* Optionally get the second index [ :expr]. */ 2600 if (*p == ':') 2601 { 2602 if (lp->ll_tv->v_type == VAR_DICT) 2603 { 2604 if (!quiet) 2605 EMSG(_(e_dictrange)); 2606 if (!empty1) 2607 clear_tv(&var1); 2608 return NULL; 2609 } 2610 if (rettv != NULL && (rettv->v_type != VAR_LIST 2611 || rettv->vval.v_list == NULL)) 2612 { 2613 if (!quiet) 2614 EMSG(_("E709: [:] requires a List value")); 2615 if (!empty1) 2616 clear_tv(&var1); 2617 return NULL; 2618 } 2619 p = skipwhite(p + 1); 2620 if (*p == ']') 2621 lp->ll_empty2 = TRUE; 2622 else 2623 { 2624 lp->ll_empty2 = FALSE; 2625 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2626 { 2627 if (!empty1) 2628 clear_tv(&var1); 2629 return NULL; 2630 } 2631 if (get_tv_string_chk(&var2) == NULL) 2632 { 2633 /* not a number or string */ 2634 if (!empty1) 2635 clear_tv(&var1); 2636 clear_tv(&var2); 2637 return NULL; 2638 } 2639 } 2640 lp->ll_range = TRUE; 2641 } 2642 else 2643 lp->ll_range = FALSE; 2644 2645 if (*p != ']') 2646 { 2647 if (!quiet) 2648 EMSG(_(e_missbrac)); 2649 if (!empty1) 2650 clear_tv(&var1); 2651 if (lp->ll_range && !lp->ll_empty2) 2652 clear_tv(&var2); 2653 return NULL; 2654 } 2655 2656 /* Skip to past ']'. */ 2657 ++p; 2658 } 2659 2660 if (lp->ll_tv->v_type == VAR_DICT) 2661 { 2662 if (len == -1) 2663 { 2664 /* "[key]": get key from "var1" */ 2665 key = get_tv_string(&var1); /* is number or string */ 2666 if (*key == NUL) 2667 { 2668 if (!quiet) 2669 EMSG(_(e_emptykey)); 2670 clear_tv(&var1); 2671 return NULL; 2672 } 2673 } 2674 lp->ll_list = NULL; 2675 lp->ll_dict = lp->ll_tv->vval.v_dict; 2676 lp->ll_di = dict_find(lp->ll_dict, key, len); 2677 if (lp->ll_di == NULL) 2678 { 2679 /* Key does not exist in dict: may need to add it. */ 2680 if (*p == '[' || *p == '.' || unlet) 2681 { 2682 if (!quiet) 2683 EMSG2(_(e_dictkey), key); 2684 if (len == -1) 2685 clear_tv(&var1); 2686 return NULL; 2687 } 2688 if (len == -1) 2689 lp->ll_newkey = vim_strsave(key); 2690 else 2691 lp->ll_newkey = vim_strnsave(key, len); 2692 if (len == -1) 2693 clear_tv(&var1); 2694 if (lp->ll_newkey == NULL) 2695 p = NULL; 2696 break; 2697 } 2698 if (len == -1) 2699 clear_tv(&var1); 2700 lp->ll_tv = &lp->ll_di->di_tv; 2701 } 2702 else 2703 { 2704 /* 2705 * Get the number and item for the only or first index of the List. 2706 */ 2707 if (empty1) 2708 lp->ll_n1 = 0; 2709 else 2710 { 2711 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2712 clear_tv(&var1); 2713 } 2714 lp->ll_dict = NULL; 2715 lp->ll_list = lp->ll_tv->vval.v_list; 2716 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2717 if (lp->ll_li == NULL) 2718 { 2719 if (lp->ll_n1 < 0) 2720 { 2721 lp->ll_n1 = 0; 2722 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2723 } 2724 } 2725 if (lp->ll_li == NULL) 2726 { 2727 if (lp->ll_range && !lp->ll_empty2) 2728 clear_tv(&var2); 2729 return NULL; 2730 } 2731 2732 /* 2733 * May need to find the item or absolute index for the second 2734 * index of a range. 2735 * When no index given: "lp->ll_empty2" is TRUE. 2736 * Otherwise "lp->ll_n2" is set to the second index. 2737 */ 2738 if (lp->ll_range && !lp->ll_empty2) 2739 { 2740 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2741 clear_tv(&var2); 2742 if (lp->ll_n2 < 0) 2743 { 2744 ni = list_find(lp->ll_list, lp->ll_n2); 2745 if (ni == NULL) 2746 return NULL; 2747 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2748 } 2749 2750 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2751 if (lp->ll_n1 < 0) 2752 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2753 if (lp->ll_n2 < lp->ll_n1) 2754 return NULL; 2755 } 2756 2757 lp->ll_tv = &lp->ll_li->li_tv; 2758 } 2759 } 2760 2761 return p; 2762 } 2763 2764 /* 2765 * Clear lval "lp" that was filled by get_lval(). 2766 */ 2767 static void 2768 clear_lval(lp) 2769 lval_T *lp; 2770 { 2771 vim_free(lp->ll_exp_name); 2772 vim_free(lp->ll_newkey); 2773 } 2774 2775 /* 2776 * Set a variable that was parsed by get_lval() to "rettv". 2777 * "endp" points to just after the parsed name. 2778 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2779 */ 2780 static void 2781 set_var_lval(lp, endp, rettv, copy, op) 2782 lval_T *lp; 2783 char_u *endp; 2784 typval_T *rettv; 2785 int copy; 2786 char_u *op; 2787 { 2788 int cc; 2789 listitem_T *ri; 2790 dictitem_T *di; 2791 2792 if (lp->ll_tv == NULL) 2793 { 2794 if (!check_changedtick(lp->ll_name)) 2795 { 2796 cc = *endp; 2797 *endp = NUL; 2798 if (op != NULL && *op != '=') 2799 { 2800 typval_T tv; 2801 2802 /* handle +=, -= and .= */ 2803 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2804 &tv, TRUE) == OK) 2805 { 2806 if (tv_op(&tv, rettv, op) == OK) 2807 set_var(lp->ll_name, &tv, FALSE); 2808 clear_tv(&tv); 2809 } 2810 } 2811 else 2812 set_var(lp->ll_name, rettv, copy); 2813 *endp = cc; 2814 } 2815 } 2816 else if (tv_check_lock(lp->ll_newkey == NULL 2817 ? lp->ll_tv->v_lock 2818 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2819 ; 2820 else if (lp->ll_range) 2821 { 2822 /* 2823 * Assign the List values to the list items. 2824 */ 2825 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2826 { 2827 if (op != NULL && *op != '=') 2828 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2829 else 2830 { 2831 clear_tv(&lp->ll_li->li_tv); 2832 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2833 } 2834 ri = ri->li_next; 2835 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2836 break; 2837 if (lp->ll_li->li_next == NULL) 2838 { 2839 /* Need to add an empty item. */ 2840 if (list_append_number(lp->ll_list, 0) == FAIL) 2841 { 2842 ri = NULL; 2843 break; 2844 } 2845 } 2846 lp->ll_li = lp->ll_li->li_next; 2847 ++lp->ll_n1; 2848 } 2849 if (ri != NULL) 2850 EMSG(_("E710: List value has more items than target")); 2851 else if (lp->ll_empty2 2852 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2853 : lp->ll_n1 != lp->ll_n2) 2854 EMSG(_("E711: List value has not enough items")); 2855 } 2856 else 2857 { 2858 /* 2859 * Assign to a List or Dictionary item. 2860 */ 2861 if (lp->ll_newkey != NULL) 2862 { 2863 if (op != NULL && *op != '=') 2864 { 2865 EMSG2(_(e_letwrong), op); 2866 return; 2867 } 2868 2869 /* Need to add an item to the Dictionary. */ 2870 di = dictitem_alloc(lp->ll_newkey); 2871 if (di == NULL) 2872 return; 2873 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2874 { 2875 vim_free(di); 2876 return; 2877 } 2878 lp->ll_tv = &di->di_tv; 2879 } 2880 else if (op != NULL && *op != '=') 2881 { 2882 tv_op(lp->ll_tv, rettv, op); 2883 return; 2884 } 2885 else 2886 clear_tv(lp->ll_tv); 2887 2888 /* 2889 * Assign the value to the variable or list item. 2890 */ 2891 if (copy) 2892 copy_tv(rettv, lp->ll_tv); 2893 else 2894 { 2895 *lp->ll_tv = *rettv; 2896 lp->ll_tv->v_lock = 0; 2897 init_tv(rettv); 2898 } 2899 } 2900 } 2901 2902 /* 2903 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2904 * Returns OK or FAIL. 2905 */ 2906 static int 2907 tv_op(tv1, tv2, op) 2908 typval_T *tv1; 2909 typval_T *tv2; 2910 char_u *op; 2911 { 2912 long n; 2913 char_u numbuf[NUMBUFLEN]; 2914 char_u *s; 2915 2916 /* Can't do anything with a Funcref or a Dict on the right. */ 2917 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2918 { 2919 switch (tv1->v_type) 2920 { 2921 case VAR_DICT: 2922 case VAR_FUNC: 2923 break; 2924 2925 case VAR_LIST: 2926 if (*op != '+' || tv2->v_type != VAR_LIST) 2927 break; 2928 /* List += List */ 2929 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2930 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2931 return OK; 2932 2933 case VAR_NUMBER: 2934 case VAR_STRING: 2935 if (tv2->v_type == VAR_LIST) 2936 break; 2937 if (*op == '+' || *op == '-') 2938 { 2939 /* nr += nr or nr -= nr*/ 2940 n = get_tv_number(tv1); 2941 #ifdef FEAT_FLOAT 2942 if (tv2->v_type == VAR_FLOAT) 2943 { 2944 float_T f = n; 2945 2946 if (*op == '+') 2947 f += tv2->vval.v_float; 2948 else 2949 f -= tv2->vval.v_float; 2950 clear_tv(tv1); 2951 tv1->v_type = VAR_FLOAT; 2952 tv1->vval.v_float = f; 2953 } 2954 else 2955 #endif 2956 { 2957 if (*op == '+') 2958 n += get_tv_number(tv2); 2959 else 2960 n -= get_tv_number(tv2); 2961 clear_tv(tv1); 2962 tv1->v_type = VAR_NUMBER; 2963 tv1->vval.v_number = n; 2964 } 2965 } 2966 else 2967 { 2968 if (tv2->v_type == VAR_FLOAT) 2969 break; 2970 2971 /* str .= str */ 2972 s = get_tv_string(tv1); 2973 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2974 clear_tv(tv1); 2975 tv1->v_type = VAR_STRING; 2976 tv1->vval.v_string = s; 2977 } 2978 return OK; 2979 2980 #ifdef FEAT_FLOAT 2981 case VAR_FLOAT: 2982 { 2983 float_T f; 2984 2985 if (*op == '.' || (tv2->v_type != VAR_FLOAT 2986 && tv2->v_type != VAR_NUMBER 2987 && tv2->v_type != VAR_STRING)) 2988 break; 2989 if (tv2->v_type == VAR_FLOAT) 2990 f = tv2->vval.v_float; 2991 else 2992 f = get_tv_number(tv2); 2993 if (*op == '+') 2994 tv1->vval.v_float += f; 2995 else 2996 tv1->vval.v_float -= f; 2997 } 2998 return OK; 2999 #endif 3000 } 3001 } 3002 3003 EMSG2(_(e_letwrong), op); 3004 return FAIL; 3005 } 3006 3007 /* 3008 * Add a watcher to a list. 3009 */ 3010 static void 3011 list_add_watch(l, lw) 3012 list_T *l; 3013 listwatch_T *lw; 3014 { 3015 lw->lw_next = l->lv_watch; 3016 l->lv_watch = lw; 3017 } 3018 3019 /* 3020 * Remove a watcher from a list. 3021 * No warning when it isn't found... 3022 */ 3023 static void 3024 list_rem_watch(l, lwrem) 3025 list_T *l; 3026 listwatch_T *lwrem; 3027 { 3028 listwatch_T *lw, **lwp; 3029 3030 lwp = &l->lv_watch; 3031 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3032 { 3033 if (lw == lwrem) 3034 { 3035 *lwp = lw->lw_next; 3036 break; 3037 } 3038 lwp = &lw->lw_next; 3039 } 3040 } 3041 3042 /* 3043 * Just before removing an item from a list: advance watchers to the next 3044 * item. 3045 */ 3046 static void 3047 list_fix_watch(l, item) 3048 list_T *l; 3049 listitem_T *item; 3050 { 3051 listwatch_T *lw; 3052 3053 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3054 if (lw->lw_item == item) 3055 lw->lw_item = item->li_next; 3056 } 3057 3058 /* 3059 * Evaluate the expression used in a ":for var in expr" command. 3060 * "arg" points to "var". 3061 * Set "*errp" to TRUE for an error, FALSE otherwise; 3062 * Return a pointer that holds the info. Null when there is an error. 3063 */ 3064 void * 3065 eval_for_line(arg, errp, nextcmdp, skip) 3066 char_u *arg; 3067 int *errp; 3068 char_u **nextcmdp; 3069 int skip; 3070 { 3071 forinfo_T *fi; 3072 char_u *expr; 3073 typval_T tv; 3074 list_T *l; 3075 3076 *errp = TRUE; /* default: there is an error */ 3077 3078 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 3079 if (fi == NULL) 3080 return NULL; 3081 3082 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 3083 if (expr == NULL) 3084 return fi; 3085 3086 expr = skipwhite(expr); 3087 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 3088 { 3089 EMSG(_("E690: Missing \"in\" after :for")); 3090 return fi; 3091 } 3092 3093 if (skip) 3094 ++emsg_skip; 3095 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 3096 { 3097 *errp = FALSE; 3098 if (!skip) 3099 { 3100 l = tv.vval.v_list; 3101 if (tv.v_type != VAR_LIST || l == NULL) 3102 { 3103 EMSG(_(e_listreq)); 3104 clear_tv(&tv); 3105 } 3106 else 3107 { 3108 /* No need to increment the refcount, it's already set for the 3109 * list being used in "tv". */ 3110 fi->fi_list = l; 3111 list_add_watch(l, &fi->fi_lw); 3112 fi->fi_lw.lw_item = l->lv_first; 3113 } 3114 } 3115 } 3116 if (skip) 3117 --emsg_skip; 3118 3119 return fi; 3120 } 3121 3122 /* 3123 * Use the first item in a ":for" list. Advance to the next. 3124 * Assign the values to the variable (list). "arg" points to the first one. 3125 * Return TRUE when a valid item was found, FALSE when at end of list or 3126 * something wrong. 3127 */ 3128 int 3129 next_for_item(fi_void, arg) 3130 void *fi_void; 3131 char_u *arg; 3132 { 3133 forinfo_T *fi = (forinfo_T *)fi_void; 3134 int result; 3135 listitem_T *item; 3136 3137 item = fi->fi_lw.lw_item; 3138 if (item == NULL) 3139 result = FALSE; 3140 else 3141 { 3142 fi->fi_lw.lw_item = item->li_next; 3143 result = (ex_let_vars(arg, &item->li_tv, TRUE, 3144 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 3145 } 3146 return result; 3147 } 3148 3149 /* 3150 * Free the structure used to store info used by ":for". 3151 */ 3152 void 3153 free_for_info(fi_void) 3154 void *fi_void; 3155 { 3156 forinfo_T *fi = (forinfo_T *)fi_void; 3157 3158 if (fi != NULL && fi->fi_list != NULL) 3159 { 3160 list_rem_watch(fi->fi_list, &fi->fi_lw); 3161 list_unref(fi->fi_list); 3162 } 3163 vim_free(fi); 3164 } 3165 3166 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3167 3168 void 3169 set_context_for_expression(xp, arg, cmdidx) 3170 expand_T *xp; 3171 char_u *arg; 3172 cmdidx_T cmdidx; 3173 { 3174 int got_eq = FALSE; 3175 int c; 3176 char_u *p; 3177 3178 if (cmdidx == CMD_let) 3179 { 3180 xp->xp_context = EXPAND_USER_VARS; 3181 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3182 { 3183 /* ":let var1 var2 ...": find last space. */ 3184 for (p = arg + STRLEN(arg); p >= arg; ) 3185 { 3186 xp->xp_pattern = p; 3187 mb_ptr_back(arg, p); 3188 if (vim_iswhite(*p)) 3189 break; 3190 } 3191 return; 3192 } 3193 } 3194 else 3195 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3196 : EXPAND_EXPRESSION; 3197 while ((xp->xp_pattern = vim_strpbrk(arg, 3198 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3199 { 3200 c = *xp->xp_pattern; 3201 if (c == '&') 3202 { 3203 c = xp->xp_pattern[1]; 3204 if (c == '&') 3205 { 3206 ++xp->xp_pattern; 3207 xp->xp_context = cmdidx != CMD_let || got_eq 3208 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3209 } 3210 else if (c != ' ') 3211 { 3212 xp->xp_context = EXPAND_SETTINGS; 3213 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3214 xp->xp_pattern += 2; 3215 3216 } 3217 } 3218 else if (c == '$') 3219 { 3220 /* environment variable */ 3221 xp->xp_context = EXPAND_ENV_VARS; 3222 } 3223 else if (c == '=') 3224 { 3225 got_eq = TRUE; 3226 xp->xp_context = EXPAND_EXPRESSION; 3227 } 3228 else if (c == '<' 3229 && xp->xp_context == EXPAND_FUNCTIONS 3230 && vim_strchr(xp->xp_pattern, '(') == NULL) 3231 { 3232 /* Function name can start with "<SNR>" */ 3233 break; 3234 } 3235 else if (cmdidx != CMD_let || got_eq) 3236 { 3237 if (c == '"') /* string */ 3238 { 3239 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3240 if (c == '\\' && xp->xp_pattern[1] != NUL) 3241 ++xp->xp_pattern; 3242 xp->xp_context = EXPAND_NOTHING; 3243 } 3244 else if (c == '\'') /* literal string */ 3245 { 3246 /* Trick: '' is like stopping and starting a literal string. */ 3247 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3248 /* skip */ ; 3249 xp->xp_context = EXPAND_NOTHING; 3250 } 3251 else if (c == '|') 3252 { 3253 if (xp->xp_pattern[1] == '|') 3254 { 3255 ++xp->xp_pattern; 3256 xp->xp_context = EXPAND_EXPRESSION; 3257 } 3258 else 3259 xp->xp_context = EXPAND_COMMANDS; 3260 } 3261 else 3262 xp->xp_context = EXPAND_EXPRESSION; 3263 } 3264 else 3265 /* Doesn't look like something valid, expand as an expression 3266 * anyway. */ 3267 xp->xp_context = EXPAND_EXPRESSION; 3268 arg = xp->xp_pattern; 3269 if (*arg != NUL) 3270 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3271 /* skip */ ; 3272 } 3273 xp->xp_pattern = arg; 3274 } 3275 3276 #endif /* FEAT_CMDL_COMPL */ 3277 3278 /* 3279 * ":1,25call func(arg1, arg2)" function call. 3280 */ 3281 void 3282 ex_call(eap) 3283 exarg_T *eap; 3284 { 3285 char_u *arg = eap->arg; 3286 char_u *startarg; 3287 char_u *name; 3288 char_u *tofree; 3289 int len; 3290 typval_T rettv; 3291 linenr_T lnum; 3292 int doesrange; 3293 int failed = FALSE; 3294 funcdict_T fudi; 3295 3296 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3297 if (fudi.fd_newkey != NULL) 3298 { 3299 /* Still need to give an error message for missing key. */ 3300 EMSG2(_(e_dictkey), fudi.fd_newkey); 3301 vim_free(fudi.fd_newkey); 3302 } 3303 if (tofree == NULL) 3304 return; 3305 3306 /* Increase refcount on dictionary, it could get deleted when evaluating 3307 * the arguments. */ 3308 if (fudi.fd_dict != NULL) 3309 ++fudi.fd_dict->dv_refcount; 3310 3311 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3312 len = (int)STRLEN(tofree); 3313 name = deref_func_name(tofree, &len); 3314 3315 /* Skip white space to allow ":call func ()". Not good, but required for 3316 * backward compatibility. */ 3317 startarg = skipwhite(arg); 3318 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3319 3320 if (*startarg != '(') 3321 { 3322 EMSG2(_("E107: Missing parentheses: %s"), eap->arg); 3323 goto end; 3324 } 3325 3326 /* 3327 * When skipping, evaluate the function once, to find the end of the 3328 * arguments. 3329 * When the function takes a range, this is discovered after the first 3330 * call, and the loop is broken. 3331 */ 3332 if (eap->skip) 3333 { 3334 ++emsg_skip; 3335 lnum = eap->line2; /* do it once, also with an invalid range */ 3336 } 3337 else 3338 lnum = eap->line1; 3339 for ( ; lnum <= eap->line2; ++lnum) 3340 { 3341 if (!eap->skip && eap->addr_count > 0) 3342 { 3343 curwin->w_cursor.lnum = lnum; 3344 curwin->w_cursor.col = 0; 3345 } 3346 arg = startarg; 3347 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3348 eap->line1, eap->line2, &doesrange, 3349 !eap->skip, fudi.fd_dict) == FAIL) 3350 { 3351 failed = TRUE; 3352 break; 3353 } 3354 3355 /* Handle a function returning a Funcref, Dictionary or List. */ 3356 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) 3357 { 3358 failed = TRUE; 3359 break; 3360 } 3361 3362 clear_tv(&rettv); 3363 if (doesrange || eap->skip) 3364 break; 3365 3366 /* Stop when immediately aborting on error, or when an interrupt 3367 * occurred or an exception was thrown but not caught. 3368 * get_func_tv() returned OK, so that the check for trailing 3369 * characters below is executed. */ 3370 if (aborting()) 3371 break; 3372 } 3373 if (eap->skip) 3374 --emsg_skip; 3375 3376 if (!failed) 3377 { 3378 /* Check for trailing illegal characters and a following command. */ 3379 if (!ends_excmd(*arg)) 3380 { 3381 emsg_severe = TRUE; 3382 EMSG(_(e_trailing)); 3383 } 3384 else 3385 eap->nextcmd = check_nextcmd(arg); 3386 } 3387 3388 end: 3389 dict_unref(fudi.fd_dict); 3390 vim_free(tofree); 3391 } 3392 3393 /* 3394 * ":unlet[!] var1 ... " command. 3395 */ 3396 void 3397 ex_unlet(eap) 3398 exarg_T *eap; 3399 { 3400 ex_unletlock(eap, eap->arg, 0); 3401 } 3402 3403 /* 3404 * ":lockvar" and ":unlockvar" commands 3405 */ 3406 void 3407 ex_lockvar(eap) 3408 exarg_T *eap; 3409 { 3410 char_u *arg = eap->arg; 3411 int deep = 2; 3412 3413 if (eap->forceit) 3414 deep = -1; 3415 else if (vim_isdigit(*arg)) 3416 { 3417 deep = getdigits(&arg); 3418 arg = skipwhite(arg); 3419 } 3420 3421 ex_unletlock(eap, arg, deep); 3422 } 3423 3424 /* 3425 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3426 */ 3427 static void 3428 ex_unletlock(eap, argstart, deep) 3429 exarg_T *eap; 3430 char_u *argstart; 3431 int deep; 3432 { 3433 char_u *arg = argstart; 3434 char_u *name_end; 3435 int error = FALSE; 3436 lval_T lv; 3437 3438 do 3439 { 3440 /* Parse the name and find the end. */ 3441 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3442 FNE_CHECK_START); 3443 if (lv.ll_name == NULL) 3444 error = TRUE; /* error but continue parsing */ 3445 if (name_end == NULL || (!vim_iswhite(*name_end) 3446 && !ends_excmd(*name_end))) 3447 { 3448 if (name_end != NULL) 3449 { 3450 emsg_severe = TRUE; 3451 EMSG(_(e_trailing)); 3452 } 3453 if (!(eap->skip || error)) 3454 clear_lval(&lv); 3455 break; 3456 } 3457 3458 if (!error && !eap->skip) 3459 { 3460 if (eap->cmdidx == CMD_unlet) 3461 { 3462 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3463 error = TRUE; 3464 } 3465 else 3466 { 3467 if (do_lock_var(&lv, name_end, deep, 3468 eap->cmdidx == CMD_lockvar) == FAIL) 3469 error = TRUE; 3470 } 3471 } 3472 3473 if (!eap->skip) 3474 clear_lval(&lv); 3475 3476 arg = skipwhite(name_end); 3477 } while (!ends_excmd(*arg)); 3478 3479 eap->nextcmd = check_nextcmd(arg); 3480 } 3481 3482 static int 3483 do_unlet_var(lp, name_end, forceit) 3484 lval_T *lp; 3485 char_u *name_end; 3486 int forceit; 3487 { 3488 int ret = OK; 3489 int cc; 3490 3491 if (lp->ll_tv == NULL) 3492 { 3493 cc = *name_end; 3494 *name_end = NUL; 3495 3496 /* Normal name or expanded name. */ 3497 if (check_changedtick(lp->ll_name)) 3498 ret = FAIL; 3499 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3500 ret = FAIL; 3501 *name_end = cc; 3502 } 3503 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3504 return FAIL; 3505 else if (lp->ll_range) 3506 { 3507 listitem_T *li; 3508 3509 /* Delete a range of List items. */ 3510 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3511 { 3512 li = lp->ll_li->li_next; 3513 listitem_remove(lp->ll_list, lp->ll_li); 3514 lp->ll_li = li; 3515 ++lp->ll_n1; 3516 } 3517 } 3518 else 3519 { 3520 if (lp->ll_list != NULL) 3521 /* unlet a List item. */ 3522 listitem_remove(lp->ll_list, lp->ll_li); 3523 else 3524 /* unlet a Dictionary item. */ 3525 dictitem_remove(lp->ll_dict, lp->ll_di); 3526 } 3527 3528 return ret; 3529 } 3530 3531 /* 3532 * "unlet" a variable. Return OK if it existed, FAIL if not. 3533 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3534 */ 3535 int 3536 do_unlet(name, forceit) 3537 char_u *name; 3538 int forceit; 3539 { 3540 hashtab_T *ht; 3541 hashitem_T *hi; 3542 char_u *varname; 3543 dictitem_T *di; 3544 3545 ht = find_var_ht(name, &varname); 3546 if (ht != NULL && *varname != NUL) 3547 { 3548 hi = hash_find(ht, varname); 3549 if (!HASHITEM_EMPTY(hi)) 3550 { 3551 di = HI2DI(hi); 3552 if (var_check_fixed(di->di_flags, name) 3553 || var_check_ro(di->di_flags, name)) 3554 return FAIL; 3555 delete_var(ht, hi); 3556 return OK; 3557 } 3558 } 3559 if (forceit) 3560 return OK; 3561 EMSG2(_("E108: No such variable: \"%s\""), name); 3562 return FAIL; 3563 } 3564 3565 /* 3566 * Lock or unlock variable indicated by "lp". 3567 * "deep" is the levels to go (-1 for unlimited); 3568 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3569 */ 3570 static int 3571 do_lock_var(lp, name_end, deep, lock) 3572 lval_T *lp; 3573 char_u *name_end; 3574 int deep; 3575 int lock; 3576 { 3577 int ret = OK; 3578 int cc; 3579 dictitem_T *di; 3580 3581 if (deep == 0) /* nothing to do */ 3582 return OK; 3583 3584 if (lp->ll_tv == NULL) 3585 { 3586 cc = *name_end; 3587 *name_end = NUL; 3588 3589 /* Normal name or expanded name. */ 3590 if (check_changedtick(lp->ll_name)) 3591 ret = FAIL; 3592 else 3593 { 3594 di = find_var(lp->ll_name, NULL); 3595 if (di == NULL) 3596 ret = FAIL; 3597 else 3598 { 3599 if (lock) 3600 di->di_flags |= DI_FLAGS_LOCK; 3601 else 3602 di->di_flags &= ~DI_FLAGS_LOCK; 3603 item_lock(&di->di_tv, deep, lock); 3604 } 3605 } 3606 *name_end = cc; 3607 } 3608 else if (lp->ll_range) 3609 { 3610 listitem_T *li = lp->ll_li; 3611 3612 /* (un)lock a range of List items. */ 3613 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3614 { 3615 item_lock(&li->li_tv, deep, lock); 3616 li = li->li_next; 3617 ++lp->ll_n1; 3618 } 3619 } 3620 else if (lp->ll_list != NULL) 3621 /* (un)lock a List item. */ 3622 item_lock(&lp->ll_li->li_tv, deep, lock); 3623 else 3624 /* un(lock) a Dictionary item. */ 3625 item_lock(&lp->ll_di->di_tv, deep, lock); 3626 3627 return ret; 3628 } 3629 3630 /* 3631 * Lock or unlock an item. "deep" is nr of levels to go. 3632 */ 3633 static void 3634 item_lock(tv, deep, lock) 3635 typval_T *tv; 3636 int deep; 3637 int lock; 3638 { 3639 static int recurse = 0; 3640 list_T *l; 3641 listitem_T *li; 3642 dict_T *d; 3643 hashitem_T *hi; 3644 int todo; 3645 3646 if (recurse >= DICT_MAXNEST) 3647 { 3648 EMSG(_("E743: variable nested too deep for (un)lock")); 3649 return; 3650 } 3651 if (deep == 0) 3652 return; 3653 ++recurse; 3654 3655 /* lock/unlock the item itself */ 3656 if (lock) 3657 tv->v_lock |= VAR_LOCKED; 3658 else 3659 tv->v_lock &= ~VAR_LOCKED; 3660 3661 switch (tv->v_type) 3662 { 3663 case VAR_LIST: 3664 if ((l = tv->vval.v_list) != NULL) 3665 { 3666 if (lock) 3667 l->lv_lock |= VAR_LOCKED; 3668 else 3669 l->lv_lock &= ~VAR_LOCKED; 3670 if (deep < 0 || deep > 1) 3671 /* recursive: lock/unlock the items the List contains */ 3672 for (li = l->lv_first; li != NULL; li = li->li_next) 3673 item_lock(&li->li_tv, deep - 1, lock); 3674 } 3675 break; 3676 case VAR_DICT: 3677 if ((d = tv->vval.v_dict) != NULL) 3678 { 3679 if (lock) 3680 d->dv_lock |= VAR_LOCKED; 3681 else 3682 d->dv_lock &= ~VAR_LOCKED; 3683 if (deep < 0 || deep > 1) 3684 { 3685 /* recursive: lock/unlock the items the List contains */ 3686 todo = (int)d->dv_hashtab.ht_used; 3687 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3688 { 3689 if (!HASHITEM_EMPTY(hi)) 3690 { 3691 --todo; 3692 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3693 } 3694 } 3695 } 3696 } 3697 } 3698 --recurse; 3699 } 3700 3701 /* 3702 * Return TRUE if typeval "tv" is locked: Either that value is locked itself 3703 * or it refers to a List or Dictionary that is locked. 3704 */ 3705 static int 3706 tv_islocked(tv) 3707 typval_T *tv; 3708 { 3709 return (tv->v_lock & VAR_LOCKED) 3710 || (tv->v_type == VAR_LIST 3711 && tv->vval.v_list != NULL 3712 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3713 || (tv->v_type == VAR_DICT 3714 && tv->vval.v_dict != NULL 3715 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3716 } 3717 3718 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3719 /* 3720 * Delete all "menutrans_" variables. 3721 */ 3722 void 3723 del_menutrans_vars() 3724 { 3725 hashitem_T *hi; 3726 int todo; 3727 3728 hash_lock(&globvarht); 3729 todo = (int)globvarht.ht_used; 3730 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3731 { 3732 if (!HASHITEM_EMPTY(hi)) 3733 { 3734 --todo; 3735 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3736 delete_var(&globvarht, hi); 3737 } 3738 } 3739 hash_unlock(&globvarht); 3740 } 3741 #endif 3742 3743 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3744 3745 /* 3746 * Local string buffer for the next two functions to store a variable name 3747 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3748 * get_user_var_name(). 3749 */ 3750 3751 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3752 3753 static char_u *varnamebuf = NULL; 3754 static int varnamebuflen = 0; 3755 3756 /* 3757 * Function to concatenate a prefix and a variable name. 3758 */ 3759 static char_u * 3760 cat_prefix_varname(prefix, name) 3761 int prefix; 3762 char_u *name; 3763 { 3764 int len; 3765 3766 len = (int)STRLEN(name) + 3; 3767 if (len > varnamebuflen) 3768 { 3769 vim_free(varnamebuf); 3770 len += 10; /* some additional space */ 3771 varnamebuf = alloc(len); 3772 if (varnamebuf == NULL) 3773 { 3774 varnamebuflen = 0; 3775 return NULL; 3776 } 3777 varnamebuflen = len; 3778 } 3779 *varnamebuf = prefix; 3780 varnamebuf[1] = ':'; 3781 STRCPY(varnamebuf + 2, name); 3782 return varnamebuf; 3783 } 3784 3785 /* 3786 * Function given to ExpandGeneric() to obtain the list of user defined 3787 * (global/buffer/window/built-in) variable names. 3788 */ 3789 char_u * 3790 get_user_var_name(xp, idx) 3791 expand_T *xp; 3792 int idx; 3793 { 3794 static long_u gdone; 3795 static long_u bdone; 3796 static long_u wdone; 3797 #ifdef FEAT_WINDOWS 3798 static long_u tdone; 3799 #endif 3800 static int vidx; 3801 static hashitem_T *hi; 3802 hashtab_T *ht; 3803 3804 if (idx == 0) 3805 { 3806 gdone = bdone = wdone = vidx = 0; 3807 #ifdef FEAT_WINDOWS 3808 tdone = 0; 3809 #endif 3810 } 3811 3812 /* Global variables */ 3813 if (gdone < globvarht.ht_used) 3814 { 3815 if (gdone++ == 0) 3816 hi = globvarht.ht_array; 3817 else 3818 ++hi; 3819 while (HASHITEM_EMPTY(hi)) 3820 ++hi; 3821 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3822 return cat_prefix_varname('g', hi->hi_key); 3823 return hi->hi_key; 3824 } 3825 3826 /* b: variables */ 3827 ht = &curbuf->b_vars.dv_hashtab; 3828 if (bdone < ht->ht_used) 3829 { 3830 if (bdone++ == 0) 3831 hi = ht->ht_array; 3832 else 3833 ++hi; 3834 while (HASHITEM_EMPTY(hi)) 3835 ++hi; 3836 return cat_prefix_varname('b', hi->hi_key); 3837 } 3838 if (bdone == ht->ht_used) 3839 { 3840 ++bdone; 3841 return (char_u *)"b:changedtick"; 3842 } 3843 3844 /* w: variables */ 3845 ht = &curwin->w_vars.dv_hashtab; 3846 if (wdone < ht->ht_used) 3847 { 3848 if (wdone++ == 0) 3849 hi = ht->ht_array; 3850 else 3851 ++hi; 3852 while (HASHITEM_EMPTY(hi)) 3853 ++hi; 3854 return cat_prefix_varname('w', hi->hi_key); 3855 } 3856 3857 #ifdef FEAT_WINDOWS 3858 /* t: variables */ 3859 ht = &curtab->tp_vars.dv_hashtab; 3860 if (tdone < ht->ht_used) 3861 { 3862 if (tdone++ == 0) 3863 hi = ht->ht_array; 3864 else 3865 ++hi; 3866 while (HASHITEM_EMPTY(hi)) 3867 ++hi; 3868 return cat_prefix_varname('t', hi->hi_key); 3869 } 3870 #endif 3871 3872 /* v: variables */ 3873 if (vidx < VV_LEN) 3874 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3875 3876 vim_free(varnamebuf); 3877 varnamebuf = NULL; 3878 varnamebuflen = 0; 3879 return NULL; 3880 } 3881 3882 #endif /* FEAT_CMDL_COMPL */ 3883 3884 /* 3885 * types for expressions. 3886 */ 3887 typedef enum 3888 { 3889 TYPE_UNKNOWN = 0 3890 , TYPE_EQUAL /* == */ 3891 , TYPE_NEQUAL /* != */ 3892 , TYPE_GREATER /* > */ 3893 , TYPE_GEQUAL /* >= */ 3894 , TYPE_SMALLER /* < */ 3895 , TYPE_SEQUAL /* <= */ 3896 , TYPE_MATCH /* =~ */ 3897 , TYPE_NOMATCH /* !~ */ 3898 } exptype_T; 3899 3900 /* 3901 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3902 * executed. The function may return OK, but the rettv will be of type 3903 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3904 */ 3905 3906 /* 3907 * Handle zero level expression. 3908 * This calls eval1() and handles error message and nextcmd. 3909 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3910 * Note: "rettv.v_lock" is not set. 3911 * Return OK or FAIL. 3912 */ 3913 static int 3914 eval0(arg, rettv, nextcmd, evaluate) 3915 char_u *arg; 3916 typval_T *rettv; 3917 char_u **nextcmd; 3918 int evaluate; 3919 { 3920 int ret; 3921 char_u *p; 3922 3923 p = skipwhite(arg); 3924 ret = eval1(&p, rettv, evaluate); 3925 if (ret == FAIL || !ends_excmd(*p)) 3926 { 3927 if (ret != FAIL) 3928 clear_tv(rettv); 3929 /* 3930 * Report the invalid expression unless the expression evaluation has 3931 * been cancelled due to an aborting error, an interrupt, or an 3932 * exception. 3933 */ 3934 if (!aborting()) 3935 EMSG2(_(e_invexpr2), arg); 3936 ret = FAIL; 3937 } 3938 if (nextcmd != NULL) 3939 *nextcmd = check_nextcmd(p); 3940 3941 return ret; 3942 } 3943 3944 /* 3945 * Handle top level expression: 3946 * expr2 ? expr1 : expr1 3947 * 3948 * "arg" must point to the first non-white of the expression. 3949 * "arg" is advanced to the next non-white after the recognized expression. 3950 * 3951 * Note: "rettv.v_lock" is not set. 3952 * 3953 * Return OK or FAIL. 3954 */ 3955 static int 3956 eval1(arg, rettv, evaluate) 3957 char_u **arg; 3958 typval_T *rettv; 3959 int evaluate; 3960 { 3961 int result; 3962 typval_T var2; 3963 3964 /* 3965 * Get the first variable. 3966 */ 3967 if (eval2(arg, rettv, evaluate) == FAIL) 3968 return FAIL; 3969 3970 if ((*arg)[0] == '?') 3971 { 3972 result = FALSE; 3973 if (evaluate) 3974 { 3975 int error = FALSE; 3976 3977 if (get_tv_number_chk(rettv, &error) != 0) 3978 result = TRUE; 3979 clear_tv(rettv); 3980 if (error) 3981 return FAIL; 3982 } 3983 3984 /* 3985 * Get the second variable. 3986 */ 3987 *arg = skipwhite(*arg + 1); 3988 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3989 return FAIL; 3990 3991 /* 3992 * Check for the ":". 3993 */ 3994 if ((*arg)[0] != ':') 3995 { 3996 EMSG(_("E109: Missing ':' after '?'")); 3997 if (evaluate && result) 3998 clear_tv(rettv); 3999 return FAIL; 4000 } 4001 4002 /* 4003 * Get the third variable. 4004 */ 4005 *arg = skipwhite(*arg + 1); 4006 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 4007 { 4008 if (evaluate && result) 4009 clear_tv(rettv); 4010 return FAIL; 4011 } 4012 if (evaluate && !result) 4013 *rettv = var2; 4014 } 4015 4016 return OK; 4017 } 4018 4019 /* 4020 * Handle first level expression: 4021 * expr2 || expr2 || expr2 logical OR 4022 * 4023 * "arg" must point to the first non-white of the expression. 4024 * "arg" is advanced to the next non-white after the recognized expression. 4025 * 4026 * Return OK or FAIL. 4027 */ 4028 static int 4029 eval2(arg, rettv, evaluate) 4030 char_u **arg; 4031 typval_T *rettv; 4032 int evaluate; 4033 { 4034 typval_T var2; 4035 long result; 4036 int first; 4037 int error = FALSE; 4038 4039 /* 4040 * Get the first variable. 4041 */ 4042 if (eval3(arg, rettv, evaluate) == FAIL) 4043 return FAIL; 4044 4045 /* 4046 * Repeat until there is no following "||". 4047 */ 4048 first = TRUE; 4049 result = FALSE; 4050 while ((*arg)[0] == '|' && (*arg)[1] == '|') 4051 { 4052 if (evaluate && first) 4053 { 4054 if (get_tv_number_chk(rettv, &error) != 0) 4055 result = TRUE; 4056 clear_tv(rettv); 4057 if (error) 4058 return FAIL; 4059 first = FALSE; 4060 } 4061 4062 /* 4063 * Get the second variable. 4064 */ 4065 *arg = skipwhite(*arg + 2); 4066 if (eval3(arg, &var2, evaluate && !result) == FAIL) 4067 return FAIL; 4068 4069 /* 4070 * Compute the result. 4071 */ 4072 if (evaluate && !result) 4073 { 4074 if (get_tv_number_chk(&var2, &error) != 0) 4075 result = TRUE; 4076 clear_tv(&var2); 4077 if (error) 4078 return FAIL; 4079 } 4080 if (evaluate) 4081 { 4082 rettv->v_type = VAR_NUMBER; 4083 rettv->vval.v_number = result; 4084 } 4085 } 4086 4087 return OK; 4088 } 4089 4090 /* 4091 * Handle second level expression: 4092 * expr3 && expr3 && expr3 logical AND 4093 * 4094 * "arg" must point to the first non-white of the expression. 4095 * "arg" is advanced to the next non-white after the recognized expression. 4096 * 4097 * Return OK or FAIL. 4098 */ 4099 static int 4100 eval3(arg, rettv, evaluate) 4101 char_u **arg; 4102 typval_T *rettv; 4103 int evaluate; 4104 { 4105 typval_T var2; 4106 long result; 4107 int first; 4108 int error = FALSE; 4109 4110 /* 4111 * Get the first variable. 4112 */ 4113 if (eval4(arg, rettv, evaluate) == FAIL) 4114 return FAIL; 4115 4116 /* 4117 * Repeat until there is no following "&&". 4118 */ 4119 first = TRUE; 4120 result = TRUE; 4121 while ((*arg)[0] == '&' && (*arg)[1] == '&') 4122 { 4123 if (evaluate && first) 4124 { 4125 if (get_tv_number_chk(rettv, &error) == 0) 4126 result = FALSE; 4127 clear_tv(rettv); 4128 if (error) 4129 return FAIL; 4130 first = FALSE; 4131 } 4132 4133 /* 4134 * Get the second variable. 4135 */ 4136 *arg = skipwhite(*arg + 2); 4137 if (eval4(arg, &var2, evaluate && result) == FAIL) 4138 return FAIL; 4139 4140 /* 4141 * Compute the result. 4142 */ 4143 if (evaluate && result) 4144 { 4145 if (get_tv_number_chk(&var2, &error) == 0) 4146 result = FALSE; 4147 clear_tv(&var2); 4148 if (error) 4149 return FAIL; 4150 } 4151 if (evaluate) 4152 { 4153 rettv->v_type = VAR_NUMBER; 4154 rettv->vval.v_number = result; 4155 } 4156 } 4157 4158 return OK; 4159 } 4160 4161 /* 4162 * Handle third level expression: 4163 * var1 == var2 4164 * var1 =~ var2 4165 * var1 != var2 4166 * var1 !~ var2 4167 * var1 > var2 4168 * var1 >= var2 4169 * var1 < var2 4170 * var1 <= var2 4171 * var1 is var2 4172 * var1 isnot var2 4173 * 4174 * "arg" must point to the first non-white of the expression. 4175 * "arg" is advanced to the next non-white after the recognized expression. 4176 * 4177 * Return OK or FAIL. 4178 */ 4179 static int 4180 eval4(arg, rettv, evaluate) 4181 char_u **arg; 4182 typval_T *rettv; 4183 int evaluate; 4184 { 4185 typval_T var2; 4186 char_u *p; 4187 int i; 4188 exptype_T type = TYPE_UNKNOWN; 4189 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 4190 int len = 2; 4191 long n1, n2; 4192 char_u *s1, *s2; 4193 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4194 regmatch_T regmatch; 4195 int ic; 4196 char_u *save_cpo; 4197 4198 /* 4199 * Get the first variable. 4200 */ 4201 if (eval5(arg, rettv, evaluate) == FAIL) 4202 return FAIL; 4203 4204 p = *arg; 4205 switch (p[0]) 4206 { 4207 case '=': if (p[1] == '=') 4208 type = TYPE_EQUAL; 4209 else if (p[1] == '~') 4210 type = TYPE_MATCH; 4211 break; 4212 case '!': if (p[1] == '=') 4213 type = TYPE_NEQUAL; 4214 else if (p[1] == '~') 4215 type = TYPE_NOMATCH; 4216 break; 4217 case '>': if (p[1] != '=') 4218 { 4219 type = TYPE_GREATER; 4220 len = 1; 4221 } 4222 else 4223 type = TYPE_GEQUAL; 4224 break; 4225 case '<': if (p[1] != '=') 4226 { 4227 type = TYPE_SMALLER; 4228 len = 1; 4229 } 4230 else 4231 type = TYPE_SEQUAL; 4232 break; 4233 case 'i': if (p[1] == 's') 4234 { 4235 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4236 len = 5; 4237 if (!vim_isIDc(p[len])) 4238 { 4239 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4240 type_is = TRUE; 4241 } 4242 } 4243 break; 4244 } 4245 4246 /* 4247 * If there is a comparative operator, use it. 4248 */ 4249 if (type != TYPE_UNKNOWN) 4250 { 4251 /* extra question mark appended: ignore case */ 4252 if (p[len] == '?') 4253 { 4254 ic = TRUE; 4255 ++len; 4256 } 4257 /* extra '#' appended: match case */ 4258 else if (p[len] == '#') 4259 { 4260 ic = FALSE; 4261 ++len; 4262 } 4263 /* nothing appended: use 'ignorecase' */ 4264 else 4265 ic = p_ic; 4266 4267 /* 4268 * Get the second variable. 4269 */ 4270 *arg = skipwhite(p + len); 4271 if (eval5(arg, &var2, evaluate) == FAIL) 4272 { 4273 clear_tv(rettv); 4274 return FAIL; 4275 } 4276 4277 if (evaluate) 4278 { 4279 if (type_is && rettv->v_type != var2.v_type) 4280 { 4281 /* For "is" a different type always means FALSE, for "notis" 4282 * it means TRUE. */ 4283 n1 = (type == TYPE_NEQUAL); 4284 } 4285 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4286 { 4287 if (type_is) 4288 { 4289 n1 = (rettv->v_type == var2.v_type 4290 && rettv->vval.v_list == var2.vval.v_list); 4291 if (type == TYPE_NEQUAL) 4292 n1 = !n1; 4293 } 4294 else if (rettv->v_type != var2.v_type 4295 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4296 { 4297 if (rettv->v_type != var2.v_type) 4298 EMSG(_("E691: Can only compare List with List")); 4299 else 4300 EMSG(_("E692: Invalid operation for Lists")); 4301 clear_tv(rettv); 4302 clear_tv(&var2); 4303 return FAIL; 4304 } 4305 else 4306 { 4307 /* Compare two Lists for being equal or unequal. */ 4308 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 4309 if (type == TYPE_NEQUAL) 4310 n1 = !n1; 4311 } 4312 } 4313 4314 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4315 { 4316 if (type_is) 4317 { 4318 n1 = (rettv->v_type == var2.v_type 4319 && rettv->vval.v_dict == var2.vval.v_dict); 4320 if (type == TYPE_NEQUAL) 4321 n1 = !n1; 4322 } 4323 else if (rettv->v_type != var2.v_type 4324 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4325 { 4326 if (rettv->v_type != var2.v_type) 4327 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4328 else 4329 EMSG(_("E736: Invalid operation for Dictionary")); 4330 clear_tv(rettv); 4331 clear_tv(&var2); 4332 return FAIL; 4333 } 4334 else 4335 { 4336 /* Compare two Dictionaries for being equal or unequal. */ 4337 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4338 if (type == TYPE_NEQUAL) 4339 n1 = !n1; 4340 } 4341 } 4342 4343 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4344 { 4345 if (rettv->v_type != var2.v_type 4346 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4347 { 4348 if (rettv->v_type != var2.v_type) 4349 EMSG(_("E693: Can only compare Funcref with Funcref")); 4350 else 4351 EMSG(_("E694: Invalid operation for Funcrefs")); 4352 clear_tv(rettv); 4353 clear_tv(&var2); 4354 return FAIL; 4355 } 4356 else 4357 { 4358 /* Compare two Funcrefs for being equal or unequal. */ 4359 if (rettv->vval.v_string == NULL 4360 || var2.vval.v_string == NULL) 4361 n1 = FALSE; 4362 else 4363 n1 = STRCMP(rettv->vval.v_string, 4364 var2.vval.v_string) == 0; 4365 if (type == TYPE_NEQUAL) 4366 n1 = !n1; 4367 } 4368 } 4369 4370 #ifdef FEAT_FLOAT 4371 /* 4372 * If one of the two variables is a float, compare as a float. 4373 * When using "=~" or "!~", always compare as string. 4374 */ 4375 else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4376 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4377 { 4378 float_T f1, f2; 4379 4380 if (rettv->v_type == VAR_FLOAT) 4381 f1 = rettv->vval.v_float; 4382 else 4383 f1 = get_tv_number(rettv); 4384 if (var2.v_type == VAR_FLOAT) 4385 f2 = var2.vval.v_float; 4386 else 4387 f2 = get_tv_number(&var2); 4388 n1 = FALSE; 4389 switch (type) 4390 { 4391 case TYPE_EQUAL: n1 = (f1 == f2); break; 4392 case TYPE_NEQUAL: n1 = (f1 != f2); break; 4393 case TYPE_GREATER: n1 = (f1 > f2); break; 4394 case TYPE_GEQUAL: n1 = (f1 >= f2); break; 4395 case TYPE_SMALLER: n1 = (f1 < f2); break; 4396 case TYPE_SEQUAL: n1 = (f1 <= f2); break; 4397 case TYPE_UNKNOWN: 4398 case TYPE_MATCH: 4399 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4400 } 4401 } 4402 #endif 4403 4404 /* 4405 * If one of the two variables is a number, compare as a number. 4406 * When using "=~" or "!~", always compare as string. 4407 */ 4408 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4409 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4410 { 4411 n1 = get_tv_number(rettv); 4412 n2 = get_tv_number(&var2); 4413 switch (type) 4414 { 4415 case TYPE_EQUAL: n1 = (n1 == n2); break; 4416 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4417 case TYPE_GREATER: n1 = (n1 > n2); break; 4418 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4419 case TYPE_SMALLER: n1 = (n1 < n2); break; 4420 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4421 case TYPE_UNKNOWN: 4422 case TYPE_MATCH: 4423 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4424 } 4425 } 4426 else 4427 { 4428 s1 = get_tv_string_buf(rettv, buf1); 4429 s2 = get_tv_string_buf(&var2, buf2); 4430 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4431 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4432 else 4433 i = 0; 4434 n1 = FALSE; 4435 switch (type) 4436 { 4437 case TYPE_EQUAL: n1 = (i == 0); break; 4438 case TYPE_NEQUAL: n1 = (i != 0); break; 4439 case TYPE_GREATER: n1 = (i > 0); break; 4440 case TYPE_GEQUAL: n1 = (i >= 0); break; 4441 case TYPE_SMALLER: n1 = (i < 0); break; 4442 case TYPE_SEQUAL: n1 = (i <= 0); break; 4443 4444 case TYPE_MATCH: 4445 case TYPE_NOMATCH: 4446 /* avoid 'l' flag in 'cpoptions' */ 4447 save_cpo = p_cpo; 4448 p_cpo = (char_u *)""; 4449 regmatch.regprog = vim_regcomp(s2, 4450 RE_MAGIC + RE_STRING); 4451 regmatch.rm_ic = ic; 4452 if (regmatch.regprog != NULL) 4453 { 4454 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4455 vim_free(regmatch.regprog); 4456 if (type == TYPE_NOMATCH) 4457 n1 = !n1; 4458 } 4459 p_cpo = save_cpo; 4460 break; 4461 4462 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4463 } 4464 } 4465 clear_tv(rettv); 4466 clear_tv(&var2); 4467 rettv->v_type = VAR_NUMBER; 4468 rettv->vval.v_number = n1; 4469 } 4470 } 4471 4472 return OK; 4473 } 4474 4475 /* 4476 * Handle fourth level expression: 4477 * + number addition 4478 * - number subtraction 4479 * . string concatenation 4480 * 4481 * "arg" must point to the first non-white of the expression. 4482 * "arg" is advanced to the next non-white after the recognized expression. 4483 * 4484 * Return OK or FAIL. 4485 */ 4486 static int 4487 eval5(arg, rettv, evaluate) 4488 char_u **arg; 4489 typval_T *rettv; 4490 int evaluate; 4491 { 4492 typval_T var2; 4493 typval_T var3; 4494 int op; 4495 long n1, n2; 4496 #ifdef FEAT_FLOAT 4497 float_T f1 = 0, f2 = 0; 4498 #endif 4499 char_u *s1, *s2; 4500 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4501 char_u *p; 4502 4503 /* 4504 * Get the first variable. 4505 */ 4506 if (eval6(arg, rettv, evaluate, FALSE) == FAIL) 4507 return FAIL; 4508 4509 /* 4510 * Repeat computing, until no '+', '-' or '.' is following. 4511 */ 4512 for (;;) 4513 { 4514 op = **arg; 4515 if (op != '+' && op != '-' && op != '.') 4516 break; 4517 4518 if ((op != '+' || rettv->v_type != VAR_LIST) 4519 #ifdef FEAT_FLOAT 4520 && (op == '.' || rettv->v_type != VAR_FLOAT) 4521 #endif 4522 ) 4523 { 4524 /* For "list + ...", an illegal use of the first operand as 4525 * a number cannot be determined before evaluating the 2nd 4526 * operand: if this is also a list, all is ok. 4527 * For "something . ...", "something - ..." or "non-list + ...", 4528 * we know that the first operand needs to be a string or number 4529 * without evaluating the 2nd operand. So check before to avoid 4530 * side effects after an error. */ 4531 if (evaluate && get_tv_string_chk(rettv) == NULL) 4532 { 4533 clear_tv(rettv); 4534 return FAIL; 4535 } 4536 } 4537 4538 /* 4539 * Get the second variable. 4540 */ 4541 *arg = skipwhite(*arg + 1); 4542 if (eval6(arg, &var2, evaluate, op == '.') == FAIL) 4543 { 4544 clear_tv(rettv); 4545 return FAIL; 4546 } 4547 4548 if (evaluate) 4549 { 4550 /* 4551 * Compute the result. 4552 */ 4553 if (op == '.') 4554 { 4555 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4556 s2 = get_tv_string_buf_chk(&var2, buf2); 4557 if (s2 == NULL) /* type error ? */ 4558 { 4559 clear_tv(rettv); 4560 clear_tv(&var2); 4561 return FAIL; 4562 } 4563 p = concat_str(s1, s2); 4564 clear_tv(rettv); 4565 rettv->v_type = VAR_STRING; 4566 rettv->vval.v_string = p; 4567 } 4568 else if (op == '+' && rettv->v_type == VAR_LIST 4569 && var2.v_type == VAR_LIST) 4570 { 4571 /* concatenate Lists */ 4572 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4573 &var3) == FAIL) 4574 { 4575 clear_tv(rettv); 4576 clear_tv(&var2); 4577 return FAIL; 4578 } 4579 clear_tv(rettv); 4580 *rettv = var3; 4581 } 4582 else 4583 { 4584 int error = FALSE; 4585 4586 #ifdef FEAT_FLOAT 4587 if (rettv->v_type == VAR_FLOAT) 4588 { 4589 f1 = rettv->vval.v_float; 4590 n1 = 0; 4591 } 4592 else 4593 #endif 4594 { 4595 n1 = get_tv_number_chk(rettv, &error); 4596 if (error) 4597 { 4598 /* This can only happen for "list + non-list". For 4599 * "non-list + ..." or "something - ...", we returned 4600 * before evaluating the 2nd operand. */ 4601 clear_tv(rettv); 4602 return FAIL; 4603 } 4604 #ifdef FEAT_FLOAT 4605 if (var2.v_type == VAR_FLOAT) 4606 f1 = n1; 4607 #endif 4608 } 4609 #ifdef FEAT_FLOAT 4610 if (var2.v_type == VAR_FLOAT) 4611 { 4612 f2 = var2.vval.v_float; 4613 n2 = 0; 4614 } 4615 else 4616 #endif 4617 { 4618 n2 = get_tv_number_chk(&var2, &error); 4619 if (error) 4620 { 4621 clear_tv(rettv); 4622 clear_tv(&var2); 4623 return FAIL; 4624 } 4625 #ifdef FEAT_FLOAT 4626 if (rettv->v_type == VAR_FLOAT) 4627 f2 = n2; 4628 #endif 4629 } 4630 clear_tv(rettv); 4631 4632 #ifdef FEAT_FLOAT 4633 /* If there is a float on either side the result is a float. */ 4634 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4635 { 4636 if (op == '+') 4637 f1 = f1 + f2; 4638 else 4639 f1 = f1 - f2; 4640 rettv->v_type = VAR_FLOAT; 4641 rettv->vval.v_float = f1; 4642 } 4643 else 4644 #endif 4645 { 4646 if (op == '+') 4647 n1 = n1 + n2; 4648 else 4649 n1 = n1 - n2; 4650 rettv->v_type = VAR_NUMBER; 4651 rettv->vval.v_number = n1; 4652 } 4653 } 4654 clear_tv(&var2); 4655 } 4656 } 4657 return OK; 4658 } 4659 4660 /* 4661 * Handle fifth level expression: 4662 * * number multiplication 4663 * / number division 4664 * % number modulo 4665 * 4666 * "arg" must point to the first non-white of the expression. 4667 * "arg" is advanced to the next non-white after the recognized expression. 4668 * 4669 * Return OK or FAIL. 4670 */ 4671 static int 4672 eval6(arg, rettv, evaluate, want_string) 4673 char_u **arg; 4674 typval_T *rettv; 4675 int evaluate; 4676 int want_string; /* after "." operator */ 4677 { 4678 typval_T var2; 4679 int op; 4680 long n1, n2; 4681 #ifdef FEAT_FLOAT 4682 int use_float = FALSE; 4683 float_T f1 = 0, f2; 4684 #endif 4685 int error = FALSE; 4686 4687 /* 4688 * Get the first variable. 4689 */ 4690 if (eval7(arg, rettv, evaluate, want_string) == FAIL) 4691 return FAIL; 4692 4693 /* 4694 * Repeat computing, until no '*', '/' or '%' is following. 4695 */ 4696 for (;;) 4697 { 4698 op = **arg; 4699 if (op != '*' && op != '/' && op != '%') 4700 break; 4701 4702 if (evaluate) 4703 { 4704 #ifdef FEAT_FLOAT 4705 if (rettv->v_type == VAR_FLOAT) 4706 { 4707 f1 = rettv->vval.v_float; 4708 use_float = TRUE; 4709 n1 = 0; 4710 } 4711 else 4712 #endif 4713 n1 = get_tv_number_chk(rettv, &error); 4714 clear_tv(rettv); 4715 if (error) 4716 return FAIL; 4717 } 4718 else 4719 n1 = 0; 4720 4721 /* 4722 * Get the second variable. 4723 */ 4724 *arg = skipwhite(*arg + 1); 4725 if (eval7(arg, &var2, evaluate, FALSE) == FAIL) 4726 return FAIL; 4727 4728 if (evaluate) 4729 { 4730 #ifdef FEAT_FLOAT 4731 if (var2.v_type == VAR_FLOAT) 4732 { 4733 if (!use_float) 4734 { 4735 f1 = n1; 4736 use_float = TRUE; 4737 } 4738 f2 = var2.vval.v_float; 4739 n2 = 0; 4740 } 4741 else 4742 #endif 4743 { 4744 n2 = get_tv_number_chk(&var2, &error); 4745 clear_tv(&var2); 4746 if (error) 4747 return FAIL; 4748 #ifdef FEAT_FLOAT 4749 if (use_float) 4750 f2 = n2; 4751 #endif 4752 } 4753 4754 /* 4755 * Compute the result. 4756 * When either side is a float the result is a float. 4757 */ 4758 #ifdef FEAT_FLOAT 4759 if (use_float) 4760 { 4761 if (op == '*') 4762 f1 = f1 * f2; 4763 else if (op == '/') 4764 { 4765 /* We rely on the floating point library to handle divide 4766 * by zero to result in "inf" and not a crash. */ 4767 f1 = f1 / f2; 4768 } 4769 else 4770 { 4771 EMSG(_("E804: Cannot use '%' with Float")); 4772 return FAIL; 4773 } 4774 rettv->v_type = VAR_FLOAT; 4775 rettv->vval.v_float = f1; 4776 } 4777 else 4778 #endif 4779 { 4780 if (op == '*') 4781 n1 = n1 * n2; 4782 else if (op == '/') 4783 { 4784 if (n2 == 0) /* give an error message? */ 4785 { 4786 if (n1 == 0) 4787 n1 = -0x7fffffffL - 1L; /* similar to NaN */ 4788 else if (n1 < 0) 4789 n1 = -0x7fffffffL; 4790 else 4791 n1 = 0x7fffffffL; 4792 } 4793 else 4794 n1 = n1 / n2; 4795 } 4796 else 4797 { 4798 if (n2 == 0) /* give an error message? */ 4799 n1 = 0; 4800 else 4801 n1 = n1 % n2; 4802 } 4803 rettv->v_type = VAR_NUMBER; 4804 rettv->vval.v_number = n1; 4805 } 4806 } 4807 } 4808 4809 return OK; 4810 } 4811 4812 /* 4813 * Handle sixth level expression: 4814 * number number constant 4815 * "string" string constant 4816 * 'string' literal string constant 4817 * &option-name option value 4818 * @r register contents 4819 * identifier variable value 4820 * function() function call 4821 * $VAR environment variable 4822 * (expression) nested expression 4823 * [expr, expr] List 4824 * {key: val, key: val} Dictionary 4825 * 4826 * Also handle: 4827 * ! in front logical NOT 4828 * - in front unary minus 4829 * + in front unary plus (ignored) 4830 * trailing [] subscript in String or List 4831 * trailing .name entry in Dictionary 4832 * 4833 * "arg" must point to the first non-white of the expression. 4834 * "arg" is advanced to the next non-white after the recognized expression. 4835 * 4836 * Return OK or FAIL. 4837 */ 4838 static int 4839 eval7(arg, rettv, evaluate, want_string) 4840 char_u **arg; 4841 typval_T *rettv; 4842 int evaluate; 4843 int want_string; /* after "." operator */ 4844 { 4845 long n; 4846 int len; 4847 char_u *s; 4848 char_u *start_leader, *end_leader; 4849 int ret = OK; 4850 char_u *alias; 4851 4852 /* 4853 * Initialise variable so that clear_tv() can't mistake this for a 4854 * string and free a string that isn't there. 4855 */ 4856 rettv->v_type = VAR_UNKNOWN; 4857 4858 /* 4859 * Skip '!' and '-' characters. They are handled later. 4860 */ 4861 start_leader = *arg; 4862 while (**arg == '!' || **arg == '-' || **arg == '+') 4863 *arg = skipwhite(*arg + 1); 4864 end_leader = *arg; 4865 4866 switch (**arg) 4867 { 4868 /* 4869 * Number constant. 4870 */ 4871 case '0': 4872 case '1': 4873 case '2': 4874 case '3': 4875 case '4': 4876 case '5': 4877 case '6': 4878 case '7': 4879 case '8': 4880 case '9': 4881 { 4882 #ifdef FEAT_FLOAT 4883 char_u *p = skipdigits(*arg + 1); 4884 int get_float = FALSE; 4885 4886 /* We accept a float when the format matches 4887 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very 4888 * strict to avoid backwards compatibility problems. 4889 * Don't look for a float after the "." operator, so that 4890 * ":let vers = 1.2.3" doesn't fail. */ 4891 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) 4892 { 4893 get_float = TRUE; 4894 p = skipdigits(p + 2); 4895 if (*p == 'e' || *p == 'E') 4896 { 4897 ++p; 4898 if (*p == '-' || *p == '+') 4899 ++p; 4900 if (!vim_isdigit(*p)) 4901 get_float = FALSE; 4902 else 4903 p = skipdigits(p + 1); 4904 } 4905 if (ASCII_ISALPHA(*p) || *p == '.') 4906 get_float = FALSE; 4907 } 4908 if (get_float) 4909 { 4910 float_T f; 4911 4912 *arg += string2float(*arg, &f); 4913 if (evaluate) 4914 { 4915 rettv->v_type = VAR_FLOAT; 4916 rettv->vval.v_float = f; 4917 } 4918 } 4919 else 4920 #endif 4921 { 4922 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4923 *arg += len; 4924 if (evaluate) 4925 { 4926 rettv->v_type = VAR_NUMBER; 4927 rettv->vval.v_number = n; 4928 } 4929 } 4930 break; 4931 } 4932 4933 /* 4934 * String constant: "string". 4935 */ 4936 case '"': ret = get_string_tv(arg, rettv, evaluate); 4937 break; 4938 4939 /* 4940 * Literal string constant: 'str''ing'. 4941 */ 4942 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4943 break; 4944 4945 /* 4946 * List: [expr, expr] 4947 */ 4948 case '[': ret = get_list_tv(arg, rettv, evaluate); 4949 break; 4950 4951 /* 4952 * Dictionary: {key: val, key: val} 4953 */ 4954 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4955 break; 4956 4957 /* 4958 * Option value: &name 4959 */ 4960 case '&': ret = get_option_tv(arg, rettv, evaluate); 4961 break; 4962 4963 /* 4964 * Environment variable: $VAR. 4965 */ 4966 case '$': ret = get_env_tv(arg, rettv, evaluate); 4967 break; 4968 4969 /* 4970 * Register contents: @r. 4971 */ 4972 case '@': ++*arg; 4973 if (evaluate) 4974 { 4975 rettv->v_type = VAR_STRING; 4976 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4977 } 4978 if (**arg != NUL) 4979 ++*arg; 4980 break; 4981 4982 /* 4983 * nested expression: (expression). 4984 */ 4985 case '(': *arg = skipwhite(*arg + 1); 4986 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4987 if (**arg == ')') 4988 ++*arg; 4989 else if (ret == OK) 4990 { 4991 EMSG(_("E110: Missing ')'")); 4992 clear_tv(rettv); 4993 ret = FAIL; 4994 } 4995 break; 4996 4997 default: ret = NOTDONE; 4998 break; 4999 } 5000 5001 if (ret == NOTDONE) 5002 { 5003 /* 5004 * Must be a variable or function name. 5005 * Can also be a curly-braces kind of name: {expr}. 5006 */ 5007 s = *arg; 5008 len = get_name_len(arg, &alias, evaluate, TRUE); 5009 if (alias != NULL) 5010 s = alias; 5011 5012 if (len <= 0) 5013 ret = FAIL; 5014 else 5015 { 5016 if (**arg == '(') /* recursive! */ 5017 { 5018 /* If "s" is the name of a variable of type VAR_FUNC 5019 * use its contents. */ 5020 s = deref_func_name(s, &len); 5021 5022 /* Invoke the function. */ 5023 ret = get_func_tv(s, len, rettv, arg, 5024 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 5025 &len, evaluate, NULL); 5026 /* Stop the expression evaluation when immediately 5027 * aborting on error, or when an interrupt occurred or 5028 * an exception was thrown but not caught. */ 5029 if (aborting()) 5030 { 5031 if (ret == OK) 5032 clear_tv(rettv); 5033 ret = FAIL; 5034 } 5035 } 5036 else if (evaluate) 5037 ret = get_var_tv(s, len, rettv, TRUE); 5038 else 5039 ret = OK; 5040 } 5041 5042 if (alias != NULL) 5043 vim_free(alias); 5044 } 5045 5046 *arg = skipwhite(*arg); 5047 5048 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 5049 * expr(expr). */ 5050 if (ret == OK) 5051 ret = handle_subscript(arg, rettv, evaluate, TRUE); 5052 5053 /* 5054 * Apply logical NOT and unary '-', from right to left, ignore '+'. 5055 */ 5056 if (ret == OK && evaluate && end_leader > start_leader) 5057 { 5058 int error = FALSE; 5059 int val = 0; 5060 #ifdef FEAT_FLOAT 5061 float_T f = 0.0; 5062 5063 if (rettv->v_type == VAR_FLOAT) 5064 f = rettv->vval.v_float; 5065 else 5066 #endif 5067 val = get_tv_number_chk(rettv, &error); 5068 if (error) 5069 { 5070 clear_tv(rettv); 5071 ret = FAIL; 5072 } 5073 else 5074 { 5075 while (end_leader > start_leader) 5076 { 5077 --end_leader; 5078 if (*end_leader == '!') 5079 { 5080 #ifdef FEAT_FLOAT 5081 if (rettv->v_type == VAR_FLOAT) 5082 f = !f; 5083 else 5084 #endif 5085 val = !val; 5086 } 5087 else if (*end_leader == '-') 5088 { 5089 #ifdef FEAT_FLOAT 5090 if (rettv->v_type == VAR_FLOAT) 5091 f = -f; 5092 else 5093 #endif 5094 val = -val; 5095 } 5096 } 5097 #ifdef FEAT_FLOAT 5098 if (rettv->v_type == VAR_FLOAT) 5099 { 5100 clear_tv(rettv); 5101 rettv->vval.v_float = f; 5102 } 5103 else 5104 #endif 5105 { 5106 clear_tv(rettv); 5107 rettv->v_type = VAR_NUMBER; 5108 rettv->vval.v_number = val; 5109 } 5110 } 5111 } 5112 5113 return ret; 5114 } 5115 5116 /* 5117 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 5118 * "*arg" points to the '[' or '.'. 5119 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 5120 */ 5121 static int 5122 eval_index(arg, rettv, evaluate, verbose) 5123 char_u **arg; 5124 typval_T *rettv; 5125 int evaluate; 5126 int verbose; /* give error messages */ 5127 { 5128 int empty1 = FALSE, empty2 = FALSE; 5129 typval_T var1, var2; 5130 long n1, n2 = 0; 5131 long len = -1; 5132 int range = FALSE; 5133 char_u *s; 5134 char_u *key = NULL; 5135 5136 if (rettv->v_type == VAR_FUNC 5137 #ifdef FEAT_FLOAT 5138 || rettv->v_type == VAR_FLOAT 5139 #endif 5140 ) 5141 { 5142 if (verbose) 5143 EMSG(_("E695: Cannot index a Funcref")); 5144 return FAIL; 5145 } 5146 5147 if (**arg == '.') 5148 { 5149 /* 5150 * dict.name 5151 */ 5152 key = *arg + 1; 5153 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 5154 ; 5155 if (len == 0) 5156 return FAIL; 5157 *arg = skipwhite(key + len); 5158 } 5159 else 5160 { 5161 /* 5162 * something[idx] 5163 * 5164 * Get the (first) variable from inside the []. 5165 */ 5166 *arg = skipwhite(*arg + 1); 5167 if (**arg == ':') 5168 empty1 = TRUE; 5169 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 5170 return FAIL; 5171 else if (evaluate && get_tv_string_chk(&var1) == NULL) 5172 { 5173 /* not a number or string */ 5174 clear_tv(&var1); 5175 return FAIL; 5176 } 5177 5178 /* 5179 * Get the second variable from inside the [:]. 5180 */ 5181 if (**arg == ':') 5182 { 5183 range = TRUE; 5184 *arg = skipwhite(*arg + 1); 5185 if (**arg == ']') 5186 empty2 = TRUE; 5187 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 5188 { 5189 if (!empty1) 5190 clear_tv(&var1); 5191 return FAIL; 5192 } 5193 else if (evaluate && get_tv_string_chk(&var2) == NULL) 5194 { 5195 /* not a number or string */ 5196 if (!empty1) 5197 clear_tv(&var1); 5198 clear_tv(&var2); 5199 return FAIL; 5200 } 5201 } 5202 5203 /* Check for the ']'. */ 5204 if (**arg != ']') 5205 { 5206 if (verbose) 5207 EMSG(_(e_missbrac)); 5208 clear_tv(&var1); 5209 if (range) 5210 clear_tv(&var2); 5211 return FAIL; 5212 } 5213 *arg = skipwhite(*arg + 1); /* skip the ']' */ 5214 } 5215 5216 if (evaluate) 5217 { 5218 n1 = 0; 5219 if (!empty1 && rettv->v_type != VAR_DICT) 5220 { 5221 n1 = get_tv_number(&var1); 5222 clear_tv(&var1); 5223 } 5224 if (range) 5225 { 5226 if (empty2) 5227 n2 = -1; 5228 else 5229 { 5230 n2 = get_tv_number(&var2); 5231 clear_tv(&var2); 5232 } 5233 } 5234 5235 switch (rettv->v_type) 5236 { 5237 case VAR_NUMBER: 5238 case VAR_STRING: 5239 s = get_tv_string(rettv); 5240 len = (long)STRLEN(s); 5241 if (range) 5242 { 5243 /* The resulting variable is a substring. If the indexes 5244 * are out of range the result is empty. */ 5245 if (n1 < 0) 5246 { 5247 n1 = len + n1; 5248 if (n1 < 0) 5249 n1 = 0; 5250 } 5251 if (n2 < 0) 5252 n2 = len + n2; 5253 else if (n2 >= len) 5254 n2 = len; 5255 if (n1 >= len || n2 < 0 || n1 > n2) 5256 s = NULL; 5257 else 5258 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 5259 } 5260 else 5261 { 5262 /* The resulting variable is a string of a single 5263 * character. If the index is too big or negative the 5264 * result is empty. */ 5265 if (n1 >= len || n1 < 0) 5266 s = NULL; 5267 else 5268 s = vim_strnsave(s + n1, 1); 5269 } 5270 clear_tv(rettv); 5271 rettv->v_type = VAR_STRING; 5272 rettv->vval.v_string = s; 5273 break; 5274 5275 case VAR_LIST: 5276 len = list_len(rettv->vval.v_list); 5277 if (n1 < 0) 5278 n1 = len + n1; 5279 if (!empty1 && (n1 < 0 || n1 >= len)) 5280 { 5281 /* For a range we allow invalid values and return an empty 5282 * list. A list index out of range is an error. */ 5283 if (!range) 5284 { 5285 if (verbose) 5286 EMSGN(_(e_listidx), n1); 5287 return FAIL; 5288 } 5289 n1 = len; 5290 } 5291 if (range) 5292 { 5293 list_T *l; 5294 listitem_T *item; 5295 5296 if (n2 < 0) 5297 n2 = len + n2; 5298 else if (n2 >= len) 5299 n2 = len - 1; 5300 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 5301 n2 = -1; 5302 l = list_alloc(); 5303 if (l == NULL) 5304 return FAIL; 5305 for (item = list_find(rettv->vval.v_list, n1); 5306 n1 <= n2; ++n1) 5307 { 5308 if (list_append_tv(l, &item->li_tv) == FAIL) 5309 { 5310 list_free(l, TRUE); 5311 return FAIL; 5312 } 5313 item = item->li_next; 5314 } 5315 clear_tv(rettv); 5316 rettv->v_type = VAR_LIST; 5317 rettv->vval.v_list = l; 5318 ++l->lv_refcount; 5319 } 5320 else 5321 { 5322 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 5323 clear_tv(rettv); 5324 *rettv = var1; 5325 } 5326 break; 5327 5328 case VAR_DICT: 5329 if (range) 5330 { 5331 if (verbose) 5332 EMSG(_(e_dictrange)); 5333 if (len == -1) 5334 clear_tv(&var1); 5335 return FAIL; 5336 } 5337 { 5338 dictitem_T *item; 5339 5340 if (len == -1) 5341 { 5342 key = get_tv_string(&var1); 5343 if (*key == NUL) 5344 { 5345 if (verbose) 5346 EMSG(_(e_emptykey)); 5347 clear_tv(&var1); 5348 return FAIL; 5349 } 5350 } 5351 5352 item = dict_find(rettv->vval.v_dict, key, (int)len); 5353 5354 if (item == NULL && verbose) 5355 EMSG2(_(e_dictkey), key); 5356 if (len == -1) 5357 clear_tv(&var1); 5358 if (item == NULL) 5359 return FAIL; 5360 5361 copy_tv(&item->di_tv, &var1); 5362 clear_tv(rettv); 5363 *rettv = var1; 5364 } 5365 break; 5366 } 5367 } 5368 5369 return OK; 5370 } 5371 5372 /* 5373 * Get an option value. 5374 * "arg" points to the '&' or '+' before the option name. 5375 * "arg" is advanced to character after the option name. 5376 * Return OK or FAIL. 5377 */ 5378 static int 5379 get_option_tv(arg, rettv, evaluate) 5380 char_u **arg; 5381 typval_T *rettv; /* when NULL, only check if option exists */ 5382 int evaluate; 5383 { 5384 char_u *option_end; 5385 long numval; 5386 char_u *stringval; 5387 int opt_type; 5388 int c; 5389 int working = (**arg == '+'); /* has("+option") */ 5390 int ret = OK; 5391 int opt_flags; 5392 5393 /* 5394 * Isolate the option name and find its value. 5395 */ 5396 option_end = find_option_end(arg, &opt_flags); 5397 if (option_end == NULL) 5398 { 5399 if (rettv != NULL) 5400 EMSG2(_("E112: Option name missing: %s"), *arg); 5401 return FAIL; 5402 } 5403 5404 if (!evaluate) 5405 { 5406 *arg = option_end; 5407 return OK; 5408 } 5409 5410 c = *option_end; 5411 *option_end = NUL; 5412 opt_type = get_option_value(*arg, &numval, 5413 rettv == NULL ? NULL : &stringval, opt_flags); 5414 5415 if (opt_type == -3) /* invalid name */ 5416 { 5417 if (rettv != NULL) 5418 EMSG2(_("E113: Unknown option: %s"), *arg); 5419 ret = FAIL; 5420 } 5421 else if (rettv != NULL) 5422 { 5423 if (opt_type == -2) /* hidden string option */ 5424 { 5425 rettv->v_type = VAR_STRING; 5426 rettv->vval.v_string = NULL; 5427 } 5428 else if (opt_type == -1) /* hidden number option */ 5429 { 5430 rettv->v_type = VAR_NUMBER; 5431 rettv->vval.v_number = 0; 5432 } 5433 else if (opt_type == 1) /* number option */ 5434 { 5435 rettv->v_type = VAR_NUMBER; 5436 rettv->vval.v_number = numval; 5437 } 5438 else /* string option */ 5439 { 5440 rettv->v_type = VAR_STRING; 5441 rettv->vval.v_string = stringval; 5442 } 5443 } 5444 else if (working && (opt_type == -2 || opt_type == -1)) 5445 ret = FAIL; 5446 5447 *option_end = c; /* put back for error messages */ 5448 *arg = option_end; 5449 5450 return ret; 5451 } 5452 5453 /* 5454 * Allocate a variable for a string constant. 5455 * Return OK or FAIL. 5456 */ 5457 static int 5458 get_string_tv(arg, rettv, evaluate) 5459 char_u **arg; 5460 typval_T *rettv; 5461 int evaluate; 5462 { 5463 char_u *p; 5464 char_u *name; 5465 int extra = 0; 5466 5467 /* 5468 * Find the end of the string, skipping backslashed characters. 5469 */ 5470 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5471 { 5472 if (*p == '\\' && p[1] != NUL) 5473 { 5474 ++p; 5475 /* A "\<x>" form occupies at least 4 characters, and produces up 5476 * to 6 characters: reserve space for 2 extra */ 5477 if (*p == '<') 5478 extra += 2; 5479 } 5480 } 5481 5482 if (*p != '"') 5483 { 5484 EMSG2(_("E114: Missing quote: %s"), *arg); 5485 return FAIL; 5486 } 5487 5488 /* If only parsing, set *arg and return here */ 5489 if (!evaluate) 5490 { 5491 *arg = p + 1; 5492 return OK; 5493 } 5494 5495 /* 5496 * Copy the string into allocated memory, handling backslashed 5497 * characters. 5498 */ 5499 name = alloc((unsigned)(p - *arg + extra)); 5500 if (name == NULL) 5501 return FAIL; 5502 rettv->v_type = VAR_STRING; 5503 rettv->vval.v_string = name; 5504 5505 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5506 { 5507 if (*p == '\\') 5508 { 5509 switch (*++p) 5510 { 5511 case 'b': *name++ = BS; ++p; break; 5512 case 'e': *name++ = ESC; ++p; break; 5513 case 'f': *name++ = FF; ++p; break; 5514 case 'n': *name++ = NL; ++p; break; 5515 case 'r': *name++ = CAR; ++p; break; 5516 case 't': *name++ = TAB; ++p; break; 5517 5518 case 'X': /* hex: "\x1", "\x12" */ 5519 case 'x': 5520 case 'u': /* Unicode: "\u0023" */ 5521 case 'U': 5522 if (vim_isxdigit(p[1])) 5523 { 5524 int n, nr; 5525 int c = toupper(*p); 5526 5527 if (c == 'X') 5528 n = 2; 5529 else 5530 n = 4; 5531 nr = 0; 5532 while (--n >= 0 && vim_isxdigit(p[1])) 5533 { 5534 ++p; 5535 nr = (nr << 4) + hex2nr(*p); 5536 } 5537 ++p; 5538 #ifdef FEAT_MBYTE 5539 /* For "\u" store the number according to 5540 * 'encoding'. */ 5541 if (c != 'X') 5542 name += (*mb_char2bytes)(nr, name); 5543 else 5544 #endif 5545 *name++ = nr; 5546 } 5547 break; 5548 5549 /* octal: "\1", "\12", "\123" */ 5550 case '0': 5551 case '1': 5552 case '2': 5553 case '3': 5554 case '4': 5555 case '5': 5556 case '6': 5557 case '7': *name = *p++ - '0'; 5558 if (*p >= '0' && *p <= '7') 5559 { 5560 *name = (*name << 3) + *p++ - '0'; 5561 if (*p >= '0' && *p <= '7') 5562 *name = (*name << 3) + *p++ - '0'; 5563 } 5564 ++name; 5565 break; 5566 5567 /* Special key, e.g.: "\<C-W>" */ 5568 case '<': extra = trans_special(&p, name, TRUE); 5569 if (extra != 0) 5570 { 5571 name += extra; 5572 break; 5573 } 5574 /* FALLTHROUGH */ 5575 5576 default: MB_COPY_CHAR(p, name); 5577 break; 5578 } 5579 } 5580 else 5581 MB_COPY_CHAR(p, name); 5582 5583 } 5584 *name = NUL; 5585 *arg = p + 1; 5586 5587 return OK; 5588 } 5589 5590 /* 5591 * Allocate a variable for a 'str''ing' constant. 5592 * Return OK or FAIL. 5593 */ 5594 static int 5595 get_lit_string_tv(arg, rettv, evaluate) 5596 char_u **arg; 5597 typval_T *rettv; 5598 int evaluate; 5599 { 5600 char_u *p; 5601 char_u *str; 5602 int reduce = 0; 5603 5604 /* 5605 * Find the end of the string, skipping ''. 5606 */ 5607 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5608 { 5609 if (*p == '\'') 5610 { 5611 if (p[1] != '\'') 5612 break; 5613 ++reduce; 5614 ++p; 5615 } 5616 } 5617 5618 if (*p != '\'') 5619 { 5620 EMSG2(_("E115: Missing quote: %s"), *arg); 5621 return FAIL; 5622 } 5623 5624 /* If only parsing return after setting "*arg" */ 5625 if (!evaluate) 5626 { 5627 *arg = p + 1; 5628 return OK; 5629 } 5630 5631 /* 5632 * Copy the string into allocated memory, handling '' to ' reduction. 5633 */ 5634 str = alloc((unsigned)((p - *arg) - reduce)); 5635 if (str == NULL) 5636 return FAIL; 5637 rettv->v_type = VAR_STRING; 5638 rettv->vval.v_string = str; 5639 5640 for (p = *arg + 1; *p != NUL; ) 5641 { 5642 if (*p == '\'') 5643 { 5644 if (p[1] != '\'') 5645 break; 5646 ++p; 5647 } 5648 MB_COPY_CHAR(p, str); 5649 } 5650 *str = NUL; 5651 *arg = p + 1; 5652 5653 return OK; 5654 } 5655 5656 /* 5657 * Allocate a variable for a List and fill it from "*arg". 5658 * Return OK or FAIL. 5659 */ 5660 static int 5661 get_list_tv(arg, rettv, evaluate) 5662 char_u **arg; 5663 typval_T *rettv; 5664 int evaluate; 5665 { 5666 list_T *l = NULL; 5667 typval_T tv; 5668 listitem_T *item; 5669 5670 if (evaluate) 5671 { 5672 l = list_alloc(); 5673 if (l == NULL) 5674 return FAIL; 5675 } 5676 5677 *arg = skipwhite(*arg + 1); 5678 while (**arg != ']' && **arg != NUL) 5679 { 5680 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5681 goto failret; 5682 if (evaluate) 5683 { 5684 item = listitem_alloc(); 5685 if (item != NULL) 5686 { 5687 item->li_tv = tv; 5688 item->li_tv.v_lock = 0; 5689 list_append(l, item); 5690 } 5691 else 5692 clear_tv(&tv); 5693 } 5694 5695 if (**arg == ']') 5696 break; 5697 if (**arg != ',') 5698 { 5699 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5700 goto failret; 5701 } 5702 *arg = skipwhite(*arg + 1); 5703 } 5704 5705 if (**arg != ']') 5706 { 5707 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5708 failret: 5709 if (evaluate) 5710 list_free(l, TRUE); 5711 return FAIL; 5712 } 5713 5714 *arg = skipwhite(*arg + 1); 5715 if (evaluate) 5716 { 5717 rettv->v_type = VAR_LIST; 5718 rettv->vval.v_list = l; 5719 ++l->lv_refcount; 5720 } 5721 5722 return OK; 5723 } 5724 5725 /* 5726 * Allocate an empty header for a list. 5727 * Caller should take care of the reference count. 5728 */ 5729 list_T * 5730 list_alloc() 5731 { 5732 list_T *l; 5733 5734 l = (list_T *)alloc_clear(sizeof(list_T)); 5735 if (l != NULL) 5736 { 5737 /* Prepend the list to the list of lists for garbage collection. */ 5738 if (first_list != NULL) 5739 first_list->lv_used_prev = l; 5740 l->lv_used_prev = NULL; 5741 l->lv_used_next = first_list; 5742 first_list = l; 5743 } 5744 return l; 5745 } 5746 5747 /* 5748 * Allocate an empty list for a return value. 5749 * Returns OK or FAIL. 5750 */ 5751 static int 5752 rettv_list_alloc(rettv) 5753 typval_T *rettv; 5754 { 5755 list_T *l = list_alloc(); 5756 5757 if (l == NULL) 5758 return FAIL; 5759 5760 rettv->vval.v_list = l; 5761 rettv->v_type = VAR_LIST; 5762 ++l->lv_refcount; 5763 return OK; 5764 } 5765 5766 /* 5767 * Unreference a list: decrement the reference count and free it when it 5768 * becomes zero. 5769 */ 5770 void 5771 list_unref(l) 5772 list_T *l; 5773 { 5774 if (l != NULL && --l->lv_refcount <= 0) 5775 list_free(l, TRUE); 5776 } 5777 5778 /* 5779 * Free a list, including all items it points to. 5780 * Ignores the reference count. 5781 */ 5782 void 5783 list_free(l, recurse) 5784 list_T *l; 5785 int recurse; /* Free Lists and Dictionaries recursively. */ 5786 { 5787 listitem_T *item; 5788 5789 /* Remove the list from the list of lists for garbage collection. */ 5790 if (l->lv_used_prev == NULL) 5791 first_list = l->lv_used_next; 5792 else 5793 l->lv_used_prev->lv_used_next = l->lv_used_next; 5794 if (l->lv_used_next != NULL) 5795 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5796 5797 for (item = l->lv_first; item != NULL; item = l->lv_first) 5798 { 5799 /* Remove the item before deleting it. */ 5800 l->lv_first = item->li_next; 5801 if (recurse || (item->li_tv.v_type != VAR_LIST 5802 && item->li_tv.v_type != VAR_DICT)) 5803 clear_tv(&item->li_tv); 5804 vim_free(item); 5805 } 5806 vim_free(l); 5807 } 5808 5809 /* 5810 * Allocate a list item. 5811 */ 5812 static listitem_T * 5813 listitem_alloc() 5814 { 5815 return (listitem_T *)alloc(sizeof(listitem_T)); 5816 } 5817 5818 /* 5819 * Free a list item. Also clears the value. Does not notify watchers. 5820 */ 5821 static void 5822 listitem_free(item) 5823 listitem_T *item; 5824 { 5825 clear_tv(&item->li_tv); 5826 vim_free(item); 5827 } 5828 5829 /* 5830 * Remove a list item from a List and free it. Also clears the value. 5831 */ 5832 static void 5833 listitem_remove(l, item) 5834 list_T *l; 5835 listitem_T *item; 5836 { 5837 list_remove(l, item, item); 5838 listitem_free(item); 5839 } 5840 5841 /* 5842 * Get the number of items in a list. 5843 */ 5844 static long 5845 list_len(l) 5846 list_T *l; 5847 { 5848 if (l == NULL) 5849 return 0L; 5850 return l->lv_len; 5851 } 5852 5853 /* 5854 * Return TRUE when two lists have exactly the same values. 5855 */ 5856 static int 5857 list_equal(l1, l2, ic) 5858 list_T *l1; 5859 list_T *l2; 5860 int ic; /* ignore case for strings */ 5861 { 5862 listitem_T *item1, *item2; 5863 5864 if (l1 == NULL || l2 == NULL) 5865 return FALSE; 5866 if (l1 == l2) 5867 return TRUE; 5868 if (list_len(l1) != list_len(l2)) 5869 return FALSE; 5870 5871 for (item1 = l1->lv_first, item2 = l2->lv_first; 5872 item1 != NULL && item2 != NULL; 5873 item1 = item1->li_next, item2 = item2->li_next) 5874 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5875 return FALSE; 5876 return item1 == NULL && item2 == NULL; 5877 } 5878 5879 #if defined(FEAT_RUBY) || defined(FEAT_PYTHON) || defined(FEAT_MZSCHEME) \ 5880 || defined(PROTO) 5881 /* 5882 * Return the dictitem that an entry in a hashtable points to. 5883 */ 5884 dictitem_T * 5885 dict_lookup(hi) 5886 hashitem_T *hi; 5887 { 5888 return HI2DI(hi); 5889 } 5890 #endif 5891 5892 /* 5893 * Return TRUE when two dictionaries have exactly the same key/values. 5894 */ 5895 static int 5896 dict_equal(d1, d2, ic) 5897 dict_T *d1; 5898 dict_T *d2; 5899 int ic; /* ignore case for strings */ 5900 { 5901 hashitem_T *hi; 5902 dictitem_T *item2; 5903 int todo; 5904 5905 if (d1 == NULL || d2 == NULL) 5906 return FALSE; 5907 if (d1 == d2) 5908 return TRUE; 5909 if (dict_len(d1) != dict_len(d2)) 5910 return FALSE; 5911 5912 todo = (int)d1->dv_hashtab.ht_used; 5913 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5914 { 5915 if (!HASHITEM_EMPTY(hi)) 5916 { 5917 item2 = dict_find(d2, hi->hi_key, -1); 5918 if (item2 == NULL) 5919 return FALSE; 5920 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5921 return FALSE; 5922 --todo; 5923 } 5924 } 5925 return TRUE; 5926 } 5927 5928 /* 5929 * Return TRUE if "tv1" and "tv2" have the same value. 5930 * Compares the items just like "==" would compare them, but strings and 5931 * numbers are different. Floats and numbers are also different. 5932 */ 5933 static int 5934 tv_equal(tv1, tv2, ic) 5935 typval_T *tv1; 5936 typval_T *tv2; 5937 int ic; /* ignore case */ 5938 { 5939 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5940 char_u *s1, *s2; 5941 static int recursive = 0; /* cach recursive loops */ 5942 int r; 5943 5944 if (tv1->v_type != tv2->v_type) 5945 return FALSE; 5946 /* Catch lists and dicts that have an endless loop by limiting 5947 * recursiveness to 1000. We guess they are equal then. */ 5948 if (recursive >= 1000) 5949 return TRUE; 5950 5951 switch (tv1->v_type) 5952 { 5953 case VAR_LIST: 5954 ++recursive; 5955 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5956 --recursive; 5957 return r; 5958 5959 case VAR_DICT: 5960 ++recursive; 5961 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5962 --recursive; 5963 return r; 5964 5965 case VAR_FUNC: 5966 return (tv1->vval.v_string != NULL 5967 && tv2->vval.v_string != NULL 5968 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5969 5970 case VAR_NUMBER: 5971 return tv1->vval.v_number == tv2->vval.v_number; 5972 5973 #ifdef FEAT_FLOAT 5974 case VAR_FLOAT: 5975 return tv1->vval.v_float == tv2->vval.v_float; 5976 #endif 5977 5978 case VAR_STRING: 5979 s1 = get_tv_string_buf(tv1, buf1); 5980 s2 = get_tv_string_buf(tv2, buf2); 5981 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5982 } 5983 5984 EMSG2(_(e_intern2), "tv_equal()"); 5985 return TRUE; 5986 } 5987 5988 /* 5989 * Locate item with index "n" in list "l" and return it. 5990 * A negative index is counted from the end; -1 is the last item. 5991 * Returns NULL when "n" is out of range. 5992 */ 5993 static listitem_T * 5994 list_find(l, n) 5995 list_T *l; 5996 long n; 5997 { 5998 listitem_T *item; 5999 long idx; 6000 6001 if (l == NULL) 6002 return NULL; 6003 6004 /* Negative index is relative to the end. */ 6005 if (n < 0) 6006 n = l->lv_len + n; 6007 6008 /* Check for index out of range. */ 6009 if (n < 0 || n >= l->lv_len) 6010 return NULL; 6011 6012 /* When there is a cached index may start search from there. */ 6013 if (l->lv_idx_item != NULL) 6014 { 6015 if (n < l->lv_idx / 2) 6016 { 6017 /* closest to the start of the list */ 6018 item = l->lv_first; 6019 idx = 0; 6020 } 6021 else if (n > (l->lv_idx + l->lv_len) / 2) 6022 { 6023 /* closest to the end of the list */ 6024 item = l->lv_last; 6025 idx = l->lv_len - 1; 6026 } 6027 else 6028 { 6029 /* closest to the cached index */ 6030 item = l->lv_idx_item; 6031 idx = l->lv_idx; 6032 } 6033 } 6034 else 6035 { 6036 if (n < l->lv_len / 2) 6037 { 6038 /* closest to the start of the list */ 6039 item = l->lv_first; 6040 idx = 0; 6041 } 6042 else 6043 { 6044 /* closest to the end of the list */ 6045 item = l->lv_last; 6046 idx = l->lv_len - 1; 6047 } 6048 } 6049 6050 while (n > idx) 6051 { 6052 /* search forward */ 6053 item = item->li_next; 6054 ++idx; 6055 } 6056 while (n < idx) 6057 { 6058 /* search backward */ 6059 item = item->li_prev; 6060 --idx; 6061 } 6062 6063 /* cache the used index */ 6064 l->lv_idx = idx; 6065 l->lv_idx_item = item; 6066 6067 return item; 6068 } 6069 6070 /* 6071 * Get list item "l[idx]" as a number. 6072 */ 6073 static long 6074 list_find_nr(l, idx, errorp) 6075 list_T *l; 6076 long idx; 6077 int *errorp; /* set to TRUE when something wrong */ 6078 { 6079 listitem_T *li; 6080 6081 li = list_find(l, idx); 6082 if (li == NULL) 6083 { 6084 if (errorp != NULL) 6085 *errorp = TRUE; 6086 return -1L; 6087 } 6088 return get_tv_number_chk(&li->li_tv, errorp); 6089 } 6090 6091 /* 6092 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. 6093 */ 6094 char_u * 6095 list_find_str(l, idx) 6096 list_T *l; 6097 long idx; 6098 { 6099 listitem_T *li; 6100 6101 li = list_find(l, idx - 1); 6102 if (li == NULL) 6103 { 6104 EMSGN(_(e_listidx), idx); 6105 return NULL; 6106 } 6107 return get_tv_string(&li->li_tv); 6108 } 6109 6110 /* 6111 * Locate "item" list "l" and return its index. 6112 * Returns -1 when "item" is not in the list. 6113 */ 6114 static long 6115 list_idx_of_item(l, item) 6116 list_T *l; 6117 listitem_T *item; 6118 { 6119 long idx = 0; 6120 listitem_T *li; 6121 6122 if (l == NULL) 6123 return -1; 6124 idx = 0; 6125 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 6126 ++idx; 6127 if (li == NULL) 6128 return -1; 6129 return idx; 6130 } 6131 6132 /* 6133 * Append item "item" to the end of list "l". 6134 */ 6135 static void 6136 list_append(l, item) 6137 list_T *l; 6138 listitem_T *item; 6139 { 6140 if (l->lv_last == NULL) 6141 { 6142 /* empty list */ 6143 l->lv_first = item; 6144 l->lv_last = item; 6145 item->li_prev = NULL; 6146 } 6147 else 6148 { 6149 l->lv_last->li_next = item; 6150 item->li_prev = l->lv_last; 6151 l->lv_last = item; 6152 } 6153 ++l->lv_len; 6154 item->li_next = NULL; 6155 } 6156 6157 /* 6158 * Append typval_T "tv" to the end of list "l". 6159 * Return FAIL when out of memory. 6160 */ 6161 int 6162 list_append_tv(l, tv) 6163 list_T *l; 6164 typval_T *tv; 6165 { 6166 listitem_T *li = listitem_alloc(); 6167 6168 if (li == NULL) 6169 return FAIL; 6170 copy_tv(tv, &li->li_tv); 6171 list_append(l, li); 6172 return OK; 6173 } 6174 6175 /* 6176 * Add a dictionary to a list. Used by getqflist(). 6177 * Return FAIL when out of memory. 6178 */ 6179 int 6180 list_append_dict(list, dict) 6181 list_T *list; 6182 dict_T *dict; 6183 { 6184 listitem_T *li = listitem_alloc(); 6185 6186 if (li == NULL) 6187 return FAIL; 6188 li->li_tv.v_type = VAR_DICT; 6189 li->li_tv.v_lock = 0; 6190 li->li_tv.vval.v_dict = dict; 6191 list_append(list, li); 6192 ++dict->dv_refcount; 6193 return OK; 6194 } 6195 6196 /* 6197 * Make a copy of "str" and append it as an item to list "l". 6198 * When "len" >= 0 use "str[len]". 6199 * Returns FAIL when out of memory. 6200 */ 6201 int 6202 list_append_string(l, str, len) 6203 list_T *l; 6204 char_u *str; 6205 int len; 6206 { 6207 listitem_T *li = listitem_alloc(); 6208 6209 if (li == NULL) 6210 return FAIL; 6211 list_append(l, li); 6212 li->li_tv.v_type = VAR_STRING; 6213 li->li_tv.v_lock = 0; 6214 if (str == NULL) 6215 li->li_tv.vval.v_string = NULL; 6216 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 6217 : vim_strsave(str))) == NULL) 6218 return FAIL; 6219 return OK; 6220 } 6221 6222 /* 6223 * Append "n" to list "l". 6224 * Returns FAIL when out of memory. 6225 */ 6226 static int 6227 list_append_number(l, n) 6228 list_T *l; 6229 varnumber_T n; 6230 { 6231 listitem_T *li; 6232 6233 li = listitem_alloc(); 6234 if (li == NULL) 6235 return FAIL; 6236 li->li_tv.v_type = VAR_NUMBER; 6237 li->li_tv.v_lock = 0; 6238 li->li_tv.vval.v_number = n; 6239 list_append(l, li); 6240 return OK; 6241 } 6242 6243 /* 6244 * Insert typval_T "tv" in list "l" before "item". 6245 * If "item" is NULL append at the end. 6246 * Return FAIL when out of memory. 6247 */ 6248 static int 6249 list_insert_tv(l, tv, item) 6250 list_T *l; 6251 typval_T *tv; 6252 listitem_T *item; 6253 { 6254 listitem_T *ni = listitem_alloc(); 6255 6256 if (ni == NULL) 6257 return FAIL; 6258 copy_tv(tv, &ni->li_tv); 6259 if (item == NULL) 6260 /* Append new item at end of list. */ 6261 list_append(l, ni); 6262 else 6263 { 6264 /* Insert new item before existing item. */ 6265 ni->li_prev = item->li_prev; 6266 ni->li_next = item; 6267 if (item->li_prev == NULL) 6268 { 6269 l->lv_first = ni; 6270 ++l->lv_idx; 6271 } 6272 else 6273 { 6274 item->li_prev->li_next = ni; 6275 l->lv_idx_item = NULL; 6276 } 6277 item->li_prev = ni; 6278 ++l->lv_len; 6279 } 6280 return OK; 6281 } 6282 6283 /* 6284 * Extend "l1" with "l2". 6285 * If "bef" is NULL append at the end, otherwise insert before this item. 6286 * Returns FAIL when out of memory. 6287 */ 6288 static int 6289 list_extend(l1, l2, bef) 6290 list_T *l1; 6291 list_T *l2; 6292 listitem_T *bef; 6293 { 6294 listitem_T *item; 6295 int todo = l2->lv_len; 6296 6297 /* We also quit the loop when we have inserted the original item count of 6298 * the list, avoid a hang when we extend a list with itself. */ 6299 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) 6300 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 6301 return FAIL; 6302 return OK; 6303 } 6304 6305 /* 6306 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 6307 * Return FAIL when out of memory. 6308 */ 6309 static int 6310 list_concat(l1, l2, tv) 6311 list_T *l1; 6312 list_T *l2; 6313 typval_T *tv; 6314 { 6315 list_T *l; 6316 6317 if (l1 == NULL || l2 == NULL) 6318 return FAIL; 6319 6320 /* make a copy of the first list. */ 6321 l = list_copy(l1, FALSE, 0); 6322 if (l == NULL) 6323 return FAIL; 6324 tv->v_type = VAR_LIST; 6325 tv->vval.v_list = l; 6326 6327 /* append all items from the second list */ 6328 return list_extend(l, l2, NULL); 6329 } 6330 6331 /* 6332 * Make a copy of list "orig". Shallow if "deep" is FALSE. 6333 * The refcount of the new list is set to 1. 6334 * See item_copy() for "copyID". 6335 * Returns NULL when out of memory. 6336 */ 6337 static list_T * 6338 list_copy(orig, deep, copyID) 6339 list_T *orig; 6340 int deep; 6341 int copyID; 6342 { 6343 list_T *copy; 6344 listitem_T *item; 6345 listitem_T *ni; 6346 6347 if (orig == NULL) 6348 return NULL; 6349 6350 copy = list_alloc(); 6351 if (copy != NULL) 6352 { 6353 if (copyID != 0) 6354 { 6355 /* Do this before adding the items, because one of the items may 6356 * refer back to this list. */ 6357 orig->lv_copyID = copyID; 6358 orig->lv_copylist = copy; 6359 } 6360 for (item = orig->lv_first; item != NULL && !got_int; 6361 item = item->li_next) 6362 { 6363 ni = listitem_alloc(); 6364 if (ni == NULL) 6365 break; 6366 if (deep) 6367 { 6368 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 6369 { 6370 vim_free(ni); 6371 break; 6372 } 6373 } 6374 else 6375 copy_tv(&item->li_tv, &ni->li_tv); 6376 list_append(copy, ni); 6377 } 6378 ++copy->lv_refcount; 6379 if (item != NULL) 6380 { 6381 list_unref(copy); 6382 copy = NULL; 6383 } 6384 } 6385 6386 return copy; 6387 } 6388 6389 /* 6390 * Remove items "item" to "item2" from list "l". 6391 * Does not free the listitem or the value! 6392 */ 6393 static void 6394 list_remove(l, item, item2) 6395 list_T *l; 6396 listitem_T *item; 6397 listitem_T *item2; 6398 { 6399 listitem_T *ip; 6400 6401 /* notify watchers */ 6402 for (ip = item; ip != NULL; ip = ip->li_next) 6403 { 6404 --l->lv_len; 6405 list_fix_watch(l, ip); 6406 if (ip == item2) 6407 break; 6408 } 6409 6410 if (item2->li_next == NULL) 6411 l->lv_last = item->li_prev; 6412 else 6413 item2->li_next->li_prev = item->li_prev; 6414 if (item->li_prev == NULL) 6415 l->lv_first = item2->li_next; 6416 else 6417 item->li_prev->li_next = item2->li_next; 6418 l->lv_idx_item = NULL; 6419 } 6420 6421 /* 6422 * Return an allocated string with the string representation of a list. 6423 * May return NULL. 6424 */ 6425 static char_u * 6426 list2string(tv, copyID) 6427 typval_T *tv; 6428 int copyID; 6429 { 6430 garray_T ga; 6431 6432 if (tv->vval.v_list == NULL) 6433 return NULL; 6434 ga_init2(&ga, (int)sizeof(char), 80); 6435 ga_append(&ga, '['); 6436 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 6437 { 6438 vim_free(ga.ga_data); 6439 return NULL; 6440 } 6441 ga_append(&ga, ']'); 6442 ga_append(&ga, NUL); 6443 return (char_u *)ga.ga_data; 6444 } 6445 6446 /* 6447 * Join list "l" into a string in "*gap", using separator "sep". 6448 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 6449 * Return FAIL or OK. 6450 */ 6451 static int 6452 list_join(gap, l, sep, echo, copyID) 6453 garray_T *gap; 6454 list_T *l; 6455 char_u *sep; 6456 int echo; 6457 int copyID; 6458 { 6459 int first = TRUE; 6460 char_u *tofree; 6461 char_u numbuf[NUMBUFLEN]; 6462 listitem_T *item; 6463 char_u *s; 6464 6465 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 6466 { 6467 if (first) 6468 first = FALSE; 6469 else 6470 ga_concat(gap, sep); 6471 6472 if (echo) 6473 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6474 else 6475 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6476 if (s != NULL) 6477 ga_concat(gap, s); 6478 vim_free(tofree); 6479 if (s == NULL) 6480 return FAIL; 6481 line_breakcheck(); 6482 } 6483 return OK; 6484 } 6485 6486 /* 6487 * Garbage collection for lists and dictionaries. 6488 * 6489 * We use reference counts to be able to free most items right away when they 6490 * are no longer used. But for composite items it's possible that it becomes 6491 * unused while the reference count is > 0: When there is a recursive 6492 * reference. Example: 6493 * :let l = [1, 2, 3] 6494 * :let d = {9: l} 6495 * :let l[1] = d 6496 * 6497 * Since this is quite unusual we handle this with garbage collection: every 6498 * once in a while find out which lists and dicts are not referenced from any 6499 * variable. 6500 * 6501 * Here is a good reference text about garbage collection (refers to Python 6502 * but it applies to all reference-counting mechanisms): 6503 * http://python.ca/nas/python/gc/ 6504 */ 6505 6506 /* 6507 * Do garbage collection for lists and dicts. 6508 * Return TRUE if some memory was freed. 6509 */ 6510 int 6511 garbage_collect() 6512 { 6513 int copyID; 6514 buf_T *buf; 6515 win_T *wp; 6516 int i; 6517 funccall_T *fc, **pfc; 6518 int did_free; 6519 int did_free_funccal = FALSE; 6520 #ifdef FEAT_WINDOWS 6521 tabpage_T *tp; 6522 #endif 6523 6524 /* Only do this once. */ 6525 want_garbage_collect = FALSE; 6526 may_garbage_collect = FALSE; 6527 garbage_collect_at_exit = FALSE; 6528 6529 /* We advance by two because we add one for items referenced through 6530 * previous_funccal. */ 6531 current_copyID += COPYID_INC; 6532 copyID = current_copyID; 6533 6534 /* 6535 * 1. Go through all accessible variables and mark all lists and dicts 6536 * with copyID. 6537 */ 6538 6539 /* Don't free variables in the previous_funccal list unless they are only 6540 * referenced through previous_funccal. This must be first, because if 6541 * the item is referenced elsewhere the funccal must not be freed. */ 6542 for (fc = previous_funccal; fc != NULL; fc = fc->caller) 6543 { 6544 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1); 6545 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1); 6546 } 6547 6548 /* script-local variables */ 6549 for (i = 1; i <= ga_scripts.ga_len; ++i) 6550 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 6551 6552 /* buffer-local variables */ 6553 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6554 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 6555 6556 /* window-local variables */ 6557 FOR_ALL_TAB_WINDOWS(tp, wp) 6558 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 6559 6560 #ifdef FEAT_WINDOWS 6561 /* tabpage-local variables */ 6562 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6563 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); 6564 #endif 6565 6566 /* global variables */ 6567 set_ref_in_ht(&globvarht, copyID); 6568 6569 /* function-local variables */ 6570 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6571 { 6572 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 6573 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 6574 } 6575 6576 /* v: vars */ 6577 set_ref_in_ht(&vimvarht, copyID); 6578 6579 /* 6580 * 2. Free lists and dictionaries that are not referenced. 6581 */ 6582 did_free = free_unref_items(copyID); 6583 6584 /* 6585 * 3. Check if any funccal can be freed now. 6586 */ 6587 for (pfc = &previous_funccal; *pfc != NULL; ) 6588 { 6589 if (can_free_funccal(*pfc, copyID)) 6590 { 6591 fc = *pfc; 6592 *pfc = fc->caller; 6593 free_funccal(fc, TRUE); 6594 did_free = TRUE; 6595 did_free_funccal = TRUE; 6596 } 6597 else 6598 pfc = &(*pfc)->caller; 6599 } 6600 if (did_free_funccal) 6601 /* When a funccal was freed some more items might be garbage 6602 * collected, so run again. */ 6603 (void)garbage_collect(); 6604 6605 return did_free; 6606 } 6607 6608 /* 6609 * Free lists and dictionaries that are no longer referenced. 6610 */ 6611 static int 6612 free_unref_items(copyID) 6613 int copyID; 6614 { 6615 dict_T *dd; 6616 list_T *ll; 6617 int did_free = FALSE; 6618 6619 /* 6620 * Go through the list of dicts and free items without the copyID. 6621 */ 6622 for (dd = first_dict; dd != NULL; ) 6623 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) 6624 { 6625 /* Free the Dictionary and ordinary items it contains, but don't 6626 * recurse into Lists and Dictionaries, they will be in the list 6627 * of dicts or list of lists. */ 6628 dict_free(dd, FALSE); 6629 did_free = TRUE; 6630 6631 /* restart, next dict may also have been freed */ 6632 dd = first_dict; 6633 } 6634 else 6635 dd = dd->dv_used_next; 6636 6637 /* 6638 * Go through the list of lists and free items without the copyID. 6639 * But don't free a list that has a watcher (used in a for loop), these 6640 * are not referenced anywhere. 6641 */ 6642 for (ll = first_list; ll != NULL; ) 6643 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 6644 && ll->lv_watch == NULL) 6645 { 6646 /* Free the List and ordinary items it contains, but don't recurse 6647 * into Lists and Dictionaries, they will be in the list of dicts 6648 * or list of lists. */ 6649 list_free(ll, FALSE); 6650 did_free = TRUE; 6651 6652 /* restart, next list may also have been freed */ 6653 ll = first_list; 6654 } 6655 else 6656 ll = ll->lv_used_next; 6657 6658 return did_free; 6659 } 6660 6661 /* 6662 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6663 */ 6664 static void 6665 set_ref_in_ht(ht, copyID) 6666 hashtab_T *ht; 6667 int copyID; 6668 { 6669 int todo; 6670 hashitem_T *hi; 6671 6672 todo = (int)ht->ht_used; 6673 for (hi = ht->ht_array; todo > 0; ++hi) 6674 if (!HASHITEM_EMPTY(hi)) 6675 { 6676 --todo; 6677 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 6678 } 6679 } 6680 6681 /* 6682 * Mark all lists and dicts referenced through list "l" with "copyID". 6683 */ 6684 static void 6685 set_ref_in_list(l, copyID) 6686 list_T *l; 6687 int copyID; 6688 { 6689 listitem_T *li; 6690 6691 for (li = l->lv_first; li != NULL; li = li->li_next) 6692 set_ref_in_item(&li->li_tv, copyID); 6693 } 6694 6695 /* 6696 * Mark all lists and dicts referenced through typval "tv" with "copyID". 6697 */ 6698 static void 6699 set_ref_in_item(tv, copyID) 6700 typval_T *tv; 6701 int copyID; 6702 { 6703 dict_T *dd; 6704 list_T *ll; 6705 6706 switch (tv->v_type) 6707 { 6708 case VAR_DICT: 6709 dd = tv->vval.v_dict; 6710 if (dd != NULL && dd->dv_copyID != copyID) 6711 { 6712 /* Didn't see this dict yet. */ 6713 dd->dv_copyID = copyID; 6714 set_ref_in_ht(&dd->dv_hashtab, copyID); 6715 } 6716 break; 6717 6718 case VAR_LIST: 6719 ll = tv->vval.v_list; 6720 if (ll != NULL && ll->lv_copyID != copyID) 6721 { 6722 /* Didn't see this list yet. */ 6723 ll->lv_copyID = copyID; 6724 set_ref_in_list(ll, copyID); 6725 } 6726 break; 6727 } 6728 return; 6729 } 6730 6731 /* 6732 * Allocate an empty header for a dictionary. 6733 */ 6734 dict_T * 6735 dict_alloc() 6736 { 6737 dict_T *d; 6738 6739 d = (dict_T *)alloc(sizeof(dict_T)); 6740 if (d != NULL) 6741 { 6742 /* Add the list to the list of dicts for garbage collection. */ 6743 if (first_dict != NULL) 6744 first_dict->dv_used_prev = d; 6745 d->dv_used_next = first_dict; 6746 d->dv_used_prev = NULL; 6747 first_dict = d; 6748 6749 hash_init(&d->dv_hashtab); 6750 d->dv_lock = 0; 6751 d->dv_refcount = 0; 6752 d->dv_copyID = 0; 6753 } 6754 return d; 6755 } 6756 6757 /* 6758 * Unreference a Dictionary: decrement the reference count and free it when it 6759 * becomes zero. 6760 */ 6761 static void 6762 dict_unref(d) 6763 dict_T *d; 6764 { 6765 if (d != NULL && --d->dv_refcount <= 0) 6766 dict_free(d, TRUE); 6767 } 6768 6769 /* 6770 * Free a Dictionary, including all items it contains. 6771 * Ignores the reference count. 6772 */ 6773 static void 6774 dict_free(d, recurse) 6775 dict_T *d; 6776 int recurse; /* Free Lists and Dictionaries recursively. */ 6777 { 6778 int todo; 6779 hashitem_T *hi; 6780 dictitem_T *di; 6781 6782 /* Remove the dict from the list of dicts for garbage collection. */ 6783 if (d->dv_used_prev == NULL) 6784 first_dict = d->dv_used_next; 6785 else 6786 d->dv_used_prev->dv_used_next = d->dv_used_next; 6787 if (d->dv_used_next != NULL) 6788 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6789 6790 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6791 hash_lock(&d->dv_hashtab); 6792 todo = (int)d->dv_hashtab.ht_used; 6793 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6794 { 6795 if (!HASHITEM_EMPTY(hi)) 6796 { 6797 /* Remove the item before deleting it, just in case there is 6798 * something recursive causing trouble. */ 6799 di = HI2DI(hi); 6800 hash_remove(&d->dv_hashtab, hi); 6801 if (recurse || (di->di_tv.v_type != VAR_LIST 6802 && di->di_tv.v_type != VAR_DICT)) 6803 clear_tv(&di->di_tv); 6804 vim_free(di); 6805 --todo; 6806 } 6807 } 6808 hash_clear(&d->dv_hashtab); 6809 vim_free(d); 6810 } 6811 6812 /* 6813 * Allocate a Dictionary item. 6814 * The "key" is copied to the new item. 6815 * Note that the value of the item "di_tv" still needs to be initialized! 6816 * Returns NULL when out of memory. 6817 */ 6818 dictitem_T * 6819 dictitem_alloc(key) 6820 char_u *key; 6821 { 6822 dictitem_T *di; 6823 6824 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 6825 if (di != NULL) 6826 { 6827 STRCPY(di->di_key, key); 6828 di->di_flags = 0; 6829 } 6830 return di; 6831 } 6832 6833 /* 6834 * Make a copy of a Dictionary item. 6835 */ 6836 static dictitem_T * 6837 dictitem_copy(org) 6838 dictitem_T *org; 6839 { 6840 dictitem_T *di; 6841 6842 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 6843 + STRLEN(org->di_key))); 6844 if (di != NULL) 6845 { 6846 STRCPY(di->di_key, org->di_key); 6847 di->di_flags = 0; 6848 copy_tv(&org->di_tv, &di->di_tv); 6849 } 6850 return di; 6851 } 6852 6853 /* 6854 * Remove item "item" from Dictionary "dict" and free it. 6855 */ 6856 static void 6857 dictitem_remove(dict, item) 6858 dict_T *dict; 6859 dictitem_T *item; 6860 { 6861 hashitem_T *hi; 6862 6863 hi = hash_find(&dict->dv_hashtab, item->di_key); 6864 if (HASHITEM_EMPTY(hi)) 6865 EMSG2(_(e_intern2), "dictitem_remove()"); 6866 else 6867 hash_remove(&dict->dv_hashtab, hi); 6868 dictitem_free(item); 6869 } 6870 6871 /* 6872 * Free a dict item. Also clears the value. 6873 */ 6874 void 6875 dictitem_free(item) 6876 dictitem_T *item; 6877 { 6878 clear_tv(&item->di_tv); 6879 vim_free(item); 6880 } 6881 6882 /* 6883 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6884 * The refcount of the new dict is set to 1. 6885 * See item_copy() for "copyID". 6886 * Returns NULL when out of memory. 6887 */ 6888 static dict_T * 6889 dict_copy(orig, deep, copyID) 6890 dict_T *orig; 6891 int deep; 6892 int copyID; 6893 { 6894 dict_T *copy; 6895 dictitem_T *di; 6896 int todo; 6897 hashitem_T *hi; 6898 6899 if (orig == NULL) 6900 return NULL; 6901 6902 copy = dict_alloc(); 6903 if (copy != NULL) 6904 { 6905 if (copyID != 0) 6906 { 6907 orig->dv_copyID = copyID; 6908 orig->dv_copydict = copy; 6909 } 6910 todo = (int)orig->dv_hashtab.ht_used; 6911 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6912 { 6913 if (!HASHITEM_EMPTY(hi)) 6914 { 6915 --todo; 6916 6917 di = dictitem_alloc(hi->hi_key); 6918 if (di == NULL) 6919 break; 6920 if (deep) 6921 { 6922 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6923 copyID) == FAIL) 6924 { 6925 vim_free(di); 6926 break; 6927 } 6928 } 6929 else 6930 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6931 if (dict_add(copy, di) == FAIL) 6932 { 6933 dictitem_free(di); 6934 break; 6935 } 6936 } 6937 } 6938 6939 ++copy->dv_refcount; 6940 if (todo > 0) 6941 { 6942 dict_unref(copy); 6943 copy = NULL; 6944 } 6945 } 6946 6947 return copy; 6948 } 6949 6950 /* 6951 * Add item "item" to Dictionary "d". 6952 * Returns FAIL when out of memory and when key already existed. 6953 */ 6954 int 6955 dict_add(d, item) 6956 dict_T *d; 6957 dictitem_T *item; 6958 { 6959 return hash_add(&d->dv_hashtab, item->di_key); 6960 } 6961 6962 /* 6963 * Add a number or string entry to dictionary "d". 6964 * When "str" is NULL use number "nr", otherwise use "str". 6965 * Returns FAIL when out of memory and when key already exists. 6966 */ 6967 int 6968 dict_add_nr_str(d, key, nr, str) 6969 dict_T *d; 6970 char *key; 6971 long nr; 6972 char_u *str; 6973 { 6974 dictitem_T *item; 6975 6976 item = dictitem_alloc((char_u *)key); 6977 if (item == NULL) 6978 return FAIL; 6979 item->di_tv.v_lock = 0; 6980 if (str == NULL) 6981 { 6982 item->di_tv.v_type = VAR_NUMBER; 6983 item->di_tv.vval.v_number = nr; 6984 } 6985 else 6986 { 6987 item->di_tv.v_type = VAR_STRING; 6988 item->di_tv.vval.v_string = vim_strsave(str); 6989 } 6990 if (dict_add(d, item) == FAIL) 6991 { 6992 dictitem_free(item); 6993 return FAIL; 6994 } 6995 return OK; 6996 } 6997 6998 /* 6999 * Get the number of items in a Dictionary. 7000 */ 7001 static long 7002 dict_len(d) 7003 dict_T *d; 7004 { 7005 if (d == NULL) 7006 return 0L; 7007 return (long)d->dv_hashtab.ht_used; 7008 } 7009 7010 /* 7011 * Find item "key[len]" in Dictionary "d". 7012 * If "len" is negative use strlen(key). 7013 * Returns NULL when not found. 7014 */ 7015 static dictitem_T * 7016 dict_find(d, key, len) 7017 dict_T *d; 7018 char_u *key; 7019 int len; 7020 { 7021 #define AKEYLEN 200 7022 char_u buf[AKEYLEN]; 7023 char_u *akey; 7024 char_u *tofree = NULL; 7025 hashitem_T *hi; 7026 7027 if (len < 0) 7028 akey = key; 7029 else if (len >= AKEYLEN) 7030 { 7031 tofree = akey = vim_strnsave(key, len); 7032 if (akey == NULL) 7033 return NULL; 7034 } 7035 else 7036 { 7037 /* Avoid a malloc/free by using buf[]. */ 7038 vim_strncpy(buf, key, len); 7039 akey = buf; 7040 } 7041 7042 hi = hash_find(&d->dv_hashtab, akey); 7043 vim_free(tofree); 7044 if (HASHITEM_EMPTY(hi)) 7045 return NULL; 7046 return HI2DI(hi); 7047 } 7048 7049 /* 7050 * Get a string item from a dictionary. 7051 * When "save" is TRUE allocate memory for it. 7052 * Returns NULL if the entry doesn't exist or out of memory. 7053 */ 7054 char_u * 7055 get_dict_string(d, key, save) 7056 dict_T *d; 7057 char_u *key; 7058 int save; 7059 { 7060 dictitem_T *di; 7061 char_u *s; 7062 7063 di = dict_find(d, key, -1); 7064 if (di == NULL) 7065 return NULL; 7066 s = get_tv_string(&di->di_tv); 7067 if (save && s != NULL) 7068 s = vim_strsave(s); 7069 return s; 7070 } 7071 7072 /* 7073 * Get a number item from a dictionary. 7074 * Returns 0 if the entry doesn't exist or out of memory. 7075 */ 7076 long 7077 get_dict_number(d, key) 7078 dict_T *d; 7079 char_u *key; 7080 { 7081 dictitem_T *di; 7082 7083 di = dict_find(d, key, -1); 7084 if (di == NULL) 7085 return 0; 7086 return get_tv_number(&di->di_tv); 7087 } 7088 7089 /* 7090 * Return an allocated string with the string representation of a Dictionary. 7091 * May return NULL. 7092 */ 7093 static char_u * 7094 dict2string(tv, copyID) 7095 typval_T *tv; 7096 int copyID; 7097 { 7098 garray_T ga; 7099 int first = TRUE; 7100 char_u *tofree; 7101 char_u numbuf[NUMBUFLEN]; 7102 hashitem_T *hi; 7103 char_u *s; 7104 dict_T *d; 7105 int todo; 7106 7107 if ((d = tv->vval.v_dict) == NULL) 7108 return NULL; 7109 ga_init2(&ga, (int)sizeof(char), 80); 7110 ga_append(&ga, '{'); 7111 7112 todo = (int)d->dv_hashtab.ht_used; 7113 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7114 { 7115 if (!HASHITEM_EMPTY(hi)) 7116 { 7117 --todo; 7118 7119 if (first) 7120 first = FALSE; 7121 else 7122 ga_concat(&ga, (char_u *)", "); 7123 7124 tofree = string_quote(hi->hi_key, FALSE); 7125 if (tofree != NULL) 7126 { 7127 ga_concat(&ga, tofree); 7128 vim_free(tofree); 7129 } 7130 ga_concat(&ga, (char_u *)": "); 7131 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 7132 if (s != NULL) 7133 ga_concat(&ga, s); 7134 vim_free(tofree); 7135 if (s == NULL) 7136 break; 7137 } 7138 } 7139 if (todo > 0) 7140 { 7141 vim_free(ga.ga_data); 7142 return NULL; 7143 } 7144 7145 ga_append(&ga, '}'); 7146 ga_append(&ga, NUL); 7147 return (char_u *)ga.ga_data; 7148 } 7149 7150 /* 7151 * Allocate a variable for a Dictionary and fill it from "*arg". 7152 * Return OK or FAIL. Returns NOTDONE for {expr}. 7153 */ 7154 static int 7155 get_dict_tv(arg, rettv, evaluate) 7156 char_u **arg; 7157 typval_T *rettv; 7158 int evaluate; 7159 { 7160 dict_T *d = NULL; 7161 typval_T tvkey; 7162 typval_T tv; 7163 char_u *key = NULL; 7164 dictitem_T *item; 7165 char_u *start = skipwhite(*arg + 1); 7166 char_u buf[NUMBUFLEN]; 7167 7168 /* 7169 * First check if it's not a curly-braces thing: {expr}. 7170 * Must do this without evaluating, otherwise a function may be called 7171 * twice. Unfortunately this means we need to call eval1() twice for the 7172 * first item. 7173 * But {} is an empty Dictionary. 7174 */ 7175 if (*start != '}') 7176 { 7177 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 7178 return FAIL; 7179 if (*start == '}') 7180 return NOTDONE; 7181 } 7182 7183 if (evaluate) 7184 { 7185 d = dict_alloc(); 7186 if (d == NULL) 7187 return FAIL; 7188 } 7189 tvkey.v_type = VAR_UNKNOWN; 7190 tv.v_type = VAR_UNKNOWN; 7191 7192 *arg = skipwhite(*arg + 1); 7193 while (**arg != '}' && **arg != NUL) 7194 { 7195 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 7196 goto failret; 7197 if (**arg != ':') 7198 { 7199 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 7200 clear_tv(&tvkey); 7201 goto failret; 7202 } 7203 if (evaluate) 7204 { 7205 key = get_tv_string_buf_chk(&tvkey, buf); 7206 if (key == NULL || *key == NUL) 7207 { 7208 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 7209 if (key != NULL) 7210 EMSG(_(e_emptykey)); 7211 clear_tv(&tvkey); 7212 goto failret; 7213 } 7214 } 7215 7216 *arg = skipwhite(*arg + 1); 7217 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 7218 { 7219 if (evaluate) 7220 clear_tv(&tvkey); 7221 goto failret; 7222 } 7223 if (evaluate) 7224 { 7225 item = dict_find(d, key, -1); 7226 if (item != NULL) 7227 { 7228 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 7229 clear_tv(&tvkey); 7230 clear_tv(&tv); 7231 goto failret; 7232 } 7233 item = dictitem_alloc(key); 7234 clear_tv(&tvkey); 7235 if (item != NULL) 7236 { 7237 item->di_tv = tv; 7238 item->di_tv.v_lock = 0; 7239 if (dict_add(d, item) == FAIL) 7240 dictitem_free(item); 7241 } 7242 } 7243 7244 if (**arg == '}') 7245 break; 7246 if (**arg != ',') 7247 { 7248 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 7249 goto failret; 7250 } 7251 *arg = skipwhite(*arg + 1); 7252 } 7253 7254 if (**arg != '}') 7255 { 7256 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 7257 failret: 7258 if (evaluate) 7259 dict_free(d, TRUE); 7260 return FAIL; 7261 } 7262 7263 *arg = skipwhite(*arg + 1); 7264 if (evaluate) 7265 { 7266 rettv->v_type = VAR_DICT; 7267 rettv->vval.v_dict = d; 7268 ++d->dv_refcount; 7269 } 7270 7271 return OK; 7272 } 7273 7274 /* 7275 * Return a string with the string representation of a variable. 7276 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7277 * "numbuf" is used for a number. 7278 * Does not put quotes around strings, as ":echo" displays values. 7279 * When "copyID" is not NULL replace recursive lists and dicts with "...". 7280 * May return NULL. 7281 */ 7282 static char_u * 7283 echo_string(tv, tofree, numbuf, copyID) 7284 typval_T *tv; 7285 char_u **tofree; 7286 char_u *numbuf; 7287 int copyID; 7288 { 7289 static int recurse = 0; 7290 char_u *r = NULL; 7291 7292 if (recurse >= DICT_MAXNEST) 7293 { 7294 EMSG(_("E724: variable nested too deep for displaying")); 7295 *tofree = NULL; 7296 return NULL; 7297 } 7298 ++recurse; 7299 7300 switch (tv->v_type) 7301 { 7302 case VAR_FUNC: 7303 *tofree = NULL; 7304 r = tv->vval.v_string; 7305 break; 7306 7307 case VAR_LIST: 7308 if (tv->vval.v_list == NULL) 7309 { 7310 *tofree = NULL; 7311 r = NULL; 7312 } 7313 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 7314 { 7315 *tofree = NULL; 7316 r = (char_u *)"[...]"; 7317 } 7318 else 7319 { 7320 tv->vval.v_list->lv_copyID = copyID; 7321 *tofree = list2string(tv, copyID); 7322 r = *tofree; 7323 } 7324 break; 7325 7326 case VAR_DICT: 7327 if (tv->vval.v_dict == NULL) 7328 { 7329 *tofree = NULL; 7330 r = NULL; 7331 } 7332 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 7333 { 7334 *tofree = NULL; 7335 r = (char_u *)"{...}"; 7336 } 7337 else 7338 { 7339 tv->vval.v_dict->dv_copyID = copyID; 7340 *tofree = dict2string(tv, copyID); 7341 r = *tofree; 7342 } 7343 break; 7344 7345 case VAR_STRING: 7346 case VAR_NUMBER: 7347 *tofree = NULL; 7348 r = get_tv_string_buf(tv, numbuf); 7349 break; 7350 7351 #ifdef FEAT_FLOAT 7352 case VAR_FLOAT: 7353 *tofree = NULL; 7354 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float); 7355 r = numbuf; 7356 break; 7357 #endif 7358 7359 default: 7360 EMSG2(_(e_intern2), "echo_string()"); 7361 *tofree = NULL; 7362 } 7363 7364 --recurse; 7365 return r; 7366 } 7367 7368 /* 7369 * Return a string with the string representation of a variable. 7370 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7371 * "numbuf" is used for a number. 7372 * Puts quotes around strings, so that they can be parsed back by eval(). 7373 * May return NULL. 7374 */ 7375 static char_u * 7376 tv2string(tv, tofree, numbuf, copyID) 7377 typval_T *tv; 7378 char_u **tofree; 7379 char_u *numbuf; 7380 int copyID; 7381 { 7382 switch (tv->v_type) 7383 { 7384 case VAR_FUNC: 7385 *tofree = string_quote(tv->vval.v_string, TRUE); 7386 return *tofree; 7387 case VAR_STRING: 7388 *tofree = string_quote(tv->vval.v_string, FALSE); 7389 return *tofree; 7390 #ifdef FEAT_FLOAT 7391 case VAR_FLOAT: 7392 *tofree = NULL; 7393 vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); 7394 return numbuf; 7395 #endif 7396 case VAR_NUMBER: 7397 case VAR_LIST: 7398 case VAR_DICT: 7399 break; 7400 default: 7401 EMSG2(_(e_intern2), "tv2string()"); 7402 } 7403 return echo_string(tv, tofree, numbuf, copyID); 7404 } 7405 7406 /* 7407 * Return string "str" in ' quotes, doubling ' characters. 7408 * If "str" is NULL an empty string is assumed. 7409 * If "function" is TRUE make it function('string'). 7410 */ 7411 static char_u * 7412 string_quote(str, function) 7413 char_u *str; 7414 int function; 7415 { 7416 unsigned len; 7417 char_u *p, *r, *s; 7418 7419 len = (function ? 13 : 3); 7420 if (str != NULL) 7421 { 7422 len += (unsigned)STRLEN(str); 7423 for (p = str; *p != NUL; mb_ptr_adv(p)) 7424 if (*p == '\'') 7425 ++len; 7426 } 7427 s = r = alloc(len); 7428 if (r != NULL) 7429 { 7430 if (function) 7431 { 7432 STRCPY(r, "function('"); 7433 r += 10; 7434 } 7435 else 7436 *r++ = '\''; 7437 if (str != NULL) 7438 for (p = str; *p != NUL; ) 7439 { 7440 if (*p == '\'') 7441 *r++ = '\''; 7442 MB_COPY_CHAR(p, r); 7443 } 7444 *r++ = '\''; 7445 if (function) 7446 *r++ = ')'; 7447 *r++ = NUL; 7448 } 7449 return s; 7450 } 7451 7452 #ifdef FEAT_FLOAT 7453 /* 7454 * Convert the string "text" to a floating point number. 7455 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure 7456 * this always uses a decimal point. 7457 * Returns the length of the text that was consumed. 7458 */ 7459 static int 7460 string2float(text, value) 7461 char_u *text; 7462 float_T *value; /* result stored here */ 7463 { 7464 char *s = (char *)text; 7465 float_T f; 7466 7467 f = strtod(s, &s); 7468 *value = f; 7469 return (int)((char_u *)s - text); 7470 } 7471 #endif 7472 7473 /* 7474 * Get the value of an environment variable. 7475 * "arg" is pointing to the '$'. It is advanced to after the name. 7476 * If the environment variable was not set, silently assume it is empty. 7477 * Always return OK. 7478 */ 7479 static int 7480 get_env_tv(arg, rettv, evaluate) 7481 char_u **arg; 7482 typval_T *rettv; 7483 int evaluate; 7484 { 7485 char_u *string = NULL; 7486 int len; 7487 int cc; 7488 char_u *name; 7489 int mustfree = FALSE; 7490 7491 ++*arg; 7492 name = *arg; 7493 len = get_env_len(arg); 7494 if (evaluate) 7495 { 7496 if (len != 0) 7497 { 7498 cc = name[len]; 7499 name[len] = NUL; 7500 /* first try vim_getenv(), fast for normal environment vars */ 7501 string = vim_getenv(name, &mustfree); 7502 if (string != NULL && *string != NUL) 7503 { 7504 if (!mustfree) 7505 string = vim_strsave(string); 7506 } 7507 else 7508 { 7509 if (mustfree) 7510 vim_free(string); 7511 7512 /* next try expanding things like $VIM and ${HOME} */ 7513 string = expand_env_save(name - 1); 7514 if (string != NULL && *string == '$') 7515 { 7516 vim_free(string); 7517 string = NULL; 7518 } 7519 } 7520 name[len] = cc; 7521 } 7522 rettv->v_type = VAR_STRING; 7523 rettv->vval.v_string = string; 7524 } 7525 7526 return OK; 7527 } 7528 7529 /* 7530 * Array with names and number of arguments of all internal functions 7531 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 7532 */ 7533 static struct fst 7534 { 7535 char *f_name; /* function name */ 7536 char f_min_argc; /* minimal number of arguments */ 7537 char f_max_argc; /* maximal number of arguments */ 7538 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 7539 /* implementation of function */ 7540 } functions[] = 7541 { 7542 #ifdef FEAT_FLOAT 7543 {"abs", 1, 1, f_abs}, 7544 #endif 7545 {"add", 2, 2, f_add}, 7546 {"append", 2, 2, f_append}, 7547 {"argc", 0, 0, f_argc}, 7548 {"argidx", 0, 0, f_argidx}, 7549 {"argv", 0, 1, f_argv}, 7550 #ifdef FEAT_FLOAT 7551 {"atan", 1, 1, f_atan}, 7552 #endif 7553 {"browse", 4, 4, f_browse}, 7554 {"browsedir", 2, 2, f_browsedir}, 7555 {"bufexists", 1, 1, f_bufexists}, 7556 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 7557 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 7558 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 7559 {"buflisted", 1, 1, f_buflisted}, 7560 {"bufloaded", 1, 1, f_bufloaded}, 7561 {"bufname", 1, 1, f_bufname}, 7562 {"bufnr", 1, 2, f_bufnr}, 7563 {"bufwinnr", 1, 1, f_bufwinnr}, 7564 {"byte2line", 1, 1, f_byte2line}, 7565 {"byteidx", 2, 2, f_byteidx}, 7566 {"call", 2, 3, f_call}, 7567 #ifdef FEAT_FLOAT 7568 {"ceil", 1, 1, f_ceil}, 7569 #endif 7570 {"changenr", 0, 0, f_changenr}, 7571 {"char2nr", 1, 1, f_char2nr}, 7572 {"cindent", 1, 1, f_cindent}, 7573 {"clearmatches", 0, 0, f_clearmatches}, 7574 {"col", 1, 1, f_col}, 7575 #if defined(FEAT_INS_EXPAND) 7576 {"complete", 2, 2, f_complete}, 7577 {"complete_add", 1, 1, f_complete_add}, 7578 {"complete_check", 0, 0, f_complete_check}, 7579 #endif 7580 {"confirm", 1, 4, f_confirm}, 7581 {"copy", 1, 1, f_copy}, 7582 #ifdef FEAT_FLOAT 7583 {"cos", 1, 1, f_cos}, 7584 #endif 7585 {"count", 2, 4, f_count}, 7586 {"cscope_connection",0,3, f_cscope_connection}, 7587 {"cursor", 1, 3, f_cursor}, 7588 {"deepcopy", 1, 2, f_deepcopy}, 7589 {"delete", 1, 1, f_delete}, 7590 {"did_filetype", 0, 0, f_did_filetype}, 7591 {"diff_filler", 1, 1, f_diff_filler}, 7592 {"diff_hlID", 2, 2, f_diff_hlID}, 7593 {"empty", 1, 1, f_empty}, 7594 {"escape", 2, 2, f_escape}, 7595 {"eval", 1, 1, f_eval}, 7596 {"eventhandler", 0, 0, f_eventhandler}, 7597 {"executable", 1, 1, f_executable}, 7598 {"exists", 1, 1, f_exists}, 7599 {"expand", 1, 2, f_expand}, 7600 {"extend", 2, 3, f_extend}, 7601 {"feedkeys", 1, 2, f_feedkeys}, 7602 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 7603 {"filereadable", 1, 1, f_filereadable}, 7604 {"filewritable", 1, 1, f_filewritable}, 7605 {"filter", 2, 2, f_filter}, 7606 {"finddir", 1, 3, f_finddir}, 7607 {"findfile", 1, 3, f_findfile}, 7608 #ifdef FEAT_FLOAT 7609 {"float2nr", 1, 1, f_float2nr}, 7610 {"floor", 1, 1, f_floor}, 7611 #endif 7612 {"fnameescape", 1, 1, f_fnameescape}, 7613 {"fnamemodify", 2, 2, f_fnamemodify}, 7614 {"foldclosed", 1, 1, f_foldclosed}, 7615 {"foldclosedend", 1, 1, f_foldclosedend}, 7616 {"foldlevel", 1, 1, f_foldlevel}, 7617 {"foldtext", 0, 0, f_foldtext}, 7618 {"foldtextresult", 1, 1, f_foldtextresult}, 7619 {"foreground", 0, 0, f_foreground}, 7620 {"function", 1, 1, f_function}, 7621 {"garbagecollect", 0, 1, f_garbagecollect}, 7622 {"get", 2, 3, f_get}, 7623 {"getbufline", 2, 3, f_getbufline}, 7624 {"getbufvar", 2, 2, f_getbufvar}, 7625 {"getchar", 0, 1, f_getchar}, 7626 {"getcharmod", 0, 0, f_getcharmod}, 7627 {"getcmdline", 0, 0, f_getcmdline}, 7628 {"getcmdpos", 0, 0, f_getcmdpos}, 7629 {"getcmdtype", 0, 0, f_getcmdtype}, 7630 {"getcwd", 0, 0, f_getcwd}, 7631 {"getfontname", 0, 1, f_getfontname}, 7632 {"getfperm", 1, 1, f_getfperm}, 7633 {"getfsize", 1, 1, f_getfsize}, 7634 {"getftime", 1, 1, f_getftime}, 7635 {"getftype", 1, 1, f_getftype}, 7636 {"getline", 1, 2, f_getline}, 7637 {"getloclist", 1, 1, f_getqflist}, 7638 {"getmatches", 0, 0, f_getmatches}, 7639 {"getpid", 0, 0, f_getpid}, 7640 {"getpos", 1, 1, f_getpos}, 7641 {"getqflist", 0, 0, f_getqflist}, 7642 {"getreg", 0, 2, f_getreg}, 7643 {"getregtype", 0, 1, f_getregtype}, 7644 {"gettabwinvar", 3, 3, f_gettabwinvar}, 7645 {"getwinposx", 0, 0, f_getwinposx}, 7646 {"getwinposy", 0, 0, f_getwinposy}, 7647 {"getwinvar", 2, 2, f_getwinvar}, 7648 {"glob", 1, 2, f_glob}, 7649 {"globpath", 2, 3, f_globpath}, 7650 {"has", 1, 1, f_has}, 7651 {"has_key", 2, 2, f_has_key}, 7652 {"haslocaldir", 0, 0, f_haslocaldir}, 7653 {"hasmapto", 1, 3, f_hasmapto}, 7654 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 7655 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 7656 {"histadd", 2, 2, f_histadd}, 7657 {"histdel", 1, 2, f_histdel}, 7658 {"histget", 1, 2, f_histget}, 7659 {"histnr", 1, 1, f_histnr}, 7660 {"hlID", 1, 1, f_hlID}, 7661 {"hlexists", 1, 1, f_hlexists}, 7662 {"hostname", 0, 0, f_hostname}, 7663 {"iconv", 3, 3, f_iconv}, 7664 {"indent", 1, 1, f_indent}, 7665 {"index", 2, 4, f_index}, 7666 {"input", 1, 3, f_input}, 7667 {"inputdialog", 1, 3, f_inputdialog}, 7668 {"inputlist", 1, 1, f_inputlist}, 7669 {"inputrestore", 0, 0, f_inputrestore}, 7670 {"inputsave", 0, 0, f_inputsave}, 7671 {"inputsecret", 1, 2, f_inputsecret}, 7672 {"insert", 2, 3, f_insert}, 7673 {"isdirectory", 1, 1, f_isdirectory}, 7674 {"islocked", 1, 1, f_islocked}, 7675 {"items", 1, 1, f_items}, 7676 {"join", 1, 2, f_join}, 7677 {"keys", 1, 1, f_keys}, 7678 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 7679 {"len", 1, 1, f_len}, 7680 {"libcall", 3, 3, f_libcall}, 7681 {"libcallnr", 3, 3, f_libcallnr}, 7682 {"line", 1, 1, f_line}, 7683 {"line2byte", 1, 1, f_line2byte}, 7684 {"lispindent", 1, 1, f_lispindent}, 7685 {"localtime", 0, 0, f_localtime}, 7686 #ifdef FEAT_FLOAT 7687 {"log10", 1, 1, f_log10}, 7688 #endif 7689 {"map", 2, 2, f_map}, 7690 {"maparg", 1, 3, f_maparg}, 7691 {"mapcheck", 1, 3, f_mapcheck}, 7692 {"match", 2, 4, f_match}, 7693 {"matchadd", 2, 4, f_matchadd}, 7694 {"matcharg", 1, 1, f_matcharg}, 7695 {"matchdelete", 1, 1, f_matchdelete}, 7696 {"matchend", 2, 4, f_matchend}, 7697 {"matchlist", 2, 4, f_matchlist}, 7698 {"matchstr", 2, 4, f_matchstr}, 7699 {"max", 1, 1, f_max}, 7700 {"min", 1, 1, f_min}, 7701 #ifdef vim_mkdir 7702 {"mkdir", 1, 3, f_mkdir}, 7703 #endif 7704 {"mode", 0, 1, f_mode}, 7705 #ifdef FEAT_MZSCHEME 7706 {"mzeval", 1, 1, f_mzeval}, 7707 #endif 7708 {"nextnonblank", 1, 1, f_nextnonblank}, 7709 {"nr2char", 1, 1, f_nr2char}, 7710 {"pathshorten", 1, 1, f_pathshorten}, 7711 #ifdef FEAT_FLOAT 7712 {"pow", 2, 2, f_pow}, 7713 #endif 7714 {"prevnonblank", 1, 1, f_prevnonblank}, 7715 {"printf", 2, 19, f_printf}, 7716 {"pumvisible", 0, 0, f_pumvisible}, 7717 {"range", 1, 3, f_range}, 7718 {"readfile", 1, 3, f_readfile}, 7719 {"reltime", 0, 2, f_reltime}, 7720 {"reltimestr", 1, 1, f_reltimestr}, 7721 {"remote_expr", 2, 3, f_remote_expr}, 7722 {"remote_foreground", 1, 1, f_remote_foreground}, 7723 {"remote_peek", 1, 2, f_remote_peek}, 7724 {"remote_read", 1, 1, f_remote_read}, 7725 {"remote_send", 2, 3, f_remote_send}, 7726 {"remove", 2, 3, f_remove}, 7727 {"rename", 2, 2, f_rename}, 7728 {"repeat", 2, 2, f_repeat}, 7729 {"resolve", 1, 1, f_resolve}, 7730 {"reverse", 1, 1, f_reverse}, 7731 #ifdef FEAT_FLOAT 7732 {"round", 1, 1, f_round}, 7733 #endif 7734 {"search", 1, 4, f_search}, 7735 {"searchdecl", 1, 3, f_searchdecl}, 7736 {"searchpair", 3, 7, f_searchpair}, 7737 {"searchpairpos", 3, 7, f_searchpairpos}, 7738 {"searchpos", 1, 4, f_searchpos}, 7739 {"server2client", 2, 2, f_server2client}, 7740 {"serverlist", 0, 0, f_serverlist}, 7741 {"setbufvar", 3, 3, f_setbufvar}, 7742 {"setcmdpos", 1, 1, f_setcmdpos}, 7743 {"setline", 2, 2, f_setline}, 7744 {"setloclist", 2, 3, f_setloclist}, 7745 {"setmatches", 1, 1, f_setmatches}, 7746 {"setpos", 2, 2, f_setpos}, 7747 {"setqflist", 1, 2, f_setqflist}, 7748 {"setreg", 2, 3, f_setreg}, 7749 {"settabwinvar", 4, 4, f_settabwinvar}, 7750 {"setwinvar", 3, 3, f_setwinvar}, 7751 {"shellescape", 1, 2, f_shellescape}, 7752 {"simplify", 1, 1, f_simplify}, 7753 #ifdef FEAT_FLOAT 7754 {"sin", 1, 1, f_sin}, 7755 #endif 7756 {"sort", 1, 2, f_sort}, 7757 {"soundfold", 1, 1, f_soundfold}, 7758 {"spellbadword", 0, 1, f_spellbadword}, 7759 {"spellsuggest", 1, 3, f_spellsuggest}, 7760 {"split", 1, 3, f_split}, 7761 #ifdef FEAT_FLOAT 7762 {"sqrt", 1, 1, f_sqrt}, 7763 {"str2float", 1, 1, f_str2float}, 7764 #endif 7765 {"str2nr", 1, 2, f_str2nr}, 7766 #ifdef HAVE_STRFTIME 7767 {"strftime", 1, 2, f_strftime}, 7768 #endif 7769 {"stridx", 2, 3, f_stridx}, 7770 {"string", 1, 1, f_string}, 7771 {"strlen", 1, 1, f_strlen}, 7772 {"strpart", 2, 3, f_strpart}, 7773 {"strridx", 2, 3, f_strridx}, 7774 {"strtrans", 1, 1, f_strtrans}, 7775 {"submatch", 1, 1, f_submatch}, 7776 {"substitute", 4, 4, f_substitute}, 7777 {"synID", 3, 3, f_synID}, 7778 {"synIDattr", 2, 3, f_synIDattr}, 7779 {"synIDtrans", 1, 1, f_synIDtrans}, 7780 {"synstack", 2, 2, f_synstack}, 7781 {"system", 1, 2, f_system}, 7782 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 7783 {"tabpagenr", 0, 1, f_tabpagenr}, 7784 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 7785 {"tagfiles", 0, 0, f_tagfiles}, 7786 {"taglist", 1, 1, f_taglist}, 7787 {"tempname", 0, 0, f_tempname}, 7788 {"test", 1, 1, f_test}, 7789 {"tolower", 1, 1, f_tolower}, 7790 {"toupper", 1, 1, f_toupper}, 7791 {"tr", 3, 3, f_tr}, 7792 #ifdef FEAT_FLOAT 7793 {"trunc", 1, 1, f_trunc}, 7794 #endif 7795 {"type", 1, 1, f_type}, 7796 {"values", 1, 1, f_values}, 7797 {"virtcol", 1, 1, f_virtcol}, 7798 {"visualmode", 0, 1, f_visualmode}, 7799 {"winbufnr", 1, 1, f_winbufnr}, 7800 {"wincol", 0, 0, f_wincol}, 7801 {"winheight", 1, 1, f_winheight}, 7802 {"winline", 0, 0, f_winline}, 7803 {"winnr", 0, 1, f_winnr}, 7804 {"winrestcmd", 0, 0, f_winrestcmd}, 7805 {"winrestview", 1, 1, f_winrestview}, 7806 {"winsaveview", 0, 0, f_winsaveview}, 7807 {"winwidth", 1, 1, f_winwidth}, 7808 {"writefile", 2, 3, f_writefile}, 7809 }; 7810 7811 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 7812 7813 /* 7814 * Function given to ExpandGeneric() to obtain the list of internal 7815 * or user defined function names. 7816 */ 7817 char_u * 7818 get_function_name(xp, idx) 7819 expand_T *xp; 7820 int idx; 7821 { 7822 static int intidx = -1; 7823 char_u *name; 7824 7825 if (idx == 0) 7826 intidx = -1; 7827 if (intidx < 0) 7828 { 7829 name = get_user_func_name(xp, idx); 7830 if (name != NULL) 7831 return name; 7832 } 7833 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 7834 { 7835 STRCPY(IObuff, functions[intidx].f_name); 7836 STRCAT(IObuff, "("); 7837 if (functions[intidx].f_max_argc == 0) 7838 STRCAT(IObuff, ")"); 7839 return IObuff; 7840 } 7841 7842 return NULL; 7843 } 7844 7845 /* 7846 * Function given to ExpandGeneric() to obtain the list of internal or 7847 * user defined variable or function names. 7848 */ 7849 char_u * 7850 get_expr_name(xp, idx) 7851 expand_T *xp; 7852 int idx; 7853 { 7854 static int intidx = -1; 7855 char_u *name; 7856 7857 if (idx == 0) 7858 intidx = -1; 7859 if (intidx < 0) 7860 { 7861 name = get_function_name(xp, idx); 7862 if (name != NULL) 7863 return name; 7864 } 7865 return get_user_var_name(xp, ++intidx); 7866 } 7867 7868 #endif /* FEAT_CMDL_COMPL */ 7869 7870 /* 7871 * Find internal function in table above. 7872 * Return index, or -1 if not found 7873 */ 7874 static int 7875 find_internal_func(name) 7876 char_u *name; /* name of the function */ 7877 { 7878 int first = 0; 7879 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 7880 int cmp; 7881 int x; 7882 7883 /* 7884 * Find the function name in the table. Binary search. 7885 */ 7886 while (first <= last) 7887 { 7888 x = first + ((unsigned)(last - first) >> 1); 7889 cmp = STRCMP(name, functions[x].f_name); 7890 if (cmp < 0) 7891 last = x - 1; 7892 else if (cmp > 0) 7893 first = x + 1; 7894 else 7895 return x; 7896 } 7897 return -1; 7898 } 7899 7900 /* 7901 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7902 * name it contains, otherwise return "name". 7903 */ 7904 static char_u * 7905 deref_func_name(name, lenp) 7906 char_u *name; 7907 int *lenp; 7908 { 7909 dictitem_T *v; 7910 int cc; 7911 7912 cc = name[*lenp]; 7913 name[*lenp] = NUL; 7914 v = find_var(name, NULL); 7915 name[*lenp] = cc; 7916 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7917 { 7918 if (v->di_tv.vval.v_string == NULL) 7919 { 7920 *lenp = 0; 7921 return (char_u *)""; /* just in case */ 7922 } 7923 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 7924 return v->di_tv.vval.v_string; 7925 } 7926 7927 return name; 7928 } 7929 7930 /* 7931 * Allocate a variable for the result of a function. 7932 * Return OK or FAIL. 7933 */ 7934 static int 7935 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7936 evaluate, selfdict) 7937 char_u *name; /* name of the function */ 7938 int len; /* length of "name" */ 7939 typval_T *rettv; 7940 char_u **arg; /* argument, pointing to the '(' */ 7941 linenr_T firstline; /* first line of range */ 7942 linenr_T lastline; /* last line of range */ 7943 int *doesrange; /* return: function handled range */ 7944 int evaluate; 7945 dict_T *selfdict; /* Dictionary for "self" */ 7946 { 7947 char_u *argp; 7948 int ret = OK; 7949 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 7950 int argcount = 0; /* number of arguments found */ 7951 7952 /* 7953 * Get the arguments. 7954 */ 7955 argp = *arg; 7956 while (argcount < MAX_FUNC_ARGS) 7957 { 7958 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7959 if (*argp == ')' || *argp == ',' || *argp == NUL) 7960 break; 7961 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7962 { 7963 ret = FAIL; 7964 break; 7965 } 7966 ++argcount; 7967 if (*argp != ',') 7968 break; 7969 } 7970 if (*argp == ')') 7971 ++argp; 7972 else 7973 ret = FAIL; 7974 7975 if (ret == OK) 7976 ret = call_func(name, len, rettv, argcount, argvars, 7977 firstline, lastline, doesrange, evaluate, selfdict); 7978 else if (!aborting()) 7979 { 7980 if (argcount == MAX_FUNC_ARGS) 7981 emsg_funcname(N_("E740: Too many arguments for function %s"), name); 7982 else 7983 emsg_funcname(N_("E116: Invalid arguments for function %s"), name); 7984 } 7985 7986 while (--argcount >= 0) 7987 clear_tv(&argvars[argcount]); 7988 7989 *arg = skipwhite(argp); 7990 return ret; 7991 } 7992 7993 7994 /* 7995 * Call a function with its resolved parameters 7996 * Return OK when the function can't be called, FAIL otherwise. 7997 * Also returns OK when an error was encountered while executing the function. 7998 */ 7999 static int 8000 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 8001 doesrange, evaluate, selfdict) 8002 char_u *name; /* name of the function */ 8003 int len; /* length of "name" */ 8004 typval_T *rettv; /* return value goes here */ 8005 int argcount; /* number of "argvars" */ 8006 typval_T *argvars; /* vars for arguments, must have "argcount" 8007 PLUS ONE elements! */ 8008 linenr_T firstline; /* first line of range */ 8009 linenr_T lastline; /* last line of range */ 8010 int *doesrange; /* return: function handled range */ 8011 int evaluate; 8012 dict_T *selfdict; /* Dictionary for "self" */ 8013 { 8014 int ret = FAIL; 8015 #define ERROR_UNKNOWN 0 8016 #define ERROR_TOOMANY 1 8017 #define ERROR_TOOFEW 2 8018 #define ERROR_SCRIPT 3 8019 #define ERROR_DICT 4 8020 #define ERROR_NONE 5 8021 #define ERROR_OTHER 6 8022 int error = ERROR_NONE; 8023 int i; 8024 int llen; 8025 ufunc_T *fp; 8026 int cc; 8027 #define FLEN_FIXED 40 8028 char_u fname_buf[FLEN_FIXED + 1]; 8029 char_u *fname; 8030 8031 /* 8032 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 8033 * Change <SNR>123_name() to K_SNR 123_name(). 8034 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 8035 */ 8036 cc = name[len]; 8037 name[len] = NUL; 8038 llen = eval_fname_script(name); 8039 if (llen > 0) 8040 { 8041 fname_buf[0] = K_SPECIAL; 8042 fname_buf[1] = KS_EXTRA; 8043 fname_buf[2] = (int)KE_SNR; 8044 i = 3; 8045 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 8046 { 8047 if (current_SID <= 0) 8048 error = ERROR_SCRIPT; 8049 else 8050 { 8051 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 8052 i = (int)STRLEN(fname_buf); 8053 } 8054 } 8055 if (i + STRLEN(name + llen) < FLEN_FIXED) 8056 { 8057 STRCPY(fname_buf + i, name + llen); 8058 fname = fname_buf; 8059 } 8060 else 8061 { 8062 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 8063 if (fname == NULL) 8064 error = ERROR_OTHER; 8065 else 8066 { 8067 mch_memmove(fname, fname_buf, (size_t)i); 8068 STRCPY(fname + i, name + llen); 8069 } 8070 } 8071 } 8072 else 8073 fname = name; 8074 8075 *doesrange = FALSE; 8076 8077 8078 /* execute the function if no errors detected and executing */ 8079 if (evaluate && error == ERROR_NONE) 8080 { 8081 rettv->v_type = VAR_NUMBER; /* default rettv is number zero */ 8082 rettv->vval.v_number = 0; 8083 error = ERROR_UNKNOWN; 8084 8085 if (!builtin_function(fname)) 8086 { 8087 /* 8088 * User defined function. 8089 */ 8090 fp = find_func(fname); 8091 8092 #ifdef FEAT_AUTOCMD 8093 /* Trigger FuncUndefined event, may load the function. */ 8094 if (fp == NULL 8095 && apply_autocmds(EVENT_FUNCUNDEFINED, 8096 fname, fname, TRUE, NULL) 8097 && !aborting()) 8098 { 8099 /* executed an autocommand, search for the function again */ 8100 fp = find_func(fname); 8101 } 8102 #endif 8103 /* Try loading a package. */ 8104 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 8105 { 8106 /* loaded a package, search for the function again */ 8107 fp = find_func(fname); 8108 } 8109 8110 if (fp != NULL) 8111 { 8112 if (fp->uf_flags & FC_RANGE) 8113 *doesrange = TRUE; 8114 if (argcount < fp->uf_args.ga_len) 8115 error = ERROR_TOOFEW; 8116 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 8117 error = ERROR_TOOMANY; 8118 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 8119 error = ERROR_DICT; 8120 else 8121 { 8122 /* 8123 * Call the user function. 8124 * Save and restore search patterns, script variables and 8125 * redo buffer. 8126 */ 8127 save_search_patterns(); 8128 saveRedobuff(); 8129 ++fp->uf_calls; 8130 call_user_func(fp, argcount, argvars, rettv, 8131 firstline, lastline, 8132 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 8133 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 8134 && fp->uf_refcount <= 0) 8135 /* Function was unreferenced while being used, free it 8136 * now. */ 8137 func_free(fp); 8138 restoreRedobuff(); 8139 restore_search_patterns(); 8140 error = ERROR_NONE; 8141 } 8142 } 8143 } 8144 else 8145 { 8146 /* 8147 * Find the function name in the table, call its implementation. 8148 */ 8149 i = find_internal_func(fname); 8150 if (i >= 0) 8151 { 8152 if (argcount < functions[i].f_min_argc) 8153 error = ERROR_TOOFEW; 8154 else if (argcount > functions[i].f_max_argc) 8155 error = ERROR_TOOMANY; 8156 else 8157 { 8158 argvars[argcount].v_type = VAR_UNKNOWN; 8159 functions[i].f_func(argvars, rettv); 8160 error = ERROR_NONE; 8161 } 8162 } 8163 } 8164 /* 8165 * The function call (or "FuncUndefined" autocommand sequence) might 8166 * have been aborted by an error, an interrupt, or an explicitly thrown 8167 * exception that has not been caught so far. This situation can be 8168 * tested for by calling aborting(). For an error in an internal 8169 * function or for the "E132" error in call_user_func(), however, the 8170 * throw point at which the "force_abort" flag (temporarily reset by 8171 * emsg()) is normally updated has not been reached yet. We need to 8172 * update that flag first to make aborting() reliable. 8173 */ 8174 update_force_abort(); 8175 } 8176 if (error == ERROR_NONE) 8177 ret = OK; 8178 8179 /* 8180 * Report an error unless the argument evaluation or function call has been 8181 * cancelled due to an aborting error, an interrupt, or an exception. 8182 */ 8183 if (!aborting()) 8184 { 8185 switch (error) 8186 { 8187 case ERROR_UNKNOWN: 8188 emsg_funcname(N_("E117: Unknown function: %s"), name); 8189 break; 8190 case ERROR_TOOMANY: 8191 emsg_funcname(e_toomanyarg, name); 8192 break; 8193 case ERROR_TOOFEW: 8194 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 8195 name); 8196 break; 8197 case ERROR_SCRIPT: 8198 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 8199 name); 8200 break; 8201 case ERROR_DICT: 8202 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 8203 name); 8204 break; 8205 } 8206 } 8207 8208 name[len] = cc; 8209 if (fname != name && fname != fname_buf) 8210 vim_free(fname); 8211 8212 return ret; 8213 } 8214 8215 /* 8216 * Give an error message with a function name. Handle <SNR> things. 8217 * "ermsg" is to be passed without translation, use N_() instead of _(). 8218 */ 8219 static void 8220 emsg_funcname(ermsg, name) 8221 char *ermsg; 8222 char_u *name; 8223 { 8224 char_u *p; 8225 8226 if (*name == K_SPECIAL) 8227 p = concat_str((char_u *)"<SNR>", name + 3); 8228 else 8229 p = name; 8230 EMSG2(_(ermsg), p); 8231 if (p != name) 8232 vim_free(p); 8233 } 8234 8235 /* 8236 * Return TRUE for a non-zero Number and a non-empty String. 8237 */ 8238 static int 8239 non_zero_arg(argvars) 8240 typval_T *argvars; 8241 { 8242 return ((argvars[0].v_type == VAR_NUMBER 8243 && argvars[0].vval.v_number != 0) 8244 || (argvars[0].v_type == VAR_STRING 8245 && argvars[0].vval.v_string != NULL 8246 && *argvars[0].vval.v_string != NUL)); 8247 } 8248 8249 /********************************************* 8250 * Implementation of the built-in functions 8251 */ 8252 8253 #ifdef FEAT_FLOAT 8254 /* 8255 * "abs(expr)" function 8256 */ 8257 static void 8258 f_abs(argvars, rettv) 8259 typval_T *argvars; 8260 typval_T *rettv; 8261 { 8262 if (argvars[0].v_type == VAR_FLOAT) 8263 { 8264 rettv->v_type = VAR_FLOAT; 8265 rettv->vval.v_float = fabs(argvars[0].vval.v_float); 8266 } 8267 else 8268 { 8269 varnumber_T n; 8270 int error = FALSE; 8271 8272 n = get_tv_number_chk(&argvars[0], &error); 8273 if (error) 8274 rettv->vval.v_number = -1; 8275 else if (n > 0) 8276 rettv->vval.v_number = n; 8277 else 8278 rettv->vval.v_number = -n; 8279 } 8280 } 8281 #endif 8282 8283 /* 8284 * "add(list, item)" function 8285 */ 8286 static void 8287 f_add(argvars, rettv) 8288 typval_T *argvars; 8289 typval_T *rettv; 8290 { 8291 list_T *l; 8292 8293 rettv->vval.v_number = 1; /* Default: Failed */ 8294 if (argvars[0].v_type == VAR_LIST) 8295 { 8296 if ((l = argvars[0].vval.v_list) != NULL 8297 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 8298 && list_append_tv(l, &argvars[1]) == OK) 8299 copy_tv(&argvars[0], rettv); 8300 } 8301 else 8302 EMSG(_(e_listreq)); 8303 } 8304 8305 /* 8306 * "append(lnum, string/list)" function 8307 */ 8308 static void 8309 f_append(argvars, rettv) 8310 typval_T *argvars; 8311 typval_T *rettv; 8312 { 8313 long lnum; 8314 char_u *line; 8315 list_T *l = NULL; 8316 listitem_T *li = NULL; 8317 typval_T *tv; 8318 long added = 0; 8319 8320 lnum = get_tv_lnum(argvars); 8321 if (lnum >= 0 8322 && lnum <= curbuf->b_ml.ml_line_count 8323 && u_save(lnum, lnum + 1) == OK) 8324 { 8325 if (argvars[1].v_type == VAR_LIST) 8326 { 8327 l = argvars[1].vval.v_list; 8328 if (l == NULL) 8329 return; 8330 li = l->lv_first; 8331 } 8332 for (;;) 8333 { 8334 if (l == NULL) 8335 tv = &argvars[1]; /* append a string */ 8336 else if (li == NULL) 8337 break; /* end of list */ 8338 else 8339 tv = &li->li_tv; /* append item from list */ 8340 line = get_tv_string_chk(tv); 8341 if (line == NULL) /* type error */ 8342 { 8343 rettv->vval.v_number = 1; /* Failed */ 8344 break; 8345 } 8346 ml_append(lnum + added, line, (colnr_T)0, FALSE); 8347 ++added; 8348 if (l == NULL) 8349 break; 8350 li = li->li_next; 8351 } 8352 8353 appended_lines_mark(lnum, added); 8354 if (curwin->w_cursor.lnum > lnum) 8355 curwin->w_cursor.lnum += added; 8356 } 8357 else 8358 rettv->vval.v_number = 1; /* Failed */ 8359 } 8360 8361 /* 8362 * "argc()" function 8363 */ 8364 static void 8365 f_argc(argvars, rettv) 8366 typval_T *argvars UNUSED; 8367 typval_T *rettv; 8368 { 8369 rettv->vval.v_number = ARGCOUNT; 8370 } 8371 8372 /* 8373 * "argidx()" function 8374 */ 8375 static void 8376 f_argidx(argvars, rettv) 8377 typval_T *argvars UNUSED; 8378 typval_T *rettv; 8379 { 8380 rettv->vval.v_number = curwin->w_arg_idx; 8381 } 8382 8383 /* 8384 * "argv(nr)" function 8385 */ 8386 static void 8387 f_argv(argvars, rettv) 8388 typval_T *argvars; 8389 typval_T *rettv; 8390 { 8391 int idx; 8392 8393 if (argvars[0].v_type != VAR_UNKNOWN) 8394 { 8395 idx = get_tv_number_chk(&argvars[0], NULL); 8396 if (idx >= 0 && idx < ARGCOUNT) 8397 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 8398 else 8399 rettv->vval.v_string = NULL; 8400 rettv->v_type = VAR_STRING; 8401 } 8402 else if (rettv_list_alloc(rettv) == OK) 8403 for (idx = 0; idx < ARGCOUNT; ++idx) 8404 list_append_string(rettv->vval.v_list, 8405 alist_name(&ARGLIST[idx]), -1); 8406 } 8407 8408 #ifdef FEAT_FLOAT 8409 static int get_float_arg __ARGS((typval_T *argvars, float_T *f)); 8410 8411 /* 8412 * Get the float value of "argvars[0]" into "f". 8413 * Returns FAIL when the argument is not a Number or Float. 8414 */ 8415 static int 8416 get_float_arg(argvars, f) 8417 typval_T *argvars; 8418 float_T *f; 8419 { 8420 if (argvars[0].v_type == VAR_FLOAT) 8421 { 8422 *f = argvars[0].vval.v_float; 8423 return OK; 8424 } 8425 if (argvars[0].v_type == VAR_NUMBER) 8426 { 8427 *f = (float_T)argvars[0].vval.v_number; 8428 return OK; 8429 } 8430 EMSG(_("E808: Number or Float required")); 8431 return FAIL; 8432 } 8433 8434 /* 8435 * "atan()" function 8436 */ 8437 static void 8438 f_atan(argvars, rettv) 8439 typval_T *argvars; 8440 typval_T *rettv; 8441 { 8442 float_T f; 8443 8444 rettv->v_type = VAR_FLOAT; 8445 if (get_float_arg(argvars, &f) == OK) 8446 rettv->vval.v_float = atan(f); 8447 else 8448 rettv->vval.v_float = 0.0; 8449 } 8450 #endif 8451 8452 /* 8453 * "browse(save, title, initdir, default)" function 8454 */ 8455 static void 8456 f_browse(argvars, rettv) 8457 typval_T *argvars UNUSED; 8458 typval_T *rettv; 8459 { 8460 #ifdef FEAT_BROWSE 8461 int save; 8462 char_u *title; 8463 char_u *initdir; 8464 char_u *defname; 8465 char_u buf[NUMBUFLEN]; 8466 char_u buf2[NUMBUFLEN]; 8467 int error = FALSE; 8468 8469 save = get_tv_number_chk(&argvars[0], &error); 8470 title = get_tv_string_chk(&argvars[1]); 8471 initdir = get_tv_string_buf_chk(&argvars[2], buf); 8472 defname = get_tv_string_buf_chk(&argvars[3], buf2); 8473 8474 if (error || title == NULL || initdir == NULL || defname == NULL) 8475 rettv->vval.v_string = NULL; 8476 else 8477 rettv->vval.v_string = 8478 do_browse(save ? BROWSE_SAVE : 0, 8479 title, defname, NULL, initdir, NULL, curbuf); 8480 #else 8481 rettv->vval.v_string = NULL; 8482 #endif 8483 rettv->v_type = VAR_STRING; 8484 } 8485 8486 /* 8487 * "browsedir(title, initdir)" function 8488 */ 8489 static void 8490 f_browsedir(argvars, rettv) 8491 typval_T *argvars UNUSED; 8492 typval_T *rettv; 8493 { 8494 #ifdef FEAT_BROWSE 8495 char_u *title; 8496 char_u *initdir; 8497 char_u buf[NUMBUFLEN]; 8498 8499 title = get_tv_string_chk(&argvars[0]); 8500 initdir = get_tv_string_buf_chk(&argvars[1], buf); 8501 8502 if (title == NULL || initdir == NULL) 8503 rettv->vval.v_string = NULL; 8504 else 8505 rettv->vval.v_string = do_browse(BROWSE_DIR, 8506 title, NULL, NULL, initdir, NULL, curbuf); 8507 #else 8508 rettv->vval.v_string = NULL; 8509 #endif 8510 rettv->v_type = VAR_STRING; 8511 } 8512 8513 static buf_T *find_buffer __ARGS((typval_T *avar)); 8514 8515 /* 8516 * Find a buffer by number or exact name. 8517 */ 8518 static buf_T * 8519 find_buffer(avar) 8520 typval_T *avar; 8521 { 8522 buf_T *buf = NULL; 8523 8524 if (avar->v_type == VAR_NUMBER) 8525 buf = buflist_findnr((int)avar->vval.v_number); 8526 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 8527 { 8528 buf = buflist_findname_exp(avar->vval.v_string); 8529 if (buf == NULL) 8530 { 8531 /* No full path name match, try a match with a URL or a "nofile" 8532 * buffer, these don't use the full path. */ 8533 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 8534 if (buf->b_fname != NULL 8535 && (path_with_url(buf->b_fname) 8536 #ifdef FEAT_QUICKFIX 8537 || bt_nofile(buf) 8538 #endif 8539 ) 8540 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 8541 break; 8542 } 8543 } 8544 return buf; 8545 } 8546 8547 /* 8548 * "bufexists(expr)" function 8549 */ 8550 static void 8551 f_bufexists(argvars, rettv) 8552 typval_T *argvars; 8553 typval_T *rettv; 8554 { 8555 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 8556 } 8557 8558 /* 8559 * "buflisted(expr)" function 8560 */ 8561 static void 8562 f_buflisted(argvars, rettv) 8563 typval_T *argvars; 8564 typval_T *rettv; 8565 { 8566 buf_T *buf; 8567 8568 buf = find_buffer(&argvars[0]); 8569 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 8570 } 8571 8572 /* 8573 * "bufloaded(expr)" function 8574 */ 8575 static void 8576 f_bufloaded(argvars, rettv) 8577 typval_T *argvars; 8578 typval_T *rettv; 8579 { 8580 buf_T *buf; 8581 8582 buf = find_buffer(&argvars[0]); 8583 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 8584 } 8585 8586 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 8587 8588 /* 8589 * Get buffer by number or pattern. 8590 */ 8591 static buf_T * 8592 get_buf_tv(tv) 8593 typval_T *tv; 8594 { 8595 char_u *name = tv->vval.v_string; 8596 int save_magic; 8597 char_u *save_cpo; 8598 buf_T *buf; 8599 8600 if (tv->v_type == VAR_NUMBER) 8601 return buflist_findnr((int)tv->vval.v_number); 8602 if (tv->v_type != VAR_STRING) 8603 return NULL; 8604 if (name == NULL || *name == NUL) 8605 return curbuf; 8606 if (name[0] == '$' && name[1] == NUL) 8607 return lastbuf; 8608 8609 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 8610 save_magic = p_magic; 8611 p_magic = TRUE; 8612 save_cpo = p_cpo; 8613 p_cpo = (char_u *)""; 8614 8615 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 8616 TRUE, FALSE)); 8617 8618 p_magic = save_magic; 8619 p_cpo = save_cpo; 8620 8621 /* If not found, try expanding the name, like done for bufexists(). */ 8622 if (buf == NULL) 8623 buf = find_buffer(tv); 8624 8625 return buf; 8626 } 8627 8628 /* 8629 * "bufname(expr)" function 8630 */ 8631 static void 8632 f_bufname(argvars, rettv) 8633 typval_T *argvars; 8634 typval_T *rettv; 8635 { 8636 buf_T *buf; 8637 8638 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8639 ++emsg_off; 8640 buf = get_buf_tv(&argvars[0]); 8641 rettv->v_type = VAR_STRING; 8642 if (buf != NULL && buf->b_fname != NULL) 8643 rettv->vval.v_string = vim_strsave(buf->b_fname); 8644 else 8645 rettv->vval.v_string = NULL; 8646 --emsg_off; 8647 } 8648 8649 /* 8650 * "bufnr(expr)" function 8651 */ 8652 static void 8653 f_bufnr(argvars, rettv) 8654 typval_T *argvars; 8655 typval_T *rettv; 8656 { 8657 buf_T *buf; 8658 int error = FALSE; 8659 char_u *name; 8660 8661 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8662 ++emsg_off; 8663 buf = get_buf_tv(&argvars[0]); 8664 --emsg_off; 8665 8666 /* If the buffer isn't found and the second argument is not zero create a 8667 * new buffer. */ 8668 if (buf == NULL 8669 && argvars[1].v_type != VAR_UNKNOWN 8670 && get_tv_number_chk(&argvars[1], &error) != 0 8671 && !error 8672 && (name = get_tv_string_chk(&argvars[0])) != NULL 8673 && !error) 8674 buf = buflist_new(name, NULL, (linenr_T)1, 0); 8675 8676 if (buf != NULL) 8677 rettv->vval.v_number = buf->b_fnum; 8678 else 8679 rettv->vval.v_number = -1; 8680 } 8681 8682 /* 8683 * "bufwinnr(nr)" function 8684 */ 8685 static void 8686 f_bufwinnr(argvars, rettv) 8687 typval_T *argvars; 8688 typval_T *rettv; 8689 { 8690 #ifdef FEAT_WINDOWS 8691 win_T *wp; 8692 int winnr = 0; 8693 #endif 8694 buf_T *buf; 8695 8696 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8697 ++emsg_off; 8698 buf = get_buf_tv(&argvars[0]); 8699 #ifdef FEAT_WINDOWS 8700 for (wp = firstwin; wp; wp = wp->w_next) 8701 { 8702 ++winnr; 8703 if (wp->w_buffer == buf) 8704 break; 8705 } 8706 rettv->vval.v_number = (wp != NULL ? winnr : -1); 8707 #else 8708 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 8709 #endif 8710 --emsg_off; 8711 } 8712 8713 /* 8714 * "byte2line(byte)" function 8715 */ 8716 static void 8717 f_byte2line(argvars, rettv) 8718 typval_T *argvars UNUSED; 8719 typval_T *rettv; 8720 { 8721 #ifndef FEAT_BYTEOFF 8722 rettv->vval.v_number = -1; 8723 #else 8724 long boff = 0; 8725 8726 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 8727 if (boff < 0) 8728 rettv->vval.v_number = -1; 8729 else 8730 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 8731 (linenr_T)0, &boff); 8732 #endif 8733 } 8734 8735 /* 8736 * "byteidx()" function 8737 */ 8738 static void 8739 f_byteidx(argvars, rettv) 8740 typval_T *argvars; 8741 typval_T *rettv; 8742 { 8743 #ifdef FEAT_MBYTE 8744 char_u *t; 8745 #endif 8746 char_u *str; 8747 long idx; 8748 8749 str = get_tv_string_chk(&argvars[0]); 8750 idx = get_tv_number_chk(&argvars[1], NULL); 8751 rettv->vval.v_number = -1; 8752 if (str == NULL || idx < 0) 8753 return; 8754 8755 #ifdef FEAT_MBYTE 8756 t = str; 8757 for ( ; idx > 0; idx--) 8758 { 8759 if (*t == NUL) /* EOL reached */ 8760 return; 8761 t += (*mb_ptr2len)(t); 8762 } 8763 rettv->vval.v_number = (varnumber_T)(t - str); 8764 #else 8765 if ((size_t)idx <= STRLEN(str)) 8766 rettv->vval.v_number = idx; 8767 #endif 8768 } 8769 8770 /* 8771 * "call(func, arglist)" function 8772 */ 8773 static void 8774 f_call(argvars, rettv) 8775 typval_T *argvars; 8776 typval_T *rettv; 8777 { 8778 char_u *func; 8779 typval_T argv[MAX_FUNC_ARGS + 1]; 8780 int argc = 0; 8781 listitem_T *item; 8782 int dummy; 8783 dict_T *selfdict = NULL; 8784 8785 if (argvars[1].v_type != VAR_LIST) 8786 { 8787 EMSG(_(e_listreq)); 8788 return; 8789 } 8790 if (argvars[1].vval.v_list == NULL) 8791 return; 8792 8793 if (argvars[0].v_type == VAR_FUNC) 8794 func = argvars[0].vval.v_string; 8795 else 8796 func = get_tv_string(&argvars[0]); 8797 if (*func == NUL) 8798 return; /* type error or empty name */ 8799 8800 if (argvars[2].v_type != VAR_UNKNOWN) 8801 { 8802 if (argvars[2].v_type != VAR_DICT) 8803 { 8804 EMSG(_(e_dictreq)); 8805 return; 8806 } 8807 selfdict = argvars[2].vval.v_dict; 8808 } 8809 8810 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 8811 item = item->li_next) 8812 { 8813 if (argc == MAX_FUNC_ARGS) 8814 { 8815 EMSG(_("E699: Too many arguments")); 8816 break; 8817 } 8818 /* Make a copy of each argument. This is needed to be able to set 8819 * v_lock to VAR_FIXED in the copy without changing the original list. 8820 */ 8821 copy_tv(&item->li_tv, &argv[argc++]); 8822 } 8823 8824 if (item == NULL) 8825 (void)call_func(func, (int)STRLEN(func), rettv, argc, argv, 8826 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 8827 &dummy, TRUE, selfdict); 8828 8829 /* Free the arguments. */ 8830 while (argc > 0) 8831 clear_tv(&argv[--argc]); 8832 } 8833 8834 #ifdef FEAT_FLOAT 8835 /* 8836 * "ceil({float})" function 8837 */ 8838 static void 8839 f_ceil(argvars, rettv) 8840 typval_T *argvars; 8841 typval_T *rettv; 8842 { 8843 float_T f; 8844 8845 rettv->v_type = VAR_FLOAT; 8846 if (get_float_arg(argvars, &f) == OK) 8847 rettv->vval.v_float = ceil(f); 8848 else 8849 rettv->vval.v_float = 0.0; 8850 } 8851 #endif 8852 8853 /* 8854 * "changenr()" function 8855 */ 8856 static void 8857 f_changenr(argvars, rettv) 8858 typval_T *argvars UNUSED; 8859 typval_T *rettv; 8860 { 8861 rettv->vval.v_number = curbuf->b_u_seq_cur; 8862 } 8863 8864 /* 8865 * "char2nr(string)" function 8866 */ 8867 static void 8868 f_char2nr(argvars, rettv) 8869 typval_T *argvars; 8870 typval_T *rettv; 8871 { 8872 #ifdef FEAT_MBYTE 8873 if (has_mbyte) 8874 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 8875 else 8876 #endif 8877 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 8878 } 8879 8880 /* 8881 * "cindent(lnum)" function 8882 */ 8883 static void 8884 f_cindent(argvars, rettv) 8885 typval_T *argvars; 8886 typval_T *rettv; 8887 { 8888 #ifdef FEAT_CINDENT 8889 pos_T pos; 8890 linenr_T lnum; 8891 8892 pos = curwin->w_cursor; 8893 lnum = get_tv_lnum(argvars); 8894 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8895 { 8896 curwin->w_cursor.lnum = lnum; 8897 rettv->vval.v_number = get_c_indent(); 8898 curwin->w_cursor = pos; 8899 } 8900 else 8901 #endif 8902 rettv->vval.v_number = -1; 8903 } 8904 8905 /* 8906 * "clearmatches()" function 8907 */ 8908 static void 8909 f_clearmatches(argvars, rettv) 8910 typval_T *argvars UNUSED; 8911 typval_T *rettv UNUSED; 8912 { 8913 #ifdef FEAT_SEARCH_EXTRA 8914 clear_matches(curwin); 8915 #endif 8916 } 8917 8918 /* 8919 * "col(string)" function 8920 */ 8921 static void 8922 f_col(argvars, rettv) 8923 typval_T *argvars; 8924 typval_T *rettv; 8925 { 8926 colnr_T col = 0; 8927 pos_T *fp; 8928 int fnum = curbuf->b_fnum; 8929 8930 fp = var2fpos(&argvars[0], FALSE, &fnum); 8931 if (fp != NULL && fnum == curbuf->b_fnum) 8932 { 8933 if (fp->col == MAXCOL) 8934 { 8935 /* '> can be MAXCOL, get the length of the line then */ 8936 if (fp->lnum <= curbuf->b_ml.ml_line_count) 8937 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 8938 else 8939 col = MAXCOL; 8940 } 8941 else 8942 { 8943 col = fp->col + 1; 8944 #ifdef FEAT_VIRTUALEDIT 8945 /* col(".") when the cursor is on the NUL at the end of the line 8946 * because of "coladd" can be seen as an extra column. */ 8947 if (virtual_active() && fp == &curwin->w_cursor) 8948 { 8949 char_u *p = ml_get_cursor(); 8950 8951 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 8952 curwin->w_virtcol - curwin->w_cursor.coladd)) 8953 { 8954 # ifdef FEAT_MBYTE 8955 int l; 8956 8957 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 8958 col += l; 8959 # else 8960 if (*p != NUL && p[1] == NUL) 8961 ++col; 8962 # endif 8963 } 8964 } 8965 #endif 8966 } 8967 } 8968 rettv->vval.v_number = col; 8969 } 8970 8971 #if defined(FEAT_INS_EXPAND) 8972 /* 8973 * "complete()" function 8974 */ 8975 static void 8976 f_complete(argvars, rettv) 8977 typval_T *argvars; 8978 typval_T *rettv UNUSED; 8979 { 8980 int startcol; 8981 8982 if ((State & INSERT) == 0) 8983 { 8984 EMSG(_("E785: complete() can only be used in Insert mode")); 8985 return; 8986 } 8987 8988 /* Check for undo allowed here, because if something was already inserted 8989 * the line was already saved for undo and this check isn't done. */ 8990 if (!undo_allowed()) 8991 return; 8992 8993 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 8994 { 8995 EMSG(_(e_invarg)); 8996 return; 8997 } 8998 8999 startcol = get_tv_number_chk(&argvars[0], NULL); 9000 if (startcol <= 0) 9001 return; 9002 9003 set_completion(startcol - 1, argvars[1].vval.v_list); 9004 } 9005 9006 /* 9007 * "complete_add()" function 9008 */ 9009 static void 9010 f_complete_add(argvars, rettv) 9011 typval_T *argvars; 9012 typval_T *rettv; 9013 { 9014 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 9015 } 9016 9017 /* 9018 * "complete_check()" function 9019 */ 9020 static void 9021 f_complete_check(argvars, rettv) 9022 typval_T *argvars UNUSED; 9023 typval_T *rettv; 9024 { 9025 int saved = RedrawingDisabled; 9026 9027 RedrawingDisabled = 0; 9028 ins_compl_check_keys(0); 9029 rettv->vval.v_number = compl_interrupted; 9030 RedrawingDisabled = saved; 9031 } 9032 #endif 9033 9034 /* 9035 * "confirm(message, buttons[, default [, type]])" function 9036 */ 9037 static void 9038 f_confirm(argvars, rettv) 9039 typval_T *argvars UNUSED; 9040 typval_T *rettv UNUSED; 9041 { 9042 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 9043 char_u *message; 9044 char_u *buttons = NULL; 9045 char_u buf[NUMBUFLEN]; 9046 char_u buf2[NUMBUFLEN]; 9047 int def = 1; 9048 int type = VIM_GENERIC; 9049 char_u *typestr; 9050 int error = FALSE; 9051 9052 message = get_tv_string_chk(&argvars[0]); 9053 if (message == NULL) 9054 error = TRUE; 9055 if (argvars[1].v_type != VAR_UNKNOWN) 9056 { 9057 buttons = get_tv_string_buf_chk(&argvars[1], buf); 9058 if (buttons == NULL) 9059 error = TRUE; 9060 if (argvars[2].v_type != VAR_UNKNOWN) 9061 { 9062 def = get_tv_number_chk(&argvars[2], &error); 9063 if (argvars[3].v_type != VAR_UNKNOWN) 9064 { 9065 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 9066 if (typestr == NULL) 9067 error = TRUE; 9068 else 9069 { 9070 switch (TOUPPER_ASC(*typestr)) 9071 { 9072 case 'E': type = VIM_ERROR; break; 9073 case 'Q': type = VIM_QUESTION; break; 9074 case 'I': type = VIM_INFO; break; 9075 case 'W': type = VIM_WARNING; break; 9076 case 'G': type = VIM_GENERIC; break; 9077 } 9078 } 9079 } 9080 } 9081 } 9082 9083 if (buttons == NULL || *buttons == NUL) 9084 buttons = (char_u *)_("&Ok"); 9085 9086 if (!error) 9087 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 9088 def, NULL); 9089 #endif 9090 } 9091 9092 /* 9093 * "copy()" function 9094 */ 9095 static void 9096 f_copy(argvars, rettv) 9097 typval_T *argvars; 9098 typval_T *rettv; 9099 { 9100 item_copy(&argvars[0], rettv, FALSE, 0); 9101 } 9102 9103 #ifdef FEAT_FLOAT 9104 /* 9105 * "cos()" function 9106 */ 9107 static void 9108 f_cos(argvars, rettv) 9109 typval_T *argvars; 9110 typval_T *rettv; 9111 { 9112 float_T f; 9113 9114 rettv->v_type = VAR_FLOAT; 9115 if (get_float_arg(argvars, &f) == OK) 9116 rettv->vval.v_float = cos(f); 9117 else 9118 rettv->vval.v_float = 0.0; 9119 } 9120 #endif 9121 9122 /* 9123 * "count()" function 9124 */ 9125 static void 9126 f_count(argvars, rettv) 9127 typval_T *argvars; 9128 typval_T *rettv; 9129 { 9130 long n = 0; 9131 int ic = FALSE; 9132 9133 if (argvars[0].v_type == VAR_LIST) 9134 { 9135 listitem_T *li; 9136 list_T *l; 9137 long idx; 9138 9139 if ((l = argvars[0].vval.v_list) != NULL) 9140 { 9141 li = l->lv_first; 9142 if (argvars[2].v_type != VAR_UNKNOWN) 9143 { 9144 int error = FALSE; 9145 9146 ic = get_tv_number_chk(&argvars[2], &error); 9147 if (argvars[3].v_type != VAR_UNKNOWN) 9148 { 9149 idx = get_tv_number_chk(&argvars[3], &error); 9150 if (!error) 9151 { 9152 li = list_find(l, idx); 9153 if (li == NULL) 9154 EMSGN(_(e_listidx), idx); 9155 } 9156 } 9157 if (error) 9158 li = NULL; 9159 } 9160 9161 for ( ; li != NULL; li = li->li_next) 9162 if (tv_equal(&li->li_tv, &argvars[1], ic)) 9163 ++n; 9164 } 9165 } 9166 else if (argvars[0].v_type == VAR_DICT) 9167 { 9168 int todo; 9169 dict_T *d; 9170 hashitem_T *hi; 9171 9172 if ((d = argvars[0].vval.v_dict) != NULL) 9173 { 9174 int error = FALSE; 9175 9176 if (argvars[2].v_type != VAR_UNKNOWN) 9177 { 9178 ic = get_tv_number_chk(&argvars[2], &error); 9179 if (argvars[3].v_type != VAR_UNKNOWN) 9180 EMSG(_(e_invarg)); 9181 } 9182 9183 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 9184 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 9185 { 9186 if (!HASHITEM_EMPTY(hi)) 9187 { 9188 --todo; 9189 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 9190 ++n; 9191 } 9192 } 9193 } 9194 } 9195 else 9196 EMSG2(_(e_listdictarg), "count()"); 9197 rettv->vval.v_number = n; 9198 } 9199 9200 /* 9201 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 9202 * 9203 * Checks the existence of a cscope connection. 9204 */ 9205 static void 9206 f_cscope_connection(argvars, rettv) 9207 typval_T *argvars UNUSED; 9208 typval_T *rettv UNUSED; 9209 { 9210 #ifdef FEAT_CSCOPE 9211 int num = 0; 9212 char_u *dbpath = NULL; 9213 char_u *prepend = NULL; 9214 char_u buf[NUMBUFLEN]; 9215 9216 if (argvars[0].v_type != VAR_UNKNOWN 9217 && argvars[1].v_type != VAR_UNKNOWN) 9218 { 9219 num = (int)get_tv_number(&argvars[0]); 9220 dbpath = get_tv_string(&argvars[1]); 9221 if (argvars[2].v_type != VAR_UNKNOWN) 9222 prepend = get_tv_string_buf(&argvars[2], buf); 9223 } 9224 9225 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 9226 #endif 9227 } 9228 9229 /* 9230 * "cursor(lnum, col)" function 9231 * 9232 * Moves the cursor to the specified line and column. 9233 * Returns 0 when the position could be set, -1 otherwise. 9234 */ 9235 static void 9236 f_cursor(argvars, rettv) 9237 typval_T *argvars; 9238 typval_T *rettv; 9239 { 9240 long line, col; 9241 #ifdef FEAT_VIRTUALEDIT 9242 long coladd = 0; 9243 #endif 9244 9245 rettv->vval.v_number = -1; 9246 if (argvars[1].v_type == VAR_UNKNOWN) 9247 { 9248 pos_T pos; 9249 9250 if (list2fpos(argvars, &pos, NULL) == FAIL) 9251 return; 9252 line = pos.lnum; 9253 col = pos.col; 9254 #ifdef FEAT_VIRTUALEDIT 9255 coladd = pos.coladd; 9256 #endif 9257 } 9258 else 9259 { 9260 line = get_tv_lnum(argvars); 9261 col = get_tv_number_chk(&argvars[1], NULL); 9262 #ifdef FEAT_VIRTUALEDIT 9263 if (argvars[2].v_type != VAR_UNKNOWN) 9264 coladd = get_tv_number_chk(&argvars[2], NULL); 9265 #endif 9266 } 9267 if (line < 0 || col < 0 9268 #ifdef FEAT_VIRTUALEDIT 9269 || coladd < 0 9270 #endif 9271 ) 9272 return; /* type error; errmsg already given */ 9273 if (line > 0) 9274 curwin->w_cursor.lnum = line; 9275 if (col > 0) 9276 curwin->w_cursor.col = col - 1; 9277 #ifdef FEAT_VIRTUALEDIT 9278 curwin->w_cursor.coladd = coladd; 9279 #endif 9280 9281 /* Make sure the cursor is in a valid position. */ 9282 check_cursor(); 9283 #ifdef FEAT_MBYTE 9284 /* Correct cursor for multi-byte character. */ 9285 if (has_mbyte) 9286 mb_adjust_cursor(); 9287 #endif 9288 9289 curwin->w_set_curswant = TRUE; 9290 rettv->vval.v_number = 0; 9291 } 9292 9293 /* 9294 * "deepcopy()" function 9295 */ 9296 static void 9297 f_deepcopy(argvars, rettv) 9298 typval_T *argvars; 9299 typval_T *rettv; 9300 { 9301 int noref = 0; 9302 9303 if (argvars[1].v_type != VAR_UNKNOWN) 9304 noref = get_tv_number_chk(&argvars[1], NULL); 9305 if (noref < 0 || noref > 1) 9306 EMSG(_(e_invarg)); 9307 else 9308 { 9309 current_copyID += COPYID_INC; 9310 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0); 9311 } 9312 } 9313 9314 /* 9315 * "delete()" function 9316 */ 9317 static void 9318 f_delete(argvars, rettv) 9319 typval_T *argvars; 9320 typval_T *rettv; 9321 { 9322 if (check_restricted() || check_secure()) 9323 rettv->vval.v_number = -1; 9324 else 9325 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 9326 } 9327 9328 /* 9329 * "did_filetype()" function 9330 */ 9331 static void 9332 f_did_filetype(argvars, rettv) 9333 typval_T *argvars UNUSED; 9334 typval_T *rettv UNUSED; 9335 { 9336 #ifdef FEAT_AUTOCMD 9337 rettv->vval.v_number = did_filetype; 9338 #endif 9339 } 9340 9341 /* 9342 * "diff_filler()" function 9343 */ 9344 static void 9345 f_diff_filler(argvars, rettv) 9346 typval_T *argvars UNUSED; 9347 typval_T *rettv UNUSED; 9348 { 9349 #ifdef FEAT_DIFF 9350 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 9351 #endif 9352 } 9353 9354 /* 9355 * "diff_hlID()" function 9356 */ 9357 static void 9358 f_diff_hlID(argvars, rettv) 9359 typval_T *argvars UNUSED; 9360 typval_T *rettv UNUSED; 9361 { 9362 #ifdef FEAT_DIFF 9363 linenr_T lnum = get_tv_lnum(argvars); 9364 static linenr_T prev_lnum = 0; 9365 static int changedtick = 0; 9366 static int fnum = 0; 9367 static int change_start = 0; 9368 static int change_end = 0; 9369 static hlf_T hlID = (hlf_T)0; 9370 int filler_lines; 9371 int col; 9372 9373 if (lnum < 0) /* ignore type error in {lnum} arg */ 9374 lnum = 0; 9375 if (lnum != prev_lnum 9376 || changedtick != curbuf->b_changedtick 9377 || fnum != curbuf->b_fnum) 9378 { 9379 /* New line, buffer, change: need to get the values. */ 9380 filler_lines = diff_check(curwin, lnum); 9381 if (filler_lines < 0) 9382 { 9383 if (filler_lines == -1) 9384 { 9385 change_start = MAXCOL; 9386 change_end = -1; 9387 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 9388 hlID = HLF_ADD; /* added line */ 9389 else 9390 hlID = HLF_CHD; /* changed line */ 9391 } 9392 else 9393 hlID = HLF_ADD; /* added line */ 9394 } 9395 else 9396 hlID = (hlf_T)0; 9397 prev_lnum = lnum; 9398 changedtick = curbuf->b_changedtick; 9399 fnum = curbuf->b_fnum; 9400 } 9401 9402 if (hlID == HLF_CHD || hlID == HLF_TXD) 9403 { 9404 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 9405 if (col >= change_start && col <= change_end) 9406 hlID = HLF_TXD; /* changed text */ 9407 else 9408 hlID = HLF_CHD; /* changed line */ 9409 } 9410 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 9411 #endif 9412 } 9413 9414 /* 9415 * "empty({expr})" function 9416 */ 9417 static void 9418 f_empty(argvars, rettv) 9419 typval_T *argvars; 9420 typval_T *rettv; 9421 { 9422 int n; 9423 9424 switch (argvars[0].v_type) 9425 { 9426 case VAR_STRING: 9427 case VAR_FUNC: 9428 n = argvars[0].vval.v_string == NULL 9429 || *argvars[0].vval.v_string == NUL; 9430 break; 9431 case VAR_NUMBER: 9432 n = argvars[0].vval.v_number == 0; 9433 break; 9434 #ifdef FEAT_FLOAT 9435 case VAR_FLOAT: 9436 n = argvars[0].vval.v_float == 0.0; 9437 break; 9438 #endif 9439 case VAR_LIST: 9440 n = argvars[0].vval.v_list == NULL 9441 || argvars[0].vval.v_list->lv_first == NULL; 9442 break; 9443 case VAR_DICT: 9444 n = argvars[0].vval.v_dict == NULL 9445 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 9446 break; 9447 default: 9448 EMSG2(_(e_intern2), "f_empty()"); 9449 n = 0; 9450 } 9451 9452 rettv->vval.v_number = n; 9453 } 9454 9455 /* 9456 * "escape({string}, {chars})" function 9457 */ 9458 static void 9459 f_escape(argvars, rettv) 9460 typval_T *argvars; 9461 typval_T *rettv; 9462 { 9463 char_u buf[NUMBUFLEN]; 9464 9465 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 9466 get_tv_string_buf(&argvars[1], buf)); 9467 rettv->v_type = VAR_STRING; 9468 } 9469 9470 /* 9471 * "eval()" function 9472 */ 9473 static void 9474 f_eval(argvars, rettv) 9475 typval_T *argvars; 9476 typval_T *rettv; 9477 { 9478 char_u *s; 9479 9480 s = get_tv_string_chk(&argvars[0]); 9481 if (s != NULL) 9482 s = skipwhite(s); 9483 9484 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 9485 { 9486 rettv->v_type = VAR_NUMBER; 9487 rettv->vval.v_number = 0; 9488 } 9489 else if (*s != NUL) 9490 EMSG(_(e_trailing)); 9491 } 9492 9493 /* 9494 * "eventhandler()" function 9495 */ 9496 static void 9497 f_eventhandler(argvars, rettv) 9498 typval_T *argvars UNUSED; 9499 typval_T *rettv; 9500 { 9501 rettv->vval.v_number = vgetc_busy; 9502 } 9503 9504 /* 9505 * "executable()" function 9506 */ 9507 static void 9508 f_executable(argvars, rettv) 9509 typval_T *argvars; 9510 typval_T *rettv; 9511 { 9512 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 9513 } 9514 9515 /* 9516 * "exists()" function 9517 */ 9518 static void 9519 f_exists(argvars, rettv) 9520 typval_T *argvars; 9521 typval_T *rettv; 9522 { 9523 char_u *p; 9524 char_u *name; 9525 int n = FALSE; 9526 int len = 0; 9527 9528 p = get_tv_string(&argvars[0]); 9529 if (*p == '$') /* environment variable */ 9530 { 9531 /* first try "normal" environment variables (fast) */ 9532 if (mch_getenv(p + 1) != NULL) 9533 n = TRUE; 9534 else 9535 { 9536 /* try expanding things like $VIM and ${HOME} */ 9537 p = expand_env_save(p); 9538 if (p != NULL && *p != '$') 9539 n = TRUE; 9540 vim_free(p); 9541 } 9542 } 9543 else if (*p == '&' || *p == '+') /* option */ 9544 { 9545 n = (get_option_tv(&p, NULL, TRUE) == OK); 9546 if (*skipwhite(p) != NUL) 9547 n = FALSE; /* trailing garbage */ 9548 } 9549 else if (*p == '*') /* internal or user defined function */ 9550 { 9551 n = function_exists(p + 1); 9552 } 9553 else if (*p == ':') 9554 { 9555 n = cmd_exists(p + 1); 9556 } 9557 else if (*p == '#') 9558 { 9559 #ifdef FEAT_AUTOCMD 9560 if (p[1] == '#') 9561 n = autocmd_supported(p + 2); 9562 else 9563 n = au_exists(p + 1); 9564 #endif 9565 } 9566 else /* internal variable */ 9567 { 9568 char_u *tofree; 9569 typval_T tv; 9570 9571 /* get_name_len() takes care of expanding curly braces */ 9572 name = p; 9573 len = get_name_len(&p, &tofree, TRUE, FALSE); 9574 if (len > 0) 9575 { 9576 if (tofree != NULL) 9577 name = tofree; 9578 n = (get_var_tv(name, len, &tv, FALSE) == OK); 9579 if (n) 9580 { 9581 /* handle d.key, l[idx], f(expr) */ 9582 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 9583 if (n) 9584 clear_tv(&tv); 9585 } 9586 } 9587 if (*p != NUL) 9588 n = FALSE; 9589 9590 vim_free(tofree); 9591 } 9592 9593 rettv->vval.v_number = n; 9594 } 9595 9596 /* 9597 * "expand()" function 9598 */ 9599 static void 9600 f_expand(argvars, rettv) 9601 typval_T *argvars; 9602 typval_T *rettv; 9603 { 9604 char_u *s; 9605 int len; 9606 char_u *errormsg; 9607 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 9608 expand_T xpc; 9609 int error = FALSE; 9610 9611 rettv->v_type = VAR_STRING; 9612 s = get_tv_string(&argvars[0]); 9613 if (*s == '%' || *s == '#' || *s == '<') 9614 { 9615 ++emsg_off; 9616 rettv->vval.v_string = eval_vars(s, s, &len, NULL, &errormsg, NULL); 9617 --emsg_off; 9618 } 9619 else 9620 { 9621 /* When the optional second argument is non-zero, don't remove matches 9622 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 9623 if (argvars[1].v_type != VAR_UNKNOWN 9624 && get_tv_number_chk(&argvars[1], &error)) 9625 flags |= WILD_KEEP_ALL; 9626 if (!error) 9627 { 9628 ExpandInit(&xpc); 9629 xpc.xp_context = EXPAND_FILES; 9630 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 9631 } 9632 else 9633 rettv->vval.v_string = NULL; 9634 } 9635 } 9636 9637 /* 9638 * "extend(list, list [, idx])" function 9639 * "extend(dict, dict [, action])" function 9640 */ 9641 static void 9642 f_extend(argvars, rettv) 9643 typval_T *argvars; 9644 typval_T *rettv; 9645 { 9646 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 9647 { 9648 list_T *l1, *l2; 9649 listitem_T *item; 9650 long before; 9651 int error = FALSE; 9652 9653 l1 = argvars[0].vval.v_list; 9654 l2 = argvars[1].vval.v_list; 9655 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 9656 && l2 != NULL) 9657 { 9658 if (argvars[2].v_type != VAR_UNKNOWN) 9659 { 9660 before = get_tv_number_chk(&argvars[2], &error); 9661 if (error) 9662 return; /* type error; errmsg already given */ 9663 9664 if (before == l1->lv_len) 9665 item = NULL; 9666 else 9667 { 9668 item = list_find(l1, before); 9669 if (item == NULL) 9670 { 9671 EMSGN(_(e_listidx), before); 9672 return; 9673 } 9674 } 9675 } 9676 else 9677 item = NULL; 9678 list_extend(l1, l2, item); 9679 9680 copy_tv(&argvars[0], rettv); 9681 } 9682 } 9683 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 9684 { 9685 dict_T *d1, *d2; 9686 dictitem_T *di1; 9687 char_u *action; 9688 int i; 9689 hashitem_T *hi2; 9690 int todo; 9691 9692 d1 = argvars[0].vval.v_dict; 9693 d2 = argvars[1].vval.v_dict; 9694 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 9695 && d2 != NULL) 9696 { 9697 /* Check the third argument. */ 9698 if (argvars[2].v_type != VAR_UNKNOWN) 9699 { 9700 static char *(av[]) = {"keep", "force", "error"}; 9701 9702 action = get_tv_string_chk(&argvars[2]); 9703 if (action == NULL) 9704 return; /* type error; errmsg already given */ 9705 for (i = 0; i < 3; ++i) 9706 if (STRCMP(action, av[i]) == 0) 9707 break; 9708 if (i == 3) 9709 { 9710 EMSG2(_(e_invarg2), action); 9711 return; 9712 } 9713 } 9714 else 9715 action = (char_u *)"force"; 9716 9717 /* Go over all entries in the second dict and add them to the 9718 * first dict. */ 9719 todo = (int)d2->dv_hashtab.ht_used; 9720 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 9721 { 9722 if (!HASHITEM_EMPTY(hi2)) 9723 { 9724 --todo; 9725 di1 = dict_find(d1, hi2->hi_key, -1); 9726 if (di1 == NULL) 9727 { 9728 di1 = dictitem_copy(HI2DI(hi2)); 9729 if (di1 != NULL && dict_add(d1, di1) == FAIL) 9730 dictitem_free(di1); 9731 } 9732 else if (*action == 'e') 9733 { 9734 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 9735 break; 9736 } 9737 else if (*action == 'f') 9738 { 9739 clear_tv(&di1->di_tv); 9740 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 9741 } 9742 } 9743 } 9744 9745 copy_tv(&argvars[0], rettv); 9746 } 9747 } 9748 else 9749 EMSG2(_(e_listdictarg), "extend()"); 9750 } 9751 9752 /* 9753 * "feedkeys()" function 9754 */ 9755 static void 9756 f_feedkeys(argvars, rettv) 9757 typval_T *argvars; 9758 typval_T *rettv UNUSED; 9759 { 9760 int remap = TRUE; 9761 char_u *keys, *flags; 9762 char_u nbuf[NUMBUFLEN]; 9763 int typed = FALSE; 9764 char_u *keys_esc; 9765 9766 /* This is not allowed in the sandbox. If the commands would still be 9767 * executed in the sandbox it would be OK, but it probably happens later, 9768 * when "sandbox" is no longer set. */ 9769 if (check_secure()) 9770 return; 9771 9772 keys = get_tv_string(&argvars[0]); 9773 if (*keys != NUL) 9774 { 9775 if (argvars[1].v_type != VAR_UNKNOWN) 9776 { 9777 flags = get_tv_string_buf(&argvars[1], nbuf); 9778 for ( ; *flags != NUL; ++flags) 9779 { 9780 switch (*flags) 9781 { 9782 case 'n': remap = FALSE; break; 9783 case 'm': remap = TRUE; break; 9784 case 't': typed = TRUE; break; 9785 } 9786 } 9787 } 9788 9789 /* Need to escape K_SPECIAL and CSI before putting the string in the 9790 * typeahead buffer. */ 9791 keys_esc = vim_strsave_escape_csi(keys); 9792 if (keys_esc != NULL) 9793 { 9794 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 9795 typebuf.tb_len, !typed, FALSE); 9796 vim_free(keys_esc); 9797 if (vgetc_busy) 9798 typebuf_was_filled = TRUE; 9799 } 9800 } 9801 } 9802 9803 /* 9804 * "filereadable()" function 9805 */ 9806 static void 9807 f_filereadable(argvars, rettv) 9808 typval_T *argvars; 9809 typval_T *rettv; 9810 { 9811 int fd; 9812 char_u *p; 9813 int n; 9814 9815 #ifndef O_NONBLOCK 9816 # define O_NONBLOCK 0 9817 #endif 9818 p = get_tv_string(&argvars[0]); 9819 if (*p && !mch_isdir(p) && (fd = mch_open((char *)p, 9820 O_RDONLY | O_NONBLOCK, 0)) >= 0) 9821 { 9822 n = TRUE; 9823 close(fd); 9824 } 9825 else 9826 n = FALSE; 9827 9828 rettv->vval.v_number = n; 9829 } 9830 9831 /* 9832 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 9833 * rights to write into. 9834 */ 9835 static void 9836 f_filewritable(argvars, rettv) 9837 typval_T *argvars; 9838 typval_T *rettv; 9839 { 9840 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 9841 } 9842 9843 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what)); 9844 9845 static void 9846 findfilendir(argvars, rettv, find_what) 9847 typval_T *argvars; 9848 typval_T *rettv; 9849 int find_what; 9850 { 9851 #ifdef FEAT_SEARCHPATH 9852 char_u *fname; 9853 char_u *fresult = NULL; 9854 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 9855 char_u *p; 9856 char_u pathbuf[NUMBUFLEN]; 9857 int count = 1; 9858 int first = TRUE; 9859 int error = FALSE; 9860 #endif 9861 9862 rettv->vval.v_string = NULL; 9863 rettv->v_type = VAR_STRING; 9864 9865 #ifdef FEAT_SEARCHPATH 9866 fname = get_tv_string(&argvars[0]); 9867 9868 if (argvars[1].v_type != VAR_UNKNOWN) 9869 { 9870 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 9871 if (p == NULL) 9872 error = TRUE; 9873 else 9874 { 9875 if (*p != NUL) 9876 path = p; 9877 9878 if (argvars[2].v_type != VAR_UNKNOWN) 9879 count = get_tv_number_chk(&argvars[2], &error); 9880 } 9881 } 9882 9883 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 9884 error = TRUE; 9885 9886 if (*fname != NUL && !error) 9887 { 9888 do 9889 { 9890 if (rettv->v_type == VAR_STRING) 9891 vim_free(fresult); 9892 fresult = find_file_in_path_option(first ? fname : NULL, 9893 first ? (int)STRLEN(fname) : 0, 9894 0, first, path, 9895 find_what, 9896 curbuf->b_ffname, 9897 find_what == FINDFILE_DIR 9898 ? (char_u *)"" : curbuf->b_p_sua); 9899 first = FALSE; 9900 9901 if (fresult != NULL && rettv->v_type == VAR_LIST) 9902 list_append_string(rettv->vval.v_list, fresult, -1); 9903 9904 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 9905 } 9906 9907 if (rettv->v_type == VAR_STRING) 9908 rettv->vval.v_string = fresult; 9909 #endif 9910 } 9911 9912 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 9913 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 9914 9915 /* 9916 * Implementation of map() and filter(). 9917 */ 9918 static void 9919 filter_map(argvars, rettv, map) 9920 typval_T *argvars; 9921 typval_T *rettv; 9922 int map; 9923 { 9924 char_u buf[NUMBUFLEN]; 9925 char_u *expr; 9926 listitem_T *li, *nli; 9927 list_T *l = NULL; 9928 dictitem_T *di; 9929 hashtab_T *ht; 9930 hashitem_T *hi; 9931 dict_T *d = NULL; 9932 typval_T save_val; 9933 typval_T save_key; 9934 int rem; 9935 int todo; 9936 char_u *ermsg = map ? (char_u *)"map()" : (char_u *)"filter()"; 9937 int save_did_emsg; 9938 int index = 0; 9939 9940 if (argvars[0].v_type == VAR_LIST) 9941 { 9942 if ((l = argvars[0].vval.v_list) == NULL 9943 || (map && tv_check_lock(l->lv_lock, ermsg))) 9944 return; 9945 } 9946 else if (argvars[0].v_type == VAR_DICT) 9947 { 9948 if ((d = argvars[0].vval.v_dict) == NULL 9949 || (map && tv_check_lock(d->dv_lock, ermsg))) 9950 return; 9951 } 9952 else 9953 { 9954 EMSG2(_(e_listdictarg), ermsg); 9955 return; 9956 } 9957 9958 expr = get_tv_string_buf_chk(&argvars[1], buf); 9959 /* On type errors, the preceding call has already displayed an error 9960 * message. Avoid a misleading error message for an empty string that 9961 * was not passed as argument. */ 9962 if (expr != NULL) 9963 { 9964 prepare_vimvar(VV_VAL, &save_val); 9965 expr = skipwhite(expr); 9966 9967 /* We reset "did_emsg" to be able to detect whether an error 9968 * occurred during evaluation of the expression. */ 9969 save_did_emsg = did_emsg; 9970 did_emsg = FALSE; 9971 9972 prepare_vimvar(VV_KEY, &save_key); 9973 if (argvars[0].v_type == VAR_DICT) 9974 { 9975 vimvars[VV_KEY].vv_type = VAR_STRING; 9976 9977 ht = &d->dv_hashtab; 9978 hash_lock(ht); 9979 todo = (int)ht->ht_used; 9980 for (hi = ht->ht_array; todo > 0; ++hi) 9981 { 9982 if (!HASHITEM_EMPTY(hi)) 9983 { 9984 --todo; 9985 di = HI2DI(hi); 9986 if (tv_check_lock(di->di_tv.v_lock, ermsg)) 9987 break; 9988 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 9989 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL 9990 || did_emsg) 9991 break; 9992 if (!map && rem) 9993 dictitem_remove(d, di); 9994 clear_tv(&vimvars[VV_KEY].vv_tv); 9995 } 9996 } 9997 hash_unlock(ht); 9998 } 9999 else 10000 { 10001 vimvars[VV_KEY].vv_type = VAR_NUMBER; 10002 10003 for (li = l->lv_first; li != NULL; li = nli) 10004 { 10005 if (tv_check_lock(li->li_tv.v_lock, ermsg)) 10006 break; 10007 nli = li->li_next; 10008 vimvars[VV_KEY].vv_nr = index; 10009 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 10010 || did_emsg) 10011 break; 10012 if (!map && rem) 10013 listitem_remove(l, li); 10014 ++index; 10015 } 10016 } 10017 10018 restore_vimvar(VV_KEY, &save_key); 10019 restore_vimvar(VV_VAL, &save_val); 10020 10021 did_emsg |= save_did_emsg; 10022 } 10023 10024 copy_tv(&argvars[0], rettv); 10025 } 10026 10027 static int 10028 filter_map_one(tv, expr, map, remp) 10029 typval_T *tv; 10030 char_u *expr; 10031 int map; 10032 int *remp; 10033 { 10034 typval_T rettv; 10035 char_u *s; 10036 int retval = FAIL; 10037 10038 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 10039 s = expr; 10040 if (eval1(&s, &rettv, TRUE) == FAIL) 10041 goto theend; 10042 if (*s != NUL) /* check for trailing chars after expr */ 10043 { 10044 EMSG2(_(e_invexpr2), s); 10045 goto theend; 10046 } 10047 if (map) 10048 { 10049 /* map(): replace the list item value */ 10050 clear_tv(tv); 10051 rettv.v_lock = 0; 10052 *tv = rettv; 10053 } 10054 else 10055 { 10056 int error = FALSE; 10057 10058 /* filter(): when expr is zero remove the item */ 10059 *remp = (get_tv_number_chk(&rettv, &error) == 0); 10060 clear_tv(&rettv); 10061 /* On type error, nothing has been removed; return FAIL to stop the 10062 * loop. The error message was given by get_tv_number_chk(). */ 10063 if (error) 10064 goto theend; 10065 } 10066 retval = OK; 10067 theend: 10068 clear_tv(&vimvars[VV_VAL].vv_tv); 10069 return retval; 10070 } 10071 10072 /* 10073 * "filter()" function 10074 */ 10075 static void 10076 f_filter(argvars, rettv) 10077 typval_T *argvars; 10078 typval_T *rettv; 10079 { 10080 filter_map(argvars, rettv, FALSE); 10081 } 10082 10083 /* 10084 * "finddir({fname}[, {path}[, {count}]])" function 10085 */ 10086 static void 10087 f_finddir(argvars, rettv) 10088 typval_T *argvars; 10089 typval_T *rettv; 10090 { 10091 findfilendir(argvars, rettv, FINDFILE_DIR); 10092 } 10093 10094 /* 10095 * "findfile({fname}[, {path}[, {count}]])" function 10096 */ 10097 static void 10098 f_findfile(argvars, rettv) 10099 typval_T *argvars; 10100 typval_T *rettv; 10101 { 10102 findfilendir(argvars, rettv, FINDFILE_FILE); 10103 } 10104 10105 #ifdef FEAT_FLOAT 10106 /* 10107 * "float2nr({float})" function 10108 */ 10109 static void 10110 f_float2nr(argvars, rettv) 10111 typval_T *argvars; 10112 typval_T *rettv; 10113 { 10114 float_T f; 10115 10116 if (get_float_arg(argvars, &f) == OK) 10117 { 10118 if (f < -0x7fffffff) 10119 rettv->vval.v_number = -0x7fffffff; 10120 else if (f > 0x7fffffff) 10121 rettv->vval.v_number = 0x7fffffff; 10122 else 10123 rettv->vval.v_number = (varnumber_T)f; 10124 } 10125 } 10126 10127 /* 10128 * "floor({float})" function 10129 */ 10130 static void 10131 f_floor(argvars, rettv) 10132 typval_T *argvars; 10133 typval_T *rettv; 10134 { 10135 float_T f; 10136 10137 rettv->v_type = VAR_FLOAT; 10138 if (get_float_arg(argvars, &f) == OK) 10139 rettv->vval.v_float = floor(f); 10140 else 10141 rettv->vval.v_float = 0.0; 10142 } 10143 #endif 10144 10145 /* 10146 * "fnameescape({string})" function 10147 */ 10148 static void 10149 f_fnameescape(argvars, rettv) 10150 typval_T *argvars; 10151 typval_T *rettv; 10152 { 10153 rettv->vval.v_string = vim_strsave_fnameescape( 10154 get_tv_string(&argvars[0]), FALSE); 10155 rettv->v_type = VAR_STRING; 10156 } 10157 10158 /* 10159 * "fnamemodify({fname}, {mods})" function 10160 */ 10161 static void 10162 f_fnamemodify(argvars, rettv) 10163 typval_T *argvars; 10164 typval_T *rettv; 10165 { 10166 char_u *fname; 10167 char_u *mods; 10168 int usedlen = 0; 10169 int len; 10170 char_u *fbuf = NULL; 10171 char_u buf[NUMBUFLEN]; 10172 10173 fname = get_tv_string_chk(&argvars[0]); 10174 mods = get_tv_string_buf_chk(&argvars[1], buf); 10175 if (fname == NULL || mods == NULL) 10176 fname = NULL; 10177 else 10178 { 10179 len = (int)STRLEN(fname); 10180 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 10181 } 10182 10183 rettv->v_type = VAR_STRING; 10184 if (fname == NULL) 10185 rettv->vval.v_string = NULL; 10186 else 10187 rettv->vval.v_string = vim_strnsave(fname, len); 10188 vim_free(fbuf); 10189 } 10190 10191 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 10192 10193 /* 10194 * "foldclosed()" function 10195 */ 10196 static void 10197 foldclosed_both(argvars, rettv, end) 10198 typval_T *argvars; 10199 typval_T *rettv; 10200 int end; 10201 { 10202 #ifdef FEAT_FOLDING 10203 linenr_T lnum; 10204 linenr_T first, last; 10205 10206 lnum = get_tv_lnum(argvars); 10207 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10208 { 10209 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 10210 { 10211 if (end) 10212 rettv->vval.v_number = (varnumber_T)last; 10213 else 10214 rettv->vval.v_number = (varnumber_T)first; 10215 return; 10216 } 10217 } 10218 #endif 10219 rettv->vval.v_number = -1; 10220 } 10221 10222 /* 10223 * "foldclosed()" function 10224 */ 10225 static void 10226 f_foldclosed(argvars, rettv) 10227 typval_T *argvars; 10228 typval_T *rettv; 10229 { 10230 foldclosed_both(argvars, rettv, FALSE); 10231 } 10232 10233 /* 10234 * "foldclosedend()" function 10235 */ 10236 static void 10237 f_foldclosedend(argvars, rettv) 10238 typval_T *argvars; 10239 typval_T *rettv; 10240 { 10241 foldclosed_both(argvars, rettv, TRUE); 10242 } 10243 10244 /* 10245 * "foldlevel()" function 10246 */ 10247 static void 10248 f_foldlevel(argvars, rettv) 10249 typval_T *argvars; 10250 typval_T *rettv; 10251 { 10252 #ifdef FEAT_FOLDING 10253 linenr_T lnum; 10254 10255 lnum = get_tv_lnum(argvars); 10256 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10257 rettv->vval.v_number = foldLevel(lnum); 10258 #endif 10259 } 10260 10261 /* 10262 * "foldtext()" function 10263 */ 10264 static void 10265 f_foldtext(argvars, rettv) 10266 typval_T *argvars UNUSED; 10267 typval_T *rettv; 10268 { 10269 #ifdef FEAT_FOLDING 10270 linenr_T lnum; 10271 char_u *s; 10272 char_u *r; 10273 int len; 10274 char *txt; 10275 #endif 10276 10277 rettv->v_type = VAR_STRING; 10278 rettv->vval.v_string = NULL; 10279 #ifdef FEAT_FOLDING 10280 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 10281 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 10282 <= curbuf->b_ml.ml_line_count 10283 && vimvars[VV_FOLDDASHES].vv_str != NULL) 10284 { 10285 /* Find first non-empty line in the fold. */ 10286 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 10287 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 10288 { 10289 if (!linewhite(lnum)) 10290 break; 10291 ++lnum; 10292 } 10293 10294 /* Find interesting text in this line. */ 10295 s = skipwhite(ml_get(lnum)); 10296 /* skip C comment-start */ 10297 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 10298 { 10299 s = skipwhite(s + 2); 10300 if (*skipwhite(s) == NUL 10301 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 10302 { 10303 s = skipwhite(ml_get(lnum + 1)); 10304 if (*s == '*') 10305 s = skipwhite(s + 1); 10306 } 10307 } 10308 txt = _("+-%s%3ld lines: "); 10309 r = alloc((unsigned)(STRLEN(txt) 10310 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 10311 + 20 /* for %3ld */ 10312 + STRLEN(s))); /* concatenated */ 10313 if (r != NULL) 10314 { 10315 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 10316 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 10317 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 10318 len = (int)STRLEN(r); 10319 STRCAT(r, s); 10320 /* remove 'foldmarker' and 'commentstring' */ 10321 foldtext_cleanup(r + len); 10322 rettv->vval.v_string = r; 10323 } 10324 } 10325 #endif 10326 } 10327 10328 /* 10329 * "foldtextresult(lnum)" function 10330 */ 10331 static void 10332 f_foldtextresult(argvars, rettv) 10333 typval_T *argvars UNUSED; 10334 typval_T *rettv; 10335 { 10336 #ifdef FEAT_FOLDING 10337 linenr_T lnum; 10338 char_u *text; 10339 char_u buf[51]; 10340 foldinfo_T foldinfo; 10341 int fold_count; 10342 #endif 10343 10344 rettv->v_type = VAR_STRING; 10345 rettv->vval.v_string = NULL; 10346 #ifdef FEAT_FOLDING 10347 lnum = get_tv_lnum(argvars); 10348 /* treat illegal types and illegal string values for {lnum} the same */ 10349 if (lnum < 0) 10350 lnum = 0; 10351 fold_count = foldedCount(curwin, lnum, &foldinfo); 10352 if (fold_count > 0) 10353 { 10354 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 10355 &foldinfo, buf); 10356 if (text == buf) 10357 text = vim_strsave(text); 10358 rettv->vval.v_string = text; 10359 } 10360 #endif 10361 } 10362 10363 /* 10364 * "foreground()" function 10365 */ 10366 static void 10367 f_foreground(argvars, rettv) 10368 typval_T *argvars UNUSED; 10369 typval_T *rettv UNUSED; 10370 { 10371 #ifdef FEAT_GUI 10372 if (gui.in_use) 10373 gui_mch_set_foreground(); 10374 #else 10375 # ifdef WIN32 10376 win32_set_foreground(); 10377 # endif 10378 #endif 10379 } 10380 10381 /* 10382 * "function()" function 10383 */ 10384 static void 10385 f_function(argvars, rettv) 10386 typval_T *argvars; 10387 typval_T *rettv; 10388 { 10389 char_u *s; 10390 10391 s = get_tv_string(&argvars[0]); 10392 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 10393 EMSG2(_(e_invarg2), s); 10394 /* Don't check an autoload name for existence here. */ 10395 else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s)) 10396 EMSG2(_("E700: Unknown function: %s"), s); 10397 else 10398 { 10399 rettv->vval.v_string = vim_strsave(s); 10400 rettv->v_type = VAR_FUNC; 10401 } 10402 } 10403 10404 /* 10405 * "garbagecollect()" function 10406 */ 10407 static void 10408 f_garbagecollect(argvars, rettv) 10409 typval_T *argvars; 10410 typval_T *rettv UNUSED; 10411 { 10412 /* This is postponed until we are back at the toplevel, because we may be 10413 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ 10414 want_garbage_collect = TRUE; 10415 10416 if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1) 10417 garbage_collect_at_exit = TRUE; 10418 } 10419 10420 /* 10421 * "get()" function 10422 */ 10423 static void 10424 f_get(argvars, rettv) 10425 typval_T *argvars; 10426 typval_T *rettv; 10427 { 10428 listitem_T *li; 10429 list_T *l; 10430 dictitem_T *di; 10431 dict_T *d; 10432 typval_T *tv = NULL; 10433 10434 if (argvars[0].v_type == VAR_LIST) 10435 { 10436 if ((l = argvars[0].vval.v_list) != NULL) 10437 { 10438 int error = FALSE; 10439 10440 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 10441 if (!error && li != NULL) 10442 tv = &li->li_tv; 10443 } 10444 } 10445 else if (argvars[0].v_type == VAR_DICT) 10446 { 10447 if ((d = argvars[0].vval.v_dict) != NULL) 10448 { 10449 di = dict_find(d, get_tv_string(&argvars[1]), -1); 10450 if (di != NULL) 10451 tv = &di->di_tv; 10452 } 10453 } 10454 else 10455 EMSG2(_(e_listdictarg), "get()"); 10456 10457 if (tv == NULL) 10458 { 10459 if (argvars[2].v_type != VAR_UNKNOWN) 10460 copy_tv(&argvars[2], rettv); 10461 } 10462 else 10463 copy_tv(tv, rettv); 10464 } 10465 10466 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 10467 10468 /* 10469 * Get line or list of lines from buffer "buf" into "rettv". 10470 * Return a range (from start to end) of lines in rettv from the specified 10471 * buffer. 10472 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 10473 */ 10474 static void 10475 get_buffer_lines(buf, start, end, retlist, rettv) 10476 buf_T *buf; 10477 linenr_T start; 10478 linenr_T end; 10479 int retlist; 10480 typval_T *rettv; 10481 { 10482 char_u *p; 10483 10484 if (retlist && rettv_list_alloc(rettv) == FAIL) 10485 return; 10486 10487 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 10488 return; 10489 10490 if (!retlist) 10491 { 10492 if (start >= 1 && start <= buf->b_ml.ml_line_count) 10493 p = ml_get_buf(buf, start, FALSE); 10494 else 10495 p = (char_u *)""; 10496 10497 rettv->v_type = VAR_STRING; 10498 rettv->vval.v_string = vim_strsave(p); 10499 } 10500 else 10501 { 10502 if (end < start) 10503 return; 10504 10505 if (start < 1) 10506 start = 1; 10507 if (end > buf->b_ml.ml_line_count) 10508 end = buf->b_ml.ml_line_count; 10509 while (start <= end) 10510 if (list_append_string(rettv->vval.v_list, 10511 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 10512 break; 10513 } 10514 } 10515 10516 /* 10517 * "getbufline()" function 10518 */ 10519 static void 10520 f_getbufline(argvars, rettv) 10521 typval_T *argvars; 10522 typval_T *rettv; 10523 { 10524 linenr_T lnum; 10525 linenr_T end; 10526 buf_T *buf; 10527 10528 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 10529 ++emsg_off; 10530 buf = get_buf_tv(&argvars[0]); 10531 --emsg_off; 10532 10533 lnum = get_tv_lnum_buf(&argvars[1], buf); 10534 if (argvars[2].v_type == VAR_UNKNOWN) 10535 end = lnum; 10536 else 10537 end = get_tv_lnum_buf(&argvars[2], buf); 10538 10539 get_buffer_lines(buf, lnum, end, TRUE, rettv); 10540 } 10541 10542 /* 10543 * "getbufvar()" function 10544 */ 10545 static void 10546 f_getbufvar(argvars, rettv) 10547 typval_T *argvars; 10548 typval_T *rettv; 10549 { 10550 buf_T *buf; 10551 buf_T *save_curbuf; 10552 char_u *varname; 10553 dictitem_T *v; 10554 10555 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 10556 varname = get_tv_string_chk(&argvars[1]); 10557 ++emsg_off; 10558 buf = get_buf_tv(&argvars[0]); 10559 10560 rettv->v_type = VAR_STRING; 10561 rettv->vval.v_string = NULL; 10562 10563 if (buf != NULL && varname != NULL) 10564 { 10565 /* set curbuf to be our buf, temporarily */ 10566 save_curbuf = curbuf; 10567 curbuf = buf; 10568 10569 if (*varname == '&') /* buffer-local-option */ 10570 get_option_tv(&varname, rettv, TRUE); 10571 else 10572 { 10573 if (*varname == NUL) 10574 /* let getbufvar({nr}, "") return the "b:" dictionary. The 10575 * scope prefix before the NUL byte is required by 10576 * find_var_in_ht(). */ 10577 varname = (char_u *)"b:" + 2; 10578 /* look up the variable */ 10579 v = find_var_in_ht(&curbuf->b_vars.dv_hashtab, varname, FALSE); 10580 if (v != NULL) 10581 copy_tv(&v->di_tv, rettv); 10582 } 10583 10584 /* restore previous notion of curbuf */ 10585 curbuf = save_curbuf; 10586 } 10587 10588 --emsg_off; 10589 } 10590 10591 /* 10592 * "getchar()" function 10593 */ 10594 static void 10595 f_getchar(argvars, rettv) 10596 typval_T *argvars; 10597 typval_T *rettv; 10598 { 10599 varnumber_T n; 10600 int error = FALSE; 10601 10602 /* Position the cursor. Needed after a message that ends in a space. */ 10603 windgoto(msg_row, msg_col); 10604 10605 ++no_mapping; 10606 ++allow_keys; 10607 for (;;) 10608 { 10609 if (argvars[0].v_type == VAR_UNKNOWN) 10610 /* getchar(): blocking wait. */ 10611 n = safe_vgetc(); 10612 else if (get_tv_number_chk(&argvars[0], &error) == 1) 10613 /* getchar(1): only check if char avail */ 10614 n = vpeekc(); 10615 else if (error || vpeekc() == NUL) 10616 /* illegal argument or getchar(0) and no char avail: return zero */ 10617 n = 0; 10618 else 10619 /* getchar(0) and char avail: return char */ 10620 n = safe_vgetc(); 10621 if (n == K_IGNORE) 10622 continue; 10623 break; 10624 } 10625 --no_mapping; 10626 --allow_keys; 10627 10628 vimvars[VV_MOUSE_WIN].vv_nr = 0; 10629 vimvars[VV_MOUSE_LNUM].vv_nr = 0; 10630 vimvars[VV_MOUSE_COL].vv_nr = 0; 10631 10632 rettv->vval.v_number = n; 10633 if (IS_SPECIAL(n) || mod_mask != 0) 10634 { 10635 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 10636 int i = 0; 10637 10638 /* Turn a special key into three bytes, plus modifier. */ 10639 if (mod_mask != 0) 10640 { 10641 temp[i++] = K_SPECIAL; 10642 temp[i++] = KS_MODIFIER; 10643 temp[i++] = mod_mask; 10644 } 10645 if (IS_SPECIAL(n)) 10646 { 10647 temp[i++] = K_SPECIAL; 10648 temp[i++] = K_SECOND(n); 10649 temp[i++] = K_THIRD(n); 10650 } 10651 #ifdef FEAT_MBYTE 10652 else if (has_mbyte) 10653 i += (*mb_char2bytes)(n, temp + i); 10654 #endif 10655 else 10656 temp[i++] = n; 10657 temp[i++] = NUL; 10658 rettv->v_type = VAR_STRING; 10659 rettv->vval.v_string = vim_strsave(temp); 10660 10661 #ifdef FEAT_MOUSE 10662 if (n == K_LEFTMOUSE 10663 || n == K_LEFTMOUSE_NM 10664 || n == K_LEFTDRAG 10665 || n == K_LEFTRELEASE 10666 || n == K_LEFTRELEASE_NM 10667 || n == K_MIDDLEMOUSE 10668 || n == K_MIDDLEDRAG 10669 || n == K_MIDDLERELEASE 10670 || n == K_RIGHTMOUSE 10671 || n == K_RIGHTDRAG 10672 || n == K_RIGHTRELEASE 10673 || n == K_X1MOUSE 10674 || n == K_X1DRAG 10675 || n == K_X1RELEASE 10676 || n == K_X2MOUSE 10677 || n == K_X2DRAG 10678 || n == K_X2RELEASE 10679 || n == K_MOUSEDOWN 10680 || n == K_MOUSEUP) 10681 { 10682 int row = mouse_row; 10683 int col = mouse_col; 10684 win_T *win; 10685 linenr_T lnum; 10686 # ifdef FEAT_WINDOWS 10687 win_T *wp; 10688 # endif 10689 int winnr = 1; 10690 10691 if (row >= 0 && col >= 0) 10692 { 10693 /* Find the window at the mouse coordinates and compute the 10694 * text position. */ 10695 win = mouse_find_win(&row, &col); 10696 (void)mouse_comp_pos(win, &row, &col, &lnum); 10697 # ifdef FEAT_WINDOWS 10698 for (wp = firstwin; wp != win; wp = wp->w_next) 10699 ++winnr; 10700 # endif 10701 vimvars[VV_MOUSE_WIN].vv_nr = winnr; 10702 vimvars[VV_MOUSE_LNUM].vv_nr = lnum; 10703 vimvars[VV_MOUSE_COL].vv_nr = col + 1; 10704 } 10705 } 10706 #endif 10707 } 10708 } 10709 10710 /* 10711 * "getcharmod()" function 10712 */ 10713 static void 10714 f_getcharmod(argvars, rettv) 10715 typval_T *argvars UNUSED; 10716 typval_T *rettv; 10717 { 10718 rettv->vval.v_number = mod_mask; 10719 } 10720 10721 /* 10722 * "getcmdline()" function 10723 */ 10724 static void 10725 f_getcmdline(argvars, rettv) 10726 typval_T *argvars UNUSED; 10727 typval_T *rettv; 10728 { 10729 rettv->v_type = VAR_STRING; 10730 rettv->vval.v_string = get_cmdline_str(); 10731 } 10732 10733 /* 10734 * "getcmdpos()" function 10735 */ 10736 static void 10737 f_getcmdpos(argvars, rettv) 10738 typval_T *argvars UNUSED; 10739 typval_T *rettv; 10740 { 10741 rettv->vval.v_number = get_cmdline_pos() + 1; 10742 } 10743 10744 /* 10745 * "getcmdtype()" function 10746 */ 10747 static void 10748 f_getcmdtype(argvars, rettv) 10749 typval_T *argvars UNUSED; 10750 typval_T *rettv; 10751 { 10752 rettv->v_type = VAR_STRING; 10753 rettv->vval.v_string = alloc(2); 10754 if (rettv->vval.v_string != NULL) 10755 { 10756 rettv->vval.v_string[0] = get_cmdline_type(); 10757 rettv->vval.v_string[1] = NUL; 10758 } 10759 } 10760 10761 /* 10762 * "getcwd()" function 10763 */ 10764 static void 10765 f_getcwd(argvars, rettv) 10766 typval_T *argvars UNUSED; 10767 typval_T *rettv; 10768 { 10769 char_u cwd[MAXPATHL]; 10770 10771 rettv->v_type = VAR_STRING; 10772 if (mch_dirname(cwd, MAXPATHL) == FAIL) 10773 rettv->vval.v_string = NULL; 10774 else 10775 { 10776 rettv->vval.v_string = vim_strsave(cwd); 10777 #ifdef BACKSLASH_IN_FILENAME 10778 if (rettv->vval.v_string != NULL) 10779 slash_adjust(rettv->vval.v_string); 10780 #endif 10781 } 10782 } 10783 10784 /* 10785 * "getfontname()" function 10786 */ 10787 static void 10788 f_getfontname(argvars, rettv) 10789 typval_T *argvars UNUSED; 10790 typval_T *rettv; 10791 { 10792 rettv->v_type = VAR_STRING; 10793 rettv->vval.v_string = NULL; 10794 #ifdef FEAT_GUI 10795 if (gui.in_use) 10796 { 10797 GuiFont font; 10798 char_u *name = NULL; 10799 10800 if (argvars[0].v_type == VAR_UNKNOWN) 10801 { 10802 /* Get the "Normal" font. Either the name saved by 10803 * hl_set_font_name() or from the font ID. */ 10804 font = gui.norm_font; 10805 name = hl_get_font_name(); 10806 } 10807 else 10808 { 10809 name = get_tv_string(&argvars[0]); 10810 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 10811 return; 10812 font = gui_mch_get_font(name, FALSE); 10813 if (font == NOFONT) 10814 return; /* Invalid font name, return empty string. */ 10815 } 10816 rettv->vval.v_string = gui_mch_get_fontname(font, name); 10817 if (argvars[0].v_type != VAR_UNKNOWN) 10818 gui_mch_free_font(font); 10819 } 10820 #endif 10821 } 10822 10823 /* 10824 * "getfperm({fname})" function 10825 */ 10826 static void 10827 f_getfperm(argvars, rettv) 10828 typval_T *argvars; 10829 typval_T *rettv; 10830 { 10831 char_u *fname; 10832 struct stat st; 10833 char_u *perm = NULL; 10834 char_u flags[] = "rwx"; 10835 int i; 10836 10837 fname = get_tv_string(&argvars[0]); 10838 10839 rettv->v_type = VAR_STRING; 10840 if (mch_stat((char *)fname, &st) >= 0) 10841 { 10842 perm = vim_strsave((char_u *)"---------"); 10843 if (perm != NULL) 10844 { 10845 for (i = 0; i < 9; i++) 10846 { 10847 if (st.st_mode & (1 << (8 - i))) 10848 perm[i] = flags[i % 3]; 10849 } 10850 } 10851 } 10852 rettv->vval.v_string = perm; 10853 } 10854 10855 /* 10856 * "getfsize({fname})" function 10857 */ 10858 static void 10859 f_getfsize(argvars, rettv) 10860 typval_T *argvars; 10861 typval_T *rettv; 10862 { 10863 char_u *fname; 10864 struct stat st; 10865 10866 fname = get_tv_string(&argvars[0]); 10867 10868 rettv->v_type = VAR_NUMBER; 10869 10870 if (mch_stat((char *)fname, &st) >= 0) 10871 { 10872 if (mch_isdir(fname)) 10873 rettv->vval.v_number = 0; 10874 else 10875 { 10876 rettv->vval.v_number = (varnumber_T)st.st_size; 10877 10878 /* non-perfect check for overflow */ 10879 if ((off_t)rettv->vval.v_number != (off_t)st.st_size) 10880 rettv->vval.v_number = -2; 10881 } 10882 } 10883 else 10884 rettv->vval.v_number = -1; 10885 } 10886 10887 /* 10888 * "getftime({fname})" function 10889 */ 10890 static void 10891 f_getftime(argvars, rettv) 10892 typval_T *argvars; 10893 typval_T *rettv; 10894 { 10895 char_u *fname; 10896 struct stat st; 10897 10898 fname = get_tv_string(&argvars[0]); 10899 10900 if (mch_stat((char *)fname, &st) >= 0) 10901 rettv->vval.v_number = (varnumber_T)st.st_mtime; 10902 else 10903 rettv->vval.v_number = -1; 10904 } 10905 10906 /* 10907 * "getftype({fname})" function 10908 */ 10909 static void 10910 f_getftype(argvars, rettv) 10911 typval_T *argvars; 10912 typval_T *rettv; 10913 { 10914 char_u *fname; 10915 struct stat st; 10916 char_u *type = NULL; 10917 char *t; 10918 10919 fname = get_tv_string(&argvars[0]); 10920 10921 rettv->v_type = VAR_STRING; 10922 if (mch_lstat((char *)fname, &st) >= 0) 10923 { 10924 #ifdef S_ISREG 10925 if (S_ISREG(st.st_mode)) 10926 t = "file"; 10927 else if (S_ISDIR(st.st_mode)) 10928 t = "dir"; 10929 # ifdef S_ISLNK 10930 else if (S_ISLNK(st.st_mode)) 10931 t = "link"; 10932 # endif 10933 # ifdef S_ISBLK 10934 else if (S_ISBLK(st.st_mode)) 10935 t = "bdev"; 10936 # endif 10937 # ifdef S_ISCHR 10938 else if (S_ISCHR(st.st_mode)) 10939 t = "cdev"; 10940 # endif 10941 # ifdef S_ISFIFO 10942 else if (S_ISFIFO(st.st_mode)) 10943 t = "fifo"; 10944 # endif 10945 # ifdef S_ISSOCK 10946 else if (S_ISSOCK(st.st_mode)) 10947 t = "fifo"; 10948 # endif 10949 else 10950 t = "other"; 10951 #else 10952 # ifdef S_IFMT 10953 switch (st.st_mode & S_IFMT) 10954 { 10955 case S_IFREG: t = "file"; break; 10956 case S_IFDIR: t = "dir"; break; 10957 # ifdef S_IFLNK 10958 case S_IFLNK: t = "link"; break; 10959 # endif 10960 # ifdef S_IFBLK 10961 case S_IFBLK: t = "bdev"; break; 10962 # endif 10963 # ifdef S_IFCHR 10964 case S_IFCHR: t = "cdev"; break; 10965 # endif 10966 # ifdef S_IFIFO 10967 case S_IFIFO: t = "fifo"; break; 10968 # endif 10969 # ifdef S_IFSOCK 10970 case S_IFSOCK: t = "socket"; break; 10971 # endif 10972 default: t = "other"; 10973 } 10974 # else 10975 if (mch_isdir(fname)) 10976 t = "dir"; 10977 else 10978 t = "file"; 10979 # endif 10980 #endif 10981 type = vim_strsave((char_u *)t); 10982 } 10983 rettv->vval.v_string = type; 10984 } 10985 10986 /* 10987 * "getline(lnum, [end])" function 10988 */ 10989 static void 10990 f_getline(argvars, rettv) 10991 typval_T *argvars; 10992 typval_T *rettv; 10993 { 10994 linenr_T lnum; 10995 linenr_T end; 10996 int retlist; 10997 10998 lnum = get_tv_lnum(argvars); 10999 if (argvars[1].v_type == VAR_UNKNOWN) 11000 { 11001 end = 0; 11002 retlist = FALSE; 11003 } 11004 else 11005 { 11006 end = get_tv_lnum(&argvars[1]); 11007 retlist = TRUE; 11008 } 11009 11010 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 11011 } 11012 11013 /* 11014 * "getmatches()" function 11015 */ 11016 static void 11017 f_getmatches(argvars, rettv) 11018 typval_T *argvars UNUSED; 11019 typval_T *rettv; 11020 { 11021 #ifdef FEAT_SEARCH_EXTRA 11022 dict_T *dict; 11023 matchitem_T *cur = curwin->w_match_head; 11024 11025 if (rettv_list_alloc(rettv) == OK) 11026 { 11027 while (cur != NULL) 11028 { 11029 dict = dict_alloc(); 11030 if (dict == NULL) 11031 return; 11032 dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id)); 11033 dict_add_nr_str(dict, "pattern", 0L, cur->pattern); 11034 dict_add_nr_str(dict, "priority", (long)cur->priority, NULL); 11035 dict_add_nr_str(dict, "id", (long)cur->id, NULL); 11036 list_append_dict(rettv->vval.v_list, dict); 11037 cur = cur->next; 11038 } 11039 } 11040 #endif 11041 } 11042 11043 /* 11044 * "getpid()" function 11045 */ 11046 static void 11047 f_getpid(argvars, rettv) 11048 typval_T *argvars UNUSED; 11049 typval_T *rettv; 11050 { 11051 rettv->vval.v_number = mch_get_pid(); 11052 } 11053 11054 /* 11055 * "getpos(string)" function 11056 */ 11057 static void 11058 f_getpos(argvars, rettv) 11059 typval_T *argvars; 11060 typval_T *rettv; 11061 { 11062 pos_T *fp; 11063 list_T *l; 11064 int fnum = -1; 11065 11066 if (rettv_list_alloc(rettv) == OK) 11067 { 11068 l = rettv->vval.v_list; 11069 fp = var2fpos(&argvars[0], TRUE, &fnum); 11070 if (fnum != -1) 11071 list_append_number(l, (varnumber_T)fnum); 11072 else 11073 list_append_number(l, (varnumber_T)0); 11074 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 11075 : (varnumber_T)0); 11076 list_append_number(l, (fp != NULL) 11077 ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1) 11078 : (varnumber_T)0); 11079 list_append_number(l, 11080 #ifdef FEAT_VIRTUALEDIT 11081 (fp != NULL) ? (varnumber_T)fp->coladd : 11082 #endif 11083 (varnumber_T)0); 11084 } 11085 else 11086 rettv->vval.v_number = FALSE; 11087 } 11088 11089 /* 11090 * "getqflist()" and "getloclist()" functions 11091 */ 11092 static void 11093 f_getqflist(argvars, rettv) 11094 typval_T *argvars UNUSED; 11095 typval_T *rettv UNUSED; 11096 { 11097 #ifdef FEAT_QUICKFIX 11098 win_T *wp; 11099 #endif 11100 11101 #ifdef FEAT_QUICKFIX 11102 if (rettv_list_alloc(rettv) == OK) 11103 { 11104 wp = NULL; 11105 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 11106 { 11107 wp = find_win_by_nr(&argvars[0], NULL); 11108 if (wp == NULL) 11109 return; 11110 } 11111 11112 (void)get_errorlist(wp, rettv->vval.v_list); 11113 } 11114 #endif 11115 } 11116 11117 /* 11118 * "getreg()" function 11119 */ 11120 static void 11121 f_getreg(argvars, rettv) 11122 typval_T *argvars; 11123 typval_T *rettv; 11124 { 11125 char_u *strregname; 11126 int regname; 11127 int arg2 = FALSE; 11128 int error = FALSE; 11129 11130 if (argvars[0].v_type != VAR_UNKNOWN) 11131 { 11132 strregname = get_tv_string_chk(&argvars[0]); 11133 error = strregname == NULL; 11134 if (argvars[1].v_type != VAR_UNKNOWN) 11135 arg2 = get_tv_number_chk(&argvars[1], &error); 11136 } 11137 else 11138 strregname = vimvars[VV_REG].vv_str; 11139 regname = (strregname == NULL ? '"' : *strregname); 11140 if (regname == 0) 11141 regname = '"'; 11142 11143 rettv->v_type = VAR_STRING; 11144 rettv->vval.v_string = error ? NULL : 11145 get_reg_contents(regname, TRUE, arg2); 11146 } 11147 11148 /* 11149 * "getregtype()" function 11150 */ 11151 static void 11152 f_getregtype(argvars, rettv) 11153 typval_T *argvars; 11154 typval_T *rettv; 11155 { 11156 char_u *strregname; 11157 int regname; 11158 char_u buf[NUMBUFLEN + 2]; 11159 long reglen = 0; 11160 11161 if (argvars[0].v_type != VAR_UNKNOWN) 11162 { 11163 strregname = get_tv_string_chk(&argvars[0]); 11164 if (strregname == NULL) /* type error; errmsg already given */ 11165 { 11166 rettv->v_type = VAR_STRING; 11167 rettv->vval.v_string = NULL; 11168 return; 11169 } 11170 } 11171 else 11172 /* Default to v:register */ 11173 strregname = vimvars[VV_REG].vv_str; 11174 11175 regname = (strregname == NULL ? '"' : *strregname); 11176 if (regname == 0) 11177 regname = '"'; 11178 11179 buf[0] = NUL; 11180 buf[1] = NUL; 11181 switch (get_reg_type(regname, ®len)) 11182 { 11183 case MLINE: buf[0] = 'V'; break; 11184 case MCHAR: buf[0] = 'v'; break; 11185 #ifdef FEAT_VISUAL 11186 case MBLOCK: 11187 buf[0] = Ctrl_V; 11188 sprintf((char *)buf + 1, "%ld", reglen + 1); 11189 break; 11190 #endif 11191 } 11192 rettv->v_type = VAR_STRING; 11193 rettv->vval.v_string = vim_strsave(buf); 11194 } 11195 11196 /* 11197 * "gettabwinvar()" function 11198 */ 11199 static void 11200 f_gettabwinvar(argvars, rettv) 11201 typval_T *argvars; 11202 typval_T *rettv; 11203 { 11204 getwinvar(argvars, rettv, 1); 11205 } 11206 11207 /* 11208 * "getwinposx()" function 11209 */ 11210 static void 11211 f_getwinposx(argvars, rettv) 11212 typval_T *argvars UNUSED; 11213 typval_T *rettv; 11214 { 11215 rettv->vval.v_number = -1; 11216 #ifdef FEAT_GUI 11217 if (gui.in_use) 11218 { 11219 int x, y; 11220 11221 if (gui_mch_get_winpos(&x, &y) == OK) 11222 rettv->vval.v_number = x; 11223 } 11224 #endif 11225 } 11226 11227 /* 11228 * "getwinposy()" function 11229 */ 11230 static void 11231 f_getwinposy(argvars, rettv) 11232 typval_T *argvars UNUSED; 11233 typval_T *rettv; 11234 { 11235 rettv->vval.v_number = -1; 11236 #ifdef FEAT_GUI 11237 if (gui.in_use) 11238 { 11239 int x, y; 11240 11241 if (gui_mch_get_winpos(&x, &y) == OK) 11242 rettv->vval.v_number = y; 11243 } 11244 #endif 11245 } 11246 11247 /* 11248 * Find window specified by "vp" in tabpage "tp". 11249 */ 11250 static win_T * 11251 find_win_by_nr(vp, tp) 11252 typval_T *vp; 11253 tabpage_T *tp; /* NULL for current tab page */ 11254 { 11255 #ifdef FEAT_WINDOWS 11256 win_T *wp; 11257 #endif 11258 int nr; 11259 11260 nr = get_tv_number_chk(vp, NULL); 11261 11262 #ifdef FEAT_WINDOWS 11263 if (nr < 0) 11264 return NULL; 11265 if (nr == 0) 11266 return curwin; 11267 11268 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 11269 wp != NULL; wp = wp->w_next) 11270 if (--nr <= 0) 11271 break; 11272 return wp; 11273 #else 11274 if (nr == 0 || nr == 1) 11275 return curwin; 11276 return NULL; 11277 #endif 11278 } 11279 11280 /* 11281 * "getwinvar()" function 11282 */ 11283 static void 11284 f_getwinvar(argvars, rettv) 11285 typval_T *argvars; 11286 typval_T *rettv; 11287 { 11288 getwinvar(argvars, rettv, 0); 11289 } 11290 11291 /* 11292 * getwinvar() and gettabwinvar() 11293 */ 11294 static void 11295 getwinvar(argvars, rettv, off) 11296 typval_T *argvars; 11297 typval_T *rettv; 11298 int off; /* 1 for gettabwinvar() */ 11299 { 11300 win_T *win, *oldcurwin; 11301 char_u *varname; 11302 dictitem_T *v; 11303 tabpage_T *tp; 11304 11305 #ifdef FEAT_WINDOWS 11306 if (off == 1) 11307 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 11308 else 11309 tp = curtab; 11310 #endif 11311 win = find_win_by_nr(&argvars[off], tp); 11312 varname = get_tv_string_chk(&argvars[off + 1]); 11313 ++emsg_off; 11314 11315 rettv->v_type = VAR_STRING; 11316 rettv->vval.v_string = NULL; 11317 11318 if (win != NULL && varname != NULL) 11319 { 11320 /* Set curwin to be our win, temporarily. Also set curbuf, so 11321 * that we can get buffer-local options. */ 11322 oldcurwin = curwin; 11323 curwin = win; 11324 curbuf = win->w_buffer; 11325 11326 if (*varname == '&') /* window-local-option */ 11327 get_option_tv(&varname, rettv, 1); 11328 else 11329 { 11330 if (*varname == NUL) 11331 /* let getwinvar({nr}, "") return the "w:" dictionary. The 11332 * scope prefix before the NUL byte is required by 11333 * find_var_in_ht(). */ 11334 varname = (char_u *)"w:" + 2; 11335 /* look up the variable */ 11336 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 11337 if (v != NULL) 11338 copy_tv(&v->di_tv, rettv); 11339 } 11340 11341 /* restore previous notion of curwin */ 11342 curwin = oldcurwin; 11343 curbuf = curwin->w_buffer; 11344 } 11345 11346 --emsg_off; 11347 } 11348 11349 /* 11350 * "glob()" function 11351 */ 11352 static void 11353 f_glob(argvars, rettv) 11354 typval_T *argvars; 11355 typval_T *rettv; 11356 { 11357 int flags = WILD_SILENT|WILD_USE_NL; 11358 expand_T xpc; 11359 int error = FALSE; 11360 11361 /* When the optional second argument is non-zero, don't remove matches 11362 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11363 if (argvars[1].v_type != VAR_UNKNOWN 11364 && get_tv_number_chk(&argvars[1], &error)) 11365 flags |= WILD_KEEP_ALL; 11366 rettv->v_type = VAR_STRING; 11367 if (!error) 11368 { 11369 ExpandInit(&xpc); 11370 xpc.xp_context = EXPAND_FILES; 11371 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 11372 NULL, flags, WILD_ALL); 11373 } 11374 else 11375 rettv->vval.v_string = NULL; 11376 } 11377 11378 /* 11379 * "globpath()" function 11380 */ 11381 static void 11382 f_globpath(argvars, rettv) 11383 typval_T *argvars; 11384 typval_T *rettv; 11385 { 11386 int flags = 0; 11387 char_u buf1[NUMBUFLEN]; 11388 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 11389 int error = FALSE; 11390 11391 /* When the optional second argument is non-zero, don't remove matches 11392 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11393 if (argvars[2].v_type != VAR_UNKNOWN 11394 && get_tv_number_chk(&argvars[2], &error)) 11395 flags |= WILD_KEEP_ALL; 11396 rettv->v_type = VAR_STRING; 11397 if (file == NULL || error) 11398 rettv->vval.v_string = NULL; 11399 else 11400 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file, 11401 flags); 11402 } 11403 11404 /* 11405 * "has()" function 11406 */ 11407 static void 11408 f_has(argvars, rettv) 11409 typval_T *argvars; 11410 typval_T *rettv; 11411 { 11412 int i; 11413 char_u *name; 11414 int n = FALSE; 11415 static char *(has_list[]) = 11416 { 11417 #ifdef AMIGA 11418 "amiga", 11419 # ifdef FEAT_ARP 11420 "arp", 11421 # endif 11422 #endif 11423 #ifdef __BEOS__ 11424 "beos", 11425 #endif 11426 #ifdef MSDOS 11427 # ifdef DJGPP 11428 "dos32", 11429 # else 11430 "dos16", 11431 # endif 11432 #endif 11433 #ifdef MACOS 11434 "mac", 11435 #endif 11436 #if defined(MACOS_X_UNIX) 11437 "macunix", 11438 #endif 11439 #ifdef OS2 11440 "os2", 11441 #endif 11442 #ifdef __QNX__ 11443 "qnx", 11444 #endif 11445 #ifdef RISCOS 11446 "riscos", 11447 #endif 11448 #ifdef UNIX 11449 "unix", 11450 #endif 11451 #ifdef VMS 11452 "vms", 11453 #endif 11454 #ifdef WIN16 11455 "win16", 11456 #endif 11457 #ifdef WIN32 11458 "win32", 11459 #endif 11460 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 11461 "win32unix", 11462 #endif 11463 #if defined(WIN64) || defined(_WIN64) 11464 "win64", 11465 #endif 11466 #ifdef EBCDIC 11467 "ebcdic", 11468 #endif 11469 #ifndef CASE_INSENSITIVE_FILENAME 11470 "fname_case", 11471 #endif 11472 #ifdef FEAT_ARABIC 11473 "arabic", 11474 #endif 11475 #ifdef FEAT_AUTOCMD 11476 "autocmd", 11477 #endif 11478 #ifdef FEAT_BEVAL 11479 "balloon_eval", 11480 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 11481 "balloon_multiline", 11482 # endif 11483 #endif 11484 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 11485 "builtin_terms", 11486 # ifdef ALL_BUILTIN_TCAPS 11487 "all_builtin_terms", 11488 # endif 11489 #endif 11490 #ifdef FEAT_BYTEOFF 11491 "byte_offset", 11492 #endif 11493 #ifdef FEAT_CINDENT 11494 "cindent", 11495 #endif 11496 #ifdef FEAT_CLIENTSERVER 11497 "clientserver", 11498 #endif 11499 #ifdef FEAT_CLIPBOARD 11500 "clipboard", 11501 #endif 11502 #ifdef FEAT_CMDL_COMPL 11503 "cmdline_compl", 11504 #endif 11505 #ifdef FEAT_CMDHIST 11506 "cmdline_hist", 11507 #endif 11508 #ifdef FEAT_COMMENTS 11509 "comments", 11510 #endif 11511 #ifdef FEAT_CRYPT 11512 "cryptv", 11513 #endif 11514 #ifdef FEAT_CSCOPE 11515 "cscope", 11516 #endif 11517 #ifdef CURSOR_SHAPE 11518 "cursorshape", 11519 #endif 11520 #ifdef DEBUG 11521 "debug", 11522 #endif 11523 #ifdef FEAT_CON_DIALOG 11524 "dialog_con", 11525 #endif 11526 #ifdef FEAT_GUI_DIALOG 11527 "dialog_gui", 11528 #endif 11529 #ifdef FEAT_DIFF 11530 "diff", 11531 #endif 11532 #ifdef FEAT_DIGRAPHS 11533 "digraphs", 11534 #endif 11535 #ifdef FEAT_DND 11536 "dnd", 11537 #endif 11538 #ifdef FEAT_EMACS_TAGS 11539 "emacs_tags", 11540 #endif 11541 "eval", /* always present, of course! */ 11542 #ifdef FEAT_EX_EXTRA 11543 "ex_extra", 11544 #endif 11545 #ifdef FEAT_SEARCH_EXTRA 11546 "extra_search", 11547 #endif 11548 #ifdef FEAT_FKMAP 11549 "farsi", 11550 #endif 11551 #ifdef FEAT_SEARCHPATH 11552 "file_in_path", 11553 #endif 11554 #if defined(UNIX) && !defined(USE_SYSTEM) 11555 "filterpipe", 11556 #endif 11557 #ifdef FEAT_FIND_ID 11558 "find_in_path", 11559 #endif 11560 #ifdef FEAT_FLOAT 11561 "float", 11562 #endif 11563 #ifdef FEAT_FOLDING 11564 "folding", 11565 #endif 11566 #ifdef FEAT_FOOTER 11567 "footer", 11568 #endif 11569 #if !defined(USE_SYSTEM) && defined(UNIX) 11570 "fork", 11571 #endif 11572 #ifdef FEAT_GETTEXT 11573 "gettext", 11574 #endif 11575 #ifdef FEAT_GUI 11576 "gui", 11577 #endif 11578 #ifdef FEAT_GUI_ATHENA 11579 # ifdef FEAT_GUI_NEXTAW 11580 "gui_neXtaw", 11581 # else 11582 "gui_athena", 11583 # endif 11584 #endif 11585 #ifdef FEAT_GUI_GTK 11586 "gui_gtk", 11587 # ifdef HAVE_GTK2 11588 "gui_gtk2", 11589 # endif 11590 #endif 11591 #ifdef FEAT_GUI_GNOME 11592 "gui_gnome", 11593 #endif 11594 #ifdef FEAT_GUI_MAC 11595 "gui_mac", 11596 #endif 11597 #ifdef FEAT_GUI_MOTIF 11598 "gui_motif", 11599 #endif 11600 #ifdef FEAT_GUI_PHOTON 11601 "gui_photon", 11602 #endif 11603 #ifdef FEAT_GUI_W16 11604 "gui_win16", 11605 #endif 11606 #ifdef FEAT_GUI_W32 11607 "gui_win32", 11608 #endif 11609 #ifdef FEAT_HANGULIN 11610 "hangul_input", 11611 #endif 11612 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 11613 "iconv", 11614 #endif 11615 #ifdef FEAT_INS_EXPAND 11616 "insert_expand", 11617 #endif 11618 #ifdef FEAT_JUMPLIST 11619 "jumplist", 11620 #endif 11621 #ifdef FEAT_KEYMAP 11622 "keymap", 11623 #endif 11624 #ifdef FEAT_LANGMAP 11625 "langmap", 11626 #endif 11627 #ifdef FEAT_LIBCALL 11628 "libcall", 11629 #endif 11630 #ifdef FEAT_LINEBREAK 11631 "linebreak", 11632 #endif 11633 #ifdef FEAT_LISP 11634 "lispindent", 11635 #endif 11636 #ifdef FEAT_LISTCMDS 11637 "listcmds", 11638 #endif 11639 #ifdef FEAT_LOCALMAP 11640 "localmap", 11641 #endif 11642 #ifdef FEAT_MENU 11643 "menu", 11644 #endif 11645 #ifdef FEAT_SESSION 11646 "mksession", 11647 #endif 11648 #ifdef FEAT_MODIFY_FNAME 11649 "modify_fname", 11650 #endif 11651 #ifdef FEAT_MOUSE 11652 "mouse", 11653 #endif 11654 #ifdef FEAT_MOUSESHAPE 11655 "mouseshape", 11656 #endif 11657 #if defined(UNIX) || defined(VMS) 11658 # ifdef FEAT_MOUSE_DEC 11659 "mouse_dec", 11660 # endif 11661 # ifdef FEAT_MOUSE_GPM 11662 "mouse_gpm", 11663 # endif 11664 # ifdef FEAT_MOUSE_JSB 11665 "mouse_jsbterm", 11666 # endif 11667 # ifdef FEAT_MOUSE_NET 11668 "mouse_netterm", 11669 # endif 11670 # ifdef FEAT_MOUSE_PTERM 11671 "mouse_pterm", 11672 # endif 11673 # ifdef FEAT_SYSMOUSE 11674 "mouse_sysmouse", 11675 # endif 11676 # ifdef FEAT_MOUSE_XTERM 11677 "mouse_xterm", 11678 # endif 11679 #endif 11680 #ifdef FEAT_MBYTE 11681 "multi_byte", 11682 #endif 11683 #ifdef FEAT_MBYTE_IME 11684 "multi_byte_ime", 11685 #endif 11686 #ifdef FEAT_MULTI_LANG 11687 "multi_lang", 11688 #endif 11689 #ifdef FEAT_MZSCHEME 11690 #ifndef DYNAMIC_MZSCHEME 11691 "mzscheme", 11692 #endif 11693 #endif 11694 #ifdef FEAT_OLE 11695 "ole", 11696 #endif 11697 #ifdef FEAT_OSFILETYPE 11698 "osfiletype", 11699 #endif 11700 #ifdef FEAT_PATH_EXTRA 11701 "path_extra", 11702 #endif 11703 #ifdef FEAT_PERL 11704 #ifndef DYNAMIC_PERL 11705 "perl", 11706 #endif 11707 #endif 11708 #ifdef FEAT_PYTHON 11709 #ifndef DYNAMIC_PYTHON 11710 "python", 11711 #endif 11712 #endif 11713 #ifdef FEAT_POSTSCRIPT 11714 "postscript", 11715 #endif 11716 #ifdef FEAT_PRINTER 11717 "printer", 11718 #endif 11719 #ifdef FEAT_PROFILE 11720 "profile", 11721 #endif 11722 #ifdef FEAT_RELTIME 11723 "reltime", 11724 #endif 11725 #ifdef FEAT_QUICKFIX 11726 "quickfix", 11727 #endif 11728 #ifdef FEAT_RIGHTLEFT 11729 "rightleft", 11730 #endif 11731 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 11732 "ruby", 11733 #endif 11734 #ifdef FEAT_SCROLLBIND 11735 "scrollbind", 11736 #endif 11737 #ifdef FEAT_CMDL_INFO 11738 "showcmd", 11739 "cmdline_info", 11740 #endif 11741 #ifdef FEAT_SIGNS 11742 "signs", 11743 #endif 11744 #ifdef FEAT_SMARTINDENT 11745 "smartindent", 11746 #endif 11747 #ifdef FEAT_SNIFF 11748 "sniff", 11749 #endif 11750 #ifdef STARTUPTIME 11751 "startuptime", 11752 #endif 11753 #ifdef FEAT_STL_OPT 11754 "statusline", 11755 #endif 11756 #ifdef FEAT_SUN_WORKSHOP 11757 "sun_workshop", 11758 #endif 11759 #ifdef FEAT_NETBEANS_INTG 11760 "netbeans_intg", 11761 #endif 11762 #ifdef FEAT_SPELL 11763 "spell", 11764 #endif 11765 #ifdef FEAT_SYN_HL 11766 "syntax", 11767 #endif 11768 #if defined(USE_SYSTEM) || !defined(UNIX) 11769 "system", 11770 #endif 11771 #ifdef FEAT_TAG_BINS 11772 "tag_binary", 11773 #endif 11774 #ifdef FEAT_TAG_OLDSTATIC 11775 "tag_old_static", 11776 #endif 11777 #ifdef FEAT_TAG_ANYWHITE 11778 "tag_any_white", 11779 #endif 11780 #ifdef FEAT_TCL 11781 # ifndef DYNAMIC_TCL 11782 "tcl", 11783 # endif 11784 #endif 11785 #ifdef TERMINFO 11786 "terminfo", 11787 #endif 11788 #ifdef FEAT_TERMRESPONSE 11789 "termresponse", 11790 #endif 11791 #ifdef FEAT_TEXTOBJ 11792 "textobjects", 11793 #endif 11794 #ifdef HAVE_TGETENT 11795 "tgetent", 11796 #endif 11797 #ifdef FEAT_TITLE 11798 "title", 11799 #endif 11800 #ifdef FEAT_TOOLBAR 11801 "toolbar", 11802 #endif 11803 #ifdef FEAT_USR_CMDS 11804 "user-commands", /* was accidentally included in 5.4 */ 11805 "user_commands", 11806 #endif 11807 #ifdef FEAT_VIMINFO 11808 "viminfo", 11809 #endif 11810 #ifdef FEAT_VERTSPLIT 11811 "vertsplit", 11812 #endif 11813 #ifdef FEAT_VIRTUALEDIT 11814 "virtualedit", 11815 #endif 11816 #ifdef FEAT_VISUAL 11817 "visual", 11818 #endif 11819 #ifdef FEAT_VISUALEXTRA 11820 "visualextra", 11821 #endif 11822 #ifdef FEAT_VREPLACE 11823 "vreplace", 11824 #endif 11825 #ifdef FEAT_WILDIGN 11826 "wildignore", 11827 #endif 11828 #ifdef FEAT_WILDMENU 11829 "wildmenu", 11830 #endif 11831 #ifdef FEAT_WINDOWS 11832 "windows", 11833 #endif 11834 #ifdef FEAT_WAK 11835 "winaltkeys", 11836 #endif 11837 #ifdef FEAT_WRITEBACKUP 11838 "writebackup", 11839 #endif 11840 #ifdef FEAT_XIM 11841 "xim", 11842 #endif 11843 #ifdef FEAT_XFONTSET 11844 "xfontset", 11845 #endif 11846 #ifdef USE_XSMP 11847 "xsmp", 11848 #endif 11849 #ifdef USE_XSMP_INTERACT 11850 "xsmp_interact", 11851 #endif 11852 #ifdef FEAT_XCLIPBOARD 11853 "xterm_clipboard", 11854 #endif 11855 #ifdef FEAT_XTERM_SAVE 11856 "xterm_save", 11857 #endif 11858 #if defined(UNIX) && defined(FEAT_X11) 11859 "X11", 11860 #endif 11861 NULL 11862 }; 11863 11864 name = get_tv_string(&argvars[0]); 11865 for (i = 0; has_list[i] != NULL; ++i) 11866 if (STRICMP(name, has_list[i]) == 0) 11867 { 11868 n = TRUE; 11869 break; 11870 } 11871 11872 if (n == FALSE) 11873 { 11874 if (STRNICMP(name, "patch", 5) == 0) 11875 n = has_patch(atoi((char *)name + 5)); 11876 else if (STRICMP(name, "vim_starting") == 0) 11877 n = (starting != 0); 11878 #ifdef FEAT_MBYTE 11879 else if (STRICMP(name, "multi_byte_encoding") == 0) 11880 n = has_mbyte; 11881 #endif 11882 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 11883 else if (STRICMP(name, "balloon_multiline") == 0) 11884 n = multiline_balloon_available(); 11885 #endif 11886 #ifdef DYNAMIC_TCL 11887 else if (STRICMP(name, "tcl") == 0) 11888 n = tcl_enabled(FALSE); 11889 #endif 11890 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 11891 else if (STRICMP(name, "iconv") == 0) 11892 n = iconv_enabled(FALSE); 11893 #endif 11894 #ifdef DYNAMIC_MZSCHEME 11895 else if (STRICMP(name, "mzscheme") == 0) 11896 n = mzscheme_enabled(FALSE); 11897 #endif 11898 #ifdef DYNAMIC_RUBY 11899 else if (STRICMP(name, "ruby") == 0) 11900 n = ruby_enabled(FALSE); 11901 #endif 11902 #ifdef DYNAMIC_PYTHON 11903 else if (STRICMP(name, "python") == 0) 11904 n = python_enabled(FALSE); 11905 #endif 11906 #ifdef DYNAMIC_PERL 11907 else if (STRICMP(name, "perl") == 0) 11908 n = perl_enabled(FALSE); 11909 #endif 11910 #ifdef FEAT_GUI 11911 else if (STRICMP(name, "gui_running") == 0) 11912 n = (gui.in_use || gui.starting); 11913 # ifdef FEAT_GUI_W32 11914 else if (STRICMP(name, "gui_win32s") == 0) 11915 n = gui_is_win32s(); 11916 # endif 11917 # ifdef FEAT_BROWSE 11918 else if (STRICMP(name, "browse") == 0) 11919 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 11920 # endif 11921 #endif 11922 #ifdef FEAT_SYN_HL 11923 else if (STRICMP(name, "syntax_items") == 0) 11924 n = syntax_present(curbuf); 11925 #endif 11926 #if defined(WIN3264) 11927 else if (STRICMP(name, "win95") == 0) 11928 n = mch_windows95(); 11929 #endif 11930 #ifdef FEAT_NETBEANS_INTG 11931 else if (STRICMP(name, "netbeans_enabled") == 0) 11932 n = usingNetbeans; 11933 #endif 11934 } 11935 11936 rettv->vval.v_number = n; 11937 } 11938 11939 /* 11940 * "has_key()" function 11941 */ 11942 static void 11943 f_has_key(argvars, rettv) 11944 typval_T *argvars; 11945 typval_T *rettv; 11946 { 11947 if (argvars[0].v_type != VAR_DICT) 11948 { 11949 EMSG(_(e_dictreq)); 11950 return; 11951 } 11952 if (argvars[0].vval.v_dict == NULL) 11953 return; 11954 11955 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 11956 get_tv_string(&argvars[1]), -1) != NULL; 11957 } 11958 11959 /* 11960 * "haslocaldir()" function 11961 */ 11962 static void 11963 f_haslocaldir(argvars, rettv) 11964 typval_T *argvars UNUSED; 11965 typval_T *rettv; 11966 { 11967 rettv->vval.v_number = (curwin->w_localdir != NULL); 11968 } 11969 11970 /* 11971 * "hasmapto()" function 11972 */ 11973 static void 11974 f_hasmapto(argvars, rettv) 11975 typval_T *argvars; 11976 typval_T *rettv; 11977 { 11978 char_u *name; 11979 char_u *mode; 11980 char_u buf[NUMBUFLEN]; 11981 int abbr = FALSE; 11982 11983 name = get_tv_string(&argvars[0]); 11984 if (argvars[1].v_type == VAR_UNKNOWN) 11985 mode = (char_u *)"nvo"; 11986 else 11987 { 11988 mode = get_tv_string_buf(&argvars[1], buf); 11989 if (argvars[2].v_type != VAR_UNKNOWN) 11990 abbr = get_tv_number(&argvars[2]); 11991 } 11992 11993 if (map_to_exists(name, mode, abbr)) 11994 rettv->vval.v_number = TRUE; 11995 else 11996 rettv->vval.v_number = FALSE; 11997 } 11998 11999 /* 12000 * "histadd()" function 12001 */ 12002 static void 12003 f_histadd(argvars, rettv) 12004 typval_T *argvars UNUSED; 12005 typval_T *rettv; 12006 { 12007 #ifdef FEAT_CMDHIST 12008 int histype; 12009 char_u *str; 12010 char_u buf[NUMBUFLEN]; 12011 #endif 12012 12013 rettv->vval.v_number = FALSE; 12014 if (check_restricted() || check_secure()) 12015 return; 12016 #ifdef FEAT_CMDHIST 12017 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12018 histype = str != NULL ? get_histtype(str) : -1; 12019 if (histype >= 0) 12020 { 12021 str = get_tv_string_buf(&argvars[1], buf); 12022 if (*str != NUL) 12023 { 12024 init_history(); 12025 add_to_history(histype, str, FALSE, NUL); 12026 rettv->vval.v_number = TRUE; 12027 return; 12028 } 12029 } 12030 #endif 12031 } 12032 12033 /* 12034 * "histdel()" function 12035 */ 12036 static void 12037 f_histdel(argvars, rettv) 12038 typval_T *argvars UNUSED; 12039 typval_T *rettv UNUSED; 12040 { 12041 #ifdef FEAT_CMDHIST 12042 int n; 12043 char_u buf[NUMBUFLEN]; 12044 char_u *str; 12045 12046 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12047 if (str == NULL) 12048 n = 0; 12049 else if (argvars[1].v_type == VAR_UNKNOWN) 12050 /* only one argument: clear entire history */ 12051 n = clr_history(get_histtype(str)); 12052 else if (argvars[1].v_type == VAR_NUMBER) 12053 /* index given: remove that entry */ 12054 n = del_history_idx(get_histtype(str), 12055 (int)get_tv_number(&argvars[1])); 12056 else 12057 /* string given: remove all matching entries */ 12058 n = del_history_entry(get_histtype(str), 12059 get_tv_string_buf(&argvars[1], buf)); 12060 rettv->vval.v_number = n; 12061 #endif 12062 } 12063 12064 /* 12065 * "histget()" function 12066 */ 12067 static void 12068 f_histget(argvars, rettv) 12069 typval_T *argvars UNUSED; 12070 typval_T *rettv; 12071 { 12072 #ifdef FEAT_CMDHIST 12073 int type; 12074 int idx; 12075 char_u *str; 12076 12077 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12078 if (str == NULL) 12079 rettv->vval.v_string = NULL; 12080 else 12081 { 12082 type = get_histtype(str); 12083 if (argvars[1].v_type == VAR_UNKNOWN) 12084 idx = get_history_idx(type); 12085 else 12086 idx = (int)get_tv_number_chk(&argvars[1], NULL); 12087 /* -1 on type error */ 12088 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 12089 } 12090 #else 12091 rettv->vval.v_string = NULL; 12092 #endif 12093 rettv->v_type = VAR_STRING; 12094 } 12095 12096 /* 12097 * "histnr()" function 12098 */ 12099 static void 12100 f_histnr(argvars, rettv) 12101 typval_T *argvars UNUSED; 12102 typval_T *rettv; 12103 { 12104 int i; 12105 12106 #ifdef FEAT_CMDHIST 12107 char_u *history = get_tv_string_chk(&argvars[0]); 12108 12109 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 12110 if (i >= HIST_CMD && i < HIST_COUNT) 12111 i = get_history_idx(i); 12112 else 12113 #endif 12114 i = -1; 12115 rettv->vval.v_number = i; 12116 } 12117 12118 /* 12119 * "highlightID(name)" function 12120 */ 12121 static void 12122 f_hlID(argvars, rettv) 12123 typval_T *argvars; 12124 typval_T *rettv; 12125 { 12126 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 12127 } 12128 12129 /* 12130 * "highlight_exists()" function 12131 */ 12132 static void 12133 f_hlexists(argvars, rettv) 12134 typval_T *argvars; 12135 typval_T *rettv; 12136 { 12137 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 12138 } 12139 12140 /* 12141 * "hostname()" function 12142 */ 12143 static void 12144 f_hostname(argvars, rettv) 12145 typval_T *argvars UNUSED; 12146 typval_T *rettv; 12147 { 12148 char_u hostname[256]; 12149 12150 mch_get_host_name(hostname, 256); 12151 rettv->v_type = VAR_STRING; 12152 rettv->vval.v_string = vim_strsave(hostname); 12153 } 12154 12155 /* 12156 * iconv() function 12157 */ 12158 static void 12159 f_iconv(argvars, rettv) 12160 typval_T *argvars UNUSED; 12161 typval_T *rettv; 12162 { 12163 #ifdef FEAT_MBYTE 12164 char_u buf1[NUMBUFLEN]; 12165 char_u buf2[NUMBUFLEN]; 12166 char_u *from, *to, *str; 12167 vimconv_T vimconv; 12168 #endif 12169 12170 rettv->v_type = VAR_STRING; 12171 rettv->vval.v_string = NULL; 12172 12173 #ifdef FEAT_MBYTE 12174 str = get_tv_string(&argvars[0]); 12175 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 12176 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 12177 vimconv.vc_type = CONV_NONE; 12178 convert_setup(&vimconv, from, to); 12179 12180 /* If the encodings are equal, no conversion needed. */ 12181 if (vimconv.vc_type == CONV_NONE) 12182 rettv->vval.v_string = vim_strsave(str); 12183 else 12184 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 12185 12186 convert_setup(&vimconv, NULL, NULL); 12187 vim_free(from); 12188 vim_free(to); 12189 #endif 12190 } 12191 12192 /* 12193 * "indent()" function 12194 */ 12195 static void 12196 f_indent(argvars, rettv) 12197 typval_T *argvars; 12198 typval_T *rettv; 12199 { 12200 linenr_T lnum; 12201 12202 lnum = get_tv_lnum(argvars); 12203 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 12204 rettv->vval.v_number = get_indent_lnum(lnum); 12205 else 12206 rettv->vval.v_number = -1; 12207 } 12208 12209 /* 12210 * "index()" function 12211 */ 12212 static void 12213 f_index(argvars, rettv) 12214 typval_T *argvars; 12215 typval_T *rettv; 12216 { 12217 list_T *l; 12218 listitem_T *item; 12219 long idx = 0; 12220 int ic = FALSE; 12221 12222 rettv->vval.v_number = -1; 12223 if (argvars[0].v_type != VAR_LIST) 12224 { 12225 EMSG(_(e_listreq)); 12226 return; 12227 } 12228 l = argvars[0].vval.v_list; 12229 if (l != NULL) 12230 { 12231 item = l->lv_first; 12232 if (argvars[2].v_type != VAR_UNKNOWN) 12233 { 12234 int error = FALSE; 12235 12236 /* Start at specified item. Use the cached index that list_find() 12237 * sets, so that a negative number also works. */ 12238 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 12239 idx = l->lv_idx; 12240 if (argvars[3].v_type != VAR_UNKNOWN) 12241 ic = get_tv_number_chk(&argvars[3], &error); 12242 if (error) 12243 item = NULL; 12244 } 12245 12246 for ( ; item != NULL; item = item->li_next, ++idx) 12247 if (tv_equal(&item->li_tv, &argvars[1], ic)) 12248 { 12249 rettv->vval.v_number = idx; 12250 break; 12251 } 12252 } 12253 } 12254 12255 static int inputsecret_flag = 0; 12256 12257 static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog)); 12258 12259 /* 12260 * This function is used by f_input() and f_inputdialog() functions. The third 12261 * argument to f_input() specifies the type of completion to use at the 12262 * prompt. The third argument to f_inputdialog() specifies the value to return 12263 * when the user cancels the prompt. 12264 */ 12265 static void 12266 get_user_input(argvars, rettv, inputdialog) 12267 typval_T *argvars; 12268 typval_T *rettv; 12269 int inputdialog; 12270 { 12271 char_u *prompt = get_tv_string_chk(&argvars[0]); 12272 char_u *p = NULL; 12273 int c; 12274 char_u buf[NUMBUFLEN]; 12275 int cmd_silent_save = cmd_silent; 12276 char_u *defstr = (char_u *)""; 12277 int xp_type = EXPAND_NOTHING; 12278 char_u *xp_arg = NULL; 12279 12280 rettv->v_type = VAR_STRING; 12281 rettv->vval.v_string = NULL; 12282 12283 #ifdef NO_CONSOLE_INPUT 12284 /* While starting up, there is no place to enter text. */ 12285 if (no_console_input()) 12286 return; 12287 #endif 12288 12289 cmd_silent = FALSE; /* Want to see the prompt. */ 12290 if (prompt != NULL) 12291 { 12292 /* Only the part of the message after the last NL is considered as 12293 * prompt for the command line */ 12294 p = vim_strrchr(prompt, '\n'); 12295 if (p == NULL) 12296 p = prompt; 12297 else 12298 { 12299 ++p; 12300 c = *p; 12301 *p = NUL; 12302 msg_start(); 12303 msg_clr_eos(); 12304 msg_puts_attr(prompt, echo_attr); 12305 msg_didout = FALSE; 12306 msg_starthere(); 12307 *p = c; 12308 } 12309 cmdline_row = msg_row; 12310 12311 if (argvars[1].v_type != VAR_UNKNOWN) 12312 { 12313 defstr = get_tv_string_buf_chk(&argvars[1], buf); 12314 if (defstr != NULL) 12315 stuffReadbuffSpec(defstr); 12316 12317 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 12318 { 12319 char_u *xp_name; 12320 int xp_namelen; 12321 long argt; 12322 12323 rettv->vval.v_string = NULL; 12324 12325 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 12326 if (xp_name == NULL) 12327 return; 12328 12329 xp_namelen = (int)STRLEN(xp_name); 12330 12331 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 12332 &xp_arg) == FAIL) 12333 return; 12334 } 12335 } 12336 12337 if (defstr != NULL) 12338 rettv->vval.v_string = 12339 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 12340 xp_type, xp_arg); 12341 12342 vim_free(xp_arg); 12343 12344 /* since the user typed this, no need to wait for return */ 12345 need_wait_return = FALSE; 12346 msg_didout = FALSE; 12347 } 12348 cmd_silent = cmd_silent_save; 12349 } 12350 12351 /* 12352 * "input()" function 12353 * Also handles inputsecret() when inputsecret is set. 12354 */ 12355 static void 12356 f_input(argvars, rettv) 12357 typval_T *argvars; 12358 typval_T *rettv; 12359 { 12360 get_user_input(argvars, rettv, FALSE); 12361 } 12362 12363 /* 12364 * "inputdialog()" function 12365 */ 12366 static void 12367 f_inputdialog(argvars, rettv) 12368 typval_T *argvars; 12369 typval_T *rettv; 12370 { 12371 #if defined(FEAT_GUI_TEXTDIALOG) 12372 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 12373 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 12374 { 12375 char_u *message; 12376 char_u buf[NUMBUFLEN]; 12377 char_u *defstr = (char_u *)""; 12378 12379 message = get_tv_string_chk(&argvars[0]); 12380 if (argvars[1].v_type != VAR_UNKNOWN 12381 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 12382 vim_strncpy(IObuff, defstr, IOSIZE - 1); 12383 else 12384 IObuff[0] = NUL; 12385 if (message != NULL && defstr != NULL 12386 && do_dialog(VIM_QUESTION, NULL, message, 12387 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 12388 rettv->vval.v_string = vim_strsave(IObuff); 12389 else 12390 { 12391 if (message != NULL && defstr != NULL 12392 && argvars[1].v_type != VAR_UNKNOWN 12393 && argvars[2].v_type != VAR_UNKNOWN) 12394 rettv->vval.v_string = vim_strsave( 12395 get_tv_string_buf(&argvars[2], buf)); 12396 else 12397 rettv->vval.v_string = NULL; 12398 } 12399 rettv->v_type = VAR_STRING; 12400 } 12401 else 12402 #endif 12403 get_user_input(argvars, rettv, TRUE); 12404 } 12405 12406 /* 12407 * "inputlist()" function 12408 */ 12409 static void 12410 f_inputlist(argvars, rettv) 12411 typval_T *argvars; 12412 typval_T *rettv; 12413 { 12414 listitem_T *li; 12415 int selected; 12416 int mouse_used; 12417 12418 #ifdef NO_CONSOLE_INPUT 12419 /* While starting up, there is no place to enter text. */ 12420 if (no_console_input()) 12421 return; 12422 #endif 12423 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 12424 { 12425 EMSG2(_(e_listarg), "inputlist()"); 12426 return; 12427 } 12428 12429 msg_start(); 12430 msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ 12431 lines_left = Rows; /* avoid more prompt */ 12432 msg_scroll = TRUE; 12433 msg_clr_eos(); 12434 12435 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 12436 { 12437 msg_puts(get_tv_string(&li->li_tv)); 12438 msg_putchar('\n'); 12439 } 12440 12441 /* Ask for choice. */ 12442 selected = prompt_for_number(&mouse_used); 12443 if (mouse_used) 12444 selected -= lines_left; 12445 12446 rettv->vval.v_number = selected; 12447 } 12448 12449 12450 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 12451 12452 /* 12453 * "inputrestore()" function 12454 */ 12455 static void 12456 f_inputrestore(argvars, rettv) 12457 typval_T *argvars UNUSED; 12458 typval_T *rettv; 12459 { 12460 if (ga_userinput.ga_len > 0) 12461 { 12462 --ga_userinput.ga_len; 12463 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 12464 + ga_userinput.ga_len); 12465 /* default return is zero == OK */ 12466 } 12467 else if (p_verbose > 1) 12468 { 12469 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 12470 rettv->vval.v_number = 1; /* Failed */ 12471 } 12472 } 12473 12474 /* 12475 * "inputsave()" function 12476 */ 12477 static void 12478 f_inputsave(argvars, rettv) 12479 typval_T *argvars UNUSED; 12480 typval_T *rettv; 12481 { 12482 /* Add an entry to the stack of typeahead storage. */ 12483 if (ga_grow(&ga_userinput, 1) == OK) 12484 { 12485 save_typeahead((tasave_T *)(ga_userinput.ga_data) 12486 + ga_userinput.ga_len); 12487 ++ga_userinput.ga_len; 12488 /* default return is zero == OK */ 12489 } 12490 else 12491 rettv->vval.v_number = 1; /* Failed */ 12492 } 12493 12494 /* 12495 * "inputsecret()" function 12496 */ 12497 static void 12498 f_inputsecret(argvars, rettv) 12499 typval_T *argvars; 12500 typval_T *rettv; 12501 { 12502 ++cmdline_star; 12503 ++inputsecret_flag; 12504 f_input(argvars, rettv); 12505 --cmdline_star; 12506 --inputsecret_flag; 12507 } 12508 12509 /* 12510 * "insert()" function 12511 */ 12512 static void 12513 f_insert(argvars, rettv) 12514 typval_T *argvars; 12515 typval_T *rettv; 12516 { 12517 long before = 0; 12518 listitem_T *item; 12519 list_T *l; 12520 int error = FALSE; 12521 12522 if (argvars[0].v_type != VAR_LIST) 12523 EMSG2(_(e_listarg), "insert()"); 12524 else if ((l = argvars[0].vval.v_list) != NULL 12525 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 12526 { 12527 if (argvars[2].v_type != VAR_UNKNOWN) 12528 before = get_tv_number_chk(&argvars[2], &error); 12529 if (error) 12530 return; /* type error; errmsg already given */ 12531 12532 if (before == l->lv_len) 12533 item = NULL; 12534 else 12535 { 12536 item = list_find(l, before); 12537 if (item == NULL) 12538 { 12539 EMSGN(_(e_listidx), before); 12540 l = NULL; 12541 } 12542 } 12543 if (l != NULL) 12544 { 12545 list_insert_tv(l, &argvars[1], item); 12546 copy_tv(&argvars[0], rettv); 12547 } 12548 } 12549 } 12550 12551 /* 12552 * "isdirectory()" function 12553 */ 12554 static void 12555 f_isdirectory(argvars, rettv) 12556 typval_T *argvars; 12557 typval_T *rettv; 12558 { 12559 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 12560 } 12561 12562 /* 12563 * "islocked()" function 12564 */ 12565 static void 12566 f_islocked(argvars, rettv) 12567 typval_T *argvars; 12568 typval_T *rettv; 12569 { 12570 lval_T lv; 12571 char_u *end; 12572 dictitem_T *di; 12573 12574 rettv->vval.v_number = -1; 12575 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 12576 FNE_CHECK_START); 12577 if (end != NULL && lv.ll_name != NULL) 12578 { 12579 if (*end != NUL) 12580 EMSG(_(e_trailing)); 12581 else 12582 { 12583 if (lv.ll_tv == NULL) 12584 { 12585 if (check_changedtick(lv.ll_name)) 12586 rettv->vval.v_number = 1; /* always locked */ 12587 else 12588 { 12589 di = find_var(lv.ll_name, NULL); 12590 if (di != NULL) 12591 { 12592 /* Consider a variable locked when: 12593 * 1. the variable itself is locked 12594 * 2. the value of the variable is locked. 12595 * 3. the List or Dict value is locked. 12596 */ 12597 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 12598 || tv_islocked(&di->di_tv)); 12599 } 12600 } 12601 } 12602 else if (lv.ll_range) 12603 EMSG(_("E786: Range not allowed")); 12604 else if (lv.ll_newkey != NULL) 12605 EMSG2(_(e_dictkey), lv.ll_newkey); 12606 else if (lv.ll_list != NULL) 12607 /* List item. */ 12608 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 12609 else 12610 /* Dictionary item. */ 12611 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 12612 } 12613 } 12614 12615 clear_lval(&lv); 12616 } 12617 12618 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 12619 12620 /* 12621 * Turn a dict into a list: 12622 * "what" == 0: list of keys 12623 * "what" == 1: list of values 12624 * "what" == 2: list of items 12625 */ 12626 static void 12627 dict_list(argvars, rettv, what) 12628 typval_T *argvars; 12629 typval_T *rettv; 12630 int what; 12631 { 12632 list_T *l2; 12633 dictitem_T *di; 12634 hashitem_T *hi; 12635 listitem_T *li; 12636 listitem_T *li2; 12637 dict_T *d; 12638 int todo; 12639 12640 if (argvars[0].v_type != VAR_DICT) 12641 { 12642 EMSG(_(e_dictreq)); 12643 return; 12644 } 12645 if ((d = argvars[0].vval.v_dict) == NULL) 12646 return; 12647 12648 if (rettv_list_alloc(rettv) == FAIL) 12649 return; 12650 12651 todo = (int)d->dv_hashtab.ht_used; 12652 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 12653 { 12654 if (!HASHITEM_EMPTY(hi)) 12655 { 12656 --todo; 12657 di = HI2DI(hi); 12658 12659 li = listitem_alloc(); 12660 if (li == NULL) 12661 break; 12662 list_append(rettv->vval.v_list, li); 12663 12664 if (what == 0) 12665 { 12666 /* keys() */ 12667 li->li_tv.v_type = VAR_STRING; 12668 li->li_tv.v_lock = 0; 12669 li->li_tv.vval.v_string = vim_strsave(di->di_key); 12670 } 12671 else if (what == 1) 12672 { 12673 /* values() */ 12674 copy_tv(&di->di_tv, &li->li_tv); 12675 } 12676 else 12677 { 12678 /* items() */ 12679 l2 = list_alloc(); 12680 li->li_tv.v_type = VAR_LIST; 12681 li->li_tv.v_lock = 0; 12682 li->li_tv.vval.v_list = l2; 12683 if (l2 == NULL) 12684 break; 12685 ++l2->lv_refcount; 12686 12687 li2 = listitem_alloc(); 12688 if (li2 == NULL) 12689 break; 12690 list_append(l2, li2); 12691 li2->li_tv.v_type = VAR_STRING; 12692 li2->li_tv.v_lock = 0; 12693 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 12694 12695 li2 = listitem_alloc(); 12696 if (li2 == NULL) 12697 break; 12698 list_append(l2, li2); 12699 copy_tv(&di->di_tv, &li2->li_tv); 12700 } 12701 } 12702 } 12703 } 12704 12705 /* 12706 * "items(dict)" function 12707 */ 12708 static void 12709 f_items(argvars, rettv) 12710 typval_T *argvars; 12711 typval_T *rettv; 12712 { 12713 dict_list(argvars, rettv, 2); 12714 } 12715 12716 /* 12717 * "join()" function 12718 */ 12719 static void 12720 f_join(argvars, rettv) 12721 typval_T *argvars; 12722 typval_T *rettv; 12723 { 12724 garray_T ga; 12725 char_u *sep; 12726 12727 if (argvars[0].v_type != VAR_LIST) 12728 { 12729 EMSG(_(e_listreq)); 12730 return; 12731 } 12732 if (argvars[0].vval.v_list == NULL) 12733 return; 12734 if (argvars[1].v_type == VAR_UNKNOWN) 12735 sep = (char_u *)" "; 12736 else 12737 sep = get_tv_string_chk(&argvars[1]); 12738 12739 rettv->v_type = VAR_STRING; 12740 12741 if (sep != NULL) 12742 { 12743 ga_init2(&ga, (int)sizeof(char), 80); 12744 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 12745 ga_append(&ga, NUL); 12746 rettv->vval.v_string = (char_u *)ga.ga_data; 12747 } 12748 else 12749 rettv->vval.v_string = NULL; 12750 } 12751 12752 /* 12753 * "keys()" function 12754 */ 12755 static void 12756 f_keys(argvars, rettv) 12757 typval_T *argvars; 12758 typval_T *rettv; 12759 { 12760 dict_list(argvars, rettv, 0); 12761 } 12762 12763 /* 12764 * "last_buffer_nr()" function. 12765 */ 12766 static void 12767 f_last_buffer_nr(argvars, rettv) 12768 typval_T *argvars UNUSED; 12769 typval_T *rettv; 12770 { 12771 int n = 0; 12772 buf_T *buf; 12773 12774 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 12775 if (n < buf->b_fnum) 12776 n = buf->b_fnum; 12777 12778 rettv->vval.v_number = n; 12779 } 12780 12781 /* 12782 * "len()" function 12783 */ 12784 static void 12785 f_len(argvars, rettv) 12786 typval_T *argvars; 12787 typval_T *rettv; 12788 { 12789 switch (argvars[0].v_type) 12790 { 12791 case VAR_STRING: 12792 case VAR_NUMBER: 12793 rettv->vval.v_number = (varnumber_T)STRLEN( 12794 get_tv_string(&argvars[0])); 12795 break; 12796 case VAR_LIST: 12797 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 12798 break; 12799 case VAR_DICT: 12800 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 12801 break; 12802 default: 12803 EMSG(_("E701: Invalid type for len()")); 12804 break; 12805 } 12806 } 12807 12808 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 12809 12810 static void 12811 libcall_common(argvars, rettv, type) 12812 typval_T *argvars; 12813 typval_T *rettv; 12814 int type; 12815 { 12816 #ifdef FEAT_LIBCALL 12817 char_u *string_in; 12818 char_u **string_result; 12819 int nr_result; 12820 #endif 12821 12822 rettv->v_type = type; 12823 if (type != VAR_NUMBER) 12824 rettv->vval.v_string = NULL; 12825 12826 if (check_restricted() || check_secure()) 12827 return; 12828 12829 #ifdef FEAT_LIBCALL 12830 /* The first two args must be strings, otherwise its meaningless */ 12831 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 12832 { 12833 string_in = NULL; 12834 if (argvars[2].v_type == VAR_STRING) 12835 string_in = argvars[2].vval.v_string; 12836 if (type == VAR_NUMBER) 12837 string_result = NULL; 12838 else 12839 string_result = &rettv->vval.v_string; 12840 if (mch_libcall(argvars[0].vval.v_string, 12841 argvars[1].vval.v_string, 12842 string_in, 12843 argvars[2].vval.v_number, 12844 string_result, 12845 &nr_result) == OK 12846 && type == VAR_NUMBER) 12847 rettv->vval.v_number = nr_result; 12848 } 12849 #endif 12850 } 12851 12852 /* 12853 * "libcall()" function 12854 */ 12855 static void 12856 f_libcall(argvars, rettv) 12857 typval_T *argvars; 12858 typval_T *rettv; 12859 { 12860 libcall_common(argvars, rettv, VAR_STRING); 12861 } 12862 12863 /* 12864 * "libcallnr()" function 12865 */ 12866 static void 12867 f_libcallnr(argvars, rettv) 12868 typval_T *argvars; 12869 typval_T *rettv; 12870 { 12871 libcall_common(argvars, rettv, VAR_NUMBER); 12872 } 12873 12874 /* 12875 * "line(string)" function 12876 */ 12877 static void 12878 f_line(argvars, rettv) 12879 typval_T *argvars; 12880 typval_T *rettv; 12881 { 12882 linenr_T lnum = 0; 12883 pos_T *fp; 12884 int fnum; 12885 12886 fp = var2fpos(&argvars[0], TRUE, &fnum); 12887 if (fp != NULL) 12888 lnum = fp->lnum; 12889 rettv->vval.v_number = lnum; 12890 } 12891 12892 /* 12893 * "line2byte(lnum)" function 12894 */ 12895 static void 12896 f_line2byte(argvars, rettv) 12897 typval_T *argvars UNUSED; 12898 typval_T *rettv; 12899 { 12900 #ifndef FEAT_BYTEOFF 12901 rettv->vval.v_number = -1; 12902 #else 12903 linenr_T lnum; 12904 12905 lnum = get_tv_lnum(argvars); 12906 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 12907 rettv->vval.v_number = -1; 12908 else 12909 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 12910 if (rettv->vval.v_number >= 0) 12911 ++rettv->vval.v_number; 12912 #endif 12913 } 12914 12915 /* 12916 * "lispindent(lnum)" function 12917 */ 12918 static void 12919 f_lispindent(argvars, rettv) 12920 typval_T *argvars; 12921 typval_T *rettv; 12922 { 12923 #ifdef FEAT_LISP 12924 pos_T pos; 12925 linenr_T lnum; 12926 12927 pos = curwin->w_cursor; 12928 lnum = get_tv_lnum(argvars); 12929 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 12930 { 12931 curwin->w_cursor.lnum = lnum; 12932 rettv->vval.v_number = get_lisp_indent(); 12933 curwin->w_cursor = pos; 12934 } 12935 else 12936 #endif 12937 rettv->vval.v_number = -1; 12938 } 12939 12940 /* 12941 * "localtime()" function 12942 */ 12943 static void 12944 f_localtime(argvars, rettv) 12945 typval_T *argvars UNUSED; 12946 typval_T *rettv; 12947 { 12948 rettv->vval.v_number = (varnumber_T)time(NULL); 12949 } 12950 12951 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 12952 12953 static void 12954 get_maparg(argvars, rettv, exact) 12955 typval_T *argvars; 12956 typval_T *rettv; 12957 int exact; 12958 { 12959 char_u *keys; 12960 char_u *which; 12961 char_u buf[NUMBUFLEN]; 12962 char_u *keys_buf = NULL; 12963 char_u *rhs; 12964 int mode; 12965 garray_T ga; 12966 int abbr = FALSE; 12967 12968 /* return empty string for failure */ 12969 rettv->v_type = VAR_STRING; 12970 rettv->vval.v_string = NULL; 12971 12972 keys = get_tv_string(&argvars[0]); 12973 if (*keys == NUL) 12974 return; 12975 12976 if (argvars[1].v_type != VAR_UNKNOWN) 12977 { 12978 which = get_tv_string_buf_chk(&argvars[1], buf); 12979 if (argvars[2].v_type != VAR_UNKNOWN) 12980 abbr = get_tv_number(&argvars[2]); 12981 } 12982 else 12983 which = (char_u *)""; 12984 if (which == NULL) 12985 return; 12986 12987 mode = get_map_mode(&which, 0); 12988 12989 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); 12990 rhs = check_map(keys, mode, exact, FALSE, abbr); 12991 vim_free(keys_buf); 12992 if (rhs != NULL) 12993 { 12994 ga_init(&ga); 12995 ga.ga_itemsize = 1; 12996 ga.ga_growsize = 40; 12997 12998 while (*rhs != NUL) 12999 ga_concat(&ga, str2special(&rhs, FALSE)); 13000 13001 ga_append(&ga, NUL); 13002 rettv->vval.v_string = (char_u *)ga.ga_data; 13003 } 13004 } 13005 13006 #ifdef FEAT_FLOAT 13007 /* 13008 * "log10()" function 13009 */ 13010 static void 13011 f_log10(argvars, rettv) 13012 typval_T *argvars; 13013 typval_T *rettv; 13014 { 13015 float_T f; 13016 13017 rettv->v_type = VAR_FLOAT; 13018 if (get_float_arg(argvars, &f) == OK) 13019 rettv->vval.v_float = log10(f); 13020 else 13021 rettv->vval.v_float = 0.0; 13022 } 13023 #endif 13024 13025 /* 13026 * "map()" function 13027 */ 13028 static void 13029 f_map(argvars, rettv) 13030 typval_T *argvars; 13031 typval_T *rettv; 13032 { 13033 filter_map(argvars, rettv, TRUE); 13034 } 13035 13036 /* 13037 * "maparg()" function 13038 */ 13039 static void 13040 f_maparg(argvars, rettv) 13041 typval_T *argvars; 13042 typval_T *rettv; 13043 { 13044 get_maparg(argvars, rettv, TRUE); 13045 } 13046 13047 /* 13048 * "mapcheck()" function 13049 */ 13050 static void 13051 f_mapcheck(argvars, rettv) 13052 typval_T *argvars; 13053 typval_T *rettv; 13054 { 13055 get_maparg(argvars, rettv, FALSE); 13056 } 13057 13058 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 13059 13060 static void 13061 find_some_match(argvars, rettv, type) 13062 typval_T *argvars; 13063 typval_T *rettv; 13064 int type; 13065 { 13066 char_u *str = NULL; 13067 char_u *expr = NULL; 13068 char_u *pat; 13069 regmatch_T regmatch; 13070 char_u patbuf[NUMBUFLEN]; 13071 char_u strbuf[NUMBUFLEN]; 13072 char_u *save_cpo; 13073 long start = 0; 13074 long nth = 1; 13075 colnr_T startcol = 0; 13076 int match = 0; 13077 list_T *l = NULL; 13078 listitem_T *li = NULL; 13079 long idx = 0; 13080 char_u *tofree = NULL; 13081 13082 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13083 save_cpo = p_cpo; 13084 p_cpo = (char_u *)""; 13085 13086 rettv->vval.v_number = -1; 13087 if (type == 3) 13088 { 13089 /* return empty list when there are no matches */ 13090 if (rettv_list_alloc(rettv) == FAIL) 13091 goto theend; 13092 } 13093 else if (type == 2) 13094 { 13095 rettv->v_type = VAR_STRING; 13096 rettv->vval.v_string = NULL; 13097 } 13098 13099 if (argvars[0].v_type == VAR_LIST) 13100 { 13101 if ((l = argvars[0].vval.v_list) == NULL) 13102 goto theend; 13103 li = l->lv_first; 13104 } 13105 else 13106 expr = str = get_tv_string(&argvars[0]); 13107 13108 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13109 if (pat == NULL) 13110 goto theend; 13111 13112 if (argvars[2].v_type != VAR_UNKNOWN) 13113 { 13114 int error = FALSE; 13115 13116 start = get_tv_number_chk(&argvars[2], &error); 13117 if (error) 13118 goto theend; 13119 if (l != NULL) 13120 { 13121 li = list_find(l, start); 13122 if (li == NULL) 13123 goto theend; 13124 idx = l->lv_idx; /* use the cached index */ 13125 } 13126 else 13127 { 13128 if (start < 0) 13129 start = 0; 13130 if (start > (long)STRLEN(str)) 13131 goto theend; 13132 /* When "count" argument is there ignore matches before "start", 13133 * otherwise skip part of the string. Differs when pattern is "^" 13134 * or "\<". */ 13135 if (argvars[3].v_type != VAR_UNKNOWN) 13136 startcol = start; 13137 else 13138 str += start; 13139 } 13140 13141 if (argvars[3].v_type != VAR_UNKNOWN) 13142 nth = get_tv_number_chk(&argvars[3], &error); 13143 if (error) 13144 goto theend; 13145 } 13146 13147 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13148 if (regmatch.regprog != NULL) 13149 { 13150 regmatch.rm_ic = p_ic; 13151 13152 for (;;) 13153 { 13154 if (l != NULL) 13155 { 13156 if (li == NULL) 13157 { 13158 match = FALSE; 13159 break; 13160 } 13161 vim_free(tofree); 13162 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 13163 if (str == NULL) 13164 break; 13165 } 13166 13167 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 13168 13169 if (match && --nth <= 0) 13170 break; 13171 if (l == NULL && !match) 13172 break; 13173 13174 /* Advance to just after the match. */ 13175 if (l != NULL) 13176 { 13177 li = li->li_next; 13178 ++idx; 13179 } 13180 else 13181 { 13182 #ifdef FEAT_MBYTE 13183 startcol = (colnr_T)(regmatch.startp[0] 13184 + (*mb_ptr2len)(regmatch.startp[0]) - str); 13185 #else 13186 startcol = regmatch.startp[0] + 1 - str; 13187 #endif 13188 } 13189 } 13190 13191 if (match) 13192 { 13193 if (type == 3) 13194 { 13195 int i; 13196 13197 /* return list with matched string and submatches */ 13198 for (i = 0; i < NSUBEXP; ++i) 13199 { 13200 if (regmatch.endp[i] == NULL) 13201 { 13202 if (list_append_string(rettv->vval.v_list, 13203 (char_u *)"", 0) == FAIL) 13204 break; 13205 } 13206 else if (list_append_string(rettv->vval.v_list, 13207 regmatch.startp[i], 13208 (int)(regmatch.endp[i] - regmatch.startp[i])) 13209 == FAIL) 13210 break; 13211 } 13212 } 13213 else if (type == 2) 13214 { 13215 /* return matched string */ 13216 if (l != NULL) 13217 copy_tv(&li->li_tv, rettv); 13218 else 13219 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 13220 (int)(regmatch.endp[0] - regmatch.startp[0])); 13221 } 13222 else if (l != NULL) 13223 rettv->vval.v_number = idx; 13224 else 13225 { 13226 if (type != 0) 13227 rettv->vval.v_number = 13228 (varnumber_T)(regmatch.startp[0] - str); 13229 else 13230 rettv->vval.v_number = 13231 (varnumber_T)(regmatch.endp[0] - str); 13232 rettv->vval.v_number += (varnumber_T)(str - expr); 13233 } 13234 } 13235 vim_free(regmatch.regprog); 13236 } 13237 13238 theend: 13239 vim_free(tofree); 13240 p_cpo = save_cpo; 13241 } 13242 13243 /* 13244 * "match()" function 13245 */ 13246 static void 13247 f_match(argvars, rettv) 13248 typval_T *argvars; 13249 typval_T *rettv; 13250 { 13251 find_some_match(argvars, rettv, 1); 13252 } 13253 13254 /* 13255 * "matchadd()" function 13256 */ 13257 static void 13258 f_matchadd(argvars, rettv) 13259 typval_T *argvars; 13260 typval_T *rettv; 13261 { 13262 #ifdef FEAT_SEARCH_EXTRA 13263 char_u buf[NUMBUFLEN]; 13264 char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */ 13265 char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */ 13266 int prio = 10; /* default priority */ 13267 int id = -1; 13268 int error = FALSE; 13269 13270 rettv->vval.v_number = -1; 13271 13272 if (grp == NULL || pat == NULL) 13273 return; 13274 if (argvars[2].v_type != VAR_UNKNOWN) 13275 { 13276 prio = get_tv_number_chk(&argvars[2], &error); 13277 if (argvars[3].v_type != VAR_UNKNOWN) 13278 id = get_tv_number_chk(&argvars[3], &error); 13279 } 13280 if (error == TRUE) 13281 return; 13282 if (id >= 1 && id <= 3) 13283 { 13284 EMSGN("E798: ID is reserved for \":match\": %ld", id); 13285 return; 13286 } 13287 13288 rettv->vval.v_number = match_add(curwin, grp, pat, prio, id); 13289 #endif 13290 } 13291 13292 /* 13293 * "matcharg()" function 13294 */ 13295 static void 13296 f_matcharg(argvars, rettv) 13297 typval_T *argvars; 13298 typval_T *rettv; 13299 { 13300 if (rettv_list_alloc(rettv) == OK) 13301 { 13302 #ifdef FEAT_SEARCH_EXTRA 13303 int id = get_tv_number(&argvars[0]); 13304 matchitem_T *m; 13305 13306 if (id >= 1 && id <= 3) 13307 { 13308 if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) 13309 { 13310 list_append_string(rettv->vval.v_list, 13311 syn_id2name(m->hlg_id), -1); 13312 list_append_string(rettv->vval.v_list, m->pattern, -1); 13313 } 13314 else 13315 { 13316 list_append_string(rettv->vval.v_list, NUL, -1); 13317 list_append_string(rettv->vval.v_list, NUL, -1); 13318 } 13319 } 13320 #endif 13321 } 13322 } 13323 13324 /* 13325 * "matchdelete()" function 13326 */ 13327 static void 13328 f_matchdelete(argvars, rettv) 13329 typval_T *argvars; 13330 typval_T *rettv; 13331 { 13332 #ifdef FEAT_SEARCH_EXTRA 13333 rettv->vval.v_number = match_delete(curwin, 13334 (int)get_tv_number(&argvars[0]), TRUE); 13335 #endif 13336 } 13337 13338 /* 13339 * "matchend()" function 13340 */ 13341 static void 13342 f_matchend(argvars, rettv) 13343 typval_T *argvars; 13344 typval_T *rettv; 13345 { 13346 find_some_match(argvars, rettv, 0); 13347 } 13348 13349 /* 13350 * "matchlist()" function 13351 */ 13352 static void 13353 f_matchlist(argvars, rettv) 13354 typval_T *argvars; 13355 typval_T *rettv; 13356 { 13357 find_some_match(argvars, rettv, 3); 13358 } 13359 13360 /* 13361 * "matchstr()" function 13362 */ 13363 static void 13364 f_matchstr(argvars, rettv) 13365 typval_T *argvars; 13366 typval_T *rettv; 13367 { 13368 find_some_match(argvars, rettv, 2); 13369 } 13370 13371 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 13372 13373 static void 13374 max_min(argvars, rettv, domax) 13375 typval_T *argvars; 13376 typval_T *rettv; 13377 int domax; 13378 { 13379 long n = 0; 13380 long i; 13381 int error = FALSE; 13382 13383 if (argvars[0].v_type == VAR_LIST) 13384 { 13385 list_T *l; 13386 listitem_T *li; 13387 13388 l = argvars[0].vval.v_list; 13389 if (l != NULL) 13390 { 13391 li = l->lv_first; 13392 if (li != NULL) 13393 { 13394 n = get_tv_number_chk(&li->li_tv, &error); 13395 for (;;) 13396 { 13397 li = li->li_next; 13398 if (li == NULL) 13399 break; 13400 i = get_tv_number_chk(&li->li_tv, &error); 13401 if (domax ? i > n : i < n) 13402 n = i; 13403 } 13404 } 13405 } 13406 } 13407 else if (argvars[0].v_type == VAR_DICT) 13408 { 13409 dict_T *d; 13410 int first = TRUE; 13411 hashitem_T *hi; 13412 int todo; 13413 13414 d = argvars[0].vval.v_dict; 13415 if (d != NULL) 13416 { 13417 todo = (int)d->dv_hashtab.ht_used; 13418 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 13419 { 13420 if (!HASHITEM_EMPTY(hi)) 13421 { 13422 --todo; 13423 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 13424 if (first) 13425 { 13426 n = i; 13427 first = FALSE; 13428 } 13429 else if (domax ? i > n : i < n) 13430 n = i; 13431 } 13432 } 13433 } 13434 } 13435 else 13436 EMSG(_(e_listdictarg)); 13437 rettv->vval.v_number = error ? 0 : n; 13438 } 13439 13440 /* 13441 * "max()" function 13442 */ 13443 static void 13444 f_max(argvars, rettv) 13445 typval_T *argvars; 13446 typval_T *rettv; 13447 { 13448 max_min(argvars, rettv, TRUE); 13449 } 13450 13451 /* 13452 * "min()" function 13453 */ 13454 static void 13455 f_min(argvars, rettv) 13456 typval_T *argvars; 13457 typval_T *rettv; 13458 { 13459 max_min(argvars, rettv, FALSE); 13460 } 13461 13462 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 13463 13464 /* 13465 * Create the directory in which "dir" is located, and higher levels when 13466 * needed. 13467 */ 13468 static int 13469 mkdir_recurse(dir, prot) 13470 char_u *dir; 13471 int prot; 13472 { 13473 char_u *p; 13474 char_u *updir; 13475 int r = FAIL; 13476 13477 /* Get end of directory name in "dir". 13478 * We're done when it's "/" or "c:/". */ 13479 p = gettail_sep(dir); 13480 if (p <= get_past_head(dir)) 13481 return OK; 13482 13483 /* If the directory exists we're done. Otherwise: create it.*/ 13484 updir = vim_strnsave(dir, (int)(p - dir)); 13485 if (updir == NULL) 13486 return FAIL; 13487 if (mch_isdir(updir)) 13488 r = OK; 13489 else if (mkdir_recurse(updir, prot) == OK) 13490 r = vim_mkdir_emsg(updir, prot); 13491 vim_free(updir); 13492 return r; 13493 } 13494 13495 #ifdef vim_mkdir 13496 /* 13497 * "mkdir()" function 13498 */ 13499 static void 13500 f_mkdir(argvars, rettv) 13501 typval_T *argvars; 13502 typval_T *rettv; 13503 { 13504 char_u *dir; 13505 char_u buf[NUMBUFLEN]; 13506 int prot = 0755; 13507 13508 rettv->vval.v_number = FAIL; 13509 if (check_restricted() || check_secure()) 13510 return; 13511 13512 dir = get_tv_string_buf(&argvars[0], buf); 13513 if (argvars[1].v_type != VAR_UNKNOWN) 13514 { 13515 if (argvars[2].v_type != VAR_UNKNOWN) 13516 prot = get_tv_number_chk(&argvars[2], NULL); 13517 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 13518 mkdir_recurse(dir, prot); 13519 } 13520 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 13521 } 13522 #endif 13523 13524 /* 13525 * "mode()" function 13526 */ 13527 static void 13528 f_mode(argvars, rettv) 13529 typval_T *argvars; 13530 typval_T *rettv; 13531 { 13532 char_u buf[3]; 13533 13534 buf[1] = NUL; 13535 buf[2] = NUL; 13536 13537 #ifdef FEAT_VISUAL 13538 if (VIsual_active) 13539 { 13540 if (VIsual_select) 13541 buf[0] = VIsual_mode + 's' - 'v'; 13542 else 13543 buf[0] = VIsual_mode; 13544 } 13545 else 13546 #endif 13547 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE 13548 || State == CONFIRM) 13549 { 13550 buf[0] = 'r'; 13551 if (State == ASKMORE) 13552 buf[1] = 'm'; 13553 else if (State == CONFIRM) 13554 buf[1] = '?'; 13555 } 13556 else if (State == EXTERNCMD) 13557 buf[0] = '!'; 13558 else if (State & INSERT) 13559 { 13560 #ifdef FEAT_VREPLACE 13561 if (State & VREPLACE_FLAG) 13562 { 13563 buf[0] = 'R'; 13564 buf[1] = 'v'; 13565 } 13566 else 13567 #endif 13568 if (State & REPLACE_FLAG) 13569 buf[0] = 'R'; 13570 else 13571 buf[0] = 'i'; 13572 } 13573 else if (State & CMDLINE) 13574 { 13575 buf[0] = 'c'; 13576 if (exmode_active) 13577 buf[1] = 'v'; 13578 } 13579 else if (exmode_active) 13580 { 13581 buf[0] = 'c'; 13582 buf[1] = 'e'; 13583 } 13584 else 13585 { 13586 buf[0] = 'n'; 13587 if (finish_op) 13588 buf[1] = 'o'; 13589 } 13590 13591 /* Clear out the minor mode when the argument is not a non-zero number or 13592 * non-empty string. */ 13593 if (!non_zero_arg(&argvars[0])) 13594 buf[1] = NUL; 13595 13596 rettv->vval.v_string = vim_strsave(buf); 13597 rettv->v_type = VAR_STRING; 13598 } 13599 13600 #ifdef FEAT_MZSCHEME 13601 /* 13602 * "mzeval()" function 13603 */ 13604 static void 13605 f_mzeval(argvars, rettv) 13606 typval_T *argvars; 13607 typval_T *rettv; 13608 { 13609 char_u *str; 13610 char_u buf[NUMBUFLEN]; 13611 13612 str = get_tv_string_buf(&argvars[0], buf); 13613 do_mzeval(str, rettv); 13614 } 13615 #endif 13616 13617 /* 13618 * "nextnonblank()" function 13619 */ 13620 static void 13621 f_nextnonblank(argvars, rettv) 13622 typval_T *argvars; 13623 typval_T *rettv; 13624 { 13625 linenr_T lnum; 13626 13627 for (lnum = get_tv_lnum(argvars); ; ++lnum) 13628 { 13629 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 13630 { 13631 lnum = 0; 13632 break; 13633 } 13634 if (*skipwhite(ml_get(lnum)) != NUL) 13635 break; 13636 } 13637 rettv->vval.v_number = lnum; 13638 } 13639 13640 /* 13641 * "nr2char()" function 13642 */ 13643 static void 13644 f_nr2char(argvars, rettv) 13645 typval_T *argvars; 13646 typval_T *rettv; 13647 { 13648 char_u buf[NUMBUFLEN]; 13649 13650 #ifdef FEAT_MBYTE 13651 if (has_mbyte) 13652 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 13653 else 13654 #endif 13655 { 13656 buf[0] = (char_u)get_tv_number(&argvars[0]); 13657 buf[1] = NUL; 13658 } 13659 rettv->v_type = VAR_STRING; 13660 rettv->vval.v_string = vim_strsave(buf); 13661 } 13662 13663 /* 13664 * "pathshorten()" function 13665 */ 13666 static void 13667 f_pathshorten(argvars, rettv) 13668 typval_T *argvars; 13669 typval_T *rettv; 13670 { 13671 char_u *p; 13672 13673 rettv->v_type = VAR_STRING; 13674 p = get_tv_string_chk(&argvars[0]); 13675 if (p == NULL) 13676 rettv->vval.v_string = NULL; 13677 else 13678 { 13679 p = vim_strsave(p); 13680 rettv->vval.v_string = p; 13681 if (p != NULL) 13682 shorten_dir(p); 13683 } 13684 } 13685 13686 #ifdef FEAT_FLOAT 13687 /* 13688 * "pow()" function 13689 */ 13690 static void 13691 f_pow(argvars, rettv) 13692 typval_T *argvars; 13693 typval_T *rettv; 13694 { 13695 float_T fx, fy; 13696 13697 rettv->v_type = VAR_FLOAT; 13698 if (get_float_arg(argvars, &fx) == OK 13699 && get_float_arg(&argvars[1], &fy) == OK) 13700 rettv->vval.v_float = pow(fx, fy); 13701 else 13702 rettv->vval.v_float = 0.0; 13703 } 13704 #endif 13705 13706 /* 13707 * "prevnonblank()" function 13708 */ 13709 static void 13710 f_prevnonblank(argvars, rettv) 13711 typval_T *argvars; 13712 typval_T *rettv; 13713 { 13714 linenr_T lnum; 13715 13716 lnum = get_tv_lnum(argvars); 13717 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 13718 lnum = 0; 13719 else 13720 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 13721 --lnum; 13722 rettv->vval.v_number = lnum; 13723 } 13724 13725 #ifdef HAVE_STDARG_H 13726 /* This dummy va_list is here because: 13727 * - passing a NULL pointer doesn't work when va_list isn't a pointer 13728 * - locally in the function results in a "used before set" warning 13729 * - using va_start() to initialize it gives "function with fixed args" error */ 13730 static va_list ap; 13731 #endif 13732 13733 /* 13734 * "printf()" function 13735 */ 13736 static void 13737 f_printf(argvars, rettv) 13738 typval_T *argvars; 13739 typval_T *rettv; 13740 { 13741 rettv->v_type = VAR_STRING; 13742 rettv->vval.v_string = NULL; 13743 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 13744 { 13745 char_u buf[NUMBUFLEN]; 13746 int len; 13747 char_u *s; 13748 int saved_did_emsg = did_emsg; 13749 char *fmt; 13750 13751 /* Get the required length, allocate the buffer and do it for real. */ 13752 did_emsg = FALSE; 13753 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 13754 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 13755 if (!did_emsg) 13756 { 13757 s = alloc(len + 1); 13758 if (s != NULL) 13759 { 13760 rettv->vval.v_string = s; 13761 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 13762 } 13763 } 13764 did_emsg |= saved_did_emsg; 13765 } 13766 #endif 13767 } 13768 13769 /* 13770 * "pumvisible()" function 13771 */ 13772 static void 13773 f_pumvisible(argvars, rettv) 13774 typval_T *argvars UNUSED; 13775 typval_T *rettv UNUSED; 13776 { 13777 #ifdef FEAT_INS_EXPAND 13778 if (pum_visible()) 13779 rettv->vval.v_number = 1; 13780 #endif 13781 } 13782 13783 /* 13784 * "range()" function 13785 */ 13786 static void 13787 f_range(argvars, rettv) 13788 typval_T *argvars; 13789 typval_T *rettv; 13790 { 13791 long start; 13792 long end; 13793 long stride = 1; 13794 long i; 13795 int error = FALSE; 13796 13797 start = get_tv_number_chk(&argvars[0], &error); 13798 if (argvars[1].v_type == VAR_UNKNOWN) 13799 { 13800 end = start - 1; 13801 start = 0; 13802 } 13803 else 13804 { 13805 end = get_tv_number_chk(&argvars[1], &error); 13806 if (argvars[2].v_type != VAR_UNKNOWN) 13807 stride = get_tv_number_chk(&argvars[2], &error); 13808 } 13809 13810 if (error) 13811 return; /* type error; errmsg already given */ 13812 if (stride == 0) 13813 EMSG(_("E726: Stride is zero")); 13814 else if (stride > 0 ? end + 1 < start : end - 1 > start) 13815 EMSG(_("E727: Start past end")); 13816 else 13817 { 13818 if (rettv_list_alloc(rettv) == OK) 13819 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 13820 if (list_append_number(rettv->vval.v_list, 13821 (varnumber_T)i) == FAIL) 13822 break; 13823 } 13824 } 13825 13826 /* 13827 * "readfile()" function 13828 */ 13829 static void 13830 f_readfile(argvars, rettv) 13831 typval_T *argvars; 13832 typval_T *rettv; 13833 { 13834 int binary = FALSE; 13835 char_u *fname; 13836 FILE *fd; 13837 listitem_T *li; 13838 #define FREAD_SIZE 200 /* optimized for text lines */ 13839 char_u buf[FREAD_SIZE]; 13840 int readlen; /* size of last fread() */ 13841 int buflen; /* nr of valid chars in buf[] */ 13842 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 13843 int tolist; /* first byte in buf[] still to be put in list */ 13844 int chop; /* how many CR to chop off */ 13845 char_u *prev = NULL; /* previously read bytes, if any */ 13846 int prevlen = 0; /* length of "prev" if not NULL */ 13847 char_u *s; 13848 int len; 13849 long maxline = MAXLNUM; 13850 long cnt = 0; 13851 13852 if (argvars[1].v_type != VAR_UNKNOWN) 13853 { 13854 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 13855 binary = TRUE; 13856 if (argvars[2].v_type != VAR_UNKNOWN) 13857 maxline = get_tv_number(&argvars[2]); 13858 } 13859 13860 if (rettv_list_alloc(rettv) == FAIL) 13861 return; 13862 13863 /* Always open the file in binary mode, library functions have a mind of 13864 * their own about CR-LF conversion. */ 13865 fname = get_tv_string(&argvars[0]); 13866 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 13867 { 13868 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 13869 return; 13870 } 13871 13872 filtd = 0; 13873 while (cnt < maxline || maxline < 0) 13874 { 13875 readlen = (int)fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 13876 buflen = filtd + readlen; 13877 tolist = 0; 13878 for ( ; filtd < buflen || readlen <= 0; ++filtd) 13879 { 13880 if (buf[filtd] == '\n' || readlen <= 0) 13881 { 13882 /* Only when in binary mode add an empty list item when the 13883 * last line ends in a '\n'. */ 13884 if (!binary && readlen == 0 && filtd == 0) 13885 break; 13886 13887 /* Found end-of-line or end-of-file: add a text line to the 13888 * list. */ 13889 chop = 0; 13890 if (!binary) 13891 while (filtd - chop - 1 >= tolist 13892 && buf[filtd - chop - 1] == '\r') 13893 ++chop; 13894 len = filtd - tolist - chop; 13895 if (prev == NULL) 13896 s = vim_strnsave(buf + tolist, len); 13897 else 13898 { 13899 s = alloc((unsigned)(prevlen + len + 1)); 13900 if (s != NULL) 13901 { 13902 mch_memmove(s, prev, prevlen); 13903 vim_free(prev); 13904 prev = NULL; 13905 mch_memmove(s + prevlen, buf + tolist, len); 13906 s[prevlen + len] = NUL; 13907 } 13908 } 13909 tolist = filtd + 1; 13910 13911 li = listitem_alloc(); 13912 if (li == NULL) 13913 { 13914 vim_free(s); 13915 break; 13916 } 13917 li->li_tv.v_type = VAR_STRING; 13918 li->li_tv.v_lock = 0; 13919 li->li_tv.vval.v_string = s; 13920 list_append(rettv->vval.v_list, li); 13921 13922 if (++cnt >= maxline && maxline >= 0) 13923 break; 13924 if (readlen <= 0) 13925 break; 13926 } 13927 else if (buf[filtd] == NUL) 13928 buf[filtd] = '\n'; 13929 } 13930 if (readlen <= 0) 13931 break; 13932 13933 if (tolist == 0) 13934 { 13935 /* "buf" is full, need to move text to an allocated buffer */ 13936 if (prev == NULL) 13937 { 13938 prev = vim_strnsave(buf, buflen); 13939 prevlen = buflen; 13940 } 13941 else 13942 { 13943 s = alloc((unsigned)(prevlen + buflen)); 13944 if (s != NULL) 13945 { 13946 mch_memmove(s, prev, prevlen); 13947 mch_memmove(s + prevlen, buf, buflen); 13948 vim_free(prev); 13949 prev = s; 13950 prevlen += buflen; 13951 } 13952 } 13953 filtd = 0; 13954 } 13955 else 13956 { 13957 mch_memmove(buf, buf + tolist, buflen - tolist); 13958 filtd -= tolist; 13959 } 13960 } 13961 13962 /* 13963 * For a negative line count use only the lines at the end of the file, 13964 * free the rest. 13965 */ 13966 if (maxline < 0) 13967 while (cnt > -maxline) 13968 { 13969 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 13970 --cnt; 13971 } 13972 13973 vim_free(prev); 13974 fclose(fd); 13975 } 13976 13977 #if defined(FEAT_RELTIME) 13978 static int list2proftime __ARGS((typval_T *arg, proftime_T *tm)); 13979 13980 /* 13981 * Convert a List to proftime_T. 13982 * Return FAIL when there is something wrong. 13983 */ 13984 static int 13985 list2proftime(arg, tm) 13986 typval_T *arg; 13987 proftime_T *tm; 13988 { 13989 long n1, n2; 13990 int error = FALSE; 13991 13992 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 13993 || arg->vval.v_list->lv_len != 2) 13994 return FAIL; 13995 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 13996 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 13997 # ifdef WIN3264 13998 tm->HighPart = n1; 13999 tm->LowPart = n2; 14000 # else 14001 tm->tv_sec = n1; 14002 tm->tv_usec = n2; 14003 # endif 14004 return error ? FAIL : OK; 14005 } 14006 #endif /* FEAT_RELTIME */ 14007 14008 /* 14009 * "reltime()" function 14010 */ 14011 static void 14012 f_reltime(argvars, rettv) 14013 typval_T *argvars; 14014 typval_T *rettv; 14015 { 14016 #ifdef FEAT_RELTIME 14017 proftime_T res; 14018 proftime_T start; 14019 14020 if (argvars[0].v_type == VAR_UNKNOWN) 14021 { 14022 /* No arguments: get current time. */ 14023 profile_start(&res); 14024 } 14025 else if (argvars[1].v_type == VAR_UNKNOWN) 14026 { 14027 if (list2proftime(&argvars[0], &res) == FAIL) 14028 return; 14029 profile_end(&res); 14030 } 14031 else 14032 { 14033 /* Two arguments: compute the difference. */ 14034 if (list2proftime(&argvars[0], &start) == FAIL 14035 || list2proftime(&argvars[1], &res) == FAIL) 14036 return; 14037 profile_sub(&res, &start); 14038 } 14039 14040 if (rettv_list_alloc(rettv) == OK) 14041 { 14042 long n1, n2; 14043 14044 # ifdef WIN3264 14045 n1 = res.HighPart; 14046 n2 = res.LowPart; 14047 # else 14048 n1 = res.tv_sec; 14049 n2 = res.tv_usec; 14050 # endif 14051 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 14052 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 14053 } 14054 #endif 14055 } 14056 14057 /* 14058 * "reltimestr()" function 14059 */ 14060 static void 14061 f_reltimestr(argvars, rettv) 14062 typval_T *argvars; 14063 typval_T *rettv; 14064 { 14065 #ifdef FEAT_RELTIME 14066 proftime_T tm; 14067 #endif 14068 14069 rettv->v_type = VAR_STRING; 14070 rettv->vval.v_string = NULL; 14071 #ifdef FEAT_RELTIME 14072 if (list2proftime(&argvars[0], &tm) == OK) 14073 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 14074 #endif 14075 } 14076 14077 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 14078 static void make_connection __ARGS((void)); 14079 static int check_connection __ARGS((void)); 14080 14081 static void 14082 make_connection() 14083 { 14084 if (X_DISPLAY == NULL 14085 # ifdef FEAT_GUI 14086 && !gui.in_use 14087 # endif 14088 ) 14089 { 14090 x_force_connect = TRUE; 14091 setup_term_clip(); 14092 x_force_connect = FALSE; 14093 } 14094 } 14095 14096 static int 14097 check_connection() 14098 { 14099 make_connection(); 14100 if (X_DISPLAY == NULL) 14101 { 14102 EMSG(_("E240: No connection to Vim server")); 14103 return FAIL; 14104 } 14105 return OK; 14106 } 14107 #endif 14108 14109 #ifdef FEAT_CLIENTSERVER 14110 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 14111 14112 static void 14113 remote_common(argvars, rettv, expr) 14114 typval_T *argvars; 14115 typval_T *rettv; 14116 int expr; 14117 { 14118 char_u *server_name; 14119 char_u *keys; 14120 char_u *r = NULL; 14121 char_u buf[NUMBUFLEN]; 14122 # ifdef WIN32 14123 HWND w; 14124 # else 14125 Window w; 14126 # endif 14127 14128 if (check_restricted() || check_secure()) 14129 return; 14130 14131 # ifdef FEAT_X11 14132 if (check_connection() == FAIL) 14133 return; 14134 # endif 14135 14136 server_name = get_tv_string_chk(&argvars[0]); 14137 if (server_name == NULL) 14138 return; /* type error; errmsg already given */ 14139 keys = get_tv_string_buf(&argvars[1], buf); 14140 # ifdef WIN32 14141 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 14142 # else 14143 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 14144 < 0) 14145 # endif 14146 { 14147 if (r != NULL) 14148 EMSG(r); /* sending worked but evaluation failed */ 14149 else 14150 EMSG2(_("E241: Unable to send to %s"), server_name); 14151 return; 14152 } 14153 14154 rettv->vval.v_string = r; 14155 14156 if (argvars[2].v_type != VAR_UNKNOWN) 14157 { 14158 dictitem_T v; 14159 char_u str[30]; 14160 char_u *idvar; 14161 14162 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 14163 v.di_tv.v_type = VAR_STRING; 14164 v.di_tv.vval.v_string = vim_strsave(str); 14165 idvar = get_tv_string_chk(&argvars[2]); 14166 if (idvar != NULL) 14167 set_var(idvar, &v.di_tv, FALSE); 14168 vim_free(v.di_tv.vval.v_string); 14169 } 14170 } 14171 #endif 14172 14173 /* 14174 * "remote_expr()" function 14175 */ 14176 static void 14177 f_remote_expr(argvars, rettv) 14178 typval_T *argvars UNUSED; 14179 typval_T *rettv; 14180 { 14181 rettv->v_type = VAR_STRING; 14182 rettv->vval.v_string = NULL; 14183 #ifdef FEAT_CLIENTSERVER 14184 remote_common(argvars, rettv, TRUE); 14185 #endif 14186 } 14187 14188 /* 14189 * "remote_foreground()" function 14190 */ 14191 static void 14192 f_remote_foreground(argvars, rettv) 14193 typval_T *argvars UNUSED; 14194 typval_T *rettv UNUSED; 14195 { 14196 #ifdef FEAT_CLIENTSERVER 14197 # ifdef WIN32 14198 /* On Win32 it's done in this application. */ 14199 { 14200 char_u *server_name = get_tv_string_chk(&argvars[0]); 14201 14202 if (server_name != NULL) 14203 serverForeground(server_name); 14204 } 14205 # else 14206 /* Send a foreground() expression to the server. */ 14207 argvars[1].v_type = VAR_STRING; 14208 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 14209 argvars[2].v_type = VAR_UNKNOWN; 14210 remote_common(argvars, rettv, TRUE); 14211 vim_free(argvars[1].vval.v_string); 14212 # endif 14213 #endif 14214 } 14215 14216 static void 14217 f_remote_peek(argvars, rettv) 14218 typval_T *argvars UNUSED; 14219 typval_T *rettv; 14220 { 14221 #ifdef FEAT_CLIENTSERVER 14222 dictitem_T v; 14223 char_u *s = NULL; 14224 # ifdef WIN32 14225 long_u n = 0; 14226 # endif 14227 char_u *serverid; 14228 14229 if (check_restricted() || check_secure()) 14230 { 14231 rettv->vval.v_number = -1; 14232 return; 14233 } 14234 serverid = get_tv_string_chk(&argvars[0]); 14235 if (serverid == NULL) 14236 { 14237 rettv->vval.v_number = -1; 14238 return; /* type error; errmsg already given */ 14239 } 14240 # ifdef WIN32 14241 sscanf(serverid, SCANF_HEX_LONG_U, &n); 14242 if (n == 0) 14243 rettv->vval.v_number = -1; 14244 else 14245 { 14246 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 14247 rettv->vval.v_number = (s != NULL); 14248 } 14249 # else 14250 if (check_connection() == FAIL) 14251 return; 14252 14253 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 14254 serverStrToWin(serverid), &s); 14255 # endif 14256 14257 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 14258 { 14259 char_u *retvar; 14260 14261 v.di_tv.v_type = VAR_STRING; 14262 v.di_tv.vval.v_string = vim_strsave(s); 14263 retvar = get_tv_string_chk(&argvars[1]); 14264 if (retvar != NULL) 14265 set_var(retvar, &v.di_tv, FALSE); 14266 vim_free(v.di_tv.vval.v_string); 14267 } 14268 #else 14269 rettv->vval.v_number = -1; 14270 #endif 14271 } 14272 14273 static void 14274 f_remote_read(argvars, rettv) 14275 typval_T *argvars UNUSED; 14276 typval_T *rettv; 14277 { 14278 char_u *r = NULL; 14279 14280 #ifdef FEAT_CLIENTSERVER 14281 char_u *serverid = get_tv_string_chk(&argvars[0]); 14282 14283 if (serverid != NULL && !check_restricted() && !check_secure()) 14284 { 14285 # ifdef WIN32 14286 /* The server's HWND is encoded in the 'id' parameter */ 14287 long_u n = 0; 14288 14289 sscanf(serverid, SCANF_HEX_LONG_U, &n); 14290 if (n != 0) 14291 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 14292 if (r == NULL) 14293 # else 14294 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 14295 serverStrToWin(serverid), &r, FALSE) < 0) 14296 # endif 14297 EMSG(_("E277: Unable to read a server reply")); 14298 } 14299 #endif 14300 rettv->v_type = VAR_STRING; 14301 rettv->vval.v_string = r; 14302 } 14303 14304 /* 14305 * "remote_send()" function 14306 */ 14307 static void 14308 f_remote_send(argvars, rettv) 14309 typval_T *argvars UNUSED; 14310 typval_T *rettv; 14311 { 14312 rettv->v_type = VAR_STRING; 14313 rettv->vval.v_string = NULL; 14314 #ifdef FEAT_CLIENTSERVER 14315 remote_common(argvars, rettv, FALSE); 14316 #endif 14317 } 14318 14319 /* 14320 * "remove()" function 14321 */ 14322 static void 14323 f_remove(argvars, rettv) 14324 typval_T *argvars; 14325 typval_T *rettv; 14326 { 14327 list_T *l; 14328 listitem_T *item, *item2; 14329 listitem_T *li; 14330 long idx; 14331 long end; 14332 char_u *key; 14333 dict_T *d; 14334 dictitem_T *di; 14335 14336 if (argvars[0].v_type == VAR_DICT) 14337 { 14338 if (argvars[2].v_type != VAR_UNKNOWN) 14339 EMSG2(_(e_toomanyarg), "remove()"); 14340 else if ((d = argvars[0].vval.v_dict) != NULL 14341 && !tv_check_lock(d->dv_lock, (char_u *)"remove() argument")) 14342 { 14343 key = get_tv_string_chk(&argvars[1]); 14344 if (key != NULL) 14345 { 14346 di = dict_find(d, key, -1); 14347 if (di == NULL) 14348 EMSG2(_(e_dictkey), key); 14349 else 14350 { 14351 *rettv = di->di_tv; 14352 init_tv(&di->di_tv); 14353 dictitem_remove(d, di); 14354 } 14355 } 14356 } 14357 } 14358 else if (argvars[0].v_type != VAR_LIST) 14359 EMSG2(_(e_listdictarg), "remove()"); 14360 else if ((l = argvars[0].vval.v_list) != NULL 14361 && !tv_check_lock(l->lv_lock, (char_u *)"remove() argument")) 14362 { 14363 int error = FALSE; 14364 14365 idx = get_tv_number_chk(&argvars[1], &error); 14366 if (error) 14367 ; /* type error: do nothing, errmsg already given */ 14368 else if ((item = list_find(l, idx)) == NULL) 14369 EMSGN(_(e_listidx), idx); 14370 else 14371 { 14372 if (argvars[2].v_type == VAR_UNKNOWN) 14373 { 14374 /* Remove one item, return its value. */ 14375 list_remove(l, item, item); 14376 *rettv = item->li_tv; 14377 vim_free(item); 14378 } 14379 else 14380 { 14381 /* Remove range of items, return list with values. */ 14382 end = get_tv_number_chk(&argvars[2], &error); 14383 if (error) 14384 ; /* type error: do nothing */ 14385 else if ((item2 = list_find(l, end)) == NULL) 14386 EMSGN(_(e_listidx), end); 14387 else 14388 { 14389 int cnt = 0; 14390 14391 for (li = item; li != NULL; li = li->li_next) 14392 { 14393 ++cnt; 14394 if (li == item2) 14395 break; 14396 } 14397 if (li == NULL) /* didn't find "item2" after "item" */ 14398 EMSG(_(e_invrange)); 14399 else 14400 { 14401 list_remove(l, item, item2); 14402 if (rettv_list_alloc(rettv) == OK) 14403 { 14404 l = rettv->vval.v_list; 14405 l->lv_first = item; 14406 l->lv_last = item2; 14407 item->li_prev = NULL; 14408 item2->li_next = NULL; 14409 l->lv_len = cnt; 14410 } 14411 } 14412 } 14413 } 14414 } 14415 } 14416 } 14417 14418 /* 14419 * "rename({from}, {to})" function 14420 */ 14421 static void 14422 f_rename(argvars, rettv) 14423 typval_T *argvars; 14424 typval_T *rettv; 14425 { 14426 char_u buf[NUMBUFLEN]; 14427 14428 if (check_restricted() || check_secure()) 14429 rettv->vval.v_number = -1; 14430 else 14431 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 14432 get_tv_string_buf(&argvars[1], buf)); 14433 } 14434 14435 /* 14436 * "repeat()" function 14437 */ 14438 static void 14439 f_repeat(argvars, rettv) 14440 typval_T *argvars; 14441 typval_T *rettv; 14442 { 14443 char_u *p; 14444 int n; 14445 int slen; 14446 int len; 14447 char_u *r; 14448 int i; 14449 14450 n = get_tv_number(&argvars[1]); 14451 if (argvars[0].v_type == VAR_LIST) 14452 { 14453 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 14454 while (n-- > 0) 14455 if (list_extend(rettv->vval.v_list, 14456 argvars[0].vval.v_list, NULL) == FAIL) 14457 break; 14458 } 14459 else 14460 { 14461 p = get_tv_string(&argvars[0]); 14462 rettv->v_type = VAR_STRING; 14463 rettv->vval.v_string = NULL; 14464 14465 slen = (int)STRLEN(p); 14466 len = slen * n; 14467 if (len <= 0) 14468 return; 14469 14470 r = alloc(len + 1); 14471 if (r != NULL) 14472 { 14473 for (i = 0; i < n; i++) 14474 mch_memmove(r + i * slen, p, (size_t)slen); 14475 r[len] = NUL; 14476 } 14477 14478 rettv->vval.v_string = r; 14479 } 14480 } 14481 14482 /* 14483 * "resolve()" function 14484 */ 14485 static void 14486 f_resolve(argvars, rettv) 14487 typval_T *argvars; 14488 typval_T *rettv; 14489 { 14490 char_u *p; 14491 14492 p = get_tv_string(&argvars[0]); 14493 #ifdef FEAT_SHORTCUT 14494 { 14495 char_u *v = NULL; 14496 14497 v = mch_resolve_shortcut(p); 14498 if (v != NULL) 14499 rettv->vval.v_string = v; 14500 else 14501 rettv->vval.v_string = vim_strsave(p); 14502 } 14503 #else 14504 # ifdef HAVE_READLINK 14505 { 14506 char_u buf[MAXPATHL + 1]; 14507 char_u *cpy; 14508 int len; 14509 char_u *remain = NULL; 14510 char_u *q; 14511 int is_relative_to_current = FALSE; 14512 int has_trailing_pathsep = FALSE; 14513 int limit = 100; 14514 14515 p = vim_strsave(p); 14516 14517 if (p[0] == '.' && (vim_ispathsep(p[1]) 14518 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 14519 is_relative_to_current = TRUE; 14520 14521 len = STRLEN(p); 14522 if (len > 0 && after_pathsep(p, p + len)) 14523 has_trailing_pathsep = TRUE; 14524 14525 q = getnextcomp(p); 14526 if (*q != NUL) 14527 { 14528 /* Separate the first path component in "p", and keep the 14529 * remainder (beginning with the path separator). */ 14530 remain = vim_strsave(q - 1); 14531 q[-1] = NUL; 14532 } 14533 14534 for (;;) 14535 { 14536 for (;;) 14537 { 14538 len = readlink((char *)p, (char *)buf, MAXPATHL); 14539 if (len <= 0) 14540 break; 14541 buf[len] = NUL; 14542 14543 if (limit-- == 0) 14544 { 14545 vim_free(p); 14546 vim_free(remain); 14547 EMSG(_("E655: Too many symbolic links (cycle?)")); 14548 rettv->vval.v_string = NULL; 14549 goto fail; 14550 } 14551 14552 /* Ensure that the result will have a trailing path separator 14553 * if the argument has one. */ 14554 if (remain == NULL && has_trailing_pathsep) 14555 add_pathsep(buf); 14556 14557 /* Separate the first path component in the link value and 14558 * concatenate the remainders. */ 14559 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 14560 if (*q != NUL) 14561 { 14562 if (remain == NULL) 14563 remain = vim_strsave(q - 1); 14564 else 14565 { 14566 cpy = concat_str(q - 1, remain); 14567 if (cpy != NULL) 14568 { 14569 vim_free(remain); 14570 remain = cpy; 14571 } 14572 } 14573 q[-1] = NUL; 14574 } 14575 14576 q = gettail(p); 14577 if (q > p && *q == NUL) 14578 { 14579 /* Ignore trailing path separator. */ 14580 q[-1] = NUL; 14581 q = gettail(p); 14582 } 14583 if (q > p && !mch_isFullName(buf)) 14584 { 14585 /* symlink is relative to directory of argument */ 14586 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 14587 if (cpy != NULL) 14588 { 14589 STRCPY(cpy, p); 14590 STRCPY(gettail(cpy), buf); 14591 vim_free(p); 14592 p = cpy; 14593 } 14594 } 14595 else 14596 { 14597 vim_free(p); 14598 p = vim_strsave(buf); 14599 } 14600 } 14601 14602 if (remain == NULL) 14603 break; 14604 14605 /* Append the first path component of "remain" to "p". */ 14606 q = getnextcomp(remain + 1); 14607 len = q - remain - (*q != NUL); 14608 cpy = vim_strnsave(p, STRLEN(p) + len); 14609 if (cpy != NULL) 14610 { 14611 STRNCAT(cpy, remain, len); 14612 vim_free(p); 14613 p = cpy; 14614 } 14615 /* Shorten "remain". */ 14616 if (*q != NUL) 14617 STRMOVE(remain, q - 1); 14618 else 14619 { 14620 vim_free(remain); 14621 remain = NULL; 14622 } 14623 } 14624 14625 /* If the result is a relative path name, make it explicitly relative to 14626 * the current directory if and only if the argument had this form. */ 14627 if (!vim_ispathsep(*p)) 14628 { 14629 if (is_relative_to_current 14630 && *p != NUL 14631 && !(p[0] == '.' 14632 && (p[1] == NUL 14633 || vim_ispathsep(p[1]) 14634 || (p[1] == '.' 14635 && (p[2] == NUL 14636 || vim_ispathsep(p[2])))))) 14637 { 14638 /* Prepend "./". */ 14639 cpy = concat_str((char_u *)"./", p); 14640 if (cpy != NULL) 14641 { 14642 vim_free(p); 14643 p = cpy; 14644 } 14645 } 14646 else if (!is_relative_to_current) 14647 { 14648 /* Strip leading "./". */ 14649 q = p; 14650 while (q[0] == '.' && vim_ispathsep(q[1])) 14651 q += 2; 14652 if (q > p) 14653 STRMOVE(p, p + 2); 14654 } 14655 } 14656 14657 /* Ensure that the result will have no trailing path separator 14658 * if the argument had none. But keep "/" or "//". */ 14659 if (!has_trailing_pathsep) 14660 { 14661 q = p + STRLEN(p); 14662 if (after_pathsep(p, q)) 14663 *gettail_sep(p) = NUL; 14664 } 14665 14666 rettv->vval.v_string = p; 14667 } 14668 # else 14669 rettv->vval.v_string = vim_strsave(p); 14670 # endif 14671 #endif 14672 14673 simplify_filename(rettv->vval.v_string); 14674 14675 #ifdef HAVE_READLINK 14676 fail: 14677 #endif 14678 rettv->v_type = VAR_STRING; 14679 } 14680 14681 /* 14682 * "reverse({list})" function 14683 */ 14684 static void 14685 f_reverse(argvars, rettv) 14686 typval_T *argvars; 14687 typval_T *rettv; 14688 { 14689 list_T *l; 14690 listitem_T *li, *ni; 14691 14692 if (argvars[0].v_type != VAR_LIST) 14693 EMSG2(_(e_listarg), "reverse()"); 14694 else if ((l = argvars[0].vval.v_list) != NULL 14695 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 14696 { 14697 li = l->lv_last; 14698 l->lv_first = l->lv_last = NULL; 14699 l->lv_len = 0; 14700 while (li != NULL) 14701 { 14702 ni = li->li_prev; 14703 list_append(l, li); 14704 li = ni; 14705 } 14706 rettv->vval.v_list = l; 14707 rettv->v_type = VAR_LIST; 14708 ++l->lv_refcount; 14709 l->lv_idx = l->lv_len - l->lv_idx - 1; 14710 } 14711 } 14712 14713 #define SP_NOMOVE 0x01 /* don't move cursor */ 14714 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 14715 #define SP_RETCOUNT 0x04 /* return matchcount */ 14716 #define SP_SETPCMARK 0x08 /* set previous context mark */ 14717 #define SP_START 0x10 /* accept match at start position */ 14718 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 14719 #define SP_END 0x40 /* leave cursor at end of match */ 14720 14721 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 14722 14723 /* 14724 * Get flags for a search function. 14725 * Possibly sets "p_ws". 14726 * Returns BACKWARD, FORWARD or zero (for an error). 14727 */ 14728 static int 14729 get_search_arg(varp, flagsp) 14730 typval_T *varp; 14731 int *flagsp; 14732 { 14733 int dir = FORWARD; 14734 char_u *flags; 14735 char_u nbuf[NUMBUFLEN]; 14736 int mask; 14737 14738 if (varp->v_type != VAR_UNKNOWN) 14739 { 14740 flags = get_tv_string_buf_chk(varp, nbuf); 14741 if (flags == NULL) 14742 return 0; /* type error; errmsg already given */ 14743 while (*flags != NUL) 14744 { 14745 switch (*flags) 14746 { 14747 case 'b': dir = BACKWARD; break; 14748 case 'w': p_ws = TRUE; break; 14749 case 'W': p_ws = FALSE; break; 14750 default: mask = 0; 14751 if (flagsp != NULL) 14752 switch (*flags) 14753 { 14754 case 'c': mask = SP_START; break; 14755 case 'e': mask = SP_END; break; 14756 case 'm': mask = SP_RETCOUNT; break; 14757 case 'n': mask = SP_NOMOVE; break; 14758 case 'p': mask = SP_SUBPAT; break; 14759 case 'r': mask = SP_REPEAT; break; 14760 case 's': mask = SP_SETPCMARK; break; 14761 } 14762 if (mask == 0) 14763 { 14764 EMSG2(_(e_invarg2), flags); 14765 dir = 0; 14766 } 14767 else 14768 *flagsp |= mask; 14769 } 14770 if (dir == 0) 14771 break; 14772 ++flags; 14773 } 14774 } 14775 return dir; 14776 } 14777 14778 /* 14779 * Shared by search() and searchpos() functions 14780 */ 14781 static int 14782 search_cmn(argvars, match_pos, flagsp) 14783 typval_T *argvars; 14784 pos_T *match_pos; 14785 int *flagsp; 14786 { 14787 int flags; 14788 char_u *pat; 14789 pos_T pos; 14790 pos_T save_cursor; 14791 int save_p_ws = p_ws; 14792 int dir; 14793 int retval = 0; /* default: FAIL */ 14794 long lnum_stop = 0; 14795 proftime_T tm; 14796 #ifdef FEAT_RELTIME 14797 long time_limit = 0; 14798 #endif 14799 int options = SEARCH_KEEP; 14800 int subpatnum; 14801 14802 pat = get_tv_string(&argvars[0]); 14803 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 14804 if (dir == 0) 14805 goto theend; 14806 flags = *flagsp; 14807 if (flags & SP_START) 14808 options |= SEARCH_START; 14809 if (flags & SP_END) 14810 options |= SEARCH_END; 14811 14812 /* Optional arguments: line number to stop searching and timeout. */ 14813 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) 14814 { 14815 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 14816 if (lnum_stop < 0) 14817 goto theend; 14818 #ifdef FEAT_RELTIME 14819 if (argvars[3].v_type != VAR_UNKNOWN) 14820 { 14821 time_limit = get_tv_number_chk(&argvars[3], NULL); 14822 if (time_limit < 0) 14823 goto theend; 14824 } 14825 #endif 14826 } 14827 14828 #ifdef FEAT_RELTIME 14829 /* Set the time limit, if there is one. */ 14830 profile_setlimit(time_limit, &tm); 14831 #endif 14832 14833 /* 14834 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 14835 * Check to make sure only those flags are set. 14836 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 14837 * flags cannot be set. Check for that condition also. 14838 */ 14839 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 14840 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 14841 { 14842 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 14843 goto theend; 14844 } 14845 14846 pos = save_cursor = curwin->w_cursor; 14847 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 14848 options, RE_SEARCH, (linenr_T)lnum_stop, &tm); 14849 if (subpatnum != FAIL) 14850 { 14851 if (flags & SP_SUBPAT) 14852 retval = subpatnum; 14853 else 14854 retval = pos.lnum; 14855 if (flags & SP_SETPCMARK) 14856 setpcmark(); 14857 curwin->w_cursor = pos; 14858 if (match_pos != NULL) 14859 { 14860 /* Store the match cursor position */ 14861 match_pos->lnum = pos.lnum; 14862 match_pos->col = pos.col + 1; 14863 } 14864 /* "/$" will put the cursor after the end of the line, may need to 14865 * correct that here */ 14866 check_cursor(); 14867 } 14868 14869 /* If 'n' flag is used: restore cursor position. */ 14870 if (flags & SP_NOMOVE) 14871 curwin->w_cursor = save_cursor; 14872 else 14873 curwin->w_set_curswant = TRUE; 14874 theend: 14875 p_ws = save_p_ws; 14876 14877 return retval; 14878 } 14879 14880 #ifdef FEAT_FLOAT 14881 /* 14882 * "round({float})" function 14883 */ 14884 static void 14885 f_round(argvars, rettv) 14886 typval_T *argvars; 14887 typval_T *rettv; 14888 { 14889 float_T f; 14890 14891 rettv->v_type = VAR_FLOAT; 14892 if (get_float_arg(argvars, &f) == OK) 14893 /* round() is not in C90, use ceil() or floor() instead. */ 14894 rettv->vval.v_float = f > 0 ? floor(f + 0.5) : ceil(f - 0.5); 14895 else 14896 rettv->vval.v_float = 0.0; 14897 } 14898 #endif 14899 14900 /* 14901 * "search()" function 14902 */ 14903 static void 14904 f_search(argvars, rettv) 14905 typval_T *argvars; 14906 typval_T *rettv; 14907 { 14908 int flags = 0; 14909 14910 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 14911 } 14912 14913 /* 14914 * "searchdecl()" function 14915 */ 14916 static void 14917 f_searchdecl(argvars, rettv) 14918 typval_T *argvars; 14919 typval_T *rettv; 14920 { 14921 int locally = 1; 14922 int thisblock = 0; 14923 int error = FALSE; 14924 char_u *name; 14925 14926 rettv->vval.v_number = 1; /* default: FAIL */ 14927 14928 name = get_tv_string_chk(&argvars[0]); 14929 if (argvars[1].v_type != VAR_UNKNOWN) 14930 { 14931 locally = get_tv_number_chk(&argvars[1], &error) == 0; 14932 if (!error && argvars[2].v_type != VAR_UNKNOWN) 14933 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 14934 } 14935 if (!error && name != NULL) 14936 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 14937 locally, thisblock, SEARCH_KEEP) == FAIL; 14938 } 14939 14940 /* 14941 * Used by searchpair() and searchpairpos() 14942 */ 14943 static int 14944 searchpair_cmn(argvars, match_pos) 14945 typval_T *argvars; 14946 pos_T *match_pos; 14947 { 14948 char_u *spat, *mpat, *epat; 14949 char_u *skip; 14950 int save_p_ws = p_ws; 14951 int dir; 14952 int flags = 0; 14953 char_u nbuf1[NUMBUFLEN]; 14954 char_u nbuf2[NUMBUFLEN]; 14955 char_u nbuf3[NUMBUFLEN]; 14956 int retval = 0; /* default: FAIL */ 14957 long lnum_stop = 0; 14958 long time_limit = 0; 14959 14960 /* Get the three pattern arguments: start, middle, end. */ 14961 spat = get_tv_string_chk(&argvars[0]); 14962 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 14963 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 14964 if (spat == NULL || mpat == NULL || epat == NULL) 14965 goto theend; /* type error */ 14966 14967 /* Handle the optional fourth argument: flags */ 14968 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 14969 if (dir == 0) 14970 goto theend; 14971 14972 /* Don't accept SP_END or SP_SUBPAT. 14973 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 14974 */ 14975 if ((flags & (SP_END | SP_SUBPAT)) != 0 14976 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 14977 { 14978 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 14979 goto theend; 14980 } 14981 14982 /* Using 'r' implies 'W', otherwise it doesn't work. */ 14983 if (flags & SP_REPEAT) 14984 p_ws = FALSE; 14985 14986 /* Optional fifth argument: skip expression */ 14987 if (argvars[3].v_type == VAR_UNKNOWN 14988 || argvars[4].v_type == VAR_UNKNOWN) 14989 skip = (char_u *)""; 14990 else 14991 { 14992 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 14993 if (argvars[5].v_type != VAR_UNKNOWN) 14994 { 14995 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 14996 if (lnum_stop < 0) 14997 goto theend; 14998 #ifdef FEAT_RELTIME 14999 if (argvars[6].v_type != VAR_UNKNOWN) 15000 { 15001 time_limit = get_tv_number_chk(&argvars[6], NULL); 15002 if (time_limit < 0) 15003 goto theend; 15004 } 15005 #endif 15006 } 15007 } 15008 if (skip == NULL) 15009 goto theend; /* type error */ 15010 15011 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 15012 match_pos, lnum_stop, time_limit); 15013 15014 theend: 15015 p_ws = save_p_ws; 15016 15017 return retval; 15018 } 15019 15020 /* 15021 * "searchpair()" function 15022 */ 15023 static void 15024 f_searchpair(argvars, rettv) 15025 typval_T *argvars; 15026 typval_T *rettv; 15027 { 15028 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 15029 } 15030 15031 /* 15032 * "searchpairpos()" function 15033 */ 15034 static void 15035 f_searchpairpos(argvars, rettv) 15036 typval_T *argvars; 15037 typval_T *rettv; 15038 { 15039 pos_T match_pos; 15040 int lnum = 0; 15041 int col = 0; 15042 15043 if (rettv_list_alloc(rettv) == FAIL) 15044 return; 15045 15046 if (searchpair_cmn(argvars, &match_pos) > 0) 15047 { 15048 lnum = match_pos.lnum; 15049 col = match_pos.col; 15050 } 15051 15052 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 15053 list_append_number(rettv->vval.v_list, (varnumber_T)col); 15054 } 15055 15056 /* 15057 * Search for a start/middle/end thing. 15058 * Used by searchpair(), see its documentation for the details. 15059 * Returns 0 or -1 for no match, 15060 */ 15061 long 15062 do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, 15063 lnum_stop, time_limit) 15064 char_u *spat; /* start pattern */ 15065 char_u *mpat; /* middle pattern */ 15066 char_u *epat; /* end pattern */ 15067 int dir; /* BACKWARD or FORWARD */ 15068 char_u *skip; /* skip expression */ 15069 int flags; /* SP_SETPCMARK and other SP_ values */ 15070 pos_T *match_pos; 15071 linenr_T lnum_stop; /* stop at this line if not zero */ 15072 long time_limit; /* stop after this many msec */ 15073 { 15074 char_u *save_cpo; 15075 char_u *pat, *pat2 = NULL, *pat3 = NULL; 15076 long retval = 0; 15077 pos_T pos; 15078 pos_T firstpos; 15079 pos_T foundpos; 15080 pos_T save_cursor; 15081 pos_T save_pos; 15082 int n; 15083 int r; 15084 int nest = 1; 15085 int err; 15086 int options = SEARCH_KEEP; 15087 proftime_T tm; 15088 15089 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 15090 save_cpo = p_cpo; 15091 p_cpo = empty_option; 15092 15093 #ifdef FEAT_RELTIME 15094 /* Set the time limit, if there is one. */ 15095 profile_setlimit(time_limit, &tm); 15096 #endif 15097 15098 /* Make two search patterns: start/end (pat2, for in nested pairs) and 15099 * start/middle/end (pat3, for the top pair). */ 15100 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 15101 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 15102 if (pat2 == NULL || pat3 == NULL) 15103 goto theend; 15104 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 15105 if (*mpat == NUL) 15106 STRCPY(pat3, pat2); 15107 else 15108 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 15109 spat, epat, mpat); 15110 if (flags & SP_START) 15111 options |= SEARCH_START; 15112 15113 save_cursor = curwin->w_cursor; 15114 pos = curwin->w_cursor; 15115 clearpos(&firstpos); 15116 clearpos(&foundpos); 15117 pat = pat3; 15118 for (;;) 15119 { 15120 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 15121 options, RE_SEARCH, lnum_stop, &tm); 15122 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 15123 /* didn't find it or found the first match again: FAIL */ 15124 break; 15125 15126 if (firstpos.lnum == 0) 15127 firstpos = pos; 15128 if (equalpos(pos, foundpos)) 15129 { 15130 /* Found the same position again. Can happen with a pattern that 15131 * has "\zs" at the end and searching backwards. Advance one 15132 * character and try again. */ 15133 if (dir == BACKWARD) 15134 decl(&pos); 15135 else 15136 incl(&pos); 15137 } 15138 foundpos = pos; 15139 15140 /* clear the start flag to avoid getting stuck here */ 15141 options &= ~SEARCH_START; 15142 15143 /* If the skip pattern matches, ignore this match. */ 15144 if (*skip != NUL) 15145 { 15146 save_pos = curwin->w_cursor; 15147 curwin->w_cursor = pos; 15148 r = eval_to_bool(skip, &err, NULL, FALSE); 15149 curwin->w_cursor = save_pos; 15150 if (err) 15151 { 15152 /* Evaluating {skip} caused an error, break here. */ 15153 curwin->w_cursor = save_cursor; 15154 retval = -1; 15155 break; 15156 } 15157 if (r) 15158 continue; 15159 } 15160 15161 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 15162 { 15163 /* Found end when searching backwards or start when searching 15164 * forward: nested pair. */ 15165 ++nest; 15166 pat = pat2; /* nested, don't search for middle */ 15167 } 15168 else 15169 { 15170 /* Found end when searching forward or start when searching 15171 * backward: end of (nested) pair; or found middle in outer pair. */ 15172 if (--nest == 1) 15173 pat = pat3; /* outer level, search for middle */ 15174 } 15175 15176 if (nest == 0) 15177 { 15178 /* Found the match: return matchcount or line number. */ 15179 if (flags & SP_RETCOUNT) 15180 ++retval; 15181 else 15182 retval = pos.lnum; 15183 if (flags & SP_SETPCMARK) 15184 setpcmark(); 15185 curwin->w_cursor = pos; 15186 if (!(flags & SP_REPEAT)) 15187 break; 15188 nest = 1; /* search for next unmatched */ 15189 } 15190 } 15191 15192 if (match_pos != NULL) 15193 { 15194 /* Store the match cursor position */ 15195 match_pos->lnum = curwin->w_cursor.lnum; 15196 match_pos->col = curwin->w_cursor.col + 1; 15197 } 15198 15199 /* If 'n' flag is used or search failed: restore cursor position. */ 15200 if ((flags & SP_NOMOVE) || retval == 0) 15201 curwin->w_cursor = save_cursor; 15202 15203 theend: 15204 vim_free(pat2); 15205 vim_free(pat3); 15206 if (p_cpo == empty_option) 15207 p_cpo = save_cpo; 15208 else 15209 /* Darn, evaluating the {skip} expression changed the value. */ 15210 free_string_option(save_cpo); 15211 15212 return retval; 15213 } 15214 15215 /* 15216 * "searchpos()" function 15217 */ 15218 static void 15219 f_searchpos(argvars, rettv) 15220 typval_T *argvars; 15221 typval_T *rettv; 15222 { 15223 pos_T match_pos; 15224 int lnum = 0; 15225 int col = 0; 15226 int n; 15227 int flags = 0; 15228 15229 if (rettv_list_alloc(rettv) == FAIL) 15230 return; 15231 15232 n = search_cmn(argvars, &match_pos, &flags); 15233 if (n > 0) 15234 { 15235 lnum = match_pos.lnum; 15236 col = match_pos.col; 15237 } 15238 15239 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 15240 list_append_number(rettv->vval.v_list, (varnumber_T)col); 15241 if (flags & SP_SUBPAT) 15242 list_append_number(rettv->vval.v_list, (varnumber_T)n); 15243 } 15244 15245 15246 static void 15247 f_server2client(argvars, rettv) 15248 typval_T *argvars UNUSED; 15249 typval_T *rettv; 15250 { 15251 #ifdef FEAT_CLIENTSERVER 15252 char_u buf[NUMBUFLEN]; 15253 char_u *server = get_tv_string_chk(&argvars[0]); 15254 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 15255 15256 rettv->vval.v_number = -1; 15257 if (server == NULL || reply == NULL) 15258 return; 15259 if (check_restricted() || check_secure()) 15260 return; 15261 # ifdef FEAT_X11 15262 if (check_connection() == FAIL) 15263 return; 15264 # endif 15265 15266 if (serverSendReply(server, reply) < 0) 15267 { 15268 EMSG(_("E258: Unable to send to client")); 15269 return; 15270 } 15271 rettv->vval.v_number = 0; 15272 #else 15273 rettv->vval.v_number = -1; 15274 #endif 15275 } 15276 15277 static void 15278 f_serverlist(argvars, rettv) 15279 typval_T *argvars UNUSED; 15280 typval_T *rettv; 15281 { 15282 char_u *r = NULL; 15283 15284 #ifdef FEAT_CLIENTSERVER 15285 # ifdef WIN32 15286 r = serverGetVimNames(); 15287 # else 15288 make_connection(); 15289 if (X_DISPLAY != NULL) 15290 r = serverGetVimNames(X_DISPLAY); 15291 # endif 15292 #endif 15293 rettv->v_type = VAR_STRING; 15294 rettv->vval.v_string = r; 15295 } 15296 15297 /* 15298 * "setbufvar()" function 15299 */ 15300 static void 15301 f_setbufvar(argvars, rettv) 15302 typval_T *argvars; 15303 typval_T *rettv UNUSED; 15304 { 15305 buf_T *buf; 15306 aco_save_T aco; 15307 char_u *varname, *bufvarname; 15308 typval_T *varp; 15309 char_u nbuf[NUMBUFLEN]; 15310 15311 if (check_restricted() || check_secure()) 15312 return; 15313 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 15314 varname = get_tv_string_chk(&argvars[1]); 15315 buf = get_buf_tv(&argvars[0]); 15316 varp = &argvars[2]; 15317 15318 if (buf != NULL && varname != NULL && varp != NULL) 15319 { 15320 /* set curbuf to be our buf, temporarily */ 15321 aucmd_prepbuf(&aco, buf); 15322 15323 if (*varname == '&') 15324 { 15325 long numval; 15326 char_u *strval; 15327 int error = FALSE; 15328 15329 ++varname; 15330 numval = get_tv_number_chk(varp, &error); 15331 strval = get_tv_string_buf_chk(varp, nbuf); 15332 if (!error && strval != NULL) 15333 set_option_value(varname, numval, strval, OPT_LOCAL); 15334 } 15335 else 15336 { 15337 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 15338 if (bufvarname != NULL) 15339 { 15340 STRCPY(bufvarname, "b:"); 15341 STRCPY(bufvarname + 2, varname); 15342 set_var(bufvarname, varp, TRUE); 15343 vim_free(bufvarname); 15344 } 15345 } 15346 15347 /* reset notion of buffer */ 15348 aucmd_restbuf(&aco); 15349 } 15350 } 15351 15352 /* 15353 * "setcmdpos()" function 15354 */ 15355 static void 15356 f_setcmdpos(argvars, rettv) 15357 typval_T *argvars; 15358 typval_T *rettv; 15359 { 15360 int pos = (int)get_tv_number(&argvars[0]) - 1; 15361 15362 if (pos >= 0) 15363 rettv->vval.v_number = set_cmdline_pos(pos); 15364 } 15365 15366 /* 15367 * "setline()" function 15368 */ 15369 static void 15370 f_setline(argvars, rettv) 15371 typval_T *argvars; 15372 typval_T *rettv; 15373 { 15374 linenr_T lnum; 15375 char_u *line = NULL; 15376 list_T *l = NULL; 15377 listitem_T *li = NULL; 15378 long added = 0; 15379 linenr_T lcount = curbuf->b_ml.ml_line_count; 15380 15381 lnum = get_tv_lnum(&argvars[0]); 15382 if (argvars[1].v_type == VAR_LIST) 15383 { 15384 l = argvars[1].vval.v_list; 15385 li = l->lv_first; 15386 } 15387 else 15388 line = get_tv_string_chk(&argvars[1]); 15389 15390 /* default result is zero == OK */ 15391 for (;;) 15392 { 15393 if (l != NULL) 15394 { 15395 /* list argument, get next string */ 15396 if (li == NULL) 15397 break; 15398 line = get_tv_string_chk(&li->li_tv); 15399 li = li->li_next; 15400 } 15401 15402 rettv->vval.v_number = 1; /* FAIL */ 15403 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 15404 break; 15405 if (lnum <= curbuf->b_ml.ml_line_count) 15406 { 15407 /* existing line, replace it */ 15408 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 15409 { 15410 changed_bytes(lnum, 0); 15411 if (lnum == curwin->w_cursor.lnum) 15412 check_cursor_col(); 15413 rettv->vval.v_number = 0; /* OK */ 15414 } 15415 } 15416 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 15417 { 15418 /* lnum is one past the last line, append the line */ 15419 ++added; 15420 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 15421 rettv->vval.v_number = 0; /* OK */ 15422 } 15423 15424 if (l == NULL) /* only one string argument */ 15425 break; 15426 ++lnum; 15427 } 15428 15429 if (added > 0) 15430 appended_lines_mark(lcount, added); 15431 } 15432 15433 static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv)); 15434 15435 /* 15436 * Used by "setqflist()" and "setloclist()" functions 15437 */ 15438 static void 15439 set_qf_ll_list(wp, list_arg, action_arg, rettv) 15440 win_T *wp UNUSED; 15441 typval_T *list_arg UNUSED; 15442 typval_T *action_arg UNUSED; 15443 typval_T *rettv; 15444 { 15445 #ifdef FEAT_QUICKFIX 15446 char_u *act; 15447 int action = ' '; 15448 #endif 15449 15450 rettv->vval.v_number = -1; 15451 15452 #ifdef FEAT_QUICKFIX 15453 if (list_arg->v_type != VAR_LIST) 15454 EMSG(_(e_listreq)); 15455 else 15456 { 15457 list_T *l = list_arg->vval.v_list; 15458 15459 if (action_arg->v_type == VAR_STRING) 15460 { 15461 act = get_tv_string_chk(action_arg); 15462 if (act == NULL) 15463 return; /* type error; errmsg already given */ 15464 if (*act == 'a' || *act == 'r') 15465 action = *act; 15466 } 15467 15468 if (l != NULL && set_errorlist(wp, l, action) == OK) 15469 rettv->vval.v_number = 0; 15470 } 15471 #endif 15472 } 15473 15474 /* 15475 * "setloclist()" function 15476 */ 15477 static void 15478 f_setloclist(argvars, rettv) 15479 typval_T *argvars; 15480 typval_T *rettv; 15481 { 15482 win_T *win; 15483 15484 rettv->vval.v_number = -1; 15485 15486 win = find_win_by_nr(&argvars[0], NULL); 15487 if (win != NULL) 15488 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 15489 } 15490 15491 /* 15492 * "setmatches()" function 15493 */ 15494 static void 15495 f_setmatches(argvars, rettv) 15496 typval_T *argvars; 15497 typval_T *rettv; 15498 { 15499 #ifdef FEAT_SEARCH_EXTRA 15500 list_T *l; 15501 listitem_T *li; 15502 dict_T *d; 15503 15504 rettv->vval.v_number = -1; 15505 if (argvars[0].v_type != VAR_LIST) 15506 { 15507 EMSG(_(e_listreq)); 15508 return; 15509 } 15510 if ((l = argvars[0].vval.v_list) != NULL) 15511 { 15512 15513 /* To some extent make sure that we are dealing with a list from 15514 * "getmatches()". */ 15515 li = l->lv_first; 15516 while (li != NULL) 15517 { 15518 if (li->li_tv.v_type != VAR_DICT 15519 || (d = li->li_tv.vval.v_dict) == NULL) 15520 { 15521 EMSG(_(e_invarg)); 15522 return; 15523 } 15524 if (!(dict_find(d, (char_u *)"group", -1) != NULL 15525 && dict_find(d, (char_u *)"pattern", -1) != NULL 15526 && dict_find(d, (char_u *)"priority", -1) != NULL 15527 && dict_find(d, (char_u *)"id", -1) != NULL)) 15528 { 15529 EMSG(_(e_invarg)); 15530 return; 15531 } 15532 li = li->li_next; 15533 } 15534 15535 clear_matches(curwin); 15536 li = l->lv_first; 15537 while (li != NULL) 15538 { 15539 d = li->li_tv.vval.v_dict; 15540 match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE), 15541 get_dict_string(d, (char_u *)"pattern", FALSE), 15542 (int)get_dict_number(d, (char_u *)"priority"), 15543 (int)get_dict_number(d, (char_u *)"id")); 15544 li = li->li_next; 15545 } 15546 rettv->vval.v_number = 0; 15547 } 15548 #endif 15549 } 15550 15551 /* 15552 * "setpos()" function 15553 */ 15554 static void 15555 f_setpos(argvars, rettv) 15556 typval_T *argvars; 15557 typval_T *rettv; 15558 { 15559 pos_T pos; 15560 int fnum; 15561 char_u *name; 15562 15563 rettv->vval.v_number = -1; 15564 name = get_tv_string_chk(argvars); 15565 if (name != NULL) 15566 { 15567 if (list2fpos(&argvars[1], &pos, &fnum) == OK) 15568 { 15569 if (--pos.col < 0) 15570 pos.col = 0; 15571 if (name[0] == '.' && name[1] == NUL) 15572 { 15573 /* set cursor */ 15574 if (fnum == curbuf->b_fnum) 15575 { 15576 curwin->w_cursor = pos; 15577 check_cursor(); 15578 rettv->vval.v_number = 0; 15579 } 15580 else 15581 EMSG(_(e_invarg)); 15582 } 15583 else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) 15584 { 15585 /* set mark */ 15586 if (setmark_pos(name[1], &pos, fnum) == OK) 15587 rettv->vval.v_number = 0; 15588 } 15589 else 15590 EMSG(_(e_invarg)); 15591 } 15592 } 15593 } 15594 15595 /* 15596 * "setqflist()" function 15597 */ 15598 static void 15599 f_setqflist(argvars, rettv) 15600 typval_T *argvars; 15601 typval_T *rettv; 15602 { 15603 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 15604 } 15605 15606 /* 15607 * "setreg()" function 15608 */ 15609 static void 15610 f_setreg(argvars, rettv) 15611 typval_T *argvars; 15612 typval_T *rettv; 15613 { 15614 int regname; 15615 char_u *strregname; 15616 char_u *stropt; 15617 char_u *strval; 15618 int append; 15619 char_u yank_type; 15620 long block_len; 15621 15622 block_len = -1; 15623 yank_type = MAUTO; 15624 append = FALSE; 15625 15626 strregname = get_tv_string_chk(argvars); 15627 rettv->vval.v_number = 1; /* FAIL is default */ 15628 15629 if (strregname == NULL) 15630 return; /* type error; errmsg already given */ 15631 regname = *strregname; 15632 if (regname == 0 || regname == '@') 15633 regname = '"'; 15634 else if (regname == '=') 15635 return; 15636 15637 if (argvars[2].v_type != VAR_UNKNOWN) 15638 { 15639 stropt = get_tv_string_chk(&argvars[2]); 15640 if (stropt == NULL) 15641 return; /* type error */ 15642 for (; *stropt != NUL; ++stropt) 15643 switch (*stropt) 15644 { 15645 case 'a': case 'A': /* append */ 15646 append = TRUE; 15647 break; 15648 case 'v': case 'c': /* character-wise selection */ 15649 yank_type = MCHAR; 15650 break; 15651 case 'V': case 'l': /* line-wise selection */ 15652 yank_type = MLINE; 15653 break; 15654 #ifdef FEAT_VISUAL 15655 case 'b': case Ctrl_V: /* block-wise selection */ 15656 yank_type = MBLOCK; 15657 if (VIM_ISDIGIT(stropt[1])) 15658 { 15659 ++stropt; 15660 block_len = getdigits(&stropt) - 1; 15661 --stropt; 15662 } 15663 break; 15664 #endif 15665 } 15666 } 15667 15668 strval = get_tv_string_chk(&argvars[1]); 15669 if (strval != NULL) 15670 write_reg_contents_ex(regname, strval, -1, 15671 append, yank_type, block_len); 15672 rettv->vval.v_number = 0; 15673 } 15674 15675 /* 15676 * "settabwinvar()" function 15677 */ 15678 static void 15679 f_settabwinvar(argvars, rettv) 15680 typval_T *argvars; 15681 typval_T *rettv; 15682 { 15683 setwinvar(argvars, rettv, 1); 15684 } 15685 15686 /* 15687 * "setwinvar()" function 15688 */ 15689 static void 15690 f_setwinvar(argvars, rettv) 15691 typval_T *argvars; 15692 typval_T *rettv; 15693 { 15694 setwinvar(argvars, rettv, 0); 15695 } 15696 15697 /* 15698 * "setwinvar()" and "settabwinvar()" functions 15699 */ 15700 static void 15701 setwinvar(argvars, rettv, off) 15702 typval_T *argvars; 15703 typval_T *rettv UNUSED; 15704 int off; 15705 { 15706 win_T *win; 15707 #ifdef FEAT_WINDOWS 15708 win_T *save_curwin; 15709 tabpage_T *save_curtab; 15710 #endif 15711 char_u *varname, *winvarname; 15712 typval_T *varp; 15713 char_u nbuf[NUMBUFLEN]; 15714 tabpage_T *tp; 15715 15716 if (check_restricted() || check_secure()) 15717 return; 15718 15719 #ifdef FEAT_WINDOWS 15720 if (off == 1) 15721 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 15722 else 15723 tp = curtab; 15724 #endif 15725 win = find_win_by_nr(&argvars[off], tp); 15726 varname = get_tv_string_chk(&argvars[off + 1]); 15727 varp = &argvars[off + 2]; 15728 15729 if (win != NULL && varname != NULL && varp != NULL) 15730 { 15731 #ifdef FEAT_WINDOWS 15732 /* set curwin to be our win, temporarily */ 15733 save_curwin = curwin; 15734 save_curtab = curtab; 15735 goto_tabpage_tp(tp); 15736 if (!win_valid(win)) 15737 return; 15738 curwin = win; 15739 curbuf = curwin->w_buffer; 15740 #endif 15741 15742 if (*varname == '&') 15743 { 15744 long numval; 15745 char_u *strval; 15746 int error = FALSE; 15747 15748 ++varname; 15749 numval = get_tv_number_chk(varp, &error); 15750 strval = get_tv_string_buf_chk(varp, nbuf); 15751 if (!error && strval != NULL) 15752 set_option_value(varname, numval, strval, OPT_LOCAL); 15753 } 15754 else 15755 { 15756 winvarname = alloc((unsigned)STRLEN(varname) + 3); 15757 if (winvarname != NULL) 15758 { 15759 STRCPY(winvarname, "w:"); 15760 STRCPY(winvarname + 2, varname); 15761 set_var(winvarname, varp, TRUE); 15762 vim_free(winvarname); 15763 } 15764 } 15765 15766 #ifdef FEAT_WINDOWS 15767 /* Restore current tabpage and window, if still valid (autocomands can 15768 * make them invalid). */ 15769 if (valid_tabpage(save_curtab)) 15770 goto_tabpage_tp(save_curtab); 15771 if (win_valid(save_curwin)) 15772 { 15773 curwin = save_curwin; 15774 curbuf = curwin->w_buffer; 15775 } 15776 #endif 15777 } 15778 } 15779 15780 /* 15781 * "shellescape({string})" function 15782 */ 15783 static void 15784 f_shellescape(argvars, rettv) 15785 typval_T *argvars; 15786 typval_T *rettv; 15787 { 15788 rettv->vval.v_string = vim_strsave_shellescape( 15789 get_tv_string(&argvars[0]), non_zero_arg(&argvars[1])); 15790 rettv->v_type = VAR_STRING; 15791 } 15792 15793 /* 15794 * "simplify()" function 15795 */ 15796 static void 15797 f_simplify(argvars, rettv) 15798 typval_T *argvars; 15799 typval_T *rettv; 15800 { 15801 char_u *p; 15802 15803 p = get_tv_string(&argvars[0]); 15804 rettv->vval.v_string = vim_strsave(p); 15805 simplify_filename(rettv->vval.v_string); /* simplify in place */ 15806 rettv->v_type = VAR_STRING; 15807 } 15808 15809 #ifdef FEAT_FLOAT 15810 /* 15811 * "sin()" function 15812 */ 15813 static void 15814 f_sin(argvars, rettv) 15815 typval_T *argvars; 15816 typval_T *rettv; 15817 { 15818 float_T f; 15819 15820 rettv->v_type = VAR_FLOAT; 15821 if (get_float_arg(argvars, &f) == OK) 15822 rettv->vval.v_float = sin(f); 15823 else 15824 rettv->vval.v_float = 0.0; 15825 } 15826 #endif 15827 15828 static int 15829 #ifdef __BORLANDC__ 15830 _RTLENTRYF 15831 #endif 15832 item_compare __ARGS((const void *s1, const void *s2)); 15833 static int 15834 #ifdef __BORLANDC__ 15835 _RTLENTRYF 15836 #endif 15837 item_compare2 __ARGS((const void *s1, const void *s2)); 15838 15839 static int item_compare_ic; 15840 static char_u *item_compare_func; 15841 static int item_compare_func_err; 15842 #define ITEM_COMPARE_FAIL 999 15843 15844 /* 15845 * Compare functions for f_sort() below. 15846 */ 15847 static int 15848 #ifdef __BORLANDC__ 15849 _RTLENTRYF 15850 #endif 15851 item_compare(s1, s2) 15852 const void *s1; 15853 const void *s2; 15854 { 15855 char_u *p1, *p2; 15856 char_u *tofree1, *tofree2; 15857 int res; 15858 char_u numbuf1[NUMBUFLEN]; 15859 char_u numbuf2[NUMBUFLEN]; 15860 15861 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0); 15862 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0); 15863 if (p1 == NULL) 15864 p1 = (char_u *)""; 15865 if (p2 == NULL) 15866 p2 = (char_u *)""; 15867 if (item_compare_ic) 15868 res = STRICMP(p1, p2); 15869 else 15870 res = STRCMP(p1, p2); 15871 vim_free(tofree1); 15872 vim_free(tofree2); 15873 return res; 15874 } 15875 15876 static int 15877 #ifdef __BORLANDC__ 15878 _RTLENTRYF 15879 #endif 15880 item_compare2(s1, s2) 15881 const void *s1; 15882 const void *s2; 15883 { 15884 int res; 15885 typval_T rettv; 15886 typval_T argv[3]; 15887 int dummy; 15888 15889 /* shortcut after failure in previous call; compare all items equal */ 15890 if (item_compare_func_err) 15891 return 0; 15892 15893 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 15894 * in the copy without changing the original list items. */ 15895 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 15896 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 15897 15898 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 15899 res = call_func(item_compare_func, (int)STRLEN(item_compare_func), 15900 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 15901 clear_tv(&argv[0]); 15902 clear_tv(&argv[1]); 15903 15904 if (res == FAIL) 15905 res = ITEM_COMPARE_FAIL; 15906 else 15907 res = get_tv_number_chk(&rettv, &item_compare_func_err); 15908 if (item_compare_func_err) 15909 res = ITEM_COMPARE_FAIL; /* return value has wrong type */ 15910 clear_tv(&rettv); 15911 return res; 15912 } 15913 15914 /* 15915 * "sort({list})" function 15916 */ 15917 static void 15918 f_sort(argvars, rettv) 15919 typval_T *argvars; 15920 typval_T *rettv; 15921 { 15922 list_T *l; 15923 listitem_T *li; 15924 listitem_T **ptrs; 15925 long len; 15926 long i; 15927 15928 if (argvars[0].v_type != VAR_LIST) 15929 EMSG2(_(e_listarg), "sort()"); 15930 else 15931 { 15932 l = argvars[0].vval.v_list; 15933 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 15934 return; 15935 rettv->vval.v_list = l; 15936 rettv->v_type = VAR_LIST; 15937 ++l->lv_refcount; 15938 15939 len = list_len(l); 15940 if (len <= 1) 15941 return; /* short list sorts pretty quickly */ 15942 15943 item_compare_ic = FALSE; 15944 item_compare_func = NULL; 15945 if (argvars[1].v_type != VAR_UNKNOWN) 15946 { 15947 if (argvars[1].v_type == VAR_FUNC) 15948 item_compare_func = argvars[1].vval.v_string; 15949 else 15950 { 15951 int error = FALSE; 15952 15953 i = get_tv_number_chk(&argvars[1], &error); 15954 if (error) 15955 return; /* type error; errmsg already given */ 15956 if (i == 1) 15957 item_compare_ic = TRUE; 15958 else 15959 item_compare_func = get_tv_string(&argvars[1]); 15960 } 15961 } 15962 15963 /* Make an array with each entry pointing to an item in the List. */ 15964 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 15965 if (ptrs == NULL) 15966 return; 15967 i = 0; 15968 for (li = l->lv_first; li != NULL; li = li->li_next) 15969 ptrs[i++] = li; 15970 15971 item_compare_func_err = FALSE; 15972 /* test the compare function */ 15973 if (item_compare_func != NULL 15974 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 15975 == ITEM_COMPARE_FAIL) 15976 EMSG(_("E702: Sort compare function failed")); 15977 else 15978 { 15979 /* Sort the array with item pointers. */ 15980 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 15981 item_compare_func == NULL ? item_compare : item_compare2); 15982 15983 if (!item_compare_func_err) 15984 { 15985 /* Clear the List and append the items in the sorted order. */ 15986 l->lv_first = l->lv_last = l->lv_idx_item = NULL; 15987 l->lv_len = 0; 15988 for (i = 0; i < len; ++i) 15989 list_append(l, ptrs[i]); 15990 } 15991 } 15992 15993 vim_free(ptrs); 15994 } 15995 } 15996 15997 /* 15998 * "soundfold({word})" function 15999 */ 16000 static void 16001 f_soundfold(argvars, rettv) 16002 typval_T *argvars; 16003 typval_T *rettv; 16004 { 16005 char_u *s; 16006 16007 rettv->v_type = VAR_STRING; 16008 s = get_tv_string(&argvars[0]); 16009 #ifdef FEAT_SPELL 16010 rettv->vval.v_string = eval_soundfold(s); 16011 #else 16012 rettv->vval.v_string = vim_strsave(s); 16013 #endif 16014 } 16015 16016 /* 16017 * "spellbadword()" function 16018 */ 16019 static void 16020 f_spellbadword(argvars, rettv) 16021 typval_T *argvars UNUSED; 16022 typval_T *rettv; 16023 { 16024 char_u *word = (char_u *)""; 16025 hlf_T attr = HLF_COUNT; 16026 int len = 0; 16027 16028 if (rettv_list_alloc(rettv) == FAIL) 16029 return; 16030 16031 #ifdef FEAT_SPELL 16032 if (argvars[0].v_type == VAR_UNKNOWN) 16033 { 16034 /* Find the start and length of the badly spelled word. */ 16035 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 16036 if (len != 0) 16037 word = ml_get_cursor(); 16038 } 16039 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 16040 { 16041 char_u *str = get_tv_string_chk(&argvars[0]); 16042 int capcol = -1; 16043 16044 if (str != NULL) 16045 { 16046 /* Check the argument for spelling. */ 16047 while (*str != NUL) 16048 { 16049 len = spell_check(curwin, str, &attr, &capcol, FALSE); 16050 if (attr != HLF_COUNT) 16051 { 16052 word = str; 16053 break; 16054 } 16055 str += len; 16056 } 16057 } 16058 } 16059 #endif 16060 16061 list_append_string(rettv->vval.v_list, word, len); 16062 list_append_string(rettv->vval.v_list, (char_u *)( 16063 attr == HLF_SPB ? "bad" : 16064 attr == HLF_SPR ? "rare" : 16065 attr == HLF_SPL ? "local" : 16066 attr == HLF_SPC ? "caps" : 16067 ""), -1); 16068 } 16069 16070 /* 16071 * "spellsuggest()" function 16072 */ 16073 static void 16074 f_spellsuggest(argvars, rettv) 16075 typval_T *argvars UNUSED; 16076 typval_T *rettv; 16077 { 16078 #ifdef FEAT_SPELL 16079 char_u *str; 16080 int typeerr = FALSE; 16081 int maxcount; 16082 garray_T ga; 16083 int i; 16084 listitem_T *li; 16085 int need_capital = FALSE; 16086 #endif 16087 16088 if (rettv_list_alloc(rettv) == FAIL) 16089 return; 16090 16091 #ifdef FEAT_SPELL 16092 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 16093 { 16094 str = get_tv_string(&argvars[0]); 16095 if (argvars[1].v_type != VAR_UNKNOWN) 16096 { 16097 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 16098 if (maxcount <= 0) 16099 return; 16100 if (argvars[2].v_type != VAR_UNKNOWN) 16101 { 16102 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 16103 if (typeerr) 16104 return; 16105 } 16106 } 16107 else 16108 maxcount = 25; 16109 16110 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 16111 16112 for (i = 0; i < ga.ga_len; ++i) 16113 { 16114 str = ((char_u **)ga.ga_data)[i]; 16115 16116 li = listitem_alloc(); 16117 if (li == NULL) 16118 vim_free(str); 16119 else 16120 { 16121 li->li_tv.v_type = VAR_STRING; 16122 li->li_tv.v_lock = 0; 16123 li->li_tv.vval.v_string = str; 16124 list_append(rettv->vval.v_list, li); 16125 } 16126 } 16127 ga_clear(&ga); 16128 } 16129 #endif 16130 } 16131 16132 static void 16133 f_split(argvars, rettv) 16134 typval_T *argvars; 16135 typval_T *rettv; 16136 { 16137 char_u *str; 16138 char_u *end; 16139 char_u *pat = NULL; 16140 regmatch_T regmatch; 16141 char_u patbuf[NUMBUFLEN]; 16142 char_u *save_cpo; 16143 int match; 16144 colnr_T col = 0; 16145 int keepempty = FALSE; 16146 int typeerr = FALSE; 16147 16148 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 16149 save_cpo = p_cpo; 16150 p_cpo = (char_u *)""; 16151 16152 str = get_tv_string(&argvars[0]); 16153 if (argvars[1].v_type != VAR_UNKNOWN) 16154 { 16155 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 16156 if (pat == NULL) 16157 typeerr = TRUE; 16158 if (argvars[2].v_type != VAR_UNKNOWN) 16159 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 16160 } 16161 if (pat == NULL || *pat == NUL) 16162 pat = (char_u *)"[\\x01- ]\\+"; 16163 16164 if (rettv_list_alloc(rettv) == FAIL) 16165 return; 16166 if (typeerr) 16167 return; 16168 16169 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 16170 if (regmatch.regprog != NULL) 16171 { 16172 regmatch.rm_ic = FALSE; 16173 while (*str != NUL || keepempty) 16174 { 16175 if (*str == NUL) 16176 match = FALSE; /* empty item at the end */ 16177 else 16178 match = vim_regexec_nl(®match, str, col); 16179 if (match) 16180 end = regmatch.startp[0]; 16181 else 16182 end = str + STRLEN(str); 16183 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 16184 && *str != NUL && match && end < regmatch.endp[0])) 16185 { 16186 if (list_append_string(rettv->vval.v_list, str, 16187 (int)(end - str)) == FAIL) 16188 break; 16189 } 16190 if (!match) 16191 break; 16192 /* Advance to just after the match. */ 16193 if (regmatch.endp[0] > str) 16194 col = 0; 16195 else 16196 { 16197 /* Don't get stuck at the same match. */ 16198 #ifdef FEAT_MBYTE 16199 col = (*mb_ptr2len)(regmatch.endp[0]); 16200 #else 16201 col = 1; 16202 #endif 16203 } 16204 str = regmatch.endp[0]; 16205 } 16206 16207 vim_free(regmatch.regprog); 16208 } 16209 16210 p_cpo = save_cpo; 16211 } 16212 16213 #ifdef FEAT_FLOAT 16214 /* 16215 * "sqrt()" function 16216 */ 16217 static void 16218 f_sqrt(argvars, rettv) 16219 typval_T *argvars; 16220 typval_T *rettv; 16221 { 16222 float_T f; 16223 16224 rettv->v_type = VAR_FLOAT; 16225 if (get_float_arg(argvars, &f) == OK) 16226 rettv->vval.v_float = sqrt(f); 16227 else 16228 rettv->vval.v_float = 0.0; 16229 } 16230 16231 /* 16232 * "str2float()" function 16233 */ 16234 static void 16235 f_str2float(argvars, rettv) 16236 typval_T *argvars; 16237 typval_T *rettv; 16238 { 16239 char_u *p = skipwhite(get_tv_string(&argvars[0])); 16240 16241 if (*p == '+') 16242 p = skipwhite(p + 1); 16243 (void)string2float(p, &rettv->vval.v_float); 16244 rettv->v_type = VAR_FLOAT; 16245 } 16246 #endif 16247 16248 /* 16249 * "str2nr()" function 16250 */ 16251 static void 16252 f_str2nr(argvars, rettv) 16253 typval_T *argvars; 16254 typval_T *rettv; 16255 { 16256 int base = 10; 16257 char_u *p; 16258 long n; 16259 16260 if (argvars[1].v_type != VAR_UNKNOWN) 16261 { 16262 base = get_tv_number(&argvars[1]); 16263 if (base != 8 && base != 10 && base != 16) 16264 { 16265 EMSG(_(e_invarg)); 16266 return; 16267 } 16268 } 16269 16270 p = skipwhite(get_tv_string(&argvars[0])); 16271 if (*p == '+') 16272 p = skipwhite(p + 1); 16273 vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL); 16274 rettv->vval.v_number = n; 16275 } 16276 16277 #ifdef HAVE_STRFTIME 16278 /* 16279 * "strftime({format}[, {time}])" function 16280 */ 16281 static void 16282 f_strftime(argvars, rettv) 16283 typval_T *argvars; 16284 typval_T *rettv; 16285 { 16286 char_u result_buf[256]; 16287 struct tm *curtime; 16288 time_t seconds; 16289 char_u *p; 16290 16291 rettv->v_type = VAR_STRING; 16292 16293 p = get_tv_string(&argvars[0]); 16294 if (argvars[1].v_type == VAR_UNKNOWN) 16295 seconds = time(NULL); 16296 else 16297 seconds = (time_t)get_tv_number(&argvars[1]); 16298 curtime = localtime(&seconds); 16299 /* MSVC returns NULL for an invalid value of seconds. */ 16300 if (curtime == NULL) 16301 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 16302 else 16303 { 16304 # ifdef FEAT_MBYTE 16305 vimconv_T conv; 16306 char_u *enc; 16307 16308 conv.vc_type = CONV_NONE; 16309 enc = enc_locale(); 16310 convert_setup(&conv, p_enc, enc); 16311 if (conv.vc_type != CONV_NONE) 16312 p = string_convert(&conv, p, NULL); 16313 # endif 16314 if (p != NULL) 16315 (void)strftime((char *)result_buf, sizeof(result_buf), 16316 (char *)p, curtime); 16317 else 16318 result_buf[0] = NUL; 16319 16320 # ifdef FEAT_MBYTE 16321 if (conv.vc_type != CONV_NONE) 16322 vim_free(p); 16323 convert_setup(&conv, enc, p_enc); 16324 if (conv.vc_type != CONV_NONE) 16325 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 16326 else 16327 # endif 16328 rettv->vval.v_string = vim_strsave(result_buf); 16329 16330 # ifdef FEAT_MBYTE 16331 /* Release conversion descriptors */ 16332 convert_setup(&conv, NULL, NULL); 16333 vim_free(enc); 16334 # endif 16335 } 16336 } 16337 #endif 16338 16339 /* 16340 * "stridx()" function 16341 */ 16342 static void 16343 f_stridx(argvars, rettv) 16344 typval_T *argvars; 16345 typval_T *rettv; 16346 { 16347 char_u buf[NUMBUFLEN]; 16348 char_u *needle; 16349 char_u *haystack; 16350 char_u *save_haystack; 16351 char_u *pos; 16352 int start_idx; 16353 16354 needle = get_tv_string_chk(&argvars[1]); 16355 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 16356 rettv->vval.v_number = -1; 16357 if (needle == NULL || haystack == NULL) 16358 return; /* type error; errmsg already given */ 16359 16360 if (argvars[2].v_type != VAR_UNKNOWN) 16361 { 16362 int error = FALSE; 16363 16364 start_idx = get_tv_number_chk(&argvars[2], &error); 16365 if (error || start_idx >= (int)STRLEN(haystack)) 16366 return; 16367 if (start_idx >= 0) 16368 haystack += start_idx; 16369 } 16370 16371 pos = (char_u *)strstr((char *)haystack, (char *)needle); 16372 if (pos != NULL) 16373 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 16374 } 16375 16376 /* 16377 * "string()" function 16378 */ 16379 static void 16380 f_string(argvars, rettv) 16381 typval_T *argvars; 16382 typval_T *rettv; 16383 { 16384 char_u *tofree; 16385 char_u numbuf[NUMBUFLEN]; 16386 16387 rettv->v_type = VAR_STRING; 16388 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 16389 /* Make a copy if we have a value but it's not in allocated memory. */ 16390 if (rettv->vval.v_string != NULL && tofree == NULL) 16391 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 16392 } 16393 16394 /* 16395 * "strlen()" function 16396 */ 16397 static void 16398 f_strlen(argvars, rettv) 16399 typval_T *argvars; 16400 typval_T *rettv; 16401 { 16402 rettv->vval.v_number = (varnumber_T)(STRLEN( 16403 get_tv_string(&argvars[0]))); 16404 } 16405 16406 /* 16407 * "strpart()" function 16408 */ 16409 static void 16410 f_strpart(argvars, rettv) 16411 typval_T *argvars; 16412 typval_T *rettv; 16413 { 16414 char_u *p; 16415 int n; 16416 int len; 16417 int slen; 16418 int error = FALSE; 16419 16420 p = get_tv_string(&argvars[0]); 16421 slen = (int)STRLEN(p); 16422 16423 n = get_tv_number_chk(&argvars[1], &error); 16424 if (error) 16425 len = 0; 16426 else if (argvars[2].v_type != VAR_UNKNOWN) 16427 len = get_tv_number(&argvars[2]); 16428 else 16429 len = slen - n; /* default len: all bytes that are available. */ 16430 16431 /* 16432 * Only return the overlap between the specified part and the actual 16433 * string. 16434 */ 16435 if (n < 0) 16436 { 16437 len += n; 16438 n = 0; 16439 } 16440 else if (n > slen) 16441 n = slen; 16442 if (len < 0) 16443 len = 0; 16444 else if (n + len > slen) 16445 len = slen - n; 16446 16447 rettv->v_type = VAR_STRING; 16448 rettv->vval.v_string = vim_strnsave(p + n, len); 16449 } 16450 16451 /* 16452 * "strridx()" function 16453 */ 16454 static void 16455 f_strridx(argvars, rettv) 16456 typval_T *argvars; 16457 typval_T *rettv; 16458 { 16459 char_u buf[NUMBUFLEN]; 16460 char_u *needle; 16461 char_u *haystack; 16462 char_u *rest; 16463 char_u *lastmatch = NULL; 16464 int haystack_len, end_idx; 16465 16466 needle = get_tv_string_chk(&argvars[1]); 16467 haystack = get_tv_string_buf_chk(&argvars[0], buf); 16468 16469 rettv->vval.v_number = -1; 16470 if (needle == NULL || haystack == NULL) 16471 return; /* type error; errmsg already given */ 16472 16473 haystack_len = (int)STRLEN(haystack); 16474 if (argvars[2].v_type != VAR_UNKNOWN) 16475 { 16476 /* Third argument: upper limit for index */ 16477 end_idx = get_tv_number_chk(&argvars[2], NULL); 16478 if (end_idx < 0) 16479 return; /* can never find a match */ 16480 } 16481 else 16482 end_idx = haystack_len; 16483 16484 if (*needle == NUL) 16485 { 16486 /* Empty string matches past the end. */ 16487 lastmatch = haystack + end_idx; 16488 } 16489 else 16490 { 16491 for (rest = haystack; *rest != '\0'; ++rest) 16492 { 16493 rest = (char_u *)strstr((char *)rest, (char *)needle); 16494 if (rest == NULL || rest > haystack + end_idx) 16495 break; 16496 lastmatch = rest; 16497 } 16498 } 16499 16500 if (lastmatch == NULL) 16501 rettv->vval.v_number = -1; 16502 else 16503 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 16504 } 16505 16506 /* 16507 * "strtrans()" function 16508 */ 16509 static void 16510 f_strtrans(argvars, rettv) 16511 typval_T *argvars; 16512 typval_T *rettv; 16513 { 16514 rettv->v_type = VAR_STRING; 16515 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 16516 } 16517 16518 /* 16519 * "submatch()" function 16520 */ 16521 static void 16522 f_submatch(argvars, rettv) 16523 typval_T *argvars; 16524 typval_T *rettv; 16525 { 16526 rettv->v_type = VAR_STRING; 16527 rettv->vval.v_string = 16528 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 16529 } 16530 16531 /* 16532 * "substitute()" function 16533 */ 16534 static void 16535 f_substitute(argvars, rettv) 16536 typval_T *argvars; 16537 typval_T *rettv; 16538 { 16539 char_u patbuf[NUMBUFLEN]; 16540 char_u subbuf[NUMBUFLEN]; 16541 char_u flagsbuf[NUMBUFLEN]; 16542 16543 char_u *str = get_tv_string_chk(&argvars[0]); 16544 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 16545 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 16546 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 16547 16548 rettv->v_type = VAR_STRING; 16549 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 16550 rettv->vval.v_string = NULL; 16551 else 16552 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 16553 } 16554 16555 /* 16556 * "synID(lnum, col, trans)" function 16557 */ 16558 static void 16559 f_synID(argvars, rettv) 16560 typval_T *argvars UNUSED; 16561 typval_T *rettv; 16562 { 16563 int id = 0; 16564 #ifdef FEAT_SYN_HL 16565 long lnum; 16566 long col; 16567 int trans; 16568 int transerr = FALSE; 16569 16570 lnum = get_tv_lnum(argvars); /* -1 on type error */ 16571 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 16572 trans = get_tv_number_chk(&argvars[2], &transerr); 16573 16574 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 16575 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 16576 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE); 16577 #endif 16578 16579 rettv->vval.v_number = id; 16580 } 16581 16582 /* 16583 * "synIDattr(id, what [, mode])" function 16584 */ 16585 static void 16586 f_synIDattr(argvars, rettv) 16587 typval_T *argvars UNUSED; 16588 typval_T *rettv; 16589 { 16590 char_u *p = NULL; 16591 #ifdef FEAT_SYN_HL 16592 int id; 16593 char_u *what; 16594 char_u *mode; 16595 char_u modebuf[NUMBUFLEN]; 16596 int modec; 16597 16598 id = get_tv_number(&argvars[0]); 16599 what = get_tv_string(&argvars[1]); 16600 if (argvars[2].v_type != VAR_UNKNOWN) 16601 { 16602 mode = get_tv_string_buf(&argvars[2], modebuf); 16603 modec = TOLOWER_ASC(mode[0]); 16604 if (modec != 't' && modec != 'c' 16605 #ifdef FEAT_GUI 16606 && modec != 'g' 16607 #endif 16608 ) 16609 modec = 0; /* replace invalid with current */ 16610 } 16611 else 16612 { 16613 #ifdef FEAT_GUI 16614 if (gui.in_use) 16615 modec = 'g'; 16616 else 16617 #endif 16618 if (t_colors > 1) 16619 modec = 'c'; 16620 else 16621 modec = 't'; 16622 } 16623 16624 16625 switch (TOLOWER_ASC(what[0])) 16626 { 16627 case 'b': 16628 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 16629 p = highlight_color(id, what, modec); 16630 else /* bold */ 16631 p = highlight_has_attr(id, HL_BOLD, modec); 16632 break; 16633 16634 case 'f': /* fg[#] or font */ 16635 p = highlight_color(id, what, modec); 16636 break; 16637 16638 case 'i': 16639 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 16640 p = highlight_has_attr(id, HL_INVERSE, modec); 16641 else /* italic */ 16642 p = highlight_has_attr(id, HL_ITALIC, modec); 16643 break; 16644 16645 case 'n': /* name */ 16646 p = get_highlight_name(NULL, id - 1); 16647 break; 16648 16649 case 'r': /* reverse */ 16650 p = highlight_has_attr(id, HL_INVERSE, modec); 16651 break; 16652 16653 case 's': 16654 if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */ 16655 p = highlight_color(id, what, modec); 16656 else /* standout */ 16657 p = highlight_has_attr(id, HL_STANDOUT, modec); 16658 break; 16659 16660 case 'u': 16661 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 16662 /* underline */ 16663 p = highlight_has_attr(id, HL_UNDERLINE, modec); 16664 else 16665 /* undercurl */ 16666 p = highlight_has_attr(id, HL_UNDERCURL, modec); 16667 break; 16668 } 16669 16670 if (p != NULL) 16671 p = vim_strsave(p); 16672 #endif 16673 rettv->v_type = VAR_STRING; 16674 rettv->vval.v_string = p; 16675 } 16676 16677 /* 16678 * "synIDtrans(id)" function 16679 */ 16680 static void 16681 f_synIDtrans(argvars, rettv) 16682 typval_T *argvars UNUSED; 16683 typval_T *rettv; 16684 { 16685 int id; 16686 16687 #ifdef FEAT_SYN_HL 16688 id = get_tv_number(&argvars[0]); 16689 16690 if (id > 0) 16691 id = syn_get_final_id(id); 16692 else 16693 #endif 16694 id = 0; 16695 16696 rettv->vval.v_number = id; 16697 } 16698 16699 /* 16700 * "synstack(lnum, col)" function 16701 */ 16702 static void 16703 f_synstack(argvars, rettv) 16704 typval_T *argvars UNUSED; 16705 typval_T *rettv; 16706 { 16707 #ifdef FEAT_SYN_HL 16708 long lnum; 16709 long col; 16710 int i; 16711 int id; 16712 #endif 16713 16714 rettv->v_type = VAR_LIST; 16715 rettv->vval.v_list = NULL; 16716 16717 #ifdef FEAT_SYN_HL 16718 lnum = get_tv_lnum(argvars); /* -1 on type error */ 16719 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 16720 16721 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 16722 && col >= 0 && (col == 0 || col < (long)STRLEN(ml_get(lnum))) 16723 && rettv_list_alloc(rettv) != FAIL) 16724 { 16725 (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE); 16726 for (i = 0; ; ++i) 16727 { 16728 id = syn_get_stack_item(i); 16729 if (id < 0) 16730 break; 16731 if (list_append_number(rettv->vval.v_list, id) == FAIL) 16732 break; 16733 } 16734 } 16735 #endif 16736 } 16737 16738 /* 16739 * "system()" function 16740 */ 16741 static void 16742 f_system(argvars, rettv) 16743 typval_T *argvars; 16744 typval_T *rettv; 16745 { 16746 char_u *res = NULL; 16747 char_u *p; 16748 char_u *infile = NULL; 16749 char_u buf[NUMBUFLEN]; 16750 int err = FALSE; 16751 FILE *fd; 16752 16753 if (check_restricted() || check_secure()) 16754 goto done; 16755 16756 if (argvars[1].v_type != VAR_UNKNOWN) 16757 { 16758 /* 16759 * Write the string to a temp file, to be used for input of the shell 16760 * command. 16761 */ 16762 if ((infile = vim_tempname('i')) == NULL) 16763 { 16764 EMSG(_(e_notmp)); 16765 goto done; 16766 } 16767 16768 fd = mch_fopen((char *)infile, WRITEBIN); 16769 if (fd == NULL) 16770 { 16771 EMSG2(_(e_notopen), infile); 16772 goto done; 16773 } 16774 p = get_tv_string_buf_chk(&argvars[1], buf); 16775 if (p == NULL) 16776 { 16777 fclose(fd); 16778 goto done; /* type error; errmsg already given */ 16779 } 16780 if (fwrite(p, STRLEN(p), 1, fd) != 1) 16781 err = TRUE; 16782 if (fclose(fd) != 0) 16783 err = TRUE; 16784 if (err) 16785 { 16786 EMSG(_("E677: Error writing temp file")); 16787 goto done; 16788 } 16789 } 16790 16791 res = get_cmd_output(get_tv_string(&argvars[0]), infile, 16792 SHELL_SILENT | SHELL_COOKED); 16793 16794 #ifdef USE_CR 16795 /* translate <CR> into <NL> */ 16796 if (res != NULL) 16797 { 16798 char_u *s; 16799 16800 for (s = res; *s; ++s) 16801 { 16802 if (*s == CAR) 16803 *s = NL; 16804 } 16805 } 16806 #else 16807 # ifdef USE_CRNL 16808 /* translate <CR><NL> into <NL> */ 16809 if (res != NULL) 16810 { 16811 char_u *s, *d; 16812 16813 d = res; 16814 for (s = res; *s; ++s) 16815 { 16816 if (s[0] == CAR && s[1] == NL) 16817 ++s; 16818 *d++ = *s; 16819 } 16820 *d = NUL; 16821 } 16822 # endif 16823 #endif 16824 16825 done: 16826 if (infile != NULL) 16827 { 16828 mch_remove(infile); 16829 vim_free(infile); 16830 } 16831 rettv->v_type = VAR_STRING; 16832 rettv->vval.v_string = res; 16833 } 16834 16835 /* 16836 * "tabpagebuflist()" function 16837 */ 16838 static void 16839 f_tabpagebuflist(argvars, rettv) 16840 typval_T *argvars UNUSED; 16841 typval_T *rettv UNUSED; 16842 { 16843 #ifdef FEAT_WINDOWS 16844 tabpage_T *tp; 16845 win_T *wp = NULL; 16846 16847 if (argvars[0].v_type == VAR_UNKNOWN) 16848 wp = firstwin; 16849 else 16850 { 16851 tp = find_tabpage((int)get_tv_number(&argvars[0])); 16852 if (tp != NULL) 16853 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 16854 } 16855 if (wp != NULL && rettv_list_alloc(rettv) != FAIL) 16856 { 16857 for (; wp != NULL; wp = wp->w_next) 16858 if (list_append_number(rettv->vval.v_list, 16859 wp->w_buffer->b_fnum) == FAIL) 16860 break; 16861 } 16862 #endif 16863 } 16864 16865 16866 /* 16867 * "tabpagenr()" function 16868 */ 16869 static void 16870 f_tabpagenr(argvars, rettv) 16871 typval_T *argvars UNUSED; 16872 typval_T *rettv; 16873 { 16874 int nr = 1; 16875 #ifdef FEAT_WINDOWS 16876 char_u *arg; 16877 16878 if (argvars[0].v_type != VAR_UNKNOWN) 16879 { 16880 arg = get_tv_string_chk(&argvars[0]); 16881 nr = 0; 16882 if (arg != NULL) 16883 { 16884 if (STRCMP(arg, "$") == 0) 16885 nr = tabpage_index(NULL) - 1; 16886 else 16887 EMSG2(_(e_invexpr2), arg); 16888 } 16889 } 16890 else 16891 nr = tabpage_index(curtab); 16892 #endif 16893 rettv->vval.v_number = nr; 16894 } 16895 16896 16897 #ifdef FEAT_WINDOWS 16898 static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 16899 16900 /* 16901 * Common code for tabpagewinnr() and winnr(). 16902 */ 16903 static int 16904 get_winnr(tp, argvar) 16905 tabpage_T *tp; 16906 typval_T *argvar; 16907 { 16908 win_T *twin; 16909 int nr = 1; 16910 win_T *wp; 16911 char_u *arg; 16912 16913 twin = (tp == curtab) ? curwin : tp->tp_curwin; 16914 if (argvar->v_type != VAR_UNKNOWN) 16915 { 16916 arg = get_tv_string_chk(argvar); 16917 if (arg == NULL) 16918 nr = 0; /* type error; errmsg already given */ 16919 else if (STRCMP(arg, "$") == 0) 16920 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 16921 else if (STRCMP(arg, "#") == 0) 16922 { 16923 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 16924 if (twin == NULL) 16925 nr = 0; 16926 } 16927 else 16928 { 16929 EMSG2(_(e_invexpr2), arg); 16930 nr = 0; 16931 } 16932 } 16933 16934 if (nr > 0) 16935 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 16936 wp != twin; wp = wp->w_next) 16937 { 16938 if (wp == NULL) 16939 { 16940 /* didn't find it in this tabpage */ 16941 nr = 0; 16942 break; 16943 } 16944 ++nr; 16945 } 16946 return nr; 16947 } 16948 #endif 16949 16950 /* 16951 * "tabpagewinnr()" function 16952 */ 16953 static void 16954 f_tabpagewinnr(argvars, rettv) 16955 typval_T *argvars UNUSED; 16956 typval_T *rettv; 16957 { 16958 int nr = 1; 16959 #ifdef FEAT_WINDOWS 16960 tabpage_T *tp; 16961 16962 tp = find_tabpage((int)get_tv_number(&argvars[0])); 16963 if (tp == NULL) 16964 nr = 0; 16965 else 16966 nr = get_winnr(tp, &argvars[1]); 16967 #endif 16968 rettv->vval.v_number = nr; 16969 } 16970 16971 16972 /* 16973 * "tagfiles()" function 16974 */ 16975 static void 16976 f_tagfiles(argvars, rettv) 16977 typval_T *argvars UNUSED; 16978 typval_T *rettv; 16979 { 16980 char_u fname[MAXPATHL + 1]; 16981 tagname_T tn; 16982 int first; 16983 16984 if (rettv_list_alloc(rettv) == FAIL) 16985 return; 16986 16987 for (first = TRUE; ; first = FALSE) 16988 if (get_tagfname(&tn, first, fname) == FAIL 16989 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 16990 break; 16991 tagname_free(&tn); 16992 } 16993 16994 /* 16995 * "taglist()" function 16996 */ 16997 static void 16998 f_taglist(argvars, rettv) 16999 typval_T *argvars; 17000 typval_T *rettv; 17001 { 17002 char_u *tag_pattern; 17003 17004 tag_pattern = get_tv_string(&argvars[0]); 17005 17006 rettv->vval.v_number = FALSE; 17007 if (*tag_pattern == NUL) 17008 return; 17009 17010 if (rettv_list_alloc(rettv) == OK) 17011 (void)get_tags(rettv->vval.v_list, tag_pattern); 17012 } 17013 17014 /* 17015 * "tempname()" function 17016 */ 17017 static void 17018 f_tempname(argvars, rettv) 17019 typval_T *argvars UNUSED; 17020 typval_T *rettv; 17021 { 17022 static int x = 'A'; 17023 17024 rettv->v_type = VAR_STRING; 17025 rettv->vval.v_string = vim_tempname(x); 17026 17027 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 17028 * names. Skip 'I' and 'O', they are used for shell redirection. */ 17029 do 17030 { 17031 if (x == 'Z') 17032 x = '0'; 17033 else if (x == '9') 17034 x = 'A'; 17035 else 17036 { 17037 #ifdef EBCDIC 17038 if (x == 'I') 17039 x = 'J'; 17040 else if (x == 'R') 17041 x = 'S'; 17042 else 17043 #endif 17044 ++x; 17045 } 17046 } while (x == 'I' || x == 'O'); 17047 } 17048 17049 /* 17050 * "test(list)" function: Just checking the walls... 17051 */ 17052 static void 17053 f_test(argvars, rettv) 17054 typval_T *argvars UNUSED; 17055 typval_T *rettv UNUSED; 17056 { 17057 /* Used for unit testing. Change the code below to your liking. */ 17058 #if 0 17059 listitem_T *li; 17060 list_T *l; 17061 char_u *bad, *good; 17062 17063 if (argvars[0].v_type != VAR_LIST) 17064 return; 17065 l = argvars[0].vval.v_list; 17066 if (l == NULL) 17067 return; 17068 li = l->lv_first; 17069 if (li == NULL) 17070 return; 17071 bad = get_tv_string(&li->li_tv); 17072 li = li->li_next; 17073 if (li == NULL) 17074 return; 17075 good = get_tv_string(&li->li_tv); 17076 rettv->vval.v_number = test_edit_score(bad, good); 17077 #endif 17078 } 17079 17080 /* 17081 * "tolower(string)" function 17082 */ 17083 static void 17084 f_tolower(argvars, rettv) 17085 typval_T *argvars; 17086 typval_T *rettv; 17087 { 17088 char_u *p; 17089 17090 p = vim_strsave(get_tv_string(&argvars[0])); 17091 rettv->v_type = VAR_STRING; 17092 rettv->vval.v_string = p; 17093 17094 if (p != NULL) 17095 while (*p != NUL) 17096 { 17097 #ifdef FEAT_MBYTE 17098 int l; 17099 17100 if (enc_utf8) 17101 { 17102 int c, lc; 17103 17104 c = utf_ptr2char(p); 17105 lc = utf_tolower(c); 17106 l = utf_ptr2len(p); 17107 /* TODO: reallocate string when byte count changes. */ 17108 if (utf_char2len(lc) == l) 17109 utf_char2bytes(lc, p); 17110 p += l; 17111 } 17112 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 17113 p += l; /* skip multi-byte character */ 17114 else 17115 #endif 17116 { 17117 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 17118 ++p; 17119 } 17120 } 17121 } 17122 17123 /* 17124 * "toupper(string)" function 17125 */ 17126 static void 17127 f_toupper(argvars, rettv) 17128 typval_T *argvars; 17129 typval_T *rettv; 17130 { 17131 rettv->v_type = VAR_STRING; 17132 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 17133 } 17134 17135 /* 17136 * "tr(string, fromstr, tostr)" function 17137 */ 17138 static void 17139 f_tr(argvars, rettv) 17140 typval_T *argvars; 17141 typval_T *rettv; 17142 { 17143 char_u *instr; 17144 char_u *fromstr; 17145 char_u *tostr; 17146 char_u *p; 17147 #ifdef FEAT_MBYTE 17148 int inlen; 17149 int fromlen; 17150 int tolen; 17151 int idx; 17152 char_u *cpstr; 17153 int cplen; 17154 int first = TRUE; 17155 #endif 17156 char_u buf[NUMBUFLEN]; 17157 char_u buf2[NUMBUFLEN]; 17158 garray_T ga; 17159 17160 instr = get_tv_string(&argvars[0]); 17161 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 17162 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 17163 17164 /* Default return value: empty string. */ 17165 rettv->v_type = VAR_STRING; 17166 rettv->vval.v_string = NULL; 17167 if (fromstr == NULL || tostr == NULL) 17168 return; /* type error; errmsg already given */ 17169 ga_init2(&ga, (int)sizeof(char), 80); 17170 17171 #ifdef FEAT_MBYTE 17172 if (!has_mbyte) 17173 #endif 17174 /* not multi-byte: fromstr and tostr must be the same length */ 17175 if (STRLEN(fromstr) != STRLEN(tostr)) 17176 { 17177 #ifdef FEAT_MBYTE 17178 error: 17179 #endif 17180 EMSG2(_(e_invarg2), fromstr); 17181 ga_clear(&ga); 17182 return; 17183 } 17184 17185 /* fromstr and tostr have to contain the same number of chars */ 17186 while (*instr != NUL) 17187 { 17188 #ifdef FEAT_MBYTE 17189 if (has_mbyte) 17190 { 17191 inlen = (*mb_ptr2len)(instr); 17192 cpstr = instr; 17193 cplen = inlen; 17194 idx = 0; 17195 for (p = fromstr; *p != NUL; p += fromlen) 17196 { 17197 fromlen = (*mb_ptr2len)(p); 17198 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 17199 { 17200 for (p = tostr; *p != NUL; p += tolen) 17201 { 17202 tolen = (*mb_ptr2len)(p); 17203 if (idx-- == 0) 17204 { 17205 cplen = tolen; 17206 cpstr = p; 17207 break; 17208 } 17209 } 17210 if (*p == NUL) /* tostr is shorter than fromstr */ 17211 goto error; 17212 break; 17213 } 17214 ++idx; 17215 } 17216 17217 if (first && cpstr == instr) 17218 { 17219 /* Check that fromstr and tostr have the same number of 17220 * (multi-byte) characters. Done only once when a character 17221 * of instr doesn't appear in fromstr. */ 17222 first = FALSE; 17223 for (p = tostr; *p != NUL; p += tolen) 17224 { 17225 tolen = (*mb_ptr2len)(p); 17226 --idx; 17227 } 17228 if (idx != 0) 17229 goto error; 17230 } 17231 17232 ga_grow(&ga, cplen); 17233 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 17234 ga.ga_len += cplen; 17235 17236 instr += inlen; 17237 } 17238 else 17239 #endif 17240 { 17241 /* When not using multi-byte chars we can do it faster. */ 17242 p = vim_strchr(fromstr, *instr); 17243 if (p != NULL) 17244 ga_append(&ga, tostr[p - fromstr]); 17245 else 17246 ga_append(&ga, *instr); 17247 ++instr; 17248 } 17249 } 17250 17251 /* add a terminating NUL */ 17252 ga_grow(&ga, 1); 17253 ga_append(&ga, NUL); 17254 17255 rettv->vval.v_string = ga.ga_data; 17256 } 17257 17258 #ifdef FEAT_FLOAT 17259 /* 17260 * "trunc({float})" function 17261 */ 17262 static void 17263 f_trunc(argvars, rettv) 17264 typval_T *argvars; 17265 typval_T *rettv; 17266 { 17267 float_T f; 17268 17269 rettv->v_type = VAR_FLOAT; 17270 if (get_float_arg(argvars, &f) == OK) 17271 /* trunc() is not in C90, use floor() or ceil() instead. */ 17272 rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); 17273 else 17274 rettv->vval.v_float = 0.0; 17275 } 17276 #endif 17277 17278 /* 17279 * "type(expr)" function 17280 */ 17281 static void 17282 f_type(argvars, rettv) 17283 typval_T *argvars; 17284 typval_T *rettv; 17285 { 17286 int n; 17287 17288 switch (argvars[0].v_type) 17289 { 17290 case VAR_NUMBER: n = 0; break; 17291 case VAR_STRING: n = 1; break; 17292 case VAR_FUNC: n = 2; break; 17293 case VAR_LIST: n = 3; break; 17294 case VAR_DICT: n = 4; break; 17295 #ifdef FEAT_FLOAT 17296 case VAR_FLOAT: n = 5; break; 17297 #endif 17298 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 17299 } 17300 rettv->vval.v_number = n; 17301 } 17302 17303 /* 17304 * "values(dict)" function 17305 */ 17306 static void 17307 f_values(argvars, rettv) 17308 typval_T *argvars; 17309 typval_T *rettv; 17310 { 17311 dict_list(argvars, rettv, 1); 17312 } 17313 17314 /* 17315 * "virtcol(string)" function 17316 */ 17317 static void 17318 f_virtcol(argvars, rettv) 17319 typval_T *argvars; 17320 typval_T *rettv; 17321 { 17322 colnr_T vcol = 0; 17323 pos_T *fp; 17324 int fnum = curbuf->b_fnum; 17325 17326 fp = var2fpos(&argvars[0], FALSE, &fnum); 17327 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 17328 && fnum == curbuf->b_fnum) 17329 { 17330 getvvcol(curwin, fp, NULL, NULL, &vcol); 17331 ++vcol; 17332 } 17333 17334 rettv->vval.v_number = vcol; 17335 } 17336 17337 /* 17338 * "visualmode()" function 17339 */ 17340 static void 17341 f_visualmode(argvars, rettv) 17342 typval_T *argvars UNUSED; 17343 typval_T *rettv UNUSED; 17344 { 17345 #ifdef FEAT_VISUAL 17346 char_u str[2]; 17347 17348 rettv->v_type = VAR_STRING; 17349 str[0] = curbuf->b_visual_mode_eval; 17350 str[1] = NUL; 17351 rettv->vval.v_string = vim_strsave(str); 17352 17353 /* A non-zero number or non-empty string argument: reset mode. */ 17354 if (non_zero_arg(&argvars[0])) 17355 curbuf->b_visual_mode_eval = NUL; 17356 #endif 17357 } 17358 17359 /* 17360 * "winbufnr(nr)" function 17361 */ 17362 static void 17363 f_winbufnr(argvars, rettv) 17364 typval_T *argvars; 17365 typval_T *rettv; 17366 { 17367 win_T *wp; 17368 17369 wp = find_win_by_nr(&argvars[0], NULL); 17370 if (wp == NULL) 17371 rettv->vval.v_number = -1; 17372 else 17373 rettv->vval.v_number = wp->w_buffer->b_fnum; 17374 } 17375 17376 /* 17377 * "wincol()" function 17378 */ 17379 static void 17380 f_wincol(argvars, rettv) 17381 typval_T *argvars UNUSED; 17382 typval_T *rettv; 17383 { 17384 validate_cursor(); 17385 rettv->vval.v_number = curwin->w_wcol + 1; 17386 } 17387 17388 /* 17389 * "winheight(nr)" function 17390 */ 17391 static void 17392 f_winheight(argvars, rettv) 17393 typval_T *argvars; 17394 typval_T *rettv; 17395 { 17396 win_T *wp; 17397 17398 wp = find_win_by_nr(&argvars[0], NULL); 17399 if (wp == NULL) 17400 rettv->vval.v_number = -1; 17401 else 17402 rettv->vval.v_number = wp->w_height; 17403 } 17404 17405 /* 17406 * "winline()" function 17407 */ 17408 static void 17409 f_winline(argvars, rettv) 17410 typval_T *argvars UNUSED; 17411 typval_T *rettv; 17412 { 17413 validate_cursor(); 17414 rettv->vval.v_number = curwin->w_wrow + 1; 17415 } 17416 17417 /* 17418 * "winnr()" function 17419 */ 17420 static void 17421 f_winnr(argvars, rettv) 17422 typval_T *argvars UNUSED; 17423 typval_T *rettv; 17424 { 17425 int nr = 1; 17426 17427 #ifdef FEAT_WINDOWS 17428 nr = get_winnr(curtab, &argvars[0]); 17429 #endif 17430 rettv->vval.v_number = nr; 17431 } 17432 17433 /* 17434 * "winrestcmd()" function 17435 */ 17436 static void 17437 f_winrestcmd(argvars, rettv) 17438 typval_T *argvars UNUSED; 17439 typval_T *rettv; 17440 { 17441 #ifdef FEAT_WINDOWS 17442 win_T *wp; 17443 int winnr = 1; 17444 garray_T ga; 17445 char_u buf[50]; 17446 17447 ga_init2(&ga, (int)sizeof(char), 70); 17448 for (wp = firstwin; wp != NULL; wp = wp->w_next) 17449 { 17450 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 17451 ga_concat(&ga, buf); 17452 # ifdef FEAT_VERTSPLIT 17453 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 17454 ga_concat(&ga, buf); 17455 # endif 17456 ++winnr; 17457 } 17458 ga_append(&ga, NUL); 17459 17460 rettv->vval.v_string = ga.ga_data; 17461 #else 17462 rettv->vval.v_string = NULL; 17463 #endif 17464 rettv->v_type = VAR_STRING; 17465 } 17466 17467 /* 17468 * "winrestview()" function 17469 */ 17470 static void 17471 f_winrestview(argvars, rettv) 17472 typval_T *argvars; 17473 typval_T *rettv UNUSED; 17474 { 17475 dict_T *dict; 17476 17477 if (argvars[0].v_type != VAR_DICT 17478 || (dict = argvars[0].vval.v_dict) == NULL) 17479 EMSG(_(e_invarg)); 17480 else 17481 { 17482 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 17483 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 17484 #ifdef FEAT_VIRTUALEDIT 17485 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 17486 #endif 17487 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 17488 curwin->w_set_curswant = FALSE; 17489 17490 set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); 17491 #ifdef FEAT_DIFF 17492 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 17493 #endif 17494 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 17495 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 17496 17497 check_cursor(); 17498 changed_cline_bef_curs(); 17499 invalidate_botline(); 17500 redraw_later(VALID); 17501 17502 if (curwin->w_topline == 0) 17503 curwin->w_topline = 1; 17504 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 17505 curwin->w_topline = curbuf->b_ml.ml_line_count; 17506 #ifdef FEAT_DIFF 17507 check_topfill(curwin, TRUE); 17508 #endif 17509 } 17510 } 17511 17512 /* 17513 * "winsaveview()" function 17514 */ 17515 static void 17516 f_winsaveview(argvars, rettv) 17517 typval_T *argvars UNUSED; 17518 typval_T *rettv; 17519 { 17520 dict_T *dict; 17521 17522 dict = dict_alloc(); 17523 if (dict == NULL) 17524 return; 17525 rettv->v_type = VAR_DICT; 17526 rettv->vval.v_dict = dict; 17527 ++dict->dv_refcount; 17528 17529 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 17530 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 17531 #ifdef FEAT_VIRTUALEDIT 17532 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 17533 #endif 17534 update_curswant(); 17535 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 17536 17537 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 17538 #ifdef FEAT_DIFF 17539 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 17540 #endif 17541 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 17542 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 17543 } 17544 17545 /* 17546 * "winwidth(nr)" function 17547 */ 17548 static void 17549 f_winwidth(argvars, rettv) 17550 typval_T *argvars; 17551 typval_T *rettv; 17552 { 17553 win_T *wp; 17554 17555 wp = find_win_by_nr(&argvars[0], NULL); 17556 if (wp == NULL) 17557 rettv->vval.v_number = -1; 17558 else 17559 #ifdef FEAT_VERTSPLIT 17560 rettv->vval.v_number = wp->w_width; 17561 #else 17562 rettv->vval.v_number = Columns; 17563 #endif 17564 } 17565 17566 /* 17567 * "writefile()" function 17568 */ 17569 static void 17570 f_writefile(argvars, rettv) 17571 typval_T *argvars; 17572 typval_T *rettv; 17573 { 17574 int binary = FALSE; 17575 char_u *fname; 17576 FILE *fd; 17577 listitem_T *li; 17578 char_u *s; 17579 int ret = 0; 17580 int c; 17581 17582 if (check_restricted() || check_secure()) 17583 return; 17584 17585 if (argvars[0].v_type != VAR_LIST) 17586 { 17587 EMSG2(_(e_listarg), "writefile()"); 17588 return; 17589 } 17590 if (argvars[0].vval.v_list == NULL) 17591 return; 17592 17593 if (argvars[2].v_type != VAR_UNKNOWN 17594 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 17595 binary = TRUE; 17596 17597 /* Always open the file in binary mode, library functions have a mind of 17598 * their own about CR-LF conversion. */ 17599 fname = get_tv_string(&argvars[1]); 17600 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 17601 { 17602 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 17603 ret = -1; 17604 } 17605 else 17606 { 17607 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 17608 li = li->li_next) 17609 { 17610 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 17611 { 17612 if (*s == '\n') 17613 c = putc(NUL, fd); 17614 else 17615 c = putc(*s, fd); 17616 if (c == EOF) 17617 { 17618 ret = -1; 17619 break; 17620 } 17621 } 17622 if (!binary || li->li_next != NULL) 17623 if (putc('\n', fd) == EOF) 17624 { 17625 ret = -1; 17626 break; 17627 } 17628 if (ret < 0) 17629 { 17630 EMSG(_(e_write)); 17631 break; 17632 } 17633 } 17634 fclose(fd); 17635 } 17636 17637 rettv->vval.v_number = ret; 17638 } 17639 17640 /* 17641 * Translate a String variable into a position. 17642 * Returns NULL when there is an error. 17643 */ 17644 static pos_T * 17645 var2fpos(varp, dollar_lnum, fnum) 17646 typval_T *varp; 17647 int dollar_lnum; /* TRUE when $ is last line */ 17648 int *fnum; /* set to fnum for '0, 'A, etc. */ 17649 { 17650 char_u *name; 17651 static pos_T pos; 17652 pos_T *pp; 17653 17654 /* Argument can be [lnum, col, coladd]. */ 17655 if (varp->v_type == VAR_LIST) 17656 { 17657 list_T *l; 17658 int len; 17659 int error = FALSE; 17660 listitem_T *li; 17661 17662 l = varp->vval.v_list; 17663 if (l == NULL) 17664 return NULL; 17665 17666 /* Get the line number */ 17667 pos.lnum = list_find_nr(l, 0L, &error); 17668 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 17669 return NULL; /* invalid line number */ 17670 17671 /* Get the column number */ 17672 pos.col = list_find_nr(l, 1L, &error); 17673 if (error) 17674 return NULL; 17675 len = (long)STRLEN(ml_get(pos.lnum)); 17676 17677 /* We accept "$" for the column number: last column. */ 17678 li = list_find(l, 1L); 17679 if (li != NULL && li->li_tv.v_type == VAR_STRING 17680 && li->li_tv.vval.v_string != NULL 17681 && STRCMP(li->li_tv.vval.v_string, "$") == 0) 17682 pos.col = len + 1; 17683 17684 /* Accept a position up to the NUL after the line. */ 17685 if (pos.col == 0 || (int)pos.col > len + 1) 17686 return NULL; /* invalid column number */ 17687 --pos.col; 17688 17689 #ifdef FEAT_VIRTUALEDIT 17690 /* Get the virtual offset. Defaults to zero. */ 17691 pos.coladd = list_find_nr(l, 2L, &error); 17692 if (error) 17693 pos.coladd = 0; 17694 #endif 17695 17696 return &pos; 17697 } 17698 17699 name = get_tv_string_chk(varp); 17700 if (name == NULL) 17701 return NULL; 17702 if (name[0] == '.') /* cursor */ 17703 return &curwin->w_cursor; 17704 #ifdef FEAT_VISUAL 17705 if (name[0] == 'v' && name[1] == NUL) /* Visual start */ 17706 { 17707 if (VIsual_active) 17708 return &VIsual; 17709 return &curwin->w_cursor; 17710 } 17711 #endif 17712 if (name[0] == '\'') /* mark */ 17713 { 17714 pp = getmark_fnum(name[1], FALSE, fnum); 17715 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 17716 return NULL; 17717 return pp; 17718 } 17719 17720 #ifdef FEAT_VIRTUALEDIT 17721 pos.coladd = 0; 17722 #endif 17723 17724 if (name[0] == 'w' && dollar_lnum) 17725 { 17726 pos.col = 0; 17727 if (name[1] == '0') /* "w0": first visible line */ 17728 { 17729 update_topline(); 17730 pos.lnum = curwin->w_topline; 17731 return &pos; 17732 } 17733 else if (name[1] == '$') /* "w$": last visible line */ 17734 { 17735 validate_botline(); 17736 pos.lnum = curwin->w_botline - 1; 17737 return &pos; 17738 } 17739 } 17740 else if (name[0] == '$') /* last column or line */ 17741 { 17742 if (dollar_lnum) 17743 { 17744 pos.lnum = curbuf->b_ml.ml_line_count; 17745 pos.col = 0; 17746 } 17747 else 17748 { 17749 pos.lnum = curwin->w_cursor.lnum; 17750 pos.col = (colnr_T)STRLEN(ml_get_curline()); 17751 } 17752 return &pos; 17753 } 17754 return NULL; 17755 } 17756 17757 /* 17758 * Convert list in "arg" into a position and optional file number. 17759 * When "fnump" is NULL there is no file number, only 3 items. 17760 * Note that the column is passed on as-is, the caller may want to decrement 17761 * it to use 1 for the first column. 17762 * Return FAIL when conversion is not possible, doesn't check the position for 17763 * validity. 17764 */ 17765 static int 17766 list2fpos(arg, posp, fnump) 17767 typval_T *arg; 17768 pos_T *posp; 17769 int *fnump; 17770 { 17771 list_T *l = arg->vval.v_list; 17772 long i = 0; 17773 long n; 17774 17775 /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there 17776 * when "fnump" isn't NULL and "coladd" is optional. */ 17777 if (arg->v_type != VAR_LIST 17778 || l == NULL 17779 || l->lv_len < (fnump == NULL ? 2 : 3) 17780 || l->lv_len > (fnump == NULL ? 3 : 4)) 17781 return FAIL; 17782 17783 if (fnump != NULL) 17784 { 17785 n = list_find_nr(l, i++, NULL); /* fnum */ 17786 if (n < 0) 17787 return FAIL; 17788 if (n == 0) 17789 n = curbuf->b_fnum; /* current buffer */ 17790 *fnump = n; 17791 } 17792 17793 n = list_find_nr(l, i++, NULL); /* lnum */ 17794 if (n < 0) 17795 return FAIL; 17796 posp->lnum = n; 17797 17798 n = list_find_nr(l, i++, NULL); /* col */ 17799 if (n < 0) 17800 return FAIL; 17801 posp->col = n; 17802 17803 #ifdef FEAT_VIRTUALEDIT 17804 n = list_find_nr(l, i, NULL); 17805 if (n < 0) 17806 posp->coladd = 0; 17807 else 17808 posp->coladd = n; 17809 #endif 17810 17811 return OK; 17812 } 17813 17814 /* 17815 * Get the length of an environment variable name. 17816 * Advance "arg" to the first character after the name. 17817 * Return 0 for error. 17818 */ 17819 static int 17820 get_env_len(arg) 17821 char_u **arg; 17822 { 17823 char_u *p; 17824 int len; 17825 17826 for (p = *arg; vim_isIDc(*p); ++p) 17827 ; 17828 if (p == *arg) /* no name found */ 17829 return 0; 17830 17831 len = (int)(p - *arg); 17832 *arg = p; 17833 return len; 17834 } 17835 17836 /* 17837 * Get the length of the name of a function or internal variable. 17838 * "arg" is advanced to the first non-white character after the name. 17839 * Return 0 if something is wrong. 17840 */ 17841 static int 17842 get_id_len(arg) 17843 char_u **arg; 17844 { 17845 char_u *p; 17846 int len; 17847 17848 /* Find the end of the name. */ 17849 for (p = *arg; eval_isnamec(*p); ++p) 17850 ; 17851 if (p == *arg) /* no name found */ 17852 return 0; 17853 17854 len = (int)(p - *arg); 17855 *arg = skipwhite(p); 17856 17857 return len; 17858 } 17859 17860 /* 17861 * Get the length of the name of a variable or function. 17862 * Only the name is recognized, does not handle ".key" or "[idx]". 17863 * "arg" is advanced to the first non-white character after the name. 17864 * Return -1 if curly braces expansion failed. 17865 * Return 0 if something else is wrong. 17866 * If the name contains 'magic' {}'s, expand them and return the 17867 * expanded name in an allocated string via 'alias' - caller must free. 17868 */ 17869 static int 17870 get_name_len(arg, alias, evaluate, verbose) 17871 char_u **arg; 17872 char_u **alias; 17873 int evaluate; 17874 int verbose; 17875 { 17876 int len; 17877 char_u *p; 17878 char_u *expr_start; 17879 char_u *expr_end; 17880 17881 *alias = NULL; /* default to no alias */ 17882 17883 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 17884 && (*arg)[2] == (int)KE_SNR) 17885 { 17886 /* hard coded <SNR>, already translated */ 17887 *arg += 3; 17888 return get_id_len(arg) + 3; 17889 } 17890 len = eval_fname_script(*arg); 17891 if (len > 0) 17892 { 17893 /* literal "<SID>", "s:" or "<SNR>" */ 17894 *arg += len; 17895 } 17896 17897 /* 17898 * Find the end of the name; check for {} construction. 17899 */ 17900 p = find_name_end(*arg, &expr_start, &expr_end, 17901 len > 0 ? 0 : FNE_CHECK_START); 17902 if (expr_start != NULL) 17903 { 17904 char_u *temp_string; 17905 17906 if (!evaluate) 17907 { 17908 len += (int)(p - *arg); 17909 *arg = skipwhite(p); 17910 return len; 17911 } 17912 17913 /* 17914 * Include any <SID> etc in the expanded string: 17915 * Thus the -len here. 17916 */ 17917 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 17918 if (temp_string == NULL) 17919 return -1; 17920 *alias = temp_string; 17921 *arg = skipwhite(p); 17922 return (int)STRLEN(temp_string); 17923 } 17924 17925 len += get_id_len(arg); 17926 if (len == 0 && verbose) 17927 EMSG2(_(e_invexpr2), *arg); 17928 17929 return len; 17930 } 17931 17932 /* 17933 * Find the end of a variable or function name, taking care of magic braces. 17934 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 17935 * start and end of the first magic braces item. 17936 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 17937 * Return a pointer to just after the name. Equal to "arg" if there is no 17938 * valid name. 17939 */ 17940 static char_u * 17941 find_name_end(arg, expr_start, expr_end, flags) 17942 char_u *arg; 17943 char_u **expr_start; 17944 char_u **expr_end; 17945 int flags; 17946 { 17947 int mb_nest = 0; 17948 int br_nest = 0; 17949 char_u *p; 17950 17951 if (expr_start != NULL) 17952 { 17953 *expr_start = NULL; 17954 *expr_end = NULL; 17955 } 17956 17957 /* Quick check for valid starting character. */ 17958 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 17959 return arg; 17960 17961 for (p = arg; *p != NUL 17962 && (eval_isnamec(*p) 17963 || *p == '{' 17964 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 17965 || mb_nest != 0 17966 || br_nest != 0); mb_ptr_adv(p)) 17967 { 17968 if (*p == '\'') 17969 { 17970 /* skip over 'string' to avoid counting [ and ] inside it. */ 17971 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 17972 ; 17973 if (*p == NUL) 17974 break; 17975 } 17976 else if (*p == '"') 17977 { 17978 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 17979 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 17980 if (*p == '\\' && p[1] != NUL) 17981 ++p; 17982 if (*p == NUL) 17983 break; 17984 } 17985 17986 if (mb_nest == 0) 17987 { 17988 if (*p == '[') 17989 ++br_nest; 17990 else if (*p == ']') 17991 --br_nest; 17992 } 17993 17994 if (br_nest == 0) 17995 { 17996 if (*p == '{') 17997 { 17998 mb_nest++; 17999 if (expr_start != NULL && *expr_start == NULL) 18000 *expr_start = p; 18001 } 18002 else if (*p == '}') 18003 { 18004 mb_nest--; 18005 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 18006 *expr_end = p; 18007 } 18008 } 18009 } 18010 18011 return p; 18012 } 18013 18014 /* 18015 * Expands out the 'magic' {}'s in a variable/function name. 18016 * Note that this can call itself recursively, to deal with 18017 * constructs like foo{bar}{baz}{bam} 18018 * The four pointer arguments point to "foo{expre}ss{ion}bar" 18019 * "in_start" ^ 18020 * "expr_start" ^ 18021 * "expr_end" ^ 18022 * "in_end" ^ 18023 * 18024 * Returns a new allocated string, which the caller must free. 18025 * Returns NULL for failure. 18026 */ 18027 static char_u * 18028 make_expanded_name(in_start, expr_start, expr_end, in_end) 18029 char_u *in_start; 18030 char_u *expr_start; 18031 char_u *expr_end; 18032 char_u *in_end; 18033 { 18034 char_u c1; 18035 char_u *retval = NULL; 18036 char_u *temp_result; 18037 char_u *nextcmd = NULL; 18038 18039 if (expr_end == NULL || in_end == NULL) 18040 return NULL; 18041 *expr_start = NUL; 18042 *expr_end = NUL; 18043 c1 = *in_end; 18044 *in_end = NUL; 18045 18046 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 18047 if (temp_result != NULL && nextcmd == NULL) 18048 { 18049 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 18050 + (in_end - expr_end) + 1)); 18051 if (retval != NULL) 18052 { 18053 STRCPY(retval, in_start); 18054 STRCAT(retval, temp_result); 18055 STRCAT(retval, expr_end + 1); 18056 } 18057 } 18058 vim_free(temp_result); 18059 18060 *in_end = c1; /* put char back for error messages */ 18061 *expr_start = '{'; 18062 *expr_end = '}'; 18063 18064 if (retval != NULL) 18065 { 18066 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 18067 if (expr_start != NULL) 18068 { 18069 /* Further expansion! */ 18070 temp_result = make_expanded_name(retval, expr_start, 18071 expr_end, temp_result); 18072 vim_free(retval); 18073 retval = temp_result; 18074 } 18075 } 18076 18077 return retval; 18078 } 18079 18080 /* 18081 * Return TRUE if character "c" can be used in a variable or function name. 18082 * Does not include '{' or '}' for magic braces. 18083 */ 18084 static int 18085 eval_isnamec(c) 18086 int c; 18087 { 18088 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 18089 } 18090 18091 /* 18092 * Return TRUE if character "c" can be used as the first character in a 18093 * variable or function name (excluding '{' and '}'). 18094 */ 18095 static int 18096 eval_isnamec1(c) 18097 int c; 18098 { 18099 return (ASCII_ISALPHA(c) || c == '_'); 18100 } 18101 18102 /* 18103 * Set number v: variable to "val". 18104 */ 18105 void 18106 set_vim_var_nr(idx, val) 18107 int idx; 18108 long val; 18109 { 18110 vimvars[idx].vv_nr = val; 18111 } 18112 18113 /* 18114 * Get number v: variable value. 18115 */ 18116 long 18117 get_vim_var_nr(idx) 18118 int idx; 18119 { 18120 return vimvars[idx].vv_nr; 18121 } 18122 18123 /* 18124 * Get string v: variable value. Uses a static buffer, can only be used once. 18125 */ 18126 char_u * 18127 get_vim_var_str(idx) 18128 int idx; 18129 { 18130 return get_tv_string(&vimvars[idx].vv_tv); 18131 } 18132 18133 /* 18134 * Get List v: variable value. Caller must take care of reference count when 18135 * needed. 18136 */ 18137 list_T * 18138 get_vim_var_list(idx) 18139 int idx; 18140 { 18141 return vimvars[idx].vv_list; 18142 } 18143 18144 /* 18145 * Set v:char to character "c". 18146 */ 18147 void 18148 set_vim_var_char(c) 18149 int c; 18150 { 18151 #ifdef FEAT_MBYTE 18152 char_u buf[MB_MAXBYTES]; 18153 #else 18154 char_u buf[2]; 18155 #endif 18156 18157 #ifdef FEAT_MBYTE 18158 if (has_mbyte) 18159 buf[(*mb_char2bytes)(c, buf)] = NUL; 18160 else 18161 #endif 18162 { 18163 buf[0] = c; 18164 buf[1] = NUL; 18165 } 18166 set_vim_var_string(VV_CHAR, buf, -1); 18167 } 18168 18169 /* 18170 * Set v:count to "count" and v:count1 to "count1". 18171 * When "set_prevcount" is TRUE first set v:prevcount from v:count. 18172 */ 18173 void 18174 set_vcount(count, count1, set_prevcount) 18175 long count; 18176 long count1; 18177 int set_prevcount; 18178 { 18179 if (set_prevcount) 18180 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 18181 vimvars[VV_COUNT].vv_nr = count; 18182 vimvars[VV_COUNT1].vv_nr = count1; 18183 } 18184 18185 /* 18186 * Set string v: variable to a copy of "val". 18187 */ 18188 void 18189 set_vim_var_string(idx, val, len) 18190 int idx; 18191 char_u *val; 18192 int len; /* length of "val" to use or -1 (whole string) */ 18193 { 18194 /* Need to do this (at least) once, since we can't initialize a union. 18195 * Will always be invoked when "v:progname" is set. */ 18196 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 18197 18198 vim_free(vimvars[idx].vv_str); 18199 if (val == NULL) 18200 vimvars[idx].vv_str = NULL; 18201 else if (len == -1) 18202 vimvars[idx].vv_str = vim_strsave(val); 18203 else 18204 vimvars[idx].vv_str = vim_strnsave(val, len); 18205 } 18206 18207 /* 18208 * Set List v: variable to "val". 18209 */ 18210 void 18211 set_vim_var_list(idx, val) 18212 int idx; 18213 list_T *val; 18214 { 18215 list_unref(vimvars[idx].vv_list); 18216 vimvars[idx].vv_list = val; 18217 if (val != NULL) 18218 ++val->lv_refcount; 18219 } 18220 18221 /* 18222 * Set v:register if needed. 18223 */ 18224 void 18225 set_reg_var(c) 18226 int c; 18227 { 18228 char_u regname; 18229 18230 if (c == 0 || c == ' ') 18231 regname = '"'; 18232 else 18233 regname = c; 18234 /* Avoid free/alloc when the value is already right. */ 18235 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 18236 set_vim_var_string(VV_REG, ®name, 1); 18237 } 18238 18239 /* 18240 * Get or set v:exception. If "oldval" == NULL, return the current value. 18241 * Otherwise, restore the value to "oldval" and return NULL. 18242 * Must always be called in pairs to save and restore v:exception! Does not 18243 * take care of memory allocations. 18244 */ 18245 char_u * 18246 v_exception(oldval) 18247 char_u *oldval; 18248 { 18249 if (oldval == NULL) 18250 return vimvars[VV_EXCEPTION].vv_str; 18251 18252 vimvars[VV_EXCEPTION].vv_str = oldval; 18253 return NULL; 18254 } 18255 18256 /* 18257 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 18258 * Otherwise, restore the value to "oldval" and return NULL. 18259 * Must always be called in pairs to save and restore v:throwpoint! Does not 18260 * take care of memory allocations. 18261 */ 18262 char_u * 18263 v_throwpoint(oldval) 18264 char_u *oldval; 18265 { 18266 if (oldval == NULL) 18267 return vimvars[VV_THROWPOINT].vv_str; 18268 18269 vimvars[VV_THROWPOINT].vv_str = oldval; 18270 return NULL; 18271 } 18272 18273 #if defined(FEAT_AUTOCMD) || defined(PROTO) 18274 /* 18275 * Set v:cmdarg. 18276 * If "eap" != NULL, use "eap" to generate the value and return the old value. 18277 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 18278 * Must always be called in pairs! 18279 */ 18280 char_u * 18281 set_cmdarg(eap, oldarg) 18282 exarg_T *eap; 18283 char_u *oldarg; 18284 { 18285 char_u *oldval; 18286 char_u *newval; 18287 unsigned len; 18288 18289 oldval = vimvars[VV_CMDARG].vv_str; 18290 if (eap == NULL) 18291 { 18292 vim_free(oldval); 18293 vimvars[VV_CMDARG].vv_str = oldarg; 18294 return NULL; 18295 } 18296 18297 if (eap->force_bin == FORCE_BIN) 18298 len = 6; 18299 else if (eap->force_bin == FORCE_NOBIN) 18300 len = 8; 18301 else 18302 len = 0; 18303 18304 if (eap->read_edit) 18305 len += 7; 18306 18307 if (eap->force_ff != 0) 18308 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 18309 # ifdef FEAT_MBYTE 18310 if (eap->force_enc != 0) 18311 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 18312 if (eap->bad_char_idx != 0) 18313 len += (unsigned)STRLEN(eap->cmd + eap->bad_char_idx) + 7; 18314 # endif 18315 18316 newval = alloc(len + 1); 18317 if (newval == NULL) 18318 return NULL; 18319 18320 if (eap->force_bin == FORCE_BIN) 18321 sprintf((char *)newval, " ++bin"); 18322 else if (eap->force_bin == FORCE_NOBIN) 18323 sprintf((char *)newval, " ++nobin"); 18324 else 18325 *newval = NUL; 18326 18327 if (eap->read_edit) 18328 STRCAT(newval, " ++edit"); 18329 18330 if (eap->force_ff != 0) 18331 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 18332 eap->cmd + eap->force_ff); 18333 # ifdef FEAT_MBYTE 18334 if (eap->force_enc != 0) 18335 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 18336 eap->cmd + eap->force_enc); 18337 if (eap->bad_char_idx != 0) 18338 sprintf((char *)newval + STRLEN(newval), " ++bad=%s", 18339 eap->cmd + eap->bad_char_idx); 18340 # endif 18341 vimvars[VV_CMDARG].vv_str = newval; 18342 return oldval; 18343 } 18344 #endif 18345 18346 /* 18347 * Get the value of internal variable "name". 18348 * Return OK or FAIL. 18349 */ 18350 static int 18351 get_var_tv(name, len, rettv, verbose) 18352 char_u *name; 18353 int len; /* length of "name" */ 18354 typval_T *rettv; /* NULL when only checking existence */ 18355 int verbose; /* may give error message */ 18356 { 18357 int ret = OK; 18358 typval_T *tv = NULL; 18359 typval_T atv; 18360 dictitem_T *v; 18361 int cc; 18362 18363 /* truncate the name, so that we can use strcmp() */ 18364 cc = name[len]; 18365 name[len] = NUL; 18366 18367 /* 18368 * Check for "b:changedtick". 18369 */ 18370 if (STRCMP(name, "b:changedtick") == 0) 18371 { 18372 atv.v_type = VAR_NUMBER; 18373 atv.vval.v_number = curbuf->b_changedtick; 18374 tv = &atv; 18375 } 18376 18377 /* 18378 * Check for user-defined variables. 18379 */ 18380 else 18381 { 18382 v = find_var(name, NULL); 18383 if (v != NULL) 18384 tv = &v->di_tv; 18385 } 18386 18387 if (tv == NULL) 18388 { 18389 if (rettv != NULL && verbose) 18390 EMSG2(_(e_undefvar), name); 18391 ret = FAIL; 18392 } 18393 else if (rettv != NULL) 18394 copy_tv(tv, rettv); 18395 18396 name[len] = cc; 18397 18398 return ret; 18399 } 18400 18401 /* 18402 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 18403 * Also handle function call with Funcref variable: func(expr) 18404 * Can all be combined: dict.func(expr)[idx]['func'](expr) 18405 */ 18406 static int 18407 handle_subscript(arg, rettv, evaluate, verbose) 18408 char_u **arg; 18409 typval_T *rettv; 18410 int evaluate; /* do more than finding the end */ 18411 int verbose; /* give error messages */ 18412 { 18413 int ret = OK; 18414 dict_T *selfdict = NULL; 18415 char_u *s; 18416 int len; 18417 typval_T functv; 18418 18419 while (ret == OK 18420 && (**arg == '[' 18421 || (**arg == '.' && rettv->v_type == VAR_DICT) 18422 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 18423 && !vim_iswhite(*(*arg - 1))) 18424 { 18425 if (**arg == '(') 18426 { 18427 /* need to copy the funcref so that we can clear rettv */ 18428 functv = *rettv; 18429 rettv->v_type = VAR_UNKNOWN; 18430 18431 /* Invoke the function. Recursive! */ 18432 s = functv.vval.v_string; 18433 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 18434 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 18435 &len, evaluate, selfdict); 18436 18437 /* Clear the funcref afterwards, so that deleting it while 18438 * evaluating the arguments is possible (see test55). */ 18439 clear_tv(&functv); 18440 18441 /* Stop the expression evaluation when immediately aborting on 18442 * error, or when an interrupt occurred or an exception was thrown 18443 * but not caught. */ 18444 if (aborting()) 18445 { 18446 if (ret == OK) 18447 clear_tv(rettv); 18448 ret = FAIL; 18449 } 18450 dict_unref(selfdict); 18451 selfdict = NULL; 18452 } 18453 else /* **arg == '[' || **arg == '.' */ 18454 { 18455 dict_unref(selfdict); 18456 if (rettv->v_type == VAR_DICT) 18457 { 18458 selfdict = rettv->vval.v_dict; 18459 if (selfdict != NULL) 18460 ++selfdict->dv_refcount; 18461 } 18462 else 18463 selfdict = NULL; 18464 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 18465 { 18466 clear_tv(rettv); 18467 ret = FAIL; 18468 } 18469 } 18470 } 18471 dict_unref(selfdict); 18472 return ret; 18473 } 18474 18475 /* 18476 * Allocate memory for a variable type-value, and make it empty (0 or NULL 18477 * value). 18478 */ 18479 static typval_T * 18480 alloc_tv() 18481 { 18482 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 18483 } 18484 18485 /* 18486 * Allocate memory for a variable type-value, and assign a string to it. 18487 * The string "s" must have been allocated, it is consumed. 18488 * Return NULL for out of memory, the variable otherwise. 18489 */ 18490 static typval_T * 18491 alloc_string_tv(s) 18492 char_u *s; 18493 { 18494 typval_T *rettv; 18495 18496 rettv = alloc_tv(); 18497 if (rettv != NULL) 18498 { 18499 rettv->v_type = VAR_STRING; 18500 rettv->vval.v_string = s; 18501 } 18502 else 18503 vim_free(s); 18504 return rettv; 18505 } 18506 18507 /* 18508 * Free the memory for a variable type-value. 18509 */ 18510 void 18511 free_tv(varp) 18512 typval_T *varp; 18513 { 18514 if (varp != NULL) 18515 { 18516 switch (varp->v_type) 18517 { 18518 case VAR_FUNC: 18519 func_unref(varp->vval.v_string); 18520 /*FALLTHROUGH*/ 18521 case VAR_STRING: 18522 vim_free(varp->vval.v_string); 18523 break; 18524 case VAR_LIST: 18525 list_unref(varp->vval.v_list); 18526 break; 18527 case VAR_DICT: 18528 dict_unref(varp->vval.v_dict); 18529 break; 18530 case VAR_NUMBER: 18531 #ifdef FEAT_FLOAT 18532 case VAR_FLOAT: 18533 #endif 18534 case VAR_UNKNOWN: 18535 break; 18536 default: 18537 EMSG2(_(e_intern2), "free_tv()"); 18538 break; 18539 } 18540 vim_free(varp); 18541 } 18542 } 18543 18544 /* 18545 * Free the memory for a variable value and set the value to NULL or 0. 18546 */ 18547 void 18548 clear_tv(varp) 18549 typval_T *varp; 18550 { 18551 if (varp != NULL) 18552 { 18553 switch (varp->v_type) 18554 { 18555 case VAR_FUNC: 18556 func_unref(varp->vval.v_string); 18557 /*FALLTHROUGH*/ 18558 case VAR_STRING: 18559 vim_free(varp->vval.v_string); 18560 varp->vval.v_string = NULL; 18561 break; 18562 case VAR_LIST: 18563 list_unref(varp->vval.v_list); 18564 varp->vval.v_list = NULL; 18565 break; 18566 case VAR_DICT: 18567 dict_unref(varp->vval.v_dict); 18568 varp->vval.v_dict = NULL; 18569 break; 18570 case VAR_NUMBER: 18571 varp->vval.v_number = 0; 18572 break; 18573 #ifdef FEAT_FLOAT 18574 case VAR_FLOAT: 18575 varp->vval.v_float = 0.0; 18576 break; 18577 #endif 18578 case VAR_UNKNOWN: 18579 break; 18580 default: 18581 EMSG2(_(e_intern2), "clear_tv()"); 18582 } 18583 varp->v_lock = 0; 18584 } 18585 } 18586 18587 /* 18588 * Set the value of a variable to NULL without freeing items. 18589 */ 18590 static void 18591 init_tv(varp) 18592 typval_T *varp; 18593 { 18594 if (varp != NULL) 18595 vim_memset(varp, 0, sizeof(typval_T)); 18596 } 18597 18598 /* 18599 * Get the number value of a variable. 18600 * If it is a String variable, uses vim_str2nr(). 18601 * For incompatible types, return 0. 18602 * get_tv_number_chk() is similar to get_tv_number(), but informs the 18603 * caller of incompatible types: it sets *denote to TRUE if "denote" 18604 * is not NULL or returns -1 otherwise. 18605 */ 18606 static long 18607 get_tv_number(varp) 18608 typval_T *varp; 18609 { 18610 int error = FALSE; 18611 18612 return get_tv_number_chk(varp, &error); /* return 0L on error */ 18613 } 18614 18615 long 18616 get_tv_number_chk(varp, denote) 18617 typval_T *varp; 18618 int *denote; 18619 { 18620 long n = 0L; 18621 18622 switch (varp->v_type) 18623 { 18624 case VAR_NUMBER: 18625 return (long)(varp->vval.v_number); 18626 #ifdef FEAT_FLOAT 18627 case VAR_FLOAT: 18628 EMSG(_("E805: Using a Float as a Number")); 18629 break; 18630 #endif 18631 case VAR_FUNC: 18632 EMSG(_("E703: Using a Funcref as a Number")); 18633 break; 18634 case VAR_STRING: 18635 if (varp->vval.v_string != NULL) 18636 vim_str2nr(varp->vval.v_string, NULL, NULL, 18637 TRUE, TRUE, &n, NULL); 18638 return n; 18639 case VAR_LIST: 18640 EMSG(_("E745: Using a List as a Number")); 18641 break; 18642 case VAR_DICT: 18643 EMSG(_("E728: Using a Dictionary as a Number")); 18644 break; 18645 default: 18646 EMSG2(_(e_intern2), "get_tv_number()"); 18647 break; 18648 } 18649 if (denote == NULL) /* useful for values that must be unsigned */ 18650 n = -1; 18651 else 18652 *denote = TRUE; 18653 return n; 18654 } 18655 18656 /* 18657 * Get the lnum from the first argument. 18658 * Also accepts ".", "$", etc., but that only works for the current buffer. 18659 * Returns -1 on error. 18660 */ 18661 static linenr_T 18662 get_tv_lnum(argvars) 18663 typval_T *argvars; 18664 { 18665 typval_T rettv; 18666 linenr_T lnum; 18667 18668 lnum = get_tv_number_chk(&argvars[0], NULL); 18669 if (lnum == 0) /* no valid number, try using line() */ 18670 { 18671 rettv.v_type = VAR_NUMBER; 18672 f_line(argvars, &rettv); 18673 lnum = rettv.vval.v_number; 18674 clear_tv(&rettv); 18675 } 18676 return lnum; 18677 } 18678 18679 /* 18680 * Get the lnum from the first argument. 18681 * Also accepts "$", then "buf" is used. 18682 * Returns 0 on error. 18683 */ 18684 static linenr_T 18685 get_tv_lnum_buf(argvars, buf) 18686 typval_T *argvars; 18687 buf_T *buf; 18688 { 18689 if (argvars[0].v_type == VAR_STRING 18690 && argvars[0].vval.v_string != NULL 18691 && argvars[0].vval.v_string[0] == '$' 18692 && buf != NULL) 18693 return buf->b_ml.ml_line_count; 18694 return get_tv_number_chk(&argvars[0], NULL); 18695 } 18696 18697 /* 18698 * Get the string value of a variable. 18699 * If it is a Number variable, the number is converted into a string. 18700 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 18701 * get_tv_string_buf() uses a given buffer. 18702 * If the String variable has never been set, return an empty string. 18703 * Never returns NULL; 18704 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 18705 * NULL on error. 18706 */ 18707 static char_u * 18708 get_tv_string(varp) 18709 typval_T *varp; 18710 { 18711 static char_u mybuf[NUMBUFLEN]; 18712 18713 return get_tv_string_buf(varp, mybuf); 18714 } 18715 18716 static char_u * 18717 get_tv_string_buf(varp, buf) 18718 typval_T *varp; 18719 char_u *buf; 18720 { 18721 char_u *res = get_tv_string_buf_chk(varp, buf); 18722 18723 return res != NULL ? res : (char_u *)""; 18724 } 18725 18726 char_u * 18727 get_tv_string_chk(varp) 18728 typval_T *varp; 18729 { 18730 static char_u mybuf[NUMBUFLEN]; 18731 18732 return get_tv_string_buf_chk(varp, mybuf); 18733 } 18734 18735 static char_u * 18736 get_tv_string_buf_chk(varp, buf) 18737 typval_T *varp; 18738 char_u *buf; 18739 { 18740 switch (varp->v_type) 18741 { 18742 case VAR_NUMBER: 18743 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 18744 return buf; 18745 case VAR_FUNC: 18746 EMSG(_("E729: using Funcref as a String")); 18747 break; 18748 case VAR_LIST: 18749 EMSG(_("E730: using List as a String")); 18750 break; 18751 case VAR_DICT: 18752 EMSG(_("E731: using Dictionary as a String")); 18753 break; 18754 #ifdef FEAT_FLOAT 18755 case VAR_FLOAT: 18756 EMSG(_("E806: using Float as a String")); 18757 break; 18758 #endif 18759 case VAR_STRING: 18760 if (varp->vval.v_string != NULL) 18761 return varp->vval.v_string; 18762 return (char_u *)""; 18763 default: 18764 EMSG2(_(e_intern2), "get_tv_string_buf()"); 18765 break; 18766 } 18767 return NULL; 18768 } 18769 18770 /* 18771 * Find variable "name" in the list of variables. 18772 * Return a pointer to it if found, NULL if not found. 18773 * Careful: "a:0" variables don't have a name. 18774 * When "htp" is not NULL we are writing to the variable, set "htp" to the 18775 * hashtab_T used. 18776 */ 18777 static dictitem_T * 18778 find_var(name, htp) 18779 char_u *name; 18780 hashtab_T **htp; 18781 { 18782 char_u *varname; 18783 hashtab_T *ht; 18784 18785 ht = find_var_ht(name, &varname); 18786 if (htp != NULL) 18787 *htp = ht; 18788 if (ht == NULL) 18789 return NULL; 18790 return find_var_in_ht(ht, varname, htp != NULL); 18791 } 18792 18793 /* 18794 * Find variable "varname" in hashtab "ht". 18795 * Returns NULL if not found. 18796 */ 18797 static dictitem_T * 18798 find_var_in_ht(ht, varname, writing) 18799 hashtab_T *ht; 18800 char_u *varname; 18801 int writing; 18802 { 18803 hashitem_T *hi; 18804 18805 if (*varname == NUL) 18806 { 18807 /* Must be something like "s:", otherwise "ht" would be NULL. */ 18808 switch (varname[-2]) 18809 { 18810 case 's': return &SCRIPT_SV(current_SID)->sv_var; 18811 case 'g': return &globvars_var; 18812 case 'v': return &vimvars_var; 18813 case 'b': return &curbuf->b_bufvar; 18814 case 'w': return &curwin->w_winvar; 18815 #ifdef FEAT_WINDOWS 18816 case 't': return &curtab->tp_winvar; 18817 #endif 18818 case 'l': return current_funccal == NULL 18819 ? NULL : ¤t_funccal->l_vars_var; 18820 case 'a': return current_funccal == NULL 18821 ? NULL : ¤t_funccal->l_avars_var; 18822 } 18823 return NULL; 18824 } 18825 18826 hi = hash_find(ht, varname); 18827 if (HASHITEM_EMPTY(hi)) 18828 { 18829 /* For global variables we may try auto-loading the script. If it 18830 * worked find the variable again. Don't auto-load a script if it was 18831 * loaded already, otherwise it would be loaded every time when 18832 * checking if a function name is a Funcref variable. */ 18833 if (ht == &globvarht && !writing 18834 && script_autoload(varname, FALSE) && !aborting()) 18835 hi = hash_find(ht, varname); 18836 if (HASHITEM_EMPTY(hi)) 18837 return NULL; 18838 } 18839 return HI2DI(hi); 18840 } 18841 18842 /* 18843 * Find the hashtab used for a variable name. 18844 * Set "varname" to the start of name without ':'. 18845 */ 18846 static hashtab_T * 18847 find_var_ht(name, varname) 18848 char_u *name; 18849 char_u **varname; 18850 { 18851 hashitem_T *hi; 18852 18853 if (name[1] != ':') 18854 { 18855 /* The name must not start with a colon or #. */ 18856 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 18857 return NULL; 18858 *varname = name; 18859 18860 /* "version" is "v:version" in all scopes */ 18861 hi = hash_find(&compat_hashtab, name); 18862 if (!HASHITEM_EMPTY(hi)) 18863 return &compat_hashtab; 18864 18865 if (current_funccal == NULL) 18866 return &globvarht; /* global variable */ 18867 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 18868 } 18869 *varname = name + 2; 18870 if (*name == 'g') /* global variable */ 18871 return &globvarht; 18872 /* There must be no ':' or '#' in the rest of the name, unless g: is used 18873 */ 18874 if (vim_strchr(name + 2, ':') != NULL 18875 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 18876 return NULL; 18877 if (*name == 'b') /* buffer variable */ 18878 return &curbuf->b_vars.dv_hashtab; 18879 if (*name == 'w') /* window variable */ 18880 return &curwin->w_vars.dv_hashtab; 18881 #ifdef FEAT_WINDOWS 18882 if (*name == 't') /* tab page variable */ 18883 return &curtab->tp_vars.dv_hashtab; 18884 #endif 18885 if (*name == 'v') /* v: variable */ 18886 return &vimvarht; 18887 if (*name == 'a' && current_funccal != NULL) /* function argument */ 18888 return ¤t_funccal->l_avars.dv_hashtab; 18889 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 18890 return ¤t_funccal->l_vars.dv_hashtab; 18891 if (*name == 's' /* script variable */ 18892 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 18893 return &SCRIPT_VARS(current_SID); 18894 return NULL; 18895 } 18896 18897 /* 18898 * Get the string value of a (global/local) variable. 18899 * Returns NULL when it doesn't exist. 18900 */ 18901 char_u * 18902 get_var_value(name) 18903 char_u *name; 18904 { 18905 dictitem_T *v; 18906 18907 v = find_var(name, NULL); 18908 if (v == NULL) 18909 return NULL; 18910 return get_tv_string(&v->di_tv); 18911 } 18912 18913 /* 18914 * Allocate a new hashtab for a sourced script. It will be used while 18915 * sourcing this script and when executing functions defined in the script. 18916 */ 18917 void 18918 new_script_vars(id) 18919 scid_T id; 18920 { 18921 int i; 18922 hashtab_T *ht; 18923 scriptvar_T *sv; 18924 18925 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 18926 { 18927 /* Re-allocating ga_data means that an ht_array pointing to 18928 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 18929 * at its init value. Also reset "v_dict", it's always the same. */ 18930 for (i = 1; i <= ga_scripts.ga_len; ++i) 18931 { 18932 ht = &SCRIPT_VARS(i); 18933 if (ht->ht_mask == HT_INIT_SIZE - 1) 18934 ht->ht_array = ht->ht_smallarray; 18935 sv = SCRIPT_SV(i); 18936 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 18937 } 18938 18939 while (ga_scripts.ga_len < id) 18940 { 18941 sv = SCRIPT_SV(ga_scripts.ga_len + 1) = 18942 (scriptvar_T *)alloc_clear(sizeof(scriptvar_T)); 18943 init_var_dict(&sv->sv_dict, &sv->sv_var); 18944 ++ga_scripts.ga_len; 18945 } 18946 } 18947 } 18948 18949 /* 18950 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 18951 * point to it. 18952 */ 18953 void 18954 init_var_dict(dict, dict_var) 18955 dict_T *dict; 18956 dictitem_T *dict_var; 18957 { 18958 hash_init(&dict->dv_hashtab); 18959 dict->dv_refcount = DO_NOT_FREE_CNT; 18960 dict->dv_copyID = 0; 18961 dict_var->di_tv.vval.v_dict = dict; 18962 dict_var->di_tv.v_type = VAR_DICT; 18963 dict_var->di_tv.v_lock = VAR_FIXED; 18964 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18965 dict_var->di_key[0] = NUL; 18966 } 18967 18968 /* 18969 * Clean up a list of internal variables. 18970 * Frees all allocated variables and the value they contain. 18971 * Clears hashtab "ht", does not free it. 18972 */ 18973 void 18974 vars_clear(ht) 18975 hashtab_T *ht; 18976 { 18977 vars_clear_ext(ht, TRUE); 18978 } 18979 18980 /* 18981 * Like vars_clear(), but only free the value if "free_val" is TRUE. 18982 */ 18983 static void 18984 vars_clear_ext(ht, free_val) 18985 hashtab_T *ht; 18986 int free_val; 18987 { 18988 int todo; 18989 hashitem_T *hi; 18990 dictitem_T *v; 18991 18992 hash_lock(ht); 18993 todo = (int)ht->ht_used; 18994 for (hi = ht->ht_array; todo > 0; ++hi) 18995 { 18996 if (!HASHITEM_EMPTY(hi)) 18997 { 18998 --todo; 18999 19000 /* Free the variable. Don't remove it from the hashtab, 19001 * ht_array might change then. hash_clear() takes care of it 19002 * later. */ 19003 v = HI2DI(hi); 19004 if (free_val) 19005 clear_tv(&v->di_tv); 19006 if ((v->di_flags & DI_FLAGS_FIX) == 0) 19007 vim_free(v); 19008 } 19009 } 19010 hash_clear(ht); 19011 ht->ht_used = 0; 19012 } 19013 19014 /* 19015 * Delete a variable from hashtab "ht" at item "hi". 19016 * Clear the variable value and free the dictitem. 19017 */ 19018 static void 19019 delete_var(ht, hi) 19020 hashtab_T *ht; 19021 hashitem_T *hi; 19022 { 19023 dictitem_T *di = HI2DI(hi); 19024 19025 hash_remove(ht, hi); 19026 clear_tv(&di->di_tv); 19027 vim_free(di); 19028 } 19029 19030 /* 19031 * List the value of one internal variable. 19032 */ 19033 static void 19034 list_one_var(v, prefix, first) 19035 dictitem_T *v; 19036 char_u *prefix; 19037 int *first; 19038 { 19039 char_u *tofree; 19040 char_u *s; 19041 char_u numbuf[NUMBUFLEN]; 19042 19043 current_copyID += COPYID_INC; 19044 s = echo_string(&v->di_tv, &tofree, numbuf, current_copyID); 19045 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 19046 s == NULL ? (char_u *)"" : s, first); 19047 vim_free(tofree); 19048 } 19049 19050 static void 19051 list_one_var_a(prefix, name, type, string, first) 19052 char_u *prefix; 19053 char_u *name; 19054 int type; 19055 char_u *string; 19056 int *first; /* when TRUE clear rest of screen and set to FALSE */ 19057 { 19058 /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ 19059 msg_start(); 19060 msg_puts(prefix); 19061 if (name != NULL) /* "a:" vars don't have a name stored */ 19062 msg_puts(name); 19063 msg_putchar(' '); 19064 msg_advance(22); 19065 if (type == VAR_NUMBER) 19066 msg_putchar('#'); 19067 else if (type == VAR_FUNC) 19068 msg_putchar('*'); 19069 else if (type == VAR_LIST) 19070 { 19071 msg_putchar('['); 19072 if (*string == '[') 19073 ++string; 19074 } 19075 else if (type == VAR_DICT) 19076 { 19077 msg_putchar('{'); 19078 if (*string == '{') 19079 ++string; 19080 } 19081 else 19082 msg_putchar(' '); 19083 19084 msg_outtrans(string); 19085 19086 if (type == VAR_FUNC) 19087 msg_puts((char_u *)"()"); 19088 if (*first) 19089 { 19090 msg_clr_eos(); 19091 *first = FALSE; 19092 } 19093 } 19094 19095 /* 19096 * Set variable "name" to value in "tv". 19097 * If the variable already exists, the value is updated. 19098 * Otherwise the variable is created. 19099 */ 19100 static void 19101 set_var(name, tv, copy) 19102 char_u *name; 19103 typval_T *tv; 19104 int copy; /* make copy of value in "tv" */ 19105 { 19106 dictitem_T *v; 19107 char_u *varname; 19108 hashtab_T *ht; 19109 char_u *p; 19110 19111 ht = find_var_ht(name, &varname); 19112 if (ht == NULL || *varname == NUL) 19113 { 19114 EMSG2(_(e_illvar), name); 19115 return; 19116 } 19117 v = find_var_in_ht(ht, varname, TRUE); 19118 19119 if (tv->v_type == VAR_FUNC) 19120 { 19121 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 19122 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 19123 ? name[2] : name[0])) 19124 { 19125 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 19126 return; 19127 } 19128 /* Don't allow hiding a function. When "v" is not NULL we migth be 19129 * assigning another function to the same var, the type is checked 19130 * below. */ 19131 if (v == NULL && function_exists(name)) 19132 { 19133 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 19134 name); 19135 return; 19136 } 19137 } 19138 19139 if (v != NULL) 19140 { 19141 /* existing variable, need to clear the value */ 19142 if (var_check_ro(v->di_flags, name) 19143 || tv_check_lock(v->di_tv.v_lock, name)) 19144 return; 19145 if (v->di_tv.v_type != tv->v_type 19146 && !((v->di_tv.v_type == VAR_STRING 19147 || v->di_tv.v_type == VAR_NUMBER) 19148 && (tv->v_type == VAR_STRING 19149 || tv->v_type == VAR_NUMBER)) 19150 #ifdef FEAT_FLOAT 19151 && !((v->di_tv.v_type == VAR_NUMBER 19152 || v->di_tv.v_type == VAR_FLOAT) 19153 && (tv->v_type == VAR_NUMBER 19154 || tv->v_type == VAR_FLOAT)) 19155 #endif 19156 ) 19157 { 19158 EMSG2(_("E706: Variable type mismatch for: %s"), name); 19159 return; 19160 } 19161 19162 /* 19163 * Handle setting internal v: variables separately: we don't change 19164 * the type. 19165 */ 19166 if (ht == &vimvarht) 19167 { 19168 if (v->di_tv.v_type == VAR_STRING) 19169 { 19170 vim_free(v->di_tv.vval.v_string); 19171 if (copy || tv->v_type != VAR_STRING) 19172 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 19173 else 19174 { 19175 /* Take over the string to avoid an extra alloc/free. */ 19176 v->di_tv.vval.v_string = tv->vval.v_string; 19177 tv->vval.v_string = NULL; 19178 } 19179 } 19180 else if (v->di_tv.v_type != VAR_NUMBER) 19181 EMSG2(_(e_intern2), "set_var()"); 19182 else 19183 { 19184 v->di_tv.vval.v_number = get_tv_number(tv); 19185 if (STRCMP(varname, "searchforward") == 0) 19186 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); 19187 } 19188 return; 19189 } 19190 19191 clear_tv(&v->di_tv); 19192 } 19193 else /* add a new variable */ 19194 { 19195 /* Can't add "v:" variable. */ 19196 if (ht == &vimvarht) 19197 { 19198 EMSG2(_(e_illvar), name); 19199 return; 19200 } 19201 19202 /* Make sure the variable name is valid. */ 19203 for (p = varname; *p != NUL; ++p) 19204 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 19205 && *p != AUTOLOAD_CHAR) 19206 { 19207 EMSG2(_(e_illvar), varname); 19208 return; 19209 } 19210 19211 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19212 + STRLEN(varname))); 19213 if (v == NULL) 19214 return; 19215 STRCPY(v->di_key, varname); 19216 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 19217 { 19218 vim_free(v); 19219 return; 19220 } 19221 v->di_flags = 0; 19222 } 19223 19224 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 19225 copy_tv(tv, &v->di_tv); 19226 else 19227 { 19228 v->di_tv = *tv; 19229 v->di_tv.v_lock = 0; 19230 init_tv(tv); 19231 } 19232 } 19233 19234 /* 19235 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 19236 * Also give an error message. 19237 */ 19238 static int 19239 var_check_ro(flags, name) 19240 int flags; 19241 char_u *name; 19242 { 19243 if (flags & DI_FLAGS_RO) 19244 { 19245 EMSG2(_(e_readonlyvar), name); 19246 return TRUE; 19247 } 19248 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 19249 { 19250 EMSG2(_(e_readonlysbx), name); 19251 return TRUE; 19252 } 19253 return FALSE; 19254 } 19255 19256 /* 19257 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 19258 * Also give an error message. 19259 */ 19260 static int 19261 var_check_fixed(flags, name) 19262 int flags; 19263 char_u *name; 19264 { 19265 if (flags & DI_FLAGS_FIX) 19266 { 19267 EMSG2(_("E795: Cannot delete variable %s"), name); 19268 return TRUE; 19269 } 19270 return FALSE; 19271 } 19272 19273 /* 19274 * Return TRUE if typeval "tv" is set to be locked (immutable). 19275 * Also give an error message, using "name". 19276 */ 19277 static int 19278 tv_check_lock(lock, name) 19279 int lock; 19280 char_u *name; 19281 { 19282 if (lock & VAR_LOCKED) 19283 { 19284 EMSG2(_("E741: Value is locked: %s"), 19285 name == NULL ? (char_u *)_("Unknown") : name); 19286 return TRUE; 19287 } 19288 if (lock & VAR_FIXED) 19289 { 19290 EMSG2(_("E742: Cannot change value of %s"), 19291 name == NULL ? (char_u *)_("Unknown") : name); 19292 return TRUE; 19293 } 19294 return FALSE; 19295 } 19296 19297 /* 19298 * Copy the values from typval_T "from" to typval_T "to". 19299 * When needed allocates string or increases reference count. 19300 * Does not make a copy of a list or dict but copies the reference! 19301 * It is OK for "from" and "to" to point to the same item. This is used to 19302 * make a copy later. 19303 */ 19304 void 19305 copy_tv(from, to) 19306 typval_T *from; 19307 typval_T *to; 19308 { 19309 to->v_type = from->v_type; 19310 to->v_lock = 0; 19311 switch (from->v_type) 19312 { 19313 case VAR_NUMBER: 19314 to->vval.v_number = from->vval.v_number; 19315 break; 19316 #ifdef FEAT_FLOAT 19317 case VAR_FLOAT: 19318 to->vval.v_float = from->vval.v_float; 19319 break; 19320 #endif 19321 case VAR_STRING: 19322 case VAR_FUNC: 19323 if (from->vval.v_string == NULL) 19324 to->vval.v_string = NULL; 19325 else 19326 { 19327 to->vval.v_string = vim_strsave(from->vval.v_string); 19328 if (from->v_type == VAR_FUNC) 19329 func_ref(to->vval.v_string); 19330 } 19331 break; 19332 case VAR_LIST: 19333 if (from->vval.v_list == NULL) 19334 to->vval.v_list = NULL; 19335 else 19336 { 19337 to->vval.v_list = from->vval.v_list; 19338 ++to->vval.v_list->lv_refcount; 19339 } 19340 break; 19341 case VAR_DICT: 19342 if (from->vval.v_dict == NULL) 19343 to->vval.v_dict = NULL; 19344 else 19345 { 19346 to->vval.v_dict = from->vval.v_dict; 19347 ++to->vval.v_dict->dv_refcount; 19348 } 19349 break; 19350 default: 19351 EMSG2(_(e_intern2), "copy_tv()"); 19352 break; 19353 } 19354 } 19355 19356 /* 19357 * Make a copy of an item. 19358 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 19359 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 19360 * reference to an already copied list/dict can be used. 19361 * Returns FAIL or OK. 19362 */ 19363 static int 19364 item_copy(from, to, deep, copyID) 19365 typval_T *from; 19366 typval_T *to; 19367 int deep; 19368 int copyID; 19369 { 19370 static int recurse = 0; 19371 int ret = OK; 19372 19373 if (recurse >= DICT_MAXNEST) 19374 { 19375 EMSG(_("E698: variable nested too deep for making a copy")); 19376 return FAIL; 19377 } 19378 ++recurse; 19379 19380 switch (from->v_type) 19381 { 19382 case VAR_NUMBER: 19383 #ifdef FEAT_FLOAT 19384 case VAR_FLOAT: 19385 #endif 19386 case VAR_STRING: 19387 case VAR_FUNC: 19388 copy_tv(from, to); 19389 break; 19390 case VAR_LIST: 19391 to->v_type = VAR_LIST; 19392 to->v_lock = 0; 19393 if (from->vval.v_list == NULL) 19394 to->vval.v_list = NULL; 19395 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 19396 { 19397 /* use the copy made earlier */ 19398 to->vval.v_list = from->vval.v_list->lv_copylist; 19399 ++to->vval.v_list->lv_refcount; 19400 } 19401 else 19402 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 19403 if (to->vval.v_list == NULL) 19404 ret = FAIL; 19405 break; 19406 case VAR_DICT: 19407 to->v_type = VAR_DICT; 19408 to->v_lock = 0; 19409 if (from->vval.v_dict == NULL) 19410 to->vval.v_dict = NULL; 19411 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 19412 { 19413 /* use the copy made earlier */ 19414 to->vval.v_dict = from->vval.v_dict->dv_copydict; 19415 ++to->vval.v_dict->dv_refcount; 19416 } 19417 else 19418 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 19419 if (to->vval.v_dict == NULL) 19420 ret = FAIL; 19421 break; 19422 default: 19423 EMSG2(_(e_intern2), "item_copy()"); 19424 ret = FAIL; 19425 } 19426 --recurse; 19427 return ret; 19428 } 19429 19430 /* 19431 * ":echo expr1 ..." print each argument separated with a space, add a 19432 * newline at the end. 19433 * ":echon expr1 ..." print each argument plain. 19434 */ 19435 void 19436 ex_echo(eap) 19437 exarg_T *eap; 19438 { 19439 char_u *arg = eap->arg; 19440 typval_T rettv; 19441 char_u *tofree; 19442 char_u *p; 19443 int needclr = TRUE; 19444 int atstart = TRUE; 19445 char_u numbuf[NUMBUFLEN]; 19446 19447 if (eap->skip) 19448 ++emsg_skip; 19449 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 19450 { 19451 /* If eval1() causes an error message the text from the command may 19452 * still need to be cleared. E.g., "echo 22,44". */ 19453 need_clr_eos = needclr; 19454 19455 p = arg; 19456 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 19457 { 19458 /* 19459 * Report the invalid expression unless the expression evaluation 19460 * has been cancelled due to an aborting error, an interrupt, or an 19461 * exception. 19462 */ 19463 if (!aborting()) 19464 EMSG2(_(e_invexpr2), p); 19465 need_clr_eos = FALSE; 19466 break; 19467 } 19468 need_clr_eos = FALSE; 19469 19470 if (!eap->skip) 19471 { 19472 if (atstart) 19473 { 19474 atstart = FALSE; 19475 /* Call msg_start() after eval1(), evaluating the expression 19476 * may cause a message to appear. */ 19477 if (eap->cmdidx == CMD_echo) 19478 msg_start(); 19479 } 19480 else if (eap->cmdidx == CMD_echo) 19481 msg_puts_attr((char_u *)" ", echo_attr); 19482 current_copyID += COPYID_INC; 19483 p = echo_string(&rettv, &tofree, numbuf, current_copyID); 19484 if (p != NULL) 19485 for ( ; *p != NUL && !got_int; ++p) 19486 { 19487 if (*p == '\n' || *p == '\r' || *p == TAB) 19488 { 19489 if (*p != TAB && needclr) 19490 { 19491 /* remove any text still there from the command */ 19492 msg_clr_eos(); 19493 needclr = FALSE; 19494 } 19495 msg_putchar_attr(*p, echo_attr); 19496 } 19497 else 19498 { 19499 #ifdef FEAT_MBYTE 19500 if (has_mbyte) 19501 { 19502 int i = (*mb_ptr2len)(p); 19503 19504 (void)msg_outtrans_len_attr(p, i, echo_attr); 19505 p += i - 1; 19506 } 19507 else 19508 #endif 19509 (void)msg_outtrans_len_attr(p, 1, echo_attr); 19510 } 19511 } 19512 vim_free(tofree); 19513 } 19514 clear_tv(&rettv); 19515 arg = skipwhite(arg); 19516 } 19517 eap->nextcmd = check_nextcmd(arg); 19518 19519 if (eap->skip) 19520 --emsg_skip; 19521 else 19522 { 19523 /* remove text that may still be there from the command */ 19524 if (needclr) 19525 msg_clr_eos(); 19526 if (eap->cmdidx == CMD_echo) 19527 msg_end(); 19528 } 19529 } 19530 19531 /* 19532 * ":echohl {name}". 19533 */ 19534 void 19535 ex_echohl(eap) 19536 exarg_T *eap; 19537 { 19538 int id; 19539 19540 id = syn_name2id(eap->arg); 19541 if (id == 0) 19542 echo_attr = 0; 19543 else 19544 echo_attr = syn_id2attr(id); 19545 } 19546 19547 /* 19548 * ":execute expr1 ..." execute the result of an expression. 19549 * ":echomsg expr1 ..." Print a message 19550 * ":echoerr expr1 ..." Print an error 19551 * Each gets spaces around each argument and a newline at the end for 19552 * echo commands 19553 */ 19554 void 19555 ex_execute(eap) 19556 exarg_T *eap; 19557 { 19558 char_u *arg = eap->arg; 19559 typval_T rettv; 19560 int ret = OK; 19561 char_u *p; 19562 garray_T ga; 19563 int len; 19564 int save_did_emsg; 19565 19566 ga_init2(&ga, 1, 80); 19567 19568 if (eap->skip) 19569 ++emsg_skip; 19570 while (*arg != NUL && *arg != '|' && *arg != '\n') 19571 { 19572 p = arg; 19573 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 19574 { 19575 /* 19576 * Report the invalid expression unless the expression evaluation 19577 * has been cancelled due to an aborting error, an interrupt, or an 19578 * exception. 19579 */ 19580 if (!aborting()) 19581 EMSG2(_(e_invexpr2), p); 19582 ret = FAIL; 19583 break; 19584 } 19585 19586 if (!eap->skip) 19587 { 19588 p = get_tv_string(&rettv); 19589 len = (int)STRLEN(p); 19590 if (ga_grow(&ga, len + 2) == FAIL) 19591 { 19592 clear_tv(&rettv); 19593 ret = FAIL; 19594 break; 19595 } 19596 if (ga.ga_len) 19597 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 19598 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 19599 ga.ga_len += len; 19600 } 19601 19602 clear_tv(&rettv); 19603 arg = skipwhite(arg); 19604 } 19605 19606 if (ret != FAIL && ga.ga_data != NULL) 19607 { 19608 if (eap->cmdidx == CMD_echomsg) 19609 { 19610 MSG_ATTR(ga.ga_data, echo_attr); 19611 out_flush(); 19612 } 19613 else if (eap->cmdidx == CMD_echoerr) 19614 { 19615 /* We don't want to abort following commands, restore did_emsg. */ 19616 save_did_emsg = did_emsg; 19617 EMSG((char_u *)ga.ga_data); 19618 if (!force_abort) 19619 did_emsg = save_did_emsg; 19620 } 19621 else if (eap->cmdidx == CMD_execute) 19622 do_cmdline((char_u *)ga.ga_data, 19623 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 19624 } 19625 19626 ga_clear(&ga); 19627 19628 if (eap->skip) 19629 --emsg_skip; 19630 19631 eap->nextcmd = check_nextcmd(arg); 19632 } 19633 19634 /* 19635 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 19636 * "arg" points to the "&" or '+' when called, to "option" when returning. 19637 * Returns NULL when no option name found. Otherwise pointer to the char 19638 * after the option name. 19639 */ 19640 static char_u * 19641 find_option_end(arg, opt_flags) 19642 char_u **arg; 19643 int *opt_flags; 19644 { 19645 char_u *p = *arg; 19646 19647 ++p; 19648 if (*p == 'g' && p[1] == ':') 19649 { 19650 *opt_flags = OPT_GLOBAL; 19651 p += 2; 19652 } 19653 else if (*p == 'l' && p[1] == ':') 19654 { 19655 *opt_flags = OPT_LOCAL; 19656 p += 2; 19657 } 19658 else 19659 *opt_flags = 0; 19660 19661 if (!ASCII_ISALPHA(*p)) 19662 return NULL; 19663 *arg = p; 19664 19665 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 19666 p += 4; /* termcap option */ 19667 else 19668 while (ASCII_ISALPHA(*p)) 19669 ++p; 19670 return p; 19671 } 19672 19673 /* 19674 * ":function" 19675 */ 19676 void 19677 ex_function(eap) 19678 exarg_T *eap; 19679 { 19680 char_u *theline; 19681 int j; 19682 int c; 19683 int saved_did_emsg; 19684 char_u *name = NULL; 19685 char_u *p; 19686 char_u *arg; 19687 char_u *line_arg = NULL; 19688 garray_T newargs; 19689 garray_T newlines; 19690 int varargs = FALSE; 19691 int mustend = FALSE; 19692 int flags = 0; 19693 ufunc_T *fp; 19694 int indent; 19695 int nesting; 19696 char_u *skip_until = NULL; 19697 dictitem_T *v; 19698 funcdict_T fudi; 19699 static int func_nr = 0; /* number for nameless function */ 19700 int paren; 19701 hashtab_T *ht; 19702 int todo; 19703 hashitem_T *hi; 19704 int sourcing_lnum_off; 19705 19706 /* 19707 * ":function" without argument: list functions. 19708 */ 19709 if (ends_excmd(*eap->arg)) 19710 { 19711 if (!eap->skip) 19712 { 19713 todo = (int)func_hashtab.ht_used; 19714 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 19715 { 19716 if (!HASHITEM_EMPTY(hi)) 19717 { 19718 --todo; 19719 fp = HI2UF(hi); 19720 if (!isdigit(*fp->uf_name)) 19721 list_func_head(fp, FALSE); 19722 } 19723 } 19724 } 19725 eap->nextcmd = check_nextcmd(eap->arg); 19726 return; 19727 } 19728 19729 /* 19730 * ":function /pat": list functions matching pattern. 19731 */ 19732 if (*eap->arg == '/') 19733 { 19734 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 19735 if (!eap->skip) 19736 { 19737 regmatch_T regmatch; 19738 19739 c = *p; 19740 *p = NUL; 19741 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 19742 *p = c; 19743 if (regmatch.regprog != NULL) 19744 { 19745 regmatch.rm_ic = p_ic; 19746 19747 todo = (int)func_hashtab.ht_used; 19748 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 19749 { 19750 if (!HASHITEM_EMPTY(hi)) 19751 { 19752 --todo; 19753 fp = HI2UF(hi); 19754 if (!isdigit(*fp->uf_name) 19755 && vim_regexec(®match, fp->uf_name, 0)) 19756 list_func_head(fp, FALSE); 19757 } 19758 } 19759 vim_free(regmatch.regprog); 19760 } 19761 } 19762 if (*p == '/') 19763 ++p; 19764 eap->nextcmd = check_nextcmd(p); 19765 return; 19766 } 19767 19768 /* 19769 * Get the function name. There are these situations: 19770 * func normal function name 19771 * "name" == func, "fudi.fd_dict" == NULL 19772 * dict.func new dictionary entry 19773 * "name" == NULL, "fudi.fd_dict" set, 19774 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 19775 * dict.func existing dict entry with a Funcref 19776 * "name" == func, "fudi.fd_dict" set, 19777 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 19778 * dict.func existing dict entry that's not a Funcref 19779 * "name" == NULL, "fudi.fd_dict" set, 19780 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 19781 */ 19782 p = eap->arg; 19783 name = trans_function_name(&p, eap->skip, 0, &fudi); 19784 paren = (vim_strchr(p, '(') != NULL); 19785 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 19786 { 19787 /* 19788 * Return on an invalid expression in braces, unless the expression 19789 * evaluation has been cancelled due to an aborting error, an 19790 * interrupt, or an exception. 19791 */ 19792 if (!aborting()) 19793 { 19794 if (!eap->skip && fudi.fd_newkey != NULL) 19795 EMSG2(_(e_dictkey), fudi.fd_newkey); 19796 vim_free(fudi.fd_newkey); 19797 return; 19798 } 19799 else 19800 eap->skip = TRUE; 19801 } 19802 19803 /* An error in a function call during evaluation of an expression in magic 19804 * braces should not cause the function not to be defined. */ 19805 saved_did_emsg = did_emsg; 19806 did_emsg = FALSE; 19807 19808 /* 19809 * ":function func" with only function name: list function. 19810 */ 19811 if (!paren) 19812 { 19813 if (!ends_excmd(*skipwhite(p))) 19814 { 19815 EMSG(_(e_trailing)); 19816 goto ret_free; 19817 } 19818 eap->nextcmd = check_nextcmd(p); 19819 if (eap->nextcmd != NULL) 19820 *p = NUL; 19821 if (!eap->skip && !got_int) 19822 { 19823 fp = find_func(name); 19824 if (fp != NULL) 19825 { 19826 list_func_head(fp, TRUE); 19827 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 19828 { 19829 if (FUNCLINE(fp, j) == NULL) 19830 continue; 19831 msg_putchar('\n'); 19832 msg_outnum((long)(j + 1)); 19833 if (j < 9) 19834 msg_putchar(' '); 19835 if (j < 99) 19836 msg_putchar(' '); 19837 msg_prt_line(FUNCLINE(fp, j), FALSE); 19838 out_flush(); /* show a line at a time */ 19839 ui_breakcheck(); 19840 } 19841 if (!got_int) 19842 { 19843 msg_putchar('\n'); 19844 msg_puts((char_u *)" endfunction"); 19845 } 19846 } 19847 else 19848 emsg_funcname(N_("E123: Undefined function: %s"), name); 19849 } 19850 goto ret_free; 19851 } 19852 19853 /* 19854 * ":function name(arg1, arg2)" Define function. 19855 */ 19856 p = skipwhite(p); 19857 if (*p != '(') 19858 { 19859 if (!eap->skip) 19860 { 19861 EMSG2(_("E124: Missing '(': %s"), eap->arg); 19862 goto ret_free; 19863 } 19864 /* attempt to continue by skipping some text */ 19865 if (vim_strchr(p, '(') != NULL) 19866 p = vim_strchr(p, '('); 19867 } 19868 p = skipwhite(p + 1); 19869 19870 ga_init2(&newargs, (int)sizeof(char_u *), 3); 19871 ga_init2(&newlines, (int)sizeof(char_u *), 3); 19872 19873 if (!eap->skip) 19874 { 19875 /* Check the name of the function. Unless it's a dictionary function 19876 * (that we are overwriting). */ 19877 if (name != NULL) 19878 arg = name; 19879 else 19880 arg = fudi.fd_newkey; 19881 if (arg != NULL && (fudi.fd_di == NULL 19882 || fudi.fd_di->di_tv.v_type != VAR_FUNC)) 19883 { 19884 if (*arg == K_SPECIAL) 19885 j = 3; 19886 else 19887 j = 0; 19888 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 19889 : eval_isnamec(arg[j]))) 19890 ++j; 19891 if (arg[j] != NUL) 19892 emsg_funcname((char *)e_invarg2, arg); 19893 } 19894 } 19895 19896 /* 19897 * Isolate the arguments: "arg1, arg2, ...)" 19898 */ 19899 while (*p != ')') 19900 { 19901 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 19902 { 19903 varargs = TRUE; 19904 p += 3; 19905 mustend = TRUE; 19906 } 19907 else 19908 { 19909 arg = p; 19910 while (ASCII_ISALNUM(*p) || *p == '_') 19911 ++p; 19912 if (arg == p || isdigit(*arg) 19913 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 19914 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 19915 { 19916 if (!eap->skip) 19917 EMSG2(_("E125: Illegal argument: %s"), arg); 19918 break; 19919 } 19920 if (ga_grow(&newargs, 1) == FAIL) 19921 goto erret; 19922 c = *p; 19923 *p = NUL; 19924 arg = vim_strsave(arg); 19925 if (arg == NULL) 19926 goto erret; 19927 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 19928 *p = c; 19929 newargs.ga_len++; 19930 if (*p == ',') 19931 ++p; 19932 else 19933 mustend = TRUE; 19934 } 19935 p = skipwhite(p); 19936 if (mustend && *p != ')') 19937 { 19938 if (!eap->skip) 19939 EMSG2(_(e_invarg2), eap->arg); 19940 break; 19941 } 19942 } 19943 ++p; /* skip the ')' */ 19944 19945 /* find extra arguments "range", "dict" and "abort" */ 19946 for (;;) 19947 { 19948 p = skipwhite(p); 19949 if (STRNCMP(p, "range", 5) == 0) 19950 { 19951 flags |= FC_RANGE; 19952 p += 5; 19953 } 19954 else if (STRNCMP(p, "dict", 4) == 0) 19955 { 19956 flags |= FC_DICT; 19957 p += 4; 19958 } 19959 else if (STRNCMP(p, "abort", 5) == 0) 19960 { 19961 flags |= FC_ABORT; 19962 p += 5; 19963 } 19964 else 19965 break; 19966 } 19967 19968 /* When there is a line break use what follows for the function body. 19969 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 19970 if (*p == '\n') 19971 line_arg = p + 1; 19972 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 19973 EMSG(_(e_trailing)); 19974 19975 /* 19976 * Read the body of the function, until ":endfunction" is found. 19977 */ 19978 if (KeyTyped) 19979 { 19980 /* Check if the function already exists, don't let the user type the 19981 * whole function before telling him it doesn't work! For a script we 19982 * need to skip the body to be able to find what follows. */ 19983 if (!eap->skip && !eap->forceit) 19984 { 19985 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 19986 EMSG(_(e_funcdict)); 19987 else if (name != NULL && find_func(name) != NULL) 19988 emsg_funcname(e_funcexts, name); 19989 } 19990 19991 if (!eap->skip && did_emsg) 19992 goto erret; 19993 19994 msg_putchar('\n'); /* don't overwrite the function name */ 19995 cmdline_row = msg_row; 19996 } 19997 19998 indent = 2; 19999 nesting = 0; 20000 for (;;) 20001 { 20002 msg_scroll = TRUE; 20003 need_wait_return = FALSE; 20004 sourcing_lnum_off = sourcing_lnum; 20005 20006 if (line_arg != NULL) 20007 { 20008 /* Use eap->arg, split up in parts by line breaks. */ 20009 theline = line_arg; 20010 p = vim_strchr(theline, '\n'); 20011 if (p == NULL) 20012 line_arg += STRLEN(line_arg); 20013 else 20014 { 20015 *p = NUL; 20016 line_arg = p + 1; 20017 } 20018 } 20019 else if (eap->getline == NULL) 20020 theline = getcmdline(':', 0L, indent); 20021 else 20022 theline = eap->getline(':', eap->cookie, indent); 20023 if (KeyTyped) 20024 lines_left = Rows - 1; 20025 if (theline == NULL) 20026 { 20027 EMSG(_("E126: Missing :endfunction")); 20028 goto erret; 20029 } 20030 20031 /* Detect line continuation: sourcing_lnum increased more than one. */ 20032 if (sourcing_lnum > sourcing_lnum_off + 1) 20033 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 20034 else 20035 sourcing_lnum_off = 0; 20036 20037 if (skip_until != NULL) 20038 { 20039 /* between ":append" and "." and between ":python <<EOF" and "EOF" 20040 * don't check for ":endfunc". */ 20041 if (STRCMP(theline, skip_until) == 0) 20042 { 20043 vim_free(skip_until); 20044 skip_until = NULL; 20045 } 20046 } 20047 else 20048 { 20049 /* skip ':' and blanks*/ 20050 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 20051 ; 20052 20053 /* Check for "endfunction". */ 20054 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 20055 { 20056 if (line_arg == NULL) 20057 vim_free(theline); 20058 break; 20059 } 20060 20061 /* Increase indent inside "if", "while", "for" and "try", decrease 20062 * at "end". */ 20063 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 20064 indent -= 2; 20065 else if (STRNCMP(p, "if", 2) == 0 20066 || STRNCMP(p, "wh", 2) == 0 20067 || STRNCMP(p, "for", 3) == 0 20068 || STRNCMP(p, "try", 3) == 0) 20069 indent += 2; 20070 20071 /* Check for defining a function inside this function. */ 20072 if (checkforcmd(&p, "function", 2)) 20073 { 20074 if (*p == '!') 20075 p = skipwhite(p + 1); 20076 p += eval_fname_script(p); 20077 if (ASCII_ISALPHA(*p)) 20078 { 20079 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 20080 if (*skipwhite(p) == '(') 20081 { 20082 ++nesting; 20083 indent += 2; 20084 } 20085 } 20086 } 20087 20088 /* Check for ":append" or ":insert". */ 20089 p = skip_range(p, NULL); 20090 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 20091 || (p[0] == 'i' 20092 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 20093 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 20094 skip_until = vim_strsave((char_u *)"."); 20095 20096 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 20097 arg = skipwhite(skiptowhite(p)); 20098 if (arg[0] == '<' && arg[1] =='<' 20099 && ((p[0] == 'p' && p[1] == 'y' 20100 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 20101 || (p[0] == 'p' && p[1] == 'e' 20102 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 20103 || (p[0] == 't' && p[1] == 'c' 20104 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 20105 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 20106 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 20107 || (p[0] == 'm' && p[1] == 'z' 20108 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 20109 )) 20110 { 20111 /* ":python <<" continues until a dot, like ":append" */ 20112 p = skipwhite(arg + 2); 20113 if (*p == NUL) 20114 skip_until = vim_strsave((char_u *)"."); 20115 else 20116 skip_until = vim_strsave(p); 20117 } 20118 } 20119 20120 /* Add the line to the function. */ 20121 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 20122 { 20123 if (line_arg == NULL) 20124 vim_free(theline); 20125 goto erret; 20126 } 20127 20128 /* Copy the line to newly allocated memory. get_one_sourceline() 20129 * allocates 250 bytes per line, this saves 80% on average. The cost 20130 * is an extra alloc/free. */ 20131 p = vim_strsave(theline); 20132 if (p != NULL) 20133 { 20134 if (line_arg == NULL) 20135 vim_free(theline); 20136 theline = p; 20137 } 20138 20139 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 20140 20141 /* Add NULL lines for continuation lines, so that the line count is 20142 * equal to the index in the growarray. */ 20143 while (sourcing_lnum_off-- > 0) 20144 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 20145 20146 /* Check for end of eap->arg. */ 20147 if (line_arg != NULL && *line_arg == NUL) 20148 line_arg = NULL; 20149 } 20150 20151 /* Don't define the function when skipping commands or when an error was 20152 * detected. */ 20153 if (eap->skip || did_emsg) 20154 goto erret; 20155 20156 /* 20157 * If there are no errors, add the function 20158 */ 20159 if (fudi.fd_dict == NULL) 20160 { 20161 v = find_var(name, &ht); 20162 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 20163 { 20164 emsg_funcname(N_("E707: Function name conflicts with variable: %s"), 20165 name); 20166 goto erret; 20167 } 20168 20169 fp = find_func(name); 20170 if (fp != NULL) 20171 { 20172 if (!eap->forceit) 20173 { 20174 emsg_funcname(e_funcexts, name); 20175 goto erret; 20176 } 20177 if (fp->uf_calls > 0) 20178 { 20179 emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), 20180 name); 20181 goto erret; 20182 } 20183 /* redefine existing function */ 20184 ga_clear_strings(&(fp->uf_args)); 20185 ga_clear_strings(&(fp->uf_lines)); 20186 vim_free(name); 20187 name = NULL; 20188 } 20189 } 20190 else 20191 { 20192 char numbuf[20]; 20193 20194 fp = NULL; 20195 if (fudi.fd_newkey == NULL && !eap->forceit) 20196 { 20197 EMSG(_(e_funcdict)); 20198 goto erret; 20199 } 20200 if (fudi.fd_di == NULL) 20201 { 20202 /* Can't add a function to a locked dictionary */ 20203 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 20204 goto erret; 20205 } 20206 /* Can't change an existing function if it is locked */ 20207 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 20208 goto erret; 20209 20210 /* Give the function a sequential number. Can only be used with a 20211 * Funcref! */ 20212 vim_free(name); 20213 sprintf(numbuf, "%d", ++func_nr); 20214 name = vim_strsave((char_u *)numbuf); 20215 if (name == NULL) 20216 goto erret; 20217 } 20218 20219 if (fp == NULL) 20220 { 20221 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 20222 { 20223 int slen, plen; 20224 char_u *scriptname; 20225 20226 /* Check that the autoload name matches the script name. */ 20227 j = FAIL; 20228 if (sourcing_name != NULL) 20229 { 20230 scriptname = autoload_name(name); 20231 if (scriptname != NULL) 20232 { 20233 p = vim_strchr(scriptname, '/'); 20234 plen = (int)STRLEN(p); 20235 slen = (int)STRLEN(sourcing_name); 20236 if (slen > plen && fnamecmp(p, 20237 sourcing_name + slen - plen) == 0) 20238 j = OK; 20239 vim_free(scriptname); 20240 } 20241 } 20242 if (j == FAIL) 20243 { 20244 EMSG2(_("E746: Function name does not match script file name: %s"), name); 20245 goto erret; 20246 } 20247 } 20248 20249 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 20250 if (fp == NULL) 20251 goto erret; 20252 20253 if (fudi.fd_dict != NULL) 20254 { 20255 if (fudi.fd_di == NULL) 20256 { 20257 /* add new dict entry */ 20258 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 20259 if (fudi.fd_di == NULL) 20260 { 20261 vim_free(fp); 20262 goto erret; 20263 } 20264 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 20265 { 20266 vim_free(fudi.fd_di); 20267 vim_free(fp); 20268 goto erret; 20269 } 20270 } 20271 else 20272 /* overwrite existing dict entry */ 20273 clear_tv(&fudi.fd_di->di_tv); 20274 fudi.fd_di->di_tv.v_type = VAR_FUNC; 20275 fudi.fd_di->di_tv.v_lock = 0; 20276 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 20277 fp->uf_refcount = 1; 20278 20279 /* behave like "dict" was used */ 20280 flags |= FC_DICT; 20281 } 20282 20283 /* insert the new function in the function list */ 20284 STRCPY(fp->uf_name, name); 20285 hash_add(&func_hashtab, UF2HIKEY(fp)); 20286 } 20287 fp->uf_args = newargs; 20288 fp->uf_lines = newlines; 20289 #ifdef FEAT_PROFILE 20290 fp->uf_tml_count = NULL; 20291 fp->uf_tml_total = NULL; 20292 fp->uf_tml_self = NULL; 20293 fp->uf_profiling = FALSE; 20294 if (prof_def_func()) 20295 func_do_profile(fp); 20296 #endif 20297 fp->uf_varargs = varargs; 20298 fp->uf_flags = flags; 20299 fp->uf_calls = 0; 20300 fp->uf_script_ID = current_SID; 20301 goto ret_free; 20302 20303 erret: 20304 ga_clear_strings(&newargs); 20305 ga_clear_strings(&newlines); 20306 ret_free: 20307 vim_free(skip_until); 20308 vim_free(fudi.fd_newkey); 20309 vim_free(name); 20310 did_emsg |= saved_did_emsg; 20311 } 20312 20313 /* 20314 * Get a function name, translating "<SID>" and "<SNR>". 20315 * Also handles a Funcref in a List or Dictionary. 20316 * Returns the function name in allocated memory, or NULL for failure. 20317 * flags: 20318 * TFN_INT: internal function name OK 20319 * TFN_QUIET: be quiet 20320 * Advances "pp" to just after the function name (if no error). 20321 */ 20322 static char_u * 20323 trans_function_name(pp, skip, flags, fdp) 20324 char_u **pp; 20325 int skip; /* only find the end, don't evaluate */ 20326 int flags; 20327 funcdict_T *fdp; /* return: info about dictionary used */ 20328 { 20329 char_u *name = NULL; 20330 char_u *start; 20331 char_u *end; 20332 int lead; 20333 char_u sid_buf[20]; 20334 int len; 20335 lval_T lv; 20336 20337 if (fdp != NULL) 20338 vim_memset(fdp, 0, sizeof(funcdict_T)); 20339 start = *pp; 20340 20341 /* Check for hard coded <SNR>: already translated function ID (from a user 20342 * command). */ 20343 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 20344 && (*pp)[2] == (int)KE_SNR) 20345 { 20346 *pp += 3; 20347 len = get_id_len(pp) + 3; 20348 return vim_strnsave(start, len); 20349 } 20350 20351 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 20352 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 20353 lead = eval_fname_script(start); 20354 if (lead > 2) 20355 start += lead; 20356 20357 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 20358 lead > 2 ? 0 : FNE_CHECK_START); 20359 if (end == start) 20360 { 20361 if (!skip) 20362 EMSG(_("E129: Function name required")); 20363 goto theend; 20364 } 20365 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 20366 { 20367 /* 20368 * Report an invalid expression in braces, unless the expression 20369 * evaluation has been cancelled due to an aborting error, an 20370 * interrupt, or an exception. 20371 */ 20372 if (!aborting()) 20373 { 20374 if (end != NULL) 20375 EMSG2(_(e_invarg2), start); 20376 } 20377 else 20378 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 20379 goto theend; 20380 } 20381 20382 if (lv.ll_tv != NULL) 20383 { 20384 if (fdp != NULL) 20385 { 20386 fdp->fd_dict = lv.ll_dict; 20387 fdp->fd_newkey = lv.ll_newkey; 20388 lv.ll_newkey = NULL; 20389 fdp->fd_di = lv.ll_di; 20390 } 20391 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 20392 { 20393 name = vim_strsave(lv.ll_tv->vval.v_string); 20394 *pp = end; 20395 } 20396 else 20397 { 20398 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 20399 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 20400 EMSG(_(e_funcref)); 20401 else 20402 *pp = end; 20403 name = NULL; 20404 } 20405 goto theend; 20406 } 20407 20408 if (lv.ll_name == NULL) 20409 { 20410 /* Error found, but continue after the function name. */ 20411 *pp = end; 20412 goto theend; 20413 } 20414 20415 /* Check if the name is a Funcref. If so, use the value. */ 20416 if (lv.ll_exp_name != NULL) 20417 { 20418 len = (int)STRLEN(lv.ll_exp_name); 20419 name = deref_func_name(lv.ll_exp_name, &len); 20420 if (name == lv.ll_exp_name) 20421 name = NULL; 20422 } 20423 else 20424 { 20425 len = (int)(end - *pp); 20426 name = deref_func_name(*pp, &len); 20427 if (name == *pp) 20428 name = NULL; 20429 } 20430 if (name != NULL) 20431 { 20432 name = vim_strsave(name); 20433 *pp = end; 20434 goto theend; 20435 } 20436 20437 if (lv.ll_exp_name != NULL) 20438 { 20439 len = (int)STRLEN(lv.ll_exp_name); 20440 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 20441 && STRNCMP(lv.ll_name, "s:", 2) == 0) 20442 { 20443 /* When there was "s:" already or the name expanded to get a 20444 * leading "s:" then remove it. */ 20445 lv.ll_name += 2; 20446 len -= 2; 20447 lead = 2; 20448 } 20449 } 20450 else 20451 { 20452 if (lead == 2) /* skip over "s:" */ 20453 lv.ll_name += 2; 20454 len = (int)(end - lv.ll_name); 20455 } 20456 20457 /* 20458 * Copy the function name to allocated memory. 20459 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 20460 * Accept <SNR>123_name() outside a script. 20461 */ 20462 if (skip) 20463 lead = 0; /* do nothing */ 20464 else if (lead > 0) 20465 { 20466 lead = 3; 20467 if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) 20468 || eval_fname_sid(*pp)) 20469 { 20470 /* It's "s:" or "<SID>" */ 20471 if (current_SID <= 0) 20472 { 20473 EMSG(_(e_usingsid)); 20474 goto theend; 20475 } 20476 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 20477 lead += (int)STRLEN(sid_buf); 20478 } 20479 } 20480 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 20481 { 20482 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 20483 goto theend; 20484 } 20485 name = alloc((unsigned)(len + lead + 1)); 20486 if (name != NULL) 20487 { 20488 if (lead > 0) 20489 { 20490 name[0] = K_SPECIAL; 20491 name[1] = KS_EXTRA; 20492 name[2] = (int)KE_SNR; 20493 if (lead > 3) /* If it's "<SID>" */ 20494 STRCPY(name + 3, sid_buf); 20495 } 20496 mch_memmove(name + lead, lv.ll_name, (size_t)len); 20497 name[len + lead] = NUL; 20498 } 20499 *pp = end; 20500 20501 theend: 20502 clear_lval(&lv); 20503 return name; 20504 } 20505 20506 /* 20507 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 20508 * Return 2 if "p" starts with "s:". 20509 * Return 0 otherwise. 20510 */ 20511 static int 20512 eval_fname_script(p) 20513 char_u *p; 20514 { 20515 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 20516 || STRNICMP(p + 1, "SNR>", 4) == 0)) 20517 return 5; 20518 if (p[0] == 's' && p[1] == ':') 20519 return 2; 20520 return 0; 20521 } 20522 20523 /* 20524 * Return TRUE if "p" starts with "<SID>" or "s:". 20525 * Only works if eval_fname_script() returned non-zero for "p"! 20526 */ 20527 static int 20528 eval_fname_sid(p) 20529 char_u *p; 20530 { 20531 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 20532 } 20533 20534 /* 20535 * List the head of the function: "name(arg1, arg2)". 20536 */ 20537 static void 20538 list_func_head(fp, indent) 20539 ufunc_T *fp; 20540 int indent; 20541 { 20542 int j; 20543 20544 msg_start(); 20545 if (indent) 20546 MSG_PUTS(" "); 20547 MSG_PUTS("function "); 20548 if (fp->uf_name[0] == K_SPECIAL) 20549 { 20550 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 20551 msg_puts(fp->uf_name + 3); 20552 } 20553 else 20554 msg_puts(fp->uf_name); 20555 msg_putchar('('); 20556 for (j = 0; j < fp->uf_args.ga_len; ++j) 20557 { 20558 if (j) 20559 MSG_PUTS(", "); 20560 msg_puts(FUNCARG(fp, j)); 20561 } 20562 if (fp->uf_varargs) 20563 { 20564 if (j) 20565 MSG_PUTS(", "); 20566 MSG_PUTS("..."); 20567 } 20568 msg_putchar(')'); 20569 msg_clr_eos(); 20570 if (p_verbose > 0) 20571 last_set_msg(fp->uf_script_ID); 20572 } 20573 20574 /* 20575 * Find a function by name, return pointer to it in ufuncs. 20576 * Return NULL for unknown function. 20577 */ 20578 static ufunc_T * 20579 find_func(name) 20580 char_u *name; 20581 { 20582 hashitem_T *hi; 20583 20584 hi = hash_find(&func_hashtab, name); 20585 if (!HASHITEM_EMPTY(hi)) 20586 return HI2UF(hi); 20587 return NULL; 20588 } 20589 20590 #if defined(EXITFREE) || defined(PROTO) 20591 void 20592 free_all_functions() 20593 { 20594 hashitem_T *hi; 20595 20596 /* Need to start all over every time, because func_free() may change the 20597 * hash table. */ 20598 while (func_hashtab.ht_used > 0) 20599 for (hi = func_hashtab.ht_array; ; ++hi) 20600 if (!HASHITEM_EMPTY(hi)) 20601 { 20602 func_free(HI2UF(hi)); 20603 break; 20604 } 20605 } 20606 #endif 20607 20608 /* 20609 * Return TRUE if a function "name" exists. 20610 */ 20611 static int 20612 function_exists(name) 20613 char_u *name; 20614 { 20615 char_u *nm = name; 20616 char_u *p; 20617 int n = FALSE; 20618 20619 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL); 20620 nm = skipwhite(nm); 20621 20622 /* Only accept "funcname", "funcname ", "funcname (..." and 20623 * "funcname(...", not "funcname!...". */ 20624 if (p != NULL && (*nm == NUL || *nm == '(')) 20625 { 20626 if (builtin_function(p)) 20627 n = (find_internal_func(p) >= 0); 20628 else 20629 n = (find_func(p) != NULL); 20630 } 20631 vim_free(p); 20632 return n; 20633 } 20634 20635 /* 20636 * Return TRUE if "name" looks like a builtin function name: starts with a 20637 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 20638 */ 20639 static int 20640 builtin_function(name) 20641 char_u *name; 20642 { 20643 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 20644 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 20645 } 20646 20647 #if defined(FEAT_PROFILE) || defined(PROTO) 20648 /* 20649 * Start profiling function "fp". 20650 */ 20651 static void 20652 func_do_profile(fp) 20653 ufunc_T *fp; 20654 { 20655 fp->uf_tm_count = 0; 20656 profile_zero(&fp->uf_tm_self); 20657 profile_zero(&fp->uf_tm_total); 20658 if (fp->uf_tml_count == NULL) 20659 fp->uf_tml_count = (int *)alloc_clear((unsigned) 20660 (sizeof(int) * fp->uf_lines.ga_len)); 20661 if (fp->uf_tml_total == NULL) 20662 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 20663 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 20664 if (fp->uf_tml_self == NULL) 20665 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 20666 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 20667 fp->uf_tml_idx = -1; 20668 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 20669 || fp->uf_tml_self == NULL) 20670 return; /* out of memory */ 20671 20672 fp->uf_profiling = TRUE; 20673 } 20674 20675 /* 20676 * Dump the profiling results for all functions in file "fd". 20677 */ 20678 void 20679 func_dump_profile(fd) 20680 FILE *fd; 20681 { 20682 hashitem_T *hi; 20683 int todo; 20684 ufunc_T *fp; 20685 int i; 20686 ufunc_T **sorttab; 20687 int st_len = 0; 20688 20689 todo = (int)func_hashtab.ht_used; 20690 if (todo == 0) 20691 return; /* nothing to dump */ 20692 20693 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 20694 20695 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 20696 { 20697 if (!HASHITEM_EMPTY(hi)) 20698 { 20699 --todo; 20700 fp = HI2UF(hi); 20701 if (fp->uf_profiling) 20702 { 20703 if (sorttab != NULL) 20704 sorttab[st_len++] = fp; 20705 20706 if (fp->uf_name[0] == K_SPECIAL) 20707 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 20708 else 20709 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 20710 if (fp->uf_tm_count == 1) 20711 fprintf(fd, "Called 1 time\n"); 20712 else 20713 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 20714 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 20715 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 20716 fprintf(fd, "\n"); 20717 fprintf(fd, "count total (s) self (s)\n"); 20718 20719 for (i = 0; i < fp->uf_lines.ga_len; ++i) 20720 { 20721 if (FUNCLINE(fp, i) == NULL) 20722 continue; 20723 prof_func_line(fd, fp->uf_tml_count[i], 20724 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 20725 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 20726 } 20727 fprintf(fd, "\n"); 20728 } 20729 } 20730 } 20731 20732 if (sorttab != NULL && st_len > 0) 20733 { 20734 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 20735 prof_total_cmp); 20736 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 20737 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 20738 prof_self_cmp); 20739 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 20740 } 20741 20742 vim_free(sorttab); 20743 } 20744 20745 static void 20746 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 20747 FILE *fd; 20748 ufunc_T **sorttab; 20749 int st_len; 20750 char *title; 20751 int prefer_self; /* when equal print only self time */ 20752 { 20753 int i; 20754 ufunc_T *fp; 20755 20756 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 20757 fprintf(fd, "count total (s) self (s) function\n"); 20758 for (i = 0; i < 20 && i < st_len; ++i) 20759 { 20760 fp = sorttab[i]; 20761 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 20762 prefer_self); 20763 if (fp->uf_name[0] == K_SPECIAL) 20764 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 20765 else 20766 fprintf(fd, " %s()\n", fp->uf_name); 20767 } 20768 fprintf(fd, "\n"); 20769 } 20770 20771 /* 20772 * Print the count and times for one function or function line. 20773 */ 20774 static void 20775 prof_func_line(fd, count, total, self, prefer_self) 20776 FILE *fd; 20777 int count; 20778 proftime_T *total; 20779 proftime_T *self; 20780 int prefer_self; /* when equal print only self time */ 20781 { 20782 if (count > 0) 20783 { 20784 fprintf(fd, "%5d ", count); 20785 if (prefer_self && profile_equal(total, self)) 20786 fprintf(fd, " "); 20787 else 20788 fprintf(fd, "%s ", profile_msg(total)); 20789 if (!prefer_self && profile_equal(total, self)) 20790 fprintf(fd, " "); 20791 else 20792 fprintf(fd, "%s ", profile_msg(self)); 20793 } 20794 else 20795 fprintf(fd, " "); 20796 } 20797 20798 /* 20799 * Compare function for total time sorting. 20800 */ 20801 static int 20802 #ifdef __BORLANDC__ 20803 _RTLENTRYF 20804 #endif 20805 prof_total_cmp(s1, s2) 20806 const void *s1; 20807 const void *s2; 20808 { 20809 ufunc_T *p1, *p2; 20810 20811 p1 = *(ufunc_T **)s1; 20812 p2 = *(ufunc_T **)s2; 20813 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 20814 } 20815 20816 /* 20817 * Compare function for self time sorting. 20818 */ 20819 static int 20820 #ifdef __BORLANDC__ 20821 _RTLENTRYF 20822 #endif 20823 prof_self_cmp(s1, s2) 20824 const void *s1; 20825 const void *s2; 20826 { 20827 ufunc_T *p1, *p2; 20828 20829 p1 = *(ufunc_T **)s1; 20830 p2 = *(ufunc_T **)s2; 20831 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 20832 } 20833 20834 #endif 20835 20836 /* 20837 * If "name" has a package name try autoloading the script for it. 20838 * Return TRUE if a package was loaded. 20839 */ 20840 static int 20841 script_autoload(name, reload) 20842 char_u *name; 20843 int reload; /* load script again when already loaded */ 20844 { 20845 char_u *p; 20846 char_u *scriptname, *tofree; 20847 int ret = FALSE; 20848 int i; 20849 20850 /* If there is no '#' after name[0] there is no package name. */ 20851 p = vim_strchr(name, AUTOLOAD_CHAR); 20852 if (p == NULL || p == name) 20853 return FALSE; 20854 20855 tofree = scriptname = autoload_name(name); 20856 20857 /* Find the name in the list of previously loaded package names. Skip 20858 * "autoload/", it's always the same. */ 20859 for (i = 0; i < ga_loaded.ga_len; ++i) 20860 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 20861 break; 20862 if (!reload && i < ga_loaded.ga_len) 20863 ret = FALSE; /* was loaded already */ 20864 else 20865 { 20866 /* Remember the name if it wasn't loaded already. */ 20867 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 20868 { 20869 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 20870 tofree = NULL; 20871 } 20872 20873 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 20874 if (source_runtime(scriptname, FALSE) == OK) 20875 ret = TRUE; 20876 } 20877 20878 vim_free(tofree); 20879 return ret; 20880 } 20881 20882 /* 20883 * Return the autoload script name for a function or variable name. 20884 * Returns NULL when out of memory. 20885 */ 20886 static char_u * 20887 autoload_name(name) 20888 char_u *name; 20889 { 20890 char_u *p; 20891 char_u *scriptname; 20892 20893 /* Get the script file name: replace '#' with '/', append ".vim". */ 20894 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 20895 if (scriptname == NULL) 20896 return FALSE; 20897 STRCPY(scriptname, "autoload/"); 20898 STRCAT(scriptname, name); 20899 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 20900 STRCAT(scriptname, ".vim"); 20901 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 20902 *p = '/'; 20903 return scriptname; 20904 } 20905 20906 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 20907 20908 /* 20909 * Function given to ExpandGeneric() to obtain the list of user defined 20910 * function names. 20911 */ 20912 char_u * 20913 get_user_func_name(xp, idx) 20914 expand_T *xp; 20915 int idx; 20916 { 20917 static long_u done; 20918 static hashitem_T *hi; 20919 ufunc_T *fp; 20920 20921 if (idx == 0) 20922 { 20923 done = 0; 20924 hi = func_hashtab.ht_array; 20925 } 20926 if (done < func_hashtab.ht_used) 20927 { 20928 if (done++ > 0) 20929 ++hi; 20930 while (HASHITEM_EMPTY(hi)) 20931 ++hi; 20932 fp = HI2UF(hi); 20933 20934 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 20935 return fp->uf_name; /* prevents overflow */ 20936 20937 cat_func_name(IObuff, fp); 20938 if (xp->xp_context != EXPAND_USER_FUNC) 20939 { 20940 STRCAT(IObuff, "("); 20941 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 20942 STRCAT(IObuff, ")"); 20943 } 20944 return IObuff; 20945 } 20946 return NULL; 20947 } 20948 20949 #endif /* FEAT_CMDL_COMPL */ 20950 20951 /* 20952 * Copy the function name of "fp" to buffer "buf". 20953 * "buf" must be able to hold the function name plus three bytes. 20954 * Takes care of script-local function names. 20955 */ 20956 static void 20957 cat_func_name(buf, fp) 20958 char_u *buf; 20959 ufunc_T *fp; 20960 { 20961 if (fp->uf_name[0] == K_SPECIAL) 20962 { 20963 STRCPY(buf, "<SNR>"); 20964 STRCAT(buf, fp->uf_name + 3); 20965 } 20966 else 20967 STRCPY(buf, fp->uf_name); 20968 } 20969 20970 /* 20971 * ":delfunction {name}" 20972 */ 20973 void 20974 ex_delfunction(eap) 20975 exarg_T *eap; 20976 { 20977 ufunc_T *fp = NULL; 20978 char_u *p; 20979 char_u *name; 20980 funcdict_T fudi; 20981 20982 p = eap->arg; 20983 name = trans_function_name(&p, eap->skip, 0, &fudi); 20984 vim_free(fudi.fd_newkey); 20985 if (name == NULL) 20986 { 20987 if (fudi.fd_dict != NULL && !eap->skip) 20988 EMSG(_(e_funcref)); 20989 return; 20990 } 20991 if (!ends_excmd(*skipwhite(p))) 20992 { 20993 vim_free(name); 20994 EMSG(_(e_trailing)); 20995 return; 20996 } 20997 eap->nextcmd = check_nextcmd(p); 20998 if (eap->nextcmd != NULL) 20999 *p = NUL; 21000 21001 if (!eap->skip) 21002 fp = find_func(name); 21003 vim_free(name); 21004 21005 if (!eap->skip) 21006 { 21007 if (fp == NULL) 21008 { 21009 EMSG2(_(e_nofunc), eap->arg); 21010 return; 21011 } 21012 if (fp->uf_calls > 0) 21013 { 21014 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 21015 return; 21016 } 21017 21018 if (fudi.fd_dict != NULL) 21019 { 21020 /* Delete the dict item that refers to the function, it will 21021 * invoke func_unref() and possibly delete the function. */ 21022 dictitem_remove(fudi.fd_dict, fudi.fd_di); 21023 } 21024 else 21025 func_free(fp); 21026 } 21027 } 21028 21029 /* 21030 * Free a function and remove it from the list of functions. 21031 */ 21032 static void 21033 func_free(fp) 21034 ufunc_T *fp; 21035 { 21036 hashitem_T *hi; 21037 21038 /* clear this function */ 21039 ga_clear_strings(&(fp->uf_args)); 21040 ga_clear_strings(&(fp->uf_lines)); 21041 #ifdef FEAT_PROFILE 21042 vim_free(fp->uf_tml_count); 21043 vim_free(fp->uf_tml_total); 21044 vim_free(fp->uf_tml_self); 21045 #endif 21046 21047 /* remove the function from the function hashtable */ 21048 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 21049 if (HASHITEM_EMPTY(hi)) 21050 EMSG2(_(e_intern2), "func_free()"); 21051 else 21052 hash_remove(&func_hashtab, hi); 21053 21054 vim_free(fp); 21055 } 21056 21057 /* 21058 * Unreference a Function: decrement the reference count and free it when it 21059 * becomes zero. Only for numbered functions. 21060 */ 21061 static void 21062 func_unref(name) 21063 char_u *name; 21064 { 21065 ufunc_T *fp; 21066 21067 if (name != NULL && isdigit(*name)) 21068 { 21069 fp = find_func(name); 21070 if (fp == NULL) 21071 EMSG2(_(e_intern2), "func_unref()"); 21072 else if (--fp->uf_refcount <= 0) 21073 { 21074 /* Only delete it when it's not being used. Otherwise it's done 21075 * when "uf_calls" becomes zero. */ 21076 if (fp->uf_calls == 0) 21077 func_free(fp); 21078 } 21079 } 21080 } 21081 21082 /* 21083 * Count a reference to a Function. 21084 */ 21085 static void 21086 func_ref(name) 21087 char_u *name; 21088 { 21089 ufunc_T *fp; 21090 21091 if (name != NULL && isdigit(*name)) 21092 { 21093 fp = find_func(name); 21094 if (fp == NULL) 21095 EMSG2(_(e_intern2), "func_ref()"); 21096 else 21097 ++fp->uf_refcount; 21098 } 21099 } 21100 21101 /* 21102 * Call a user function. 21103 */ 21104 static void 21105 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 21106 ufunc_T *fp; /* pointer to function */ 21107 int argcount; /* nr of args */ 21108 typval_T *argvars; /* arguments */ 21109 typval_T *rettv; /* return value */ 21110 linenr_T firstline; /* first line of range */ 21111 linenr_T lastline; /* last line of range */ 21112 dict_T *selfdict; /* Dictionary for "self" */ 21113 { 21114 char_u *save_sourcing_name; 21115 linenr_T save_sourcing_lnum; 21116 scid_T save_current_SID; 21117 funccall_T *fc; 21118 int save_did_emsg; 21119 static int depth = 0; 21120 dictitem_T *v; 21121 int fixvar_idx = 0; /* index in fixvar[] */ 21122 int i; 21123 int ai; 21124 char_u numbuf[NUMBUFLEN]; 21125 char_u *name; 21126 #ifdef FEAT_PROFILE 21127 proftime_T wait_start; 21128 proftime_T call_start; 21129 #endif 21130 21131 /* If depth of calling is getting too high, don't execute the function */ 21132 if (depth >= p_mfd) 21133 { 21134 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 21135 rettv->v_type = VAR_NUMBER; 21136 rettv->vval.v_number = -1; 21137 return; 21138 } 21139 ++depth; 21140 21141 line_breakcheck(); /* check for CTRL-C hit */ 21142 21143 fc = (funccall_T *)alloc(sizeof(funccall_T)); 21144 fc->caller = current_funccal; 21145 current_funccal = fc; 21146 fc->func = fp; 21147 fc->rettv = rettv; 21148 rettv->vval.v_number = 0; 21149 fc->linenr = 0; 21150 fc->returned = FALSE; 21151 fc->level = ex_nesting_level; 21152 /* Check if this function has a breakpoint. */ 21153 fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 21154 fc->dbg_tick = debug_tick; 21155 21156 /* 21157 * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables 21158 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 21159 * each argument variable and saves a lot of time. 21160 */ 21161 /* 21162 * Init l: variables. 21163 */ 21164 init_var_dict(&fc->l_vars, &fc->l_vars_var); 21165 if (selfdict != NULL) 21166 { 21167 /* Set l:self to "selfdict". Use "name" to avoid a warning from 21168 * some compiler that checks the destination size. */ 21169 v = &fc->fixvar[fixvar_idx++].var; 21170 name = v->di_key; 21171 STRCPY(name, "self"); 21172 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 21173 hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); 21174 v->di_tv.v_type = VAR_DICT; 21175 v->di_tv.v_lock = 0; 21176 v->di_tv.vval.v_dict = selfdict; 21177 ++selfdict->dv_refcount; 21178 } 21179 21180 /* 21181 * Init a: variables. 21182 * Set a:0 to "argcount". 21183 * Set a:000 to a list with room for the "..." arguments. 21184 */ 21185 init_var_dict(&fc->l_avars, &fc->l_avars_var); 21186 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", 21187 (varnumber_T)(argcount - fp->uf_args.ga_len)); 21188 /* Use "name" to avoid a warning from some compiler that checks the 21189 * destination size. */ 21190 v = &fc->fixvar[fixvar_idx++].var; 21191 name = v->di_key; 21192 STRCPY(name, "000"); 21193 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21194 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 21195 v->di_tv.v_type = VAR_LIST; 21196 v->di_tv.v_lock = VAR_FIXED; 21197 v->di_tv.vval.v_list = &fc->l_varlist; 21198 vim_memset(&fc->l_varlist, 0, sizeof(list_T)); 21199 fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT; 21200 fc->l_varlist.lv_lock = VAR_FIXED; 21201 21202 /* 21203 * Set a:firstline to "firstline" and a:lastline to "lastline". 21204 * Set a:name to named arguments. 21205 * Set a:N to the "..." arguments. 21206 */ 21207 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", 21208 (varnumber_T)firstline); 21209 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", 21210 (varnumber_T)lastline); 21211 for (i = 0; i < argcount; ++i) 21212 { 21213 ai = i - fp->uf_args.ga_len; 21214 if (ai < 0) 21215 /* named argument a:name */ 21216 name = FUNCARG(fp, i); 21217 else 21218 { 21219 /* "..." argument a:1, a:2, etc. */ 21220 sprintf((char *)numbuf, "%d", ai + 1); 21221 name = numbuf; 21222 } 21223 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 21224 { 21225 v = &fc->fixvar[fixvar_idx++].var; 21226 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21227 } 21228 else 21229 { 21230 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 21231 + STRLEN(name))); 21232 if (v == NULL) 21233 break; 21234 v->di_flags = DI_FLAGS_RO; 21235 } 21236 STRCPY(v->di_key, name); 21237 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 21238 21239 /* Note: the values are copied directly to avoid alloc/free. 21240 * "argvars" must have VAR_FIXED for v_lock. */ 21241 v->di_tv = argvars[i]; 21242 v->di_tv.v_lock = VAR_FIXED; 21243 21244 if (ai >= 0 && ai < MAX_FUNC_ARGS) 21245 { 21246 list_append(&fc->l_varlist, &fc->l_listitems[ai]); 21247 fc->l_listitems[ai].li_tv = argvars[i]; 21248 fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED; 21249 } 21250 } 21251 21252 /* Don't redraw while executing the function. */ 21253 ++RedrawingDisabled; 21254 save_sourcing_name = sourcing_name; 21255 save_sourcing_lnum = sourcing_lnum; 21256 sourcing_lnum = 1; 21257 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 21258 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 21259 if (sourcing_name != NULL) 21260 { 21261 if (save_sourcing_name != NULL 21262 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 21263 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 21264 else 21265 STRCPY(sourcing_name, "function "); 21266 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 21267 21268 if (p_verbose >= 12) 21269 { 21270 ++no_wait_return; 21271 verbose_enter_scroll(); 21272 21273 smsg((char_u *)_("calling %s"), sourcing_name); 21274 if (p_verbose >= 14) 21275 { 21276 char_u buf[MSG_BUF_LEN]; 21277 char_u numbuf2[NUMBUFLEN]; 21278 char_u *tofree; 21279 char_u *s; 21280 21281 msg_puts((char_u *)"("); 21282 for (i = 0; i < argcount; ++i) 21283 { 21284 if (i > 0) 21285 msg_puts((char_u *)", "); 21286 if (argvars[i].v_type == VAR_NUMBER) 21287 msg_outnum((long)argvars[i].vval.v_number); 21288 else 21289 { 21290 s = tv2string(&argvars[i], &tofree, numbuf2, 0); 21291 if (s != NULL) 21292 { 21293 trunc_string(s, buf, MSG_BUF_CLEN); 21294 msg_puts(buf); 21295 vim_free(tofree); 21296 } 21297 } 21298 } 21299 msg_puts((char_u *)")"); 21300 } 21301 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 21302 21303 verbose_leave_scroll(); 21304 --no_wait_return; 21305 } 21306 } 21307 #ifdef FEAT_PROFILE 21308 if (do_profiling == PROF_YES) 21309 { 21310 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 21311 func_do_profile(fp); 21312 if (fp->uf_profiling 21313 || (fc->caller != NULL && fc->caller->func->uf_profiling)) 21314 { 21315 ++fp->uf_tm_count; 21316 profile_start(&call_start); 21317 profile_zero(&fp->uf_tm_children); 21318 } 21319 script_prof_save(&wait_start); 21320 } 21321 #endif 21322 21323 save_current_SID = current_SID; 21324 current_SID = fp->uf_script_ID; 21325 save_did_emsg = did_emsg; 21326 did_emsg = FALSE; 21327 21328 /* call do_cmdline() to execute the lines */ 21329 do_cmdline(NULL, get_func_line, (void *)fc, 21330 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 21331 21332 --RedrawingDisabled; 21333 21334 /* when the function was aborted because of an error, return -1 */ 21335 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 21336 { 21337 clear_tv(rettv); 21338 rettv->v_type = VAR_NUMBER; 21339 rettv->vval.v_number = -1; 21340 } 21341 21342 #ifdef FEAT_PROFILE 21343 if (do_profiling == PROF_YES && (fp->uf_profiling 21344 || (fc->caller != NULL && fc->caller->func->uf_profiling))) 21345 { 21346 profile_end(&call_start); 21347 profile_sub_wait(&wait_start, &call_start); 21348 profile_add(&fp->uf_tm_total, &call_start); 21349 profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); 21350 if (fc->caller != NULL && fc->caller->func->uf_profiling) 21351 { 21352 profile_add(&fc->caller->func->uf_tm_children, &call_start); 21353 profile_add(&fc->caller->func->uf_tml_children, &call_start); 21354 } 21355 } 21356 #endif 21357 21358 /* when being verbose, mention the return value */ 21359 if (p_verbose >= 12) 21360 { 21361 ++no_wait_return; 21362 verbose_enter_scroll(); 21363 21364 if (aborting()) 21365 smsg((char_u *)_("%s aborted"), sourcing_name); 21366 else if (fc->rettv->v_type == VAR_NUMBER) 21367 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 21368 (long)fc->rettv->vval.v_number); 21369 else 21370 { 21371 char_u buf[MSG_BUF_LEN]; 21372 char_u numbuf2[NUMBUFLEN]; 21373 char_u *tofree; 21374 char_u *s; 21375 21376 /* The value may be very long. Skip the middle part, so that we 21377 * have some idea how it starts and ends. smsg() would always 21378 * truncate it at the end. */ 21379 s = tv2string(fc->rettv, &tofree, numbuf2, 0); 21380 if (s != NULL) 21381 { 21382 trunc_string(s, buf, MSG_BUF_CLEN); 21383 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 21384 vim_free(tofree); 21385 } 21386 } 21387 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 21388 21389 verbose_leave_scroll(); 21390 --no_wait_return; 21391 } 21392 21393 vim_free(sourcing_name); 21394 sourcing_name = save_sourcing_name; 21395 sourcing_lnum = save_sourcing_lnum; 21396 current_SID = save_current_SID; 21397 #ifdef FEAT_PROFILE 21398 if (do_profiling == PROF_YES) 21399 script_prof_restore(&wait_start); 21400 #endif 21401 21402 if (p_verbose >= 12 && sourcing_name != NULL) 21403 { 21404 ++no_wait_return; 21405 verbose_enter_scroll(); 21406 21407 smsg((char_u *)_("continuing in %s"), sourcing_name); 21408 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 21409 21410 verbose_leave_scroll(); 21411 --no_wait_return; 21412 } 21413 21414 did_emsg |= save_did_emsg; 21415 current_funccal = fc->caller; 21416 --depth; 21417 21418 /* If the a:000 list and the l: and a: dicts are not referenced we can 21419 * free the funccall_T and what's in it. */ 21420 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT 21421 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT 21422 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) 21423 { 21424 free_funccal(fc, FALSE); 21425 } 21426 else 21427 { 21428 hashitem_T *hi; 21429 listitem_T *li; 21430 int todo; 21431 21432 /* "fc" is still in use. This can happen when returning "a:000" or 21433 * assigning "l:" to a global variable. 21434 * Link "fc" in the list for garbage collection later. */ 21435 fc->caller = previous_funccal; 21436 previous_funccal = fc; 21437 21438 /* Make a copy of the a: variables, since we didn't do that above. */ 21439 todo = (int)fc->l_avars.dv_hashtab.ht_used; 21440 for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) 21441 { 21442 if (!HASHITEM_EMPTY(hi)) 21443 { 21444 --todo; 21445 v = HI2DI(hi); 21446 copy_tv(&v->di_tv, &v->di_tv); 21447 } 21448 } 21449 21450 /* Make a copy of the a:000 items, since we didn't do that above. */ 21451 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 21452 copy_tv(&li->li_tv, &li->li_tv); 21453 } 21454 } 21455 21456 /* 21457 * Return TRUE if items in "fc" do not have "copyID". That means they are not 21458 * referenced from anywhere that is in use. 21459 */ 21460 static int 21461 can_free_funccal(fc, copyID) 21462 funccall_T *fc; 21463 int copyID; 21464 { 21465 return (fc->l_varlist.lv_copyID != copyID 21466 && fc->l_vars.dv_copyID != copyID 21467 && fc->l_avars.dv_copyID != copyID); 21468 } 21469 21470 /* 21471 * Free "fc" and what it contains. 21472 */ 21473 static void 21474 free_funccal(fc, free_val) 21475 funccall_T *fc; 21476 int free_val; /* a: vars were allocated */ 21477 { 21478 listitem_T *li; 21479 21480 /* The a: variables typevals may not have been allocated, only free the 21481 * allocated variables. */ 21482 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); 21483 21484 /* free all l: variables */ 21485 vars_clear(&fc->l_vars.dv_hashtab); 21486 21487 /* Free the a:000 variables if they were allocated. */ 21488 if (free_val) 21489 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 21490 clear_tv(&li->li_tv); 21491 21492 vim_free(fc); 21493 } 21494 21495 /* 21496 * Add a number variable "name" to dict "dp" with value "nr". 21497 */ 21498 static void 21499 add_nr_var(dp, v, name, nr) 21500 dict_T *dp; 21501 dictitem_T *v; 21502 char *name; 21503 varnumber_T nr; 21504 { 21505 STRCPY(v->di_key, name); 21506 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21507 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 21508 v->di_tv.v_type = VAR_NUMBER; 21509 v->di_tv.v_lock = VAR_FIXED; 21510 v->di_tv.vval.v_number = nr; 21511 } 21512 21513 /* 21514 * ":return [expr]" 21515 */ 21516 void 21517 ex_return(eap) 21518 exarg_T *eap; 21519 { 21520 char_u *arg = eap->arg; 21521 typval_T rettv; 21522 int returning = FALSE; 21523 21524 if (current_funccal == NULL) 21525 { 21526 EMSG(_("E133: :return not inside a function")); 21527 return; 21528 } 21529 21530 if (eap->skip) 21531 ++emsg_skip; 21532 21533 eap->nextcmd = NULL; 21534 if ((*arg != NUL && *arg != '|' && *arg != '\n') 21535 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 21536 { 21537 if (!eap->skip) 21538 returning = do_return(eap, FALSE, TRUE, &rettv); 21539 else 21540 clear_tv(&rettv); 21541 } 21542 /* It's safer to return also on error. */ 21543 else if (!eap->skip) 21544 { 21545 /* 21546 * Return unless the expression evaluation has been cancelled due to an 21547 * aborting error, an interrupt, or an exception. 21548 */ 21549 if (!aborting()) 21550 returning = do_return(eap, FALSE, TRUE, NULL); 21551 } 21552 21553 /* When skipping or the return gets pending, advance to the next command 21554 * in this line (!returning). Otherwise, ignore the rest of the line. 21555 * Following lines will be ignored by get_func_line(). */ 21556 if (returning) 21557 eap->nextcmd = NULL; 21558 else if (eap->nextcmd == NULL) /* no argument */ 21559 eap->nextcmd = check_nextcmd(arg); 21560 21561 if (eap->skip) 21562 --emsg_skip; 21563 } 21564 21565 /* 21566 * Return from a function. Possibly makes the return pending. Also called 21567 * for a pending return at the ":endtry" or after returning from an extra 21568 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 21569 * when called due to a ":return" command. "rettv" may point to a typval_T 21570 * with the return rettv. Returns TRUE when the return can be carried out, 21571 * FALSE when the return gets pending. 21572 */ 21573 int 21574 do_return(eap, reanimate, is_cmd, rettv) 21575 exarg_T *eap; 21576 int reanimate; 21577 int is_cmd; 21578 void *rettv; 21579 { 21580 int idx; 21581 struct condstack *cstack = eap->cstack; 21582 21583 if (reanimate) 21584 /* Undo the return. */ 21585 current_funccal->returned = FALSE; 21586 21587 /* 21588 * Cleanup (and inactivate) conditionals, but stop when a try conditional 21589 * not in its finally clause (which then is to be executed next) is found. 21590 * In this case, make the ":return" pending for execution at the ":endtry". 21591 * Otherwise, return normally. 21592 */ 21593 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 21594 if (idx >= 0) 21595 { 21596 cstack->cs_pending[idx] = CSTP_RETURN; 21597 21598 if (!is_cmd && !reanimate) 21599 /* A pending return again gets pending. "rettv" points to an 21600 * allocated variable with the rettv of the original ":return"'s 21601 * argument if present or is NULL else. */ 21602 cstack->cs_rettv[idx] = rettv; 21603 else 21604 { 21605 /* When undoing a return in order to make it pending, get the stored 21606 * return rettv. */ 21607 if (reanimate) 21608 rettv = current_funccal->rettv; 21609 21610 if (rettv != NULL) 21611 { 21612 /* Store the value of the pending return. */ 21613 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 21614 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 21615 else 21616 EMSG(_(e_outofmem)); 21617 } 21618 else 21619 cstack->cs_rettv[idx] = NULL; 21620 21621 if (reanimate) 21622 { 21623 /* The pending return value could be overwritten by a ":return" 21624 * without argument in a finally clause; reset the default 21625 * return value. */ 21626 current_funccal->rettv->v_type = VAR_NUMBER; 21627 current_funccal->rettv->vval.v_number = 0; 21628 } 21629 } 21630 report_make_pending(CSTP_RETURN, rettv); 21631 } 21632 else 21633 { 21634 current_funccal->returned = TRUE; 21635 21636 /* If the return is carried out now, store the return value. For 21637 * a return immediately after reanimation, the value is already 21638 * there. */ 21639 if (!reanimate && rettv != NULL) 21640 { 21641 clear_tv(current_funccal->rettv); 21642 *current_funccal->rettv = *(typval_T *)rettv; 21643 if (!is_cmd) 21644 vim_free(rettv); 21645 } 21646 } 21647 21648 return idx < 0; 21649 } 21650 21651 /* 21652 * Free the variable with a pending return value. 21653 */ 21654 void 21655 discard_pending_return(rettv) 21656 void *rettv; 21657 { 21658 free_tv((typval_T *)rettv); 21659 } 21660 21661 /* 21662 * Generate a return command for producing the value of "rettv". The result 21663 * is an allocated string. Used by report_pending() for verbose messages. 21664 */ 21665 char_u * 21666 get_return_cmd(rettv) 21667 void *rettv; 21668 { 21669 char_u *s = NULL; 21670 char_u *tofree = NULL; 21671 char_u numbuf[NUMBUFLEN]; 21672 21673 if (rettv != NULL) 21674 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 21675 if (s == NULL) 21676 s = (char_u *)""; 21677 21678 STRCPY(IObuff, ":return "); 21679 STRNCPY(IObuff + 8, s, IOSIZE - 8); 21680 if (STRLEN(s) + 8 >= IOSIZE) 21681 STRCPY(IObuff + IOSIZE - 4, "..."); 21682 vim_free(tofree); 21683 return vim_strsave(IObuff); 21684 } 21685 21686 /* 21687 * Get next function line. 21688 * Called by do_cmdline() to get the next line. 21689 * Returns allocated string, or NULL for end of function. 21690 */ 21691 char_u * 21692 get_func_line(c, cookie, indent) 21693 int c UNUSED; 21694 void *cookie; 21695 int indent UNUSED; 21696 { 21697 funccall_T *fcp = (funccall_T *)cookie; 21698 ufunc_T *fp = fcp->func; 21699 char_u *retval; 21700 garray_T *gap; /* growarray with function lines */ 21701 21702 /* If breakpoints have been added/deleted need to check for it. */ 21703 if (fcp->dbg_tick != debug_tick) 21704 { 21705 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 21706 sourcing_lnum); 21707 fcp->dbg_tick = debug_tick; 21708 } 21709 #ifdef FEAT_PROFILE 21710 if (do_profiling == PROF_YES) 21711 func_line_end(cookie); 21712 #endif 21713 21714 gap = &fp->uf_lines; 21715 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 21716 || fcp->returned) 21717 retval = NULL; 21718 else 21719 { 21720 /* Skip NULL lines (continuation lines). */ 21721 while (fcp->linenr < gap->ga_len 21722 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 21723 ++fcp->linenr; 21724 if (fcp->linenr >= gap->ga_len) 21725 retval = NULL; 21726 else 21727 { 21728 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 21729 sourcing_lnum = fcp->linenr; 21730 #ifdef FEAT_PROFILE 21731 if (do_profiling == PROF_YES) 21732 func_line_start(cookie); 21733 #endif 21734 } 21735 } 21736 21737 /* Did we encounter a breakpoint? */ 21738 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 21739 { 21740 dbg_breakpoint(fp->uf_name, sourcing_lnum); 21741 /* Find next breakpoint. */ 21742 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 21743 sourcing_lnum); 21744 fcp->dbg_tick = debug_tick; 21745 } 21746 21747 return retval; 21748 } 21749 21750 #if defined(FEAT_PROFILE) || defined(PROTO) 21751 /* 21752 * Called when starting to read a function line. 21753 * "sourcing_lnum" must be correct! 21754 * When skipping lines it may not actually be executed, but we won't find out 21755 * until later and we need to store the time now. 21756 */ 21757 void 21758 func_line_start(cookie) 21759 void *cookie; 21760 { 21761 funccall_T *fcp = (funccall_T *)cookie; 21762 ufunc_T *fp = fcp->func; 21763 21764 if (fp->uf_profiling && sourcing_lnum >= 1 21765 && sourcing_lnum <= fp->uf_lines.ga_len) 21766 { 21767 fp->uf_tml_idx = sourcing_lnum - 1; 21768 /* Skip continuation lines. */ 21769 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 21770 --fp->uf_tml_idx; 21771 fp->uf_tml_execed = FALSE; 21772 profile_start(&fp->uf_tml_start); 21773 profile_zero(&fp->uf_tml_children); 21774 profile_get_wait(&fp->uf_tml_wait); 21775 } 21776 } 21777 21778 /* 21779 * Called when actually executing a function line. 21780 */ 21781 void 21782 func_line_exec(cookie) 21783 void *cookie; 21784 { 21785 funccall_T *fcp = (funccall_T *)cookie; 21786 ufunc_T *fp = fcp->func; 21787 21788 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 21789 fp->uf_tml_execed = TRUE; 21790 } 21791 21792 /* 21793 * Called when done with a function line. 21794 */ 21795 void 21796 func_line_end(cookie) 21797 void *cookie; 21798 { 21799 funccall_T *fcp = (funccall_T *)cookie; 21800 ufunc_T *fp = fcp->func; 21801 21802 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 21803 { 21804 if (fp->uf_tml_execed) 21805 { 21806 ++fp->uf_tml_count[fp->uf_tml_idx]; 21807 profile_end(&fp->uf_tml_start); 21808 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 21809 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 21810 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 21811 &fp->uf_tml_children); 21812 } 21813 fp->uf_tml_idx = -1; 21814 } 21815 } 21816 #endif 21817 21818 /* 21819 * Return TRUE if the currently active function should be ended, because a 21820 * return was encountered or an error occurred. Used inside a ":while". 21821 */ 21822 int 21823 func_has_ended(cookie) 21824 void *cookie; 21825 { 21826 funccall_T *fcp = (funccall_T *)cookie; 21827 21828 /* Ignore the "abort" flag if the abortion behavior has been changed due to 21829 * an error inside a try conditional. */ 21830 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 21831 || fcp->returned); 21832 } 21833 21834 /* 21835 * return TRUE if cookie indicates a function which "abort"s on errors. 21836 */ 21837 int 21838 func_has_abort(cookie) 21839 void *cookie; 21840 { 21841 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 21842 } 21843 21844 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 21845 typedef enum 21846 { 21847 VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ 21848 VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ 21849 VAR_FLAVOUR_VIMINFO /* all uppercase */ 21850 } var_flavour_T; 21851 21852 static var_flavour_T var_flavour __ARGS((char_u *varname)); 21853 21854 static var_flavour_T 21855 var_flavour(varname) 21856 char_u *varname; 21857 { 21858 char_u *p = varname; 21859 21860 if (ASCII_ISUPPER(*p)) 21861 { 21862 while (*(++p)) 21863 if (ASCII_ISLOWER(*p)) 21864 return VAR_FLAVOUR_SESSION; 21865 return VAR_FLAVOUR_VIMINFO; 21866 } 21867 else 21868 return VAR_FLAVOUR_DEFAULT; 21869 } 21870 #endif 21871 21872 #if defined(FEAT_VIMINFO) || defined(PROTO) 21873 /* 21874 * Restore global vars that start with a capital from the viminfo file 21875 */ 21876 int 21877 read_viminfo_varlist(virp, writing) 21878 vir_T *virp; 21879 int writing; 21880 { 21881 char_u *tab; 21882 int type = VAR_NUMBER; 21883 typval_T tv; 21884 21885 if (!writing && (find_viminfo_parameter('!') != NULL)) 21886 { 21887 tab = vim_strchr(virp->vir_line + 1, '\t'); 21888 if (tab != NULL) 21889 { 21890 *tab++ = '\0'; /* isolate the variable name */ 21891 if (*tab == 'S') /* string var */ 21892 type = VAR_STRING; 21893 #ifdef FEAT_FLOAT 21894 else if (*tab == 'F') 21895 type = VAR_FLOAT; 21896 #endif 21897 21898 tab = vim_strchr(tab, '\t'); 21899 if (tab != NULL) 21900 { 21901 tv.v_type = type; 21902 if (type == VAR_STRING) 21903 tv.vval.v_string = viminfo_readstring(virp, 21904 (int)(tab - virp->vir_line + 1), TRUE); 21905 #ifdef FEAT_FLOAT 21906 else if (type == VAR_FLOAT) 21907 (void)string2float(tab + 1, &tv.vval.v_float); 21908 #endif 21909 else 21910 tv.vval.v_number = atol((char *)tab + 1); 21911 set_var(virp->vir_line + 1, &tv, FALSE); 21912 if (type == VAR_STRING) 21913 vim_free(tv.vval.v_string); 21914 } 21915 } 21916 } 21917 21918 return viminfo_readline(virp); 21919 } 21920 21921 /* 21922 * Write global vars that start with a capital to the viminfo file 21923 */ 21924 void 21925 write_viminfo_varlist(fp) 21926 FILE *fp; 21927 { 21928 hashitem_T *hi; 21929 dictitem_T *this_var; 21930 int todo; 21931 char *s; 21932 char_u *p; 21933 char_u *tofree; 21934 char_u numbuf[NUMBUFLEN]; 21935 21936 if (find_viminfo_parameter('!') == NULL) 21937 return; 21938 21939 fputs(_("\n# global variables:\n"), fp); 21940 21941 todo = (int)globvarht.ht_used; 21942 for (hi = globvarht.ht_array; todo > 0; ++hi) 21943 { 21944 if (!HASHITEM_EMPTY(hi)) 21945 { 21946 --todo; 21947 this_var = HI2DI(hi); 21948 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 21949 { 21950 switch (this_var->di_tv.v_type) 21951 { 21952 case VAR_STRING: s = "STR"; break; 21953 case VAR_NUMBER: s = "NUM"; break; 21954 #ifdef FEAT_FLOAT 21955 case VAR_FLOAT: s = "FLO"; break; 21956 #endif 21957 default: continue; 21958 } 21959 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 21960 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 21961 if (p != NULL) 21962 viminfo_writestring(fp, p); 21963 vim_free(tofree); 21964 } 21965 } 21966 } 21967 } 21968 #endif 21969 21970 #if defined(FEAT_SESSION) || defined(PROTO) 21971 int 21972 store_session_globals(fd) 21973 FILE *fd; 21974 { 21975 hashitem_T *hi; 21976 dictitem_T *this_var; 21977 int todo; 21978 char_u *p, *t; 21979 21980 todo = (int)globvarht.ht_used; 21981 for (hi = globvarht.ht_array; todo > 0; ++hi) 21982 { 21983 if (!HASHITEM_EMPTY(hi)) 21984 { 21985 --todo; 21986 this_var = HI2DI(hi); 21987 if ((this_var->di_tv.v_type == VAR_NUMBER 21988 || this_var->di_tv.v_type == VAR_STRING) 21989 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 21990 { 21991 /* Escape special characters with a backslash. Turn a LF and 21992 * CR into \n and \r. */ 21993 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 21994 (char_u *)"\\\"\n\r"); 21995 if (p == NULL) /* out of memory */ 21996 break; 21997 for (t = p; *t != NUL; ++t) 21998 if (*t == '\n') 21999 *t = 'n'; 22000 else if (*t == '\r') 22001 *t = 'r'; 22002 if ((fprintf(fd, "let %s = %c%s%c", 22003 this_var->di_key, 22004 (this_var->di_tv.v_type == VAR_STRING) ? '"' 22005 : ' ', 22006 p, 22007 (this_var->di_tv.v_type == VAR_STRING) ? '"' 22008 : ' ') < 0) 22009 || put_eol(fd) == FAIL) 22010 { 22011 vim_free(p); 22012 return FAIL; 22013 } 22014 vim_free(p); 22015 } 22016 #ifdef FEAT_FLOAT 22017 else if (this_var->di_tv.v_type == VAR_FLOAT 22018 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 22019 { 22020 float_T f = this_var->di_tv.vval.v_float; 22021 int sign = ' '; 22022 22023 if (f < 0) 22024 { 22025 f = -f; 22026 sign = '-'; 22027 } 22028 if ((fprintf(fd, "let %s = %c&%f", 22029 this_var->di_key, sign, f) < 0) 22030 || put_eol(fd) == FAIL) 22031 return FAIL; 22032 } 22033 #endif 22034 } 22035 } 22036 return OK; 22037 } 22038 #endif 22039 22040 /* 22041 * Display script name where an item was last set. 22042 * Should only be invoked when 'verbose' is non-zero. 22043 */ 22044 void 22045 last_set_msg(scriptID) 22046 scid_T scriptID; 22047 { 22048 char_u *p; 22049 22050 if (scriptID != 0) 22051 { 22052 p = home_replace_save(NULL, get_scriptname(scriptID)); 22053 if (p != NULL) 22054 { 22055 verbose_enter(); 22056 MSG_PUTS(_("\n\tLast set from ")); 22057 MSG_PUTS(p); 22058 vim_free(p); 22059 verbose_leave(); 22060 } 22061 } 22062 } 22063 22064 /* 22065 * List v:oldfiles in a nice way. 22066 */ 22067 void 22068 ex_oldfiles(eap) 22069 exarg_T *eap UNUSED; 22070 { 22071 list_T *l = vimvars[VV_OLDFILES].vv_list; 22072 listitem_T *li; 22073 int nr = 0; 22074 22075 if (l == NULL) 22076 msg((char_u *)_("No old files")); 22077 else 22078 { 22079 msg_start(); 22080 msg_scroll = TRUE; 22081 for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) 22082 { 22083 msg_outnum((long)++nr); 22084 MSG_PUTS(": "); 22085 msg_outtrans(get_tv_string(&li->li_tv)); 22086 msg_putchar('\n'); 22087 out_flush(); /* output one line at a time */ 22088 ui_breakcheck(); 22089 } 22090 /* Assume "got_int" was set to truncate the listing. */ 22091 got_int = FALSE; 22092 22093 #ifdef FEAT_BROWSE_CMD 22094 if (cmdmod.browse) 22095 { 22096 quit_more = FALSE; 22097 nr = prompt_for_number(FALSE); 22098 msg_starthere(); 22099 if (nr > 0) 22100 { 22101 char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES), 22102 (long)nr); 22103 22104 if (p != NULL) 22105 { 22106 p = expand_env_save(p); 22107 eap->arg = p; 22108 eap->cmdidx = CMD_edit; 22109 cmdmod.browse = FALSE; 22110 do_exedit(eap, NULL); 22111 vim_free(p); 22112 } 22113 } 22114 } 22115 #endif 22116 } 22117 } 22118 22119 #endif /* FEAT_EVAL */ 22120 22121 22122 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 22123 22124 #ifdef WIN3264 22125 /* 22126 * Functions for ":8" filename modifier: get 8.3 version of a filename. 22127 */ 22128 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 22129 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 22130 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 22131 22132 /* 22133 * Get the short path (8.3) for the filename in "fnamep". 22134 * Only works for a valid file name. 22135 * When the path gets longer "fnamep" is changed and the allocated buffer 22136 * is put in "bufp". 22137 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path. 22138 * Returns OK on success, FAIL on failure. 22139 */ 22140 static int 22141 get_short_pathname(fnamep, bufp, fnamelen) 22142 char_u **fnamep; 22143 char_u **bufp; 22144 int *fnamelen; 22145 { 22146 int l, len; 22147 char_u *newbuf; 22148 22149 len = *fnamelen; 22150 l = GetShortPathName(*fnamep, *fnamep, len); 22151 if (l > len - 1) 22152 { 22153 /* If that doesn't work (not enough space), then save the string 22154 * and try again with a new buffer big enough. */ 22155 newbuf = vim_strnsave(*fnamep, l); 22156 if (newbuf == NULL) 22157 return FAIL; 22158 22159 vim_free(*bufp); 22160 *fnamep = *bufp = newbuf; 22161 22162 /* Really should always succeed, as the buffer is big enough. */ 22163 l = GetShortPathName(*fnamep, *fnamep, l+1); 22164 } 22165 22166 *fnamelen = l; 22167 return OK; 22168 } 22169 22170 /* 22171 * Get the short path (8.3) for the filename in "fname". The converted 22172 * path is returned in "bufp". 22173 * 22174 * Some of the directories specified in "fname" may not exist. This function 22175 * will shorten the existing directories at the beginning of the path and then 22176 * append the remaining non-existing path. 22177 * 22178 * fname - Pointer to the filename to shorten. On return, contains the 22179 * pointer to the shortened pathname 22180 * bufp - Pointer to an allocated buffer for the filename. 22181 * fnamelen - Length of the filename pointed to by fname 22182 * 22183 * Returns OK on success (or nothing done) and FAIL on failure (out of memory). 22184 */ 22185 static int 22186 shortpath_for_invalid_fname(fname, bufp, fnamelen) 22187 char_u **fname; 22188 char_u **bufp; 22189 int *fnamelen; 22190 { 22191 char_u *short_fname, *save_fname, *pbuf_unused; 22192 char_u *endp, *save_endp; 22193 char_u ch; 22194 int old_len, len; 22195 int new_len, sfx_len; 22196 int retval = OK; 22197 22198 /* Make a copy */ 22199 old_len = *fnamelen; 22200 save_fname = vim_strnsave(*fname, old_len); 22201 pbuf_unused = NULL; 22202 short_fname = NULL; 22203 22204 endp = save_fname + old_len - 1; /* Find the end of the copy */ 22205 save_endp = endp; 22206 22207 /* 22208 * Try shortening the supplied path till it succeeds by removing one 22209 * directory at a time from the tail of the path. 22210 */ 22211 len = 0; 22212 for (;;) 22213 { 22214 /* go back one path-separator */ 22215 while (endp > save_fname && !after_pathsep(save_fname, endp + 1)) 22216 --endp; 22217 if (endp <= save_fname) 22218 break; /* processed the complete path */ 22219 22220 /* 22221 * Replace the path separator with a NUL and try to shorten the 22222 * resulting path. 22223 */ 22224 ch = *endp; 22225 *endp = 0; 22226 short_fname = save_fname; 22227 len = (int)STRLEN(short_fname) + 1; 22228 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL) 22229 { 22230 retval = FAIL; 22231 goto theend; 22232 } 22233 *endp = ch; /* preserve the string */ 22234 22235 if (len > 0) 22236 break; /* successfully shortened the path */ 22237 22238 /* failed to shorten the path. Skip the path separator */ 22239 --endp; 22240 } 22241 22242 if (len > 0) 22243 { 22244 /* 22245 * Succeeded in shortening the path. Now concatenate the shortened 22246 * path with the remaining path at the tail. 22247 */ 22248 22249 /* Compute the length of the new path. */ 22250 sfx_len = (int)(save_endp - endp) + 1; 22251 new_len = len + sfx_len; 22252 22253 *fnamelen = new_len; 22254 vim_free(*bufp); 22255 if (new_len > old_len) 22256 { 22257 /* There is not enough space in the currently allocated string, 22258 * copy it to a buffer big enough. */ 22259 *fname = *bufp = vim_strnsave(short_fname, new_len); 22260 if (*fname == NULL) 22261 { 22262 retval = FAIL; 22263 goto theend; 22264 } 22265 } 22266 else 22267 { 22268 /* Transfer short_fname to the main buffer (it's big enough), 22269 * unless get_short_pathname() did its work in-place. */ 22270 *fname = *bufp = save_fname; 22271 if (short_fname != save_fname) 22272 vim_strncpy(save_fname, short_fname, len); 22273 save_fname = NULL; 22274 } 22275 22276 /* concat the not-shortened part of the path */ 22277 vim_strncpy(*fname + len, endp, sfx_len); 22278 (*fname)[new_len] = NUL; 22279 } 22280 22281 theend: 22282 vim_free(pbuf_unused); 22283 vim_free(save_fname); 22284 22285 return retval; 22286 } 22287 22288 /* 22289 * Get a pathname for a partial path. 22290 * Returns OK for success, FAIL for failure. 22291 */ 22292 static int 22293 shortpath_for_partial(fnamep, bufp, fnamelen) 22294 char_u **fnamep; 22295 char_u **bufp; 22296 int *fnamelen; 22297 { 22298 int sepcount, len, tflen; 22299 char_u *p; 22300 char_u *pbuf, *tfname; 22301 int hasTilde; 22302 22303 /* Count up the path separators from the RHS.. so we know which part 22304 * of the path to return. */ 22305 sepcount = 0; 22306 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 22307 if (vim_ispathsep(*p)) 22308 ++sepcount; 22309 22310 /* Need full path first (use expand_env() to remove a "~/") */ 22311 hasTilde = (**fnamep == '~'); 22312 if (hasTilde) 22313 pbuf = tfname = expand_env_save(*fnamep); 22314 else 22315 pbuf = tfname = FullName_save(*fnamep, FALSE); 22316 22317 len = tflen = (int)STRLEN(tfname); 22318 22319 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) 22320 return FAIL; 22321 22322 if (len == 0) 22323 { 22324 /* Don't have a valid filename, so shorten the rest of the 22325 * path if we can. This CAN give us invalid 8.3 filenames, but 22326 * there's not a lot of point in guessing what it might be. 22327 */ 22328 len = tflen; 22329 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) 22330 return FAIL; 22331 } 22332 22333 /* Count the paths backward to find the beginning of the desired string. */ 22334 for (p = tfname + len - 1; p >= tfname; --p) 22335 { 22336 #ifdef FEAT_MBYTE 22337 if (has_mbyte) 22338 p -= mb_head_off(tfname, p); 22339 #endif 22340 if (vim_ispathsep(*p)) 22341 { 22342 if (sepcount == 0 || (hasTilde && sepcount == 1)) 22343 break; 22344 else 22345 sepcount --; 22346 } 22347 } 22348 if (hasTilde) 22349 { 22350 --p; 22351 if (p >= tfname) 22352 *p = '~'; 22353 else 22354 return FAIL; 22355 } 22356 else 22357 ++p; 22358 22359 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 22360 vim_free(*bufp); 22361 *fnamelen = (int)STRLEN(p); 22362 *bufp = pbuf; 22363 *fnamep = p; 22364 22365 return OK; 22366 } 22367 #endif /* WIN3264 */ 22368 22369 /* 22370 * Adjust a filename, according to a string of modifiers. 22371 * *fnamep must be NUL terminated when called. When returning, the length is 22372 * determined by *fnamelen. 22373 * Returns VALID_ flags or -1 for failure. 22374 * When there is an error, *fnamep is set to NULL. 22375 */ 22376 int 22377 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 22378 char_u *src; /* string with modifiers */ 22379 int *usedlen; /* characters after src that are used */ 22380 char_u **fnamep; /* file name so far */ 22381 char_u **bufp; /* buffer for allocated file name or NULL */ 22382 int *fnamelen; /* length of fnamep */ 22383 { 22384 int valid = 0; 22385 char_u *tail; 22386 char_u *s, *p, *pbuf; 22387 char_u dirname[MAXPATHL]; 22388 int c; 22389 int has_fullname = 0; 22390 #ifdef WIN3264 22391 int has_shortname = 0; 22392 #endif 22393 22394 repeat: 22395 /* ":p" - full path/file_name */ 22396 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 22397 { 22398 has_fullname = 1; 22399 22400 valid |= VALID_PATH; 22401 *usedlen += 2; 22402 22403 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 22404 if ((*fnamep)[0] == '~' 22405 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 22406 && ((*fnamep)[1] == '/' 22407 # ifdef BACKSLASH_IN_FILENAME 22408 || (*fnamep)[1] == '\\' 22409 # endif 22410 || (*fnamep)[1] == NUL) 22411 22412 #endif 22413 ) 22414 { 22415 *fnamep = expand_env_save(*fnamep); 22416 vim_free(*bufp); /* free any allocated file name */ 22417 *bufp = *fnamep; 22418 if (*fnamep == NULL) 22419 return -1; 22420 } 22421 22422 /* When "/." or "/.." is used: force expansion to get rid of it. */ 22423 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 22424 { 22425 if (vim_ispathsep(*p) 22426 && p[1] == '.' 22427 && (p[2] == NUL 22428 || vim_ispathsep(p[2]) 22429 || (p[2] == '.' 22430 && (p[3] == NUL || vim_ispathsep(p[3]))))) 22431 break; 22432 } 22433 22434 /* FullName_save() is slow, don't use it when not needed. */ 22435 if (*p != NUL || !vim_isAbsName(*fnamep)) 22436 { 22437 *fnamep = FullName_save(*fnamep, *p != NUL); 22438 vim_free(*bufp); /* free any allocated file name */ 22439 *bufp = *fnamep; 22440 if (*fnamep == NULL) 22441 return -1; 22442 } 22443 22444 /* Append a path separator to a directory. */ 22445 if (mch_isdir(*fnamep)) 22446 { 22447 /* Make room for one or two extra characters. */ 22448 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 22449 vim_free(*bufp); /* free any allocated file name */ 22450 *bufp = *fnamep; 22451 if (*fnamep == NULL) 22452 return -1; 22453 add_pathsep(*fnamep); 22454 } 22455 } 22456 22457 /* ":." - path relative to the current directory */ 22458 /* ":~" - path relative to the home directory */ 22459 /* ":8" - shortname path - postponed till after */ 22460 while (src[*usedlen] == ':' 22461 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 22462 { 22463 *usedlen += 2; 22464 if (c == '8') 22465 { 22466 #ifdef WIN3264 22467 has_shortname = 1; /* Postpone this. */ 22468 #endif 22469 continue; 22470 } 22471 pbuf = NULL; 22472 /* Need full path first (use expand_env() to remove a "~/") */ 22473 if (!has_fullname) 22474 { 22475 if (c == '.' && **fnamep == '~') 22476 p = pbuf = expand_env_save(*fnamep); 22477 else 22478 p = pbuf = FullName_save(*fnamep, FALSE); 22479 } 22480 else 22481 p = *fnamep; 22482 22483 has_fullname = 0; 22484 22485 if (p != NULL) 22486 { 22487 if (c == '.') 22488 { 22489 mch_dirname(dirname, MAXPATHL); 22490 s = shorten_fname(p, dirname); 22491 if (s != NULL) 22492 { 22493 *fnamep = s; 22494 if (pbuf != NULL) 22495 { 22496 vim_free(*bufp); /* free any allocated file name */ 22497 *bufp = pbuf; 22498 pbuf = NULL; 22499 } 22500 } 22501 } 22502 else 22503 { 22504 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 22505 /* Only replace it when it starts with '~' */ 22506 if (*dirname == '~') 22507 { 22508 s = vim_strsave(dirname); 22509 if (s != NULL) 22510 { 22511 *fnamep = s; 22512 vim_free(*bufp); 22513 *bufp = s; 22514 } 22515 } 22516 } 22517 vim_free(pbuf); 22518 } 22519 } 22520 22521 tail = gettail(*fnamep); 22522 *fnamelen = (int)STRLEN(*fnamep); 22523 22524 /* ":h" - head, remove "/file_name", can be repeated */ 22525 /* Don't remove the first "/" or "c:\" */ 22526 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 22527 { 22528 valid |= VALID_HEAD; 22529 *usedlen += 2; 22530 s = get_past_head(*fnamep); 22531 while (tail > s && after_pathsep(s, tail)) 22532 mb_ptr_back(*fnamep, tail); 22533 *fnamelen = (int)(tail - *fnamep); 22534 #ifdef VMS 22535 if (*fnamelen > 0) 22536 *fnamelen += 1; /* the path separator is part of the path */ 22537 #endif 22538 if (*fnamelen == 0) 22539 { 22540 /* Result is empty. Turn it into "." to make ":cd %:h" work. */ 22541 p = vim_strsave((char_u *)"."); 22542 if (p == NULL) 22543 return -1; 22544 vim_free(*bufp); 22545 *bufp = *fnamep = tail = p; 22546 *fnamelen = 1; 22547 } 22548 else 22549 { 22550 while (tail > s && !after_pathsep(s, tail)) 22551 mb_ptr_back(*fnamep, tail); 22552 } 22553 } 22554 22555 /* ":8" - shortname */ 22556 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 22557 { 22558 *usedlen += 2; 22559 #ifdef WIN3264 22560 has_shortname = 1; 22561 #endif 22562 } 22563 22564 #ifdef WIN3264 22565 /* Check shortname after we have done 'heads' and before we do 'tails' 22566 */ 22567 if (has_shortname) 22568 { 22569 pbuf = NULL; 22570 /* Copy the string if it is shortened by :h */ 22571 if (*fnamelen < (int)STRLEN(*fnamep)) 22572 { 22573 p = vim_strnsave(*fnamep, *fnamelen); 22574 if (p == 0) 22575 return -1; 22576 vim_free(*bufp); 22577 *bufp = *fnamep = p; 22578 } 22579 22580 /* Split into two implementations - makes it easier. First is where 22581 * there isn't a full name already, second is where there is. 22582 */ 22583 if (!has_fullname && !vim_isAbsName(*fnamep)) 22584 { 22585 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) 22586 return -1; 22587 } 22588 else 22589 { 22590 int l; 22591 22592 /* Simple case, already have the full-name 22593 * Nearly always shorter, so try first time. */ 22594 l = *fnamelen; 22595 if (get_short_pathname(fnamep, bufp, &l) == FAIL) 22596 return -1; 22597 22598 if (l == 0) 22599 { 22600 /* Couldn't find the filename.. search the paths. 22601 */ 22602 l = *fnamelen; 22603 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) 22604 return -1; 22605 } 22606 *fnamelen = l; 22607 } 22608 } 22609 #endif /* WIN3264 */ 22610 22611 /* ":t" - tail, just the basename */ 22612 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 22613 { 22614 *usedlen += 2; 22615 *fnamelen -= (int)(tail - *fnamep); 22616 *fnamep = tail; 22617 } 22618 22619 /* ":e" - extension, can be repeated */ 22620 /* ":r" - root, without extension, can be repeated */ 22621 while (src[*usedlen] == ':' 22622 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 22623 { 22624 /* find a '.' in the tail: 22625 * - for second :e: before the current fname 22626 * - otherwise: The last '.' 22627 */ 22628 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 22629 s = *fnamep - 2; 22630 else 22631 s = *fnamep + *fnamelen - 1; 22632 for ( ; s > tail; --s) 22633 if (s[0] == '.') 22634 break; 22635 if (src[*usedlen + 1] == 'e') /* :e */ 22636 { 22637 if (s > tail) 22638 { 22639 *fnamelen += (int)(*fnamep - (s + 1)); 22640 *fnamep = s + 1; 22641 #ifdef VMS 22642 /* cut version from the extension */ 22643 s = *fnamep + *fnamelen - 1; 22644 for ( ; s > *fnamep; --s) 22645 if (s[0] == ';') 22646 break; 22647 if (s > *fnamep) 22648 *fnamelen = s - *fnamep; 22649 #endif 22650 } 22651 else if (*fnamep <= tail) 22652 *fnamelen = 0; 22653 } 22654 else /* :r */ 22655 { 22656 if (s > tail) /* remove one extension */ 22657 *fnamelen = (int)(s - *fnamep); 22658 } 22659 *usedlen += 2; 22660 } 22661 22662 /* ":s?pat?foo?" - substitute */ 22663 /* ":gs?pat?foo?" - global substitute */ 22664 if (src[*usedlen] == ':' 22665 && (src[*usedlen + 1] == 's' 22666 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 22667 { 22668 char_u *str; 22669 char_u *pat; 22670 char_u *sub; 22671 int sep; 22672 char_u *flags; 22673 int didit = FALSE; 22674 22675 flags = (char_u *)""; 22676 s = src + *usedlen + 2; 22677 if (src[*usedlen + 1] == 'g') 22678 { 22679 flags = (char_u *)"g"; 22680 ++s; 22681 } 22682 22683 sep = *s++; 22684 if (sep) 22685 { 22686 /* find end of pattern */ 22687 p = vim_strchr(s, sep); 22688 if (p != NULL) 22689 { 22690 pat = vim_strnsave(s, (int)(p - s)); 22691 if (pat != NULL) 22692 { 22693 s = p + 1; 22694 /* find end of substitution */ 22695 p = vim_strchr(s, sep); 22696 if (p != NULL) 22697 { 22698 sub = vim_strnsave(s, (int)(p - s)); 22699 str = vim_strnsave(*fnamep, *fnamelen); 22700 if (sub != NULL && str != NULL) 22701 { 22702 *usedlen = (int)(p + 1 - src); 22703 s = do_string_sub(str, pat, sub, flags); 22704 if (s != NULL) 22705 { 22706 *fnamep = s; 22707 *fnamelen = (int)STRLEN(s); 22708 vim_free(*bufp); 22709 *bufp = s; 22710 didit = TRUE; 22711 } 22712 } 22713 vim_free(sub); 22714 vim_free(str); 22715 } 22716 vim_free(pat); 22717 } 22718 } 22719 /* after using ":s", repeat all the modifiers */ 22720 if (didit) 22721 goto repeat; 22722 } 22723 } 22724 22725 return valid; 22726 } 22727 22728 /* 22729 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 22730 * "flags" can be "g" to do a global substitute. 22731 * Returns an allocated string, NULL for error. 22732 */ 22733 char_u * 22734 do_string_sub(str, pat, sub, flags) 22735 char_u *str; 22736 char_u *pat; 22737 char_u *sub; 22738 char_u *flags; 22739 { 22740 int sublen; 22741 regmatch_T regmatch; 22742 int i; 22743 int do_all; 22744 char_u *tail; 22745 garray_T ga; 22746 char_u *ret; 22747 char_u *save_cpo; 22748 22749 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 22750 save_cpo = p_cpo; 22751 p_cpo = empty_option; 22752 22753 ga_init2(&ga, 1, 200); 22754 22755 do_all = (flags[0] == 'g'); 22756 22757 regmatch.rm_ic = p_ic; 22758 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 22759 if (regmatch.regprog != NULL) 22760 { 22761 tail = str; 22762 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 22763 { 22764 /* 22765 * Get some space for a temporary buffer to do the substitution 22766 * into. It will contain: 22767 * - The text up to where the match is. 22768 * - The substituted text. 22769 * - The text after the match. 22770 */ 22771 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 22772 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 22773 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 22774 { 22775 ga_clear(&ga); 22776 break; 22777 } 22778 22779 /* copy the text up to where the match is */ 22780 i = (int)(regmatch.startp[0] - tail); 22781 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 22782 /* add the substituted text */ 22783 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 22784 + ga.ga_len + i, TRUE, TRUE, FALSE); 22785 ga.ga_len += i + sublen - 1; 22786 /* avoid getting stuck on a match with an empty string */ 22787 if (tail == regmatch.endp[0]) 22788 { 22789 if (*tail == NUL) 22790 break; 22791 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 22792 ++ga.ga_len; 22793 } 22794 else 22795 { 22796 tail = regmatch.endp[0]; 22797 if (*tail == NUL) 22798 break; 22799 } 22800 if (!do_all) 22801 break; 22802 } 22803 22804 if (ga.ga_data != NULL) 22805 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 22806 22807 vim_free(regmatch.regprog); 22808 } 22809 22810 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 22811 ga_clear(&ga); 22812 if (p_cpo == empty_option) 22813 p_cpo = save_cpo; 22814 else 22815 /* Darn, evaluating {sub} expression changed the value. */ 22816 free_string_option(save_cpo); 22817 22818 return ret; 22819 } 22820 22821 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 22822