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_tv __ARGS((list_T *l, typval_T *tv)); 437 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 438 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 439 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 440 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 441 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 442 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 443 static char_u *list2string __ARGS((typval_T *tv, int copyID)); 444 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 445 static int free_unref_items __ARGS((int copyID)); 446 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 447 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 448 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 449 static void dict_unref __ARGS((dict_T *d)); 450 static void dict_free __ARGS((dict_T *d, int recurse)); 451 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 452 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 453 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 454 static void dictitem_free __ARGS((dictitem_T *item)); 455 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 456 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 457 static long dict_len __ARGS((dict_T *d)); 458 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 459 static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 460 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 461 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 462 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 463 static char_u *string_quote __ARGS((char_u *str, int function)); 464 #ifdef FEAT_FLOAT 465 static int string2float __ARGS((char_u *text, float_T *value)); 466 #endif 467 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 468 static int find_internal_func __ARGS((char_u *name)); 469 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 470 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)); 471 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)); 472 static void emsg_funcname __ARGS((char *ermsg, char_u *name)); 473 static int non_zero_arg __ARGS((typval_T *argvars)); 474 475 #ifdef FEAT_FLOAT 476 static void f_abs __ARGS((typval_T *argvars, typval_T *rettv)); 477 #endif 478 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 483 #ifdef FEAT_FLOAT 484 static void f_atan __ARGS((typval_T *argvars, typval_T *rettv)); 485 #endif 486 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 497 #ifdef FEAT_FLOAT 498 static void f_ceil __ARGS((typval_T *argvars, typval_T *rettv)); 499 #endif 500 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 505 #if defined(FEAT_INS_EXPAND) 506 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 509 #endif 510 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 512 #ifdef FEAT_FLOAT 513 static void f_cos __ARGS((typval_T *argvars, typval_T *rettv)); 514 #endif 515 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 518 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 537 #ifdef FEAT_FLOAT 538 static void f_float2nr __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_floor __ARGS((typval_T *argvars, typval_T *rettv)); 540 #endif 541 static void f_fnameescape __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_haslocaldir __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 612 #ifdef FEAT_FLOAT 613 static void f_log10 __ARGS((typval_T *argvars, typval_T *rettv)); 614 #endif 615 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 627 #ifdef vim_mkdir 628 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 629 #endif 630 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); 634 #ifdef FEAT_FLOAT 635 static void f_pow __ARGS((typval_T *argvars, typval_T *rettv)); 636 #endif 637 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 640 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 641 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 642 static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); 643 static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv)); 644 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 645 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 646 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 647 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 648 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 649 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 650 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 651 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 652 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 653 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 654 #ifdef FEAT_FLOAT 655 static void f_round __ARGS((typval_T *argvars, typval_T *rettv)); 656 #endif 657 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 658 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 659 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 660 static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 661 static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 662 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 663 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 664 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 665 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 666 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 667 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 668 static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv)); 669 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 670 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 671 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 672 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 673 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 674 static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv)); 675 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 676 #ifdef FEAT_FLOAT 677 static void f_sin __ARGS((typval_T *argvars, typval_T *rettv)); 678 #endif 679 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 680 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 681 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 682 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 683 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 684 #ifdef FEAT_FLOAT 685 static void f_sqrt __ARGS((typval_T *argvars, typval_T *rettv)); 686 static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv)); 687 #endif 688 static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv)); 689 #ifdef HAVE_STRFTIME 690 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 691 #endif 692 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 693 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 694 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 695 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 696 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 697 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 698 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 699 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 700 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 701 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 702 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 703 static void f_synstack __ARGS((typval_T *argvars, typval_T *rettv)); 704 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 705 static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 706 static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 707 static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 708 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 709 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 710 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 711 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 712 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 713 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 714 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 715 #ifdef FEAT_FLOAT 716 static void f_trunc __ARGS((typval_T *argvars, typval_T *rettv)); 717 #endif 718 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 719 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 720 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 721 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 722 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 723 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 724 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 725 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 726 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 727 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 728 static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 729 static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 730 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 731 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 732 733 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); 734 static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum)); 735 static int get_env_len __ARGS((char_u **arg)); 736 static int get_id_len __ARGS((char_u **arg)); 737 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 738 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 739 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 740 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 741 valid character */ 742 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 743 static int eval_isnamec __ARGS((int c)); 744 static int eval_isnamec1 __ARGS((int c)); 745 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 746 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 747 static typval_T *alloc_tv __ARGS((void)); 748 static typval_T *alloc_string_tv __ARGS((char_u *string)); 749 static void init_tv __ARGS((typval_T *varp)); 750 static long get_tv_number __ARGS((typval_T *varp)); 751 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 752 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 753 static char_u *get_tv_string __ARGS((typval_T *varp)); 754 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 755 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 756 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 757 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 758 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 759 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 760 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 761 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first)); 762 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first)); 763 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 764 static int var_check_ro __ARGS((int flags, char_u *name)); 765 static int var_check_fixed __ARGS((int flags, char_u *name)); 766 static int tv_check_lock __ARGS((int lock, char_u *name)); 767 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 768 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 769 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 770 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 771 static int eval_fname_script __ARGS((char_u *p)); 772 static int eval_fname_sid __ARGS((char_u *p)); 773 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 774 static ufunc_T *find_func __ARGS((char_u *name)); 775 static int function_exists __ARGS((char_u *name)); 776 static int builtin_function __ARGS((char_u *name)); 777 #ifdef FEAT_PROFILE 778 static void func_do_profile __ARGS((ufunc_T *fp)); 779 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 780 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 781 static int 782 # ifdef __BORLANDC__ 783 _RTLENTRYF 784 # endif 785 prof_total_cmp __ARGS((const void *s1, const void *s2)); 786 static int 787 # ifdef __BORLANDC__ 788 _RTLENTRYF 789 # endif 790 prof_self_cmp __ARGS((const void *s1, const void *s2)); 791 #endif 792 static int script_autoload __ARGS((char_u *name, int reload)); 793 static char_u *autoload_name __ARGS((char_u *name)); 794 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 795 static void func_free __ARGS((ufunc_T *fp)); 796 static void func_unref __ARGS((char_u *name)); 797 static void func_ref __ARGS((char_u *name)); 798 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)); 799 static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ; 800 static void free_funccal __ARGS((funccall_T *fc, int free_val)); 801 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 802 static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); 803 static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 804 static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 805 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 806 static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 807 808 /* Character used as separated in autoload function/variable names. */ 809 #define AUTOLOAD_CHAR '#' 810 811 /* 812 * Initialize the global and v: variables. 813 */ 814 void 815 eval_init() 816 { 817 int i; 818 struct vimvar *p; 819 820 init_var_dict(&globvardict, &globvars_var); 821 init_var_dict(&vimvardict, &vimvars_var); 822 hash_init(&compat_hashtab); 823 hash_init(&func_hashtab); 824 825 for (i = 0; i < VV_LEN; ++i) 826 { 827 p = &vimvars[i]; 828 STRCPY(p->vv_di.di_key, p->vv_name); 829 if (p->vv_flags & VV_RO) 830 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 831 else if (p->vv_flags & VV_RO_SBX) 832 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 833 else 834 p->vv_di.di_flags = DI_FLAGS_FIX; 835 836 /* add to v: scope dict, unless the value is not always available */ 837 if (p->vv_type != VAR_UNKNOWN) 838 hash_add(&vimvarht, p->vv_di.di_key); 839 if (p->vv_flags & VV_COMPAT) 840 /* add to compat scope dict */ 841 hash_add(&compat_hashtab, p->vv_di.di_key); 842 } 843 set_vim_var_nr(VV_SEARCHFORWARD, 1L); 844 } 845 846 #if defined(EXITFREE) || defined(PROTO) 847 void 848 eval_clear() 849 { 850 int i; 851 struct vimvar *p; 852 853 for (i = 0; i < VV_LEN; ++i) 854 { 855 p = &vimvars[i]; 856 if (p->vv_di.di_tv.v_type == VAR_STRING) 857 { 858 vim_free(p->vv_str); 859 p->vv_str = NULL; 860 } 861 else if (p->vv_di.di_tv.v_type == VAR_LIST) 862 { 863 list_unref(p->vv_list); 864 p->vv_list = NULL; 865 } 866 } 867 hash_clear(&vimvarht); 868 hash_init(&vimvarht); /* garbage_collect() will access it */ 869 hash_clear(&compat_hashtab); 870 871 /* script-local variables */ 872 for (i = 1; i <= ga_scripts.ga_len; ++i) 873 vars_clear(&SCRIPT_VARS(i)); 874 ga_clear(&ga_scripts); 875 free_scriptnames(); 876 877 /* global variables */ 878 vars_clear(&globvarht); 879 880 /* autoloaded script names */ 881 ga_clear_strings(&ga_loaded); 882 883 /* unreferenced lists and dicts */ 884 (void)garbage_collect(); 885 886 /* functions */ 887 free_all_functions(); 888 hash_clear(&func_hashtab); 889 } 890 #endif 891 892 /* 893 * Return the name of the executed function. 894 */ 895 char_u * 896 func_name(cookie) 897 void *cookie; 898 { 899 return ((funccall_T *)cookie)->func->uf_name; 900 } 901 902 /* 903 * Return the address holding the next breakpoint line for a funccall cookie. 904 */ 905 linenr_T * 906 func_breakpoint(cookie) 907 void *cookie; 908 { 909 return &((funccall_T *)cookie)->breakpoint; 910 } 911 912 /* 913 * Return the address holding the debug tick for a funccall cookie. 914 */ 915 int * 916 func_dbg_tick(cookie) 917 void *cookie; 918 { 919 return &((funccall_T *)cookie)->dbg_tick; 920 } 921 922 /* 923 * Return the nesting level for a funccall cookie. 924 */ 925 int 926 func_level(cookie) 927 void *cookie; 928 { 929 return ((funccall_T *)cookie)->level; 930 } 931 932 /* pointer to funccal for currently active function */ 933 funccall_T *current_funccal = NULL; 934 935 /* pointer to list of previously used funccal, still around because some 936 * item in it is still being used. */ 937 funccall_T *previous_funccal = NULL; 938 939 /* 940 * Return TRUE when a function was ended by a ":return" command. 941 */ 942 int 943 current_func_returned() 944 { 945 return current_funccal->returned; 946 } 947 948 949 /* 950 * Set an internal variable to a string value. Creates the variable if it does 951 * not already exist. 952 */ 953 void 954 set_internal_string_var(name, value) 955 char_u *name; 956 char_u *value; 957 { 958 char_u *val; 959 typval_T *tvp; 960 961 val = vim_strsave(value); 962 if (val != NULL) 963 { 964 tvp = alloc_string_tv(val); 965 if (tvp != NULL) 966 { 967 set_var(name, tvp, FALSE); 968 free_tv(tvp); 969 } 970 } 971 } 972 973 static lval_T *redir_lval = NULL; 974 static garray_T redir_ga; /* only valid when redir_lval is not NULL */ 975 static char_u *redir_endp = NULL; 976 static char_u *redir_varname = NULL; 977 978 /* 979 * Start recording command output to a variable 980 * Returns OK if successfully completed the setup. FAIL otherwise. 981 */ 982 int 983 var_redir_start(name, append) 984 char_u *name; 985 int append; /* append to an existing variable */ 986 { 987 int save_emsg; 988 int err; 989 typval_T tv; 990 991 /* Catch a bad name early. */ 992 if (!eval_isnamec1(*name)) 993 { 994 EMSG(_(e_invarg)); 995 return FAIL; 996 } 997 998 /* Make a copy of the name, it is used in redir_lval until redir ends. */ 999 redir_varname = vim_strsave(name); 1000 if (redir_varname == NULL) 1001 return FAIL; 1002 1003 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 1004 if (redir_lval == NULL) 1005 { 1006 var_redir_stop(); 1007 return FAIL; 1008 } 1009 1010 /* The output is stored in growarray "redir_ga" until redirection ends. */ 1011 ga_init2(&redir_ga, (int)sizeof(char), 500); 1012 1013 /* Parse the variable name (can be a dict or list entry). */ 1014 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 1015 FNE_CHECK_START); 1016 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 1017 { 1018 if (redir_endp != NULL && *redir_endp != NUL) 1019 /* Trailing characters are present after the variable name */ 1020 EMSG(_(e_trailing)); 1021 else 1022 EMSG(_(e_invarg)); 1023 redir_endp = NULL; /* don't store a value, only cleanup */ 1024 var_redir_stop(); 1025 return FAIL; 1026 } 1027 1028 /* check if we can write to the variable: set it to or append an empty 1029 * string */ 1030 save_emsg = did_emsg; 1031 did_emsg = FALSE; 1032 tv.v_type = VAR_STRING; 1033 tv.vval.v_string = (char_u *)""; 1034 if (append) 1035 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 1036 else 1037 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 1038 err = did_emsg; 1039 did_emsg |= save_emsg; 1040 if (err) 1041 { 1042 redir_endp = NULL; /* don't store a value, only cleanup */ 1043 var_redir_stop(); 1044 return FAIL; 1045 } 1046 if (redir_lval->ll_newkey != NULL) 1047 { 1048 /* Dictionary item was created, don't do it again. */ 1049 vim_free(redir_lval->ll_newkey); 1050 redir_lval->ll_newkey = NULL; 1051 } 1052 1053 return OK; 1054 } 1055 1056 /* 1057 * Append "value[value_len]" to the variable set by var_redir_start(). 1058 * The actual appending is postponed until redirection ends, because the value 1059 * appended may in fact be the string we write to, changing it may cause freed 1060 * memory to be used: 1061 * :redir => foo 1062 * :let foo 1063 * :redir END 1064 */ 1065 void 1066 var_redir_str(value, value_len) 1067 char_u *value; 1068 int value_len; 1069 { 1070 int len; 1071 1072 if (redir_lval == NULL) 1073 return; 1074 1075 if (value_len == -1) 1076 len = (int)STRLEN(value); /* Append the entire string */ 1077 else 1078 len = value_len; /* Append only "value_len" characters */ 1079 1080 if (ga_grow(&redir_ga, len) == OK) 1081 { 1082 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 1083 redir_ga.ga_len += len; 1084 } 1085 else 1086 var_redir_stop(); 1087 } 1088 1089 /* 1090 * Stop redirecting command output to a variable. 1091 * Frees the allocated memory. 1092 */ 1093 void 1094 var_redir_stop() 1095 { 1096 typval_T tv; 1097 1098 if (redir_lval != NULL) 1099 { 1100 /* If there was no error: assign the text to the variable. */ 1101 if (redir_endp != NULL) 1102 { 1103 ga_append(&redir_ga, NUL); /* Append the trailing NUL. */ 1104 tv.v_type = VAR_STRING; 1105 tv.vval.v_string = redir_ga.ga_data; 1106 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 1107 } 1108 1109 /* free the collected output */ 1110 vim_free(redir_ga.ga_data); 1111 redir_ga.ga_data = NULL; 1112 1113 clear_lval(redir_lval); 1114 vim_free(redir_lval); 1115 redir_lval = NULL; 1116 } 1117 vim_free(redir_varname); 1118 redir_varname = NULL; 1119 } 1120 1121 # if defined(FEAT_MBYTE) || defined(PROTO) 1122 int 1123 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1124 char_u *enc_from; 1125 char_u *enc_to; 1126 char_u *fname_from; 1127 char_u *fname_to; 1128 { 1129 int err = FALSE; 1130 1131 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1132 set_vim_var_string(VV_CC_TO, enc_to, -1); 1133 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1134 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1135 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1136 err = TRUE; 1137 set_vim_var_string(VV_CC_FROM, NULL, -1); 1138 set_vim_var_string(VV_CC_TO, NULL, -1); 1139 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1140 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1141 1142 if (err) 1143 return FAIL; 1144 return OK; 1145 } 1146 # endif 1147 1148 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1149 int 1150 eval_printexpr(fname, args) 1151 char_u *fname; 1152 char_u *args; 1153 { 1154 int err = FALSE; 1155 1156 set_vim_var_string(VV_FNAME_IN, fname, -1); 1157 set_vim_var_string(VV_CMDARG, args, -1); 1158 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1159 err = TRUE; 1160 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1161 set_vim_var_string(VV_CMDARG, NULL, -1); 1162 1163 if (err) 1164 { 1165 mch_remove(fname); 1166 return FAIL; 1167 } 1168 return OK; 1169 } 1170 # endif 1171 1172 # if defined(FEAT_DIFF) || defined(PROTO) 1173 void 1174 eval_diff(origfile, newfile, outfile) 1175 char_u *origfile; 1176 char_u *newfile; 1177 char_u *outfile; 1178 { 1179 int err = FALSE; 1180 1181 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1182 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1183 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1184 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1185 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1186 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1187 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1188 } 1189 1190 void 1191 eval_patch(origfile, difffile, outfile) 1192 char_u *origfile; 1193 char_u *difffile; 1194 char_u *outfile; 1195 { 1196 int err; 1197 1198 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1199 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1200 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1201 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1202 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1203 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1204 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1205 } 1206 # endif 1207 1208 /* 1209 * Top level evaluation function, returning a boolean. 1210 * Sets "error" to TRUE if there was an error. 1211 * Return TRUE or FALSE. 1212 */ 1213 int 1214 eval_to_bool(arg, error, nextcmd, skip) 1215 char_u *arg; 1216 int *error; 1217 char_u **nextcmd; 1218 int skip; /* only parse, don't execute */ 1219 { 1220 typval_T tv; 1221 int retval = FALSE; 1222 1223 if (skip) 1224 ++emsg_skip; 1225 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1226 *error = TRUE; 1227 else 1228 { 1229 *error = FALSE; 1230 if (!skip) 1231 { 1232 retval = (get_tv_number_chk(&tv, error) != 0); 1233 clear_tv(&tv); 1234 } 1235 } 1236 if (skip) 1237 --emsg_skip; 1238 1239 return retval; 1240 } 1241 1242 /* 1243 * Top level evaluation function, returning a string. If "skip" is TRUE, 1244 * only parsing to "nextcmd" is done, without reporting errors. Return 1245 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1246 */ 1247 char_u * 1248 eval_to_string_skip(arg, nextcmd, skip) 1249 char_u *arg; 1250 char_u **nextcmd; 1251 int skip; /* only parse, don't execute */ 1252 { 1253 typval_T tv; 1254 char_u *retval; 1255 1256 if (skip) 1257 ++emsg_skip; 1258 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1259 retval = NULL; 1260 else 1261 { 1262 retval = vim_strsave(get_tv_string(&tv)); 1263 clear_tv(&tv); 1264 } 1265 if (skip) 1266 --emsg_skip; 1267 1268 return retval; 1269 } 1270 1271 /* 1272 * Skip over an expression at "*pp". 1273 * Return FAIL for an error, OK otherwise. 1274 */ 1275 int 1276 skip_expr(pp) 1277 char_u **pp; 1278 { 1279 typval_T rettv; 1280 1281 *pp = skipwhite(*pp); 1282 return eval1(pp, &rettv, FALSE); 1283 } 1284 1285 /* 1286 * Top level evaluation function, returning a string. 1287 * When "convert" is TRUE convert a List into a sequence of lines and convert 1288 * a Float to a String. 1289 * Return pointer to allocated memory, or NULL for failure. 1290 */ 1291 char_u * 1292 eval_to_string(arg, nextcmd, convert) 1293 char_u *arg; 1294 char_u **nextcmd; 1295 int convert; 1296 { 1297 typval_T tv; 1298 char_u *retval; 1299 garray_T ga; 1300 #ifdef FEAT_FLOAT 1301 char_u numbuf[NUMBUFLEN]; 1302 #endif 1303 1304 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1305 retval = NULL; 1306 else 1307 { 1308 if (convert && tv.v_type == VAR_LIST) 1309 { 1310 ga_init2(&ga, (int)sizeof(char), 80); 1311 if (tv.vval.v_list != NULL) 1312 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1313 ga_append(&ga, NUL); 1314 retval = (char_u *)ga.ga_data; 1315 } 1316 #ifdef FEAT_FLOAT 1317 else if (convert && tv.v_type == VAR_FLOAT) 1318 { 1319 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float); 1320 retval = vim_strsave(numbuf); 1321 } 1322 #endif 1323 else 1324 retval = vim_strsave(get_tv_string(&tv)); 1325 clear_tv(&tv); 1326 } 1327 1328 return retval; 1329 } 1330 1331 /* 1332 * Call eval_to_string() without using current local variables and using 1333 * textlock. When "use_sandbox" is TRUE use the sandbox. 1334 */ 1335 char_u * 1336 eval_to_string_safe(arg, nextcmd, use_sandbox) 1337 char_u *arg; 1338 char_u **nextcmd; 1339 int use_sandbox; 1340 { 1341 char_u *retval; 1342 void *save_funccalp; 1343 1344 save_funccalp = save_funccal(); 1345 if (use_sandbox) 1346 ++sandbox; 1347 ++textlock; 1348 retval = eval_to_string(arg, nextcmd, FALSE); 1349 if (use_sandbox) 1350 --sandbox; 1351 --textlock; 1352 restore_funccal(save_funccalp); 1353 return retval; 1354 } 1355 1356 /* 1357 * Top level evaluation function, returning a number. 1358 * Evaluates "expr" silently. 1359 * Returns -1 for an error. 1360 */ 1361 int 1362 eval_to_number(expr) 1363 char_u *expr; 1364 { 1365 typval_T rettv; 1366 int retval; 1367 char_u *p = skipwhite(expr); 1368 1369 ++emsg_off; 1370 1371 if (eval1(&p, &rettv, TRUE) == FAIL) 1372 retval = -1; 1373 else 1374 { 1375 retval = get_tv_number_chk(&rettv, NULL); 1376 clear_tv(&rettv); 1377 } 1378 --emsg_off; 1379 1380 return retval; 1381 } 1382 1383 /* 1384 * Prepare v: variable "idx" to be used. 1385 * Save the current typeval in "save_tv". 1386 * When not used yet add the variable to the v: hashtable. 1387 */ 1388 static void 1389 prepare_vimvar(idx, save_tv) 1390 int idx; 1391 typval_T *save_tv; 1392 { 1393 *save_tv = vimvars[idx].vv_tv; 1394 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1395 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1396 } 1397 1398 /* 1399 * Restore v: variable "idx" to typeval "save_tv". 1400 * When no longer defined, remove the variable from the v: hashtable. 1401 */ 1402 static void 1403 restore_vimvar(idx, save_tv) 1404 int idx; 1405 typval_T *save_tv; 1406 { 1407 hashitem_T *hi; 1408 1409 vimvars[idx].vv_tv = *save_tv; 1410 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1411 { 1412 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1413 if (HASHITEM_EMPTY(hi)) 1414 EMSG2(_(e_intern2), "restore_vimvar()"); 1415 else 1416 hash_remove(&vimvarht, hi); 1417 } 1418 } 1419 1420 #if defined(FEAT_SPELL) || defined(PROTO) 1421 /* 1422 * Evaluate an expression to a list with suggestions. 1423 * For the "expr:" part of 'spellsuggest'. 1424 * Returns NULL when there is an error. 1425 */ 1426 list_T * 1427 eval_spell_expr(badword, expr) 1428 char_u *badword; 1429 char_u *expr; 1430 { 1431 typval_T save_val; 1432 typval_T rettv; 1433 list_T *list = NULL; 1434 char_u *p = skipwhite(expr); 1435 1436 /* Set "v:val" to the bad word. */ 1437 prepare_vimvar(VV_VAL, &save_val); 1438 vimvars[VV_VAL].vv_type = VAR_STRING; 1439 vimvars[VV_VAL].vv_str = badword; 1440 if (p_verbose == 0) 1441 ++emsg_off; 1442 1443 if (eval1(&p, &rettv, TRUE) == OK) 1444 { 1445 if (rettv.v_type != VAR_LIST) 1446 clear_tv(&rettv); 1447 else 1448 list = rettv.vval.v_list; 1449 } 1450 1451 if (p_verbose == 0) 1452 --emsg_off; 1453 restore_vimvar(VV_VAL, &save_val); 1454 1455 return list; 1456 } 1457 1458 /* 1459 * "list" is supposed to contain two items: a word and a number. Return the 1460 * word in "pp" and the number as the return value. 1461 * Return -1 if anything isn't right. 1462 * Used to get the good word and score from the eval_spell_expr() result. 1463 */ 1464 int 1465 get_spellword(list, pp) 1466 list_T *list; 1467 char_u **pp; 1468 { 1469 listitem_T *li; 1470 1471 li = list->lv_first; 1472 if (li == NULL) 1473 return -1; 1474 *pp = get_tv_string(&li->li_tv); 1475 1476 li = li->li_next; 1477 if (li == NULL) 1478 return -1; 1479 return get_tv_number(&li->li_tv); 1480 } 1481 #endif 1482 1483 /* 1484 * Top level evaluation function. 1485 * Returns an allocated typval_T with the result. 1486 * Returns NULL when there is an error. 1487 */ 1488 typval_T * 1489 eval_expr(arg, nextcmd) 1490 char_u *arg; 1491 char_u **nextcmd; 1492 { 1493 typval_T *tv; 1494 1495 tv = (typval_T *)alloc(sizeof(typval_T)); 1496 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1497 { 1498 vim_free(tv); 1499 tv = NULL; 1500 } 1501 1502 return tv; 1503 } 1504 1505 1506 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \ 1507 || defined(FEAT_COMPL_FUNC) || defined(PROTO) 1508 /* 1509 * Call some vimL function and return the result in "*rettv". 1510 * Uses argv[argc] for the function arguments. Only Number and String 1511 * arguments are currently supported. 1512 * Returns OK or FAIL. 1513 */ 1514 static int 1515 call_vim_function(func, argc, argv, safe, rettv) 1516 char_u *func; 1517 int argc; 1518 char_u **argv; 1519 int safe; /* use the sandbox */ 1520 typval_T *rettv; 1521 { 1522 typval_T *argvars; 1523 long n; 1524 int len; 1525 int i; 1526 int doesrange; 1527 void *save_funccalp = NULL; 1528 int ret; 1529 1530 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1531 if (argvars == NULL) 1532 return FAIL; 1533 1534 for (i = 0; i < argc; i++) 1535 { 1536 /* Pass a NULL or empty argument as an empty string */ 1537 if (argv[i] == NULL || *argv[i] == NUL) 1538 { 1539 argvars[i].v_type = VAR_STRING; 1540 argvars[i].vval.v_string = (char_u *)""; 1541 continue; 1542 } 1543 1544 /* Recognize a number argument, the others must be strings. */ 1545 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1546 if (len != 0 && len == (int)STRLEN(argv[i])) 1547 { 1548 argvars[i].v_type = VAR_NUMBER; 1549 argvars[i].vval.v_number = n; 1550 } 1551 else 1552 { 1553 argvars[i].v_type = VAR_STRING; 1554 argvars[i].vval.v_string = argv[i]; 1555 } 1556 } 1557 1558 if (safe) 1559 { 1560 save_funccalp = save_funccal(); 1561 ++sandbox; 1562 } 1563 1564 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1565 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1566 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1567 &doesrange, TRUE, NULL); 1568 if (safe) 1569 { 1570 --sandbox; 1571 restore_funccal(save_funccalp); 1572 } 1573 vim_free(argvars); 1574 1575 if (ret == FAIL) 1576 clear_tv(rettv); 1577 1578 return ret; 1579 } 1580 1581 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1582 /* 1583 * Call vimL function "func" and return the result as a string. 1584 * Returns NULL when calling the function fails. 1585 * Uses argv[argc] for the function arguments. 1586 */ 1587 void * 1588 call_func_retstr(func, argc, argv, safe) 1589 char_u *func; 1590 int argc; 1591 char_u **argv; 1592 int safe; /* use the sandbox */ 1593 { 1594 typval_T rettv; 1595 char_u *retval; 1596 1597 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1598 return NULL; 1599 1600 retval = vim_strsave(get_tv_string(&rettv)); 1601 clear_tv(&rettv); 1602 return retval; 1603 } 1604 # endif 1605 1606 # if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1607 /* 1608 * Call vimL function "func" and return the result as a number. 1609 * Returns -1 when calling the function fails. 1610 * Uses argv[argc] for the function arguments. 1611 */ 1612 long 1613 call_func_retnr(func, argc, argv, safe) 1614 char_u *func; 1615 int argc; 1616 char_u **argv; 1617 int safe; /* use the sandbox */ 1618 { 1619 typval_T rettv; 1620 long retval; 1621 1622 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1623 return -1; 1624 1625 retval = get_tv_number_chk(&rettv, NULL); 1626 clear_tv(&rettv); 1627 return retval; 1628 } 1629 # endif 1630 1631 /* 1632 * Call vimL function "func" and return the result as a List. 1633 * Uses argv[argc] for the function arguments. 1634 * Returns NULL when there is something wrong. 1635 */ 1636 void * 1637 call_func_retlist(func, argc, argv, safe) 1638 char_u *func; 1639 int argc; 1640 char_u **argv; 1641 int safe; /* use the sandbox */ 1642 { 1643 typval_T rettv; 1644 1645 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1646 return NULL; 1647 1648 if (rettv.v_type != VAR_LIST) 1649 { 1650 clear_tv(&rettv); 1651 return NULL; 1652 } 1653 1654 return rettv.vval.v_list; 1655 } 1656 #endif 1657 1658 1659 /* 1660 * Save the current function call pointer, and set it to NULL. 1661 * Used when executing autocommands and for ":source". 1662 */ 1663 void * 1664 save_funccal() 1665 { 1666 funccall_T *fc = current_funccal; 1667 1668 current_funccal = NULL; 1669 return (void *)fc; 1670 } 1671 1672 void 1673 restore_funccal(vfc) 1674 void *vfc; 1675 { 1676 funccall_T *fc = (funccall_T *)vfc; 1677 1678 current_funccal = fc; 1679 } 1680 1681 #if defined(FEAT_PROFILE) || defined(PROTO) 1682 /* 1683 * Prepare profiling for entering a child or something else that is not 1684 * counted for the script/function itself. 1685 * Should always be called in pair with prof_child_exit(). 1686 */ 1687 void 1688 prof_child_enter(tm) 1689 proftime_T *tm; /* place to store waittime */ 1690 { 1691 funccall_T *fc = current_funccal; 1692 1693 if (fc != NULL && fc->func->uf_profiling) 1694 profile_start(&fc->prof_child); 1695 script_prof_save(tm); 1696 } 1697 1698 /* 1699 * Take care of time spent in a child. 1700 * Should always be called after prof_child_enter(). 1701 */ 1702 void 1703 prof_child_exit(tm) 1704 proftime_T *tm; /* where waittime was stored */ 1705 { 1706 funccall_T *fc = current_funccal; 1707 1708 if (fc != NULL && fc->func->uf_profiling) 1709 { 1710 profile_end(&fc->prof_child); 1711 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1712 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1713 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1714 } 1715 script_prof_restore(tm); 1716 } 1717 #endif 1718 1719 1720 #ifdef FEAT_FOLDING 1721 /* 1722 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1723 * it in "*cp". Doesn't give error messages. 1724 */ 1725 int 1726 eval_foldexpr(arg, cp) 1727 char_u *arg; 1728 int *cp; 1729 { 1730 typval_T tv; 1731 int retval; 1732 char_u *s; 1733 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1734 OPT_LOCAL); 1735 1736 ++emsg_off; 1737 if (use_sandbox) 1738 ++sandbox; 1739 ++textlock; 1740 *cp = NUL; 1741 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1742 retval = 0; 1743 else 1744 { 1745 /* If the result is a number, just return the number. */ 1746 if (tv.v_type == VAR_NUMBER) 1747 retval = tv.vval.v_number; 1748 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1749 retval = 0; 1750 else 1751 { 1752 /* If the result is a string, check if there is a non-digit before 1753 * the number. */ 1754 s = tv.vval.v_string; 1755 if (!VIM_ISDIGIT(*s) && *s != '-') 1756 *cp = *s++; 1757 retval = atol((char *)s); 1758 } 1759 clear_tv(&tv); 1760 } 1761 --emsg_off; 1762 if (use_sandbox) 1763 --sandbox; 1764 --textlock; 1765 1766 return retval; 1767 } 1768 #endif 1769 1770 /* 1771 * ":let" list all variable values 1772 * ":let var1 var2" list variable values 1773 * ":let var = expr" assignment command. 1774 * ":let var += expr" assignment command. 1775 * ":let var -= expr" assignment command. 1776 * ":let var .= expr" assignment command. 1777 * ":let [var1, var2] = expr" unpack list. 1778 */ 1779 void 1780 ex_let(eap) 1781 exarg_T *eap; 1782 { 1783 char_u *arg = eap->arg; 1784 char_u *expr = NULL; 1785 typval_T rettv; 1786 int i; 1787 int var_count = 0; 1788 int semicolon = 0; 1789 char_u op[2]; 1790 char_u *argend; 1791 int first = TRUE; 1792 1793 argend = skip_var_list(arg, &var_count, &semicolon); 1794 if (argend == NULL) 1795 return; 1796 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1797 --argend; 1798 expr = vim_strchr(argend, '='); 1799 if (expr == NULL) 1800 { 1801 /* 1802 * ":let" without "=": list variables 1803 */ 1804 if (*arg == '[') 1805 EMSG(_(e_invarg)); 1806 else if (!ends_excmd(*arg)) 1807 /* ":let var1 var2" */ 1808 arg = list_arg_vars(eap, arg, &first); 1809 else if (!eap->skip) 1810 { 1811 /* ":let" */ 1812 list_glob_vars(&first); 1813 list_buf_vars(&first); 1814 list_win_vars(&first); 1815 #ifdef FEAT_WINDOWS 1816 list_tab_vars(&first); 1817 #endif 1818 list_script_vars(&first); 1819 list_func_vars(&first); 1820 list_vim_vars(&first); 1821 } 1822 eap->nextcmd = check_nextcmd(arg); 1823 } 1824 else 1825 { 1826 op[0] = '='; 1827 op[1] = NUL; 1828 if (expr > argend) 1829 { 1830 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1831 op[0] = expr[-1]; /* +=, -= or .= */ 1832 } 1833 expr = skipwhite(expr + 1); 1834 1835 if (eap->skip) 1836 ++emsg_skip; 1837 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1838 if (eap->skip) 1839 { 1840 if (i != FAIL) 1841 clear_tv(&rettv); 1842 --emsg_skip; 1843 } 1844 else if (i != FAIL) 1845 { 1846 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1847 op); 1848 clear_tv(&rettv); 1849 } 1850 } 1851 } 1852 1853 /* 1854 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1855 * Handles both "var" with any type and "[var, var; var]" with a list type. 1856 * When "nextchars" is not NULL it points to a string with characters that 1857 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1858 * or concatenate. 1859 * Returns OK or FAIL; 1860 */ 1861 static int 1862 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1863 char_u *arg_start; 1864 typval_T *tv; 1865 int copy; /* copy values from "tv", don't move */ 1866 int semicolon; /* from skip_var_list() */ 1867 int var_count; /* from skip_var_list() */ 1868 char_u *nextchars; 1869 { 1870 char_u *arg = arg_start; 1871 list_T *l; 1872 int i; 1873 listitem_T *item; 1874 typval_T ltv; 1875 1876 if (*arg != '[') 1877 { 1878 /* 1879 * ":let var = expr" or ":for var in list" 1880 */ 1881 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1882 return FAIL; 1883 return OK; 1884 } 1885 1886 /* 1887 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1888 */ 1889 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1890 { 1891 EMSG(_(e_listreq)); 1892 return FAIL; 1893 } 1894 1895 i = list_len(l); 1896 if (semicolon == 0 && var_count < i) 1897 { 1898 EMSG(_("E687: Less targets than List items")); 1899 return FAIL; 1900 } 1901 if (var_count - semicolon > i) 1902 { 1903 EMSG(_("E688: More targets than List items")); 1904 return FAIL; 1905 } 1906 1907 item = l->lv_first; 1908 while (*arg != ']') 1909 { 1910 arg = skipwhite(arg + 1); 1911 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1912 item = item->li_next; 1913 if (arg == NULL) 1914 return FAIL; 1915 1916 arg = skipwhite(arg); 1917 if (*arg == ';') 1918 { 1919 /* Put the rest of the list (may be empty) in the var after ';'. 1920 * Create a new list for this. */ 1921 l = list_alloc(); 1922 if (l == NULL) 1923 return FAIL; 1924 while (item != NULL) 1925 { 1926 list_append_tv(l, &item->li_tv); 1927 item = item->li_next; 1928 } 1929 1930 ltv.v_type = VAR_LIST; 1931 ltv.v_lock = 0; 1932 ltv.vval.v_list = l; 1933 l->lv_refcount = 1; 1934 1935 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1936 (char_u *)"]", nextchars); 1937 clear_tv(<v); 1938 if (arg == NULL) 1939 return FAIL; 1940 break; 1941 } 1942 else if (*arg != ',' && *arg != ']') 1943 { 1944 EMSG2(_(e_intern2), "ex_let_vars()"); 1945 return FAIL; 1946 } 1947 } 1948 1949 return OK; 1950 } 1951 1952 /* 1953 * Skip over assignable variable "var" or list of variables "[var, var]". 1954 * Used for ":let varvar = expr" and ":for varvar in expr". 1955 * For "[var, var]" increment "*var_count" for each variable. 1956 * for "[var, var; var]" set "semicolon". 1957 * Return NULL for an error. 1958 */ 1959 static char_u * 1960 skip_var_list(arg, var_count, semicolon) 1961 char_u *arg; 1962 int *var_count; 1963 int *semicolon; 1964 { 1965 char_u *p, *s; 1966 1967 if (*arg == '[') 1968 { 1969 /* "[var, var]": find the matching ']'. */ 1970 p = arg; 1971 for (;;) 1972 { 1973 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1974 s = skip_var_one(p); 1975 if (s == p) 1976 { 1977 EMSG2(_(e_invarg2), p); 1978 return NULL; 1979 } 1980 ++*var_count; 1981 1982 p = skipwhite(s); 1983 if (*p == ']') 1984 break; 1985 else if (*p == ';') 1986 { 1987 if (*semicolon == 1) 1988 { 1989 EMSG(_("Double ; in list of variables")); 1990 return NULL; 1991 } 1992 *semicolon = 1; 1993 } 1994 else if (*p != ',') 1995 { 1996 EMSG2(_(e_invarg2), p); 1997 return NULL; 1998 } 1999 } 2000 return p + 1; 2001 } 2002 else 2003 return skip_var_one(arg); 2004 } 2005 2006 /* 2007 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 2008 * l[idx]. 2009 */ 2010 static char_u * 2011 skip_var_one(arg) 2012 char_u *arg; 2013 { 2014 if (*arg == '@' && arg[1] != NUL) 2015 return arg + 2; 2016 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 2017 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2018 } 2019 2020 /* 2021 * List variables for hashtab "ht" with prefix "prefix". 2022 * If "empty" is TRUE also list NULL strings as empty strings. 2023 */ 2024 static void 2025 list_hashtable_vars(ht, prefix, empty, first) 2026 hashtab_T *ht; 2027 char_u *prefix; 2028 int empty; 2029 int *first; 2030 { 2031 hashitem_T *hi; 2032 dictitem_T *di; 2033 int todo; 2034 2035 todo = (int)ht->ht_used; 2036 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 2037 { 2038 if (!HASHITEM_EMPTY(hi)) 2039 { 2040 --todo; 2041 di = HI2DI(hi); 2042 if (empty || di->di_tv.v_type != VAR_STRING 2043 || di->di_tv.vval.v_string != NULL) 2044 list_one_var(di, prefix, first); 2045 } 2046 } 2047 } 2048 2049 /* 2050 * List global variables. 2051 */ 2052 static void 2053 list_glob_vars(first) 2054 int *first; 2055 { 2056 list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first); 2057 } 2058 2059 /* 2060 * List buffer variables. 2061 */ 2062 static void 2063 list_buf_vars(first) 2064 int *first; 2065 { 2066 char_u numbuf[NUMBUFLEN]; 2067 2068 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", 2069 TRUE, first); 2070 2071 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 2072 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, 2073 numbuf, first); 2074 } 2075 2076 /* 2077 * List window variables. 2078 */ 2079 static void 2080 list_win_vars(first) 2081 int *first; 2082 { 2083 list_hashtable_vars(&curwin->w_vars.dv_hashtab, 2084 (char_u *)"w:", TRUE, first); 2085 } 2086 2087 #ifdef FEAT_WINDOWS 2088 /* 2089 * List tab page variables. 2090 */ 2091 static void 2092 list_tab_vars(first) 2093 int *first; 2094 { 2095 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, 2096 (char_u *)"t:", TRUE, first); 2097 } 2098 #endif 2099 2100 /* 2101 * List Vim variables. 2102 */ 2103 static void 2104 list_vim_vars(first) 2105 int *first; 2106 { 2107 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first); 2108 } 2109 2110 /* 2111 * List script-local variables, if there is a script. 2112 */ 2113 static void 2114 list_script_vars(first) 2115 int *first; 2116 { 2117 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 2118 list_hashtable_vars(&SCRIPT_VARS(current_SID), 2119 (char_u *)"s:", FALSE, first); 2120 } 2121 2122 /* 2123 * List function variables, if there is a function. 2124 */ 2125 static void 2126 list_func_vars(first) 2127 int *first; 2128 { 2129 if (current_funccal != NULL) 2130 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2131 (char_u *)"l:", FALSE, first); 2132 } 2133 2134 /* 2135 * List variables in "arg". 2136 */ 2137 static char_u * 2138 list_arg_vars(eap, arg, first) 2139 exarg_T *eap; 2140 char_u *arg; 2141 int *first; 2142 { 2143 int error = FALSE; 2144 int len; 2145 char_u *name; 2146 char_u *name_start; 2147 char_u *arg_subsc; 2148 char_u *tofree; 2149 typval_T tv; 2150 2151 while (!ends_excmd(*arg) && !got_int) 2152 { 2153 if (error || eap->skip) 2154 { 2155 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2156 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2157 { 2158 emsg_severe = TRUE; 2159 EMSG(_(e_trailing)); 2160 break; 2161 } 2162 } 2163 else 2164 { 2165 /* get_name_len() takes care of expanding curly braces */ 2166 name_start = name = arg; 2167 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2168 if (len <= 0) 2169 { 2170 /* This is mainly to keep test 49 working: when expanding 2171 * curly braces fails overrule the exception error message. */ 2172 if (len < 0 && !aborting()) 2173 { 2174 emsg_severe = TRUE; 2175 EMSG2(_(e_invarg2), arg); 2176 break; 2177 } 2178 error = TRUE; 2179 } 2180 else 2181 { 2182 if (tofree != NULL) 2183 name = tofree; 2184 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 2185 error = TRUE; 2186 else 2187 { 2188 /* handle d.key, l[idx], f(expr) */ 2189 arg_subsc = arg; 2190 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2191 error = TRUE; 2192 else 2193 { 2194 if (arg == arg_subsc && len == 2 && name[1] == ':') 2195 { 2196 switch (*name) 2197 { 2198 case 'g': list_glob_vars(first); break; 2199 case 'b': list_buf_vars(first); break; 2200 case 'w': list_win_vars(first); break; 2201 #ifdef FEAT_WINDOWS 2202 case 't': list_tab_vars(first); break; 2203 #endif 2204 case 'v': list_vim_vars(first); break; 2205 case 's': list_script_vars(first); break; 2206 case 'l': list_func_vars(first); break; 2207 default: 2208 EMSG2(_("E738: Can't list variables for %s"), name); 2209 } 2210 } 2211 else 2212 { 2213 char_u numbuf[NUMBUFLEN]; 2214 char_u *tf; 2215 int c; 2216 char_u *s; 2217 2218 s = echo_string(&tv, &tf, numbuf, 0); 2219 c = *arg; 2220 *arg = NUL; 2221 list_one_var_a((char_u *)"", 2222 arg == arg_subsc ? name : name_start, 2223 tv.v_type, 2224 s == NULL ? (char_u *)"" : s, 2225 first); 2226 *arg = c; 2227 vim_free(tf); 2228 } 2229 clear_tv(&tv); 2230 } 2231 } 2232 } 2233 2234 vim_free(tofree); 2235 } 2236 2237 arg = skipwhite(arg); 2238 } 2239 2240 return arg; 2241 } 2242 2243 /* 2244 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2245 * Returns a pointer to the char just after the var name. 2246 * Returns NULL if there is an error. 2247 */ 2248 static char_u * 2249 ex_let_one(arg, tv, copy, endchars, op) 2250 char_u *arg; /* points to variable name */ 2251 typval_T *tv; /* value to assign to variable */ 2252 int copy; /* copy value from "tv" */ 2253 char_u *endchars; /* valid chars after variable name or NULL */ 2254 char_u *op; /* "+", "-", "." or NULL*/ 2255 { 2256 int c1; 2257 char_u *name; 2258 char_u *p; 2259 char_u *arg_end = NULL; 2260 int len; 2261 int opt_flags; 2262 char_u *tofree = NULL; 2263 2264 /* 2265 * ":let $VAR = expr": Set environment variable. 2266 */ 2267 if (*arg == '$') 2268 { 2269 /* Find the end of the name. */ 2270 ++arg; 2271 name = arg; 2272 len = get_env_len(&arg); 2273 if (len == 0) 2274 EMSG2(_(e_invarg2), name - 1); 2275 else 2276 { 2277 if (op != NULL && (*op == '+' || *op == '-')) 2278 EMSG2(_(e_letwrong), op); 2279 else if (endchars != NULL 2280 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2281 EMSG(_(e_letunexp)); 2282 else 2283 { 2284 c1 = name[len]; 2285 name[len] = NUL; 2286 p = get_tv_string_chk(tv); 2287 if (p != NULL && op != NULL && *op == '.') 2288 { 2289 int mustfree = FALSE; 2290 char_u *s = vim_getenv(name, &mustfree); 2291 2292 if (s != NULL) 2293 { 2294 p = tofree = concat_str(s, p); 2295 if (mustfree) 2296 vim_free(s); 2297 } 2298 } 2299 if (p != NULL) 2300 { 2301 vim_setenv(name, p); 2302 if (STRICMP(name, "HOME") == 0) 2303 init_homedir(); 2304 else if (didset_vim && STRICMP(name, "VIM") == 0) 2305 didset_vim = FALSE; 2306 else if (didset_vimruntime 2307 && STRICMP(name, "VIMRUNTIME") == 0) 2308 didset_vimruntime = FALSE; 2309 arg_end = arg; 2310 } 2311 name[len] = c1; 2312 vim_free(tofree); 2313 } 2314 } 2315 } 2316 2317 /* 2318 * ":let &option = expr": Set option value. 2319 * ":let &l:option = expr": Set local option value. 2320 * ":let &g:option = expr": Set global option value. 2321 */ 2322 else if (*arg == '&') 2323 { 2324 /* Find the end of the name. */ 2325 p = find_option_end(&arg, &opt_flags); 2326 if (p == NULL || (endchars != NULL 2327 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2328 EMSG(_(e_letunexp)); 2329 else 2330 { 2331 long n; 2332 int opt_type; 2333 long numval; 2334 char_u *stringval = NULL; 2335 char_u *s; 2336 2337 c1 = *p; 2338 *p = NUL; 2339 2340 n = get_tv_number(tv); 2341 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2342 if (s != NULL && op != NULL && *op != '=') 2343 { 2344 opt_type = get_option_value(arg, &numval, 2345 &stringval, opt_flags); 2346 if ((opt_type == 1 && *op == '.') 2347 || (opt_type == 0 && *op != '.')) 2348 EMSG2(_(e_letwrong), op); 2349 else 2350 { 2351 if (opt_type == 1) /* number */ 2352 { 2353 if (*op == '+') 2354 n = numval + n; 2355 else 2356 n = numval - n; 2357 } 2358 else if (opt_type == 0 && stringval != NULL) /* string */ 2359 { 2360 s = concat_str(stringval, s); 2361 vim_free(stringval); 2362 stringval = s; 2363 } 2364 } 2365 } 2366 if (s != NULL) 2367 { 2368 set_option_value(arg, n, s, opt_flags); 2369 arg_end = p; 2370 } 2371 *p = c1; 2372 vim_free(stringval); 2373 } 2374 } 2375 2376 /* 2377 * ":let @r = expr": Set register contents. 2378 */ 2379 else if (*arg == '@') 2380 { 2381 ++arg; 2382 if (op != NULL && (*op == '+' || *op == '-')) 2383 EMSG2(_(e_letwrong), op); 2384 else if (endchars != NULL 2385 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2386 EMSG(_(e_letunexp)); 2387 else 2388 { 2389 char_u *ptofree = NULL; 2390 char_u *s; 2391 2392 p = get_tv_string_chk(tv); 2393 if (p != NULL && op != NULL && *op == '.') 2394 { 2395 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2396 if (s != NULL) 2397 { 2398 p = ptofree = concat_str(s, p); 2399 vim_free(s); 2400 } 2401 } 2402 if (p != NULL) 2403 { 2404 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2405 arg_end = arg + 1; 2406 } 2407 vim_free(ptofree); 2408 } 2409 } 2410 2411 /* 2412 * ":let var = expr": Set internal variable. 2413 * ":let {expr} = expr": Idem, name made with curly braces 2414 */ 2415 else if (eval_isnamec1(*arg) || *arg == '{') 2416 { 2417 lval_T lv; 2418 2419 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2420 if (p != NULL && lv.ll_name != NULL) 2421 { 2422 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2423 EMSG(_(e_letunexp)); 2424 else 2425 { 2426 set_var_lval(&lv, p, tv, copy, op); 2427 arg_end = p; 2428 } 2429 } 2430 clear_lval(&lv); 2431 } 2432 2433 else 2434 EMSG2(_(e_invarg2), arg); 2435 2436 return arg_end; 2437 } 2438 2439 /* 2440 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2441 */ 2442 static int 2443 check_changedtick(arg) 2444 char_u *arg; 2445 { 2446 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2447 { 2448 EMSG2(_(e_readonlyvar), arg); 2449 return TRUE; 2450 } 2451 return FALSE; 2452 } 2453 2454 /* 2455 * Get an lval: variable, Dict item or List item that can be assigned a value 2456 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2457 * "name.key", "name.key[expr]" etc. 2458 * Indexing only works if "name" is an existing List or Dictionary. 2459 * "name" points to the start of the name. 2460 * If "rettv" is not NULL it points to the value to be assigned. 2461 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2462 * wrong; must end in space or cmd separator. 2463 * 2464 * Returns a pointer to just after the name, including indexes. 2465 * When an evaluation error occurs "lp->ll_name" is NULL; 2466 * Returns NULL for a parsing error. Still need to free items in "lp"! 2467 */ 2468 static char_u * 2469 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2470 char_u *name; 2471 typval_T *rettv; 2472 lval_T *lp; 2473 int unlet; 2474 int skip; 2475 int quiet; /* don't give error messages */ 2476 int fne_flags; /* flags for find_name_end() */ 2477 { 2478 char_u *p; 2479 char_u *expr_start, *expr_end; 2480 int cc; 2481 dictitem_T *v; 2482 typval_T var1; 2483 typval_T var2; 2484 int empty1 = FALSE; 2485 listitem_T *ni; 2486 char_u *key = NULL; 2487 int len; 2488 hashtab_T *ht; 2489 2490 /* Clear everything in "lp". */ 2491 vim_memset(lp, 0, sizeof(lval_T)); 2492 2493 if (skip) 2494 { 2495 /* When skipping just find the end of the name. */ 2496 lp->ll_name = name; 2497 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2498 } 2499 2500 /* Find the end of the name. */ 2501 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2502 if (expr_start != NULL) 2503 { 2504 /* Don't expand the name when we already know there is an error. */ 2505 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2506 && *p != '[' && *p != '.') 2507 { 2508 EMSG(_(e_trailing)); 2509 return NULL; 2510 } 2511 2512 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2513 if (lp->ll_exp_name == NULL) 2514 { 2515 /* Report an invalid expression in braces, unless the 2516 * expression evaluation has been cancelled due to an 2517 * aborting error, an interrupt, or an exception. */ 2518 if (!aborting() && !quiet) 2519 { 2520 emsg_severe = TRUE; 2521 EMSG2(_(e_invarg2), name); 2522 return NULL; 2523 } 2524 } 2525 lp->ll_name = lp->ll_exp_name; 2526 } 2527 else 2528 lp->ll_name = name; 2529 2530 /* Without [idx] or .key we are done. */ 2531 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2532 return p; 2533 2534 cc = *p; 2535 *p = NUL; 2536 v = find_var(lp->ll_name, &ht); 2537 if (v == NULL && !quiet) 2538 EMSG2(_(e_undefvar), lp->ll_name); 2539 *p = cc; 2540 if (v == NULL) 2541 return NULL; 2542 2543 /* 2544 * Loop until no more [idx] or .key is following. 2545 */ 2546 lp->ll_tv = &v->di_tv; 2547 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2548 { 2549 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2550 && !(lp->ll_tv->v_type == VAR_DICT 2551 && lp->ll_tv->vval.v_dict != NULL)) 2552 { 2553 if (!quiet) 2554 EMSG(_("E689: Can only index a List or Dictionary")); 2555 return NULL; 2556 } 2557 if (lp->ll_range) 2558 { 2559 if (!quiet) 2560 EMSG(_("E708: [:] must come last")); 2561 return NULL; 2562 } 2563 2564 len = -1; 2565 if (*p == '.') 2566 { 2567 key = p + 1; 2568 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2569 ; 2570 if (len == 0) 2571 { 2572 if (!quiet) 2573 EMSG(_(e_emptykey)); 2574 return NULL; 2575 } 2576 p = key + len; 2577 } 2578 else 2579 { 2580 /* Get the index [expr] or the first index [expr: ]. */ 2581 p = skipwhite(p + 1); 2582 if (*p == ':') 2583 empty1 = TRUE; 2584 else 2585 { 2586 empty1 = FALSE; 2587 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2588 return NULL; 2589 if (get_tv_string_chk(&var1) == NULL) 2590 { 2591 /* not a number or string */ 2592 clear_tv(&var1); 2593 return NULL; 2594 } 2595 } 2596 2597 /* Optionally get the second index [ :expr]. */ 2598 if (*p == ':') 2599 { 2600 if (lp->ll_tv->v_type == VAR_DICT) 2601 { 2602 if (!quiet) 2603 EMSG(_(e_dictrange)); 2604 if (!empty1) 2605 clear_tv(&var1); 2606 return NULL; 2607 } 2608 if (rettv != NULL && (rettv->v_type != VAR_LIST 2609 || rettv->vval.v_list == NULL)) 2610 { 2611 if (!quiet) 2612 EMSG(_("E709: [:] requires a List value")); 2613 if (!empty1) 2614 clear_tv(&var1); 2615 return NULL; 2616 } 2617 p = skipwhite(p + 1); 2618 if (*p == ']') 2619 lp->ll_empty2 = TRUE; 2620 else 2621 { 2622 lp->ll_empty2 = FALSE; 2623 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2624 { 2625 if (!empty1) 2626 clear_tv(&var1); 2627 return NULL; 2628 } 2629 if (get_tv_string_chk(&var2) == NULL) 2630 { 2631 /* not a number or string */ 2632 if (!empty1) 2633 clear_tv(&var1); 2634 clear_tv(&var2); 2635 return NULL; 2636 } 2637 } 2638 lp->ll_range = TRUE; 2639 } 2640 else 2641 lp->ll_range = FALSE; 2642 2643 if (*p != ']') 2644 { 2645 if (!quiet) 2646 EMSG(_(e_missbrac)); 2647 if (!empty1) 2648 clear_tv(&var1); 2649 if (lp->ll_range && !lp->ll_empty2) 2650 clear_tv(&var2); 2651 return NULL; 2652 } 2653 2654 /* Skip to past ']'. */ 2655 ++p; 2656 } 2657 2658 if (lp->ll_tv->v_type == VAR_DICT) 2659 { 2660 if (len == -1) 2661 { 2662 /* "[key]": get key from "var1" */ 2663 key = get_tv_string(&var1); /* is number or string */ 2664 if (*key == NUL) 2665 { 2666 if (!quiet) 2667 EMSG(_(e_emptykey)); 2668 clear_tv(&var1); 2669 return NULL; 2670 } 2671 } 2672 lp->ll_list = NULL; 2673 lp->ll_dict = lp->ll_tv->vval.v_dict; 2674 lp->ll_di = dict_find(lp->ll_dict, key, len); 2675 if (lp->ll_di == NULL) 2676 { 2677 /* Key does not exist in dict: may need to add it. */ 2678 if (*p == '[' || *p == '.' || unlet) 2679 { 2680 if (!quiet) 2681 EMSG2(_(e_dictkey), key); 2682 if (len == -1) 2683 clear_tv(&var1); 2684 return NULL; 2685 } 2686 if (len == -1) 2687 lp->ll_newkey = vim_strsave(key); 2688 else 2689 lp->ll_newkey = vim_strnsave(key, len); 2690 if (len == -1) 2691 clear_tv(&var1); 2692 if (lp->ll_newkey == NULL) 2693 p = NULL; 2694 break; 2695 } 2696 if (len == -1) 2697 clear_tv(&var1); 2698 lp->ll_tv = &lp->ll_di->di_tv; 2699 } 2700 else 2701 { 2702 /* 2703 * Get the number and item for the only or first index of the List. 2704 */ 2705 if (empty1) 2706 lp->ll_n1 = 0; 2707 else 2708 { 2709 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2710 clear_tv(&var1); 2711 } 2712 lp->ll_dict = NULL; 2713 lp->ll_list = lp->ll_tv->vval.v_list; 2714 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2715 if (lp->ll_li == NULL) 2716 { 2717 if (lp->ll_n1 < 0) 2718 { 2719 lp->ll_n1 = 0; 2720 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2721 } 2722 } 2723 if (lp->ll_li == NULL) 2724 { 2725 if (lp->ll_range && !lp->ll_empty2) 2726 clear_tv(&var2); 2727 return NULL; 2728 } 2729 2730 /* 2731 * May need to find the item or absolute index for the second 2732 * index of a range. 2733 * When no index given: "lp->ll_empty2" is TRUE. 2734 * Otherwise "lp->ll_n2" is set to the second index. 2735 */ 2736 if (lp->ll_range && !lp->ll_empty2) 2737 { 2738 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2739 clear_tv(&var2); 2740 if (lp->ll_n2 < 0) 2741 { 2742 ni = list_find(lp->ll_list, lp->ll_n2); 2743 if (ni == NULL) 2744 return NULL; 2745 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2746 } 2747 2748 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2749 if (lp->ll_n1 < 0) 2750 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2751 if (lp->ll_n2 < lp->ll_n1) 2752 return NULL; 2753 } 2754 2755 lp->ll_tv = &lp->ll_li->li_tv; 2756 } 2757 } 2758 2759 return p; 2760 } 2761 2762 /* 2763 * Clear lval "lp" that was filled by get_lval(). 2764 */ 2765 static void 2766 clear_lval(lp) 2767 lval_T *lp; 2768 { 2769 vim_free(lp->ll_exp_name); 2770 vim_free(lp->ll_newkey); 2771 } 2772 2773 /* 2774 * Set a variable that was parsed by get_lval() to "rettv". 2775 * "endp" points to just after the parsed name. 2776 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2777 */ 2778 static void 2779 set_var_lval(lp, endp, rettv, copy, op) 2780 lval_T *lp; 2781 char_u *endp; 2782 typval_T *rettv; 2783 int copy; 2784 char_u *op; 2785 { 2786 int cc; 2787 listitem_T *ri; 2788 dictitem_T *di; 2789 2790 if (lp->ll_tv == NULL) 2791 { 2792 if (!check_changedtick(lp->ll_name)) 2793 { 2794 cc = *endp; 2795 *endp = NUL; 2796 if (op != NULL && *op != '=') 2797 { 2798 typval_T tv; 2799 2800 /* handle +=, -= and .= */ 2801 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2802 &tv, TRUE) == OK) 2803 { 2804 if (tv_op(&tv, rettv, op) == OK) 2805 set_var(lp->ll_name, &tv, FALSE); 2806 clear_tv(&tv); 2807 } 2808 } 2809 else 2810 set_var(lp->ll_name, rettv, copy); 2811 *endp = cc; 2812 } 2813 } 2814 else if (tv_check_lock(lp->ll_newkey == NULL 2815 ? lp->ll_tv->v_lock 2816 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2817 ; 2818 else if (lp->ll_range) 2819 { 2820 /* 2821 * Assign the List values to the list items. 2822 */ 2823 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2824 { 2825 if (op != NULL && *op != '=') 2826 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2827 else 2828 { 2829 clear_tv(&lp->ll_li->li_tv); 2830 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2831 } 2832 ri = ri->li_next; 2833 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2834 break; 2835 if (lp->ll_li->li_next == NULL) 2836 { 2837 /* Need to add an empty item. */ 2838 if (list_append_number(lp->ll_list, 0) == FAIL) 2839 { 2840 ri = NULL; 2841 break; 2842 } 2843 } 2844 lp->ll_li = lp->ll_li->li_next; 2845 ++lp->ll_n1; 2846 } 2847 if (ri != NULL) 2848 EMSG(_("E710: List value has more items than target")); 2849 else if (lp->ll_empty2 2850 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2851 : lp->ll_n1 != lp->ll_n2) 2852 EMSG(_("E711: List value has not enough items")); 2853 } 2854 else 2855 { 2856 /* 2857 * Assign to a List or Dictionary item. 2858 */ 2859 if (lp->ll_newkey != NULL) 2860 { 2861 if (op != NULL && *op != '=') 2862 { 2863 EMSG2(_(e_letwrong), op); 2864 return; 2865 } 2866 2867 /* Need to add an item to the Dictionary. */ 2868 di = dictitem_alloc(lp->ll_newkey); 2869 if (di == NULL) 2870 return; 2871 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2872 { 2873 vim_free(di); 2874 return; 2875 } 2876 lp->ll_tv = &di->di_tv; 2877 } 2878 else if (op != NULL && *op != '=') 2879 { 2880 tv_op(lp->ll_tv, rettv, op); 2881 return; 2882 } 2883 else 2884 clear_tv(lp->ll_tv); 2885 2886 /* 2887 * Assign the value to the variable or list item. 2888 */ 2889 if (copy) 2890 copy_tv(rettv, lp->ll_tv); 2891 else 2892 { 2893 *lp->ll_tv = *rettv; 2894 lp->ll_tv->v_lock = 0; 2895 init_tv(rettv); 2896 } 2897 } 2898 } 2899 2900 /* 2901 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2902 * Returns OK or FAIL. 2903 */ 2904 static int 2905 tv_op(tv1, tv2, op) 2906 typval_T *tv1; 2907 typval_T *tv2; 2908 char_u *op; 2909 { 2910 long n; 2911 char_u numbuf[NUMBUFLEN]; 2912 char_u *s; 2913 2914 /* Can't do anything with a Funcref or a Dict on the right. */ 2915 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2916 { 2917 switch (tv1->v_type) 2918 { 2919 case VAR_DICT: 2920 case VAR_FUNC: 2921 break; 2922 2923 case VAR_LIST: 2924 if (*op != '+' || tv2->v_type != VAR_LIST) 2925 break; 2926 /* List += List */ 2927 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2928 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2929 return OK; 2930 2931 case VAR_NUMBER: 2932 case VAR_STRING: 2933 if (tv2->v_type == VAR_LIST) 2934 break; 2935 if (*op == '+' || *op == '-') 2936 { 2937 /* nr += nr or nr -= nr*/ 2938 n = get_tv_number(tv1); 2939 #ifdef FEAT_FLOAT 2940 if (tv2->v_type == VAR_FLOAT) 2941 { 2942 float_T f = n; 2943 2944 if (*op == '+') 2945 f += tv2->vval.v_float; 2946 else 2947 f -= tv2->vval.v_float; 2948 clear_tv(tv1); 2949 tv1->v_type = VAR_FLOAT; 2950 tv1->vval.v_float = f; 2951 } 2952 else 2953 #endif 2954 { 2955 if (*op == '+') 2956 n += get_tv_number(tv2); 2957 else 2958 n -= get_tv_number(tv2); 2959 clear_tv(tv1); 2960 tv1->v_type = VAR_NUMBER; 2961 tv1->vval.v_number = n; 2962 } 2963 } 2964 else 2965 { 2966 if (tv2->v_type == VAR_FLOAT) 2967 break; 2968 2969 /* str .= str */ 2970 s = get_tv_string(tv1); 2971 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2972 clear_tv(tv1); 2973 tv1->v_type = VAR_STRING; 2974 tv1->vval.v_string = s; 2975 } 2976 return OK; 2977 2978 #ifdef FEAT_FLOAT 2979 case VAR_FLOAT: 2980 { 2981 float_T f; 2982 2983 if (*op == '.' || (tv2->v_type != VAR_FLOAT 2984 && tv2->v_type != VAR_NUMBER 2985 && tv2->v_type != VAR_STRING)) 2986 break; 2987 if (tv2->v_type == VAR_FLOAT) 2988 f = tv2->vval.v_float; 2989 else 2990 f = get_tv_number(tv2); 2991 if (*op == '+') 2992 tv1->vval.v_float += f; 2993 else 2994 tv1->vval.v_float -= f; 2995 } 2996 return OK; 2997 #endif 2998 } 2999 } 3000 3001 EMSG2(_(e_letwrong), op); 3002 return FAIL; 3003 } 3004 3005 /* 3006 * Add a watcher to a list. 3007 */ 3008 static void 3009 list_add_watch(l, lw) 3010 list_T *l; 3011 listwatch_T *lw; 3012 { 3013 lw->lw_next = l->lv_watch; 3014 l->lv_watch = lw; 3015 } 3016 3017 /* 3018 * Remove a watcher from a list. 3019 * No warning when it isn't found... 3020 */ 3021 static void 3022 list_rem_watch(l, lwrem) 3023 list_T *l; 3024 listwatch_T *lwrem; 3025 { 3026 listwatch_T *lw, **lwp; 3027 3028 lwp = &l->lv_watch; 3029 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3030 { 3031 if (lw == lwrem) 3032 { 3033 *lwp = lw->lw_next; 3034 break; 3035 } 3036 lwp = &lw->lw_next; 3037 } 3038 } 3039 3040 /* 3041 * Just before removing an item from a list: advance watchers to the next 3042 * item. 3043 */ 3044 static void 3045 list_fix_watch(l, item) 3046 list_T *l; 3047 listitem_T *item; 3048 { 3049 listwatch_T *lw; 3050 3051 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3052 if (lw->lw_item == item) 3053 lw->lw_item = item->li_next; 3054 } 3055 3056 /* 3057 * Evaluate the expression used in a ":for var in expr" command. 3058 * "arg" points to "var". 3059 * Set "*errp" to TRUE for an error, FALSE otherwise; 3060 * Return a pointer that holds the info. Null when there is an error. 3061 */ 3062 void * 3063 eval_for_line(arg, errp, nextcmdp, skip) 3064 char_u *arg; 3065 int *errp; 3066 char_u **nextcmdp; 3067 int skip; 3068 { 3069 forinfo_T *fi; 3070 char_u *expr; 3071 typval_T tv; 3072 list_T *l; 3073 3074 *errp = TRUE; /* default: there is an error */ 3075 3076 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 3077 if (fi == NULL) 3078 return NULL; 3079 3080 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 3081 if (expr == NULL) 3082 return fi; 3083 3084 expr = skipwhite(expr); 3085 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 3086 { 3087 EMSG(_("E690: Missing \"in\" after :for")); 3088 return fi; 3089 } 3090 3091 if (skip) 3092 ++emsg_skip; 3093 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 3094 { 3095 *errp = FALSE; 3096 if (!skip) 3097 { 3098 l = tv.vval.v_list; 3099 if (tv.v_type != VAR_LIST || l == NULL) 3100 { 3101 EMSG(_(e_listreq)); 3102 clear_tv(&tv); 3103 } 3104 else 3105 { 3106 /* No need to increment the refcount, it's already set for the 3107 * list being used in "tv". */ 3108 fi->fi_list = l; 3109 list_add_watch(l, &fi->fi_lw); 3110 fi->fi_lw.lw_item = l->lv_first; 3111 } 3112 } 3113 } 3114 if (skip) 3115 --emsg_skip; 3116 3117 return fi; 3118 } 3119 3120 /* 3121 * Use the first item in a ":for" list. Advance to the next. 3122 * Assign the values to the variable (list). "arg" points to the first one. 3123 * Return TRUE when a valid item was found, FALSE when at end of list or 3124 * something wrong. 3125 */ 3126 int 3127 next_for_item(fi_void, arg) 3128 void *fi_void; 3129 char_u *arg; 3130 { 3131 forinfo_T *fi = (forinfo_T *)fi_void; 3132 int result; 3133 listitem_T *item; 3134 3135 item = fi->fi_lw.lw_item; 3136 if (item == NULL) 3137 result = FALSE; 3138 else 3139 { 3140 fi->fi_lw.lw_item = item->li_next; 3141 result = (ex_let_vars(arg, &item->li_tv, TRUE, 3142 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 3143 } 3144 return result; 3145 } 3146 3147 /* 3148 * Free the structure used to store info used by ":for". 3149 */ 3150 void 3151 free_for_info(fi_void) 3152 void *fi_void; 3153 { 3154 forinfo_T *fi = (forinfo_T *)fi_void; 3155 3156 if (fi != NULL && fi->fi_list != NULL) 3157 { 3158 list_rem_watch(fi->fi_list, &fi->fi_lw); 3159 list_unref(fi->fi_list); 3160 } 3161 vim_free(fi); 3162 } 3163 3164 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3165 3166 void 3167 set_context_for_expression(xp, arg, cmdidx) 3168 expand_T *xp; 3169 char_u *arg; 3170 cmdidx_T cmdidx; 3171 { 3172 int got_eq = FALSE; 3173 int c; 3174 char_u *p; 3175 3176 if (cmdidx == CMD_let) 3177 { 3178 xp->xp_context = EXPAND_USER_VARS; 3179 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3180 { 3181 /* ":let var1 var2 ...": find last space. */ 3182 for (p = arg + STRLEN(arg); p >= arg; ) 3183 { 3184 xp->xp_pattern = p; 3185 mb_ptr_back(arg, p); 3186 if (vim_iswhite(*p)) 3187 break; 3188 } 3189 return; 3190 } 3191 } 3192 else 3193 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3194 : EXPAND_EXPRESSION; 3195 while ((xp->xp_pattern = vim_strpbrk(arg, 3196 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3197 { 3198 c = *xp->xp_pattern; 3199 if (c == '&') 3200 { 3201 c = xp->xp_pattern[1]; 3202 if (c == '&') 3203 { 3204 ++xp->xp_pattern; 3205 xp->xp_context = cmdidx != CMD_let || got_eq 3206 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3207 } 3208 else if (c != ' ') 3209 { 3210 xp->xp_context = EXPAND_SETTINGS; 3211 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3212 xp->xp_pattern += 2; 3213 3214 } 3215 } 3216 else if (c == '$') 3217 { 3218 /* environment variable */ 3219 xp->xp_context = EXPAND_ENV_VARS; 3220 } 3221 else if (c == '=') 3222 { 3223 got_eq = TRUE; 3224 xp->xp_context = EXPAND_EXPRESSION; 3225 } 3226 else if (c == '<' 3227 && xp->xp_context == EXPAND_FUNCTIONS 3228 && vim_strchr(xp->xp_pattern, '(') == NULL) 3229 { 3230 /* Function name can start with "<SNR>" */ 3231 break; 3232 } 3233 else if (cmdidx != CMD_let || got_eq) 3234 { 3235 if (c == '"') /* string */ 3236 { 3237 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3238 if (c == '\\' && xp->xp_pattern[1] != NUL) 3239 ++xp->xp_pattern; 3240 xp->xp_context = EXPAND_NOTHING; 3241 } 3242 else if (c == '\'') /* literal string */ 3243 { 3244 /* Trick: '' is like stopping and starting a literal string. */ 3245 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3246 /* skip */ ; 3247 xp->xp_context = EXPAND_NOTHING; 3248 } 3249 else if (c == '|') 3250 { 3251 if (xp->xp_pattern[1] == '|') 3252 { 3253 ++xp->xp_pattern; 3254 xp->xp_context = EXPAND_EXPRESSION; 3255 } 3256 else 3257 xp->xp_context = EXPAND_COMMANDS; 3258 } 3259 else 3260 xp->xp_context = EXPAND_EXPRESSION; 3261 } 3262 else 3263 /* Doesn't look like something valid, expand as an expression 3264 * anyway. */ 3265 xp->xp_context = EXPAND_EXPRESSION; 3266 arg = xp->xp_pattern; 3267 if (*arg != NUL) 3268 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3269 /* skip */ ; 3270 } 3271 xp->xp_pattern = arg; 3272 } 3273 3274 #endif /* FEAT_CMDL_COMPL */ 3275 3276 /* 3277 * ":1,25call func(arg1, arg2)" function call. 3278 */ 3279 void 3280 ex_call(eap) 3281 exarg_T *eap; 3282 { 3283 char_u *arg = eap->arg; 3284 char_u *startarg; 3285 char_u *name; 3286 char_u *tofree; 3287 int len; 3288 typval_T rettv; 3289 linenr_T lnum; 3290 int doesrange; 3291 int failed = FALSE; 3292 funcdict_T fudi; 3293 3294 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3295 if (fudi.fd_newkey != NULL) 3296 { 3297 /* Still need to give an error message for missing key. */ 3298 EMSG2(_(e_dictkey), fudi.fd_newkey); 3299 vim_free(fudi.fd_newkey); 3300 } 3301 if (tofree == NULL) 3302 return; 3303 3304 /* Increase refcount on dictionary, it could get deleted when evaluating 3305 * the arguments. */ 3306 if (fudi.fd_dict != NULL) 3307 ++fudi.fd_dict->dv_refcount; 3308 3309 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3310 len = (int)STRLEN(tofree); 3311 name = deref_func_name(tofree, &len); 3312 3313 /* Skip white space to allow ":call func ()". Not good, but required for 3314 * backward compatibility. */ 3315 startarg = skipwhite(arg); 3316 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3317 3318 if (*startarg != '(') 3319 { 3320 EMSG2(_("E107: Missing parentheses: %s"), eap->arg); 3321 goto end; 3322 } 3323 3324 /* 3325 * When skipping, evaluate the function once, to find the end of the 3326 * arguments. 3327 * When the function takes a range, this is discovered after the first 3328 * call, and the loop is broken. 3329 */ 3330 if (eap->skip) 3331 { 3332 ++emsg_skip; 3333 lnum = eap->line2; /* do it once, also with an invalid range */ 3334 } 3335 else 3336 lnum = eap->line1; 3337 for ( ; lnum <= eap->line2; ++lnum) 3338 { 3339 if (!eap->skip && eap->addr_count > 0) 3340 { 3341 curwin->w_cursor.lnum = lnum; 3342 curwin->w_cursor.col = 0; 3343 } 3344 arg = startarg; 3345 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3346 eap->line1, eap->line2, &doesrange, 3347 !eap->skip, fudi.fd_dict) == FAIL) 3348 { 3349 failed = TRUE; 3350 break; 3351 } 3352 3353 /* Handle a function returning a Funcref, Dictionary or List. */ 3354 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) 3355 { 3356 failed = TRUE; 3357 break; 3358 } 3359 3360 clear_tv(&rettv); 3361 if (doesrange || eap->skip) 3362 break; 3363 3364 /* Stop when immediately aborting on error, or when an interrupt 3365 * occurred or an exception was thrown but not caught. 3366 * get_func_tv() returned OK, so that the check for trailing 3367 * characters below is executed. */ 3368 if (aborting()) 3369 break; 3370 } 3371 if (eap->skip) 3372 --emsg_skip; 3373 3374 if (!failed) 3375 { 3376 /* Check for trailing illegal characters and a following command. */ 3377 if (!ends_excmd(*arg)) 3378 { 3379 emsg_severe = TRUE; 3380 EMSG(_(e_trailing)); 3381 } 3382 else 3383 eap->nextcmd = check_nextcmd(arg); 3384 } 3385 3386 end: 3387 dict_unref(fudi.fd_dict); 3388 vim_free(tofree); 3389 } 3390 3391 /* 3392 * ":unlet[!] var1 ... " command. 3393 */ 3394 void 3395 ex_unlet(eap) 3396 exarg_T *eap; 3397 { 3398 ex_unletlock(eap, eap->arg, 0); 3399 } 3400 3401 /* 3402 * ":lockvar" and ":unlockvar" commands 3403 */ 3404 void 3405 ex_lockvar(eap) 3406 exarg_T *eap; 3407 { 3408 char_u *arg = eap->arg; 3409 int deep = 2; 3410 3411 if (eap->forceit) 3412 deep = -1; 3413 else if (vim_isdigit(*arg)) 3414 { 3415 deep = getdigits(&arg); 3416 arg = skipwhite(arg); 3417 } 3418 3419 ex_unletlock(eap, arg, deep); 3420 } 3421 3422 /* 3423 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3424 */ 3425 static void 3426 ex_unletlock(eap, argstart, deep) 3427 exarg_T *eap; 3428 char_u *argstart; 3429 int deep; 3430 { 3431 char_u *arg = argstart; 3432 char_u *name_end; 3433 int error = FALSE; 3434 lval_T lv; 3435 3436 do 3437 { 3438 /* Parse the name and find the end. */ 3439 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3440 FNE_CHECK_START); 3441 if (lv.ll_name == NULL) 3442 error = TRUE; /* error but continue parsing */ 3443 if (name_end == NULL || (!vim_iswhite(*name_end) 3444 && !ends_excmd(*name_end))) 3445 { 3446 if (name_end != NULL) 3447 { 3448 emsg_severe = TRUE; 3449 EMSG(_(e_trailing)); 3450 } 3451 if (!(eap->skip || error)) 3452 clear_lval(&lv); 3453 break; 3454 } 3455 3456 if (!error && !eap->skip) 3457 { 3458 if (eap->cmdidx == CMD_unlet) 3459 { 3460 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3461 error = TRUE; 3462 } 3463 else 3464 { 3465 if (do_lock_var(&lv, name_end, deep, 3466 eap->cmdidx == CMD_lockvar) == FAIL) 3467 error = TRUE; 3468 } 3469 } 3470 3471 if (!eap->skip) 3472 clear_lval(&lv); 3473 3474 arg = skipwhite(name_end); 3475 } while (!ends_excmd(*arg)); 3476 3477 eap->nextcmd = check_nextcmd(arg); 3478 } 3479 3480 static int 3481 do_unlet_var(lp, name_end, forceit) 3482 lval_T *lp; 3483 char_u *name_end; 3484 int forceit; 3485 { 3486 int ret = OK; 3487 int cc; 3488 3489 if (lp->ll_tv == NULL) 3490 { 3491 cc = *name_end; 3492 *name_end = NUL; 3493 3494 /* Normal name or expanded name. */ 3495 if (check_changedtick(lp->ll_name)) 3496 ret = FAIL; 3497 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3498 ret = FAIL; 3499 *name_end = cc; 3500 } 3501 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3502 return FAIL; 3503 else if (lp->ll_range) 3504 { 3505 listitem_T *li; 3506 3507 /* Delete a range of List items. */ 3508 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3509 { 3510 li = lp->ll_li->li_next; 3511 listitem_remove(lp->ll_list, lp->ll_li); 3512 lp->ll_li = li; 3513 ++lp->ll_n1; 3514 } 3515 } 3516 else 3517 { 3518 if (lp->ll_list != NULL) 3519 /* unlet a List item. */ 3520 listitem_remove(lp->ll_list, lp->ll_li); 3521 else 3522 /* unlet a Dictionary item. */ 3523 dictitem_remove(lp->ll_dict, lp->ll_di); 3524 } 3525 3526 return ret; 3527 } 3528 3529 /* 3530 * "unlet" a variable. Return OK if it existed, FAIL if not. 3531 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3532 */ 3533 int 3534 do_unlet(name, forceit) 3535 char_u *name; 3536 int forceit; 3537 { 3538 hashtab_T *ht; 3539 hashitem_T *hi; 3540 char_u *varname; 3541 dictitem_T *di; 3542 3543 ht = find_var_ht(name, &varname); 3544 if (ht != NULL && *varname != NUL) 3545 { 3546 hi = hash_find(ht, varname); 3547 if (!HASHITEM_EMPTY(hi)) 3548 { 3549 di = HI2DI(hi); 3550 if (var_check_fixed(di->di_flags, name) 3551 || var_check_ro(di->di_flags, name)) 3552 return FAIL; 3553 delete_var(ht, hi); 3554 return OK; 3555 } 3556 } 3557 if (forceit) 3558 return OK; 3559 EMSG2(_("E108: No such variable: \"%s\""), name); 3560 return FAIL; 3561 } 3562 3563 /* 3564 * Lock or unlock variable indicated by "lp". 3565 * "deep" is the levels to go (-1 for unlimited); 3566 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3567 */ 3568 static int 3569 do_lock_var(lp, name_end, deep, lock) 3570 lval_T *lp; 3571 char_u *name_end; 3572 int deep; 3573 int lock; 3574 { 3575 int ret = OK; 3576 int cc; 3577 dictitem_T *di; 3578 3579 if (deep == 0) /* nothing to do */ 3580 return OK; 3581 3582 if (lp->ll_tv == NULL) 3583 { 3584 cc = *name_end; 3585 *name_end = NUL; 3586 3587 /* Normal name or expanded name. */ 3588 if (check_changedtick(lp->ll_name)) 3589 ret = FAIL; 3590 else 3591 { 3592 di = find_var(lp->ll_name, NULL); 3593 if (di == NULL) 3594 ret = FAIL; 3595 else 3596 { 3597 if (lock) 3598 di->di_flags |= DI_FLAGS_LOCK; 3599 else 3600 di->di_flags &= ~DI_FLAGS_LOCK; 3601 item_lock(&di->di_tv, deep, lock); 3602 } 3603 } 3604 *name_end = cc; 3605 } 3606 else if (lp->ll_range) 3607 { 3608 listitem_T *li = lp->ll_li; 3609 3610 /* (un)lock a range of List items. */ 3611 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3612 { 3613 item_lock(&li->li_tv, deep, lock); 3614 li = li->li_next; 3615 ++lp->ll_n1; 3616 } 3617 } 3618 else if (lp->ll_list != NULL) 3619 /* (un)lock a List item. */ 3620 item_lock(&lp->ll_li->li_tv, deep, lock); 3621 else 3622 /* un(lock) a Dictionary item. */ 3623 item_lock(&lp->ll_di->di_tv, deep, lock); 3624 3625 return ret; 3626 } 3627 3628 /* 3629 * Lock or unlock an item. "deep" is nr of levels to go. 3630 */ 3631 static void 3632 item_lock(tv, deep, lock) 3633 typval_T *tv; 3634 int deep; 3635 int lock; 3636 { 3637 static int recurse = 0; 3638 list_T *l; 3639 listitem_T *li; 3640 dict_T *d; 3641 hashitem_T *hi; 3642 int todo; 3643 3644 if (recurse >= DICT_MAXNEST) 3645 { 3646 EMSG(_("E743: variable nested too deep for (un)lock")); 3647 return; 3648 } 3649 if (deep == 0) 3650 return; 3651 ++recurse; 3652 3653 /* lock/unlock the item itself */ 3654 if (lock) 3655 tv->v_lock |= VAR_LOCKED; 3656 else 3657 tv->v_lock &= ~VAR_LOCKED; 3658 3659 switch (tv->v_type) 3660 { 3661 case VAR_LIST: 3662 if ((l = tv->vval.v_list) != NULL) 3663 { 3664 if (lock) 3665 l->lv_lock |= VAR_LOCKED; 3666 else 3667 l->lv_lock &= ~VAR_LOCKED; 3668 if (deep < 0 || deep > 1) 3669 /* recursive: lock/unlock the items the List contains */ 3670 for (li = l->lv_first; li != NULL; li = li->li_next) 3671 item_lock(&li->li_tv, deep - 1, lock); 3672 } 3673 break; 3674 case VAR_DICT: 3675 if ((d = tv->vval.v_dict) != NULL) 3676 { 3677 if (lock) 3678 d->dv_lock |= VAR_LOCKED; 3679 else 3680 d->dv_lock &= ~VAR_LOCKED; 3681 if (deep < 0 || deep > 1) 3682 { 3683 /* recursive: lock/unlock the items the List contains */ 3684 todo = (int)d->dv_hashtab.ht_used; 3685 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3686 { 3687 if (!HASHITEM_EMPTY(hi)) 3688 { 3689 --todo; 3690 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3691 } 3692 } 3693 } 3694 } 3695 } 3696 --recurse; 3697 } 3698 3699 /* 3700 * Return TRUE if typeval "tv" is locked: Either that value is locked itself 3701 * or it refers to a List or Dictionary that is locked. 3702 */ 3703 static int 3704 tv_islocked(tv) 3705 typval_T *tv; 3706 { 3707 return (tv->v_lock & VAR_LOCKED) 3708 || (tv->v_type == VAR_LIST 3709 && tv->vval.v_list != NULL 3710 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3711 || (tv->v_type == VAR_DICT 3712 && tv->vval.v_dict != NULL 3713 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3714 } 3715 3716 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3717 /* 3718 * Delete all "menutrans_" variables. 3719 */ 3720 void 3721 del_menutrans_vars() 3722 { 3723 hashitem_T *hi; 3724 int todo; 3725 3726 hash_lock(&globvarht); 3727 todo = (int)globvarht.ht_used; 3728 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3729 { 3730 if (!HASHITEM_EMPTY(hi)) 3731 { 3732 --todo; 3733 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3734 delete_var(&globvarht, hi); 3735 } 3736 } 3737 hash_unlock(&globvarht); 3738 } 3739 #endif 3740 3741 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3742 3743 /* 3744 * Local string buffer for the next two functions to store a variable name 3745 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3746 * get_user_var_name(). 3747 */ 3748 3749 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3750 3751 static char_u *varnamebuf = NULL; 3752 static int varnamebuflen = 0; 3753 3754 /* 3755 * Function to concatenate a prefix and a variable name. 3756 */ 3757 static char_u * 3758 cat_prefix_varname(prefix, name) 3759 int prefix; 3760 char_u *name; 3761 { 3762 int len; 3763 3764 len = (int)STRLEN(name) + 3; 3765 if (len > varnamebuflen) 3766 { 3767 vim_free(varnamebuf); 3768 len += 10; /* some additional space */ 3769 varnamebuf = alloc(len); 3770 if (varnamebuf == NULL) 3771 { 3772 varnamebuflen = 0; 3773 return NULL; 3774 } 3775 varnamebuflen = len; 3776 } 3777 *varnamebuf = prefix; 3778 varnamebuf[1] = ':'; 3779 STRCPY(varnamebuf + 2, name); 3780 return varnamebuf; 3781 } 3782 3783 /* 3784 * Function given to ExpandGeneric() to obtain the list of user defined 3785 * (global/buffer/window/built-in) variable names. 3786 */ 3787 char_u * 3788 get_user_var_name(xp, idx) 3789 expand_T *xp; 3790 int idx; 3791 { 3792 static long_u gdone; 3793 static long_u bdone; 3794 static long_u wdone; 3795 #ifdef FEAT_WINDOWS 3796 static long_u tdone; 3797 #endif 3798 static int vidx; 3799 static hashitem_T *hi; 3800 hashtab_T *ht; 3801 3802 if (idx == 0) 3803 { 3804 gdone = bdone = wdone = vidx = 0; 3805 #ifdef FEAT_WINDOWS 3806 tdone = 0; 3807 #endif 3808 } 3809 3810 /* Global variables */ 3811 if (gdone < globvarht.ht_used) 3812 { 3813 if (gdone++ == 0) 3814 hi = globvarht.ht_array; 3815 else 3816 ++hi; 3817 while (HASHITEM_EMPTY(hi)) 3818 ++hi; 3819 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3820 return cat_prefix_varname('g', hi->hi_key); 3821 return hi->hi_key; 3822 } 3823 3824 /* b: variables */ 3825 ht = &curbuf->b_vars.dv_hashtab; 3826 if (bdone < ht->ht_used) 3827 { 3828 if (bdone++ == 0) 3829 hi = ht->ht_array; 3830 else 3831 ++hi; 3832 while (HASHITEM_EMPTY(hi)) 3833 ++hi; 3834 return cat_prefix_varname('b', hi->hi_key); 3835 } 3836 if (bdone == ht->ht_used) 3837 { 3838 ++bdone; 3839 return (char_u *)"b:changedtick"; 3840 } 3841 3842 /* w: variables */ 3843 ht = &curwin->w_vars.dv_hashtab; 3844 if (wdone < ht->ht_used) 3845 { 3846 if (wdone++ == 0) 3847 hi = ht->ht_array; 3848 else 3849 ++hi; 3850 while (HASHITEM_EMPTY(hi)) 3851 ++hi; 3852 return cat_prefix_varname('w', hi->hi_key); 3853 } 3854 3855 #ifdef FEAT_WINDOWS 3856 /* t: variables */ 3857 ht = &curtab->tp_vars.dv_hashtab; 3858 if (tdone < ht->ht_used) 3859 { 3860 if (tdone++ == 0) 3861 hi = ht->ht_array; 3862 else 3863 ++hi; 3864 while (HASHITEM_EMPTY(hi)) 3865 ++hi; 3866 return cat_prefix_varname('t', hi->hi_key); 3867 } 3868 #endif 3869 3870 /* v: variables */ 3871 if (vidx < VV_LEN) 3872 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3873 3874 vim_free(varnamebuf); 3875 varnamebuf = NULL; 3876 varnamebuflen = 0; 3877 return NULL; 3878 } 3879 3880 #endif /* FEAT_CMDL_COMPL */ 3881 3882 /* 3883 * types for expressions. 3884 */ 3885 typedef enum 3886 { 3887 TYPE_UNKNOWN = 0 3888 , TYPE_EQUAL /* == */ 3889 , TYPE_NEQUAL /* != */ 3890 , TYPE_GREATER /* > */ 3891 , TYPE_GEQUAL /* >= */ 3892 , TYPE_SMALLER /* < */ 3893 , TYPE_SEQUAL /* <= */ 3894 , TYPE_MATCH /* =~ */ 3895 , TYPE_NOMATCH /* !~ */ 3896 } exptype_T; 3897 3898 /* 3899 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3900 * executed. The function may return OK, but the rettv will be of type 3901 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3902 */ 3903 3904 /* 3905 * Handle zero level expression. 3906 * This calls eval1() and handles error message and nextcmd. 3907 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3908 * Note: "rettv.v_lock" is not set. 3909 * Return OK or FAIL. 3910 */ 3911 static int 3912 eval0(arg, rettv, nextcmd, evaluate) 3913 char_u *arg; 3914 typval_T *rettv; 3915 char_u **nextcmd; 3916 int evaluate; 3917 { 3918 int ret; 3919 char_u *p; 3920 3921 p = skipwhite(arg); 3922 ret = eval1(&p, rettv, evaluate); 3923 if (ret == FAIL || !ends_excmd(*p)) 3924 { 3925 if (ret != FAIL) 3926 clear_tv(rettv); 3927 /* 3928 * Report the invalid expression unless the expression evaluation has 3929 * been cancelled due to an aborting error, an interrupt, or an 3930 * exception. 3931 */ 3932 if (!aborting()) 3933 EMSG2(_(e_invexpr2), arg); 3934 ret = FAIL; 3935 } 3936 if (nextcmd != NULL) 3937 *nextcmd = check_nextcmd(p); 3938 3939 return ret; 3940 } 3941 3942 /* 3943 * Handle top level expression: 3944 * expr2 ? expr1 : expr1 3945 * 3946 * "arg" must point to the first non-white of the expression. 3947 * "arg" is advanced to the next non-white after the recognized expression. 3948 * 3949 * Note: "rettv.v_lock" is not set. 3950 * 3951 * Return OK or FAIL. 3952 */ 3953 static int 3954 eval1(arg, rettv, evaluate) 3955 char_u **arg; 3956 typval_T *rettv; 3957 int evaluate; 3958 { 3959 int result; 3960 typval_T var2; 3961 3962 /* 3963 * Get the first variable. 3964 */ 3965 if (eval2(arg, rettv, evaluate) == FAIL) 3966 return FAIL; 3967 3968 if ((*arg)[0] == '?') 3969 { 3970 result = FALSE; 3971 if (evaluate) 3972 { 3973 int error = FALSE; 3974 3975 if (get_tv_number_chk(rettv, &error) != 0) 3976 result = TRUE; 3977 clear_tv(rettv); 3978 if (error) 3979 return FAIL; 3980 } 3981 3982 /* 3983 * Get the second variable. 3984 */ 3985 *arg = skipwhite(*arg + 1); 3986 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3987 return FAIL; 3988 3989 /* 3990 * Check for the ":". 3991 */ 3992 if ((*arg)[0] != ':') 3993 { 3994 EMSG(_("E109: Missing ':' after '?'")); 3995 if (evaluate && result) 3996 clear_tv(rettv); 3997 return FAIL; 3998 } 3999 4000 /* 4001 * Get the third variable. 4002 */ 4003 *arg = skipwhite(*arg + 1); 4004 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 4005 { 4006 if (evaluate && result) 4007 clear_tv(rettv); 4008 return FAIL; 4009 } 4010 if (evaluate && !result) 4011 *rettv = var2; 4012 } 4013 4014 return OK; 4015 } 4016 4017 /* 4018 * Handle first level expression: 4019 * expr2 || expr2 || expr2 logical OR 4020 * 4021 * "arg" must point to the first non-white of the expression. 4022 * "arg" is advanced to the next non-white after the recognized expression. 4023 * 4024 * Return OK or FAIL. 4025 */ 4026 static int 4027 eval2(arg, rettv, evaluate) 4028 char_u **arg; 4029 typval_T *rettv; 4030 int evaluate; 4031 { 4032 typval_T var2; 4033 long result; 4034 int first; 4035 int error = FALSE; 4036 4037 /* 4038 * Get the first variable. 4039 */ 4040 if (eval3(arg, rettv, evaluate) == FAIL) 4041 return FAIL; 4042 4043 /* 4044 * Repeat until there is no following "||". 4045 */ 4046 first = TRUE; 4047 result = FALSE; 4048 while ((*arg)[0] == '|' && (*arg)[1] == '|') 4049 { 4050 if (evaluate && first) 4051 { 4052 if (get_tv_number_chk(rettv, &error) != 0) 4053 result = TRUE; 4054 clear_tv(rettv); 4055 if (error) 4056 return FAIL; 4057 first = FALSE; 4058 } 4059 4060 /* 4061 * Get the second variable. 4062 */ 4063 *arg = skipwhite(*arg + 2); 4064 if (eval3(arg, &var2, evaluate && !result) == FAIL) 4065 return FAIL; 4066 4067 /* 4068 * Compute the result. 4069 */ 4070 if (evaluate && !result) 4071 { 4072 if (get_tv_number_chk(&var2, &error) != 0) 4073 result = TRUE; 4074 clear_tv(&var2); 4075 if (error) 4076 return FAIL; 4077 } 4078 if (evaluate) 4079 { 4080 rettv->v_type = VAR_NUMBER; 4081 rettv->vval.v_number = result; 4082 } 4083 } 4084 4085 return OK; 4086 } 4087 4088 /* 4089 * Handle second level expression: 4090 * expr3 && expr3 && expr3 logical AND 4091 * 4092 * "arg" must point to the first non-white of the expression. 4093 * "arg" is advanced to the next non-white after the recognized expression. 4094 * 4095 * Return OK or FAIL. 4096 */ 4097 static int 4098 eval3(arg, rettv, evaluate) 4099 char_u **arg; 4100 typval_T *rettv; 4101 int evaluate; 4102 { 4103 typval_T var2; 4104 long result; 4105 int first; 4106 int error = FALSE; 4107 4108 /* 4109 * Get the first variable. 4110 */ 4111 if (eval4(arg, rettv, evaluate) == FAIL) 4112 return FAIL; 4113 4114 /* 4115 * Repeat until there is no following "&&". 4116 */ 4117 first = TRUE; 4118 result = TRUE; 4119 while ((*arg)[0] == '&' && (*arg)[1] == '&') 4120 { 4121 if (evaluate && first) 4122 { 4123 if (get_tv_number_chk(rettv, &error) == 0) 4124 result = FALSE; 4125 clear_tv(rettv); 4126 if (error) 4127 return FAIL; 4128 first = FALSE; 4129 } 4130 4131 /* 4132 * Get the second variable. 4133 */ 4134 *arg = skipwhite(*arg + 2); 4135 if (eval4(arg, &var2, evaluate && result) == FAIL) 4136 return FAIL; 4137 4138 /* 4139 * Compute the result. 4140 */ 4141 if (evaluate && result) 4142 { 4143 if (get_tv_number_chk(&var2, &error) == 0) 4144 result = FALSE; 4145 clear_tv(&var2); 4146 if (error) 4147 return FAIL; 4148 } 4149 if (evaluate) 4150 { 4151 rettv->v_type = VAR_NUMBER; 4152 rettv->vval.v_number = result; 4153 } 4154 } 4155 4156 return OK; 4157 } 4158 4159 /* 4160 * Handle third level expression: 4161 * var1 == var2 4162 * var1 =~ var2 4163 * var1 != var2 4164 * var1 !~ var2 4165 * var1 > var2 4166 * var1 >= var2 4167 * var1 < var2 4168 * var1 <= var2 4169 * var1 is var2 4170 * var1 isnot var2 4171 * 4172 * "arg" must point to the first non-white of the expression. 4173 * "arg" is advanced to the next non-white after the recognized expression. 4174 * 4175 * Return OK or FAIL. 4176 */ 4177 static int 4178 eval4(arg, rettv, evaluate) 4179 char_u **arg; 4180 typval_T *rettv; 4181 int evaluate; 4182 { 4183 typval_T var2; 4184 char_u *p; 4185 int i; 4186 exptype_T type = TYPE_UNKNOWN; 4187 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 4188 int len = 2; 4189 long n1, n2; 4190 char_u *s1, *s2; 4191 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4192 regmatch_T regmatch; 4193 int ic; 4194 char_u *save_cpo; 4195 4196 /* 4197 * Get the first variable. 4198 */ 4199 if (eval5(arg, rettv, evaluate) == FAIL) 4200 return FAIL; 4201 4202 p = *arg; 4203 switch (p[0]) 4204 { 4205 case '=': if (p[1] == '=') 4206 type = TYPE_EQUAL; 4207 else if (p[1] == '~') 4208 type = TYPE_MATCH; 4209 break; 4210 case '!': if (p[1] == '=') 4211 type = TYPE_NEQUAL; 4212 else if (p[1] == '~') 4213 type = TYPE_NOMATCH; 4214 break; 4215 case '>': if (p[1] != '=') 4216 { 4217 type = TYPE_GREATER; 4218 len = 1; 4219 } 4220 else 4221 type = TYPE_GEQUAL; 4222 break; 4223 case '<': if (p[1] != '=') 4224 { 4225 type = TYPE_SMALLER; 4226 len = 1; 4227 } 4228 else 4229 type = TYPE_SEQUAL; 4230 break; 4231 case 'i': if (p[1] == 's') 4232 { 4233 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4234 len = 5; 4235 if (!vim_isIDc(p[len])) 4236 { 4237 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4238 type_is = TRUE; 4239 } 4240 } 4241 break; 4242 } 4243 4244 /* 4245 * If there is a comparative operator, use it. 4246 */ 4247 if (type != TYPE_UNKNOWN) 4248 { 4249 /* extra question mark appended: ignore case */ 4250 if (p[len] == '?') 4251 { 4252 ic = TRUE; 4253 ++len; 4254 } 4255 /* extra '#' appended: match case */ 4256 else if (p[len] == '#') 4257 { 4258 ic = FALSE; 4259 ++len; 4260 } 4261 /* nothing appended: use 'ignorecase' */ 4262 else 4263 ic = p_ic; 4264 4265 /* 4266 * Get the second variable. 4267 */ 4268 *arg = skipwhite(p + len); 4269 if (eval5(arg, &var2, evaluate) == FAIL) 4270 { 4271 clear_tv(rettv); 4272 return FAIL; 4273 } 4274 4275 if (evaluate) 4276 { 4277 if (type_is && rettv->v_type != var2.v_type) 4278 { 4279 /* For "is" a different type always means FALSE, for "notis" 4280 * it means TRUE. */ 4281 n1 = (type == TYPE_NEQUAL); 4282 } 4283 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4284 { 4285 if (type_is) 4286 { 4287 n1 = (rettv->v_type == var2.v_type 4288 && rettv->vval.v_list == var2.vval.v_list); 4289 if (type == TYPE_NEQUAL) 4290 n1 = !n1; 4291 } 4292 else if (rettv->v_type != var2.v_type 4293 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4294 { 4295 if (rettv->v_type != var2.v_type) 4296 EMSG(_("E691: Can only compare List with List")); 4297 else 4298 EMSG(_("E692: Invalid operation for Lists")); 4299 clear_tv(rettv); 4300 clear_tv(&var2); 4301 return FAIL; 4302 } 4303 else 4304 { 4305 /* Compare two Lists for being equal or unequal. */ 4306 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 4307 if (type == TYPE_NEQUAL) 4308 n1 = !n1; 4309 } 4310 } 4311 4312 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4313 { 4314 if (type_is) 4315 { 4316 n1 = (rettv->v_type == var2.v_type 4317 && rettv->vval.v_dict == var2.vval.v_dict); 4318 if (type == TYPE_NEQUAL) 4319 n1 = !n1; 4320 } 4321 else if (rettv->v_type != var2.v_type 4322 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4323 { 4324 if (rettv->v_type != var2.v_type) 4325 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4326 else 4327 EMSG(_("E736: Invalid operation for Dictionary")); 4328 clear_tv(rettv); 4329 clear_tv(&var2); 4330 return FAIL; 4331 } 4332 else 4333 { 4334 /* Compare two Dictionaries for being equal or unequal. */ 4335 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4336 if (type == TYPE_NEQUAL) 4337 n1 = !n1; 4338 } 4339 } 4340 4341 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4342 { 4343 if (rettv->v_type != var2.v_type 4344 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4345 { 4346 if (rettv->v_type != var2.v_type) 4347 EMSG(_("E693: Can only compare Funcref with Funcref")); 4348 else 4349 EMSG(_("E694: Invalid operation for Funcrefs")); 4350 clear_tv(rettv); 4351 clear_tv(&var2); 4352 return FAIL; 4353 } 4354 else 4355 { 4356 /* Compare two Funcrefs for being equal or unequal. */ 4357 if (rettv->vval.v_string == NULL 4358 || var2.vval.v_string == NULL) 4359 n1 = FALSE; 4360 else 4361 n1 = STRCMP(rettv->vval.v_string, 4362 var2.vval.v_string) == 0; 4363 if (type == TYPE_NEQUAL) 4364 n1 = !n1; 4365 } 4366 } 4367 4368 #ifdef FEAT_FLOAT 4369 /* 4370 * If one of the two variables is a float, compare as a float. 4371 * When using "=~" or "!~", always compare as string. 4372 */ 4373 else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4374 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4375 { 4376 float_T f1, f2; 4377 4378 if (rettv->v_type == VAR_FLOAT) 4379 f1 = rettv->vval.v_float; 4380 else 4381 f1 = get_tv_number(rettv); 4382 if (var2.v_type == VAR_FLOAT) 4383 f2 = var2.vval.v_float; 4384 else 4385 f2 = get_tv_number(&var2); 4386 n1 = FALSE; 4387 switch (type) 4388 { 4389 case TYPE_EQUAL: n1 = (f1 == f2); break; 4390 case TYPE_NEQUAL: n1 = (f1 != f2); break; 4391 case TYPE_GREATER: n1 = (f1 > f2); break; 4392 case TYPE_GEQUAL: n1 = (f1 >= f2); break; 4393 case TYPE_SMALLER: n1 = (f1 < f2); break; 4394 case TYPE_SEQUAL: n1 = (f1 <= f2); break; 4395 case TYPE_UNKNOWN: 4396 case TYPE_MATCH: 4397 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4398 } 4399 } 4400 #endif 4401 4402 /* 4403 * If one of the two variables is a number, compare as a number. 4404 * When using "=~" or "!~", always compare as string. 4405 */ 4406 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4407 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4408 { 4409 n1 = get_tv_number(rettv); 4410 n2 = get_tv_number(&var2); 4411 switch (type) 4412 { 4413 case TYPE_EQUAL: n1 = (n1 == n2); break; 4414 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4415 case TYPE_GREATER: n1 = (n1 > n2); break; 4416 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4417 case TYPE_SMALLER: n1 = (n1 < n2); break; 4418 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4419 case TYPE_UNKNOWN: 4420 case TYPE_MATCH: 4421 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4422 } 4423 } 4424 else 4425 { 4426 s1 = get_tv_string_buf(rettv, buf1); 4427 s2 = get_tv_string_buf(&var2, buf2); 4428 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4429 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4430 else 4431 i = 0; 4432 n1 = FALSE; 4433 switch (type) 4434 { 4435 case TYPE_EQUAL: n1 = (i == 0); break; 4436 case TYPE_NEQUAL: n1 = (i != 0); break; 4437 case TYPE_GREATER: n1 = (i > 0); break; 4438 case TYPE_GEQUAL: n1 = (i >= 0); break; 4439 case TYPE_SMALLER: n1 = (i < 0); break; 4440 case TYPE_SEQUAL: n1 = (i <= 0); break; 4441 4442 case TYPE_MATCH: 4443 case TYPE_NOMATCH: 4444 /* avoid 'l' flag in 'cpoptions' */ 4445 save_cpo = p_cpo; 4446 p_cpo = (char_u *)""; 4447 regmatch.regprog = vim_regcomp(s2, 4448 RE_MAGIC + RE_STRING); 4449 regmatch.rm_ic = ic; 4450 if (regmatch.regprog != NULL) 4451 { 4452 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4453 vim_free(regmatch.regprog); 4454 if (type == TYPE_NOMATCH) 4455 n1 = !n1; 4456 } 4457 p_cpo = save_cpo; 4458 break; 4459 4460 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4461 } 4462 } 4463 clear_tv(rettv); 4464 clear_tv(&var2); 4465 rettv->v_type = VAR_NUMBER; 4466 rettv->vval.v_number = n1; 4467 } 4468 } 4469 4470 return OK; 4471 } 4472 4473 /* 4474 * Handle fourth level expression: 4475 * + number addition 4476 * - number subtraction 4477 * . string concatenation 4478 * 4479 * "arg" must point to the first non-white of the expression. 4480 * "arg" is advanced to the next non-white after the recognized expression. 4481 * 4482 * Return OK or FAIL. 4483 */ 4484 static int 4485 eval5(arg, rettv, evaluate) 4486 char_u **arg; 4487 typval_T *rettv; 4488 int evaluate; 4489 { 4490 typval_T var2; 4491 typval_T var3; 4492 int op; 4493 long n1, n2; 4494 #ifdef FEAT_FLOAT 4495 float_T f1 = 0, f2 = 0; 4496 #endif 4497 char_u *s1, *s2; 4498 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4499 char_u *p; 4500 4501 /* 4502 * Get the first variable. 4503 */ 4504 if (eval6(arg, rettv, evaluate, FALSE) == FAIL) 4505 return FAIL; 4506 4507 /* 4508 * Repeat computing, until no '+', '-' or '.' is following. 4509 */ 4510 for (;;) 4511 { 4512 op = **arg; 4513 if (op != '+' && op != '-' && op != '.') 4514 break; 4515 4516 if ((op != '+' || rettv->v_type != VAR_LIST) 4517 #ifdef FEAT_FLOAT 4518 && (op == '.' || rettv->v_type != VAR_FLOAT) 4519 #endif 4520 ) 4521 { 4522 /* For "list + ...", an illegal use of the first operand as 4523 * a number cannot be determined before evaluating the 2nd 4524 * operand: if this is also a list, all is ok. 4525 * For "something . ...", "something - ..." or "non-list + ...", 4526 * we know that the first operand needs to be a string or number 4527 * without evaluating the 2nd operand. So check before to avoid 4528 * side effects after an error. */ 4529 if (evaluate && get_tv_string_chk(rettv) == NULL) 4530 { 4531 clear_tv(rettv); 4532 return FAIL; 4533 } 4534 } 4535 4536 /* 4537 * Get the second variable. 4538 */ 4539 *arg = skipwhite(*arg + 1); 4540 if (eval6(arg, &var2, evaluate, op == '.') == FAIL) 4541 { 4542 clear_tv(rettv); 4543 return FAIL; 4544 } 4545 4546 if (evaluate) 4547 { 4548 /* 4549 * Compute the result. 4550 */ 4551 if (op == '.') 4552 { 4553 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4554 s2 = get_tv_string_buf_chk(&var2, buf2); 4555 if (s2 == NULL) /* type error ? */ 4556 { 4557 clear_tv(rettv); 4558 clear_tv(&var2); 4559 return FAIL; 4560 } 4561 p = concat_str(s1, s2); 4562 clear_tv(rettv); 4563 rettv->v_type = VAR_STRING; 4564 rettv->vval.v_string = p; 4565 } 4566 else if (op == '+' && rettv->v_type == VAR_LIST 4567 && var2.v_type == VAR_LIST) 4568 { 4569 /* concatenate Lists */ 4570 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4571 &var3) == FAIL) 4572 { 4573 clear_tv(rettv); 4574 clear_tv(&var2); 4575 return FAIL; 4576 } 4577 clear_tv(rettv); 4578 *rettv = var3; 4579 } 4580 else 4581 { 4582 int error = FALSE; 4583 4584 #ifdef FEAT_FLOAT 4585 if (rettv->v_type == VAR_FLOAT) 4586 { 4587 f1 = rettv->vval.v_float; 4588 n1 = 0; 4589 } 4590 else 4591 #endif 4592 { 4593 n1 = get_tv_number_chk(rettv, &error); 4594 if (error) 4595 { 4596 /* This can only happen for "list + non-list". For 4597 * "non-list + ..." or "something - ...", we returned 4598 * before evaluating the 2nd operand. */ 4599 clear_tv(rettv); 4600 return FAIL; 4601 } 4602 #ifdef FEAT_FLOAT 4603 if (var2.v_type == VAR_FLOAT) 4604 f1 = n1; 4605 #endif 4606 } 4607 #ifdef FEAT_FLOAT 4608 if (var2.v_type == VAR_FLOAT) 4609 { 4610 f2 = var2.vval.v_float; 4611 n2 = 0; 4612 } 4613 else 4614 #endif 4615 { 4616 n2 = get_tv_number_chk(&var2, &error); 4617 if (error) 4618 { 4619 clear_tv(rettv); 4620 clear_tv(&var2); 4621 return FAIL; 4622 } 4623 #ifdef FEAT_FLOAT 4624 if (rettv->v_type == VAR_FLOAT) 4625 f2 = n2; 4626 #endif 4627 } 4628 clear_tv(rettv); 4629 4630 #ifdef FEAT_FLOAT 4631 /* If there is a float on either side the result is a float. */ 4632 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4633 { 4634 if (op == '+') 4635 f1 = f1 + f2; 4636 else 4637 f1 = f1 - f2; 4638 rettv->v_type = VAR_FLOAT; 4639 rettv->vval.v_float = f1; 4640 } 4641 else 4642 #endif 4643 { 4644 if (op == '+') 4645 n1 = n1 + n2; 4646 else 4647 n1 = n1 - n2; 4648 rettv->v_type = VAR_NUMBER; 4649 rettv->vval.v_number = n1; 4650 } 4651 } 4652 clear_tv(&var2); 4653 } 4654 } 4655 return OK; 4656 } 4657 4658 /* 4659 * Handle fifth level expression: 4660 * * number multiplication 4661 * / number division 4662 * % number modulo 4663 * 4664 * "arg" must point to the first non-white of the expression. 4665 * "arg" is advanced to the next non-white after the recognized expression. 4666 * 4667 * Return OK or FAIL. 4668 */ 4669 static int 4670 eval6(arg, rettv, evaluate, want_string) 4671 char_u **arg; 4672 typval_T *rettv; 4673 int evaluate; 4674 int want_string; /* after "." operator */ 4675 { 4676 typval_T var2; 4677 int op; 4678 long n1, n2; 4679 #ifdef FEAT_FLOAT 4680 int use_float = FALSE; 4681 float_T f1 = 0, f2; 4682 #endif 4683 int error = FALSE; 4684 4685 /* 4686 * Get the first variable. 4687 */ 4688 if (eval7(arg, rettv, evaluate, want_string) == FAIL) 4689 return FAIL; 4690 4691 /* 4692 * Repeat computing, until no '*', '/' or '%' is following. 4693 */ 4694 for (;;) 4695 { 4696 op = **arg; 4697 if (op != '*' && op != '/' && op != '%') 4698 break; 4699 4700 if (evaluate) 4701 { 4702 #ifdef FEAT_FLOAT 4703 if (rettv->v_type == VAR_FLOAT) 4704 { 4705 f1 = rettv->vval.v_float; 4706 use_float = TRUE; 4707 n1 = 0; 4708 } 4709 else 4710 #endif 4711 n1 = get_tv_number_chk(rettv, &error); 4712 clear_tv(rettv); 4713 if (error) 4714 return FAIL; 4715 } 4716 else 4717 n1 = 0; 4718 4719 /* 4720 * Get the second variable. 4721 */ 4722 *arg = skipwhite(*arg + 1); 4723 if (eval7(arg, &var2, evaluate, FALSE) == FAIL) 4724 return FAIL; 4725 4726 if (evaluate) 4727 { 4728 #ifdef FEAT_FLOAT 4729 if (var2.v_type == VAR_FLOAT) 4730 { 4731 if (!use_float) 4732 { 4733 f1 = n1; 4734 use_float = TRUE; 4735 } 4736 f2 = var2.vval.v_float; 4737 n2 = 0; 4738 } 4739 else 4740 #endif 4741 { 4742 n2 = get_tv_number_chk(&var2, &error); 4743 clear_tv(&var2); 4744 if (error) 4745 return FAIL; 4746 #ifdef FEAT_FLOAT 4747 if (use_float) 4748 f2 = n2; 4749 #endif 4750 } 4751 4752 /* 4753 * Compute the result. 4754 * When either side is a float the result is a float. 4755 */ 4756 #ifdef FEAT_FLOAT 4757 if (use_float) 4758 { 4759 if (op == '*') 4760 f1 = f1 * f2; 4761 else if (op == '/') 4762 { 4763 /* We rely on the floating point library to handle divide 4764 * by zero to result in "inf" and not a crash. */ 4765 f1 = f1 / f2; 4766 } 4767 else 4768 { 4769 EMSG(_("E804: Cannot use '%' with Float")); 4770 return FAIL; 4771 } 4772 rettv->v_type = VAR_FLOAT; 4773 rettv->vval.v_float = f1; 4774 } 4775 else 4776 #endif 4777 { 4778 if (op == '*') 4779 n1 = n1 * n2; 4780 else if (op == '/') 4781 { 4782 if (n2 == 0) /* give an error message? */ 4783 { 4784 if (n1 == 0) 4785 n1 = -0x7fffffffL - 1L; /* similar to NaN */ 4786 else if (n1 < 0) 4787 n1 = -0x7fffffffL; 4788 else 4789 n1 = 0x7fffffffL; 4790 } 4791 else 4792 n1 = n1 / n2; 4793 } 4794 else 4795 { 4796 if (n2 == 0) /* give an error message? */ 4797 n1 = 0; 4798 else 4799 n1 = n1 % n2; 4800 } 4801 rettv->v_type = VAR_NUMBER; 4802 rettv->vval.v_number = n1; 4803 } 4804 } 4805 } 4806 4807 return OK; 4808 } 4809 4810 /* 4811 * Handle sixth level expression: 4812 * number number constant 4813 * "string" string constant 4814 * 'string' literal string constant 4815 * &option-name option value 4816 * @r register contents 4817 * identifier variable value 4818 * function() function call 4819 * $VAR environment variable 4820 * (expression) nested expression 4821 * [expr, expr] List 4822 * {key: val, key: val} Dictionary 4823 * 4824 * Also handle: 4825 * ! in front logical NOT 4826 * - in front unary minus 4827 * + in front unary plus (ignored) 4828 * trailing [] subscript in String or List 4829 * trailing .name entry in Dictionary 4830 * 4831 * "arg" must point to the first non-white of the expression. 4832 * "arg" is advanced to the next non-white after the recognized expression. 4833 * 4834 * Return OK or FAIL. 4835 */ 4836 static int 4837 eval7(arg, rettv, evaluate, want_string) 4838 char_u **arg; 4839 typval_T *rettv; 4840 int evaluate; 4841 int want_string; /* after "." operator */ 4842 { 4843 long n; 4844 int len; 4845 char_u *s; 4846 char_u *start_leader, *end_leader; 4847 int ret = OK; 4848 char_u *alias; 4849 4850 /* 4851 * Initialise variable so that clear_tv() can't mistake this for a 4852 * string and free a string that isn't there. 4853 */ 4854 rettv->v_type = VAR_UNKNOWN; 4855 4856 /* 4857 * Skip '!' and '-' characters. They are handled later. 4858 */ 4859 start_leader = *arg; 4860 while (**arg == '!' || **arg == '-' || **arg == '+') 4861 *arg = skipwhite(*arg + 1); 4862 end_leader = *arg; 4863 4864 switch (**arg) 4865 { 4866 /* 4867 * Number constant. 4868 */ 4869 case '0': 4870 case '1': 4871 case '2': 4872 case '3': 4873 case '4': 4874 case '5': 4875 case '6': 4876 case '7': 4877 case '8': 4878 case '9': 4879 { 4880 #ifdef FEAT_FLOAT 4881 char_u *p = skipdigits(*arg + 1); 4882 int get_float = FALSE; 4883 4884 /* We accept a float when the format matches 4885 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very 4886 * strict to avoid backwards compatibility problems. 4887 * Don't look for a float after the "." operator, so that 4888 * ":let vers = 1.2.3" doesn't fail. */ 4889 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) 4890 { 4891 get_float = TRUE; 4892 p = skipdigits(p + 2); 4893 if (*p == 'e' || *p == 'E') 4894 { 4895 ++p; 4896 if (*p == '-' || *p == '+') 4897 ++p; 4898 if (!vim_isdigit(*p)) 4899 get_float = FALSE; 4900 else 4901 p = skipdigits(p + 1); 4902 } 4903 if (ASCII_ISALPHA(*p) || *p == '.') 4904 get_float = FALSE; 4905 } 4906 if (get_float) 4907 { 4908 float_T f; 4909 4910 *arg += string2float(*arg, &f); 4911 if (evaluate) 4912 { 4913 rettv->v_type = VAR_FLOAT; 4914 rettv->vval.v_float = f; 4915 } 4916 } 4917 else 4918 #endif 4919 { 4920 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4921 *arg += len; 4922 if (evaluate) 4923 { 4924 rettv->v_type = VAR_NUMBER; 4925 rettv->vval.v_number = n; 4926 } 4927 } 4928 break; 4929 } 4930 4931 /* 4932 * String constant: "string". 4933 */ 4934 case '"': ret = get_string_tv(arg, rettv, evaluate); 4935 break; 4936 4937 /* 4938 * Literal string constant: 'str''ing'. 4939 */ 4940 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4941 break; 4942 4943 /* 4944 * List: [expr, expr] 4945 */ 4946 case '[': ret = get_list_tv(arg, rettv, evaluate); 4947 break; 4948 4949 /* 4950 * Dictionary: {key: val, key: val} 4951 */ 4952 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4953 break; 4954 4955 /* 4956 * Option value: &name 4957 */ 4958 case '&': ret = get_option_tv(arg, rettv, evaluate); 4959 break; 4960 4961 /* 4962 * Environment variable: $VAR. 4963 */ 4964 case '$': ret = get_env_tv(arg, rettv, evaluate); 4965 break; 4966 4967 /* 4968 * Register contents: @r. 4969 */ 4970 case '@': ++*arg; 4971 if (evaluate) 4972 { 4973 rettv->v_type = VAR_STRING; 4974 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4975 } 4976 if (**arg != NUL) 4977 ++*arg; 4978 break; 4979 4980 /* 4981 * nested expression: (expression). 4982 */ 4983 case '(': *arg = skipwhite(*arg + 1); 4984 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4985 if (**arg == ')') 4986 ++*arg; 4987 else if (ret == OK) 4988 { 4989 EMSG(_("E110: Missing ')'")); 4990 clear_tv(rettv); 4991 ret = FAIL; 4992 } 4993 break; 4994 4995 default: ret = NOTDONE; 4996 break; 4997 } 4998 4999 if (ret == NOTDONE) 5000 { 5001 /* 5002 * Must be a variable or function name. 5003 * Can also be a curly-braces kind of name: {expr}. 5004 */ 5005 s = *arg; 5006 len = get_name_len(arg, &alias, evaluate, TRUE); 5007 if (alias != NULL) 5008 s = alias; 5009 5010 if (len <= 0) 5011 ret = FAIL; 5012 else 5013 { 5014 if (**arg == '(') /* recursive! */ 5015 { 5016 /* If "s" is the name of a variable of type VAR_FUNC 5017 * use its contents. */ 5018 s = deref_func_name(s, &len); 5019 5020 /* Invoke the function. */ 5021 ret = get_func_tv(s, len, rettv, arg, 5022 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 5023 &len, evaluate, NULL); 5024 /* Stop the expression evaluation when immediately 5025 * aborting on error, or when an interrupt occurred or 5026 * an exception was thrown but not caught. */ 5027 if (aborting()) 5028 { 5029 if (ret == OK) 5030 clear_tv(rettv); 5031 ret = FAIL; 5032 } 5033 } 5034 else if (evaluate) 5035 ret = get_var_tv(s, len, rettv, TRUE); 5036 else 5037 ret = OK; 5038 } 5039 5040 if (alias != NULL) 5041 vim_free(alias); 5042 } 5043 5044 *arg = skipwhite(*arg); 5045 5046 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 5047 * expr(expr). */ 5048 if (ret == OK) 5049 ret = handle_subscript(arg, rettv, evaluate, TRUE); 5050 5051 /* 5052 * Apply logical NOT and unary '-', from right to left, ignore '+'. 5053 */ 5054 if (ret == OK && evaluate && end_leader > start_leader) 5055 { 5056 int error = FALSE; 5057 int val = 0; 5058 #ifdef FEAT_FLOAT 5059 float_T f = 0.0; 5060 5061 if (rettv->v_type == VAR_FLOAT) 5062 f = rettv->vval.v_float; 5063 else 5064 #endif 5065 val = get_tv_number_chk(rettv, &error); 5066 if (error) 5067 { 5068 clear_tv(rettv); 5069 ret = FAIL; 5070 } 5071 else 5072 { 5073 while (end_leader > start_leader) 5074 { 5075 --end_leader; 5076 if (*end_leader == '!') 5077 { 5078 #ifdef FEAT_FLOAT 5079 if (rettv->v_type == VAR_FLOAT) 5080 f = !f; 5081 else 5082 #endif 5083 val = !val; 5084 } 5085 else if (*end_leader == '-') 5086 { 5087 #ifdef FEAT_FLOAT 5088 if (rettv->v_type == VAR_FLOAT) 5089 f = -f; 5090 else 5091 #endif 5092 val = -val; 5093 } 5094 } 5095 #ifdef FEAT_FLOAT 5096 if (rettv->v_type == VAR_FLOAT) 5097 { 5098 clear_tv(rettv); 5099 rettv->vval.v_float = f; 5100 } 5101 else 5102 #endif 5103 { 5104 clear_tv(rettv); 5105 rettv->v_type = VAR_NUMBER; 5106 rettv->vval.v_number = val; 5107 } 5108 } 5109 } 5110 5111 return ret; 5112 } 5113 5114 /* 5115 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 5116 * "*arg" points to the '[' or '.'. 5117 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 5118 */ 5119 static int 5120 eval_index(arg, rettv, evaluate, verbose) 5121 char_u **arg; 5122 typval_T *rettv; 5123 int evaluate; 5124 int verbose; /* give error messages */ 5125 { 5126 int empty1 = FALSE, empty2 = FALSE; 5127 typval_T var1, var2; 5128 long n1, n2 = 0; 5129 long len = -1; 5130 int range = FALSE; 5131 char_u *s; 5132 char_u *key = NULL; 5133 5134 if (rettv->v_type == VAR_FUNC 5135 #ifdef FEAT_FLOAT 5136 || rettv->v_type == VAR_FLOAT 5137 #endif 5138 ) 5139 { 5140 if (verbose) 5141 EMSG(_("E695: Cannot index a Funcref")); 5142 return FAIL; 5143 } 5144 5145 if (**arg == '.') 5146 { 5147 /* 5148 * dict.name 5149 */ 5150 key = *arg + 1; 5151 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 5152 ; 5153 if (len == 0) 5154 return FAIL; 5155 *arg = skipwhite(key + len); 5156 } 5157 else 5158 { 5159 /* 5160 * something[idx] 5161 * 5162 * Get the (first) variable from inside the []. 5163 */ 5164 *arg = skipwhite(*arg + 1); 5165 if (**arg == ':') 5166 empty1 = TRUE; 5167 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 5168 return FAIL; 5169 else if (evaluate && get_tv_string_chk(&var1) == NULL) 5170 { 5171 /* not a number or string */ 5172 clear_tv(&var1); 5173 return FAIL; 5174 } 5175 5176 /* 5177 * Get the second variable from inside the [:]. 5178 */ 5179 if (**arg == ':') 5180 { 5181 range = TRUE; 5182 *arg = skipwhite(*arg + 1); 5183 if (**arg == ']') 5184 empty2 = TRUE; 5185 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 5186 { 5187 if (!empty1) 5188 clear_tv(&var1); 5189 return FAIL; 5190 } 5191 else if (evaluate && get_tv_string_chk(&var2) == NULL) 5192 { 5193 /* not a number or string */ 5194 if (!empty1) 5195 clear_tv(&var1); 5196 clear_tv(&var2); 5197 return FAIL; 5198 } 5199 } 5200 5201 /* Check for the ']'. */ 5202 if (**arg != ']') 5203 { 5204 if (verbose) 5205 EMSG(_(e_missbrac)); 5206 clear_tv(&var1); 5207 if (range) 5208 clear_tv(&var2); 5209 return FAIL; 5210 } 5211 *arg = skipwhite(*arg + 1); /* skip the ']' */ 5212 } 5213 5214 if (evaluate) 5215 { 5216 n1 = 0; 5217 if (!empty1 && rettv->v_type != VAR_DICT) 5218 { 5219 n1 = get_tv_number(&var1); 5220 clear_tv(&var1); 5221 } 5222 if (range) 5223 { 5224 if (empty2) 5225 n2 = -1; 5226 else 5227 { 5228 n2 = get_tv_number(&var2); 5229 clear_tv(&var2); 5230 } 5231 } 5232 5233 switch (rettv->v_type) 5234 { 5235 case VAR_NUMBER: 5236 case VAR_STRING: 5237 s = get_tv_string(rettv); 5238 len = (long)STRLEN(s); 5239 if (range) 5240 { 5241 /* The resulting variable is a substring. If the indexes 5242 * are out of range the result is empty. */ 5243 if (n1 < 0) 5244 { 5245 n1 = len + n1; 5246 if (n1 < 0) 5247 n1 = 0; 5248 } 5249 if (n2 < 0) 5250 n2 = len + n2; 5251 else if (n2 >= len) 5252 n2 = len; 5253 if (n1 >= len || n2 < 0 || n1 > n2) 5254 s = NULL; 5255 else 5256 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 5257 } 5258 else 5259 { 5260 /* The resulting variable is a string of a single 5261 * character. If the index is too big or negative the 5262 * result is empty. */ 5263 if (n1 >= len || n1 < 0) 5264 s = NULL; 5265 else 5266 s = vim_strnsave(s + n1, 1); 5267 } 5268 clear_tv(rettv); 5269 rettv->v_type = VAR_STRING; 5270 rettv->vval.v_string = s; 5271 break; 5272 5273 case VAR_LIST: 5274 len = list_len(rettv->vval.v_list); 5275 if (n1 < 0) 5276 n1 = len + n1; 5277 if (!empty1 && (n1 < 0 || n1 >= len)) 5278 { 5279 /* For a range we allow invalid values and return an empty 5280 * list. A list index out of range is an error. */ 5281 if (!range) 5282 { 5283 if (verbose) 5284 EMSGN(_(e_listidx), n1); 5285 return FAIL; 5286 } 5287 n1 = len; 5288 } 5289 if (range) 5290 { 5291 list_T *l; 5292 listitem_T *item; 5293 5294 if (n2 < 0) 5295 n2 = len + n2; 5296 else if (n2 >= len) 5297 n2 = len - 1; 5298 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 5299 n2 = -1; 5300 l = list_alloc(); 5301 if (l == NULL) 5302 return FAIL; 5303 for (item = list_find(rettv->vval.v_list, n1); 5304 n1 <= n2; ++n1) 5305 { 5306 if (list_append_tv(l, &item->li_tv) == FAIL) 5307 { 5308 list_free(l, TRUE); 5309 return FAIL; 5310 } 5311 item = item->li_next; 5312 } 5313 clear_tv(rettv); 5314 rettv->v_type = VAR_LIST; 5315 rettv->vval.v_list = l; 5316 ++l->lv_refcount; 5317 } 5318 else 5319 { 5320 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 5321 clear_tv(rettv); 5322 *rettv = var1; 5323 } 5324 break; 5325 5326 case VAR_DICT: 5327 if (range) 5328 { 5329 if (verbose) 5330 EMSG(_(e_dictrange)); 5331 if (len == -1) 5332 clear_tv(&var1); 5333 return FAIL; 5334 } 5335 { 5336 dictitem_T *item; 5337 5338 if (len == -1) 5339 { 5340 key = get_tv_string(&var1); 5341 if (*key == NUL) 5342 { 5343 if (verbose) 5344 EMSG(_(e_emptykey)); 5345 clear_tv(&var1); 5346 return FAIL; 5347 } 5348 } 5349 5350 item = dict_find(rettv->vval.v_dict, key, (int)len); 5351 5352 if (item == NULL && verbose) 5353 EMSG2(_(e_dictkey), key); 5354 if (len == -1) 5355 clear_tv(&var1); 5356 if (item == NULL) 5357 return FAIL; 5358 5359 copy_tv(&item->di_tv, &var1); 5360 clear_tv(rettv); 5361 *rettv = var1; 5362 } 5363 break; 5364 } 5365 } 5366 5367 return OK; 5368 } 5369 5370 /* 5371 * Get an option value. 5372 * "arg" points to the '&' or '+' before the option name. 5373 * "arg" is advanced to character after the option name. 5374 * Return OK or FAIL. 5375 */ 5376 static int 5377 get_option_tv(arg, rettv, evaluate) 5378 char_u **arg; 5379 typval_T *rettv; /* when NULL, only check if option exists */ 5380 int evaluate; 5381 { 5382 char_u *option_end; 5383 long numval; 5384 char_u *stringval; 5385 int opt_type; 5386 int c; 5387 int working = (**arg == '+'); /* has("+option") */ 5388 int ret = OK; 5389 int opt_flags; 5390 5391 /* 5392 * Isolate the option name and find its value. 5393 */ 5394 option_end = find_option_end(arg, &opt_flags); 5395 if (option_end == NULL) 5396 { 5397 if (rettv != NULL) 5398 EMSG2(_("E112: Option name missing: %s"), *arg); 5399 return FAIL; 5400 } 5401 5402 if (!evaluate) 5403 { 5404 *arg = option_end; 5405 return OK; 5406 } 5407 5408 c = *option_end; 5409 *option_end = NUL; 5410 opt_type = get_option_value(*arg, &numval, 5411 rettv == NULL ? NULL : &stringval, opt_flags); 5412 5413 if (opt_type == -3) /* invalid name */ 5414 { 5415 if (rettv != NULL) 5416 EMSG2(_("E113: Unknown option: %s"), *arg); 5417 ret = FAIL; 5418 } 5419 else if (rettv != NULL) 5420 { 5421 if (opt_type == -2) /* hidden string option */ 5422 { 5423 rettv->v_type = VAR_STRING; 5424 rettv->vval.v_string = NULL; 5425 } 5426 else if (opt_type == -1) /* hidden number option */ 5427 { 5428 rettv->v_type = VAR_NUMBER; 5429 rettv->vval.v_number = 0; 5430 } 5431 else if (opt_type == 1) /* number option */ 5432 { 5433 rettv->v_type = VAR_NUMBER; 5434 rettv->vval.v_number = numval; 5435 } 5436 else /* string option */ 5437 { 5438 rettv->v_type = VAR_STRING; 5439 rettv->vval.v_string = stringval; 5440 } 5441 } 5442 else if (working && (opt_type == -2 || opt_type == -1)) 5443 ret = FAIL; 5444 5445 *option_end = c; /* put back for error messages */ 5446 *arg = option_end; 5447 5448 return ret; 5449 } 5450 5451 /* 5452 * Allocate a variable for a string constant. 5453 * Return OK or FAIL. 5454 */ 5455 static int 5456 get_string_tv(arg, rettv, evaluate) 5457 char_u **arg; 5458 typval_T *rettv; 5459 int evaluate; 5460 { 5461 char_u *p; 5462 char_u *name; 5463 int extra = 0; 5464 5465 /* 5466 * Find the end of the string, skipping backslashed characters. 5467 */ 5468 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5469 { 5470 if (*p == '\\' && p[1] != NUL) 5471 { 5472 ++p; 5473 /* A "\<x>" form occupies at least 4 characters, and produces up 5474 * to 6 characters: reserve space for 2 extra */ 5475 if (*p == '<') 5476 extra += 2; 5477 } 5478 } 5479 5480 if (*p != '"') 5481 { 5482 EMSG2(_("E114: Missing quote: %s"), *arg); 5483 return FAIL; 5484 } 5485 5486 /* If only parsing, set *arg and return here */ 5487 if (!evaluate) 5488 { 5489 *arg = p + 1; 5490 return OK; 5491 } 5492 5493 /* 5494 * Copy the string into allocated memory, handling backslashed 5495 * characters. 5496 */ 5497 name = alloc((unsigned)(p - *arg + extra)); 5498 if (name == NULL) 5499 return FAIL; 5500 rettv->v_type = VAR_STRING; 5501 rettv->vval.v_string = name; 5502 5503 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5504 { 5505 if (*p == '\\') 5506 { 5507 switch (*++p) 5508 { 5509 case 'b': *name++ = BS; ++p; break; 5510 case 'e': *name++ = ESC; ++p; break; 5511 case 'f': *name++ = FF; ++p; break; 5512 case 'n': *name++ = NL; ++p; break; 5513 case 'r': *name++ = CAR; ++p; break; 5514 case 't': *name++ = TAB; ++p; break; 5515 5516 case 'X': /* hex: "\x1", "\x12" */ 5517 case 'x': 5518 case 'u': /* Unicode: "\u0023" */ 5519 case 'U': 5520 if (vim_isxdigit(p[1])) 5521 { 5522 int n, nr; 5523 int c = toupper(*p); 5524 5525 if (c == 'X') 5526 n = 2; 5527 else 5528 n = 4; 5529 nr = 0; 5530 while (--n >= 0 && vim_isxdigit(p[1])) 5531 { 5532 ++p; 5533 nr = (nr << 4) + hex2nr(*p); 5534 } 5535 ++p; 5536 #ifdef FEAT_MBYTE 5537 /* For "\u" store the number according to 5538 * 'encoding'. */ 5539 if (c != 'X') 5540 name += (*mb_char2bytes)(nr, name); 5541 else 5542 #endif 5543 *name++ = nr; 5544 } 5545 break; 5546 5547 /* octal: "\1", "\12", "\123" */ 5548 case '0': 5549 case '1': 5550 case '2': 5551 case '3': 5552 case '4': 5553 case '5': 5554 case '6': 5555 case '7': *name = *p++ - '0'; 5556 if (*p >= '0' && *p <= '7') 5557 { 5558 *name = (*name << 3) + *p++ - '0'; 5559 if (*p >= '0' && *p <= '7') 5560 *name = (*name << 3) + *p++ - '0'; 5561 } 5562 ++name; 5563 break; 5564 5565 /* Special key, e.g.: "\<C-W>" */ 5566 case '<': extra = trans_special(&p, name, TRUE); 5567 if (extra != 0) 5568 { 5569 name += extra; 5570 break; 5571 } 5572 /* FALLTHROUGH */ 5573 5574 default: MB_COPY_CHAR(p, name); 5575 break; 5576 } 5577 } 5578 else 5579 MB_COPY_CHAR(p, name); 5580 5581 } 5582 *name = NUL; 5583 *arg = p + 1; 5584 5585 return OK; 5586 } 5587 5588 /* 5589 * Allocate a variable for a 'str''ing' constant. 5590 * Return OK or FAIL. 5591 */ 5592 static int 5593 get_lit_string_tv(arg, rettv, evaluate) 5594 char_u **arg; 5595 typval_T *rettv; 5596 int evaluate; 5597 { 5598 char_u *p; 5599 char_u *str; 5600 int reduce = 0; 5601 5602 /* 5603 * Find the end of the string, skipping ''. 5604 */ 5605 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5606 { 5607 if (*p == '\'') 5608 { 5609 if (p[1] != '\'') 5610 break; 5611 ++reduce; 5612 ++p; 5613 } 5614 } 5615 5616 if (*p != '\'') 5617 { 5618 EMSG2(_("E115: Missing quote: %s"), *arg); 5619 return FAIL; 5620 } 5621 5622 /* If only parsing return after setting "*arg" */ 5623 if (!evaluate) 5624 { 5625 *arg = p + 1; 5626 return OK; 5627 } 5628 5629 /* 5630 * Copy the string into allocated memory, handling '' to ' reduction. 5631 */ 5632 str = alloc((unsigned)((p - *arg) - reduce)); 5633 if (str == NULL) 5634 return FAIL; 5635 rettv->v_type = VAR_STRING; 5636 rettv->vval.v_string = str; 5637 5638 for (p = *arg + 1; *p != NUL; ) 5639 { 5640 if (*p == '\'') 5641 { 5642 if (p[1] != '\'') 5643 break; 5644 ++p; 5645 } 5646 MB_COPY_CHAR(p, str); 5647 } 5648 *str = NUL; 5649 *arg = p + 1; 5650 5651 return OK; 5652 } 5653 5654 /* 5655 * Allocate a variable for a List and fill it from "*arg". 5656 * Return OK or FAIL. 5657 */ 5658 static int 5659 get_list_tv(arg, rettv, evaluate) 5660 char_u **arg; 5661 typval_T *rettv; 5662 int evaluate; 5663 { 5664 list_T *l = NULL; 5665 typval_T tv; 5666 listitem_T *item; 5667 5668 if (evaluate) 5669 { 5670 l = list_alloc(); 5671 if (l == NULL) 5672 return FAIL; 5673 } 5674 5675 *arg = skipwhite(*arg + 1); 5676 while (**arg != ']' && **arg != NUL) 5677 { 5678 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5679 goto failret; 5680 if (evaluate) 5681 { 5682 item = listitem_alloc(); 5683 if (item != NULL) 5684 { 5685 item->li_tv = tv; 5686 item->li_tv.v_lock = 0; 5687 list_append(l, item); 5688 } 5689 else 5690 clear_tv(&tv); 5691 } 5692 5693 if (**arg == ']') 5694 break; 5695 if (**arg != ',') 5696 { 5697 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5698 goto failret; 5699 } 5700 *arg = skipwhite(*arg + 1); 5701 } 5702 5703 if (**arg != ']') 5704 { 5705 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5706 failret: 5707 if (evaluate) 5708 list_free(l, TRUE); 5709 return FAIL; 5710 } 5711 5712 *arg = skipwhite(*arg + 1); 5713 if (evaluate) 5714 { 5715 rettv->v_type = VAR_LIST; 5716 rettv->vval.v_list = l; 5717 ++l->lv_refcount; 5718 } 5719 5720 return OK; 5721 } 5722 5723 /* 5724 * Allocate an empty header for a list. 5725 * Caller should take care of the reference count. 5726 */ 5727 list_T * 5728 list_alloc() 5729 { 5730 list_T *l; 5731 5732 l = (list_T *)alloc_clear(sizeof(list_T)); 5733 if (l != NULL) 5734 { 5735 /* Prepend the list to the list of lists for garbage collection. */ 5736 if (first_list != NULL) 5737 first_list->lv_used_prev = l; 5738 l->lv_used_prev = NULL; 5739 l->lv_used_next = first_list; 5740 first_list = l; 5741 } 5742 return l; 5743 } 5744 5745 /* 5746 * Allocate an empty list for a return value. 5747 * Returns OK or FAIL. 5748 */ 5749 static int 5750 rettv_list_alloc(rettv) 5751 typval_T *rettv; 5752 { 5753 list_T *l = list_alloc(); 5754 5755 if (l == NULL) 5756 return FAIL; 5757 5758 rettv->vval.v_list = l; 5759 rettv->v_type = VAR_LIST; 5760 ++l->lv_refcount; 5761 return OK; 5762 } 5763 5764 /* 5765 * Unreference a list: decrement the reference count and free it when it 5766 * becomes zero. 5767 */ 5768 void 5769 list_unref(l) 5770 list_T *l; 5771 { 5772 if (l != NULL && --l->lv_refcount <= 0) 5773 list_free(l, TRUE); 5774 } 5775 5776 /* 5777 * Free a list, including all items it points to. 5778 * Ignores the reference count. 5779 */ 5780 void 5781 list_free(l, recurse) 5782 list_T *l; 5783 int recurse; /* Free Lists and Dictionaries recursively. */ 5784 { 5785 listitem_T *item; 5786 5787 /* Remove the list from the list of lists for garbage collection. */ 5788 if (l->lv_used_prev == NULL) 5789 first_list = l->lv_used_next; 5790 else 5791 l->lv_used_prev->lv_used_next = l->lv_used_next; 5792 if (l->lv_used_next != NULL) 5793 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5794 5795 for (item = l->lv_first; item != NULL; item = l->lv_first) 5796 { 5797 /* Remove the item before deleting it. */ 5798 l->lv_first = item->li_next; 5799 if (recurse || (item->li_tv.v_type != VAR_LIST 5800 && item->li_tv.v_type != VAR_DICT)) 5801 clear_tv(&item->li_tv); 5802 vim_free(item); 5803 } 5804 vim_free(l); 5805 } 5806 5807 /* 5808 * Allocate a list item. 5809 */ 5810 static listitem_T * 5811 listitem_alloc() 5812 { 5813 return (listitem_T *)alloc(sizeof(listitem_T)); 5814 } 5815 5816 /* 5817 * Free a list item. Also clears the value. Does not notify watchers. 5818 */ 5819 static void 5820 listitem_free(item) 5821 listitem_T *item; 5822 { 5823 clear_tv(&item->li_tv); 5824 vim_free(item); 5825 } 5826 5827 /* 5828 * Remove a list item from a List and free it. Also clears the value. 5829 */ 5830 static void 5831 listitem_remove(l, item) 5832 list_T *l; 5833 listitem_T *item; 5834 { 5835 list_remove(l, item, item); 5836 listitem_free(item); 5837 } 5838 5839 /* 5840 * Get the number of items in a list. 5841 */ 5842 static long 5843 list_len(l) 5844 list_T *l; 5845 { 5846 if (l == NULL) 5847 return 0L; 5848 return l->lv_len; 5849 } 5850 5851 /* 5852 * Return TRUE when two lists have exactly the same values. 5853 */ 5854 static int 5855 list_equal(l1, l2, ic) 5856 list_T *l1; 5857 list_T *l2; 5858 int ic; /* ignore case for strings */ 5859 { 5860 listitem_T *item1, *item2; 5861 5862 if (l1 == NULL || l2 == NULL) 5863 return FALSE; 5864 if (l1 == l2) 5865 return TRUE; 5866 if (list_len(l1) != list_len(l2)) 5867 return FALSE; 5868 5869 for (item1 = l1->lv_first, item2 = l2->lv_first; 5870 item1 != NULL && item2 != NULL; 5871 item1 = item1->li_next, item2 = item2->li_next) 5872 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5873 return FALSE; 5874 return item1 == NULL && item2 == NULL; 5875 } 5876 5877 #if defined(FEAT_PYTHON) || defined(FEAT_MZSCHEME) || defined(PROTO) 5878 /* 5879 * Return the dictitem that an entry in a hashtable points to. 5880 */ 5881 dictitem_T * 5882 dict_lookup(hi) 5883 hashitem_T *hi; 5884 { 5885 return HI2DI(hi); 5886 } 5887 #endif 5888 5889 /* 5890 * Return TRUE when two dictionaries have exactly the same key/values. 5891 */ 5892 static int 5893 dict_equal(d1, d2, ic) 5894 dict_T *d1; 5895 dict_T *d2; 5896 int ic; /* ignore case for strings */ 5897 { 5898 hashitem_T *hi; 5899 dictitem_T *item2; 5900 int todo; 5901 5902 if (d1 == NULL || d2 == NULL) 5903 return FALSE; 5904 if (d1 == d2) 5905 return TRUE; 5906 if (dict_len(d1) != dict_len(d2)) 5907 return FALSE; 5908 5909 todo = (int)d1->dv_hashtab.ht_used; 5910 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5911 { 5912 if (!HASHITEM_EMPTY(hi)) 5913 { 5914 item2 = dict_find(d2, hi->hi_key, -1); 5915 if (item2 == NULL) 5916 return FALSE; 5917 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5918 return FALSE; 5919 --todo; 5920 } 5921 } 5922 return TRUE; 5923 } 5924 5925 /* 5926 * Return TRUE if "tv1" and "tv2" have the same value. 5927 * Compares the items just like "==" would compare them, but strings and 5928 * numbers are different. Floats and numbers are also different. 5929 */ 5930 static int 5931 tv_equal(tv1, tv2, ic) 5932 typval_T *tv1; 5933 typval_T *tv2; 5934 int ic; /* ignore case */ 5935 { 5936 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5937 char_u *s1, *s2; 5938 static int recursive = 0; /* cach recursive loops */ 5939 int r; 5940 5941 if (tv1->v_type != tv2->v_type) 5942 return FALSE; 5943 /* Catch lists and dicts that have an endless loop by limiting 5944 * recursiveness to 1000. We guess they are equal then. */ 5945 if (recursive >= 1000) 5946 return TRUE; 5947 5948 switch (tv1->v_type) 5949 { 5950 case VAR_LIST: 5951 ++recursive; 5952 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5953 --recursive; 5954 return r; 5955 5956 case VAR_DICT: 5957 ++recursive; 5958 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5959 --recursive; 5960 return r; 5961 5962 case VAR_FUNC: 5963 return (tv1->vval.v_string != NULL 5964 && tv2->vval.v_string != NULL 5965 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5966 5967 case VAR_NUMBER: 5968 return tv1->vval.v_number == tv2->vval.v_number; 5969 5970 #ifdef FEAT_FLOAT 5971 case VAR_FLOAT: 5972 return tv1->vval.v_float == tv2->vval.v_float; 5973 #endif 5974 5975 case VAR_STRING: 5976 s1 = get_tv_string_buf(tv1, buf1); 5977 s2 = get_tv_string_buf(tv2, buf2); 5978 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5979 } 5980 5981 EMSG2(_(e_intern2), "tv_equal()"); 5982 return TRUE; 5983 } 5984 5985 /* 5986 * Locate item with index "n" in list "l" and return it. 5987 * A negative index is counted from the end; -1 is the last item. 5988 * Returns NULL when "n" is out of range. 5989 */ 5990 static listitem_T * 5991 list_find(l, n) 5992 list_T *l; 5993 long n; 5994 { 5995 listitem_T *item; 5996 long idx; 5997 5998 if (l == NULL) 5999 return NULL; 6000 6001 /* Negative index is relative to the end. */ 6002 if (n < 0) 6003 n = l->lv_len + n; 6004 6005 /* Check for index out of range. */ 6006 if (n < 0 || n >= l->lv_len) 6007 return NULL; 6008 6009 /* When there is a cached index may start search from there. */ 6010 if (l->lv_idx_item != NULL) 6011 { 6012 if (n < l->lv_idx / 2) 6013 { 6014 /* closest to the start of the list */ 6015 item = l->lv_first; 6016 idx = 0; 6017 } 6018 else if (n > (l->lv_idx + l->lv_len) / 2) 6019 { 6020 /* closest to the end of the list */ 6021 item = l->lv_last; 6022 idx = l->lv_len - 1; 6023 } 6024 else 6025 { 6026 /* closest to the cached index */ 6027 item = l->lv_idx_item; 6028 idx = l->lv_idx; 6029 } 6030 } 6031 else 6032 { 6033 if (n < l->lv_len / 2) 6034 { 6035 /* closest to the start of the list */ 6036 item = l->lv_first; 6037 idx = 0; 6038 } 6039 else 6040 { 6041 /* closest to the end of the list */ 6042 item = l->lv_last; 6043 idx = l->lv_len - 1; 6044 } 6045 } 6046 6047 while (n > idx) 6048 { 6049 /* search forward */ 6050 item = item->li_next; 6051 ++idx; 6052 } 6053 while (n < idx) 6054 { 6055 /* search backward */ 6056 item = item->li_prev; 6057 --idx; 6058 } 6059 6060 /* cache the used index */ 6061 l->lv_idx = idx; 6062 l->lv_idx_item = item; 6063 6064 return item; 6065 } 6066 6067 /* 6068 * Get list item "l[idx]" as a number. 6069 */ 6070 static long 6071 list_find_nr(l, idx, errorp) 6072 list_T *l; 6073 long idx; 6074 int *errorp; /* set to TRUE when something wrong */ 6075 { 6076 listitem_T *li; 6077 6078 li = list_find(l, idx); 6079 if (li == NULL) 6080 { 6081 if (errorp != NULL) 6082 *errorp = TRUE; 6083 return -1L; 6084 } 6085 return get_tv_number_chk(&li->li_tv, errorp); 6086 } 6087 6088 /* 6089 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. 6090 */ 6091 char_u * 6092 list_find_str(l, idx) 6093 list_T *l; 6094 long idx; 6095 { 6096 listitem_T *li; 6097 6098 li = list_find(l, idx - 1); 6099 if (li == NULL) 6100 { 6101 EMSGN(_(e_listidx), idx); 6102 return NULL; 6103 } 6104 return get_tv_string(&li->li_tv); 6105 } 6106 6107 /* 6108 * Locate "item" list "l" and return its index. 6109 * Returns -1 when "item" is not in the list. 6110 */ 6111 static long 6112 list_idx_of_item(l, item) 6113 list_T *l; 6114 listitem_T *item; 6115 { 6116 long idx = 0; 6117 listitem_T *li; 6118 6119 if (l == NULL) 6120 return -1; 6121 idx = 0; 6122 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 6123 ++idx; 6124 if (li == NULL) 6125 return -1; 6126 return idx; 6127 } 6128 6129 /* 6130 * Append item "item" to the end of list "l". 6131 */ 6132 static void 6133 list_append(l, item) 6134 list_T *l; 6135 listitem_T *item; 6136 { 6137 if (l->lv_last == NULL) 6138 { 6139 /* empty list */ 6140 l->lv_first = item; 6141 l->lv_last = item; 6142 item->li_prev = NULL; 6143 } 6144 else 6145 { 6146 l->lv_last->li_next = item; 6147 item->li_prev = l->lv_last; 6148 l->lv_last = item; 6149 } 6150 ++l->lv_len; 6151 item->li_next = NULL; 6152 } 6153 6154 /* 6155 * Append typval_T "tv" to the end of list "l". 6156 * Return FAIL when out of memory. 6157 */ 6158 static int 6159 list_append_tv(l, tv) 6160 list_T *l; 6161 typval_T *tv; 6162 { 6163 listitem_T *li = listitem_alloc(); 6164 6165 if (li == NULL) 6166 return FAIL; 6167 copy_tv(tv, &li->li_tv); 6168 list_append(l, li); 6169 return OK; 6170 } 6171 6172 /* 6173 * Add a dictionary to a list. Used by getqflist(). 6174 * Return FAIL when out of memory. 6175 */ 6176 int 6177 list_append_dict(list, dict) 6178 list_T *list; 6179 dict_T *dict; 6180 { 6181 listitem_T *li = listitem_alloc(); 6182 6183 if (li == NULL) 6184 return FAIL; 6185 li->li_tv.v_type = VAR_DICT; 6186 li->li_tv.v_lock = 0; 6187 li->li_tv.vval.v_dict = dict; 6188 list_append(list, li); 6189 ++dict->dv_refcount; 6190 return OK; 6191 } 6192 6193 /* 6194 * Make a copy of "str" and append it as an item to list "l". 6195 * When "len" >= 0 use "str[len]". 6196 * Returns FAIL when out of memory. 6197 */ 6198 int 6199 list_append_string(l, str, len) 6200 list_T *l; 6201 char_u *str; 6202 int len; 6203 { 6204 listitem_T *li = listitem_alloc(); 6205 6206 if (li == NULL) 6207 return FAIL; 6208 list_append(l, li); 6209 li->li_tv.v_type = VAR_STRING; 6210 li->li_tv.v_lock = 0; 6211 if (str == NULL) 6212 li->li_tv.vval.v_string = NULL; 6213 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 6214 : vim_strsave(str))) == NULL) 6215 return FAIL; 6216 return OK; 6217 } 6218 6219 /* 6220 * Append "n" to list "l". 6221 * Returns FAIL when out of memory. 6222 */ 6223 static int 6224 list_append_number(l, n) 6225 list_T *l; 6226 varnumber_T n; 6227 { 6228 listitem_T *li; 6229 6230 li = listitem_alloc(); 6231 if (li == NULL) 6232 return FAIL; 6233 li->li_tv.v_type = VAR_NUMBER; 6234 li->li_tv.v_lock = 0; 6235 li->li_tv.vval.v_number = n; 6236 list_append(l, li); 6237 return OK; 6238 } 6239 6240 /* 6241 * Insert typval_T "tv" in list "l" before "item". 6242 * If "item" is NULL append at the end. 6243 * Return FAIL when out of memory. 6244 */ 6245 static int 6246 list_insert_tv(l, tv, item) 6247 list_T *l; 6248 typval_T *tv; 6249 listitem_T *item; 6250 { 6251 listitem_T *ni = listitem_alloc(); 6252 6253 if (ni == NULL) 6254 return FAIL; 6255 copy_tv(tv, &ni->li_tv); 6256 if (item == NULL) 6257 /* Append new item at end of list. */ 6258 list_append(l, ni); 6259 else 6260 { 6261 /* Insert new item before existing item. */ 6262 ni->li_prev = item->li_prev; 6263 ni->li_next = item; 6264 if (item->li_prev == NULL) 6265 { 6266 l->lv_first = ni; 6267 ++l->lv_idx; 6268 } 6269 else 6270 { 6271 item->li_prev->li_next = ni; 6272 l->lv_idx_item = NULL; 6273 } 6274 item->li_prev = ni; 6275 ++l->lv_len; 6276 } 6277 return OK; 6278 } 6279 6280 /* 6281 * Extend "l1" with "l2". 6282 * If "bef" is NULL append at the end, otherwise insert before this item. 6283 * Returns FAIL when out of memory. 6284 */ 6285 static int 6286 list_extend(l1, l2, bef) 6287 list_T *l1; 6288 list_T *l2; 6289 listitem_T *bef; 6290 { 6291 listitem_T *item; 6292 int todo = l2->lv_len; 6293 6294 /* We also quit the loop when we have inserted the original item count of 6295 * the list, avoid a hang when we extend a list with itself. */ 6296 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) 6297 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 6298 return FAIL; 6299 return OK; 6300 } 6301 6302 /* 6303 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 6304 * Return FAIL when out of memory. 6305 */ 6306 static int 6307 list_concat(l1, l2, tv) 6308 list_T *l1; 6309 list_T *l2; 6310 typval_T *tv; 6311 { 6312 list_T *l; 6313 6314 if (l1 == NULL || l2 == NULL) 6315 return FAIL; 6316 6317 /* make a copy of the first list. */ 6318 l = list_copy(l1, FALSE, 0); 6319 if (l == NULL) 6320 return FAIL; 6321 tv->v_type = VAR_LIST; 6322 tv->vval.v_list = l; 6323 6324 /* append all items from the second list */ 6325 return list_extend(l, l2, NULL); 6326 } 6327 6328 /* 6329 * Make a copy of list "orig". Shallow if "deep" is FALSE. 6330 * The refcount of the new list is set to 1. 6331 * See item_copy() for "copyID". 6332 * Returns NULL when out of memory. 6333 */ 6334 static list_T * 6335 list_copy(orig, deep, copyID) 6336 list_T *orig; 6337 int deep; 6338 int copyID; 6339 { 6340 list_T *copy; 6341 listitem_T *item; 6342 listitem_T *ni; 6343 6344 if (orig == NULL) 6345 return NULL; 6346 6347 copy = list_alloc(); 6348 if (copy != NULL) 6349 { 6350 if (copyID != 0) 6351 { 6352 /* Do this before adding the items, because one of the items may 6353 * refer back to this list. */ 6354 orig->lv_copyID = copyID; 6355 orig->lv_copylist = copy; 6356 } 6357 for (item = orig->lv_first; item != NULL && !got_int; 6358 item = item->li_next) 6359 { 6360 ni = listitem_alloc(); 6361 if (ni == NULL) 6362 break; 6363 if (deep) 6364 { 6365 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 6366 { 6367 vim_free(ni); 6368 break; 6369 } 6370 } 6371 else 6372 copy_tv(&item->li_tv, &ni->li_tv); 6373 list_append(copy, ni); 6374 } 6375 ++copy->lv_refcount; 6376 if (item != NULL) 6377 { 6378 list_unref(copy); 6379 copy = NULL; 6380 } 6381 } 6382 6383 return copy; 6384 } 6385 6386 /* 6387 * Remove items "item" to "item2" from list "l". 6388 * Does not free the listitem or the value! 6389 */ 6390 static void 6391 list_remove(l, item, item2) 6392 list_T *l; 6393 listitem_T *item; 6394 listitem_T *item2; 6395 { 6396 listitem_T *ip; 6397 6398 /* notify watchers */ 6399 for (ip = item; ip != NULL; ip = ip->li_next) 6400 { 6401 --l->lv_len; 6402 list_fix_watch(l, ip); 6403 if (ip == item2) 6404 break; 6405 } 6406 6407 if (item2->li_next == NULL) 6408 l->lv_last = item->li_prev; 6409 else 6410 item2->li_next->li_prev = item->li_prev; 6411 if (item->li_prev == NULL) 6412 l->lv_first = item2->li_next; 6413 else 6414 item->li_prev->li_next = item2->li_next; 6415 l->lv_idx_item = NULL; 6416 } 6417 6418 /* 6419 * Return an allocated string with the string representation of a list. 6420 * May return NULL. 6421 */ 6422 static char_u * 6423 list2string(tv, copyID) 6424 typval_T *tv; 6425 int copyID; 6426 { 6427 garray_T ga; 6428 6429 if (tv->vval.v_list == NULL) 6430 return NULL; 6431 ga_init2(&ga, (int)sizeof(char), 80); 6432 ga_append(&ga, '['); 6433 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 6434 { 6435 vim_free(ga.ga_data); 6436 return NULL; 6437 } 6438 ga_append(&ga, ']'); 6439 ga_append(&ga, NUL); 6440 return (char_u *)ga.ga_data; 6441 } 6442 6443 /* 6444 * Join list "l" into a string in "*gap", using separator "sep". 6445 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 6446 * Return FAIL or OK. 6447 */ 6448 static int 6449 list_join(gap, l, sep, echo, copyID) 6450 garray_T *gap; 6451 list_T *l; 6452 char_u *sep; 6453 int echo; 6454 int copyID; 6455 { 6456 int first = TRUE; 6457 char_u *tofree; 6458 char_u numbuf[NUMBUFLEN]; 6459 listitem_T *item; 6460 char_u *s; 6461 6462 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 6463 { 6464 if (first) 6465 first = FALSE; 6466 else 6467 ga_concat(gap, sep); 6468 6469 if (echo) 6470 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6471 else 6472 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6473 if (s != NULL) 6474 ga_concat(gap, s); 6475 vim_free(tofree); 6476 if (s == NULL) 6477 return FAIL; 6478 } 6479 return OK; 6480 } 6481 6482 /* 6483 * Garbage collection for lists and dictionaries. 6484 * 6485 * We use reference counts to be able to free most items right away when they 6486 * are no longer used. But for composite items it's possible that it becomes 6487 * unused while the reference count is > 0: When there is a recursive 6488 * reference. Example: 6489 * :let l = [1, 2, 3] 6490 * :let d = {9: l} 6491 * :let l[1] = d 6492 * 6493 * Since this is quite unusual we handle this with garbage collection: every 6494 * once in a while find out which lists and dicts are not referenced from any 6495 * variable. 6496 * 6497 * Here is a good reference text about garbage collection (refers to Python 6498 * but it applies to all reference-counting mechanisms): 6499 * http://python.ca/nas/python/gc/ 6500 */ 6501 6502 /* 6503 * Do garbage collection for lists and dicts. 6504 * Return TRUE if some memory was freed. 6505 */ 6506 int 6507 garbage_collect() 6508 { 6509 int copyID; 6510 buf_T *buf; 6511 win_T *wp; 6512 int i; 6513 funccall_T *fc, **pfc; 6514 int did_free; 6515 int did_free_funccal = FALSE; 6516 #ifdef FEAT_WINDOWS 6517 tabpage_T *tp; 6518 #endif 6519 6520 /* Only do this once. */ 6521 want_garbage_collect = FALSE; 6522 may_garbage_collect = FALSE; 6523 garbage_collect_at_exit = FALSE; 6524 6525 /* We advance by two because we add one for items referenced through 6526 * previous_funccal. */ 6527 current_copyID += COPYID_INC; 6528 copyID = current_copyID; 6529 6530 /* 6531 * 1. Go through all accessible variables and mark all lists and dicts 6532 * with copyID. 6533 */ 6534 6535 /* Don't free variables in the previous_funccal list unless they are only 6536 * referenced through previous_funccal. This must be first, because if 6537 * the item is referenced elsewhere the funccal must not be freed. */ 6538 for (fc = previous_funccal; fc != NULL; fc = fc->caller) 6539 { 6540 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1); 6541 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1); 6542 } 6543 6544 /* script-local variables */ 6545 for (i = 1; i <= ga_scripts.ga_len; ++i) 6546 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 6547 6548 /* buffer-local variables */ 6549 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6550 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 6551 6552 /* window-local variables */ 6553 FOR_ALL_TAB_WINDOWS(tp, wp) 6554 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 6555 6556 #ifdef FEAT_WINDOWS 6557 /* tabpage-local variables */ 6558 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6559 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); 6560 #endif 6561 6562 /* global variables */ 6563 set_ref_in_ht(&globvarht, copyID); 6564 6565 /* function-local variables */ 6566 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6567 { 6568 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 6569 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 6570 } 6571 6572 /* v: vars */ 6573 set_ref_in_ht(&vimvarht, copyID); 6574 6575 /* 6576 * 2. Free lists and dictionaries that are not referenced. 6577 */ 6578 did_free = free_unref_items(copyID); 6579 6580 /* 6581 * 3. Check if any funccal can be freed now. 6582 */ 6583 for (pfc = &previous_funccal; *pfc != NULL; ) 6584 { 6585 if (can_free_funccal(*pfc, copyID)) 6586 { 6587 fc = *pfc; 6588 *pfc = fc->caller; 6589 free_funccal(fc, TRUE); 6590 did_free = TRUE; 6591 did_free_funccal = TRUE; 6592 } 6593 else 6594 pfc = &(*pfc)->caller; 6595 } 6596 if (did_free_funccal) 6597 /* When a funccal was freed some more items might be garbage 6598 * collected, so run again. */ 6599 (void)garbage_collect(); 6600 6601 return did_free; 6602 } 6603 6604 /* 6605 * Free lists and dictionaries that are no longer referenced. 6606 */ 6607 static int 6608 free_unref_items(copyID) 6609 int copyID; 6610 { 6611 dict_T *dd; 6612 list_T *ll; 6613 int did_free = FALSE; 6614 6615 /* 6616 * Go through the list of dicts and free items without the copyID. 6617 */ 6618 for (dd = first_dict; dd != NULL; ) 6619 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) 6620 { 6621 /* Free the Dictionary and ordinary items it contains, but don't 6622 * recurse into Lists and Dictionaries, they will be in the list 6623 * of dicts or list of lists. */ 6624 dict_free(dd, FALSE); 6625 did_free = TRUE; 6626 6627 /* restart, next dict may also have been freed */ 6628 dd = first_dict; 6629 } 6630 else 6631 dd = dd->dv_used_next; 6632 6633 /* 6634 * Go through the list of lists and free items without the copyID. 6635 * But don't free a list that has a watcher (used in a for loop), these 6636 * are not referenced anywhere. 6637 */ 6638 for (ll = first_list; ll != NULL; ) 6639 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 6640 && ll->lv_watch == NULL) 6641 { 6642 /* Free the List and ordinary items it contains, but don't recurse 6643 * into Lists and Dictionaries, they will be in the list of dicts 6644 * or list of lists. */ 6645 list_free(ll, FALSE); 6646 did_free = TRUE; 6647 6648 /* restart, next list may also have been freed */ 6649 ll = first_list; 6650 } 6651 else 6652 ll = ll->lv_used_next; 6653 6654 return did_free; 6655 } 6656 6657 /* 6658 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6659 */ 6660 static void 6661 set_ref_in_ht(ht, copyID) 6662 hashtab_T *ht; 6663 int copyID; 6664 { 6665 int todo; 6666 hashitem_T *hi; 6667 6668 todo = (int)ht->ht_used; 6669 for (hi = ht->ht_array; todo > 0; ++hi) 6670 if (!HASHITEM_EMPTY(hi)) 6671 { 6672 --todo; 6673 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 6674 } 6675 } 6676 6677 /* 6678 * Mark all lists and dicts referenced through list "l" with "copyID". 6679 */ 6680 static void 6681 set_ref_in_list(l, copyID) 6682 list_T *l; 6683 int copyID; 6684 { 6685 listitem_T *li; 6686 6687 for (li = l->lv_first; li != NULL; li = li->li_next) 6688 set_ref_in_item(&li->li_tv, copyID); 6689 } 6690 6691 /* 6692 * Mark all lists and dicts referenced through typval "tv" with "copyID". 6693 */ 6694 static void 6695 set_ref_in_item(tv, copyID) 6696 typval_T *tv; 6697 int copyID; 6698 { 6699 dict_T *dd; 6700 list_T *ll; 6701 6702 switch (tv->v_type) 6703 { 6704 case VAR_DICT: 6705 dd = tv->vval.v_dict; 6706 if (dd != NULL && dd->dv_copyID != copyID) 6707 { 6708 /* Didn't see this dict yet. */ 6709 dd->dv_copyID = copyID; 6710 set_ref_in_ht(&dd->dv_hashtab, copyID); 6711 } 6712 break; 6713 6714 case VAR_LIST: 6715 ll = tv->vval.v_list; 6716 if (ll != NULL && ll->lv_copyID != copyID) 6717 { 6718 /* Didn't see this list yet. */ 6719 ll->lv_copyID = copyID; 6720 set_ref_in_list(ll, copyID); 6721 } 6722 break; 6723 } 6724 return; 6725 } 6726 6727 /* 6728 * Allocate an empty header for a dictionary. 6729 */ 6730 dict_T * 6731 dict_alloc() 6732 { 6733 dict_T *d; 6734 6735 d = (dict_T *)alloc(sizeof(dict_T)); 6736 if (d != NULL) 6737 { 6738 /* Add the list to the list of dicts for garbage collection. */ 6739 if (first_dict != NULL) 6740 first_dict->dv_used_prev = d; 6741 d->dv_used_next = first_dict; 6742 d->dv_used_prev = NULL; 6743 first_dict = d; 6744 6745 hash_init(&d->dv_hashtab); 6746 d->dv_lock = 0; 6747 d->dv_refcount = 0; 6748 d->dv_copyID = 0; 6749 } 6750 return d; 6751 } 6752 6753 /* 6754 * Unreference a Dictionary: decrement the reference count and free it when it 6755 * becomes zero. 6756 */ 6757 static void 6758 dict_unref(d) 6759 dict_T *d; 6760 { 6761 if (d != NULL && --d->dv_refcount <= 0) 6762 dict_free(d, TRUE); 6763 } 6764 6765 /* 6766 * Free a Dictionary, including all items it contains. 6767 * Ignores the reference count. 6768 */ 6769 static void 6770 dict_free(d, recurse) 6771 dict_T *d; 6772 int recurse; /* Free Lists and Dictionaries recursively. */ 6773 { 6774 int todo; 6775 hashitem_T *hi; 6776 dictitem_T *di; 6777 6778 /* Remove the dict from the list of dicts for garbage collection. */ 6779 if (d->dv_used_prev == NULL) 6780 first_dict = d->dv_used_next; 6781 else 6782 d->dv_used_prev->dv_used_next = d->dv_used_next; 6783 if (d->dv_used_next != NULL) 6784 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6785 6786 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6787 hash_lock(&d->dv_hashtab); 6788 todo = (int)d->dv_hashtab.ht_used; 6789 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6790 { 6791 if (!HASHITEM_EMPTY(hi)) 6792 { 6793 /* Remove the item before deleting it, just in case there is 6794 * something recursive causing trouble. */ 6795 di = HI2DI(hi); 6796 hash_remove(&d->dv_hashtab, hi); 6797 if (recurse || (di->di_tv.v_type != VAR_LIST 6798 && di->di_tv.v_type != VAR_DICT)) 6799 clear_tv(&di->di_tv); 6800 vim_free(di); 6801 --todo; 6802 } 6803 } 6804 hash_clear(&d->dv_hashtab); 6805 vim_free(d); 6806 } 6807 6808 /* 6809 * Allocate a Dictionary item. 6810 * The "key" is copied to the new item. 6811 * Note that the value of the item "di_tv" still needs to be initialized! 6812 * Returns NULL when out of memory. 6813 */ 6814 static dictitem_T * 6815 dictitem_alloc(key) 6816 char_u *key; 6817 { 6818 dictitem_T *di; 6819 6820 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 6821 if (di != NULL) 6822 { 6823 STRCPY(di->di_key, key); 6824 di->di_flags = 0; 6825 } 6826 return di; 6827 } 6828 6829 /* 6830 * Make a copy of a Dictionary item. 6831 */ 6832 static dictitem_T * 6833 dictitem_copy(org) 6834 dictitem_T *org; 6835 { 6836 dictitem_T *di; 6837 6838 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 6839 + STRLEN(org->di_key))); 6840 if (di != NULL) 6841 { 6842 STRCPY(di->di_key, org->di_key); 6843 di->di_flags = 0; 6844 copy_tv(&org->di_tv, &di->di_tv); 6845 } 6846 return di; 6847 } 6848 6849 /* 6850 * Remove item "item" from Dictionary "dict" and free it. 6851 */ 6852 static void 6853 dictitem_remove(dict, item) 6854 dict_T *dict; 6855 dictitem_T *item; 6856 { 6857 hashitem_T *hi; 6858 6859 hi = hash_find(&dict->dv_hashtab, item->di_key); 6860 if (HASHITEM_EMPTY(hi)) 6861 EMSG2(_(e_intern2), "dictitem_remove()"); 6862 else 6863 hash_remove(&dict->dv_hashtab, hi); 6864 dictitem_free(item); 6865 } 6866 6867 /* 6868 * Free a dict item. Also clears the value. 6869 */ 6870 static void 6871 dictitem_free(item) 6872 dictitem_T *item; 6873 { 6874 clear_tv(&item->di_tv); 6875 vim_free(item); 6876 } 6877 6878 /* 6879 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6880 * The refcount of the new dict is set to 1. 6881 * See item_copy() for "copyID". 6882 * Returns NULL when out of memory. 6883 */ 6884 static dict_T * 6885 dict_copy(orig, deep, copyID) 6886 dict_T *orig; 6887 int deep; 6888 int copyID; 6889 { 6890 dict_T *copy; 6891 dictitem_T *di; 6892 int todo; 6893 hashitem_T *hi; 6894 6895 if (orig == NULL) 6896 return NULL; 6897 6898 copy = dict_alloc(); 6899 if (copy != NULL) 6900 { 6901 if (copyID != 0) 6902 { 6903 orig->dv_copyID = copyID; 6904 orig->dv_copydict = copy; 6905 } 6906 todo = (int)orig->dv_hashtab.ht_used; 6907 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6908 { 6909 if (!HASHITEM_EMPTY(hi)) 6910 { 6911 --todo; 6912 6913 di = dictitem_alloc(hi->hi_key); 6914 if (di == NULL) 6915 break; 6916 if (deep) 6917 { 6918 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6919 copyID) == FAIL) 6920 { 6921 vim_free(di); 6922 break; 6923 } 6924 } 6925 else 6926 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6927 if (dict_add(copy, di) == FAIL) 6928 { 6929 dictitem_free(di); 6930 break; 6931 } 6932 } 6933 } 6934 6935 ++copy->dv_refcount; 6936 if (todo > 0) 6937 { 6938 dict_unref(copy); 6939 copy = NULL; 6940 } 6941 } 6942 6943 return copy; 6944 } 6945 6946 /* 6947 * Add item "item" to Dictionary "d". 6948 * Returns FAIL when out of memory and when key already existed. 6949 */ 6950 static int 6951 dict_add(d, item) 6952 dict_T *d; 6953 dictitem_T *item; 6954 { 6955 return hash_add(&d->dv_hashtab, item->di_key); 6956 } 6957 6958 /* 6959 * Add a number or string entry to dictionary "d". 6960 * When "str" is NULL use number "nr", otherwise use "str". 6961 * Returns FAIL when out of memory and when key already exists. 6962 */ 6963 int 6964 dict_add_nr_str(d, key, nr, str) 6965 dict_T *d; 6966 char *key; 6967 long nr; 6968 char_u *str; 6969 { 6970 dictitem_T *item; 6971 6972 item = dictitem_alloc((char_u *)key); 6973 if (item == NULL) 6974 return FAIL; 6975 item->di_tv.v_lock = 0; 6976 if (str == NULL) 6977 { 6978 item->di_tv.v_type = VAR_NUMBER; 6979 item->di_tv.vval.v_number = nr; 6980 } 6981 else 6982 { 6983 item->di_tv.v_type = VAR_STRING; 6984 item->di_tv.vval.v_string = vim_strsave(str); 6985 } 6986 if (dict_add(d, item) == FAIL) 6987 { 6988 dictitem_free(item); 6989 return FAIL; 6990 } 6991 return OK; 6992 } 6993 6994 /* 6995 * Get the number of items in a Dictionary. 6996 */ 6997 static long 6998 dict_len(d) 6999 dict_T *d; 7000 { 7001 if (d == NULL) 7002 return 0L; 7003 return (long)d->dv_hashtab.ht_used; 7004 } 7005 7006 /* 7007 * Find item "key[len]" in Dictionary "d". 7008 * If "len" is negative use strlen(key). 7009 * Returns NULL when not found. 7010 */ 7011 static dictitem_T * 7012 dict_find(d, key, len) 7013 dict_T *d; 7014 char_u *key; 7015 int len; 7016 { 7017 #define AKEYLEN 200 7018 char_u buf[AKEYLEN]; 7019 char_u *akey; 7020 char_u *tofree = NULL; 7021 hashitem_T *hi; 7022 7023 if (len < 0) 7024 akey = key; 7025 else if (len >= AKEYLEN) 7026 { 7027 tofree = akey = vim_strnsave(key, len); 7028 if (akey == NULL) 7029 return NULL; 7030 } 7031 else 7032 { 7033 /* Avoid a malloc/free by using buf[]. */ 7034 vim_strncpy(buf, key, len); 7035 akey = buf; 7036 } 7037 7038 hi = hash_find(&d->dv_hashtab, akey); 7039 vim_free(tofree); 7040 if (HASHITEM_EMPTY(hi)) 7041 return NULL; 7042 return HI2DI(hi); 7043 } 7044 7045 /* 7046 * Get a string item from a dictionary. 7047 * When "save" is TRUE allocate memory for it. 7048 * Returns NULL if the entry doesn't exist or out of memory. 7049 */ 7050 char_u * 7051 get_dict_string(d, key, save) 7052 dict_T *d; 7053 char_u *key; 7054 int save; 7055 { 7056 dictitem_T *di; 7057 char_u *s; 7058 7059 di = dict_find(d, key, -1); 7060 if (di == NULL) 7061 return NULL; 7062 s = get_tv_string(&di->di_tv); 7063 if (save && s != NULL) 7064 s = vim_strsave(s); 7065 return s; 7066 } 7067 7068 /* 7069 * Get a number item from a dictionary. 7070 * Returns 0 if the entry doesn't exist or out of memory. 7071 */ 7072 long 7073 get_dict_number(d, key) 7074 dict_T *d; 7075 char_u *key; 7076 { 7077 dictitem_T *di; 7078 7079 di = dict_find(d, key, -1); 7080 if (di == NULL) 7081 return 0; 7082 return get_tv_number(&di->di_tv); 7083 } 7084 7085 /* 7086 * Return an allocated string with the string representation of a Dictionary. 7087 * May return NULL. 7088 */ 7089 static char_u * 7090 dict2string(tv, copyID) 7091 typval_T *tv; 7092 int copyID; 7093 { 7094 garray_T ga; 7095 int first = TRUE; 7096 char_u *tofree; 7097 char_u numbuf[NUMBUFLEN]; 7098 hashitem_T *hi; 7099 char_u *s; 7100 dict_T *d; 7101 int todo; 7102 7103 if ((d = tv->vval.v_dict) == NULL) 7104 return NULL; 7105 ga_init2(&ga, (int)sizeof(char), 80); 7106 ga_append(&ga, '{'); 7107 7108 todo = (int)d->dv_hashtab.ht_used; 7109 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7110 { 7111 if (!HASHITEM_EMPTY(hi)) 7112 { 7113 --todo; 7114 7115 if (first) 7116 first = FALSE; 7117 else 7118 ga_concat(&ga, (char_u *)", "); 7119 7120 tofree = string_quote(hi->hi_key, FALSE); 7121 if (tofree != NULL) 7122 { 7123 ga_concat(&ga, tofree); 7124 vim_free(tofree); 7125 } 7126 ga_concat(&ga, (char_u *)": "); 7127 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 7128 if (s != NULL) 7129 ga_concat(&ga, s); 7130 vim_free(tofree); 7131 if (s == NULL) 7132 break; 7133 } 7134 } 7135 if (todo > 0) 7136 { 7137 vim_free(ga.ga_data); 7138 return NULL; 7139 } 7140 7141 ga_append(&ga, '}'); 7142 ga_append(&ga, NUL); 7143 return (char_u *)ga.ga_data; 7144 } 7145 7146 /* 7147 * Allocate a variable for a Dictionary and fill it from "*arg". 7148 * Return OK or FAIL. Returns NOTDONE for {expr}. 7149 */ 7150 static int 7151 get_dict_tv(arg, rettv, evaluate) 7152 char_u **arg; 7153 typval_T *rettv; 7154 int evaluate; 7155 { 7156 dict_T *d = NULL; 7157 typval_T tvkey; 7158 typval_T tv; 7159 char_u *key = NULL; 7160 dictitem_T *item; 7161 char_u *start = skipwhite(*arg + 1); 7162 char_u buf[NUMBUFLEN]; 7163 7164 /* 7165 * First check if it's not a curly-braces thing: {expr}. 7166 * Must do this without evaluating, otherwise a function may be called 7167 * twice. Unfortunately this means we need to call eval1() twice for the 7168 * first item. 7169 * But {} is an empty Dictionary. 7170 */ 7171 if (*start != '}') 7172 { 7173 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 7174 return FAIL; 7175 if (*start == '}') 7176 return NOTDONE; 7177 } 7178 7179 if (evaluate) 7180 { 7181 d = dict_alloc(); 7182 if (d == NULL) 7183 return FAIL; 7184 } 7185 tvkey.v_type = VAR_UNKNOWN; 7186 tv.v_type = VAR_UNKNOWN; 7187 7188 *arg = skipwhite(*arg + 1); 7189 while (**arg != '}' && **arg != NUL) 7190 { 7191 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 7192 goto failret; 7193 if (**arg != ':') 7194 { 7195 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 7196 clear_tv(&tvkey); 7197 goto failret; 7198 } 7199 if (evaluate) 7200 { 7201 key = get_tv_string_buf_chk(&tvkey, buf); 7202 if (key == NULL || *key == NUL) 7203 { 7204 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 7205 if (key != NULL) 7206 EMSG(_(e_emptykey)); 7207 clear_tv(&tvkey); 7208 goto failret; 7209 } 7210 } 7211 7212 *arg = skipwhite(*arg + 1); 7213 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 7214 { 7215 if (evaluate) 7216 clear_tv(&tvkey); 7217 goto failret; 7218 } 7219 if (evaluate) 7220 { 7221 item = dict_find(d, key, -1); 7222 if (item != NULL) 7223 { 7224 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 7225 clear_tv(&tvkey); 7226 clear_tv(&tv); 7227 goto failret; 7228 } 7229 item = dictitem_alloc(key); 7230 clear_tv(&tvkey); 7231 if (item != NULL) 7232 { 7233 item->di_tv = tv; 7234 item->di_tv.v_lock = 0; 7235 if (dict_add(d, item) == FAIL) 7236 dictitem_free(item); 7237 } 7238 } 7239 7240 if (**arg == '}') 7241 break; 7242 if (**arg != ',') 7243 { 7244 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 7245 goto failret; 7246 } 7247 *arg = skipwhite(*arg + 1); 7248 } 7249 7250 if (**arg != '}') 7251 { 7252 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 7253 failret: 7254 if (evaluate) 7255 dict_free(d, TRUE); 7256 return FAIL; 7257 } 7258 7259 *arg = skipwhite(*arg + 1); 7260 if (evaluate) 7261 { 7262 rettv->v_type = VAR_DICT; 7263 rettv->vval.v_dict = d; 7264 ++d->dv_refcount; 7265 } 7266 7267 return OK; 7268 } 7269 7270 /* 7271 * Return a string with the string representation of a variable. 7272 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7273 * "numbuf" is used for a number. 7274 * Does not put quotes around strings, as ":echo" displays values. 7275 * When "copyID" is not NULL replace recursive lists and dicts with "...". 7276 * May return NULL. 7277 */ 7278 static char_u * 7279 echo_string(tv, tofree, numbuf, copyID) 7280 typval_T *tv; 7281 char_u **tofree; 7282 char_u *numbuf; 7283 int copyID; 7284 { 7285 static int recurse = 0; 7286 char_u *r = NULL; 7287 7288 if (recurse >= DICT_MAXNEST) 7289 { 7290 EMSG(_("E724: variable nested too deep for displaying")); 7291 *tofree = NULL; 7292 return NULL; 7293 } 7294 ++recurse; 7295 7296 switch (tv->v_type) 7297 { 7298 case VAR_FUNC: 7299 *tofree = NULL; 7300 r = tv->vval.v_string; 7301 break; 7302 7303 case VAR_LIST: 7304 if (tv->vval.v_list == NULL) 7305 { 7306 *tofree = NULL; 7307 r = NULL; 7308 } 7309 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 7310 { 7311 *tofree = NULL; 7312 r = (char_u *)"[...]"; 7313 } 7314 else 7315 { 7316 tv->vval.v_list->lv_copyID = copyID; 7317 *tofree = list2string(tv, copyID); 7318 r = *tofree; 7319 } 7320 break; 7321 7322 case VAR_DICT: 7323 if (tv->vval.v_dict == NULL) 7324 { 7325 *tofree = NULL; 7326 r = NULL; 7327 } 7328 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 7329 { 7330 *tofree = NULL; 7331 r = (char_u *)"{...}"; 7332 } 7333 else 7334 { 7335 tv->vval.v_dict->dv_copyID = copyID; 7336 *tofree = dict2string(tv, copyID); 7337 r = *tofree; 7338 } 7339 break; 7340 7341 case VAR_STRING: 7342 case VAR_NUMBER: 7343 *tofree = NULL; 7344 r = get_tv_string_buf(tv, numbuf); 7345 break; 7346 7347 #ifdef FEAT_FLOAT 7348 case VAR_FLOAT: 7349 *tofree = NULL; 7350 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float); 7351 r = numbuf; 7352 break; 7353 #endif 7354 7355 default: 7356 EMSG2(_(e_intern2), "echo_string()"); 7357 *tofree = NULL; 7358 } 7359 7360 --recurse; 7361 return r; 7362 } 7363 7364 /* 7365 * Return a string with the string representation of a variable. 7366 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7367 * "numbuf" is used for a number. 7368 * Puts quotes around strings, so that they can be parsed back by eval(). 7369 * May return NULL. 7370 */ 7371 static char_u * 7372 tv2string(tv, tofree, numbuf, copyID) 7373 typval_T *tv; 7374 char_u **tofree; 7375 char_u *numbuf; 7376 int copyID; 7377 { 7378 switch (tv->v_type) 7379 { 7380 case VAR_FUNC: 7381 *tofree = string_quote(tv->vval.v_string, TRUE); 7382 return *tofree; 7383 case VAR_STRING: 7384 *tofree = string_quote(tv->vval.v_string, FALSE); 7385 return *tofree; 7386 #ifdef FEAT_FLOAT 7387 case VAR_FLOAT: 7388 *tofree = NULL; 7389 vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); 7390 return numbuf; 7391 #endif 7392 case VAR_NUMBER: 7393 case VAR_LIST: 7394 case VAR_DICT: 7395 break; 7396 default: 7397 EMSG2(_(e_intern2), "tv2string()"); 7398 } 7399 return echo_string(tv, tofree, numbuf, copyID); 7400 } 7401 7402 /* 7403 * Return string "str" in ' quotes, doubling ' characters. 7404 * If "str" is NULL an empty string is assumed. 7405 * If "function" is TRUE make it function('string'). 7406 */ 7407 static char_u * 7408 string_quote(str, function) 7409 char_u *str; 7410 int function; 7411 { 7412 unsigned len; 7413 char_u *p, *r, *s; 7414 7415 len = (function ? 13 : 3); 7416 if (str != NULL) 7417 { 7418 len += (unsigned)STRLEN(str); 7419 for (p = str; *p != NUL; mb_ptr_adv(p)) 7420 if (*p == '\'') 7421 ++len; 7422 } 7423 s = r = alloc(len); 7424 if (r != NULL) 7425 { 7426 if (function) 7427 { 7428 STRCPY(r, "function('"); 7429 r += 10; 7430 } 7431 else 7432 *r++ = '\''; 7433 if (str != NULL) 7434 for (p = str; *p != NUL; ) 7435 { 7436 if (*p == '\'') 7437 *r++ = '\''; 7438 MB_COPY_CHAR(p, r); 7439 } 7440 *r++ = '\''; 7441 if (function) 7442 *r++ = ')'; 7443 *r++ = NUL; 7444 } 7445 return s; 7446 } 7447 7448 #ifdef FEAT_FLOAT 7449 /* 7450 * Convert the string "text" to a floating point number. 7451 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure 7452 * this always uses a decimal point. 7453 * Returns the length of the text that was consumed. 7454 */ 7455 static int 7456 string2float(text, value) 7457 char_u *text; 7458 float_T *value; /* result stored here */ 7459 { 7460 char *s = (char *)text; 7461 float_T f; 7462 7463 f = strtod(s, &s); 7464 *value = f; 7465 return (int)((char_u *)s - text); 7466 } 7467 #endif 7468 7469 /* 7470 * Get the value of an environment variable. 7471 * "arg" is pointing to the '$'. It is advanced to after the name. 7472 * If the environment variable was not set, silently assume it is empty. 7473 * Always return OK. 7474 */ 7475 static int 7476 get_env_tv(arg, rettv, evaluate) 7477 char_u **arg; 7478 typval_T *rettv; 7479 int evaluate; 7480 { 7481 char_u *string = NULL; 7482 int len; 7483 int cc; 7484 char_u *name; 7485 int mustfree = FALSE; 7486 7487 ++*arg; 7488 name = *arg; 7489 len = get_env_len(arg); 7490 if (evaluate) 7491 { 7492 if (len != 0) 7493 { 7494 cc = name[len]; 7495 name[len] = NUL; 7496 /* first try vim_getenv(), fast for normal environment vars */ 7497 string = vim_getenv(name, &mustfree); 7498 if (string != NULL && *string != NUL) 7499 { 7500 if (!mustfree) 7501 string = vim_strsave(string); 7502 } 7503 else 7504 { 7505 if (mustfree) 7506 vim_free(string); 7507 7508 /* next try expanding things like $VIM and ${HOME} */ 7509 string = expand_env_save(name - 1); 7510 if (string != NULL && *string == '$') 7511 { 7512 vim_free(string); 7513 string = NULL; 7514 } 7515 } 7516 name[len] = cc; 7517 } 7518 rettv->v_type = VAR_STRING; 7519 rettv->vval.v_string = string; 7520 } 7521 7522 return OK; 7523 } 7524 7525 /* 7526 * Array with names and number of arguments of all internal functions 7527 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 7528 */ 7529 static struct fst 7530 { 7531 char *f_name; /* function name */ 7532 char f_min_argc; /* minimal number of arguments */ 7533 char f_max_argc; /* maximal number of arguments */ 7534 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 7535 /* implementation of function */ 7536 } functions[] = 7537 { 7538 #ifdef FEAT_FLOAT 7539 {"abs", 1, 1, f_abs}, 7540 #endif 7541 {"add", 2, 2, f_add}, 7542 {"append", 2, 2, f_append}, 7543 {"argc", 0, 0, f_argc}, 7544 {"argidx", 0, 0, f_argidx}, 7545 {"argv", 0, 1, f_argv}, 7546 #ifdef FEAT_FLOAT 7547 {"atan", 1, 1, f_atan}, 7548 #endif 7549 {"browse", 4, 4, f_browse}, 7550 {"browsedir", 2, 2, f_browsedir}, 7551 {"bufexists", 1, 1, f_bufexists}, 7552 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 7553 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 7554 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 7555 {"buflisted", 1, 1, f_buflisted}, 7556 {"bufloaded", 1, 1, f_bufloaded}, 7557 {"bufname", 1, 1, f_bufname}, 7558 {"bufnr", 1, 2, f_bufnr}, 7559 {"bufwinnr", 1, 1, f_bufwinnr}, 7560 {"byte2line", 1, 1, f_byte2line}, 7561 {"byteidx", 2, 2, f_byteidx}, 7562 {"call", 2, 3, f_call}, 7563 #ifdef FEAT_FLOAT 7564 {"ceil", 1, 1, f_ceil}, 7565 #endif 7566 {"changenr", 0, 0, f_changenr}, 7567 {"char2nr", 1, 1, f_char2nr}, 7568 {"cindent", 1, 1, f_cindent}, 7569 {"clearmatches", 0, 0, f_clearmatches}, 7570 {"col", 1, 1, f_col}, 7571 #if defined(FEAT_INS_EXPAND) 7572 {"complete", 2, 2, f_complete}, 7573 {"complete_add", 1, 1, f_complete_add}, 7574 {"complete_check", 0, 0, f_complete_check}, 7575 #endif 7576 {"confirm", 1, 4, f_confirm}, 7577 {"copy", 1, 1, f_copy}, 7578 #ifdef FEAT_FLOAT 7579 {"cos", 1, 1, f_cos}, 7580 #endif 7581 {"count", 2, 4, f_count}, 7582 {"cscope_connection",0,3, f_cscope_connection}, 7583 {"cursor", 1, 3, f_cursor}, 7584 {"deepcopy", 1, 2, f_deepcopy}, 7585 {"delete", 1, 1, f_delete}, 7586 {"did_filetype", 0, 0, f_did_filetype}, 7587 {"diff_filler", 1, 1, f_diff_filler}, 7588 {"diff_hlID", 2, 2, f_diff_hlID}, 7589 {"empty", 1, 1, f_empty}, 7590 {"escape", 2, 2, f_escape}, 7591 {"eval", 1, 1, f_eval}, 7592 {"eventhandler", 0, 0, f_eventhandler}, 7593 {"executable", 1, 1, f_executable}, 7594 {"exists", 1, 1, f_exists}, 7595 {"expand", 1, 2, f_expand}, 7596 {"extend", 2, 3, f_extend}, 7597 {"feedkeys", 1, 2, f_feedkeys}, 7598 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 7599 {"filereadable", 1, 1, f_filereadable}, 7600 {"filewritable", 1, 1, f_filewritable}, 7601 {"filter", 2, 2, f_filter}, 7602 {"finddir", 1, 3, f_finddir}, 7603 {"findfile", 1, 3, f_findfile}, 7604 #ifdef FEAT_FLOAT 7605 {"float2nr", 1, 1, f_float2nr}, 7606 {"floor", 1, 1, f_floor}, 7607 #endif 7608 {"fnameescape", 1, 1, f_fnameescape}, 7609 {"fnamemodify", 2, 2, f_fnamemodify}, 7610 {"foldclosed", 1, 1, f_foldclosed}, 7611 {"foldclosedend", 1, 1, f_foldclosedend}, 7612 {"foldlevel", 1, 1, f_foldlevel}, 7613 {"foldtext", 0, 0, f_foldtext}, 7614 {"foldtextresult", 1, 1, f_foldtextresult}, 7615 {"foreground", 0, 0, f_foreground}, 7616 {"function", 1, 1, f_function}, 7617 {"garbagecollect", 0, 1, f_garbagecollect}, 7618 {"get", 2, 3, f_get}, 7619 {"getbufline", 2, 3, f_getbufline}, 7620 {"getbufvar", 2, 2, f_getbufvar}, 7621 {"getchar", 0, 1, f_getchar}, 7622 {"getcharmod", 0, 0, f_getcharmod}, 7623 {"getcmdline", 0, 0, f_getcmdline}, 7624 {"getcmdpos", 0, 0, f_getcmdpos}, 7625 {"getcmdtype", 0, 0, f_getcmdtype}, 7626 {"getcwd", 0, 0, f_getcwd}, 7627 {"getfontname", 0, 1, f_getfontname}, 7628 {"getfperm", 1, 1, f_getfperm}, 7629 {"getfsize", 1, 1, f_getfsize}, 7630 {"getftime", 1, 1, f_getftime}, 7631 {"getftype", 1, 1, f_getftype}, 7632 {"getline", 1, 2, f_getline}, 7633 {"getloclist", 1, 1, f_getqflist}, 7634 {"getmatches", 0, 0, f_getmatches}, 7635 {"getpid", 0, 0, f_getpid}, 7636 {"getpos", 1, 1, f_getpos}, 7637 {"getqflist", 0, 0, f_getqflist}, 7638 {"getreg", 0, 2, f_getreg}, 7639 {"getregtype", 0, 1, f_getregtype}, 7640 {"gettabwinvar", 3, 3, f_gettabwinvar}, 7641 {"getwinposx", 0, 0, f_getwinposx}, 7642 {"getwinposy", 0, 0, f_getwinposy}, 7643 {"getwinvar", 2, 2, f_getwinvar}, 7644 {"glob", 1, 2, f_glob}, 7645 {"globpath", 2, 3, f_globpath}, 7646 {"has", 1, 1, f_has}, 7647 {"has_key", 2, 2, f_has_key}, 7648 {"haslocaldir", 0, 0, f_haslocaldir}, 7649 {"hasmapto", 1, 3, f_hasmapto}, 7650 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 7651 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 7652 {"histadd", 2, 2, f_histadd}, 7653 {"histdel", 1, 2, f_histdel}, 7654 {"histget", 1, 2, f_histget}, 7655 {"histnr", 1, 1, f_histnr}, 7656 {"hlID", 1, 1, f_hlID}, 7657 {"hlexists", 1, 1, f_hlexists}, 7658 {"hostname", 0, 0, f_hostname}, 7659 {"iconv", 3, 3, f_iconv}, 7660 {"indent", 1, 1, f_indent}, 7661 {"index", 2, 4, f_index}, 7662 {"input", 1, 3, f_input}, 7663 {"inputdialog", 1, 3, f_inputdialog}, 7664 {"inputlist", 1, 1, f_inputlist}, 7665 {"inputrestore", 0, 0, f_inputrestore}, 7666 {"inputsave", 0, 0, f_inputsave}, 7667 {"inputsecret", 1, 2, f_inputsecret}, 7668 {"insert", 2, 3, f_insert}, 7669 {"isdirectory", 1, 1, f_isdirectory}, 7670 {"islocked", 1, 1, f_islocked}, 7671 {"items", 1, 1, f_items}, 7672 {"join", 1, 2, f_join}, 7673 {"keys", 1, 1, f_keys}, 7674 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 7675 {"len", 1, 1, f_len}, 7676 {"libcall", 3, 3, f_libcall}, 7677 {"libcallnr", 3, 3, f_libcallnr}, 7678 {"line", 1, 1, f_line}, 7679 {"line2byte", 1, 1, f_line2byte}, 7680 {"lispindent", 1, 1, f_lispindent}, 7681 {"localtime", 0, 0, f_localtime}, 7682 #ifdef FEAT_FLOAT 7683 {"log10", 1, 1, f_log10}, 7684 #endif 7685 {"map", 2, 2, f_map}, 7686 {"maparg", 1, 3, f_maparg}, 7687 {"mapcheck", 1, 3, f_mapcheck}, 7688 {"match", 2, 4, f_match}, 7689 {"matchadd", 2, 4, f_matchadd}, 7690 {"matcharg", 1, 1, f_matcharg}, 7691 {"matchdelete", 1, 1, f_matchdelete}, 7692 {"matchend", 2, 4, f_matchend}, 7693 {"matchlist", 2, 4, f_matchlist}, 7694 {"matchstr", 2, 4, f_matchstr}, 7695 {"max", 1, 1, f_max}, 7696 {"min", 1, 1, f_min}, 7697 #ifdef vim_mkdir 7698 {"mkdir", 1, 3, f_mkdir}, 7699 #endif 7700 {"mode", 0, 1, f_mode}, 7701 {"nextnonblank", 1, 1, f_nextnonblank}, 7702 {"nr2char", 1, 1, f_nr2char}, 7703 {"pathshorten", 1, 1, f_pathshorten}, 7704 #ifdef FEAT_FLOAT 7705 {"pow", 2, 2, f_pow}, 7706 #endif 7707 {"prevnonblank", 1, 1, f_prevnonblank}, 7708 {"printf", 2, 19, f_printf}, 7709 {"pumvisible", 0, 0, f_pumvisible}, 7710 {"range", 1, 3, f_range}, 7711 {"readfile", 1, 3, f_readfile}, 7712 {"reltime", 0, 2, f_reltime}, 7713 {"reltimestr", 1, 1, f_reltimestr}, 7714 {"remote_expr", 2, 3, f_remote_expr}, 7715 {"remote_foreground", 1, 1, f_remote_foreground}, 7716 {"remote_peek", 1, 2, f_remote_peek}, 7717 {"remote_read", 1, 1, f_remote_read}, 7718 {"remote_send", 2, 3, f_remote_send}, 7719 {"remove", 2, 3, f_remove}, 7720 {"rename", 2, 2, f_rename}, 7721 {"repeat", 2, 2, f_repeat}, 7722 {"resolve", 1, 1, f_resolve}, 7723 {"reverse", 1, 1, f_reverse}, 7724 #ifdef FEAT_FLOAT 7725 {"round", 1, 1, f_round}, 7726 #endif 7727 {"search", 1, 4, f_search}, 7728 {"searchdecl", 1, 3, f_searchdecl}, 7729 {"searchpair", 3, 7, f_searchpair}, 7730 {"searchpairpos", 3, 7, f_searchpairpos}, 7731 {"searchpos", 1, 4, f_searchpos}, 7732 {"server2client", 2, 2, f_server2client}, 7733 {"serverlist", 0, 0, f_serverlist}, 7734 {"setbufvar", 3, 3, f_setbufvar}, 7735 {"setcmdpos", 1, 1, f_setcmdpos}, 7736 {"setline", 2, 2, f_setline}, 7737 {"setloclist", 2, 3, f_setloclist}, 7738 {"setmatches", 1, 1, f_setmatches}, 7739 {"setpos", 2, 2, f_setpos}, 7740 {"setqflist", 1, 2, f_setqflist}, 7741 {"setreg", 2, 3, f_setreg}, 7742 {"settabwinvar", 4, 4, f_settabwinvar}, 7743 {"setwinvar", 3, 3, f_setwinvar}, 7744 {"shellescape", 1, 2, f_shellescape}, 7745 {"simplify", 1, 1, f_simplify}, 7746 #ifdef FEAT_FLOAT 7747 {"sin", 1, 1, f_sin}, 7748 #endif 7749 {"sort", 1, 2, f_sort}, 7750 {"soundfold", 1, 1, f_soundfold}, 7751 {"spellbadword", 0, 1, f_spellbadword}, 7752 {"spellsuggest", 1, 3, f_spellsuggest}, 7753 {"split", 1, 3, f_split}, 7754 #ifdef FEAT_FLOAT 7755 {"sqrt", 1, 1, f_sqrt}, 7756 {"str2float", 1, 1, f_str2float}, 7757 #endif 7758 {"str2nr", 1, 2, f_str2nr}, 7759 #ifdef HAVE_STRFTIME 7760 {"strftime", 1, 2, f_strftime}, 7761 #endif 7762 {"stridx", 2, 3, f_stridx}, 7763 {"string", 1, 1, f_string}, 7764 {"strlen", 1, 1, f_strlen}, 7765 {"strpart", 2, 3, f_strpart}, 7766 {"strridx", 2, 3, f_strridx}, 7767 {"strtrans", 1, 1, f_strtrans}, 7768 {"submatch", 1, 1, f_submatch}, 7769 {"substitute", 4, 4, f_substitute}, 7770 {"synID", 3, 3, f_synID}, 7771 {"synIDattr", 2, 3, f_synIDattr}, 7772 {"synIDtrans", 1, 1, f_synIDtrans}, 7773 {"synstack", 2, 2, f_synstack}, 7774 {"system", 1, 2, f_system}, 7775 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 7776 {"tabpagenr", 0, 1, f_tabpagenr}, 7777 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 7778 {"tagfiles", 0, 0, f_tagfiles}, 7779 {"taglist", 1, 1, f_taglist}, 7780 {"tempname", 0, 0, f_tempname}, 7781 {"test", 1, 1, f_test}, 7782 {"tolower", 1, 1, f_tolower}, 7783 {"toupper", 1, 1, f_toupper}, 7784 {"tr", 3, 3, f_tr}, 7785 #ifdef FEAT_FLOAT 7786 {"trunc", 1, 1, f_trunc}, 7787 #endif 7788 {"type", 1, 1, f_type}, 7789 {"values", 1, 1, f_values}, 7790 {"virtcol", 1, 1, f_virtcol}, 7791 {"visualmode", 0, 1, f_visualmode}, 7792 {"winbufnr", 1, 1, f_winbufnr}, 7793 {"wincol", 0, 0, f_wincol}, 7794 {"winheight", 1, 1, f_winheight}, 7795 {"winline", 0, 0, f_winline}, 7796 {"winnr", 0, 1, f_winnr}, 7797 {"winrestcmd", 0, 0, f_winrestcmd}, 7798 {"winrestview", 1, 1, f_winrestview}, 7799 {"winsaveview", 0, 0, f_winsaveview}, 7800 {"winwidth", 1, 1, f_winwidth}, 7801 {"writefile", 2, 3, f_writefile}, 7802 }; 7803 7804 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 7805 7806 /* 7807 * Function given to ExpandGeneric() to obtain the list of internal 7808 * or user defined function names. 7809 */ 7810 char_u * 7811 get_function_name(xp, idx) 7812 expand_T *xp; 7813 int idx; 7814 { 7815 static int intidx = -1; 7816 char_u *name; 7817 7818 if (idx == 0) 7819 intidx = -1; 7820 if (intidx < 0) 7821 { 7822 name = get_user_func_name(xp, idx); 7823 if (name != NULL) 7824 return name; 7825 } 7826 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 7827 { 7828 STRCPY(IObuff, functions[intidx].f_name); 7829 STRCAT(IObuff, "("); 7830 if (functions[intidx].f_max_argc == 0) 7831 STRCAT(IObuff, ")"); 7832 return IObuff; 7833 } 7834 7835 return NULL; 7836 } 7837 7838 /* 7839 * Function given to ExpandGeneric() to obtain the list of internal or 7840 * user defined variable or function names. 7841 */ 7842 char_u * 7843 get_expr_name(xp, idx) 7844 expand_T *xp; 7845 int idx; 7846 { 7847 static int intidx = -1; 7848 char_u *name; 7849 7850 if (idx == 0) 7851 intidx = -1; 7852 if (intidx < 0) 7853 { 7854 name = get_function_name(xp, idx); 7855 if (name != NULL) 7856 return name; 7857 } 7858 return get_user_var_name(xp, ++intidx); 7859 } 7860 7861 #endif /* FEAT_CMDL_COMPL */ 7862 7863 /* 7864 * Find internal function in table above. 7865 * Return index, or -1 if not found 7866 */ 7867 static int 7868 find_internal_func(name) 7869 char_u *name; /* name of the function */ 7870 { 7871 int first = 0; 7872 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 7873 int cmp; 7874 int x; 7875 7876 /* 7877 * Find the function name in the table. Binary search. 7878 */ 7879 while (first <= last) 7880 { 7881 x = first + ((unsigned)(last - first) >> 1); 7882 cmp = STRCMP(name, functions[x].f_name); 7883 if (cmp < 0) 7884 last = x - 1; 7885 else if (cmp > 0) 7886 first = x + 1; 7887 else 7888 return x; 7889 } 7890 return -1; 7891 } 7892 7893 /* 7894 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7895 * name it contains, otherwise return "name". 7896 */ 7897 static char_u * 7898 deref_func_name(name, lenp) 7899 char_u *name; 7900 int *lenp; 7901 { 7902 dictitem_T *v; 7903 int cc; 7904 7905 cc = name[*lenp]; 7906 name[*lenp] = NUL; 7907 v = find_var(name, NULL); 7908 name[*lenp] = cc; 7909 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7910 { 7911 if (v->di_tv.vval.v_string == NULL) 7912 { 7913 *lenp = 0; 7914 return (char_u *)""; /* just in case */ 7915 } 7916 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 7917 return v->di_tv.vval.v_string; 7918 } 7919 7920 return name; 7921 } 7922 7923 /* 7924 * Allocate a variable for the result of a function. 7925 * Return OK or FAIL. 7926 */ 7927 static int 7928 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7929 evaluate, selfdict) 7930 char_u *name; /* name of the function */ 7931 int len; /* length of "name" */ 7932 typval_T *rettv; 7933 char_u **arg; /* argument, pointing to the '(' */ 7934 linenr_T firstline; /* first line of range */ 7935 linenr_T lastline; /* last line of range */ 7936 int *doesrange; /* return: function handled range */ 7937 int evaluate; 7938 dict_T *selfdict; /* Dictionary for "self" */ 7939 { 7940 char_u *argp; 7941 int ret = OK; 7942 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 7943 int argcount = 0; /* number of arguments found */ 7944 7945 /* 7946 * Get the arguments. 7947 */ 7948 argp = *arg; 7949 while (argcount < MAX_FUNC_ARGS) 7950 { 7951 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7952 if (*argp == ')' || *argp == ',' || *argp == NUL) 7953 break; 7954 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7955 { 7956 ret = FAIL; 7957 break; 7958 } 7959 ++argcount; 7960 if (*argp != ',') 7961 break; 7962 } 7963 if (*argp == ')') 7964 ++argp; 7965 else 7966 ret = FAIL; 7967 7968 if (ret == OK) 7969 ret = call_func(name, len, rettv, argcount, argvars, 7970 firstline, lastline, doesrange, evaluate, selfdict); 7971 else if (!aborting()) 7972 { 7973 if (argcount == MAX_FUNC_ARGS) 7974 emsg_funcname(N_("E740: Too many arguments for function %s"), name); 7975 else 7976 emsg_funcname(N_("E116: Invalid arguments for function %s"), name); 7977 } 7978 7979 while (--argcount >= 0) 7980 clear_tv(&argvars[argcount]); 7981 7982 *arg = skipwhite(argp); 7983 return ret; 7984 } 7985 7986 7987 /* 7988 * Call a function with its resolved parameters 7989 * Return OK when the function can't be called, FAIL otherwise. 7990 * Also returns OK when an error was encountered while executing the function. 7991 */ 7992 static int 7993 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7994 doesrange, evaluate, selfdict) 7995 char_u *name; /* name of the function */ 7996 int len; /* length of "name" */ 7997 typval_T *rettv; /* return value goes here */ 7998 int argcount; /* number of "argvars" */ 7999 typval_T *argvars; /* vars for arguments, must have "argcount" 8000 PLUS ONE elements! */ 8001 linenr_T firstline; /* first line of range */ 8002 linenr_T lastline; /* last line of range */ 8003 int *doesrange; /* return: function handled range */ 8004 int evaluate; 8005 dict_T *selfdict; /* Dictionary for "self" */ 8006 { 8007 int ret = FAIL; 8008 #define ERROR_UNKNOWN 0 8009 #define ERROR_TOOMANY 1 8010 #define ERROR_TOOFEW 2 8011 #define ERROR_SCRIPT 3 8012 #define ERROR_DICT 4 8013 #define ERROR_NONE 5 8014 #define ERROR_OTHER 6 8015 int error = ERROR_NONE; 8016 int i; 8017 int llen; 8018 ufunc_T *fp; 8019 int cc; 8020 #define FLEN_FIXED 40 8021 char_u fname_buf[FLEN_FIXED + 1]; 8022 char_u *fname; 8023 8024 /* 8025 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 8026 * Change <SNR>123_name() to K_SNR 123_name(). 8027 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 8028 */ 8029 cc = name[len]; 8030 name[len] = NUL; 8031 llen = eval_fname_script(name); 8032 if (llen > 0) 8033 { 8034 fname_buf[0] = K_SPECIAL; 8035 fname_buf[1] = KS_EXTRA; 8036 fname_buf[2] = (int)KE_SNR; 8037 i = 3; 8038 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 8039 { 8040 if (current_SID <= 0) 8041 error = ERROR_SCRIPT; 8042 else 8043 { 8044 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 8045 i = (int)STRLEN(fname_buf); 8046 } 8047 } 8048 if (i + STRLEN(name + llen) < FLEN_FIXED) 8049 { 8050 STRCPY(fname_buf + i, name + llen); 8051 fname = fname_buf; 8052 } 8053 else 8054 { 8055 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 8056 if (fname == NULL) 8057 error = ERROR_OTHER; 8058 else 8059 { 8060 mch_memmove(fname, fname_buf, (size_t)i); 8061 STRCPY(fname + i, name + llen); 8062 } 8063 } 8064 } 8065 else 8066 fname = name; 8067 8068 *doesrange = FALSE; 8069 8070 8071 /* execute the function if no errors detected and executing */ 8072 if (evaluate && error == ERROR_NONE) 8073 { 8074 rettv->v_type = VAR_NUMBER; /* default rettv is number zero */ 8075 rettv->vval.v_number = 0; 8076 error = ERROR_UNKNOWN; 8077 8078 if (!builtin_function(fname)) 8079 { 8080 /* 8081 * User defined function. 8082 */ 8083 fp = find_func(fname); 8084 8085 #ifdef FEAT_AUTOCMD 8086 /* Trigger FuncUndefined event, may load the function. */ 8087 if (fp == NULL 8088 && apply_autocmds(EVENT_FUNCUNDEFINED, 8089 fname, fname, TRUE, NULL) 8090 && !aborting()) 8091 { 8092 /* executed an autocommand, search for the function again */ 8093 fp = find_func(fname); 8094 } 8095 #endif 8096 /* Try loading a package. */ 8097 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 8098 { 8099 /* loaded a package, search for the function again */ 8100 fp = find_func(fname); 8101 } 8102 8103 if (fp != NULL) 8104 { 8105 if (fp->uf_flags & FC_RANGE) 8106 *doesrange = TRUE; 8107 if (argcount < fp->uf_args.ga_len) 8108 error = ERROR_TOOFEW; 8109 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 8110 error = ERROR_TOOMANY; 8111 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 8112 error = ERROR_DICT; 8113 else 8114 { 8115 /* 8116 * Call the user function. 8117 * Save and restore search patterns, script variables and 8118 * redo buffer. 8119 */ 8120 save_search_patterns(); 8121 saveRedobuff(); 8122 ++fp->uf_calls; 8123 call_user_func(fp, argcount, argvars, rettv, 8124 firstline, lastline, 8125 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 8126 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 8127 && fp->uf_refcount <= 0) 8128 /* Function was unreferenced while being used, free it 8129 * now. */ 8130 func_free(fp); 8131 restoreRedobuff(); 8132 restore_search_patterns(); 8133 error = ERROR_NONE; 8134 } 8135 } 8136 } 8137 else 8138 { 8139 /* 8140 * Find the function name in the table, call its implementation. 8141 */ 8142 i = find_internal_func(fname); 8143 if (i >= 0) 8144 { 8145 if (argcount < functions[i].f_min_argc) 8146 error = ERROR_TOOFEW; 8147 else if (argcount > functions[i].f_max_argc) 8148 error = ERROR_TOOMANY; 8149 else 8150 { 8151 argvars[argcount].v_type = VAR_UNKNOWN; 8152 functions[i].f_func(argvars, rettv); 8153 error = ERROR_NONE; 8154 } 8155 } 8156 } 8157 /* 8158 * The function call (or "FuncUndefined" autocommand sequence) might 8159 * have been aborted by an error, an interrupt, or an explicitly thrown 8160 * exception that has not been caught so far. This situation can be 8161 * tested for by calling aborting(). For an error in an internal 8162 * function or for the "E132" error in call_user_func(), however, the 8163 * throw point at which the "force_abort" flag (temporarily reset by 8164 * emsg()) is normally updated has not been reached yet. We need to 8165 * update that flag first to make aborting() reliable. 8166 */ 8167 update_force_abort(); 8168 } 8169 if (error == ERROR_NONE) 8170 ret = OK; 8171 8172 /* 8173 * Report an error unless the argument evaluation or function call has been 8174 * cancelled due to an aborting error, an interrupt, or an exception. 8175 */ 8176 if (!aborting()) 8177 { 8178 switch (error) 8179 { 8180 case ERROR_UNKNOWN: 8181 emsg_funcname(N_("E117: Unknown function: %s"), name); 8182 break; 8183 case ERROR_TOOMANY: 8184 emsg_funcname(e_toomanyarg, name); 8185 break; 8186 case ERROR_TOOFEW: 8187 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 8188 name); 8189 break; 8190 case ERROR_SCRIPT: 8191 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 8192 name); 8193 break; 8194 case ERROR_DICT: 8195 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 8196 name); 8197 break; 8198 } 8199 } 8200 8201 name[len] = cc; 8202 if (fname != name && fname != fname_buf) 8203 vim_free(fname); 8204 8205 return ret; 8206 } 8207 8208 /* 8209 * Give an error message with a function name. Handle <SNR> things. 8210 * "ermsg" is to be passed without translation, use N_() instead of _(). 8211 */ 8212 static void 8213 emsg_funcname(ermsg, name) 8214 char *ermsg; 8215 char_u *name; 8216 { 8217 char_u *p; 8218 8219 if (*name == K_SPECIAL) 8220 p = concat_str((char_u *)"<SNR>", name + 3); 8221 else 8222 p = name; 8223 EMSG2(_(ermsg), p); 8224 if (p != name) 8225 vim_free(p); 8226 } 8227 8228 /* 8229 * Return TRUE for a non-zero Number and a non-empty String. 8230 */ 8231 static int 8232 non_zero_arg(argvars) 8233 typval_T *argvars; 8234 { 8235 return ((argvars[0].v_type == VAR_NUMBER 8236 && argvars[0].vval.v_number != 0) 8237 || (argvars[0].v_type == VAR_STRING 8238 && argvars[0].vval.v_string != NULL 8239 && *argvars[0].vval.v_string != NUL)); 8240 } 8241 8242 /********************************************* 8243 * Implementation of the built-in functions 8244 */ 8245 8246 #ifdef FEAT_FLOAT 8247 /* 8248 * "abs(expr)" function 8249 */ 8250 static void 8251 f_abs(argvars, rettv) 8252 typval_T *argvars; 8253 typval_T *rettv; 8254 { 8255 if (argvars[0].v_type == VAR_FLOAT) 8256 { 8257 rettv->v_type = VAR_FLOAT; 8258 rettv->vval.v_float = fabs(argvars[0].vval.v_float); 8259 } 8260 else 8261 { 8262 varnumber_T n; 8263 int error = FALSE; 8264 8265 n = get_tv_number_chk(&argvars[0], &error); 8266 if (error) 8267 rettv->vval.v_number = -1; 8268 else if (n > 0) 8269 rettv->vval.v_number = n; 8270 else 8271 rettv->vval.v_number = -n; 8272 } 8273 } 8274 #endif 8275 8276 /* 8277 * "add(list, item)" function 8278 */ 8279 static void 8280 f_add(argvars, rettv) 8281 typval_T *argvars; 8282 typval_T *rettv; 8283 { 8284 list_T *l; 8285 8286 rettv->vval.v_number = 1; /* Default: Failed */ 8287 if (argvars[0].v_type == VAR_LIST) 8288 { 8289 if ((l = argvars[0].vval.v_list) != NULL 8290 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 8291 && list_append_tv(l, &argvars[1]) == OK) 8292 copy_tv(&argvars[0], rettv); 8293 } 8294 else 8295 EMSG(_(e_listreq)); 8296 } 8297 8298 /* 8299 * "append(lnum, string/list)" function 8300 */ 8301 static void 8302 f_append(argvars, rettv) 8303 typval_T *argvars; 8304 typval_T *rettv; 8305 { 8306 long lnum; 8307 char_u *line; 8308 list_T *l = NULL; 8309 listitem_T *li = NULL; 8310 typval_T *tv; 8311 long added = 0; 8312 8313 lnum = get_tv_lnum(argvars); 8314 if (lnum >= 0 8315 && lnum <= curbuf->b_ml.ml_line_count 8316 && u_save(lnum, lnum + 1) == OK) 8317 { 8318 if (argvars[1].v_type == VAR_LIST) 8319 { 8320 l = argvars[1].vval.v_list; 8321 if (l == NULL) 8322 return; 8323 li = l->lv_first; 8324 } 8325 for (;;) 8326 { 8327 if (l == NULL) 8328 tv = &argvars[1]; /* append a string */ 8329 else if (li == NULL) 8330 break; /* end of list */ 8331 else 8332 tv = &li->li_tv; /* append item from list */ 8333 line = get_tv_string_chk(tv); 8334 if (line == NULL) /* type error */ 8335 { 8336 rettv->vval.v_number = 1; /* Failed */ 8337 break; 8338 } 8339 ml_append(lnum + added, line, (colnr_T)0, FALSE); 8340 ++added; 8341 if (l == NULL) 8342 break; 8343 li = li->li_next; 8344 } 8345 8346 appended_lines_mark(lnum, added); 8347 if (curwin->w_cursor.lnum > lnum) 8348 curwin->w_cursor.lnum += added; 8349 } 8350 else 8351 rettv->vval.v_number = 1; /* Failed */ 8352 } 8353 8354 /* 8355 * "argc()" function 8356 */ 8357 static void 8358 f_argc(argvars, rettv) 8359 typval_T *argvars UNUSED; 8360 typval_T *rettv; 8361 { 8362 rettv->vval.v_number = ARGCOUNT; 8363 } 8364 8365 /* 8366 * "argidx()" function 8367 */ 8368 static void 8369 f_argidx(argvars, rettv) 8370 typval_T *argvars UNUSED; 8371 typval_T *rettv; 8372 { 8373 rettv->vval.v_number = curwin->w_arg_idx; 8374 } 8375 8376 /* 8377 * "argv(nr)" function 8378 */ 8379 static void 8380 f_argv(argvars, rettv) 8381 typval_T *argvars; 8382 typval_T *rettv; 8383 { 8384 int idx; 8385 8386 if (argvars[0].v_type != VAR_UNKNOWN) 8387 { 8388 idx = get_tv_number_chk(&argvars[0], NULL); 8389 if (idx >= 0 && idx < ARGCOUNT) 8390 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 8391 else 8392 rettv->vval.v_string = NULL; 8393 rettv->v_type = VAR_STRING; 8394 } 8395 else if (rettv_list_alloc(rettv) == OK) 8396 for (idx = 0; idx < ARGCOUNT; ++idx) 8397 list_append_string(rettv->vval.v_list, 8398 alist_name(&ARGLIST[idx]), -1); 8399 } 8400 8401 #ifdef FEAT_FLOAT 8402 static int get_float_arg __ARGS((typval_T *argvars, float_T *f)); 8403 8404 /* 8405 * Get the float value of "argvars[0]" into "f". 8406 * Returns FAIL when the argument is not a Number or Float. 8407 */ 8408 static int 8409 get_float_arg(argvars, f) 8410 typval_T *argvars; 8411 float_T *f; 8412 { 8413 if (argvars[0].v_type == VAR_FLOAT) 8414 { 8415 *f = argvars[0].vval.v_float; 8416 return OK; 8417 } 8418 if (argvars[0].v_type == VAR_NUMBER) 8419 { 8420 *f = (float_T)argvars[0].vval.v_number; 8421 return OK; 8422 } 8423 EMSG(_("E808: Number or Float required")); 8424 return FAIL; 8425 } 8426 8427 /* 8428 * "atan()" function 8429 */ 8430 static void 8431 f_atan(argvars, rettv) 8432 typval_T *argvars; 8433 typval_T *rettv; 8434 { 8435 float_T f; 8436 8437 rettv->v_type = VAR_FLOAT; 8438 if (get_float_arg(argvars, &f) == OK) 8439 rettv->vval.v_float = atan(f); 8440 else 8441 rettv->vval.v_float = 0.0; 8442 } 8443 #endif 8444 8445 /* 8446 * "browse(save, title, initdir, default)" function 8447 */ 8448 static void 8449 f_browse(argvars, rettv) 8450 typval_T *argvars UNUSED; 8451 typval_T *rettv; 8452 { 8453 #ifdef FEAT_BROWSE 8454 int save; 8455 char_u *title; 8456 char_u *initdir; 8457 char_u *defname; 8458 char_u buf[NUMBUFLEN]; 8459 char_u buf2[NUMBUFLEN]; 8460 int error = FALSE; 8461 8462 save = get_tv_number_chk(&argvars[0], &error); 8463 title = get_tv_string_chk(&argvars[1]); 8464 initdir = get_tv_string_buf_chk(&argvars[2], buf); 8465 defname = get_tv_string_buf_chk(&argvars[3], buf2); 8466 8467 if (error || title == NULL || initdir == NULL || defname == NULL) 8468 rettv->vval.v_string = NULL; 8469 else 8470 rettv->vval.v_string = 8471 do_browse(save ? BROWSE_SAVE : 0, 8472 title, defname, NULL, initdir, NULL, curbuf); 8473 #else 8474 rettv->vval.v_string = NULL; 8475 #endif 8476 rettv->v_type = VAR_STRING; 8477 } 8478 8479 /* 8480 * "browsedir(title, initdir)" function 8481 */ 8482 static void 8483 f_browsedir(argvars, rettv) 8484 typval_T *argvars UNUSED; 8485 typval_T *rettv; 8486 { 8487 #ifdef FEAT_BROWSE 8488 char_u *title; 8489 char_u *initdir; 8490 char_u buf[NUMBUFLEN]; 8491 8492 title = get_tv_string_chk(&argvars[0]); 8493 initdir = get_tv_string_buf_chk(&argvars[1], buf); 8494 8495 if (title == NULL || initdir == NULL) 8496 rettv->vval.v_string = NULL; 8497 else 8498 rettv->vval.v_string = do_browse(BROWSE_DIR, 8499 title, NULL, NULL, initdir, NULL, curbuf); 8500 #else 8501 rettv->vval.v_string = NULL; 8502 #endif 8503 rettv->v_type = VAR_STRING; 8504 } 8505 8506 static buf_T *find_buffer __ARGS((typval_T *avar)); 8507 8508 /* 8509 * Find a buffer by number or exact name. 8510 */ 8511 static buf_T * 8512 find_buffer(avar) 8513 typval_T *avar; 8514 { 8515 buf_T *buf = NULL; 8516 8517 if (avar->v_type == VAR_NUMBER) 8518 buf = buflist_findnr((int)avar->vval.v_number); 8519 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 8520 { 8521 buf = buflist_findname_exp(avar->vval.v_string); 8522 if (buf == NULL) 8523 { 8524 /* No full path name match, try a match with a URL or a "nofile" 8525 * buffer, these don't use the full path. */ 8526 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 8527 if (buf->b_fname != NULL 8528 && (path_with_url(buf->b_fname) 8529 #ifdef FEAT_QUICKFIX 8530 || bt_nofile(buf) 8531 #endif 8532 ) 8533 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 8534 break; 8535 } 8536 } 8537 return buf; 8538 } 8539 8540 /* 8541 * "bufexists(expr)" function 8542 */ 8543 static void 8544 f_bufexists(argvars, rettv) 8545 typval_T *argvars; 8546 typval_T *rettv; 8547 { 8548 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 8549 } 8550 8551 /* 8552 * "buflisted(expr)" function 8553 */ 8554 static void 8555 f_buflisted(argvars, rettv) 8556 typval_T *argvars; 8557 typval_T *rettv; 8558 { 8559 buf_T *buf; 8560 8561 buf = find_buffer(&argvars[0]); 8562 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 8563 } 8564 8565 /* 8566 * "bufloaded(expr)" function 8567 */ 8568 static void 8569 f_bufloaded(argvars, rettv) 8570 typval_T *argvars; 8571 typval_T *rettv; 8572 { 8573 buf_T *buf; 8574 8575 buf = find_buffer(&argvars[0]); 8576 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 8577 } 8578 8579 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 8580 8581 /* 8582 * Get buffer by number or pattern. 8583 */ 8584 static buf_T * 8585 get_buf_tv(tv) 8586 typval_T *tv; 8587 { 8588 char_u *name = tv->vval.v_string; 8589 int save_magic; 8590 char_u *save_cpo; 8591 buf_T *buf; 8592 8593 if (tv->v_type == VAR_NUMBER) 8594 return buflist_findnr((int)tv->vval.v_number); 8595 if (tv->v_type != VAR_STRING) 8596 return NULL; 8597 if (name == NULL || *name == NUL) 8598 return curbuf; 8599 if (name[0] == '$' && name[1] == NUL) 8600 return lastbuf; 8601 8602 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 8603 save_magic = p_magic; 8604 p_magic = TRUE; 8605 save_cpo = p_cpo; 8606 p_cpo = (char_u *)""; 8607 8608 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 8609 TRUE, FALSE)); 8610 8611 p_magic = save_magic; 8612 p_cpo = save_cpo; 8613 8614 /* If not found, try expanding the name, like done for bufexists(). */ 8615 if (buf == NULL) 8616 buf = find_buffer(tv); 8617 8618 return buf; 8619 } 8620 8621 /* 8622 * "bufname(expr)" function 8623 */ 8624 static void 8625 f_bufname(argvars, rettv) 8626 typval_T *argvars; 8627 typval_T *rettv; 8628 { 8629 buf_T *buf; 8630 8631 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8632 ++emsg_off; 8633 buf = get_buf_tv(&argvars[0]); 8634 rettv->v_type = VAR_STRING; 8635 if (buf != NULL && buf->b_fname != NULL) 8636 rettv->vval.v_string = vim_strsave(buf->b_fname); 8637 else 8638 rettv->vval.v_string = NULL; 8639 --emsg_off; 8640 } 8641 8642 /* 8643 * "bufnr(expr)" function 8644 */ 8645 static void 8646 f_bufnr(argvars, rettv) 8647 typval_T *argvars; 8648 typval_T *rettv; 8649 { 8650 buf_T *buf; 8651 int error = FALSE; 8652 char_u *name; 8653 8654 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8655 ++emsg_off; 8656 buf = get_buf_tv(&argvars[0]); 8657 --emsg_off; 8658 8659 /* If the buffer isn't found and the second argument is not zero create a 8660 * new buffer. */ 8661 if (buf == NULL 8662 && argvars[1].v_type != VAR_UNKNOWN 8663 && get_tv_number_chk(&argvars[1], &error) != 0 8664 && !error 8665 && (name = get_tv_string_chk(&argvars[0])) != NULL 8666 && !error) 8667 buf = buflist_new(name, NULL, (linenr_T)1, 0); 8668 8669 if (buf != NULL) 8670 rettv->vval.v_number = buf->b_fnum; 8671 else 8672 rettv->vval.v_number = -1; 8673 } 8674 8675 /* 8676 * "bufwinnr(nr)" function 8677 */ 8678 static void 8679 f_bufwinnr(argvars, rettv) 8680 typval_T *argvars; 8681 typval_T *rettv; 8682 { 8683 #ifdef FEAT_WINDOWS 8684 win_T *wp; 8685 int winnr = 0; 8686 #endif 8687 buf_T *buf; 8688 8689 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8690 ++emsg_off; 8691 buf = get_buf_tv(&argvars[0]); 8692 #ifdef FEAT_WINDOWS 8693 for (wp = firstwin; wp; wp = wp->w_next) 8694 { 8695 ++winnr; 8696 if (wp->w_buffer == buf) 8697 break; 8698 } 8699 rettv->vval.v_number = (wp != NULL ? winnr : -1); 8700 #else 8701 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 8702 #endif 8703 --emsg_off; 8704 } 8705 8706 /* 8707 * "byte2line(byte)" function 8708 */ 8709 static void 8710 f_byte2line(argvars, rettv) 8711 typval_T *argvars UNUSED; 8712 typval_T *rettv; 8713 { 8714 #ifndef FEAT_BYTEOFF 8715 rettv->vval.v_number = -1; 8716 #else 8717 long boff = 0; 8718 8719 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 8720 if (boff < 0) 8721 rettv->vval.v_number = -1; 8722 else 8723 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 8724 (linenr_T)0, &boff); 8725 #endif 8726 } 8727 8728 /* 8729 * "byteidx()" function 8730 */ 8731 static void 8732 f_byteidx(argvars, rettv) 8733 typval_T *argvars; 8734 typval_T *rettv; 8735 { 8736 #ifdef FEAT_MBYTE 8737 char_u *t; 8738 #endif 8739 char_u *str; 8740 long idx; 8741 8742 str = get_tv_string_chk(&argvars[0]); 8743 idx = get_tv_number_chk(&argvars[1], NULL); 8744 rettv->vval.v_number = -1; 8745 if (str == NULL || idx < 0) 8746 return; 8747 8748 #ifdef FEAT_MBYTE 8749 t = str; 8750 for ( ; idx > 0; idx--) 8751 { 8752 if (*t == NUL) /* EOL reached */ 8753 return; 8754 t += (*mb_ptr2len)(t); 8755 } 8756 rettv->vval.v_number = (varnumber_T)(t - str); 8757 #else 8758 if ((size_t)idx <= STRLEN(str)) 8759 rettv->vval.v_number = idx; 8760 #endif 8761 } 8762 8763 /* 8764 * "call(func, arglist)" function 8765 */ 8766 static void 8767 f_call(argvars, rettv) 8768 typval_T *argvars; 8769 typval_T *rettv; 8770 { 8771 char_u *func; 8772 typval_T argv[MAX_FUNC_ARGS + 1]; 8773 int argc = 0; 8774 listitem_T *item; 8775 int dummy; 8776 dict_T *selfdict = NULL; 8777 8778 if (argvars[1].v_type != VAR_LIST) 8779 { 8780 EMSG(_(e_listreq)); 8781 return; 8782 } 8783 if (argvars[1].vval.v_list == NULL) 8784 return; 8785 8786 if (argvars[0].v_type == VAR_FUNC) 8787 func = argvars[0].vval.v_string; 8788 else 8789 func = get_tv_string(&argvars[0]); 8790 if (*func == NUL) 8791 return; /* type error or empty name */ 8792 8793 if (argvars[2].v_type != VAR_UNKNOWN) 8794 { 8795 if (argvars[2].v_type != VAR_DICT) 8796 { 8797 EMSG(_(e_dictreq)); 8798 return; 8799 } 8800 selfdict = argvars[2].vval.v_dict; 8801 } 8802 8803 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 8804 item = item->li_next) 8805 { 8806 if (argc == MAX_FUNC_ARGS) 8807 { 8808 EMSG(_("E699: Too many arguments")); 8809 break; 8810 } 8811 /* Make a copy of each argument. This is needed to be able to set 8812 * v_lock to VAR_FIXED in the copy without changing the original list. 8813 */ 8814 copy_tv(&item->li_tv, &argv[argc++]); 8815 } 8816 8817 if (item == NULL) 8818 (void)call_func(func, (int)STRLEN(func), rettv, argc, argv, 8819 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 8820 &dummy, TRUE, selfdict); 8821 8822 /* Free the arguments. */ 8823 while (argc > 0) 8824 clear_tv(&argv[--argc]); 8825 } 8826 8827 #ifdef FEAT_FLOAT 8828 /* 8829 * "ceil({float})" function 8830 */ 8831 static void 8832 f_ceil(argvars, rettv) 8833 typval_T *argvars; 8834 typval_T *rettv; 8835 { 8836 float_T f; 8837 8838 rettv->v_type = VAR_FLOAT; 8839 if (get_float_arg(argvars, &f) == OK) 8840 rettv->vval.v_float = ceil(f); 8841 else 8842 rettv->vval.v_float = 0.0; 8843 } 8844 #endif 8845 8846 /* 8847 * "changenr()" function 8848 */ 8849 static void 8850 f_changenr(argvars, rettv) 8851 typval_T *argvars UNUSED; 8852 typval_T *rettv; 8853 { 8854 rettv->vval.v_number = curbuf->b_u_seq_cur; 8855 } 8856 8857 /* 8858 * "char2nr(string)" function 8859 */ 8860 static void 8861 f_char2nr(argvars, rettv) 8862 typval_T *argvars; 8863 typval_T *rettv; 8864 { 8865 #ifdef FEAT_MBYTE 8866 if (has_mbyte) 8867 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 8868 else 8869 #endif 8870 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 8871 } 8872 8873 /* 8874 * "cindent(lnum)" function 8875 */ 8876 static void 8877 f_cindent(argvars, rettv) 8878 typval_T *argvars; 8879 typval_T *rettv; 8880 { 8881 #ifdef FEAT_CINDENT 8882 pos_T pos; 8883 linenr_T lnum; 8884 8885 pos = curwin->w_cursor; 8886 lnum = get_tv_lnum(argvars); 8887 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8888 { 8889 curwin->w_cursor.lnum = lnum; 8890 rettv->vval.v_number = get_c_indent(); 8891 curwin->w_cursor = pos; 8892 } 8893 else 8894 #endif 8895 rettv->vval.v_number = -1; 8896 } 8897 8898 /* 8899 * "clearmatches()" function 8900 */ 8901 static void 8902 f_clearmatches(argvars, rettv) 8903 typval_T *argvars UNUSED; 8904 typval_T *rettv UNUSED; 8905 { 8906 #ifdef FEAT_SEARCH_EXTRA 8907 clear_matches(curwin); 8908 #endif 8909 } 8910 8911 /* 8912 * "col(string)" function 8913 */ 8914 static void 8915 f_col(argvars, rettv) 8916 typval_T *argvars; 8917 typval_T *rettv; 8918 { 8919 colnr_T col = 0; 8920 pos_T *fp; 8921 int fnum = curbuf->b_fnum; 8922 8923 fp = var2fpos(&argvars[0], FALSE, &fnum); 8924 if (fp != NULL && fnum == curbuf->b_fnum) 8925 { 8926 if (fp->col == MAXCOL) 8927 { 8928 /* '> can be MAXCOL, get the length of the line then */ 8929 if (fp->lnum <= curbuf->b_ml.ml_line_count) 8930 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 8931 else 8932 col = MAXCOL; 8933 } 8934 else 8935 { 8936 col = fp->col + 1; 8937 #ifdef FEAT_VIRTUALEDIT 8938 /* col(".") when the cursor is on the NUL at the end of the line 8939 * because of "coladd" can be seen as an extra column. */ 8940 if (virtual_active() && fp == &curwin->w_cursor) 8941 { 8942 char_u *p = ml_get_cursor(); 8943 8944 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 8945 curwin->w_virtcol - curwin->w_cursor.coladd)) 8946 { 8947 # ifdef FEAT_MBYTE 8948 int l; 8949 8950 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 8951 col += l; 8952 # else 8953 if (*p != NUL && p[1] == NUL) 8954 ++col; 8955 # endif 8956 } 8957 } 8958 #endif 8959 } 8960 } 8961 rettv->vval.v_number = col; 8962 } 8963 8964 #if defined(FEAT_INS_EXPAND) 8965 /* 8966 * "complete()" function 8967 */ 8968 static void 8969 f_complete(argvars, rettv) 8970 typval_T *argvars; 8971 typval_T *rettv UNUSED; 8972 { 8973 int startcol; 8974 8975 if ((State & INSERT) == 0) 8976 { 8977 EMSG(_("E785: complete() can only be used in Insert mode")); 8978 return; 8979 } 8980 8981 /* Check for undo allowed here, because if something was already inserted 8982 * the line was already saved for undo and this check isn't done. */ 8983 if (!undo_allowed()) 8984 return; 8985 8986 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 8987 { 8988 EMSG(_(e_invarg)); 8989 return; 8990 } 8991 8992 startcol = get_tv_number_chk(&argvars[0], NULL); 8993 if (startcol <= 0) 8994 return; 8995 8996 set_completion(startcol - 1, argvars[1].vval.v_list); 8997 } 8998 8999 /* 9000 * "complete_add()" function 9001 */ 9002 static void 9003 f_complete_add(argvars, rettv) 9004 typval_T *argvars; 9005 typval_T *rettv; 9006 { 9007 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 9008 } 9009 9010 /* 9011 * "complete_check()" function 9012 */ 9013 static void 9014 f_complete_check(argvars, rettv) 9015 typval_T *argvars UNUSED; 9016 typval_T *rettv; 9017 { 9018 int saved = RedrawingDisabled; 9019 9020 RedrawingDisabled = 0; 9021 ins_compl_check_keys(0); 9022 rettv->vval.v_number = compl_interrupted; 9023 RedrawingDisabled = saved; 9024 } 9025 #endif 9026 9027 /* 9028 * "confirm(message, buttons[, default [, type]])" function 9029 */ 9030 static void 9031 f_confirm(argvars, rettv) 9032 typval_T *argvars UNUSED; 9033 typval_T *rettv UNUSED; 9034 { 9035 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 9036 char_u *message; 9037 char_u *buttons = NULL; 9038 char_u buf[NUMBUFLEN]; 9039 char_u buf2[NUMBUFLEN]; 9040 int def = 1; 9041 int type = VIM_GENERIC; 9042 char_u *typestr; 9043 int error = FALSE; 9044 9045 message = get_tv_string_chk(&argvars[0]); 9046 if (message == NULL) 9047 error = TRUE; 9048 if (argvars[1].v_type != VAR_UNKNOWN) 9049 { 9050 buttons = get_tv_string_buf_chk(&argvars[1], buf); 9051 if (buttons == NULL) 9052 error = TRUE; 9053 if (argvars[2].v_type != VAR_UNKNOWN) 9054 { 9055 def = get_tv_number_chk(&argvars[2], &error); 9056 if (argvars[3].v_type != VAR_UNKNOWN) 9057 { 9058 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 9059 if (typestr == NULL) 9060 error = TRUE; 9061 else 9062 { 9063 switch (TOUPPER_ASC(*typestr)) 9064 { 9065 case 'E': type = VIM_ERROR; break; 9066 case 'Q': type = VIM_QUESTION; break; 9067 case 'I': type = VIM_INFO; break; 9068 case 'W': type = VIM_WARNING; break; 9069 case 'G': type = VIM_GENERIC; break; 9070 } 9071 } 9072 } 9073 } 9074 } 9075 9076 if (buttons == NULL || *buttons == NUL) 9077 buttons = (char_u *)_("&Ok"); 9078 9079 if (!error) 9080 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 9081 def, NULL); 9082 #endif 9083 } 9084 9085 /* 9086 * "copy()" function 9087 */ 9088 static void 9089 f_copy(argvars, rettv) 9090 typval_T *argvars; 9091 typval_T *rettv; 9092 { 9093 item_copy(&argvars[0], rettv, FALSE, 0); 9094 } 9095 9096 #ifdef FEAT_FLOAT 9097 /* 9098 * "cos()" function 9099 */ 9100 static void 9101 f_cos(argvars, rettv) 9102 typval_T *argvars; 9103 typval_T *rettv; 9104 { 9105 float_T f; 9106 9107 rettv->v_type = VAR_FLOAT; 9108 if (get_float_arg(argvars, &f) == OK) 9109 rettv->vval.v_float = cos(f); 9110 else 9111 rettv->vval.v_float = 0.0; 9112 } 9113 #endif 9114 9115 /* 9116 * "count()" function 9117 */ 9118 static void 9119 f_count(argvars, rettv) 9120 typval_T *argvars; 9121 typval_T *rettv; 9122 { 9123 long n = 0; 9124 int ic = FALSE; 9125 9126 if (argvars[0].v_type == VAR_LIST) 9127 { 9128 listitem_T *li; 9129 list_T *l; 9130 long idx; 9131 9132 if ((l = argvars[0].vval.v_list) != NULL) 9133 { 9134 li = l->lv_first; 9135 if (argvars[2].v_type != VAR_UNKNOWN) 9136 { 9137 int error = FALSE; 9138 9139 ic = get_tv_number_chk(&argvars[2], &error); 9140 if (argvars[3].v_type != VAR_UNKNOWN) 9141 { 9142 idx = get_tv_number_chk(&argvars[3], &error); 9143 if (!error) 9144 { 9145 li = list_find(l, idx); 9146 if (li == NULL) 9147 EMSGN(_(e_listidx), idx); 9148 } 9149 } 9150 if (error) 9151 li = NULL; 9152 } 9153 9154 for ( ; li != NULL; li = li->li_next) 9155 if (tv_equal(&li->li_tv, &argvars[1], ic)) 9156 ++n; 9157 } 9158 } 9159 else if (argvars[0].v_type == VAR_DICT) 9160 { 9161 int todo; 9162 dict_T *d; 9163 hashitem_T *hi; 9164 9165 if ((d = argvars[0].vval.v_dict) != NULL) 9166 { 9167 int error = FALSE; 9168 9169 if (argvars[2].v_type != VAR_UNKNOWN) 9170 { 9171 ic = get_tv_number_chk(&argvars[2], &error); 9172 if (argvars[3].v_type != VAR_UNKNOWN) 9173 EMSG(_(e_invarg)); 9174 } 9175 9176 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 9177 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 9178 { 9179 if (!HASHITEM_EMPTY(hi)) 9180 { 9181 --todo; 9182 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 9183 ++n; 9184 } 9185 } 9186 } 9187 } 9188 else 9189 EMSG2(_(e_listdictarg), "count()"); 9190 rettv->vval.v_number = n; 9191 } 9192 9193 /* 9194 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 9195 * 9196 * Checks the existence of a cscope connection. 9197 */ 9198 static void 9199 f_cscope_connection(argvars, rettv) 9200 typval_T *argvars UNUSED; 9201 typval_T *rettv UNUSED; 9202 { 9203 #ifdef FEAT_CSCOPE 9204 int num = 0; 9205 char_u *dbpath = NULL; 9206 char_u *prepend = NULL; 9207 char_u buf[NUMBUFLEN]; 9208 9209 if (argvars[0].v_type != VAR_UNKNOWN 9210 && argvars[1].v_type != VAR_UNKNOWN) 9211 { 9212 num = (int)get_tv_number(&argvars[0]); 9213 dbpath = get_tv_string(&argvars[1]); 9214 if (argvars[2].v_type != VAR_UNKNOWN) 9215 prepend = get_tv_string_buf(&argvars[2], buf); 9216 } 9217 9218 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 9219 #endif 9220 } 9221 9222 /* 9223 * "cursor(lnum, col)" function 9224 * 9225 * Moves the cursor to the specified line and column. 9226 * Returns 0 when the position could be set, -1 otherwise. 9227 */ 9228 static void 9229 f_cursor(argvars, rettv) 9230 typval_T *argvars; 9231 typval_T *rettv; 9232 { 9233 long line, col; 9234 #ifdef FEAT_VIRTUALEDIT 9235 long coladd = 0; 9236 #endif 9237 9238 rettv->vval.v_number = -1; 9239 if (argvars[1].v_type == VAR_UNKNOWN) 9240 { 9241 pos_T pos; 9242 9243 if (list2fpos(argvars, &pos, NULL) == FAIL) 9244 return; 9245 line = pos.lnum; 9246 col = pos.col; 9247 #ifdef FEAT_VIRTUALEDIT 9248 coladd = pos.coladd; 9249 #endif 9250 } 9251 else 9252 { 9253 line = get_tv_lnum(argvars); 9254 col = get_tv_number_chk(&argvars[1], NULL); 9255 #ifdef FEAT_VIRTUALEDIT 9256 if (argvars[2].v_type != VAR_UNKNOWN) 9257 coladd = get_tv_number_chk(&argvars[2], NULL); 9258 #endif 9259 } 9260 if (line < 0 || col < 0 9261 #ifdef FEAT_VIRTUALEDIT 9262 || coladd < 0 9263 #endif 9264 ) 9265 return; /* type error; errmsg already given */ 9266 if (line > 0) 9267 curwin->w_cursor.lnum = line; 9268 if (col > 0) 9269 curwin->w_cursor.col = col - 1; 9270 #ifdef FEAT_VIRTUALEDIT 9271 curwin->w_cursor.coladd = coladd; 9272 #endif 9273 9274 /* Make sure the cursor is in a valid position. */ 9275 check_cursor(); 9276 #ifdef FEAT_MBYTE 9277 /* Correct cursor for multi-byte character. */ 9278 if (has_mbyte) 9279 mb_adjust_cursor(); 9280 #endif 9281 9282 curwin->w_set_curswant = TRUE; 9283 rettv->vval.v_number = 0; 9284 } 9285 9286 /* 9287 * "deepcopy()" function 9288 */ 9289 static void 9290 f_deepcopy(argvars, rettv) 9291 typval_T *argvars; 9292 typval_T *rettv; 9293 { 9294 int noref = 0; 9295 9296 if (argvars[1].v_type != VAR_UNKNOWN) 9297 noref = get_tv_number_chk(&argvars[1], NULL); 9298 if (noref < 0 || noref > 1) 9299 EMSG(_(e_invarg)); 9300 else 9301 { 9302 current_copyID += COPYID_INC; 9303 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0); 9304 } 9305 } 9306 9307 /* 9308 * "delete()" function 9309 */ 9310 static void 9311 f_delete(argvars, rettv) 9312 typval_T *argvars; 9313 typval_T *rettv; 9314 { 9315 if (check_restricted() || check_secure()) 9316 rettv->vval.v_number = -1; 9317 else 9318 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 9319 } 9320 9321 /* 9322 * "did_filetype()" function 9323 */ 9324 static void 9325 f_did_filetype(argvars, rettv) 9326 typval_T *argvars UNUSED; 9327 typval_T *rettv UNUSED; 9328 { 9329 #ifdef FEAT_AUTOCMD 9330 rettv->vval.v_number = did_filetype; 9331 #endif 9332 } 9333 9334 /* 9335 * "diff_filler()" function 9336 */ 9337 static void 9338 f_diff_filler(argvars, rettv) 9339 typval_T *argvars UNUSED; 9340 typval_T *rettv UNUSED; 9341 { 9342 #ifdef FEAT_DIFF 9343 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 9344 #endif 9345 } 9346 9347 /* 9348 * "diff_hlID()" function 9349 */ 9350 static void 9351 f_diff_hlID(argvars, rettv) 9352 typval_T *argvars UNUSED; 9353 typval_T *rettv UNUSED; 9354 { 9355 #ifdef FEAT_DIFF 9356 linenr_T lnum = get_tv_lnum(argvars); 9357 static linenr_T prev_lnum = 0; 9358 static int changedtick = 0; 9359 static int fnum = 0; 9360 static int change_start = 0; 9361 static int change_end = 0; 9362 static hlf_T hlID = (hlf_T)0; 9363 int filler_lines; 9364 int col; 9365 9366 if (lnum < 0) /* ignore type error in {lnum} arg */ 9367 lnum = 0; 9368 if (lnum != prev_lnum 9369 || changedtick != curbuf->b_changedtick 9370 || fnum != curbuf->b_fnum) 9371 { 9372 /* New line, buffer, change: need to get the values. */ 9373 filler_lines = diff_check(curwin, lnum); 9374 if (filler_lines < 0) 9375 { 9376 if (filler_lines == -1) 9377 { 9378 change_start = MAXCOL; 9379 change_end = -1; 9380 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 9381 hlID = HLF_ADD; /* added line */ 9382 else 9383 hlID = HLF_CHD; /* changed line */ 9384 } 9385 else 9386 hlID = HLF_ADD; /* added line */ 9387 } 9388 else 9389 hlID = (hlf_T)0; 9390 prev_lnum = lnum; 9391 changedtick = curbuf->b_changedtick; 9392 fnum = curbuf->b_fnum; 9393 } 9394 9395 if (hlID == HLF_CHD || hlID == HLF_TXD) 9396 { 9397 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 9398 if (col >= change_start && col <= change_end) 9399 hlID = HLF_TXD; /* changed text */ 9400 else 9401 hlID = HLF_CHD; /* changed line */ 9402 } 9403 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 9404 #endif 9405 } 9406 9407 /* 9408 * "empty({expr})" function 9409 */ 9410 static void 9411 f_empty(argvars, rettv) 9412 typval_T *argvars; 9413 typval_T *rettv; 9414 { 9415 int n; 9416 9417 switch (argvars[0].v_type) 9418 { 9419 case VAR_STRING: 9420 case VAR_FUNC: 9421 n = argvars[0].vval.v_string == NULL 9422 || *argvars[0].vval.v_string == NUL; 9423 break; 9424 case VAR_NUMBER: 9425 n = argvars[0].vval.v_number == 0; 9426 break; 9427 #ifdef FEAT_FLOAT 9428 case VAR_FLOAT: 9429 n = argvars[0].vval.v_float == 0.0; 9430 break; 9431 #endif 9432 case VAR_LIST: 9433 n = argvars[0].vval.v_list == NULL 9434 || argvars[0].vval.v_list->lv_first == NULL; 9435 break; 9436 case VAR_DICT: 9437 n = argvars[0].vval.v_dict == NULL 9438 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 9439 break; 9440 default: 9441 EMSG2(_(e_intern2), "f_empty()"); 9442 n = 0; 9443 } 9444 9445 rettv->vval.v_number = n; 9446 } 9447 9448 /* 9449 * "escape({string}, {chars})" function 9450 */ 9451 static void 9452 f_escape(argvars, rettv) 9453 typval_T *argvars; 9454 typval_T *rettv; 9455 { 9456 char_u buf[NUMBUFLEN]; 9457 9458 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 9459 get_tv_string_buf(&argvars[1], buf)); 9460 rettv->v_type = VAR_STRING; 9461 } 9462 9463 /* 9464 * "eval()" function 9465 */ 9466 static void 9467 f_eval(argvars, rettv) 9468 typval_T *argvars; 9469 typval_T *rettv; 9470 { 9471 char_u *s; 9472 9473 s = get_tv_string_chk(&argvars[0]); 9474 if (s != NULL) 9475 s = skipwhite(s); 9476 9477 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 9478 { 9479 rettv->v_type = VAR_NUMBER; 9480 rettv->vval.v_number = 0; 9481 } 9482 else if (*s != NUL) 9483 EMSG(_(e_trailing)); 9484 } 9485 9486 /* 9487 * "eventhandler()" function 9488 */ 9489 static void 9490 f_eventhandler(argvars, rettv) 9491 typval_T *argvars UNUSED; 9492 typval_T *rettv; 9493 { 9494 rettv->vval.v_number = vgetc_busy; 9495 } 9496 9497 /* 9498 * "executable()" function 9499 */ 9500 static void 9501 f_executable(argvars, rettv) 9502 typval_T *argvars; 9503 typval_T *rettv; 9504 { 9505 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 9506 } 9507 9508 /* 9509 * "exists()" function 9510 */ 9511 static void 9512 f_exists(argvars, rettv) 9513 typval_T *argvars; 9514 typval_T *rettv; 9515 { 9516 char_u *p; 9517 char_u *name; 9518 int n = FALSE; 9519 int len = 0; 9520 9521 p = get_tv_string(&argvars[0]); 9522 if (*p == '$') /* environment variable */ 9523 { 9524 /* first try "normal" environment variables (fast) */ 9525 if (mch_getenv(p + 1) != NULL) 9526 n = TRUE; 9527 else 9528 { 9529 /* try expanding things like $VIM and ${HOME} */ 9530 p = expand_env_save(p); 9531 if (p != NULL && *p != '$') 9532 n = TRUE; 9533 vim_free(p); 9534 } 9535 } 9536 else if (*p == '&' || *p == '+') /* option */ 9537 { 9538 n = (get_option_tv(&p, NULL, TRUE) == OK); 9539 if (*skipwhite(p) != NUL) 9540 n = FALSE; /* trailing garbage */ 9541 } 9542 else if (*p == '*') /* internal or user defined function */ 9543 { 9544 n = function_exists(p + 1); 9545 } 9546 else if (*p == ':') 9547 { 9548 n = cmd_exists(p + 1); 9549 } 9550 else if (*p == '#') 9551 { 9552 #ifdef FEAT_AUTOCMD 9553 if (p[1] == '#') 9554 n = autocmd_supported(p + 2); 9555 else 9556 n = au_exists(p + 1); 9557 #endif 9558 } 9559 else /* internal variable */ 9560 { 9561 char_u *tofree; 9562 typval_T tv; 9563 9564 /* get_name_len() takes care of expanding curly braces */ 9565 name = p; 9566 len = get_name_len(&p, &tofree, TRUE, FALSE); 9567 if (len > 0) 9568 { 9569 if (tofree != NULL) 9570 name = tofree; 9571 n = (get_var_tv(name, len, &tv, FALSE) == OK); 9572 if (n) 9573 { 9574 /* handle d.key, l[idx], f(expr) */ 9575 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 9576 if (n) 9577 clear_tv(&tv); 9578 } 9579 } 9580 if (*p != NUL) 9581 n = FALSE; 9582 9583 vim_free(tofree); 9584 } 9585 9586 rettv->vval.v_number = n; 9587 } 9588 9589 /* 9590 * "expand()" function 9591 */ 9592 static void 9593 f_expand(argvars, rettv) 9594 typval_T *argvars; 9595 typval_T *rettv; 9596 { 9597 char_u *s; 9598 int len; 9599 char_u *errormsg; 9600 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 9601 expand_T xpc; 9602 int error = FALSE; 9603 9604 rettv->v_type = VAR_STRING; 9605 s = get_tv_string(&argvars[0]); 9606 if (*s == '%' || *s == '#' || *s == '<') 9607 { 9608 ++emsg_off; 9609 rettv->vval.v_string = eval_vars(s, s, &len, NULL, &errormsg, NULL); 9610 --emsg_off; 9611 } 9612 else 9613 { 9614 /* When the optional second argument is non-zero, don't remove matches 9615 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 9616 if (argvars[1].v_type != VAR_UNKNOWN 9617 && get_tv_number_chk(&argvars[1], &error)) 9618 flags |= WILD_KEEP_ALL; 9619 if (!error) 9620 { 9621 ExpandInit(&xpc); 9622 xpc.xp_context = EXPAND_FILES; 9623 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 9624 } 9625 else 9626 rettv->vval.v_string = NULL; 9627 } 9628 } 9629 9630 /* 9631 * "extend(list, list [, idx])" function 9632 * "extend(dict, dict [, action])" function 9633 */ 9634 static void 9635 f_extend(argvars, rettv) 9636 typval_T *argvars; 9637 typval_T *rettv; 9638 { 9639 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 9640 { 9641 list_T *l1, *l2; 9642 listitem_T *item; 9643 long before; 9644 int error = FALSE; 9645 9646 l1 = argvars[0].vval.v_list; 9647 l2 = argvars[1].vval.v_list; 9648 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 9649 && l2 != NULL) 9650 { 9651 if (argvars[2].v_type != VAR_UNKNOWN) 9652 { 9653 before = get_tv_number_chk(&argvars[2], &error); 9654 if (error) 9655 return; /* type error; errmsg already given */ 9656 9657 if (before == l1->lv_len) 9658 item = NULL; 9659 else 9660 { 9661 item = list_find(l1, before); 9662 if (item == NULL) 9663 { 9664 EMSGN(_(e_listidx), before); 9665 return; 9666 } 9667 } 9668 } 9669 else 9670 item = NULL; 9671 list_extend(l1, l2, item); 9672 9673 copy_tv(&argvars[0], rettv); 9674 } 9675 } 9676 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 9677 { 9678 dict_T *d1, *d2; 9679 dictitem_T *di1; 9680 char_u *action; 9681 int i; 9682 hashitem_T *hi2; 9683 int todo; 9684 9685 d1 = argvars[0].vval.v_dict; 9686 d2 = argvars[1].vval.v_dict; 9687 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 9688 && d2 != NULL) 9689 { 9690 /* Check the third argument. */ 9691 if (argvars[2].v_type != VAR_UNKNOWN) 9692 { 9693 static char *(av[]) = {"keep", "force", "error"}; 9694 9695 action = get_tv_string_chk(&argvars[2]); 9696 if (action == NULL) 9697 return; /* type error; errmsg already given */ 9698 for (i = 0; i < 3; ++i) 9699 if (STRCMP(action, av[i]) == 0) 9700 break; 9701 if (i == 3) 9702 { 9703 EMSG2(_(e_invarg2), action); 9704 return; 9705 } 9706 } 9707 else 9708 action = (char_u *)"force"; 9709 9710 /* Go over all entries in the second dict and add them to the 9711 * first dict. */ 9712 todo = (int)d2->dv_hashtab.ht_used; 9713 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 9714 { 9715 if (!HASHITEM_EMPTY(hi2)) 9716 { 9717 --todo; 9718 di1 = dict_find(d1, hi2->hi_key, -1); 9719 if (di1 == NULL) 9720 { 9721 di1 = dictitem_copy(HI2DI(hi2)); 9722 if (di1 != NULL && dict_add(d1, di1) == FAIL) 9723 dictitem_free(di1); 9724 } 9725 else if (*action == 'e') 9726 { 9727 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 9728 break; 9729 } 9730 else if (*action == 'f') 9731 { 9732 clear_tv(&di1->di_tv); 9733 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 9734 } 9735 } 9736 } 9737 9738 copy_tv(&argvars[0], rettv); 9739 } 9740 } 9741 else 9742 EMSG2(_(e_listdictarg), "extend()"); 9743 } 9744 9745 /* 9746 * "feedkeys()" function 9747 */ 9748 static void 9749 f_feedkeys(argvars, rettv) 9750 typval_T *argvars; 9751 typval_T *rettv UNUSED; 9752 { 9753 int remap = TRUE; 9754 char_u *keys, *flags; 9755 char_u nbuf[NUMBUFLEN]; 9756 int typed = FALSE; 9757 char_u *keys_esc; 9758 9759 /* This is not allowed in the sandbox. If the commands would still be 9760 * executed in the sandbox it would be OK, but it probably happens later, 9761 * when "sandbox" is no longer set. */ 9762 if (check_secure()) 9763 return; 9764 9765 keys = get_tv_string(&argvars[0]); 9766 if (*keys != NUL) 9767 { 9768 if (argvars[1].v_type != VAR_UNKNOWN) 9769 { 9770 flags = get_tv_string_buf(&argvars[1], nbuf); 9771 for ( ; *flags != NUL; ++flags) 9772 { 9773 switch (*flags) 9774 { 9775 case 'n': remap = FALSE; break; 9776 case 'm': remap = TRUE; break; 9777 case 't': typed = TRUE; break; 9778 } 9779 } 9780 } 9781 9782 /* Need to escape K_SPECIAL and CSI before putting the string in the 9783 * typeahead buffer. */ 9784 keys_esc = vim_strsave_escape_csi(keys); 9785 if (keys_esc != NULL) 9786 { 9787 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 9788 typebuf.tb_len, !typed, FALSE); 9789 vim_free(keys_esc); 9790 if (vgetc_busy) 9791 typebuf_was_filled = TRUE; 9792 } 9793 } 9794 } 9795 9796 /* 9797 * "filereadable()" function 9798 */ 9799 static void 9800 f_filereadable(argvars, rettv) 9801 typval_T *argvars; 9802 typval_T *rettv; 9803 { 9804 int fd; 9805 char_u *p; 9806 int n; 9807 9808 #ifndef O_NONBLOCK 9809 # define O_NONBLOCK 0 9810 #endif 9811 p = get_tv_string(&argvars[0]); 9812 if (*p && !mch_isdir(p) && (fd = mch_open((char *)p, 9813 O_RDONLY | O_NONBLOCK, 0)) >= 0) 9814 { 9815 n = TRUE; 9816 close(fd); 9817 } 9818 else 9819 n = FALSE; 9820 9821 rettv->vval.v_number = n; 9822 } 9823 9824 /* 9825 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 9826 * rights to write into. 9827 */ 9828 static void 9829 f_filewritable(argvars, rettv) 9830 typval_T *argvars; 9831 typval_T *rettv; 9832 { 9833 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 9834 } 9835 9836 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what)); 9837 9838 static void 9839 findfilendir(argvars, rettv, find_what) 9840 typval_T *argvars; 9841 typval_T *rettv; 9842 int find_what; 9843 { 9844 #ifdef FEAT_SEARCHPATH 9845 char_u *fname; 9846 char_u *fresult = NULL; 9847 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 9848 char_u *p; 9849 char_u pathbuf[NUMBUFLEN]; 9850 int count = 1; 9851 int first = TRUE; 9852 int error = FALSE; 9853 #endif 9854 9855 rettv->vval.v_string = NULL; 9856 rettv->v_type = VAR_STRING; 9857 9858 #ifdef FEAT_SEARCHPATH 9859 fname = get_tv_string(&argvars[0]); 9860 9861 if (argvars[1].v_type != VAR_UNKNOWN) 9862 { 9863 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 9864 if (p == NULL) 9865 error = TRUE; 9866 else 9867 { 9868 if (*p != NUL) 9869 path = p; 9870 9871 if (argvars[2].v_type != VAR_UNKNOWN) 9872 count = get_tv_number_chk(&argvars[2], &error); 9873 } 9874 } 9875 9876 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 9877 error = TRUE; 9878 9879 if (*fname != NUL && !error) 9880 { 9881 do 9882 { 9883 if (rettv->v_type == VAR_STRING) 9884 vim_free(fresult); 9885 fresult = find_file_in_path_option(first ? fname : NULL, 9886 first ? (int)STRLEN(fname) : 0, 9887 0, first, path, 9888 find_what, 9889 curbuf->b_ffname, 9890 find_what == FINDFILE_DIR 9891 ? (char_u *)"" : curbuf->b_p_sua); 9892 first = FALSE; 9893 9894 if (fresult != NULL && rettv->v_type == VAR_LIST) 9895 list_append_string(rettv->vval.v_list, fresult, -1); 9896 9897 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 9898 } 9899 9900 if (rettv->v_type == VAR_STRING) 9901 rettv->vval.v_string = fresult; 9902 #endif 9903 } 9904 9905 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 9906 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 9907 9908 /* 9909 * Implementation of map() and filter(). 9910 */ 9911 static void 9912 filter_map(argvars, rettv, map) 9913 typval_T *argvars; 9914 typval_T *rettv; 9915 int map; 9916 { 9917 char_u buf[NUMBUFLEN]; 9918 char_u *expr; 9919 listitem_T *li, *nli; 9920 list_T *l = NULL; 9921 dictitem_T *di; 9922 hashtab_T *ht; 9923 hashitem_T *hi; 9924 dict_T *d = NULL; 9925 typval_T save_val; 9926 typval_T save_key; 9927 int rem; 9928 int todo; 9929 char_u *ermsg = map ? (char_u *)"map()" : (char_u *)"filter()"; 9930 int save_did_emsg; 9931 int index = 0; 9932 9933 if (argvars[0].v_type == VAR_LIST) 9934 { 9935 if ((l = argvars[0].vval.v_list) == NULL 9936 || (map && tv_check_lock(l->lv_lock, ermsg))) 9937 return; 9938 } 9939 else if (argvars[0].v_type == VAR_DICT) 9940 { 9941 if ((d = argvars[0].vval.v_dict) == NULL 9942 || (map && tv_check_lock(d->dv_lock, ermsg))) 9943 return; 9944 } 9945 else 9946 { 9947 EMSG2(_(e_listdictarg), ermsg); 9948 return; 9949 } 9950 9951 expr = get_tv_string_buf_chk(&argvars[1], buf); 9952 /* On type errors, the preceding call has already displayed an error 9953 * message. Avoid a misleading error message for an empty string that 9954 * was not passed as argument. */ 9955 if (expr != NULL) 9956 { 9957 prepare_vimvar(VV_VAL, &save_val); 9958 expr = skipwhite(expr); 9959 9960 /* We reset "did_emsg" to be able to detect whether an error 9961 * occurred during evaluation of the expression. */ 9962 save_did_emsg = did_emsg; 9963 did_emsg = FALSE; 9964 9965 prepare_vimvar(VV_KEY, &save_key); 9966 if (argvars[0].v_type == VAR_DICT) 9967 { 9968 vimvars[VV_KEY].vv_type = VAR_STRING; 9969 9970 ht = &d->dv_hashtab; 9971 hash_lock(ht); 9972 todo = (int)ht->ht_used; 9973 for (hi = ht->ht_array; todo > 0; ++hi) 9974 { 9975 if (!HASHITEM_EMPTY(hi)) 9976 { 9977 --todo; 9978 di = HI2DI(hi); 9979 if (tv_check_lock(di->di_tv.v_lock, ermsg)) 9980 break; 9981 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 9982 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL 9983 || did_emsg) 9984 break; 9985 if (!map && rem) 9986 dictitem_remove(d, di); 9987 clear_tv(&vimvars[VV_KEY].vv_tv); 9988 } 9989 } 9990 hash_unlock(ht); 9991 } 9992 else 9993 { 9994 vimvars[VV_KEY].vv_type = VAR_NUMBER; 9995 9996 for (li = l->lv_first; li != NULL; li = nli) 9997 { 9998 if (tv_check_lock(li->li_tv.v_lock, ermsg)) 9999 break; 10000 nli = li->li_next; 10001 vimvars[VV_KEY].vv_nr = index; 10002 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 10003 || did_emsg) 10004 break; 10005 if (!map && rem) 10006 listitem_remove(l, li); 10007 ++index; 10008 } 10009 } 10010 10011 restore_vimvar(VV_KEY, &save_key); 10012 restore_vimvar(VV_VAL, &save_val); 10013 10014 did_emsg |= save_did_emsg; 10015 } 10016 10017 copy_tv(&argvars[0], rettv); 10018 } 10019 10020 static int 10021 filter_map_one(tv, expr, map, remp) 10022 typval_T *tv; 10023 char_u *expr; 10024 int map; 10025 int *remp; 10026 { 10027 typval_T rettv; 10028 char_u *s; 10029 int retval = FAIL; 10030 10031 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 10032 s = expr; 10033 if (eval1(&s, &rettv, TRUE) == FAIL) 10034 goto theend; 10035 if (*s != NUL) /* check for trailing chars after expr */ 10036 { 10037 EMSG2(_(e_invexpr2), s); 10038 goto theend; 10039 } 10040 if (map) 10041 { 10042 /* map(): replace the list item value */ 10043 clear_tv(tv); 10044 rettv.v_lock = 0; 10045 *tv = rettv; 10046 } 10047 else 10048 { 10049 int error = FALSE; 10050 10051 /* filter(): when expr is zero remove the item */ 10052 *remp = (get_tv_number_chk(&rettv, &error) == 0); 10053 clear_tv(&rettv); 10054 /* On type error, nothing has been removed; return FAIL to stop the 10055 * loop. The error message was given by get_tv_number_chk(). */ 10056 if (error) 10057 goto theend; 10058 } 10059 retval = OK; 10060 theend: 10061 clear_tv(&vimvars[VV_VAL].vv_tv); 10062 return retval; 10063 } 10064 10065 /* 10066 * "filter()" function 10067 */ 10068 static void 10069 f_filter(argvars, rettv) 10070 typval_T *argvars; 10071 typval_T *rettv; 10072 { 10073 filter_map(argvars, rettv, FALSE); 10074 } 10075 10076 /* 10077 * "finddir({fname}[, {path}[, {count}]])" function 10078 */ 10079 static void 10080 f_finddir(argvars, rettv) 10081 typval_T *argvars; 10082 typval_T *rettv; 10083 { 10084 findfilendir(argvars, rettv, FINDFILE_DIR); 10085 } 10086 10087 /* 10088 * "findfile({fname}[, {path}[, {count}]])" function 10089 */ 10090 static void 10091 f_findfile(argvars, rettv) 10092 typval_T *argvars; 10093 typval_T *rettv; 10094 { 10095 findfilendir(argvars, rettv, FINDFILE_FILE); 10096 } 10097 10098 #ifdef FEAT_FLOAT 10099 /* 10100 * "float2nr({float})" function 10101 */ 10102 static void 10103 f_float2nr(argvars, rettv) 10104 typval_T *argvars; 10105 typval_T *rettv; 10106 { 10107 float_T f; 10108 10109 if (get_float_arg(argvars, &f) == OK) 10110 { 10111 if (f < -0x7fffffff) 10112 rettv->vval.v_number = -0x7fffffff; 10113 else if (f > 0x7fffffff) 10114 rettv->vval.v_number = 0x7fffffff; 10115 else 10116 rettv->vval.v_number = (varnumber_T)f; 10117 } 10118 } 10119 10120 /* 10121 * "floor({float})" function 10122 */ 10123 static void 10124 f_floor(argvars, rettv) 10125 typval_T *argvars; 10126 typval_T *rettv; 10127 { 10128 float_T f; 10129 10130 rettv->v_type = VAR_FLOAT; 10131 if (get_float_arg(argvars, &f) == OK) 10132 rettv->vval.v_float = floor(f); 10133 else 10134 rettv->vval.v_float = 0.0; 10135 } 10136 #endif 10137 10138 /* 10139 * "fnameescape({string})" function 10140 */ 10141 static void 10142 f_fnameescape(argvars, rettv) 10143 typval_T *argvars; 10144 typval_T *rettv; 10145 { 10146 rettv->vval.v_string = vim_strsave_fnameescape( 10147 get_tv_string(&argvars[0]), FALSE); 10148 rettv->v_type = VAR_STRING; 10149 } 10150 10151 /* 10152 * "fnamemodify({fname}, {mods})" function 10153 */ 10154 static void 10155 f_fnamemodify(argvars, rettv) 10156 typval_T *argvars; 10157 typval_T *rettv; 10158 { 10159 char_u *fname; 10160 char_u *mods; 10161 int usedlen = 0; 10162 int len; 10163 char_u *fbuf = NULL; 10164 char_u buf[NUMBUFLEN]; 10165 10166 fname = get_tv_string_chk(&argvars[0]); 10167 mods = get_tv_string_buf_chk(&argvars[1], buf); 10168 if (fname == NULL || mods == NULL) 10169 fname = NULL; 10170 else 10171 { 10172 len = (int)STRLEN(fname); 10173 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 10174 } 10175 10176 rettv->v_type = VAR_STRING; 10177 if (fname == NULL) 10178 rettv->vval.v_string = NULL; 10179 else 10180 rettv->vval.v_string = vim_strnsave(fname, len); 10181 vim_free(fbuf); 10182 } 10183 10184 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 10185 10186 /* 10187 * "foldclosed()" function 10188 */ 10189 static void 10190 foldclosed_both(argvars, rettv, end) 10191 typval_T *argvars; 10192 typval_T *rettv; 10193 int end; 10194 { 10195 #ifdef FEAT_FOLDING 10196 linenr_T lnum; 10197 linenr_T first, last; 10198 10199 lnum = get_tv_lnum(argvars); 10200 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10201 { 10202 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 10203 { 10204 if (end) 10205 rettv->vval.v_number = (varnumber_T)last; 10206 else 10207 rettv->vval.v_number = (varnumber_T)first; 10208 return; 10209 } 10210 } 10211 #endif 10212 rettv->vval.v_number = -1; 10213 } 10214 10215 /* 10216 * "foldclosed()" function 10217 */ 10218 static void 10219 f_foldclosed(argvars, rettv) 10220 typval_T *argvars; 10221 typval_T *rettv; 10222 { 10223 foldclosed_both(argvars, rettv, FALSE); 10224 } 10225 10226 /* 10227 * "foldclosedend()" function 10228 */ 10229 static void 10230 f_foldclosedend(argvars, rettv) 10231 typval_T *argvars; 10232 typval_T *rettv; 10233 { 10234 foldclosed_both(argvars, rettv, TRUE); 10235 } 10236 10237 /* 10238 * "foldlevel()" function 10239 */ 10240 static void 10241 f_foldlevel(argvars, rettv) 10242 typval_T *argvars; 10243 typval_T *rettv; 10244 { 10245 #ifdef FEAT_FOLDING 10246 linenr_T lnum; 10247 10248 lnum = get_tv_lnum(argvars); 10249 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10250 rettv->vval.v_number = foldLevel(lnum); 10251 #endif 10252 } 10253 10254 /* 10255 * "foldtext()" function 10256 */ 10257 static void 10258 f_foldtext(argvars, rettv) 10259 typval_T *argvars UNUSED; 10260 typval_T *rettv; 10261 { 10262 #ifdef FEAT_FOLDING 10263 linenr_T lnum; 10264 char_u *s; 10265 char_u *r; 10266 int len; 10267 char *txt; 10268 #endif 10269 10270 rettv->v_type = VAR_STRING; 10271 rettv->vval.v_string = NULL; 10272 #ifdef FEAT_FOLDING 10273 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 10274 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 10275 <= curbuf->b_ml.ml_line_count 10276 && vimvars[VV_FOLDDASHES].vv_str != NULL) 10277 { 10278 /* Find first non-empty line in the fold. */ 10279 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 10280 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 10281 { 10282 if (!linewhite(lnum)) 10283 break; 10284 ++lnum; 10285 } 10286 10287 /* Find interesting text in this line. */ 10288 s = skipwhite(ml_get(lnum)); 10289 /* skip C comment-start */ 10290 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 10291 { 10292 s = skipwhite(s + 2); 10293 if (*skipwhite(s) == NUL 10294 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 10295 { 10296 s = skipwhite(ml_get(lnum + 1)); 10297 if (*s == '*') 10298 s = skipwhite(s + 1); 10299 } 10300 } 10301 txt = _("+-%s%3ld lines: "); 10302 r = alloc((unsigned)(STRLEN(txt) 10303 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 10304 + 20 /* for %3ld */ 10305 + STRLEN(s))); /* concatenated */ 10306 if (r != NULL) 10307 { 10308 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 10309 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 10310 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 10311 len = (int)STRLEN(r); 10312 STRCAT(r, s); 10313 /* remove 'foldmarker' and 'commentstring' */ 10314 foldtext_cleanup(r + len); 10315 rettv->vval.v_string = r; 10316 } 10317 } 10318 #endif 10319 } 10320 10321 /* 10322 * "foldtextresult(lnum)" function 10323 */ 10324 static void 10325 f_foldtextresult(argvars, rettv) 10326 typval_T *argvars UNUSED; 10327 typval_T *rettv; 10328 { 10329 #ifdef FEAT_FOLDING 10330 linenr_T lnum; 10331 char_u *text; 10332 char_u buf[51]; 10333 foldinfo_T foldinfo; 10334 int fold_count; 10335 #endif 10336 10337 rettv->v_type = VAR_STRING; 10338 rettv->vval.v_string = NULL; 10339 #ifdef FEAT_FOLDING 10340 lnum = get_tv_lnum(argvars); 10341 /* treat illegal types and illegal string values for {lnum} the same */ 10342 if (lnum < 0) 10343 lnum = 0; 10344 fold_count = foldedCount(curwin, lnum, &foldinfo); 10345 if (fold_count > 0) 10346 { 10347 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 10348 &foldinfo, buf); 10349 if (text == buf) 10350 text = vim_strsave(text); 10351 rettv->vval.v_string = text; 10352 } 10353 #endif 10354 } 10355 10356 /* 10357 * "foreground()" function 10358 */ 10359 static void 10360 f_foreground(argvars, rettv) 10361 typval_T *argvars UNUSED; 10362 typval_T *rettv UNUSED; 10363 { 10364 #ifdef FEAT_GUI 10365 if (gui.in_use) 10366 gui_mch_set_foreground(); 10367 #else 10368 # ifdef WIN32 10369 win32_set_foreground(); 10370 # endif 10371 #endif 10372 } 10373 10374 /* 10375 * "function()" function 10376 */ 10377 static void 10378 f_function(argvars, rettv) 10379 typval_T *argvars; 10380 typval_T *rettv; 10381 { 10382 char_u *s; 10383 10384 s = get_tv_string(&argvars[0]); 10385 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 10386 EMSG2(_(e_invarg2), s); 10387 /* Don't check an autoload name for existence here. */ 10388 else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s)) 10389 EMSG2(_("E700: Unknown function: %s"), s); 10390 else 10391 { 10392 rettv->vval.v_string = vim_strsave(s); 10393 rettv->v_type = VAR_FUNC; 10394 } 10395 } 10396 10397 /* 10398 * "garbagecollect()" function 10399 */ 10400 static void 10401 f_garbagecollect(argvars, rettv) 10402 typval_T *argvars; 10403 typval_T *rettv UNUSED; 10404 { 10405 /* This is postponed until we are back at the toplevel, because we may be 10406 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ 10407 want_garbage_collect = TRUE; 10408 10409 if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1) 10410 garbage_collect_at_exit = TRUE; 10411 } 10412 10413 /* 10414 * "get()" function 10415 */ 10416 static void 10417 f_get(argvars, rettv) 10418 typval_T *argvars; 10419 typval_T *rettv; 10420 { 10421 listitem_T *li; 10422 list_T *l; 10423 dictitem_T *di; 10424 dict_T *d; 10425 typval_T *tv = NULL; 10426 10427 if (argvars[0].v_type == VAR_LIST) 10428 { 10429 if ((l = argvars[0].vval.v_list) != NULL) 10430 { 10431 int error = FALSE; 10432 10433 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 10434 if (!error && li != NULL) 10435 tv = &li->li_tv; 10436 } 10437 } 10438 else if (argvars[0].v_type == VAR_DICT) 10439 { 10440 if ((d = argvars[0].vval.v_dict) != NULL) 10441 { 10442 di = dict_find(d, get_tv_string(&argvars[1]), -1); 10443 if (di != NULL) 10444 tv = &di->di_tv; 10445 } 10446 } 10447 else 10448 EMSG2(_(e_listdictarg), "get()"); 10449 10450 if (tv == NULL) 10451 { 10452 if (argvars[2].v_type != VAR_UNKNOWN) 10453 copy_tv(&argvars[2], rettv); 10454 } 10455 else 10456 copy_tv(tv, rettv); 10457 } 10458 10459 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 10460 10461 /* 10462 * Get line or list of lines from buffer "buf" into "rettv". 10463 * Return a range (from start to end) of lines in rettv from the specified 10464 * buffer. 10465 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 10466 */ 10467 static void 10468 get_buffer_lines(buf, start, end, retlist, rettv) 10469 buf_T *buf; 10470 linenr_T start; 10471 linenr_T end; 10472 int retlist; 10473 typval_T *rettv; 10474 { 10475 char_u *p; 10476 10477 if (retlist && rettv_list_alloc(rettv) == FAIL) 10478 return; 10479 10480 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 10481 return; 10482 10483 if (!retlist) 10484 { 10485 if (start >= 1 && start <= buf->b_ml.ml_line_count) 10486 p = ml_get_buf(buf, start, FALSE); 10487 else 10488 p = (char_u *)""; 10489 10490 rettv->v_type = VAR_STRING; 10491 rettv->vval.v_string = vim_strsave(p); 10492 } 10493 else 10494 { 10495 if (end < start) 10496 return; 10497 10498 if (start < 1) 10499 start = 1; 10500 if (end > buf->b_ml.ml_line_count) 10501 end = buf->b_ml.ml_line_count; 10502 while (start <= end) 10503 if (list_append_string(rettv->vval.v_list, 10504 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 10505 break; 10506 } 10507 } 10508 10509 /* 10510 * "getbufline()" function 10511 */ 10512 static void 10513 f_getbufline(argvars, rettv) 10514 typval_T *argvars; 10515 typval_T *rettv; 10516 { 10517 linenr_T lnum; 10518 linenr_T end; 10519 buf_T *buf; 10520 10521 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 10522 ++emsg_off; 10523 buf = get_buf_tv(&argvars[0]); 10524 --emsg_off; 10525 10526 lnum = get_tv_lnum_buf(&argvars[1], buf); 10527 if (argvars[2].v_type == VAR_UNKNOWN) 10528 end = lnum; 10529 else 10530 end = get_tv_lnum_buf(&argvars[2], buf); 10531 10532 get_buffer_lines(buf, lnum, end, TRUE, rettv); 10533 } 10534 10535 /* 10536 * "getbufvar()" function 10537 */ 10538 static void 10539 f_getbufvar(argvars, rettv) 10540 typval_T *argvars; 10541 typval_T *rettv; 10542 { 10543 buf_T *buf; 10544 buf_T *save_curbuf; 10545 char_u *varname; 10546 dictitem_T *v; 10547 10548 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 10549 varname = get_tv_string_chk(&argvars[1]); 10550 ++emsg_off; 10551 buf = get_buf_tv(&argvars[0]); 10552 10553 rettv->v_type = VAR_STRING; 10554 rettv->vval.v_string = NULL; 10555 10556 if (buf != NULL && varname != NULL) 10557 { 10558 /* set curbuf to be our buf, temporarily */ 10559 save_curbuf = curbuf; 10560 curbuf = buf; 10561 10562 if (*varname == '&') /* buffer-local-option */ 10563 get_option_tv(&varname, rettv, TRUE); 10564 else 10565 { 10566 if (*varname == NUL) 10567 /* let getbufvar({nr}, "") return the "b:" dictionary. The 10568 * scope prefix before the NUL byte is required by 10569 * find_var_in_ht(). */ 10570 varname = (char_u *)"b:" + 2; 10571 /* look up the variable */ 10572 v = find_var_in_ht(&curbuf->b_vars.dv_hashtab, varname, FALSE); 10573 if (v != NULL) 10574 copy_tv(&v->di_tv, rettv); 10575 } 10576 10577 /* restore previous notion of curbuf */ 10578 curbuf = save_curbuf; 10579 } 10580 10581 --emsg_off; 10582 } 10583 10584 /* 10585 * "getchar()" function 10586 */ 10587 static void 10588 f_getchar(argvars, rettv) 10589 typval_T *argvars; 10590 typval_T *rettv; 10591 { 10592 varnumber_T n; 10593 int error = FALSE; 10594 10595 /* Position the cursor. Needed after a message that ends in a space. */ 10596 windgoto(msg_row, msg_col); 10597 10598 ++no_mapping; 10599 ++allow_keys; 10600 for (;;) 10601 { 10602 if (argvars[0].v_type == VAR_UNKNOWN) 10603 /* getchar(): blocking wait. */ 10604 n = safe_vgetc(); 10605 else if (get_tv_number_chk(&argvars[0], &error) == 1) 10606 /* getchar(1): only check if char avail */ 10607 n = vpeekc(); 10608 else if (error || vpeekc() == NUL) 10609 /* illegal argument or getchar(0) and no char avail: return zero */ 10610 n = 0; 10611 else 10612 /* getchar(0) and char avail: return char */ 10613 n = safe_vgetc(); 10614 if (n == K_IGNORE) 10615 continue; 10616 break; 10617 } 10618 --no_mapping; 10619 --allow_keys; 10620 10621 vimvars[VV_MOUSE_WIN].vv_nr = 0; 10622 vimvars[VV_MOUSE_LNUM].vv_nr = 0; 10623 vimvars[VV_MOUSE_COL].vv_nr = 0; 10624 10625 rettv->vval.v_number = n; 10626 if (IS_SPECIAL(n) || mod_mask != 0) 10627 { 10628 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 10629 int i = 0; 10630 10631 /* Turn a special key into three bytes, plus modifier. */ 10632 if (mod_mask != 0) 10633 { 10634 temp[i++] = K_SPECIAL; 10635 temp[i++] = KS_MODIFIER; 10636 temp[i++] = mod_mask; 10637 } 10638 if (IS_SPECIAL(n)) 10639 { 10640 temp[i++] = K_SPECIAL; 10641 temp[i++] = K_SECOND(n); 10642 temp[i++] = K_THIRD(n); 10643 } 10644 #ifdef FEAT_MBYTE 10645 else if (has_mbyte) 10646 i += (*mb_char2bytes)(n, temp + i); 10647 #endif 10648 else 10649 temp[i++] = n; 10650 temp[i++] = NUL; 10651 rettv->v_type = VAR_STRING; 10652 rettv->vval.v_string = vim_strsave(temp); 10653 10654 #ifdef FEAT_MOUSE 10655 if (n == K_LEFTMOUSE 10656 || n == K_LEFTMOUSE_NM 10657 || n == K_LEFTDRAG 10658 || n == K_LEFTRELEASE 10659 || n == K_LEFTRELEASE_NM 10660 || n == K_MIDDLEMOUSE 10661 || n == K_MIDDLEDRAG 10662 || n == K_MIDDLERELEASE 10663 || n == K_RIGHTMOUSE 10664 || n == K_RIGHTDRAG 10665 || n == K_RIGHTRELEASE 10666 || n == K_X1MOUSE 10667 || n == K_X1DRAG 10668 || n == K_X1RELEASE 10669 || n == K_X2MOUSE 10670 || n == K_X2DRAG 10671 || n == K_X2RELEASE 10672 || n == K_MOUSEDOWN 10673 || n == K_MOUSEUP) 10674 { 10675 int row = mouse_row; 10676 int col = mouse_col; 10677 win_T *win; 10678 linenr_T lnum; 10679 # ifdef FEAT_WINDOWS 10680 win_T *wp; 10681 # endif 10682 int winnr = 1; 10683 10684 if (row >= 0 && col >= 0) 10685 { 10686 /* Find the window at the mouse coordinates and compute the 10687 * text position. */ 10688 win = mouse_find_win(&row, &col); 10689 (void)mouse_comp_pos(win, &row, &col, &lnum); 10690 # ifdef FEAT_WINDOWS 10691 for (wp = firstwin; wp != win; wp = wp->w_next) 10692 ++winnr; 10693 # endif 10694 vimvars[VV_MOUSE_WIN].vv_nr = winnr; 10695 vimvars[VV_MOUSE_LNUM].vv_nr = lnum; 10696 vimvars[VV_MOUSE_COL].vv_nr = col + 1; 10697 } 10698 } 10699 #endif 10700 } 10701 } 10702 10703 /* 10704 * "getcharmod()" function 10705 */ 10706 static void 10707 f_getcharmod(argvars, rettv) 10708 typval_T *argvars UNUSED; 10709 typval_T *rettv; 10710 { 10711 rettv->vval.v_number = mod_mask; 10712 } 10713 10714 /* 10715 * "getcmdline()" function 10716 */ 10717 static void 10718 f_getcmdline(argvars, rettv) 10719 typval_T *argvars UNUSED; 10720 typval_T *rettv; 10721 { 10722 rettv->v_type = VAR_STRING; 10723 rettv->vval.v_string = get_cmdline_str(); 10724 } 10725 10726 /* 10727 * "getcmdpos()" function 10728 */ 10729 static void 10730 f_getcmdpos(argvars, rettv) 10731 typval_T *argvars UNUSED; 10732 typval_T *rettv; 10733 { 10734 rettv->vval.v_number = get_cmdline_pos() + 1; 10735 } 10736 10737 /* 10738 * "getcmdtype()" function 10739 */ 10740 static void 10741 f_getcmdtype(argvars, rettv) 10742 typval_T *argvars UNUSED; 10743 typval_T *rettv; 10744 { 10745 rettv->v_type = VAR_STRING; 10746 rettv->vval.v_string = alloc(2); 10747 if (rettv->vval.v_string != NULL) 10748 { 10749 rettv->vval.v_string[0] = get_cmdline_type(); 10750 rettv->vval.v_string[1] = NUL; 10751 } 10752 } 10753 10754 /* 10755 * "getcwd()" function 10756 */ 10757 static void 10758 f_getcwd(argvars, rettv) 10759 typval_T *argvars UNUSED; 10760 typval_T *rettv; 10761 { 10762 char_u cwd[MAXPATHL]; 10763 10764 rettv->v_type = VAR_STRING; 10765 if (mch_dirname(cwd, MAXPATHL) == FAIL) 10766 rettv->vval.v_string = NULL; 10767 else 10768 { 10769 rettv->vval.v_string = vim_strsave(cwd); 10770 #ifdef BACKSLASH_IN_FILENAME 10771 if (rettv->vval.v_string != NULL) 10772 slash_adjust(rettv->vval.v_string); 10773 #endif 10774 } 10775 } 10776 10777 /* 10778 * "getfontname()" function 10779 */ 10780 static void 10781 f_getfontname(argvars, rettv) 10782 typval_T *argvars UNUSED; 10783 typval_T *rettv; 10784 { 10785 rettv->v_type = VAR_STRING; 10786 rettv->vval.v_string = NULL; 10787 #ifdef FEAT_GUI 10788 if (gui.in_use) 10789 { 10790 GuiFont font; 10791 char_u *name = NULL; 10792 10793 if (argvars[0].v_type == VAR_UNKNOWN) 10794 { 10795 /* Get the "Normal" font. Either the name saved by 10796 * hl_set_font_name() or from the font ID. */ 10797 font = gui.norm_font; 10798 name = hl_get_font_name(); 10799 } 10800 else 10801 { 10802 name = get_tv_string(&argvars[0]); 10803 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 10804 return; 10805 font = gui_mch_get_font(name, FALSE); 10806 if (font == NOFONT) 10807 return; /* Invalid font name, return empty string. */ 10808 } 10809 rettv->vval.v_string = gui_mch_get_fontname(font, name); 10810 if (argvars[0].v_type != VAR_UNKNOWN) 10811 gui_mch_free_font(font); 10812 } 10813 #endif 10814 } 10815 10816 /* 10817 * "getfperm({fname})" function 10818 */ 10819 static void 10820 f_getfperm(argvars, rettv) 10821 typval_T *argvars; 10822 typval_T *rettv; 10823 { 10824 char_u *fname; 10825 struct stat st; 10826 char_u *perm = NULL; 10827 char_u flags[] = "rwx"; 10828 int i; 10829 10830 fname = get_tv_string(&argvars[0]); 10831 10832 rettv->v_type = VAR_STRING; 10833 if (mch_stat((char *)fname, &st) >= 0) 10834 { 10835 perm = vim_strsave((char_u *)"---------"); 10836 if (perm != NULL) 10837 { 10838 for (i = 0; i < 9; i++) 10839 { 10840 if (st.st_mode & (1 << (8 - i))) 10841 perm[i] = flags[i % 3]; 10842 } 10843 } 10844 } 10845 rettv->vval.v_string = perm; 10846 } 10847 10848 /* 10849 * "getfsize({fname})" function 10850 */ 10851 static void 10852 f_getfsize(argvars, rettv) 10853 typval_T *argvars; 10854 typval_T *rettv; 10855 { 10856 char_u *fname; 10857 struct stat st; 10858 10859 fname = get_tv_string(&argvars[0]); 10860 10861 rettv->v_type = VAR_NUMBER; 10862 10863 if (mch_stat((char *)fname, &st) >= 0) 10864 { 10865 if (mch_isdir(fname)) 10866 rettv->vval.v_number = 0; 10867 else 10868 { 10869 rettv->vval.v_number = (varnumber_T)st.st_size; 10870 10871 /* non-perfect check for overflow */ 10872 if ((off_t)rettv->vval.v_number != (off_t)st.st_size) 10873 rettv->vval.v_number = -2; 10874 } 10875 } 10876 else 10877 rettv->vval.v_number = -1; 10878 } 10879 10880 /* 10881 * "getftime({fname})" function 10882 */ 10883 static void 10884 f_getftime(argvars, rettv) 10885 typval_T *argvars; 10886 typval_T *rettv; 10887 { 10888 char_u *fname; 10889 struct stat st; 10890 10891 fname = get_tv_string(&argvars[0]); 10892 10893 if (mch_stat((char *)fname, &st) >= 0) 10894 rettv->vval.v_number = (varnumber_T)st.st_mtime; 10895 else 10896 rettv->vval.v_number = -1; 10897 } 10898 10899 /* 10900 * "getftype({fname})" function 10901 */ 10902 static void 10903 f_getftype(argvars, rettv) 10904 typval_T *argvars; 10905 typval_T *rettv; 10906 { 10907 char_u *fname; 10908 struct stat st; 10909 char_u *type = NULL; 10910 char *t; 10911 10912 fname = get_tv_string(&argvars[0]); 10913 10914 rettv->v_type = VAR_STRING; 10915 if (mch_lstat((char *)fname, &st) >= 0) 10916 { 10917 #ifdef S_ISREG 10918 if (S_ISREG(st.st_mode)) 10919 t = "file"; 10920 else if (S_ISDIR(st.st_mode)) 10921 t = "dir"; 10922 # ifdef S_ISLNK 10923 else if (S_ISLNK(st.st_mode)) 10924 t = "link"; 10925 # endif 10926 # ifdef S_ISBLK 10927 else if (S_ISBLK(st.st_mode)) 10928 t = "bdev"; 10929 # endif 10930 # ifdef S_ISCHR 10931 else if (S_ISCHR(st.st_mode)) 10932 t = "cdev"; 10933 # endif 10934 # ifdef S_ISFIFO 10935 else if (S_ISFIFO(st.st_mode)) 10936 t = "fifo"; 10937 # endif 10938 # ifdef S_ISSOCK 10939 else if (S_ISSOCK(st.st_mode)) 10940 t = "fifo"; 10941 # endif 10942 else 10943 t = "other"; 10944 #else 10945 # ifdef S_IFMT 10946 switch (st.st_mode & S_IFMT) 10947 { 10948 case S_IFREG: t = "file"; break; 10949 case S_IFDIR: t = "dir"; break; 10950 # ifdef S_IFLNK 10951 case S_IFLNK: t = "link"; break; 10952 # endif 10953 # ifdef S_IFBLK 10954 case S_IFBLK: t = "bdev"; break; 10955 # endif 10956 # ifdef S_IFCHR 10957 case S_IFCHR: t = "cdev"; break; 10958 # endif 10959 # ifdef S_IFIFO 10960 case S_IFIFO: t = "fifo"; break; 10961 # endif 10962 # ifdef S_IFSOCK 10963 case S_IFSOCK: t = "socket"; break; 10964 # endif 10965 default: t = "other"; 10966 } 10967 # else 10968 if (mch_isdir(fname)) 10969 t = "dir"; 10970 else 10971 t = "file"; 10972 # endif 10973 #endif 10974 type = vim_strsave((char_u *)t); 10975 } 10976 rettv->vval.v_string = type; 10977 } 10978 10979 /* 10980 * "getline(lnum, [end])" function 10981 */ 10982 static void 10983 f_getline(argvars, rettv) 10984 typval_T *argvars; 10985 typval_T *rettv; 10986 { 10987 linenr_T lnum; 10988 linenr_T end; 10989 int retlist; 10990 10991 lnum = get_tv_lnum(argvars); 10992 if (argvars[1].v_type == VAR_UNKNOWN) 10993 { 10994 end = 0; 10995 retlist = FALSE; 10996 } 10997 else 10998 { 10999 end = get_tv_lnum(&argvars[1]); 11000 retlist = TRUE; 11001 } 11002 11003 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 11004 } 11005 11006 /* 11007 * "getmatches()" function 11008 */ 11009 static void 11010 f_getmatches(argvars, rettv) 11011 typval_T *argvars UNUSED; 11012 typval_T *rettv; 11013 { 11014 #ifdef FEAT_SEARCH_EXTRA 11015 dict_T *dict; 11016 matchitem_T *cur = curwin->w_match_head; 11017 11018 if (rettv_list_alloc(rettv) == OK) 11019 { 11020 while (cur != NULL) 11021 { 11022 dict = dict_alloc(); 11023 if (dict == NULL) 11024 return; 11025 dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id)); 11026 dict_add_nr_str(dict, "pattern", 0L, cur->pattern); 11027 dict_add_nr_str(dict, "priority", (long)cur->priority, NULL); 11028 dict_add_nr_str(dict, "id", (long)cur->id, NULL); 11029 list_append_dict(rettv->vval.v_list, dict); 11030 cur = cur->next; 11031 } 11032 } 11033 #endif 11034 } 11035 11036 /* 11037 * "getpid()" function 11038 */ 11039 static void 11040 f_getpid(argvars, rettv) 11041 typval_T *argvars UNUSED; 11042 typval_T *rettv; 11043 { 11044 rettv->vval.v_number = mch_get_pid(); 11045 } 11046 11047 /* 11048 * "getpos(string)" function 11049 */ 11050 static void 11051 f_getpos(argvars, rettv) 11052 typval_T *argvars; 11053 typval_T *rettv; 11054 { 11055 pos_T *fp; 11056 list_T *l; 11057 int fnum = -1; 11058 11059 if (rettv_list_alloc(rettv) == OK) 11060 { 11061 l = rettv->vval.v_list; 11062 fp = var2fpos(&argvars[0], TRUE, &fnum); 11063 if (fnum != -1) 11064 list_append_number(l, (varnumber_T)fnum); 11065 else 11066 list_append_number(l, (varnumber_T)0); 11067 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 11068 : (varnumber_T)0); 11069 list_append_number(l, (fp != NULL) 11070 ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1) 11071 : (varnumber_T)0); 11072 list_append_number(l, 11073 #ifdef FEAT_VIRTUALEDIT 11074 (fp != NULL) ? (varnumber_T)fp->coladd : 11075 #endif 11076 (varnumber_T)0); 11077 } 11078 else 11079 rettv->vval.v_number = FALSE; 11080 } 11081 11082 /* 11083 * "getqflist()" and "getloclist()" functions 11084 */ 11085 static void 11086 f_getqflist(argvars, rettv) 11087 typval_T *argvars UNUSED; 11088 typval_T *rettv UNUSED; 11089 { 11090 #ifdef FEAT_QUICKFIX 11091 win_T *wp; 11092 #endif 11093 11094 #ifdef FEAT_QUICKFIX 11095 if (rettv_list_alloc(rettv) == OK) 11096 { 11097 wp = NULL; 11098 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 11099 { 11100 wp = find_win_by_nr(&argvars[0], NULL); 11101 if (wp == NULL) 11102 return; 11103 } 11104 11105 (void)get_errorlist(wp, rettv->vval.v_list); 11106 } 11107 #endif 11108 } 11109 11110 /* 11111 * "getreg()" function 11112 */ 11113 static void 11114 f_getreg(argvars, rettv) 11115 typval_T *argvars; 11116 typval_T *rettv; 11117 { 11118 char_u *strregname; 11119 int regname; 11120 int arg2 = FALSE; 11121 int error = FALSE; 11122 11123 if (argvars[0].v_type != VAR_UNKNOWN) 11124 { 11125 strregname = get_tv_string_chk(&argvars[0]); 11126 error = strregname == NULL; 11127 if (argvars[1].v_type != VAR_UNKNOWN) 11128 arg2 = get_tv_number_chk(&argvars[1], &error); 11129 } 11130 else 11131 strregname = vimvars[VV_REG].vv_str; 11132 regname = (strregname == NULL ? '"' : *strregname); 11133 if (regname == 0) 11134 regname = '"'; 11135 11136 rettv->v_type = VAR_STRING; 11137 rettv->vval.v_string = error ? NULL : 11138 get_reg_contents(regname, TRUE, arg2); 11139 } 11140 11141 /* 11142 * "getregtype()" function 11143 */ 11144 static void 11145 f_getregtype(argvars, rettv) 11146 typval_T *argvars; 11147 typval_T *rettv; 11148 { 11149 char_u *strregname; 11150 int regname; 11151 char_u buf[NUMBUFLEN + 2]; 11152 long reglen = 0; 11153 11154 if (argvars[0].v_type != VAR_UNKNOWN) 11155 { 11156 strregname = get_tv_string_chk(&argvars[0]); 11157 if (strregname == NULL) /* type error; errmsg already given */ 11158 { 11159 rettv->v_type = VAR_STRING; 11160 rettv->vval.v_string = NULL; 11161 return; 11162 } 11163 } 11164 else 11165 /* Default to v:register */ 11166 strregname = vimvars[VV_REG].vv_str; 11167 11168 regname = (strregname == NULL ? '"' : *strregname); 11169 if (regname == 0) 11170 regname = '"'; 11171 11172 buf[0] = NUL; 11173 buf[1] = NUL; 11174 switch (get_reg_type(regname, ®len)) 11175 { 11176 case MLINE: buf[0] = 'V'; break; 11177 case MCHAR: buf[0] = 'v'; break; 11178 #ifdef FEAT_VISUAL 11179 case MBLOCK: 11180 buf[0] = Ctrl_V; 11181 sprintf((char *)buf + 1, "%ld", reglen + 1); 11182 break; 11183 #endif 11184 } 11185 rettv->v_type = VAR_STRING; 11186 rettv->vval.v_string = vim_strsave(buf); 11187 } 11188 11189 /* 11190 * "gettabwinvar()" function 11191 */ 11192 static void 11193 f_gettabwinvar(argvars, rettv) 11194 typval_T *argvars; 11195 typval_T *rettv; 11196 { 11197 getwinvar(argvars, rettv, 1); 11198 } 11199 11200 /* 11201 * "getwinposx()" function 11202 */ 11203 static void 11204 f_getwinposx(argvars, rettv) 11205 typval_T *argvars UNUSED; 11206 typval_T *rettv; 11207 { 11208 rettv->vval.v_number = -1; 11209 #ifdef FEAT_GUI 11210 if (gui.in_use) 11211 { 11212 int x, y; 11213 11214 if (gui_mch_get_winpos(&x, &y) == OK) 11215 rettv->vval.v_number = x; 11216 } 11217 #endif 11218 } 11219 11220 /* 11221 * "getwinposy()" function 11222 */ 11223 static void 11224 f_getwinposy(argvars, rettv) 11225 typval_T *argvars UNUSED; 11226 typval_T *rettv; 11227 { 11228 rettv->vval.v_number = -1; 11229 #ifdef FEAT_GUI 11230 if (gui.in_use) 11231 { 11232 int x, y; 11233 11234 if (gui_mch_get_winpos(&x, &y) == OK) 11235 rettv->vval.v_number = y; 11236 } 11237 #endif 11238 } 11239 11240 /* 11241 * Find window specified by "vp" in tabpage "tp". 11242 */ 11243 static win_T * 11244 find_win_by_nr(vp, tp) 11245 typval_T *vp; 11246 tabpage_T *tp; /* NULL for current tab page */ 11247 { 11248 #ifdef FEAT_WINDOWS 11249 win_T *wp; 11250 #endif 11251 int nr; 11252 11253 nr = get_tv_number_chk(vp, NULL); 11254 11255 #ifdef FEAT_WINDOWS 11256 if (nr < 0) 11257 return NULL; 11258 if (nr == 0) 11259 return curwin; 11260 11261 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 11262 wp != NULL; wp = wp->w_next) 11263 if (--nr <= 0) 11264 break; 11265 return wp; 11266 #else 11267 if (nr == 0 || nr == 1) 11268 return curwin; 11269 return NULL; 11270 #endif 11271 } 11272 11273 /* 11274 * "getwinvar()" function 11275 */ 11276 static void 11277 f_getwinvar(argvars, rettv) 11278 typval_T *argvars; 11279 typval_T *rettv; 11280 { 11281 getwinvar(argvars, rettv, 0); 11282 } 11283 11284 /* 11285 * getwinvar() and gettabwinvar() 11286 */ 11287 static void 11288 getwinvar(argvars, rettv, off) 11289 typval_T *argvars; 11290 typval_T *rettv; 11291 int off; /* 1 for gettabwinvar() */ 11292 { 11293 win_T *win, *oldcurwin; 11294 char_u *varname; 11295 dictitem_T *v; 11296 tabpage_T *tp; 11297 11298 #ifdef FEAT_WINDOWS 11299 if (off == 1) 11300 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 11301 else 11302 tp = curtab; 11303 #endif 11304 win = find_win_by_nr(&argvars[off], tp); 11305 varname = get_tv_string_chk(&argvars[off + 1]); 11306 ++emsg_off; 11307 11308 rettv->v_type = VAR_STRING; 11309 rettv->vval.v_string = NULL; 11310 11311 if (win != NULL && varname != NULL) 11312 { 11313 /* Set curwin to be our win, temporarily. Also set curbuf, so 11314 * that we can get buffer-local options. */ 11315 oldcurwin = curwin; 11316 curwin = win; 11317 curbuf = win->w_buffer; 11318 11319 if (*varname == '&') /* window-local-option */ 11320 get_option_tv(&varname, rettv, 1); 11321 else 11322 { 11323 if (*varname == NUL) 11324 /* let getwinvar({nr}, "") return the "w:" dictionary. The 11325 * scope prefix before the NUL byte is required by 11326 * find_var_in_ht(). */ 11327 varname = (char_u *)"w:" + 2; 11328 /* look up the variable */ 11329 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 11330 if (v != NULL) 11331 copy_tv(&v->di_tv, rettv); 11332 } 11333 11334 /* restore previous notion of curwin */ 11335 curwin = oldcurwin; 11336 curbuf = curwin->w_buffer; 11337 } 11338 11339 --emsg_off; 11340 } 11341 11342 /* 11343 * "glob()" function 11344 */ 11345 static void 11346 f_glob(argvars, rettv) 11347 typval_T *argvars; 11348 typval_T *rettv; 11349 { 11350 int flags = WILD_SILENT|WILD_USE_NL; 11351 expand_T xpc; 11352 int error = FALSE; 11353 11354 /* When the optional second argument is non-zero, don't remove matches 11355 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11356 if (argvars[1].v_type != VAR_UNKNOWN 11357 && get_tv_number_chk(&argvars[1], &error)) 11358 flags |= WILD_KEEP_ALL; 11359 rettv->v_type = VAR_STRING; 11360 if (!error) 11361 { 11362 ExpandInit(&xpc); 11363 xpc.xp_context = EXPAND_FILES; 11364 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 11365 NULL, flags, WILD_ALL); 11366 } 11367 else 11368 rettv->vval.v_string = NULL; 11369 } 11370 11371 /* 11372 * "globpath()" function 11373 */ 11374 static void 11375 f_globpath(argvars, rettv) 11376 typval_T *argvars; 11377 typval_T *rettv; 11378 { 11379 int flags = 0; 11380 char_u buf1[NUMBUFLEN]; 11381 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 11382 int error = FALSE; 11383 11384 /* When the optional second argument is non-zero, don't remove matches 11385 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11386 if (argvars[2].v_type != VAR_UNKNOWN 11387 && get_tv_number_chk(&argvars[2], &error)) 11388 flags |= WILD_KEEP_ALL; 11389 rettv->v_type = VAR_STRING; 11390 if (file == NULL || error) 11391 rettv->vval.v_string = NULL; 11392 else 11393 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file, 11394 flags); 11395 } 11396 11397 /* 11398 * "has()" function 11399 */ 11400 static void 11401 f_has(argvars, rettv) 11402 typval_T *argvars; 11403 typval_T *rettv; 11404 { 11405 int i; 11406 char_u *name; 11407 int n = FALSE; 11408 static char *(has_list[]) = 11409 { 11410 #ifdef AMIGA 11411 "amiga", 11412 # ifdef FEAT_ARP 11413 "arp", 11414 # endif 11415 #endif 11416 #ifdef __BEOS__ 11417 "beos", 11418 #endif 11419 #ifdef MSDOS 11420 # ifdef DJGPP 11421 "dos32", 11422 # else 11423 "dos16", 11424 # endif 11425 #endif 11426 #ifdef MACOS 11427 "mac", 11428 #endif 11429 #if defined(MACOS_X_UNIX) 11430 "macunix", 11431 #endif 11432 #ifdef OS2 11433 "os2", 11434 #endif 11435 #ifdef __QNX__ 11436 "qnx", 11437 #endif 11438 #ifdef RISCOS 11439 "riscos", 11440 #endif 11441 #ifdef UNIX 11442 "unix", 11443 #endif 11444 #ifdef VMS 11445 "vms", 11446 #endif 11447 #ifdef WIN16 11448 "win16", 11449 #endif 11450 #ifdef WIN32 11451 "win32", 11452 #endif 11453 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 11454 "win32unix", 11455 #endif 11456 #if defined(WIN64) || defined(_WIN64) 11457 "win64", 11458 #endif 11459 #ifdef EBCDIC 11460 "ebcdic", 11461 #endif 11462 #ifndef CASE_INSENSITIVE_FILENAME 11463 "fname_case", 11464 #endif 11465 #ifdef FEAT_ARABIC 11466 "arabic", 11467 #endif 11468 #ifdef FEAT_AUTOCMD 11469 "autocmd", 11470 #endif 11471 #ifdef FEAT_BEVAL 11472 "balloon_eval", 11473 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 11474 "balloon_multiline", 11475 # endif 11476 #endif 11477 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 11478 "builtin_terms", 11479 # ifdef ALL_BUILTIN_TCAPS 11480 "all_builtin_terms", 11481 # endif 11482 #endif 11483 #ifdef FEAT_BYTEOFF 11484 "byte_offset", 11485 #endif 11486 #ifdef FEAT_CINDENT 11487 "cindent", 11488 #endif 11489 #ifdef FEAT_CLIENTSERVER 11490 "clientserver", 11491 #endif 11492 #ifdef FEAT_CLIPBOARD 11493 "clipboard", 11494 #endif 11495 #ifdef FEAT_CMDL_COMPL 11496 "cmdline_compl", 11497 #endif 11498 #ifdef FEAT_CMDHIST 11499 "cmdline_hist", 11500 #endif 11501 #ifdef FEAT_COMMENTS 11502 "comments", 11503 #endif 11504 #ifdef FEAT_CRYPT 11505 "cryptv", 11506 #endif 11507 #ifdef FEAT_CSCOPE 11508 "cscope", 11509 #endif 11510 #ifdef CURSOR_SHAPE 11511 "cursorshape", 11512 #endif 11513 #ifdef DEBUG 11514 "debug", 11515 #endif 11516 #ifdef FEAT_CON_DIALOG 11517 "dialog_con", 11518 #endif 11519 #ifdef FEAT_GUI_DIALOG 11520 "dialog_gui", 11521 #endif 11522 #ifdef FEAT_DIFF 11523 "diff", 11524 #endif 11525 #ifdef FEAT_DIGRAPHS 11526 "digraphs", 11527 #endif 11528 #ifdef FEAT_DND 11529 "dnd", 11530 #endif 11531 #ifdef FEAT_EMACS_TAGS 11532 "emacs_tags", 11533 #endif 11534 "eval", /* always present, of course! */ 11535 #ifdef FEAT_EX_EXTRA 11536 "ex_extra", 11537 #endif 11538 #ifdef FEAT_SEARCH_EXTRA 11539 "extra_search", 11540 #endif 11541 #ifdef FEAT_FKMAP 11542 "farsi", 11543 #endif 11544 #ifdef FEAT_SEARCHPATH 11545 "file_in_path", 11546 #endif 11547 #if defined(UNIX) && !defined(USE_SYSTEM) 11548 "filterpipe", 11549 #endif 11550 #ifdef FEAT_FIND_ID 11551 "find_in_path", 11552 #endif 11553 #ifdef FEAT_FLOAT 11554 "float", 11555 #endif 11556 #ifdef FEAT_FOLDING 11557 "folding", 11558 #endif 11559 #ifdef FEAT_FOOTER 11560 "footer", 11561 #endif 11562 #if !defined(USE_SYSTEM) && defined(UNIX) 11563 "fork", 11564 #endif 11565 #ifdef FEAT_GETTEXT 11566 "gettext", 11567 #endif 11568 #ifdef FEAT_GUI 11569 "gui", 11570 #endif 11571 #ifdef FEAT_GUI_ATHENA 11572 # ifdef FEAT_GUI_NEXTAW 11573 "gui_neXtaw", 11574 # else 11575 "gui_athena", 11576 # endif 11577 #endif 11578 #ifdef FEAT_GUI_GTK 11579 "gui_gtk", 11580 # ifdef HAVE_GTK2 11581 "gui_gtk2", 11582 # endif 11583 #endif 11584 #ifdef FEAT_GUI_GNOME 11585 "gui_gnome", 11586 #endif 11587 #ifdef FEAT_GUI_MAC 11588 "gui_mac", 11589 #endif 11590 #ifdef FEAT_GUI_MOTIF 11591 "gui_motif", 11592 #endif 11593 #ifdef FEAT_GUI_PHOTON 11594 "gui_photon", 11595 #endif 11596 #ifdef FEAT_GUI_W16 11597 "gui_win16", 11598 #endif 11599 #ifdef FEAT_GUI_W32 11600 "gui_win32", 11601 #endif 11602 #ifdef FEAT_HANGULIN 11603 "hangul_input", 11604 #endif 11605 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 11606 "iconv", 11607 #endif 11608 #ifdef FEAT_INS_EXPAND 11609 "insert_expand", 11610 #endif 11611 #ifdef FEAT_JUMPLIST 11612 "jumplist", 11613 #endif 11614 #ifdef FEAT_KEYMAP 11615 "keymap", 11616 #endif 11617 #ifdef FEAT_LANGMAP 11618 "langmap", 11619 #endif 11620 #ifdef FEAT_LIBCALL 11621 "libcall", 11622 #endif 11623 #ifdef FEAT_LINEBREAK 11624 "linebreak", 11625 #endif 11626 #ifdef FEAT_LISP 11627 "lispindent", 11628 #endif 11629 #ifdef FEAT_LISTCMDS 11630 "listcmds", 11631 #endif 11632 #ifdef FEAT_LOCALMAP 11633 "localmap", 11634 #endif 11635 #ifdef FEAT_MENU 11636 "menu", 11637 #endif 11638 #ifdef FEAT_SESSION 11639 "mksession", 11640 #endif 11641 #ifdef FEAT_MODIFY_FNAME 11642 "modify_fname", 11643 #endif 11644 #ifdef FEAT_MOUSE 11645 "mouse", 11646 #endif 11647 #ifdef FEAT_MOUSESHAPE 11648 "mouseshape", 11649 #endif 11650 #if defined(UNIX) || defined(VMS) 11651 # ifdef FEAT_MOUSE_DEC 11652 "mouse_dec", 11653 # endif 11654 # ifdef FEAT_MOUSE_GPM 11655 "mouse_gpm", 11656 # endif 11657 # ifdef FEAT_MOUSE_JSB 11658 "mouse_jsbterm", 11659 # endif 11660 # ifdef FEAT_MOUSE_NET 11661 "mouse_netterm", 11662 # endif 11663 # ifdef FEAT_MOUSE_PTERM 11664 "mouse_pterm", 11665 # endif 11666 # ifdef FEAT_SYSMOUSE 11667 "mouse_sysmouse", 11668 # endif 11669 # ifdef FEAT_MOUSE_XTERM 11670 "mouse_xterm", 11671 # endif 11672 #endif 11673 #ifdef FEAT_MBYTE 11674 "multi_byte", 11675 #endif 11676 #ifdef FEAT_MBYTE_IME 11677 "multi_byte_ime", 11678 #endif 11679 #ifdef FEAT_MULTI_LANG 11680 "multi_lang", 11681 #endif 11682 #ifdef FEAT_MZSCHEME 11683 #ifndef DYNAMIC_MZSCHEME 11684 "mzscheme", 11685 #endif 11686 #endif 11687 #ifdef FEAT_OLE 11688 "ole", 11689 #endif 11690 #ifdef FEAT_OSFILETYPE 11691 "osfiletype", 11692 #endif 11693 #ifdef FEAT_PATH_EXTRA 11694 "path_extra", 11695 #endif 11696 #ifdef FEAT_PERL 11697 #ifndef DYNAMIC_PERL 11698 "perl", 11699 #endif 11700 #endif 11701 #ifdef FEAT_PYTHON 11702 #ifndef DYNAMIC_PYTHON 11703 "python", 11704 #endif 11705 #endif 11706 #ifdef FEAT_POSTSCRIPT 11707 "postscript", 11708 #endif 11709 #ifdef FEAT_PRINTER 11710 "printer", 11711 #endif 11712 #ifdef FEAT_PROFILE 11713 "profile", 11714 #endif 11715 #ifdef FEAT_RELTIME 11716 "reltime", 11717 #endif 11718 #ifdef FEAT_QUICKFIX 11719 "quickfix", 11720 #endif 11721 #ifdef FEAT_RIGHTLEFT 11722 "rightleft", 11723 #endif 11724 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 11725 "ruby", 11726 #endif 11727 #ifdef FEAT_SCROLLBIND 11728 "scrollbind", 11729 #endif 11730 #ifdef FEAT_CMDL_INFO 11731 "showcmd", 11732 "cmdline_info", 11733 #endif 11734 #ifdef FEAT_SIGNS 11735 "signs", 11736 #endif 11737 #ifdef FEAT_SMARTINDENT 11738 "smartindent", 11739 #endif 11740 #ifdef FEAT_SNIFF 11741 "sniff", 11742 #endif 11743 #ifdef STARTUPTIME 11744 "startuptime", 11745 #endif 11746 #ifdef FEAT_STL_OPT 11747 "statusline", 11748 #endif 11749 #ifdef FEAT_SUN_WORKSHOP 11750 "sun_workshop", 11751 #endif 11752 #ifdef FEAT_NETBEANS_INTG 11753 "netbeans_intg", 11754 #endif 11755 #ifdef FEAT_SPELL 11756 "spell", 11757 #endif 11758 #ifdef FEAT_SYN_HL 11759 "syntax", 11760 #endif 11761 #if defined(USE_SYSTEM) || !defined(UNIX) 11762 "system", 11763 #endif 11764 #ifdef FEAT_TAG_BINS 11765 "tag_binary", 11766 #endif 11767 #ifdef FEAT_TAG_OLDSTATIC 11768 "tag_old_static", 11769 #endif 11770 #ifdef FEAT_TAG_ANYWHITE 11771 "tag_any_white", 11772 #endif 11773 #ifdef FEAT_TCL 11774 # ifndef DYNAMIC_TCL 11775 "tcl", 11776 # endif 11777 #endif 11778 #ifdef TERMINFO 11779 "terminfo", 11780 #endif 11781 #ifdef FEAT_TERMRESPONSE 11782 "termresponse", 11783 #endif 11784 #ifdef FEAT_TEXTOBJ 11785 "textobjects", 11786 #endif 11787 #ifdef HAVE_TGETENT 11788 "tgetent", 11789 #endif 11790 #ifdef FEAT_TITLE 11791 "title", 11792 #endif 11793 #ifdef FEAT_TOOLBAR 11794 "toolbar", 11795 #endif 11796 #ifdef FEAT_USR_CMDS 11797 "user-commands", /* was accidentally included in 5.4 */ 11798 "user_commands", 11799 #endif 11800 #ifdef FEAT_VIMINFO 11801 "viminfo", 11802 #endif 11803 #ifdef FEAT_VERTSPLIT 11804 "vertsplit", 11805 #endif 11806 #ifdef FEAT_VIRTUALEDIT 11807 "virtualedit", 11808 #endif 11809 #ifdef FEAT_VISUAL 11810 "visual", 11811 #endif 11812 #ifdef FEAT_VISUALEXTRA 11813 "visualextra", 11814 #endif 11815 #ifdef FEAT_VREPLACE 11816 "vreplace", 11817 #endif 11818 #ifdef FEAT_WILDIGN 11819 "wildignore", 11820 #endif 11821 #ifdef FEAT_WILDMENU 11822 "wildmenu", 11823 #endif 11824 #ifdef FEAT_WINDOWS 11825 "windows", 11826 #endif 11827 #ifdef FEAT_WAK 11828 "winaltkeys", 11829 #endif 11830 #ifdef FEAT_WRITEBACKUP 11831 "writebackup", 11832 #endif 11833 #ifdef FEAT_XIM 11834 "xim", 11835 #endif 11836 #ifdef FEAT_XFONTSET 11837 "xfontset", 11838 #endif 11839 #ifdef USE_XSMP 11840 "xsmp", 11841 #endif 11842 #ifdef USE_XSMP_INTERACT 11843 "xsmp_interact", 11844 #endif 11845 #ifdef FEAT_XCLIPBOARD 11846 "xterm_clipboard", 11847 #endif 11848 #ifdef FEAT_XTERM_SAVE 11849 "xterm_save", 11850 #endif 11851 #if defined(UNIX) && defined(FEAT_X11) 11852 "X11", 11853 #endif 11854 NULL 11855 }; 11856 11857 name = get_tv_string(&argvars[0]); 11858 for (i = 0; has_list[i] != NULL; ++i) 11859 if (STRICMP(name, has_list[i]) == 0) 11860 { 11861 n = TRUE; 11862 break; 11863 } 11864 11865 if (n == FALSE) 11866 { 11867 if (STRNICMP(name, "patch", 5) == 0) 11868 n = has_patch(atoi((char *)name + 5)); 11869 else if (STRICMP(name, "vim_starting") == 0) 11870 n = (starting != 0); 11871 #ifdef FEAT_MBYTE 11872 else if (STRICMP(name, "multi_byte_encoding") == 0) 11873 n = has_mbyte; 11874 #endif 11875 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 11876 else if (STRICMP(name, "balloon_multiline") == 0) 11877 n = multiline_balloon_available(); 11878 #endif 11879 #ifdef DYNAMIC_TCL 11880 else if (STRICMP(name, "tcl") == 0) 11881 n = tcl_enabled(FALSE); 11882 #endif 11883 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 11884 else if (STRICMP(name, "iconv") == 0) 11885 n = iconv_enabled(FALSE); 11886 #endif 11887 #ifdef DYNAMIC_MZSCHEME 11888 else if (STRICMP(name, "mzscheme") == 0) 11889 n = mzscheme_enabled(FALSE); 11890 #endif 11891 #ifdef DYNAMIC_RUBY 11892 else if (STRICMP(name, "ruby") == 0) 11893 n = ruby_enabled(FALSE); 11894 #endif 11895 #ifdef DYNAMIC_PYTHON 11896 else if (STRICMP(name, "python") == 0) 11897 n = python_enabled(FALSE); 11898 #endif 11899 #ifdef DYNAMIC_PERL 11900 else if (STRICMP(name, "perl") == 0) 11901 n = perl_enabled(FALSE); 11902 #endif 11903 #ifdef FEAT_GUI 11904 else if (STRICMP(name, "gui_running") == 0) 11905 n = (gui.in_use || gui.starting); 11906 # ifdef FEAT_GUI_W32 11907 else if (STRICMP(name, "gui_win32s") == 0) 11908 n = gui_is_win32s(); 11909 # endif 11910 # ifdef FEAT_BROWSE 11911 else if (STRICMP(name, "browse") == 0) 11912 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 11913 # endif 11914 #endif 11915 #ifdef FEAT_SYN_HL 11916 else if (STRICMP(name, "syntax_items") == 0) 11917 n = syntax_present(curbuf); 11918 #endif 11919 #if defined(WIN3264) 11920 else if (STRICMP(name, "win95") == 0) 11921 n = mch_windows95(); 11922 #endif 11923 #ifdef FEAT_NETBEANS_INTG 11924 else if (STRICMP(name, "netbeans_enabled") == 0) 11925 n = usingNetbeans; 11926 #endif 11927 } 11928 11929 rettv->vval.v_number = n; 11930 } 11931 11932 /* 11933 * "has_key()" function 11934 */ 11935 static void 11936 f_has_key(argvars, rettv) 11937 typval_T *argvars; 11938 typval_T *rettv; 11939 { 11940 if (argvars[0].v_type != VAR_DICT) 11941 { 11942 EMSG(_(e_dictreq)); 11943 return; 11944 } 11945 if (argvars[0].vval.v_dict == NULL) 11946 return; 11947 11948 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 11949 get_tv_string(&argvars[1]), -1) != NULL; 11950 } 11951 11952 /* 11953 * "haslocaldir()" function 11954 */ 11955 static void 11956 f_haslocaldir(argvars, rettv) 11957 typval_T *argvars UNUSED; 11958 typval_T *rettv; 11959 { 11960 rettv->vval.v_number = (curwin->w_localdir != NULL); 11961 } 11962 11963 /* 11964 * "hasmapto()" function 11965 */ 11966 static void 11967 f_hasmapto(argvars, rettv) 11968 typval_T *argvars; 11969 typval_T *rettv; 11970 { 11971 char_u *name; 11972 char_u *mode; 11973 char_u buf[NUMBUFLEN]; 11974 int abbr = FALSE; 11975 11976 name = get_tv_string(&argvars[0]); 11977 if (argvars[1].v_type == VAR_UNKNOWN) 11978 mode = (char_u *)"nvo"; 11979 else 11980 { 11981 mode = get_tv_string_buf(&argvars[1], buf); 11982 if (argvars[2].v_type != VAR_UNKNOWN) 11983 abbr = get_tv_number(&argvars[2]); 11984 } 11985 11986 if (map_to_exists(name, mode, abbr)) 11987 rettv->vval.v_number = TRUE; 11988 else 11989 rettv->vval.v_number = FALSE; 11990 } 11991 11992 /* 11993 * "histadd()" function 11994 */ 11995 static void 11996 f_histadd(argvars, rettv) 11997 typval_T *argvars UNUSED; 11998 typval_T *rettv; 11999 { 12000 #ifdef FEAT_CMDHIST 12001 int histype; 12002 char_u *str; 12003 char_u buf[NUMBUFLEN]; 12004 #endif 12005 12006 rettv->vval.v_number = FALSE; 12007 if (check_restricted() || check_secure()) 12008 return; 12009 #ifdef FEAT_CMDHIST 12010 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12011 histype = str != NULL ? get_histtype(str) : -1; 12012 if (histype >= 0) 12013 { 12014 str = get_tv_string_buf(&argvars[1], buf); 12015 if (*str != NUL) 12016 { 12017 init_history(); 12018 add_to_history(histype, str, FALSE, NUL); 12019 rettv->vval.v_number = TRUE; 12020 return; 12021 } 12022 } 12023 #endif 12024 } 12025 12026 /* 12027 * "histdel()" function 12028 */ 12029 static void 12030 f_histdel(argvars, rettv) 12031 typval_T *argvars UNUSED; 12032 typval_T *rettv UNUSED; 12033 { 12034 #ifdef FEAT_CMDHIST 12035 int n; 12036 char_u buf[NUMBUFLEN]; 12037 char_u *str; 12038 12039 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12040 if (str == NULL) 12041 n = 0; 12042 else if (argvars[1].v_type == VAR_UNKNOWN) 12043 /* only one argument: clear entire history */ 12044 n = clr_history(get_histtype(str)); 12045 else if (argvars[1].v_type == VAR_NUMBER) 12046 /* index given: remove that entry */ 12047 n = del_history_idx(get_histtype(str), 12048 (int)get_tv_number(&argvars[1])); 12049 else 12050 /* string given: remove all matching entries */ 12051 n = del_history_entry(get_histtype(str), 12052 get_tv_string_buf(&argvars[1], buf)); 12053 rettv->vval.v_number = n; 12054 #endif 12055 } 12056 12057 /* 12058 * "histget()" function 12059 */ 12060 static void 12061 f_histget(argvars, rettv) 12062 typval_T *argvars UNUSED; 12063 typval_T *rettv; 12064 { 12065 #ifdef FEAT_CMDHIST 12066 int type; 12067 int idx; 12068 char_u *str; 12069 12070 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12071 if (str == NULL) 12072 rettv->vval.v_string = NULL; 12073 else 12074 { 12075 type = get_histtype(str); 12076 if (argvars[1].v_type == VAR_UNKNOWN) 12077 idx = get_history_idx(type); 12078 else 12079 idx = (int)get_tv_number_chk(&argvars[1], NULL); 12080 /* -1 on type error */ 12081 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 12082 } 12083 #else 12084 rettv->vval.v_string = NULL; 12085 #endif 12086 rettv->v_type = VAR_STRING; 12087 } 12088 12089 /* 12090 * "histnr()" function 12091 */ 12092 static void 12093 f_histnr(argvars, rettv) 12094 typval_T *argvars UNUSED; 12095 typval_T *rettv; 12096 { 12097 int i; 12098 12099 #ifdef FEAT_CMDHIST 12100 char_u *history = get_tv_string_chk(&argvars[0]); 12101 12102 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 12103 if (i >= HIST_CMD && i < HIST_COUNT) 12104 i = get_history_idx(i); 12105 else 12106 #endif 12107 i = -1; 12108 rettv->vval.v_number = i; 12109 } 12110 12111 /* 12112 * "highlightID(name)" function 12113 */ 12114 static void 12115 f_hlID(argvars, rettv) 12116 typval_T *argvars; 12117 typval_T *rettv; 12118 { 12119 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 12120 } 12121 12122 /* 12123 * "highlight_exists()" function 12124 */ 12125 static void 12126 f_hlexists(argvars, rettv) 12127 typval_T *argvars; 12128 typval_T *rettv; 12129 { 12130 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 12131 } 12132 12133 /* 12134 * "hostname()" function 12135 */ 12136 static void 12137 f_hostname(argvars, rettv) 12138 typval_T *argvars UNUSED; 12139 typval_T *rettv; 12140 { 12141 char_u hostname[256]; 12142 12143 mch_get_host_name(hostname, 256); 12144 rettv->v_type = VAR_STRING; 12145 rettv->vval.v_string = vim_strsave(hostname); 12146 } 12147 12148 /* 12149 * iconv() function 12150 */ 12151 static void 12152 f_iconv(argvars, rettv) 12153 typval_T *argvars UNUSED; 12154 typval_T *rettv; 12155 { 12156 #ifdef FEAT_MBYTE 12157 char_u buf1[NUMBUFLEN]; 12158 char_u buf2[NUMBUFLEN]; 12159 char_u *from, *to, *str; 12160 vimconv_T vimconv; 12161 #endif 12162 12163 rettv->v_type = VAR_STRING; 12164 rettv->vval.v_string = NULL; 12165 12166 #ifdef FEAT_MBYTE 12167 str = get_tv_string(&argvars[0]); 12168 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 12169 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 12170 vimconv.vc_type = CONV_NONE; 12171 convert_setup(&vimconv, from, to); 12172 12173 /* If the encodings are equal, no conversion needed. */ 12174 if (vimconv.vc_type == CONV_NONE) 12175 rettv->vval.v_string = vim_strsave(str); 12176 else 12177 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 12178 12179 convert_setup(&vimconv, NULL, NULL); 12180 vim_free(from); 12181 vim_free(to); 12182 #endif 12183 } 12184 12185 /* 12186 * "indent()" function 12187 */ 12188 static void 12189 f_indent(argvars, rettv) 12190 typval_T *argvars; 12191 typval_T *rettv; 12192 { 12193 linenr_T lnum; 12194 12195 lnum = get_tv_lnum(argvars); 12196 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 12197 rettv->vval.v_number = get_indent_lnum(lnum); 12198 else 12199 rettv->vval.v_number = -1; 12200 } 12201 12202 /* 12203 * "index()" function 12204 */ 12205 static void 12206 f_index(argvars, rettv) 12207 typval_T *argvars; 12208 typval_T *rettv; 12209 { 12210 list_T *l; 12211 listitem_T *item; 12212 long idx = 0; 12213 int ic = FALSE; 12214 12215 rettv->vval.v_number = -1; 12216 if (argvars[0].v_type != VAR_LIST) 12217 { 12218 EMSG(_(e_listreq)); 12219 return; 12220 } 12221 l = argvars[0].vval.v_list; 12222 if (l != NULL) 12223 { 12224 item = l->lv_first; 12225 if (argvars[2].v_type != VAR_UNKNOWN) 12226 { 12227 int error = FALSE; 12228 12229 /* Start at specified item. Use the cached index that list_find() 12230 * sets, so that a negative number also works. */ 12231 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 12232 idx = l->lv_idx; 12233 if (argvars[3].v_type != VAR_UNKNOWN) 12234 ic = get_tv_number_chk(&argvars[3], &error); 12235 if (error) 12236 item = NULL; 12237 } 12238 12239 for ( ; item != NULL; item = item->li_next, ++idx) 12240 if (tv_equal(&item->li_tv, &argvars[1], ic)) 12241 { 12242 rettv->vval.v_number = idx; 12243 break; 12244 } 12245 } 12246 } 12247 12248 static int inputsecret_flag = 0; 12249 12250 static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog)); 12251 12252 /* 12253 * This function is used by f_input() and f_inputdialog() functions. The third 12254 * argument to f_input() specifies the type of completion to use at the 12255 * prompt. The third argument to f_inputdialog() specifies the value to return 12256 * when the user cancels the prompt. 12257 */ 12258 static void 12259 get_user_input(argvars, rettv, inputdialog) 12260 typval_T *argvars; 12261 typval_T *rettv; 12262 int inputdialog; 12263 { 12264 char_u *prompt = get_tv_string_chk(&argvars[0]); 12265 char_u *p = NULL; 12266 int c; 12267 char_u buf[NUMBUFLEN]; 12268 int cmd_silent_save = cmd_silent; 12269 char_u *defstr = (char_u *)""; 12270 int xp_type = EXPAND_NOTHING; 12271 char_u *xp_arg = NULL; 12272 12273 rettv->v_type = VAR_STRING; 12274 rettv->vval.v_string = NULL; 12275 12276 #ifdef NO_CONSOLE_INPUT 12277 /* While starting up, there is no place to enter text. */ 12278 if (no_console_input()) 12279 return; 12280 #endif 12281 12282 cmd_silent = FALSE; /* Want to see the prompt. */ 12283 if (prompt != NULL) 12284 { 12285 /* Only the part of the message after the last NL is considered as 12286 * prompt for the command line */ 12287 p = vim_strrchr(prompt, '\n'); 12288 if (p == NULL) 12289 p = prompt; 12290 else 12291 { 12292 ++p; 12293 c = *p; 12294 *p = NUL; 12295 msg_start(); 12296 msg_clr_eos(); 12297 msg_puts_attr(prompt, echo_attr); 12298 msg_didout = FALSE; 12299 msg_starthere(); 12300 *p = c; 12301 } 12302 cmdline_row = msg_row; 12303 12304 if (argvars[1].v_type != VAR_UNKNOWN) 12305 { 12306 defstr = get_tv_string_buf_chk(&argvars[1], buf); 12307 if (defstr != NULL) 12308 stuffReadbuffSpec(defstr); 12309 12310 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 12311 { 12312 char_u *xp_name; 12313 int xp_namelen; 12314 long argt; 12315 12316 rettv->vval.v_string = NULL; 12317 12318 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 12319 if (xp_name == NULL) 12320 return; 12321 12322 xp_namelen = (int)STRLEN(xp_name); 12323 12324 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 12325 &xp_arg) == FAIL) 12326 return; 12327 } 12328 } 12329 12330 if (defstr != NULL) 12331 rettv->vval.v_string = 12332 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 12333 xp_type, xp_arg); 12334 12335 vim_free(xp_arg); 12336 12337 /* since the user typed this, no need to wait for return */ 12338 need_wait_return = FALSE; 12339 msg_didout = FALSE; 12340 } 12341 cmd_silent = cmd_silent_save; 12342 } 12343 12344 /* 12345 * "input()" function 12346 * Also handles inputsecret() when inputsecret is set. 12347 */ 12348 static void 12349 f_input(argvars, rettv) 12350 typval_T *argvars; 12351 typval_T *rettv; 12352 { 12353 get_user_input(argvars, rettv, FALSE); 12354 } 12355 12356 /* 12357 * "inputdialog()" function 12358 */ 12359 static void 12360 f_inputdialog(argvars, rettv) 12361 typval_T *argvars; 12362 typval_T *rettv; 12363 { 12364 #if defined(FEAT_GUI_TEXTDIALOG) 12365 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 12366 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 12367 { 12368 char_u *message; 12369 char_u buf[NUMBUFLEN]; 12370 char_u *defstr = (char_u *)""; 12371 12372 message = get_tv_string_chk(&argvars[0]); 12373 if (argvars[1].v_type != VAR_UNKNOWN 12374 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 12375 vim_strncpy(IObuff, defstr, IOSIZE - 1); 12376 else 12377 IObuff[0] = NUL; 12378 if (message != NULL && defstr != NULL 12379 && do_dialog(VIM_QUESTION, NULL, message, 12380 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 12381 rettv->vval.v_string = vim_strsave(IObuff); 12382 else 12383 { 12384 if (message != NULL && defstr != NULL 12385 && argvars[1].v_type != VAR_UNKNOWN 12386 && argvars[2].v_type != VAR_UNKNOWN) 12387 rettv->vval.v_string = vim_strsave( 12388 get_tv_string_buf(&argvars[2], buf)); 12389 else 12390 rettv->vval.v_string = NULL; 12391 } 12392 rettv->v_type = VAR_STRING; 12393 } 12394 else 12395 #endif 12396 get_user_input(argvars, rettv, TRUE); 12397 } 12398 12399 /* 12400 * "inputlist()" function 12401 */ 12402 static void 12403 f_inputlist(argvars, rettv) 12404 typval_T *argvars; 12405 typval_T *rettv; 12406 { 12407 listitem_T *li; 12408 int selected; 12409 int mouse_used; 12410 12411 #ifdef NO_CONSOLE_INPUT 12412 /* While starting up, there is no place to enter text. */ 12413 if (no_console_input()) 12414 return; 12415 #endif 12416 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 12417 { 12418 EMSG2(_(e_listarg), "inputlist()"); 12419 return; 12420 } 12421 12422 msg_start(); 12423 msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ 12424 lines_left = Rows; /* avoid more prompt */ 12425 msg_scroll = TRUE; 12426 msg_clr_eos(); 12427 12428 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 12429 { 12430 msg_puts(get_tv_string(&li->li_tv)); 12431 msg_putchar('\n'); 12432 } 12433 12434 /* Ask for choice. */ 12435 selected = prompt_for_number(&mouse_used); 12436 if (mouse_used) 12437 selected -= lines_left; 12438 12439 rettv->vval.v_number = selected; 12440 } 12441 12442 12443 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 12444 12445 /* 12446 * "inputrestore()" function 12447 */ 12448 static void 12449 f_inputrestore(argvars, rettv) 12450 typval_T *argvars UNUSED; 12451 typval_T *rettv; 12452 { 12453 if (ga_userinput.ga_len > 0) 12454 { 12455 --ga_userinput.ga_len; 12456 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 12457 + ga_userinput.ga_len); 12458 /* default return is zero == OK */ 12459 } 12460 else if (p_verbose > 1) 12461 { 12462 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 12463 rettv->vval.v_number = 1; /* Failed */ 12464 } 12465 } 12466 12467 /* 12468 * "inputsave()" function 12469 */ 12470 static void 12471 f_inputsave(argvars, rettv) 12472 typval_T *argvars UNUSED; 12473 typval_T *rettv; 12474 { 12475 /* Add an entry to the stack of typeahead storage. */ 12476 if (ga_grow(&ga_userinput, 1) == OK) 12477 { 12478 save_typeahead((tasave_T *)(ga_userinput.ga_data) 12479 + ga_userinput.ga_len); 12480 ++ga_userinput.ga_len; 12481 /* default return is zero == OK */ 12482 } 12483 else 12484 rettv->vval.v_number = 1; /* Failed */ 12485 } 12486 12487 /* 12488 * "inputsecret()" function 12489 */ 12490 static void 12491 f_inputsecret(argvars, rettv) 12492 typval_T *argvars; 12493 typval_T *rettv; 12494 { 12495 ++cmdline_star; 12496 ++inputsecret_flag; 12497 f_input(argvars, rettv); 12498 --cmdline_star; 12499 --inputsecret_flag; 12500 } 12501 12502 /* 12503 * "insert()" function 12504 */ 12505 static void 12506 f_insert(argvars, rettv) 12507 typval_T *argvars; 12508 typval_T *rettv; 12509 { 12510 long before = 0; 12511 listitem_T *item; 12512 list_T *l; 12513 int error = FALSE; 12514 12515 if (argvars[0].v_type != VAR_LIST) 12516 EMSG2(_(e_listarg), "insert()"); 12517 else if ((l = argvars[0].vval.v_list) != NULL 12518 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 12519 { 12520 if (argvars[2].v_type != VAR_UNKNOWN) 12521 before = get_tv_number_chk(&argvars[2], &error); 12522 if (error) 12523 return; /* type error; errmsg already given */ 12524 12525 if (before == l->lv_len) 12526 item = NULL; 12527 else 12528 { 12529 item = list_find(l, before); 12530 if (item == NULL) 12531 { 12532 EMSGN(_(e_listidx), before); 12533 l = NULL; 12534 } 12535 } 12536 if (l != NULL) 12537 { 12538 list_insert_tv(l, &argvars[1], item); 12539 copy_tv(&argvars[0], rettv); 12540 } 12541 } 12542 } 12543 12544 /* 12545 * "isdirectory()" function 12546 */ 12547 static void 12548 f_isdirectory(argvars, rettv) 12549 typval_T *argvars; 12550 typval_T *rettv; 12551 { 12552 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 12553 } 12554 12555 /* 12556 * "islocked()" function 12557 */ 12558 static void 12559 f_islocked(argvars, rettv) 12560 typval_T *argvars; 12561 typval_T *rettv; 12562 { 12563 lval_T lv; 12564 char_u *end; 12565 dictitem_T *di; 12566 12567 rettv->vval.v_number = -1; 12568 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 12569 FNE_CHECK_START); 12570 if (end != NULL && lv.ll_name != NULL) 12571 { 12572 if (*end != NUL) 12573 EMSG(_(e_trailing)); 12574 else 12575 { 12576 if (lv.ll_tv == NULL) 12577 { 12578 if (check_changedtick(lv.ll_name)) 12579 rettv->vval.v_number = 1; /* always locked */ 12580 else 12581 { 12582 di = find_var(lv.ll_name, NULL); 12583 if (di != NULL) 12584 { 12585 /* Consider a variable locked when: 12586 * 1. the variable itself is locked 12587 * 2. the value of the variable is locked. 12588 * 3. the List or Dict value is locked. 12589 */ 12590 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 12591 || tv_islocked(&di->di_tv)); 12592 } 12593 } 12594 } 12595 else if (lv.ll_range) 12596 EMSG(_("E786: Range not allowed")); 12597 else if (lv.ll_newkey != NULL) 12598 EMSG2(_(e_dictkey), lv.ll_newkey); 12599 else if (lv.ll_list != NULL) 12600 /* List item. */ 12601 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 12602 else 12603 /* Dictionary item. */ 12604 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 12605 } 12606 } 12607 12608 clear_lval(&lv); 12609 } 12610 12611 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 12612 12613 /* 12614 * Turn a dict into a list: 12615 * "what" == 0: list of keys 12616 * "what" == 1: list of values 12617 * "what" == 2: list of items 12618 */ 12619 static void 12620 dict_list(argvars, rettv, what) 12621 typval_T *argvars; 12622 typval_T *rettv; 12623 int what; 12624 { 12625 list_T *l2; 12626 dictitem_T *di; 12627 hashitem_T *hi; 12628 listitem_T *li; 12629 listitem_T *li2; 12630 dict_T *d; 12631 int todo; 12632 12633 if (argvars[0].v_type != VAR_DICT) 12634 { 12635 EMSG(_(e_dictreq)); 12636 return; 12637 } 12638 if ((d = argvars[0].vval.v_dict) == NULL) 12639 return; 12640 12641 if (rettv_list_alloc(rettv) == FAIL) 12642 return; 12643 12644 todo = (int)d->dv_hashtab.ht_used; 12645 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 12646 { 12647 if (!HASHITEM_EMPTY(hi)) 12648 { 12649 --todo; 12650 di = HI2DI(hi); 12651 12652 li = listitem_alloc(); 12653 if (li == NULL) 12654 break; 12655 list_append(rettv->vval.v_list, li); 12656 12657 if (what == 0) 12658 { 12659 /* keys() */ 12660 li->li_tv.v_type = VAR_STRING; 12661 li->li_tv.v_lock = 0; 12662 li->li_tv.vval.v_string = vim_strsave(di->di_key); 12663 } 12664 else if (what == 1) 12665 { 12666 /* values() */ 12667 copy_tv(&di->di_tv, &li->li_tv); 12668 } 12669 else 12670 { 12671 /* items() */ 12672 l2 = list_alloc(); 12673 li->li_tv.v_type = VAR_LIST; 12674 li->li_tv.v_lock = 0; 12675 li->li_tv.vval.v_list = l2; 12676 if (l2 == NULL) 12677 break; 12678 ++l2->lv_refcount; 12679 12680 li2 = listitem_alloc(); 12681 if (li2 == NULL) 12682 break; 12683 list_append(l2, li2); 12684 li2->li_tv.v_type = VAR_STRING; 12685 li2->li_tv.v_lock = 0; 12686 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 12687 12688 li2 = listitem_alloc(); 12689 if (li2 == NULL) 12690 break; 12691 list_append(l2, li2); 12692 copy_tv(&di->di_tv, &li2->li_tv); 12693 } 12694 } 12695 } 12696 } 12697 12698 /* 12699 * "items(dict)" function 12700 */ 12701 static void 12702 f_items(argvars, rettv) 12703 typval_T *argvars; 12704 typval_T *rettv; 12705 { 12706 dict_list(argvars, rettv, 2); 12707 } 12708 12709 /* 12710 * "join()" function 12711 */ 12712 static void 12713 f_join(argvars, rettv) 12714 typval_T *argvars; 12715 typval_T *rettv; 12716 { 12717 garray_T ga; 12718 char_u *sep; 12719 12720 if (argvars[0].v_type != VAR_LIST) 12721 { 12722 EMSG(_(e_listreq)); 12723 return; 12724 } 12725 if (argvars[0].vval.v_list == NULL) 12726 return; 12727 if (argvars[1].v_type == VAR_UNKNOWN) 12728 sep = (char_u *)" "; 12729 else 12730 sep = get_tv_string_chk(&argvars[1]); 12731 12732 rettv->v_type = VAR_STRING; 12733 12734 if (sep != NULL) 12735 { 12736 ga_init2(&ga, (int)sizeof(char), 80); 12737 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 12738 ga_append(&ga, NUL); 12739 rettv->vval.v_string = (char_u *)ga.ga_data; 12740 } 12741 else 12742 rettv->vval.v_string = NULL; 12743 } 12744 12745 /* 12746 * "keys()" function 12747 */ 12748 static void 12749 f_keys(argvars, rettv) 12750 typval_T *argvars; 12751 typval_T *rettv; 12752 { 12753 dict_list(argvars, rettv, 0); 12754 } 12755 12756 /* 12757 * "last_buffer_nr()" function. 12758 */ 12759 static void 12760 f_last_buffer_nr(argvars, rettv) 12761 typval_T *argvars UNUSED; 12762 typval_T *rettv; 12763 { 12764 int n = 0; 12765 buf_T *buf; 12766 12767 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 12768 if (n < buf->b_fnum) 12769 n = buf->b_fnum; 12770 12771 rettv->vval.v_number = n; 12772 } 12773 12774 /* 12775 * "len()" function 12776 */ 12777 static void 12778 f_len(argvars, rettv) 12779 typval_T *argvars; 12780 typval_T *rettv; 12781 { 12782 switch (argvars[0].v_type) 12783 { 12784 case VAR_STRING: 12785 case VAR_NUMBER: 12786 rettv->vval.v_number = (varnumber_T)STRLEN( 12787 get_tv_string(&argvars[0])); 12788 break; 12789 case VAR_LIST: 12790 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 12791 break; 12792 case VAR_DICT: 12793 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 12794 break; 12795 default: 12796 EMSG(_("E701: Invalid type for len()")); 12797 break; 12798 } 12799 } 12800 12801 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 12802 12803 static void 12804 libcall_common(argvars, rettv, type) 12805 typval_T *argvars; 12806 typval_T *rettv; 12807 int type; 12808 { 12809 #ifdef FEAT_LIBCALL 12810 char_u *string_in; 12811 char_u **string_result; 12812 int nr_result; 12813 #endif 12814 12815 rettv->v_type = type; 12816 if (type != VAR_NUMBER) 12817 rettv->vval.v_string = NULL; 12818 12819 if (check_restricted() || check_secure()) 12820 return; 12821 12822 #ifdef FEAT_LIBCALL 12823 /* The first two args must be strings, otherwise its meaningless */ 12824 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 12825 { 12826 string_in = NULL; 12827 if (argvars[2].v_type == VAR_STRING) 12828 string_in = argvars[2].vval.v_string; 12829 if (type == VAR_NUMBER) 12830 string_result = NULL; 12831 else 12832 string_result = &rettv->vval.v_string; 12833 if (mch_libcall(argvars[0].vval.v_string, 12834 argvars[1].vval.v_string, 12835 string_in, 12836 argvars[2].vval.v_number, 12837 string_result, 12838 &nr_result) == OK 12839 && type == VAR_NUMBER) 12840 rettv->vval.v_number = nr_result; 12841 } 12842 #endif 12843 } 12844 12845 /* 12846 * "libcall()" function 12847 */ 12848 static void 12849 f_libcall(argvars, rettv) 12850 typval_T *argvars; 12851 typval_T *rettv; 12852 { 12853 libcall_common(argvars, rettv, VAR_STRING); 12854 } 12855 12856 /* 12857 * "libcallnr()" function 12858 */ 12859 static void 12860 f_libcallnr(argvars, rettv) 12861 typval_T *argvars; 12862 typval_T *rettv; 12863 { 12864 libcall_common(argvars, rettv, VAR_NUMBER); 12865 } 12866 12867 /* 12868 * "line(string)" function 12869 */ 12870 static void 12871 f_line(argvars, rettv) 12872 typval_T *argvars; 12873 typval_T *rettv; 12874 { 12875 linenr_T lnum = 0; 12876 pos_T *fp; 12877 int fnum; 12878 12879 fp = var2fpos(&argvars[0], TRUE, &fnum); 12880 if (fp != NULL) 12881 lnum = fp->lnum; 12882 rettv->vval.v_number = lnum; 12883 } 12884 12885 /* 12886 * "line2byte(lnum)" function 12887 */ 12888 static void 12889 f_line2byte(argvars, rettv) 12890 typval_T *argvars UNUSED; 12891 typval_T *rettv; 12892 { 12893 #ifndef FEAT_BYTEOFF 12894 rettv->vval.v_number = -1; 12895 #else 12896 linenr_T lnum; 12897 12898 lnum = get_tv_lnum(argvars); 12899 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 12900 rettv->vval.v_number = -1; 12901 else 12902 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 12903 if (rettv->vval.v_number >= 0) 12904 ++rettv->vval.v_number; 12905 #endif 12906 } 12907 12908 /* 12909 * "lispindent(lnum)" function 12910 */ 12911 static void 12912 f_lispindent(argvars, rettv) 12913 typval_T *argvars; 12914 typval_T *rettv; 12915 { 12916 #ifdef FEAT_LISP 12917 pos_T pos; 12918 linenr_T lnum; 12919 12920 pos = curwin->w_cursor; 12921 lnum = get_tv_lnum(argvars); 12922 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 12923 { 12924 curwin->w_cursor.lnum = lnum; 12925 rettv->vval.v_number = get_lisp_indent(); 12926 curwin->w_cursor = pos; 12927 } 12928 else 12929 #endif 12930 rettv->vval.v_number = -1; 12931 } 12932 12933 /* 12934 * "localtime()" function 12935 */ 12936 static void 12937 f_localtime(argvars, rettv) 12938 typval_T *argvars UNUSED; 12939 typval_T *rettv; 12940 { 12941 rettv->vval.v_number = (varnumber_T)time(NULL); 12942 } 12943 12944 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 12945 12946 static void 12947 get_maparg(argvars, rettv, exact) 12948 typval_T *argvars; 12949 typval_T *rettv; 12950 int exact; 12951 { 12952 char_u *keys; 12953 char_u *which; 12954 char_u buf[NUMBUFLEN]; 12955 char_u *keys_buf = NULL; 12956 char_u *rhs; 12957 int mode; 12958 garray_T ga; 12959 int abbr = FALSE; 12960 12961 /* return empty string for failure */ 12962 rettv->v_type = VAR_STRING; 12963 rettv->vval.v_string = NULL; 12964 12965 keys = get_tv_string(&argvars[0]); 12966 if (*keys == NUL) 12967 return; 12968 12969 if (argvars[1].v_type != VAR_UNKNOWN) 12970 { 12971 which = get_tv_string_buf_chk(&argvars[1], buf); 12972 if (argvars[2].v_type != VAR_UNKNOWN) 12973 abbr = get_tv_number(&argvars[2]); 12974 } 12975 else 12976 which = (char_u *)""; 12977 if (which == NULL) 12978 return; 12979 12980 mode = get_map_mode(&which, 0); 12981 12982 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); 12983 rhs = check_map(keys, mode, exact, FALSE, abbr); 12984 vim_free(keys_buf); 12985 if (rhs != NULL) 12986 { 12987 ga_init(&ga); 12988 ga.ga_itemsize = 1; 12989 ga.ga_growsize = 40; 12990 12991 while (*rhs != NUL) 12992 ga_concat(&ga, str2special(&rhs, FALSE)); 12993 12994 ga_append(&ga, NUL); 12995 rettv->vval.v_string = (char_u *)ga.ga_data; 12996 } 12997 } 12998 12999 #ifdef FEAT_FLOAT 13000 /* 13001 * "log10()" function 13002 */ 13003 static void 13004 f_log10(argvars, rettv) 13005 typval_T *argvars; 13006 typval_T *rettv; 13007 { 13008 float_T f; 13009 13010 rettv->v_type = VAR_FLOAT; 13011 if (get_float_arg(argvars, &f) == OK) 13012 rettv->vval.v_float = log10(f); 13013 else 13014 rettv->vval.v_float = 0.0; 13015 } 13016 #endif 13017 13018 /* 13019 * "map()" function 13020 */ 13021 static void 13022 f_map(argvars, rettv) 13023 typval_T *argvars; 13024 typval_T *rettv; 13025 { 13026 filter_map(argvars, rettv, TRUE); 13027 } 13028 13029 /* 13030 * "maparg()" function 13031 */ 13032 static void 13033 f_maparg(argvars, rettv) 13034 typval_T *argvars; 13035 typval_T *rettv; 13036 { 13037 get_maparg(argvars, rettv, TRUE); 13038 } 13039 13040 /* 13041 * "mapcheck()" function 13042 */ 13043 static void 13044 f_mapcheck(argvars, rettv) 13045 typval_T *argvars; 13046 typval_T *rettv; 13047 { 13048 get_maparg(argvars, rettv, FALSE); 13049 } 13050 13051 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 13052 13053 static void 13054 find_some_match(argvars, rettv, type) 13055 typval_T *argvars; 13056 typval_T *rettv; 13057 int type; 13058 { 13059 char_u *str = NULL; 13060 char_u *expr = NULL; 13061 char_u *pat; 13062 regmatch_T regmatch; 13063 char_u patbuf[NUMBUFLEN]; 13064 char_u strbuf[NUMBUFLEN]; 13065 char_u *save_cpo; 13066 long start = 0; 13067 long nth = 1; 13068 colnr_T startcol = 0; 13069 int match = 0; 13070 list_T *l = NULL; 13071 listitem_T *li = NULL; 13072 long idx = 0; 13073 char_u *tofree = NULL; 13074 13075 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13076 save_cpo = p_cpo; 13077 p_cpo = (char_u *)""; 13078 13079 rettv->vval.v_number = -1; 13080 if (type == 3) 13081 { 13082 /* return empty list when there are no matches */ 13083 if (rettv_list_alloc(rettv) == FAIL) 13084 goto theend; 13085 } 13086 else if (type == 2) 13087 { 13088 rettv->v_type = VAR_STRING; 13089 rettv->vval.v_string = NULL; 13090 } 13091 13092 if (argvars[0].v_type == VAR_LIST) 13093 { 13094 if ((l = argvars[0].vval.v_list) == NULL) 13095 goto theend; 13096 li = l->lv_first; 13097 } 13098 else 13099 expr = str = get_tv_string(&argvars[0]); 13100 13101 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13102 if (pat == NULL) 13103 goto theend; 13104 13105 if (argvars[2].v_type != VAR_UNKNOWN) 13106 { 13107 int error = FALSE; 13108 13109 start = get_tv_number_chk(&argvars[2], &error); 13110 if (error) 13111 goto theend; 13112 if (l != NULL) 13113 { 13114 li = list_find(l, start); 13115 if (li == NULL) 13116 goto theend; 13117 idx = l->lv_idx; /* use the cached index */ 13118 } 13119 else 13120 { 13121 if (start < 0) 13122 start = 0; 13123 if (start > (long)STRLEN(str)) 13124 goto theend; 13125 /* When "count" argument is there ignore matches before "start", 13126 * otherwise skip part of the string. Differs when pattern is "^" 13127 * or "\<". */ 13128 if (argvars[3].v_type != VAR_UNKNOWN) 13129 startcol = start; 13130 else 13131 str += start; 13132 } 13133 13134 if (argvars[3].v_type != VAR_UNKNOWN) 13135 nth = get_tv_number_chk(&argvars[3], &error); 13136 if (error) 13137 goto theend; 13138 } 13139 13140 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13141 if (regmatch.regprog != NULL) 13142 { 13143 regmatch.rm_ic = p_ic; 13144 13145 for (;;) 13146 { 13147 if (l != NULL) 13148 { 13149 if (li == NULL) 13150 { 13151 match = FALSE; 13152 break; 13153 } 13154 vim_free(tofree); 13155 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 13156 if (str == NULL) 13157 break; 13158 } 13159 13160 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 13161 13162 if (match && --nth <= 0) 13163 break; 13164 if (l == NULL && !match) 13165 break; 13166 13167 /* Advance to just after the match. */ 13168 if (l != NULL) 13169 { 13170 li = li->li_next; 13171 ++idx; 13172 } 13173 else 13174 { 13175 #ifdef FEAT_MBYTE 13176 startcol = (colnr_T)(regmatch.startp[0] 13177 + (*mb_ptr2len)(regmatch.startp[0]) - str); 13178 #else 13179 startcol = regmatch.startp[0] + 1 - str; 13180 #endif 13181 } 13182 } 13183 13184 if (match) 13185 { 13186 if (type == 3) 13187 { 13188 int i; 13189 13190 /* return list with matched string and submatches */ 13191 for (i = 0; i < NSUBEXP; ++i) 13192 { 13193 if (regmatch.endp[i] == NULL) 13194 { 13195 if (list_append_string(rettv->vval.v_list, 13196 (char_u *)"", 0) == FAIL) 13197 break; 13198 } 13199 else if (list_append_string(rettv->vval.v_list, 13200 regmatch.startp[i], 13201 (int)(regmatch.endp[i] - regmatch.startp[i])) 13202 == FAIL) 13203 break; 13204 } 13205 } 13206 else if (type == 2) 13207 { 13208 /* return matched string */ 13209 if (l != NULL) 13210 copy_tv(&li->li_tv, rettv); 13211 else 13212 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 13213 (int)(regmatch.endp[0] - regmatch.startp[0])); 13214 } 13215 else if (l != NULL) 13216 rettv->vval.v_number = idx; 13217 else 13218 { 13219 if (type != 0) 13220 rettv->vval.v_number = 13221 (varnumber_T)(regmatch.startp[0] - str); 13222 else 13223 rettv->vval.v_number = 13224 (varnumber_T)(regmatch.endp[0] - str); 13225 rettv->vval.v_number += (varnumber_T)(str - expr); 13226 } 13227 } 13228 vim_free(regmatch.regprog); 13229 } 13230 13231 theend: 13232 vim_free(tofree); 13233 p_cpo = save_cpo; 13234 } 13235 13236 /* 13237 * "match()" function 13238 */ 13239 static void 13240 f_match(argvars, rettv) 13241 typval_T *argvars; 13242 typval_T *rettv; 13243 { 13244 find_some_match(argvars, rettv, 1); 13245 } 13246 13247 /* 13248 * "matchadd()" function 13249 */ 13250 static void 13251 f_matchadd(argvars, rettv) 13252 typval_T *argvars; 13253 typval_T *rettv; 13254 { 13255 #ifdef FEAT_SEARCH_EXTRA 13256 char_u buf[NUMBUFLEN]; 13257 char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */ 13258 char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */ 13259 int prio = 10; /* default priority */ 13260 int id = -1; 13261 int error = FALSE; 13262 13263 rettv->vval.v_number = -1; 13264 13265 if (grp == NULL || pat == NULL) 13266 return; 13267 if (argvars[2].v_type != VAR_UNKNOWN) 13268 { 13269 prio = get_tv_number_chk(&argvars[2], &error); 13270 if (argvars[3].v_type != VAR_UNKNOWN) 13271 id = get_tv_number_chk(&argvars[3], &error); 13272 } 13273 if (error == TRUE) 13274 return; 13275 if (id >= 1 && id <= 3) 13276 { 13277 EMSGN("E798: ID is reserved for \":match\": %ld", id); 13278 return; 13279 } 13280 13281 rettv->vval.v_number = match_add(curwin, grp, pat, prio, id); 13282 #endif 13283 } 13284 13285 /* 13286 * "matcharg()" function 13287 */ 13288 static void 13289 f_matcharg(argvars, rettv) 13290 typval_T *argvars; 13291 typval_T *rettv; 13292 { 13293 if (rettv_list_alloc(rettv) == OK) 13294 { 13295 #ifdef FEAT_SEARCH_EXTRA 13296 int id = get_tv_number(&argvars[0]); 13297 matchitem_T *m; 13298 13299 if (id >= 1 && id <= 3) 13300 { 13301 if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) 13302 { 13303 list_append_string(rettv->vval.v_list, 13304 syn_id2name(m->hlg_id), -1); 13305 list_append_string(rettv->vval.v_list, m->pattern, -1); 13306 } 13307 else 13308 { 13309 list_append_string(rettv->vval.v_list, NUL, -1); 13310 list_append_string(rettv->vval.v_list, NUL, -1); 13311 } 13312 } 13313 #endif 13314 } 13315 } 13316 13317 /* 13318 * "matchdelete()" function 13319 */ 13320 static void 13321 f_matchdelete(argvars, rettv) 13322 typval_T *argvars; 13323 typval_T *rettv; 13324 { 13325 #ifdef FEAT_SEARCH_EXTRA 13326 rettv->vval.v_number = match_delete(curwin, 13327 (int)get_tv_number(&argvars[0]), TRUE); 13328 #endif 13329 } 13330 13331 /* 13332 * "matchend()" function 13333 */ 13334 static void 13335 f_matchend(argvars, rettv) 13336 typval_T *argvars; 13337 typval_T *rettv; 13338 { 13339 find_some_match(argvars, rettv, 0); 13340 } 13341 13342 /* 13343 * "matchlist()" function 13344 */ 13345 static void 13346 f_matchlist(argvars, rettv) 13347 typval_T *argvars; 13348 typval_T *rettv; 13349 { 13350 find_some_match(argvars, rettv, 3); 13351 } 13352 13353 /* 13354 * "matchstr()" function 13355 */ 13356 static void 13357 f_matchstr(argvars, rettv) 13358 typval_T *argvars; 13359 typval_T *rettv; 13360 { 13361 find_some_match(argvars, rettv, 2); 13362 } 13363 13364 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 13365 13366 static void 13367 max_min(argvars, rettv, domax) 13368 typval_T *argvars; 13369 typval_T *rettv; 13370 int domax; 13371 { 13372 long n = 0; 13373 long i; 13374 int error = FALSE; 13375 13376 if (argvars[0].v_type == VAR_LIST) 13377 { 13378 list_T *l; 13379 listitem_T *li; 13380 13381 l = argvars[0].vval.v_list; 13382 if (l != NULL) 13383 { 13384 li = l->lv_first; 13385 if (li != NULL) 13386 { 13387 n = get_tv_number_chk(&li->li_tv, &error); 13388 for (;;) 13389 { 13390 li = li->li_next; 13391 if (li == NULL) 13392 break; 13393 i = get_tv_number_chk(&li->li_tv, &error); 13394 if (domax ? i > n : i < n) 13395 n = i; 13396 } 13397 } 13398 } 13399 } 13400 else if (argvars[0].v_type == VAR_DICT) 13401 { 13402 dict_T *d; 13403 int first = TRUE; 13404 hashitem_T *hi; 13405 int todo; 13406 13407 d = argvars[0].vval.v_dict; 13408 if (d != NULL) 13409 { 13410 todo = (int)d->dv_hashtab.ht_used; 13411 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 13412 { 13413 if (!HASHITEM_EMPTY(hi)) 13414 { 13415 --todo; 13416 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 13417 if (first) 13418 { 13419 n = i; 13420 first = FALSE; 13421 } 13422 else if (domax ? i > n : i < n) 13423 n = i; 13424 } 13425 } 13426 } 13427 } 13428 else 13429 EMSG(_(e_listdictarg)); 13430 rettv->vval.v_number = error ? 0 : n; 13431 } 13432 13433 /* 13434 * "max()" function 13435 */ 13436 static void 13437 f_max(argvars, rettv) 13438 typval_T *argvars; 13439 typval_T *rettv; 13440 { 13441 max_min(argvars, rettv, TRUE); 13442 } 13443 13444 /* 13445 * "min()" function 13446 */ 13447 static void 13448 f_min(argvars, rettv) 13449 typval_T *argvars; 13450 typval_T *rettv; 13451 { 13452 max_min(argvars, rettv, FALSE); 13453 } 13454 13455 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 13456 13457 /* 13458 * Create the directory in which "dir" is located, and higher levels when 13459 * needed. 13460 */ 13461 static int 13462 mkdir_recurse(dir, prot) 13463 char_u *dir; 13464 int prot; 13465 { 13466 char_u *p; 13467 char_u *updir; 13468 int r = FAIL; 13469 13470 /* Get end of directory name in "dir". 13471 * We're done when it's "/" or "c:/". */ 13472 p = gettail_sep(dir); 13473 if (p <= get_past_head(dir)) 13474 return OK; 13475 13476 /* If the directory exists we're done. Otherwise: create it.*/ 13477 updir = vim_strnsave(dir, (int)(p - dir)); 13478 if (updir == NULL) 13479 return FAIL; 13480 if (mch_isdir(updir)) 13481 r = OK; 13482 else if (mkdir_recurse(updir, prot) == OK) 13483 r = vim_mkdir_emsg(updir, prot); 13484 vim_free(updir); 13485 return r; 13486 } 13487 13488 #ifdef vim_mkdir 13489 /* 13490 * "mkdir()" function 13491 */ 13492 static void 13493 f_mkdir(argvars, rettv) 13494 typval_T *argvars; 13495 typval_T *rettv; 13496 { 13497 char_u *dir; 13498 char_u buf[NUMBUFLEN]; 13499 int prot = 0755; 13500 13501 rettv->vval.v_number = FAIL; 13502 if (check_restricted() || check_secure()) 13503 return; 13504 13505 dir = get_tv_string_buf(&argvars[0], buf); 13506 if (argvars[1].v_type != VAR_UNKNOWN) 13507 { 13508 if (argvars[2].v_type != VAR_UNKNOWN) 13509 prot = get_tv_number_chk(&argvars[2], NULL); 13510 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 13511 mkdir_recurse(dir, prot); 13512 } 13513 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 13514 } 13515 #endif 13516 13517 /* 13518 * "mode()" function 13519 */ 13520 static void 13521 f_mode(argvars, rettv) 13522 typval_T *argvars; 13523 typval_T *rettv; 13524 { 13525 char_u buf[3]; 13526 13527 buf[1] = NUL; 13528 buf[2] = NUL; 13529 13530 #ifdef FEAT_VISUAL 13531 if (VIsual_active) 13532 { 13533 if (VIsual_select) 13534 buf[0] = VIsual_mode + 's' - 'v'; 13535 else 13536 buf[0] = VIsual_mode; 13537 } 13538 else 13539 #endif 13540 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE 13541 || State == CONFIRM) 13542 { 13543 buf[0] = 'r'; 13544 if (State == ASKMORE) 13545 buf[1] = 'm'; 13546 else if (State == CONFIRM) 13547 buf[1] = '?'; 13548 } 13549 else if (State == EXTERNCMD) 13550 buf[0] = '!'; 13551 else if (State & INSERT) 13552 { 13553 #ifdef FEAT_VREPLACE 13554 if (State & VREPLACE_FLAG) 13555 { 13556 buf[0] = 'R'; 13557 buf[1] = 'v'; 13558 } 13559 else 13560 #endif 13561 if (State & REPLACE_FLAG) 13562 buf[0] = 'R'; 13563 else 13564 buf[0] = 'i'; 13565 } 13566 else if (State & CMDLINE) 13567 { 13568 buf[0] = 'c'; 13569 if (exmode_active) 13570 buf[1] = 'v'; 13571 } 13572 else if (exmode_active) 13573 { 13574 buf[0] = 'c'; 13575 buf[1] = 'e'; 13576 } 13577 else 13578 { 13579 buf[0] = 'n'; 13580 if (finish_op) 13581 buf[1] = 'o'; 13582 } 13583 13584 /* Clear out the minor mode when the argument is not a non-zero number or 13585 * non-empty string. */ 13586 if (!non_zero_arg(&argvars[0])) 13587 buf[1] = NUL; 13588 13589 rettv->vval.v_string = vim_strsave(buf); 13590 rettv->v_type = VAR_STRING; 13591 } 13592 13593 /* 13594 * "nextnonblank()" function 13595 */ 13596 static void 13597 f_nextnonblank(argvars, rettv) 13598 typval_T *argvars; 13599 typval_T *rettv; 13600 { 13601 linenr_T lnum; 13602 13603 for (lnum = get_tv_lnum(argvars); ; ++lnum) 13604 { 13605 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 13606 { 13607 lnum = 0; 13608 break; 13609 } 13610 if (*skipwhite(ml_get(lnum)) != NUL) 13611 break; 13612 } 13613 rettv->vval.v_number = lnum; 13614 } 13615 13616 /* 13617 * "nr2char()" function 13618 */ 13619 static void 13620 f_nr2char(argvars, rettv) 13621 typval_T *argvars; 13622 typval_T *rettv; 13623 { 13624 char_u buf[NUMBUFLEN]; 13625 13626 #ifdef FEAT_MBYTE 13627 if (has_mbyte) 13628 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 13629 else 13630 #endif 13631 { 13632 buf[0] = (char_u)get_tv_number(&argvars[0]); 13633 buf[1] = NUL; 13634 } 13635 rettv->v_type = VAR_STRING; 13636 rettv->vval.v_string = vim_strsave(buf); 13637 } 13638 13639 /* 13640 * "pathshorten()" function 13641 */ 13642 static void 13643 f_pathshorten(argvars, rettv) 13644 typval_T *argvars; 13645 typval_T *rettv; 13646 { 13647 char_u *p; 13648 13649 rettv->v_type = VAR_STRING; 13650 p = get_tv_string_chk(&argvars[0]); 13651 if (p == NULL) 13652 rettv->vval.v_string = NULL; 13653 else 13654 { 13655 p = vim_strsave(p); 13656 rettv->vval.v_string = p; 13657 if (p != NULL) 13658 shorten_dir(p); 13659 } 13660 } 13661 13662 #ifdef FEAT_FLOAT 13663 /* 13664 * "pow()" function 13665 */ 13666 static void 13667 f_pow(argvars, rettv) 13668 typval_T *argvars; 13669 typval_T *rettv; 13670 { 13671 float_T fx, fy; 13672 13673 rettv->v_type = VAR_FLOAT; 13674 if (get_float_arg(argvars, &fx) == OK 13675 && get_float_arg(&argvars[1], &fy) == OK) 13676 rettv->vval.v_float = pow(fx, fy); 13677 else 13678 rettv->vval.v_float = 0.0; 13679 } 13680 #endif 13681 13682 /* 13683 * "prevnonblank()" function 13684 */ 13685 static void 13686 f_prevnonblank(argvars, rettv) 13687 typval_T *argvars; 13688 typval_T *rettv; 13689 { 13690 linenr_T lnum; 13691 13692 lnum = get_tv_lnum(argvars); 13693 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 13694 lnum = 0; 13695 else 13696 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 13697 --lnum; 13698 rettv->vval.v_number = lnum; 13699 } 13700 13701 #ifdef HAVE_STDARG_H 13702 /* This dummy va_list is here because: 13703 * - passing a NULL pointer doesn't work when va_list isn't a pointer 13704 * - locally in the function results in a "used before set" warning 13705 * - using va_start() to initialize it gives "function with fixed args" error */ 13706 static va_list ap; 13707 #endif 13708 13709 /* 13710 * "printf()" function 13711 */ 13712 static void 13713 f_printf(argvars, rettv) 13714 typval_T *argvars; 13715 typval_T *rettv; 13716 { 13717 rettv->v_type = VAR_STRING; 13718 rettv->vval.v_string = NULL; 13719 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 13720 { 13721 char_u buf[NUMBUFLEN]; 13722 int len; 13723 char_u *s; 13724 int saved_did_emsg = did_emsg; 13725 char *fmt; 13726 13727 /* Get the required length, allocate the buffer and do it for real. */ 13728 did_emsg = FALSE; 13729 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 13730 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 13731 if (!did_emsg) 13732 { 13733 s = alloc(len + 1); 13734 if (s != NULL) 13735 { 13736 rettv->vval.v_string = s; 13737 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 13738 } 13739 } 13740 did_emsg |= saved_did_emsg; 13741 } 13742 #endif 13743 } 13744 13745 /* 13746 * "pumvisible()" function 13747 */ 13748 static void 13749 f_pumvisible(argvars, rettv) 13750 typval_T *argvars UNUSED; 13751 typval_T *rettv UNUSED; 13752 { 13753 #ifdef FEAT_INS_EXPAND 13754 if (pum_visible()) 13755 rettv->vval.v_number = 1; 13756 #endif 13757 } 13758 13759 /* 13760 * "range()" function 13761 */ 13762 static void 13763 f_range(argvars, rettv) 13764 typval_T *argvars; 13765 typval_T *rettv; 13766 { 13767 long start; 13768 long end; 13769 long stride = 1; 13770 long i; 13771 int error = FALSE; 13772 13773 start = get_tv_number_chk(&argvars[0], &error); 13774 if (argvars[1].v_type == VAR_UNKNOWN) 13775 { 13776 end = start - 1; 13777 start = 0; 13778 } 13779 else 13780 { 13781 end = get_tv_number_chk(&argvars[1], &error); 13782 if (argvars[2].v_type != VAR_UNKNOWN) 13783 stride = get_tv_number_chk(&argvars[2], &error); 13784 } 13785 13786 if (error) 13787 return; /* type error; errmsg already given */ 13788 if (stride == 0) 13789 EMSG(_("E726: Stride is zero")); 13790 else if (stride > 0 ? end + 1 < start : end - 1 > start) 13791 EMSG(_("E727: Start past end")); 13792 else 13793 { 13794 if (rettv_list_alloc(rettv) == OK) 13795 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 13796 if (list_append_number(rettv->vval.v_list, 13797 (varnumber_T)i) == FAIL) 13798 break; 13799 } 13800 } 13801 13802 /* 13803 * "readfile()" function 13804 */ 13805 static void 13806 f_readfile(argvars, rettv) 13807 typval_T *argvars; 13808 typval_T *rettv; 13809 { 13810 int binary = FALSE; 13811 char_u *fname; 13812 FILE *fd; 13813 listitem_T *li; 13814 #define FREAD_SIZE 200 /* optimized for text lines */ 13815 char_u buf[FREAD_SIZE]; 13816 int readlen; /* size of last fread() */ 13817 int buflen; /* nr of valid chars in buf[] */ 13818 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 13819 int tolist; /* first byte in buf[] still to be put in list */ 13820 int chop; /* how many CR to chop off */ 13821 char_u *prev = NULL; /* previously read bytes, if any */ 13822 int prevlen = 0; /* length of "prev" if not NULL */ 13823 char_u *s; 13824 int len; 13825 long maxline = MAXLNUM; 13826 long cnt = 0; 13827 13828 if (argvars[1].v_type != VAR_UNKNOWN) 13829 { 13830 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 13831 binary = TRUE; 13832 if (argvars[2].v_type != VAR_UNKNOWN) 13833 maxline = get_tv_number(&argvars[2]); 13834 } 13835 13836 if (rettv_list_alloc(rettv) == FAIL) 13837 return; 13838 13839 /* Always open the file in binary mode, library functions have a mind of 13840 * their own about CR-LF conversion. */ 13841 fname = get_tv_string(&argvars[0]); 13842 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 13843 { 13844 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 13845 return; 13846 } 13847 13848 filtd = 0; 13849 while (cnt < maxline || maxline < 0) 13850 { 13851 readlen = (int)fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 13852 buflen = filtd + readlen; 13853 tolist = 0; 13854 for ( ; filtd < buflen || readlen <= 0; ++filtd) 13855 { 13856 if (buf[filtd] == '\n' || readlen <= 0) 13857 { 13858 /* Only when in binary mode add an empty list item when the 13859 * last line ends in a '\n'. */ 13860 if (!binary && readlen == 0 && filtd == 0) 13861 break; 13862 13863 /* Found end-of-line or end-of-file: add a text line to the 13864 * list. */ 13865 chop = 0; 13866 if (!binary) 13867 while (filtd - chop - 1 >= tolist 13868 && buf[filtd - chop - 1] == '\r') 13869 ++chop; 13870 len = filtd - tolist - chop; 13871 if (prev == NULL) 13872 s = vim_strnsave(buf + tolist, len); 13873 else 13874 { 13875 s = alloc((unsigned)(prevlen + len + 1)); 13876 if (s != NULL) 13877 { 13878 mch_memmove(s, prev, prevlen); 13879 vim_free(prev); 13880 prev = NULL; 13881 mch_memmove(s + prevlen, buf + tolist, len); 13882 s[prevlen + len] = NUL; 13883 } 13884 } 13885 tolist = filtd + 1; 13886 13887 li = listitem_alloc(); 13888 if (li == NULL) 13889 { 13890 vim_free(s); 13891 break; 13892 } 13893 li->li_tv.v_type = VAR_STRING; 13894 li->li_tv.v_lock = 0; 13895 li->li_tv.vval.v_string = s; 13896 list_append(rettv->vval.v_list, li); 13897 13898 if (++cnt >= maxline && maxline >= 0) 13899 break; 13900 if (readlen <= 0) 13901 break; 13902 } 13903 else if (buf[filtd] == NUL) 13904 buf[filtd] = '\n'; 13905 } 13906 if (readlen <= 0) 13907 break; 13908 13909 if (tolist == 0) 13910 { 13911 /* "buf" is full, need to move text to an allocated buffer */ 13912 if (prev == NULL) 13913 { 13914 prev = vim_strnsave(buf, buflen); 13915 prevlen = buflen; 13916 } 13917 else 13918 { 13919 s = alloc((unsigned)(prevlen + buflen)); 13920 if (s != NULL) 13921 { 13922 mch_memmove(s, prev, prevlen); 13923 mch_memmove(s + prevlen, buf, buflen); 13924 vim_free(prev); 13925 prev = s; 13926 prevlen += buflen; 13927 } 13928 } 13929 filtd = 0; 13930 } 13931 else 13932 { 13933 mch_memmove(buf, buf + tolist, buflen - tolist); 13934 filtd -= tolist; 13935 } 13936 } 13937 13938 /* 13939 * For a negative line count use only the lines at the end of the file, 13940 * free the rest. 13941 */ 13942 if (maxline < 0) 13943 while (cnt > -maxline) 13944 { 13945 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 13946 --cnt; 13947 } 13948 13949 vim_free(prev); 13950 fclose(fd); 13951 } 13952 13953 #if defined(FEAT_RELTIME) 13954 static int list2proftime __ARGS((typval_T *arg, proftime_T *tm)); 13955 13956 /* 13957 * Convert a List to proftime_T. 13958 * Return FAIL when there is something wrong. 13959 */ 13960 static int 13961 list2proftime(arg, tm) 13962 typval_T *arg; 13963 proftime_T *tm; 13964 { 13965 long n1, n2; 13966 int error = FALSE; 13967 13968 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 13969 || arg->vval.v_list->lv_len != 2) 13970 return FAIL; 13971 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 13972 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 13973 # ifdef WIN3264 13974 tm->HighPart = n1; 13975 tm->LowPart = n2; 13976 # else 13977 tm->tv_sec = n1; 13978 tm->tv_usec = n2; 13979 # endif 13980 return error ? FAIL : OK; 13981 } 13982 #endif /* FEAT_RELTIME */ 13983 13984 /* 13985 * "reltime()" function 13986 */ 13987 static void 13988 f_reltime(argvars, rettv) 13989 typval_T *argvars; 13990 typval_T *rettv; 13991 { 13992 #ifdef FEAT_RELTIME 13993 proftime_T res; 13994 proftime_T start; 13995 13996 if (argvars[0].v_type == VAR_UNKNOWN) 13997 { 13998 /* No arguments: get current time. */ 13999 profile_start(&res); 14000 } 14001 else if (argvars[1].v_type == VAR_UNKNOWN) 14002 { 14003 if (list2proftime(&argvars[0], &res) == FAIL) 14004 return; 14005 profile_end(&res); 14006 } 14007 else 14008 { 14009 /* Two arguments: compute the difference. */ 14010 if (list2proftime(&argvars[0], &start) == FAIL 14011 || list2proftime(&argvars[1], &res) == FAIL) 14012 return; 14013 profile_sub(&res, &start); 14014 } 14015 14016 if (rettv_list_alloc(rettv) == OK) 14017 { 14018 long n1, n2; 14019 14020 # ifdef WIN3264 14021 n1 = res.HighPart; 14022 n2 = res.LowPart; 14023 # else 14024 n1 = res.tv_sec; 14025 n2 = res.tv_usec; 14026 # endif 14027 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 14028 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 14029 } 14030 #endif 14031 } 14032 14033 /* 14034 * "reltimestr()" function 14035 */ 14036 static void 14037 f_reltimestr(argvars, rettv) 14038 typval_T *argvars; 14039 typval_T *rettv; 14040 { 14041 #ifdef FEAT_RELTIME 14042 proftime_T tm; 14043 #endif 14044 14045 rettv->v_type = VAR_STRING; 14046 rettv->vval.v_string = NULL; 14047 #ifdef FEAT_RELTIME 14048 if (list2proftime(&argvars[0], &tm) == OK) 14049 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 14050 #endif 14051 } 14052 14053 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 14054 static void make_connection __ARGS((void)); 14055 static int check_connection __ARGS((void)); 14056 14057 static void 14058 make_connection() 14059 { 14060 if (X_DISPLAY == NULL 14061 # ifdef FEAT_GUI 14062 && !gui.in_use 14063 # endif 14064 ) 14065 { 14066 x_force_connect = TRUE; 14067 setup_term_clip(); 14068 x_force_connect = FALSE; 14069 } 14070 } 14071 14072 static int 14073 check_connection() 14074 { 14075 make_connection(); 14076 if (X_DISPLAY == NULL) 14077 { 14078 EMSG(_("E240: No connection to Vim server")); 14079 return FAIL; 14080 } 14081 return OK; 14082 } 14083 #endif 14084 14085 #ifdef FEAT_CLIENTSERVER 14086 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 14087 14088 static void 14089 remote_common(argvars, rettv, expr) 14090 typval_T *argvars; 14091 typval_T *rettv; 14092 int expr; 14093 { 14094 char_u *server_name; 14095 char_u *keys; 14096 char_u *r = NULL; 14097 char_u buf[NUMBUFLEN]; 14098 # ifdef WIN32 14099 HWND w; 14100 # else 14101 Window w; 14102 # endif 14103 14104 if (check_restricted() || check_secure()) 14105 return; 14106 14107 # ifdef FEAT_X11 14108 if (check_connection() == FAIL) 14109 return; 14110 # endif 14111 14112 server_name = get_tv_string_chk(&argvars[0]); 14113 if (server_name == NULL) 14114 return; /* type error; errmsg already given */ 14115 keys = get_tv_string_buf(&argvars[1], buf); 14116 # ifdef WIN32 14117 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 14118 # else 14119 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 14120 < 0) 14121 # endif 14122 { 14123 if (r != NULL) 14124 EMSG(r); /* sending worked but evaluation failed */ 14125 else 14126 EMSG2(_("E241: Unable to send to %s"), server_name); 14127 return; 14128 } 14129 14130 rettv->vval.v_string = r; 14131 14132 if (argvars[2].v_type != VAR_UNKNOWN) 14133 { 14134 dictitem_T v; 14135 char_u str[30]; 14136 char_u *idvar; 14137 14138 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 14139 v.di_tv.v_type = VAR_STRING; 14140 v.di_tv.vval.v_string = vim_strsave(str); 14141 idvar = get_tv_string_chk(&argvars[2]); 14142 if (idvar != NULL) 14143 set_var(idvar, &v.di_tv, FALSE); 14144 vim_free(v.di_tv.vval.v_string); 14145 } 14146 } 14147 #endif 14148 14149 /* 14150 * "remote_expr()" function 14151 */ 14152 static void 14153 f_remote_expr(argvars, rettv) 14154 typval_T *argvars UNUSED; 14155 typval_T *rettv; 14156 { 14157 rettv->v_type = VAR_STRING; 14158 rettv->vval.v_string = NULL; 14159 #ifdef FEAT_CLIENTSERVER 14160 remote_common(argvars, rettv, TRUE); 14161 #endif 14162 } 14163 14164 /* 14165 * "remote_foreground()" function 14166 */ 14167 static void 14168 f_remote_foreground(argvars, rettv) 14169 typval_T *argvars UNUSED; 14170 typval_T *rettv UNUSED; 14171 { 14172 #ifdef FEAT_CLIENTSERVER 14173 # ifdef WIN32 14174 /* On Win32 it's done in this application. */ 14175 { 14176 char_u *server_name = get_tv_string_chk(&argvars[0]); 14177 14178 if (server_name != NULL) 14179 serverForeground(server_name); 14180 } 14181 # else 14182 /* Send a foreground() expression to the server. */ 14183 argvars[1].v_type = VAR_STRING; 14184 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 14185 argvars[2].v_type = VAR_UNKNOWN; 14186 remote_common(argvars, rettv, TRUE); 14187 vim_free(argvars[1].vval.v_string); 14188 # endif 14189 #endif 14190 } 14191 14192 static void 14193 f_remote_peek(argvars, rettv) 14194 typval_T *argvars UNUSED; 14195 typval_T *rettv; 14196 { 14197 #ifdef FEAT_CLIENTSERVER 14198 dictitem_T v; 14199 char_u *s = NULL; 14200 # ifdef WIN32 14201 long_u n = 0; 14202 # endif 14203 char_u *serverid; 14204 14205 if (check_restricted() || check_secure()) 14206 { 14207 rettv->vval.v_number = -1; 14208 return; 14209 } 14210 serverid = get_tv_string_chk(&argvars[0]); 14211 if (serverid == NULL) 14212 { 14213 rettv->vval.v_number = -1; 14214 return; /* type error; errmsg already given */ 14215 } 14216 # ifdef WIN32 14217 sscanf(serverid, SCANF_HEX_LONG_U, &n); 14218 if (n == 0) 14219 rettv->vval.v_number = -1; 14220 else 14221 { 14222 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 14223 rettv->vval.v_number = (s != NULL); 14224 } 14225 # else 14226 if (check_connection() == FAIL) 14227 return; 14228 14229 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 14230 serverStrToWin(serverid), &s); 14231 # endif 14232 14233 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 14234 { 14235 char_u *retvar; 14236 14237 v.di_tv.v_type = VAR_STRING; 14238 v.di_tv.vval.v_string = vim_strsave(s); 14239 retvar = get_tv_string_chk(&argvars[1]); 14240 if (retvar != NULL) 14241 set_var(retvar, &v.di_tv, FALSE); 14242 vim_free(v.di_tv.vval.v_string); 14243 } 14244 #else 14245 rettv->vval.v_number = -1; 14246 #endif 14247 } 14248 14249 static void 14250 f_remote_read(argvars, rettv) 14251 typval_T *argvars UNUSED; 14252 typval_T *rettv; 14253 { 14254 char_u *r = NULL; 14255 14256 #ifdef FEAT_CLIENTSERVER 14257 char_u *serverid = get_tv_string_chk(&argvars[0]); 14258 14259 if (serverid != NULL && !check_restricted() && !check_secure()) 14260 { 14261 # ifdef WIN32 14262 /* The server's HWND is encoded in the 'id' parameter */ 14263 long_u n = 0; 14264 14265 sscanf(serverid, SCANF_HEX_LONG_U, &n); 14266 if (n != 0) 14267 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 14268 if (r == NULL) 14269 # else 14270 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 14271 serverStrToWin(serverid), &r, FALSE) < 0) 14272 # endif 14273 EMSG(_("E277: Unable to read a server reply")); 14274 } 14275 #endif 14276 rettv->v_type = VAR_STRING; 14277 rettv->vval.v_string = r; 14278 } 14279 14280 /* 14281 * "remote_send()" function 14282 */ 14283 static void 14284 f_remote_send(argvars, rettv) 14285 typval_T *argvars UNUSED; 14286 typval_T *rettv; 14287 { 14288 rettv->v_type = VAR_STRING; 14289 rettv->vval.v_string = NULL; 14290 #ifdef FEAT_CLIENTSERVER 14291 remote_common(argvars, rettv, FALSE); 14292 #endif 14293 } 14294 14295 /* 14296 * "remove()" function 14297 */ 14298 static void 14299 f_remove(argvars, rettv) 14300 typval_T *argvars; 14301 typval_T *rettv; 14302 { 14303 list_T *l; 14304 listitem_T *item, *item2; 14305 listitem_T *li; 14306 long idx; 14307 long end; 14308 char_u *key; 14309 dict_T *d; 14310 dictitem_T *di; 14311 14312 if (argvars[0].v_type == VAR_DICT) 14313 { 14314 if (argvars[2].v_type != VAR_UNKNOWN) 14315 EMSG2(_(e_toomanyarg), "remove()"); 14316 else if ((d = argvars[0].vval.v_dict) != NULL 14317 && !tv_check_lock(d->dv_lock, (char_u *)"remove() argument")) 14318 { 14319 key = get_tv_string_chk(&argvars[1]); 14320 if (key != NULL) 14321 { 14322 di = dict_find(d, key, -1); 14323 if (di == NULL) 14324 EMSG2(_(e_dictkey), key); 14325 else 14326 { 14327 *rettv = di->di_tv; 14328 init_tv(&di->di_tv); 14329 dictitem_remove(d, di); 14330 } 14331 } 14332 } 14333 } 14334 else if (argvars[0].v_type != VAR_LIST) 14335 EMSG2(_(e_listdictarg), "remove()"); 14336 else if ((l = argvars[0].vval.v_list) != NULL 14337 && !tv_check_lock(l->lv_lock, (char_u *)"remove() argument")) 14338 { 14339 int error = FALSE; 14340 14341 idx = get_tv_number_chk(&argvars[1], &error); 14342 if (error) 14343 ; /* type error: do nothing, errmsg already given */ 14344 else if ((item = list_find(l, idx)) == NULL) 14345 EMSGN(_(e_listidx), idx); 14346 else 14347 { 14348 if (argvars[2].v_type == VAR_UNKNOWN) 14349 { 14350 /* Remove one item, return its value. */ 14351 list_remove(l, item, item); 14352 *rettv = item->li_tv; 14353 vim_free(item); 14354 } 14355 else 14356 { 14357 /* Remove range of items, return list with values. */ 14358 end = get_tv_number_chk(&argvars[2], &error); 14359 if (error) 14360 ; /* type error: do nothing */ 14361 else if ((item2 = list_find(l, end)) == NULL) 14362 EMSGN(_(e_listidx), end); 14363 else 14364 { 14365 int cnt = 0; 14366 14367 for (li = item; li != NULL; li = li->li_next) 14368 { 14369 ++cnt; 14370 if (li == item2) 14371 break; 14372 } 14373 if (li == NULL) /* didn't find "item2" after "item" */ 14374 EMSG(_(e_invrange)); 14375 else 14376 { 14377 list_remove(l, item, item2); 14378 if (rettv_list_alloc(rettv) == OK) 14379 { 14380 l = rettv->vval.v_list; 14381 l->lv_first = item; 14382 l->lv_last = item2; 14383 item->li_prev = NULL; 14384 item2->li_next = NULL; 14385 l->lv_len = cnt; 14386 } 14387 } 14388 } 14389 } 14390 } 14391 } 14392 } 14393 14394 /* 14395 * "rename({from}, {to})" function 14396 */ 14397 static void 14398 f_rename(argvars, rettv) 14399 typval_T *argvars; 14400 typval_T *rettv; 14401 { 14402 char_u buf[NUMBUFLEN]; 14403 14404 if (check_restricted() || check_secure()) 14405 rettv->vval.v_number = -1; 14406 else 14407 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 14408 get_tv_string_buf(&argvars[1], buf)); 14409 } 14410 14411 /* 14412 * "repeat()" function 14413 */ 14414 static void 14415 f_repeat(argvars, rettv) 14416 typval_T *argvars; 14417 typval_T *rettv; 14418 { 14419 char_u *p; 14420 int n; 14421 int slen; 14422 int len; 14423 char_u *r; 14424 int i; 14425 14426 n = get_tv_number(&argvars[1]); 14427 if (argvars[0].v_type == VAR_LIST) 14428 { 14429 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 14430 while (n-- > 0) 14431 if (list_extend(rettv->vval.v_list, 14432 argvars[0].vval.v_list, NULL) == FAIL) 14433 break; 14434 } 14435 else 14436 { 14437 p = get_tv_string(&argvars[0]); 14438 rettv->v_type = VAR_STRING; 14439 rettv->vval.v_string = NULL; 14440 14441 slen = (int)STRLEN(p); 14442 len = slen * n; 14443 if (len <= 0) 14444 return; 14445 14446 r = alloc(len + 1); 14447 if (r != NULL) 14448 { 14449 for (i = 0; i < n; i++) 14450 mch_memmove(r + i * slen, p, (size_t)slen); 14451 r[len] = NUL; 14452 } 14453 14454 rettv->vval.v_string = r; 14455 } 14456 } 14457 14458 /* 14459 * "resolve()" function 14460 */ 14461 static void 14462 f_resolve(argvars, rettv) 14463 typval_T *argvars; 14464 typval_T *rettv; 14465 { 14466 char_u *p; 14467 14468 p = get_tv_string(&argvars[0]); 14469 #ifdef FEAT_SHORTCUT 14470 { 14471 char_u *v = NULL; 14472 14473 v = mch_resolve_shortcut(p); 14474 if (v != NULL) 14475 rettv->vval.v_string = v; 14476 else 14477 rettv->vval.v_string = vim_strsave(p); 14478 } 14479 #else 14480 # ifdef HAVE_READLINK 14481 { 14482 char_u buf[MAXPATHL + 1]; 14483 char_u *cpy; 14484 int len; 14485 char_u *remain = NULL; 14486 char_u *q; 14487 int is_relative_to_current = FALSE; 14488 int has_trailing_pathsep = FALSE; 14489 int limit = 100; 14490 14491 p = vim_strsave(p); 14492 14493 if (p[0] == '.' && (vim_ispathsep(p[1]) 14494 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 14495 is_relative_to_current = TRUE; 14496 14497 len = STRLEN(p); 14498 if (len > 0 && after_pathsep(p, p + len)) 14499 has_trailing_pathsep = TRUE; 14500 14501 q = getnextcomp(p); 14502 if (*q != NUL) 14503 { 14504 /* Separate the first path component in "p", and keep the 14505 * remainder (beginning with the path separator). */ 14506 remain = vim_strsave(q - 1); 14507 q[-1] = NUL; 14508 } 14509 14510 for (;;) 14511 { 14512 for (;;) 14513 { 14514 len = readlink((char *)p, (char *)buf, MAXPATHL); 14515 if (len <= 0) 14516 break; 14517 buf[len] = NUL; 14518 14519 if (limit-- == 0) 14520 { 14521 vim_free(p); 14522 vim_free(remain); 14523 EMSG(_("E655: Too many symbolic links (cycle?)")); 14524 rettv->vval.v_string = NULL; 14525 goto fail; 14526 } 14527 14528 /* Ensure that the result will have a trailing path separator 14529 * if the argument has one. */ 14530 if (remain == NULL && has_trailing_pathsep) 14531 add_pathsep(buf); 14532 14533 /* Separate the first path component in the link value and 14534 * concatenate the remainders. */ 14535 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 14536 if (*q != NUL) 14537 { 14538 if (remain == NULL) 14539 remain = vim_strsave(q - 1); 14540 else 14541 { 14542 cpy = concat_str(q - 1, remain); 14543 if (cpy != NULL) 14544 { 14545 vim_free(remain); 14546 remain = cpy; 14547 } 14548 } 14549 q[-1] = NUL; 14550 } 14551 14552 q = gettail(p); 14553 if (q > p && *q == NUL) 14554 { 14555 /* Ignore trailing path separator. */ 14556 q[-1] = NUL; 14557 q = gettail(p); 14558 } 14559 if (q > p && !mch_isFullName(buf)) 14560 { 14561 /* symlink is relative to directory of argument */ 14562 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 14563 if (cpy != NULL) 14564 { 14565 STRCPY(cpy, p); 14566 STRCPY(gettail(cpy), buf); 14567 vim_free(p); 14568 p = cpy; 14569 } 14570 } 14571 else 14572 { 14573 vim_free(p); 14574 p = vim_strsave(buf); 14575 } 14576 } 14577 14578 if (remain == NULL) 14579 break; 14580 14581 /* Append the first path component of "remain" to "p". */ 14582 q = getnextcomp(remain + 1); 14583 len = q - remain - (*q != NUL); 14584 cpy = vim_strnsave(p, STRLEN(p) + len); 14585 if (cpy != NULL) 14586 { 14587 STRNCAT(cpy, remain, len); 14588 vim_free(p); 14589 p = cpy; 14590 } 14591 /* Shorten "remain". */ 14592 if (*q != NUL) 14593 STRMOVE(remain, q - 1); 14594 else 14595 { 14596 vim_free(remain); 14597 remain = NULL; 14598 } 14599 } 14600 14601 /* If the result is a relative path name, make it explicitly relative to 14602 * the current directory if and only if the argument had this form. */ 14603 if (!vim_ispathsep(*p)) 14604 { 14605 if (is_relative_to_current 14606 && *p != NUL 14607 && !(p[0] == '.' 14608 && (p[1] == NUL 14609 || vim_ispathsep(p[1]) 14610 || (p[1] == '.' 14611 && (p[2] == NUL 14612 || vim_ispathsep(p[2])))))) 14613 { 14614 /* Prepend "./". */ 14615 cpy = concat_str((char_u *)"./", p); 14616 if (cpy != NULL) 14617 { 14618 vim_free(p); 14619 p = cpy; 14620 } 14621 } 14622 else if (!is_relative_to_current) 14623 { 14624 /* Strip leading "./". */ 14625 q = p; 14626 while (q[0] == '.' && vim_ispathsep(q[1])) 14627 q += 2; 14628 if (q > p) 14629 STRMOVE(p, p + 2); 14630 } 14631 } 14632 14633 /* Ensure that the result will have no trailing path separator 14634 * if the argument had none. But keep "/" or "//". */ 14635 if (!has_trailing_pathsep) 14636 { 14637 q = p + STRLEN(p); 14638 if (after_pathsep(p, q)) 14639 *gettail_sep(p) = NUL; 14640 } 14641 14642 rettv->vval.v_string = p; 14643 } 14644 # else 14645 rettv->vval.v_string = vim_strsave(p); 14646 # endif 14647 #endif 14648 14649 simplify_filename(rettv->vval.v_string); 14650 14651 #ifdef HAVE_READLINK 14652 fail: 14653 #endif 14654 rettv->v_type = VAR_STRING; 14655 } 14656 14657 /* 14658 * "reverse({list})" function 14659 */ 14660 static void 14661 f_reverse(argvars, rettv) 14662 typval_T *argvars; 14663 typval_T *rettv; 14664 { 14665 list_T *l; 14666 listitem_T *li, *ni; 14667 14668 if (argvars[0].v_type != VAR_LIST) 14669 EMSG2(_(e_listarg), "reverse()"); 14670 else if ((l = argvars[0].vval.v_list) != NULL 14671 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 14672 { 14673 li = l->lv_last; 14674 l->lv_first = l->lv_last = NULL; 14675 l->lv_len = 0; 14676 while (li != NULL) 14677 { 14678 ni = li->li_prev; 14679 list_append(l, li); 14680 li = ni; 14681 } 14682 rettv->vval.v_list = l; 14683 rettv->v_type = VAR_LIST; 14684 ++l->lv_refcount; 14685 l->lv_idx = l->lv_len - l->lv_idx - 1; 14686 } 14687 } 14688 14689 #define SP_NOMOVE 0x01 /* don't move cursor */ 14690 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 14691 #define SP_RETCOUNT 0x04 /* return matchcount */ 14692 #define SP_SETPCMARK 0x08 /* set previous context mark */ 14693 #define SP_START 0x10 /* accept match at start position */ 14694 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 14695 #define SP_END 0x40 /* leave cursor at end of match */ 14696 14697 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 14698 14699 /* 14700 * Get flags for a search function. 14701 * Possibly sets "p_ws". 14702 * Returns BACKWARD, FORWARD or zero (for an error). 14703 */ 14704 static int 14705 get_search_arg(varp, flagsp) 14706 typval_T *varp; 14707 int *flagsp; 14708 { 14709 int dir = FORWARD; 14710 char_u *flags; 14711 char_u nbuf[NUMBUFLEN]; 14712 int mask; 14713 14714 if (varp->v_type != VAR_UNKNOWN) 14715 { 14716 flags = get_tv_string_buf_chk(varp, nbuf); 14717 if (flags == NULL) 14718 return 0; /* type error; errmsg already given */ 14719 while (*flags != NUL) 14720 { 14721 switch (*flags) 14722 { 14723 case 'b': dir = BACKWARD; break; 14724 case 'w': p_ws = TRUE; break; 14725 case 'W': p_ws = FALSE; break; 14726 default: mask = 0; 14727 if (flagsp != NULL) 14728 switch (*flags) 14729 { 14730 case 'c': mask = SP_START; break; 14731 case 'e': mask = SP_END; break; 14732 case 'm': mask = SP_RETCOUNT; break; 14733 case 'n': mask = SP_NOMOVE; break; 14734 case 'p': mask = SP_SUBPAT; break; 14735 case 'r': mask = SP_REPEAT; break; 14736 case 's': mask = SP_SETPCMARK; break; 14737 } 14738 if (mask == 0) 14739 { 14740 EMSG2(_(e_invarg2), flags); 14741 dir = 0; 14742 } 14743 else 14744 *flagsp |= mask; 14745 } 14746 if (dir == 0) 14747 break; 14748 ++flags; 14749 } 14750 } 14751 return dir; 14752 } 14753 14754 /* 14755 * Shared by search() and searchpos() functions 14756 */ 14757 static int 14758 search_cmn(argvars, match_pos, flagsp) 14759 typval_T *argvars; 14760 pos_T *match_pos; 14761 int *flagsp; 14762 { 14763 int flags; 14764 char_u *pat; 14765 pos_T pos; 14766 pos_T save_cursor; 14767 int save_p_ws = p_ws; 14768 int dir; 14769 int retval = 0; /* default: FAIL */ 14770 long lnum_stop = 0; 14771 proftime_T tm; 14772 #ifdef FEAT_RELTIME 14773 long time_limit = 0; 14774 #endif 14775 int options = SEARCH_KEEP; 14776 int subpatnum; 14777 14778 pat = get_tv_string(&argvars[0]); 14779 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 14780 if (dir == 0) 14781 goto theend; 14782 flags = *flagsp; 14783 if (flags & SP_START) 14784 options |= SEARCH_START; 14785 if (flags & SP_END) 14786 options |= SEARCH_END; 14787 14788 /* Optional arguments: line number to stop searching and timeout. */ 14789 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) 14790 { 14791 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 14792 if (lnum_stop < 0) 14793 goto theend; 14794 #ifdef FEAT_RELTIME 14795 if (argvars[3].v_type != VAR_UNKNOWN) 14796 { 14797 time_limit = get_tv_number_chk(&argvars[3], NULL); 14798 if (time_limit < 0) 14799 goto theend; 14800 } 14801 #endif 14802 } 14803 14804 #ifdef FEAT_RELTIME 14805 /* Set the time limit, if there is one. */ 14806 profile_setlimit(time_limit, &tm); 14807 #endif 14808 14809 /* 14810 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 14811 * Check to make sure only those flags are set. 14812 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 14813 * flags cannot be set. Check for that condition also. 14814 */ 14815 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 14816 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 14817 { 14818 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 14819 goto theend; 14820 } 14821 14822 pos = save_cursor = curwin->w_cursor; 14823 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 14824 options, RE_SEARCH, (linenr_T)lnum_stop, &tm); 14825 if (subpatnum != FAIL) 14826 { 14827 if (flags & SP_SUBPAT) 14828 retval = subpatnum; 14829 else 14830 retval = pos.lnum; 14831 if (flags & SP_SETPCMARK) 14832 setpcmark(); 14833 curwin->w_cursor = pos; 14834 if (match_pos != NULL) 14835 { 14836 /* Store the match cursor position */ 14837 match_pos->lnum = pos.lnum; 14838 match_pos->col = pos.col + 1; 14839 } 14840 /* "/$" will put the cursor after the end of the line, may need to 14841 * correct that here */ 14842 check_cursor(); 14843 } 14844 14845 /* If 'n' flag is used: restore cursor position. */ 14846 if (flags & SP_NOMOVE) 14847 curwin->w_cursor = save_cursor; 14848 else 14849 curwin->w_set_curswant = TRUE; 14850 theend: 14851 p_ws = save_p_ws; 14852 14853 return retval; 14854 } 14855 14856 #ifdef FEAT_FLOAT 14857 /* 14858 * "round({float})" function 14859 */ 14860 static void 14861 f_round(argvars, rettv) 14862 typval_T *argvars; 14863 typval_T *rettv; 14864 { 14865 float_T f; 14866 14867 rettv->v_type = VAR_FLOAT; 14868 if (get_float_arg(argvars, &f) == OK) 14869 /* round() is not in C90, use ceil() or floor() instead. */ 14870 rettv->vval.v_float = f > 0 ? floor(f + 0.5) : ceil(f - 0.5); 14871 else 14872 rettv->vval.v_float = 0.0; 14873 } 14874 #endif 14875 14876 /* 14877 * "search()" function 14878 */ 14879 static void 14880 f_search(argvars, rettv) 14881 typval_T *argvars; 14882 typval_T *rettv; 14883 { 14884 int flags = 0; 14885 14886 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 14887 } 14888 14889 /* 14890 * "searchdecl()" function 14891 */ 14892 static void 14893 f_searchdecl(argvars, rettv) 14894 typval_T *argvars; 14895 typval_T *rettv; 14896 { 14897 int locally = 1; 14898 int thisblock = 0; 14899 int error = FALSE; 14900 char_u *name; 14901 14902 rettv->vval.v_number = 1; /* default: FAIL */ 14903 14904 name = get_tv_string_chk(&argvars[0]); 14905 if (argvars[1].v_type != VAR_UNKNOWN) 14906 { 14907 locally = get_tv_number_chk(&argvars[1], &error) == 0; 14908 if (!error && argvars[2].v_type != VAR_UNKNOWN) 14909 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 14910 } 14911 if (!error && name != NULL) 14912 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 14913 locally, thisblock, SEARCH_KEEP) == FAIL; 14914 } 14915 14916 /* 14917 * Used by searchpair() and searchpairpos() 14918 */ 14919 static int 14920 searchpair_cmn(argvars, match_pos) 14921 typval_T *argvars; 14922 pos_T *match_pos; 14923 { 14924 char_u *spat, *mpat, *epat; 14925 char_u *skip; 14926 int save_p_ws = p_ws; 14927 int dir; 14928 int flags = 0; 14929 char_u nbuf1[NUMBUFLEN]; 14930 char_u nbuf2[NUMBUFLEN]; 14931 char_u nbuf3[NUMBUFLEN]; 14932 int retval = 0; /* default: FAIL */ 14933 long lnum_stop = 0; 14934 long time_limit = 0; 14935 14936 /* Get the three pattern arguments: start, middle, end. */ 14937 spat = get_tv_string_chk(&argvars[0]); 14938 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 14939 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 14940 if (spat == NULL || mpat == NULL || epat == NULL) 14941 goto theend; /* type error */ 14942 14943 /* Handle the optional fourth argument: flags */ 14944 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 14945 if (dir == 0) 14946 goto theend; 14947 14948 /* Don't accept SP_END or SP_SUBPAT. 14949 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 14950 */ 14951 if ((flags & (SP_END | SP_SUBPAT)) != 0 14952 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 14953 { 14954 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 14955 goto theend; 14956 } 14957 14958 /* Using 'r' implies 'W', otherwise it doesn't work. */ 14959 if (flags & SP_REPEAT) 14960 p_ws = FALSE; 14961 14962 /* Optional fifth argument: skip expression */ 14963 if (argvars[3].v_type == VAR_UNKNOWN 14964 || argvars[4].v_type == VAR_UNKNOWN) 14965 skip = (char_u *)""; 14966 else 14967 { 14968 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 14969 if (argvars[5].v_type != VAR_UNKNOWN) 14970 { 14971 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 14972 if (lnum_stop < 0) 14973 goto theend; 14974 #ifdef FEAT_RELTIME 14975 if (argvars[6].v_type != VAR_UNKNOWN) 14976 { 14977 time_limit = get_tv_number_chk(&argvars[6], NULL); 14978 if (time_limit < 0) 14979 goto theend; 14980 } 14981 #endif 14982 } 14983 } 14984 if (skip == NULL) 14985 goto theend; /* type error */ 14986 14987 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 14988 match_pos, lnum_stop, time_limit); 14989 14990 theend: 14991 p_ws = save_p_ws; 14992 14993 return retval; 14994 } 14995 14996 /* 14997 * "searchpair()" function 14998 */ 14999 static void 15000 f_searchpair(argvars, rettv) 15001 typval_T *argvars; 15002 typval_T *rettv; 15003 { 15004 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 15005 } 15006 15007 /* 15008 * "searchpairpos()" function 15009 */ 15010 static void 15011 f_searchpairpos(argvars, rettv) 15012 typval_T *argvars; 15013 typval_T *rettv; 15014 { 15015 pos_T match_pos; 15016 int lnum = 0; 15017 int col = 0; 15018 15019 if (rettv_list_alloc(rettv) == FAIL) 15020 return; 15021 15022 if (searchpair_cmn(argvars, &match_pos) > 0) 15023 { 15024 lnum = match_pos.lnum; 15025 col = match_pos.col; 15026 } 15027 15028 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 15029 list_append_number(rettv->vval.v_list, (varnumber_T)col); 15030 } 15031 15032 /* 15033 * Search for a start/middle/end thing. 15034 * Used by searchpair(), see its documentation for the details. 15035 * Returns 0 or -1 for no match, 15036 */ 15037 long 15038 do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, 15039 lnum_stop, time_limit) 15040 char_u *spat; /* start pattern */ 15041 char_u *mpat; /* middle pattern */ 15042 char_u *epat; /* end pattern */ 15043 int dir; /* BACKWARD or FORWARD */ 15044 char_u *skip; /* skip expression */ 15045 int flags; /* SP_SETPCMARK and other SP_ values */ 15046 pos_T *match_pos; 15047 linenr_T lnum_stop; /* stop at this line if not zero */ 15048 long time_limit; /* stop after this many msec */ 15049 { 15050 char_u *save_cpo; 15051 char_u *pat, *pat2 = NULL, *pat3 = NULL; 15052 long retval = 0; 15053 pos_T pos; 15054 pos_T firstpos; 15055 pos_T foundpos; 15056 pos_T save_cursor; 15057 pos_T save_pos; 15058 int n; 15059 int r; 15060 int nest = 1; 15061 int err; 15062 int options = SEARCH_KEEP; 15063 proftime_T tm; 15064 15065 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 15066 save_cpo = p_cpo; 15067 p_cpo = empty_option; 15068 15069 #ifdef FEAT_RELTIME 15070 /* Set the time limit, if there is one. */ 15071 profile_setlimit(time_limit, &tm); 15072 #endif 15073 15074 /* Make two search patterns: start/end (pat2, for in nested pairs) and 15075 * start/middle/end (pat3, for the top pair). */ 15076 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 15077 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 15078 if (pat2 == NULL || pat3 == NULL) 15079 goto theend; 15080 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 15081 if (*mpat == NUL) 15082 STRCPY(pat3, pat2); 15083 else 15084 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 15085 spat, epat, mpat); 15086 if (flags & SP_START) 15087 options |= SEARCH_START; 15088 15089 save_cursor = curwin->w_cursor; 15090 pos = curwin->w_cursor; 15091 clearpos(&firstpos); 15092 clearpos(&foundpos); 15093 pat = pat3; 15094 for (;;) 15095 { 15096 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 15097 options, RE_SEARCH, lnum_stop, &tm); 15098 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 15099 /* didn't find it or found the first match again: FAIL */ 15100 break; 15101 15102 if (firstpos.lnum == 0) 15103 firstpos = pos; 15104 if (equalpos(pos, foundpos)) 15105 { 15106 /* Found the same position again. Can happen with a pattern that 15107 * has "\zs" at the end and searching backwards. Advance one 15108 * character and try again. */ 15109 if (dir == BACKWARD) 15110 decl(&pos); 15111 else 15112 incl(&pos); 15113 } 15114 foundpos = pos; 15115 15116 /* clear the start flag to avoid getting stuck here */ 15117 options &= ~SEARCH_START; 15118 15119 /* If the skip pattern matches, ignore this match. */ 15120 if (*skip != NUL) 15121 { 15122 save_pos = curwin->w_cursor; 15123 curwin->w_cursor = pos; 15124 r = eval_to_bool(skip, &err, NULL, FALSE); 15125 curwin->w_cursor = save_pos; 15126 if (err) 15127 { 15128 /* Evaluating {skip} caused an error, break here. */ 15129 curwin->w_cursor = save_cursor; 15130 retval = -1; 15131 break; 15132 } 15133 if (r) 15134 continue; 15135 } 15136 15137 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 15138 { 15139 /* Found end when searching backwards or start when searching 15140 * forward: nested pair. */ 15141 ++nest; 15142 pat = pat2; /* nested, don't search for middle */ 15143 } 15144 else 15145 { 15146 /* Found end when searching forward or start when searching 15147 * backward: end of (nested) pair; or found middle in outer pair. */ 15148 if (--nest == 1) 15149 pat = pat3; /* outer level, search for middle */ 15150 } 15151 15152 if (nest == 0) 15153 { 15154 /* Found the match: return matchcount or line number. */ 15155 if (flags & SP_RETCOUNT) 15156 ++retval; 15157 else 15158 retval = pos.lnum; 15159 if (flags & SP_SETPCMARK) 15160 setpcmark(); 15161 curwin->w_cursor = pos; 15162 if (!(flags & SP_REPEAT)) 15163 break; 15164 nest = 1; /* search for next unmatched */ 15165 } 15166 } 15167 15168 if (match_pos != NULL) 15169 { 15170 /* Store the match cursor position */ 15171 match_pos->lnum = curwin->w_cursor.lnum; 15172 match_pos->col = curwin->w_cursor.col + 1; 15173 } 15174 15175 /* If 'n' flag is used or search failed: restore cursor position. */ 15176 if ((flags & SP_NOMOVE) || retval == 0) 15177 curwin->w_cursor = save_cursor; 15178 15179 theend: 15180 vim_free(pat2); 15181 vim_free(pat3); 15182 if (p_cpo == empty_option) 15183 p_cpo = save_cpo; 15184 else 15185 /* Darn, evaluating the {skip} expression changed the value. */ 15186 free_string_option(save_cpo); 15187 15188 return retval; 15189 } 15190 15191 /* 15192 * "searchpos()" function 15193 */ 15194 static void 15195 f_searchpos(argvars, rettv) 15196 typval_T *argvars; 15197 typval_T *rettv; 15198 { 15199 pos_T match_pos; 15200 int lnum = 0; 15201 int col = 0; 15202 int n; 15203 int flags = 0; 15204 15205 if (rettv_list_alloc(rettv) == FAIL) 15206 return; 15207 15208 n = search_cmn(argvars, &match_pos, &flags); 15209 if (n > 0) 15210 { 15211 lnum = match_pos.lnum; 15212 col = match_pos.col; 15213 } 15214 15215 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 15216 list_append_number(rettv->vval.v_list, (varnumber_T)col); 15217 if (flags & SP_SUBPAT) 15218 list_append_number(rettv->vval.v_list, (varnumber_T)n); 15219 } 15220 15221 15222 static void 15223 f_server2client(argvars, rettv) 15224 typval_T *argvars UNUSED; 15225 typval_T *rettv; 15226 { 15227 #ifdef FEAT_CLIENTSERVER 15228 char_u buf[NUMBUFLEN]; 15229 char_u *server = get_tv_string_chk(&argvars[0]); 15230 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 15231 15232 rettv->vval.v_number = -1; 15233 if (server == NULL || reply == NULL) 15234 return; 15235 if (check_restricted() || check_secure()) 15236 return; 15237 # ifdef FEAT_X11 15238 if (check_connection() == FAIL) 15239 return; 15240 # endif 15241 15242 if (serverSendReply(server, reply) < 0) 15243 { 15244 EMSG(_("E258: Unable to send to client")); 15245 return; 15246 } 15247 rettv->vval.v_number = 0; 15248 #else 15249 rettv->vval.v_number = -1; 15250 #endif 15251 } 15252 15253 static void 15254 f_serverlist(argvars, rettv) 15255 typval_T *argvars UNUSED; 15256 typval_T *rettv; 15257 { 15258 char_u *r = NULL; 15259 15260 #ifdef FEAT_CLIENTSERVER 15261 # ifdef WIN32 15262 r = serverGetVimNames(); 15263 # else 15264 make_connection(); 15265 if (X_DISPLAY != NULL) 15266 r = serverGetVimNames(X_DISPLAY); 15267 # endif 15268 #endif 15269 rettv->v_type = VAR_STRING; 15270 rettv->vval.v_string = r; 15271 } 15272 15273 /* 15274 * "setbufvar()" function 15275 */ 15276 static void 15277 f_setbufvar(argvars, rettv) 15278 typval_T *argvars; 15279 typval_T *rettv UNUSED; 15280 { 15281 buf_T *buf; 15282 aco_save_T aco; 15283 char_u *varname, *bufvarname; 15284 typval_T *varp; 15285 char_u nbuf[NUMBUFLEN]; 15286 15287 if (check_restricted() || check_secure()) 15288 return; 15289 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 15290 varname = get_tv_string_chk(&argvars[1]); 15291 buf = get_buf_tv(&argvars[0]); 15292 varp = &argvars[2]; 15293 15294 if (buf != NULL && varname != NULL && varp != NULL) 15295 { 15296 /* set curbuf to be our buf, temporarily */ 15297 aucmd_prepbuf(&aco, buf); 15298 15299 if (*varname == '&') 15300 { 15301 long numval; 15302 char_u *strval; 15303 int error = FALSE; 15304 15305 ++varname; 15306 numval = get_tv_number_chk(varp, &error); 15307 strval = get_tv_string_buf_chk(varp, nbuf); 15308 if (!error && strval != NULL) 15309 set_option_value(varname, numval, strval, OPT_LOCAL); 15310 } 15311 else 15312 { 15313 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 15314 if (bufvarname != NULL) 15315 { 15316 STRCPY(bufvarname, "b:"); 15317 STRCPY(bufvarname + 2, varname); 15318 set_var(bufvarname, varp, TRUE); 15319 vim_free(bufvarname); 15320 } 15321 } 15322 15323 /* reset notion of buffer */ 15324 aucmd_restbuf(&aco); 15325 } 15326 } 15327 15328 /* 15329 * "setcmdpos()" function 15330 */ 15331 static void 15332 f_setcmdpos(argvars, rettv) 15333 typval_T *argvars; 15334 typval_T *rettv; 15335 { 15336 int pos = (int)get_tv_number(&argvars[0]) - 1; 15337 15338 if (pos >= 0) 15339 rettv->vval.v_number = set_cmdline_pos(pos); 15340 } 15341 15342 /* 15343 * "setline()" function 15344 */ 15345 static void 15346 f_setline(argvars, rettv) 15347 typval_T *argvars; 15348 typval_T *rettv; 15349 { 15350 linenr_T lnum; 15351 char_u *line = NULL; 15352 list_T *l = NULL; 15353 listitem_T *li = NULL; 15354 long added = 0; 15355 linenr_T lcount = curbuf->b_ml.ml_line_count; 15356 15357 lnum = get_tv_lnum(&argvars[0]); 15358 if (argvars[1].v_type == VAR_LIST) 15359 { 15360 l = argvars[1].vval.v_list; 15361 li = l->lv_first; 15362 } 15363 else 15364 line = get_tv_string_chk(&argvars[1]); 15365 15366 /* default result is zero == OK */ 15367 for (;;) 15368 { 15369 if (l != NULL) 15370 { 15371 /* list argument, get next string */ 15372 if (li == NULL) 15373 break; 15374 line = get_tv_string_chk(&li->li_tv); 15375 li = li->li_next; 15376 } 15377 15378 rettv->vval.v_number = 1; /* FAIL */ 15379 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 15380 break; 15381 if (lnum <= curbuf->b_ml.ml_line_count) 15382 { 15383 /* existing line, replace it */ 15384 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 15385 { 15386 changed_bytes(lnum, 0); 15387 if (lnum == curwin->w_cursor.lnum) 15388 check_cursor_col(); 15389 rettv->vval.v_number = 0; /* OK */ 15390 } 15391 } 15392 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 15393 { 15394 /* lnum is one past the last line, append the line */ 15395 ++added; 15396 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 15397 rettv->vval.v_number = 0; /* OK */ 15398 } 15399 15400 if (l == NULL) /* only one string argument */ 15401 break; 15402 ++lnum; 15403 } 15404 15405 if (added > 0) 15406 appended_lines_mark(lcount, added); 15407 } 15408 15409 static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv)); 15410 15411 /* 15412 * Used by "setqflist()" and "setloclist()" functions 15413 */ 15414 static void 15415 set_qf_ll_list(wp, list_arg, action_arg, rettv) 15416 win_T *wp UNUSED; 15417 typval_T *list_arg UNUSED; 15418 typval_T *action_arg UNUSED; 15419 typval_T *rettv; 15420 { 15421 #ifdef FEAT_QUICKFIX 15422 char_u *act; 15423 int action = ' '; 15424 #endif 15425 15426 rettv->vval.v_number = -1; 15427 15428 #ifdef FEAT_QUICKFIX 15429 if (list_arg->v_type != VAR_LIST) 15430 EMSG(_(e_listreq)); 15431 else 15432 { 15433 list_T *l = list_arg->vval.v_list; 15434 15435 if (action_arg->v_type == VAR_STRING) 15436 { 15437 act = get_tv_string_chk(action_arg); 15438 if (act == NULL) 15439 return; /* type error; errmsg already given */ 15440 if (*act == 'a' || *act == 'r') 15441 action = *act; 15442 } 15443 15444 if (l != NULL && set_errorlist(wp, l, action) == OK) 15445 rettv->vval.v_number = 0; 15446 } 15447 #endif 15448 } 15449 15450 /* 15451 * "setloclist()" function 15452 */ 15453 static void 15454 f_setloclist(argvars, rettv) 15455 typval_T *argvars; 15456 typval_T *rettv; 15457 { 15458 win_T *win; 15459 15460 rettv->vval.v_number = -1; 15461 15462 win = find_win_by_nr(&argvars[0], NULL); 15463 if (win != NULL) 15464 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 15465 } 15466 15467 /* 15468 * "setmatches()" function 15469 */ 15470 static void 15471 f_setmatches(argvars, rettv) 15472 typval_T *argvars; 15473 typval_T *rettv; 15474 { 15475 #ifdef FEAT_SEARCH_EXTRA 15476 list_T *l; 15477 listitem_T *li; 15478 dict_T *d; 15479 15480 rettv->vval.v_number = -1; 15481 if (argvars[0].v_type != VAR_LIST) 15482 { 15483 EMSG(_(e_listreq)); 15484 return; 15485 } 15486 if ((l = argvars[0].vval.v_list) != NULL) 15487 { 15488 15489 /* To some extent make sure that we are dealing with a list from 15490 * "getmatches()". */ 15491 li = l->lv_first; 15492 while (li != NULL) 15493 { 15494 if (li->li_tv.v_type != VAR_DICT 15495 || (d = li->li_tv.vval.v_dict) == NULL) 15496 { 15497 EMSG(_(e_invarg)); 15498 return; 15499 } 15500 if (!(dict_find(d, (char_u *)"group", -1) != NULL 15501 && dict_find(d, (char_u *)"pattern", -1) != NULL 15502 && dict_find(d, (char_u *)"priority", -1) != NULL 15503 && dict_find(d, (char_u *)"id", -1) != NULL)) 15504 { 15505 EMSG(_(e_invarg)); 15506 return; 15507 } 15508 li = li->li_next; 15509 } 15510 15511 clear_matches(curwin); 15512 li = l->lv_first; 15513 while (li != NULL) 15514 { 15515 d = li->li_tv.vval.v_dict; 15516 match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE), 15517 get_dict_string(d, (char_u *)"pattern", FALSE), 15518 (int)get_dict_number(d, (char_u *)"priority"), 15519 (int)get_dict_number(d, (char_u *)"id")); 15520 li = li->li_next; 15521 } 15522 rettv->vval.v_number = 0; 15523 } 15524 #endif 15525 } 15526 15527 /* 15528 * "setpos()" function 15529 */ 15530 static void 15531 f_setpos(argvars, rettv) 15532 typval_T *argvars; 15533 typval_T *rettv; 15534 { 15535 pos_T pos; 15536 int fnum; 15537 char_u *name; 15538 15539 rettv->vval.v_number = -1; 15540 name = get_tv_string_chk(argvars); 15541 if (name != NULL) 15542 { 15543 if (list2fpos(&argvars[1], &pos, &fnum) == OK) 15544 { 15545 if (--pos.col < 0) 15546 pos.col = 0; 15547 if (name[0] == '.' && name[1] == NUL) 15548 { 15549 /* set cursor */ 15550 if (fnum == curbuf->b_fnum) 15551 { 15552 curwin->w_cursor = pos; 15553 check_cursor(); 15554 rettv->vval.v_number = 0; 15555 } 15556 else 15557 EMSG(_(e_invarg)); 15558 } 15559 else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) 15560 { 15561 /* set mark */ 15562 if (setmark_pos(name[1], &pos, fnum) == OK) 15563 rettv->vval.v_number = 0; 15564 } 15565 else 15566 EMSG(_(e_invarg)); 15567 } 15568 } 15569 } 15570 15571 /* 15572 * "setqflist()" function 15573 */ 15574 static void 15575 f_setqflist(argvars, rettv) 15576 typval_T *argvars; 15577 typval_T *rettv; 15578 { 15579 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 15580 } 15581 15582 /* 15583 * "setreg()" function 15584 */ 15585 static void 15586 f_setreg(argvars, rettv) 15587 typval_T *argvars; 15588 typval_T *rettv; 15589 { 15590 int regname; 15591 char_u *strregname; 15592 char_u *stropt; 15593 char_u *strval; 15594 int append; 15595 char_u yank_type; 15596 long block_len; 15597 15598 block_len = -1; 15599 yank_type = MAUTO; 15600 append = FALSE; 15601 15602 strregname = get_tv_string_chk(argvars); 15603 rettv->vval.v_number = 1; /* FAIL is default */ 15604 15605 if (strregname == NULL) 15606 return; /* type error; errmsg already given */ 15607 regname = *strregname; 15608 if (regname == 0 || regname == '@') 15609 regname = '"'; 15610 else if (regname == '=') 15611 return; 15612 15613 if (argvars[2].v_type != VAR_UNKNOWN) 15614 { 15615 stropt = get_tv_string_chk(&argvars[2]); 15616 if (stropt == NULL) 15617 return; /* type error */ 15618 for (; *stropt != NUL; ++stropt) 15619 switch (*stropt) 15620 { 15621 case 'a': case 'A': /* append */ 15622 append = TRUE; 15623 break; 15624 case 'v': case 'c': /* character-wise selection */ 15625 yank_type = MCHAR; 15626 break; 15627 case 'V': case 'l': /* line-wise selection */ 15628 yank_type = MLINE; 15629 break; 15630 #ifdef FEAT_VISUAL 15631 case 'b': case Ctrl_V: /* block-wise selection */ 15632 yank_type = MBLOCK; 15633 if (VIM_ISDIGIT(stropt[1])) 15634 { 15635 ++stropt; 15636 block_len = getdigits(&stropt) - 1; 15637 --stropt; 15638 } 15639 break; 15640 #endif 15641 } 15642 } 15643 15644 strval = get_tv_string_chk(&argvars[1]); 15645 if (strval != NULL) 15646 write_reg_contents_ex(regname, strval, -1, 15647 append, yank_type, block_len); 15648 rettv->vval.v_number = 0; 15649 } 15650 15651 /* 15652 * "settabwinvar()" function 15653 */ 15654 static void 15655 f_settabwinvar(argvars, rettv) 15656 typval_T *argvars; 15657 typval_T *rettv; 15658 { 15659 setwinvar(argvars, rettv, 1); 15660 } 15661 15662 /* 15663 * "setwinvar()" function 15664 */ 15665 static void 15666 f_setwinvar(argvars, rettv) 15667 typval_T *argvars; 15668 typval_T *rettv; 15669 { 15670 setwinvar(argvars, rettv, 0); 15671 } 15672 15673 /* 15674 * "setwinvar()" and "settabwinvar()" functions 15675 */ 15676 static void 15677 setwinvar(argvars, rettv, off) 15678 typval_T *argvars; 15679 typval_T *rettv UNUSED; 15680 int off; 15681 { 15682 win_T *win; 15683 #ifdef FEAT_WINDOWS 15684 win_T *save_curwin; 15685 tabpage_T *save_curtab; 15686 #endif 15687 char_u *varname, *winvarname; 15688 typval_T *varp; 15689 char_u nbuf[NUMBUFLEN]; 15690 tabpage_T *tp; 15691 15692 if (check_restricted() || check_secure()) 15693 return; 15694 15695 #ifdef FEAT_WINDOWS 15696 if (off == 1) 15697 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 15698 else 15699 tp = curtab; 15700 #endif 15701 win = find_win_by_nr(&argvars[off], tp); 15702 varname = get_tv_string_chk(&argvars[off + 1]); 15703 varp = &argvars[off + 2]; 15704 15705 if (win != NULL && varname != NULL && varp != NULL) 15706 { 15707 #ifdef FEAT_WINDOWS 15708 /* set curwin to be our win, temporarily */ 15709 save_curwin = curwin; 15710 save_curtab = curtab; 15711 goto_tabpage_tp(tp); 15712 if (!win_valid(win)) 15713 return; 15714 curwin = win; 15715 curbuf = curwin->w_buffer; 15716 #endif 15717 15718 if (*varname == '&') 15719 { 15720 long numval; 15721 char_u *strval; 15722 int error = FALSE; 15723 15724 ++varname; 15725 numval = get_tv_number_chk(varp, &error); 15726 strval = get_tv_string_buf_chk(varp, nbuf); 15727 if (!error && strval != NULL) 15728 set_option_value(varname, numval, strval, OPT_LOCAL); 15729 } 15730 else 15731 { 15732 winvarname = alloc((unsigned)STRLEN(varname) + 3); 15733 if (winvarname != NULL) 15734 { 15735 STRCPY(winvarname, "w:"); 15736 STRCPY(winvarname + 2, varname); 15737 set_var(winvarname, varp, TRUE); 15738 vim_free(winvarname); 15739 } 15740 } 15741 15742 #ifdef FEAT_WINDOWS 15743 /* Restore current tabpage and window, if still valid (autocomands can 15744 * make them invalid). */ 15745 if (valid_tabpage(save_curtab)) 15746 goto_tabpage_tp(save_curtab); 15747 if (win_valid(save_curwin)) 15748 { 15749 curwin = save_curwin; 15750 curbuf = curwin->w_buffer; 15751 } 15752 #endif 15753 } 15754 } 15755 15756 /* 15757 * "shellescape({string})" function 15758 */ 15759 static void 15760 f_shellescape(argvars, rettv) 15761 typval_T *argvars; 15762 typval_T *rettv; 15763 { 15764 rettv->vval.v_string = vim_strsave_shellescape( 15765 get_tv_string(&argvars[0]), non_zero_arg(&argvars[1])); 15766 rettv->v_type = VAR_STRING; 15767 } 15768 15769 /* 15770 * "simplify()" function 15771 */ 15772 static void 15773 f_simplify(argvars, rettv) 15774 typval_T *argvars; 15775 typval_T *rettv; 15776 { 15777 char_u *p; 15778 15779 p = get_tv_string(&argvars[0]); 15780 rettv->vval.v_string = vim_strsave(p); 15781 simplify_filename(rettv->vval.v_string); /* simplify in place */ 15782 rettv->v_type = VAR_STRING; 15783 } 15784 15785 #ifdef FEAT_FLOAT 15786 /* 15787 * "sin()" function 15788 */ 15789 static void 15790 f_sin(argvars, rettv) 15791 typval_T *argvars; 15792 typval_T *rettv; 15793 { 15794 float_T f; 15795 15796 rettv->v_type = VAR_FLOAT; 15797 if (get_float_arg(argvars, &f) == OK) 15798 rettv->vval.v_float = sin(f); 15799 else 15800 rettv->vval.v_float = 0.0; 15801 } 15802 #endif 15803 15804 static int 15805 #ifdef __BORLANDC__ 15806 _RTLENTRYF 15807 #endif 15808 item_compare __ARGS((const void *s1, const void *s2)); 15809 static int 15810 #ifdef __BORLANDC__ 15811 _RTLENTRYF 15812 #endif 15813 item_compare2 __ARGS((const void *s1, const void *s2)); 15814 15815 static int item_compare_ic; 15816 static char_u *item_compare_func; 15817 static int item_compare_func_err; 15818 #define ITEM_COMPARE_FAIL 999 15819 15820 /* 15821 * Compare functions for f_sort() below. 15822 */ 15823 static int 15824 #ifdef __BORLANDC__ 15825 _RTLENTRYF 15826 #endif 15827 item_compare(s1, s2) 15828 const void *s1; 15829 const void *s2; 15830 { 15831 char_u *p1, *p2; 15832 char_u *tofree1, *tofree2; 15833 int res; 15834 char_u numbuf1[NUMBUFLEN]; 15835 char_u numbuf2[NUMBUFLEN]; 15836 15837 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0); 15838 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0); 15839 if (p1 == NULL) 15840 p1 = (char_u *)""; 15841 if (p2 == NULL) 15842 p2 = (char_u *)""; 15843 if (item_compare_ic) 15844 res = STRICMP(p1, p2); 15845 else 15846 res = STRCMP(p1, p2); 15847 vim_free(tofree1); 15848 vim_free(tofree2); 15849 return res; 15850 } 15851 15852 static int 15853 #ifdef __BORLANDC__ 15854 _RTLENTRYF 15855 #endif 15856 item_compare2(s1, s2) 15857 const void *s1; 15858 const void *s2; 15859 { 15860 int res; 15861 typval_T rettv; 15862 typval_T argv[3]; 15863 int dummy; 15864 15865 /* shortcut after failure in previous call; compare all items equal */ 15866 if (item_compare_func_err) 15867 return 0; 15868 15869 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 15870 * in the copy without changing the original list items. */ 15871 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 15872 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 15873 15874 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 15875 res = call_func(item_compare_func, (int)STRLEN(item_compare_func), 15876 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 15877 clear_tv(&argv[0]); 15878 clear_tv(&argv[1]); 15879 15880 if (res == FAIL) 15881 res = ITEM_COMPARE_FAIL; 15882 else 15883 res = get_tv_number_chk(&rettv, &item_compare_func_err); 15884 if (item_compare_func_err) 15885 res = ITEM_COMPARE_FAIL; /* return value has wrong type */ 15886 clear_tv(&rettv); 15887 return res; 15888 } 15889 15890 /* 15891 * "sort({list})" function 15892 */ 15893 static void 15894 f_sort(argvars, rettv) 15895 typval_T *argvars; 15896 typval_T *rettv; 15897 { 15898 list_T *l; 15899 listitem_T *li; 15900 listitem_T **ptrs; 15901 long len; 15902 long i; 15903 15904 if (argvars[0].v_type != VAR_LIST) 15905 EMSG2(_(e_listarg), "sort()"); 15906 else 15907 { 15908 l = argvars[0].vval.v_list; 15909 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 15910 return; 15911 rettv->vval.v_list = l; 15912 rettv->v_type = VAR_LIST; 15913 ++l->lv_refcount; 15914 15915 len = list_len(l); 15916 if (len <= 1) 15917 return; /* short list sorts pretty quickly */ 15918 15919 item_compare_ic = FALSE; 15920 item_compare_func = NULL; 15921 if (argvars[1].v_type != VAR_UNKNOWN) 15922 { 15923 if (argvars[1].v_type == VAR_FUNC) 15924 item_compare_func = argvars[1].vval.v_string; 15925 else 15926 { 15927 int error = FALSE; 15928 15929 i = get_tv_number_chk(&argvars[1], &error); 15930 if (error) 15931 return; /* type error; errmsg already given */ 15932 if (i == 1) 15933 item_compare_ic = TRUE; 15934 else 15935 item_compare_func = get_tv_string(&argvars[1]); 15936 } 15937 } 15938 15939 /* Make an array with each entry pointing to an item in the List. */ 15940 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 15941 if (ptrs == NULL) 15942 return; 15943 i = 0; 15944 for (li = l->lv_first; li != NULL; li = li->li_next) 15945 ptrs[i++] = li; 15946 15947 item_compare_func_err = FALSE; 15948 /* test the compare function */ 15949 if (item_compare_func != NULL 15950 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 15951 == ITEM_COMPARE_FAIL) 15952 EMSG(_("E702: Sort compare function failed")); 15953 else 15954 { 15955 /* Sort the array with item pointers. */ 15956 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 15957 item_compare_func == NULL ? item_compare : item_compare2); 15958 15959 if (!item_compare_func_err) 15960 { 15961 /* Clear the List and append the items in the sorted order. */ 15962 l->lv_first = l->lv_last = l->lv_idx_item = NULL; 15963 l->lv_len = 0; 15964 for (i = 0; i < len; ++i) 15965 list_append(l, ptrs[i]); 15966 } 15967 } 15968 15969 vim_free(ptrs); 15970 } 15971 } 15972 15973 /* 15974 * "soundfold({word})" function 15975 */ 15976 static void 15977 f_soundfold(argvars, rettv) 15978 typval_T *argvars; 15979 typval_T *rettv; 15980 { 15981 char_u *s; 15982 15983 rettv->v_type = VAR_STRING; 15984 s = get_tv_string(&argvars[0]); 15985 #ifdef FEAT_SPELL 15986 rettv->vval.v_string = eval_soundfold(s); 15987 #else 15988 rettv->vval.v_string = vim_strsave(s); 15989 #endif 15990 } 15991 15992 /* 15993 * "spellbadword()" function 15994 */ 15995 static void 15996 f_spellbadword(argvars, rettv) 15997 typval_T *argvars UNUSED; 15998 typval_T *rettv; 15999 { 16000 char_u *word = (char_u *)""; 16001 hlf_T attr = HLF_COUNT; 16002 int len = 0; 16003 16004 if (rettv_list_alloc(rettv) == FAIL) 16005 return; 16006 16007 #ifdef FEAT_SPELL 16008 if (argvars[0].v_type == VAR_UNKNOWN) 16009 { 16010 /* Find the start and length of the badly spelled word. */ 16011 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 16012 if (len != 0) 16013 word = ml_get_cursor(); 16014 } 16015 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 16016 { 16017 char_u *str = get_tv_string_chk(&argvars[0]); 16018 int capcol = -1; 16019 16020 if (str != NULL) 16021 { 16022 /* Check the argument for spelling. */ 16023 while (*str != NUL) 16024 { 16025 len = spell_check(curwin, str, &attr, &capcol, FALSE); 16026 if (attr != HLF_COUNT) 16027 { 16028 word = str; 16029 break; 16030 } 16031 str += len; 16032 } 16033 } 16034 } 16035 #endif 16036 16037 list_append_string(rettv->vval.v_list, word, len); 16038 list_append_string(rettv->vval.v_list, (char_u *)( 16039 attr == HLF_SPB ? "bad" : 16040 attr == HLF_SPR ? "rare" : 16041 attr == HLF_SPL ? "local" : 16042 attr == HLF_SPC ? "caps" : 16043 ""), -1); 16044 } 16045 16046 /* 16047 * "spellsuggest()" function 16048 */ 16049 static void 16050 f_spellsuggest(argvars, rettv) 16051 typval_T *argvars UNUSED; 16052 typval_T *rettv; 16053 { 16054 #ifdef FEAT_SPELL 16055 char_u *str; 16056 int typeerr = FALSE; 16057 int maxcount; 16058 garray_T ga; 16059 int i; 16060 listitem_T *li; 16061 int need_capital = FALSE; 16062 #endif 16063 16064 if (rettv_list_alloc(rettv) == FAIL) 16065 return; 16066 16067 #ifdef FEAT_SPELL 16068 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 16069 { 16070 str = get_tv_string(&argvars[0]); 16071 if (argvars[1].v_type != VAR_UNKNOWN) 16072 { 16073 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 16074 if (maxcount <= 0) 16075 return; 16076 if (argvars[2].v_type != VAR_UNKNOWN) 16077 { 16078 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 16079 if (typeerr) 16080 return; 16081 } 16082 } 16083 else 16084 maxcount = 25; 16085 16086 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 16087 16088 for (i = 0; i < ga.ga_len; ++i) 16089 { 16090 str = ((char_u **)ga.ga_data)[i]; 16091 16092 li = listitem_alloc(); 16093 if (li == NULL) 16094 vim_free(str); 16095 else 16096 { 16097 li->li_tv.v_type = VAR_STRING; 16098 li->li_tv.v_lock = 0; 16099 li->li_tv.vval.v_string = str; 16100 list_append(rettv->vval.v_list, li); 16101 } 16102 } 16103 ga_clear(&ga); 16104 } 16105 #endif 16106 } 16107 16108 static void 16109 f_split(argvars, rettv) 16110 typval_T *argvars; 16111 typval_T *rettv; 16112 { 16113 char_u *str; 16114 char_u *end; 16115 char_u *pat = NULL; 16116 regmatch_T regmatch; 16117 char_u patbuf[NUMBUFLEN]; 16118 char_u *save_cpo; 16119 int match; 16120 colnr_T col = 0; 16121 int keepempty = FALSE; 16122 int typeerr = FALSE; 16123 16124 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 16125 save_cpo = p_cpo; 16126 p_cpo = (char_u *)""; 16127 16128 str = get_tv_string(&argvars[0]); 16129 if (argvars[1].v_type != VAR_UNKNOWN) 16130 { 16131 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 16132 if (pat == NULL) 16133 typeerr = TRUE; 16134 if (argvars[2].v_type != VAR_UNKNOWN) 16135 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 16136 } 16137 if (pat == NULL || *pat == NUL) 16138 pat = (char_u *)"[\\x01- ]\\+"; 16139 16140 if (rettv_list_alloc(rettv) == FAIL) 16141 return; 16142 if (typeerr) 16143 return; 16144 16145 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 16146 if (regmatch.regprog != NULL) 16147 { 16148 regmatch.rm_ic = FALSE; 16149 while (*str != NUL || keepempty) 16150 { 16151 if (*str == NUL) 16152 match = FALSE; /* empty item at the end */ 16153 else 16154 match = vim_regexec_nl(®match, str, col); 16155 if (match) 16156 end = regmatch.startp[0]; 16157 else 16158 end = str + STRLEN(str); 16159 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 16160 && *str != NUL && match && end < regmatch.endp[0])) 16161 { 16162 if (list_append_string(rettv->vval.v_list, str, 16163 (int)(end - str)) == FAIL) 16164 break; 16165 } 16166 if (!match) 16167 break; 16168 /* Advance to just after the match. */ 16169 if (regmatch.endp[0] > str) 16170 col = 0; 16171 else 16172 { 16173 /* Don't get stuck at the same match. */ 16174 #ifdef FEAT_MBYTE 16175 col = (*mb_ptr2len)(regmatch.endp[0]); 16176 #else 16177 col = 1; 16178 #endif 16179 } 16180 str = regmatch.endp[0]; 16181 } 16182 16183 vim_free(regmatch.regprog); 16184 } 16185 16186 p_cpo = save_cpo; 16187 } 16188 16189 #ifdef FEAT_FLOAT 16190 /* 16191 * "sqrt()" function 16192 */ 16193 static void 16194 f_sqrt(argvars, rettv) 16195 typval_T *argvars; 16196 typval_T *rettv; 16197 { 16198 float_T f; 16199 16200 rettv->v_type = VAR_FLOAT; 16201 if (get_float_arg(argvars, &f) == OK) 16202 rettv->vval.v_float = sqrt(f); 16203 else 16204 rettv->vval.v_float = 0.0; 16205 } 16206 16207 /* 16208 * "str2float()" function 16209 */ 16210 static void 16211 f_str2float(argvars, rettv) 16212 typval_T *argvars; 16213 typval_T *rettv; 16214 { 16215 char_u *p = skipwhite(get_tv_string(&argvars[0])); 16216 16217 if (*p == '+') 16218 p = skipwhite(p + 1); 16219 (void)string2float(p, &rettv->vval.v_float); 16220 rettv->v_type = VAR_FLOAT; 16221 } 16222 #endif 16223 16224 /* 16225 * "str2nr()" function 16226 */ 16227 static void 16228 f_str2nr(argvars, rettv) 16229 typval_T *argvars; 16230 typval_T *rettv; 16231 { 16232 int base = 10; 16233 char_u *p; 16234 long n; 16235 16236 if (argvars[1].v_type != VAR_UNKNOWN) 16237 { 16238 base = get_tv_number(&argvars[1]); 16239 if (base != 8 && base != 10 && base != 16) 16240 { 16241 EMSG(_(e_invarg)); 16242 return; 16243 } 16244 } 16245 16246 p = skipwhite(get_tv_string(&argvars[0])); 16247 if (*p == '+') 16248 p = skipwhite(p + 1); 16249 vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL); 16250 rettv->vval.v_number = n; 16251 } 16252 16253 #ifdef HAVE_STRFTIME 16254 /* 16255 * "strftime({format}[, {time}])" function 16256 */ 16257 static void 16258 f_strftime(argvars, rettv) 16259 typval_T *argvars; 16260 typval_T *rettv; 16261 { 16262 char_u result_buf[256]; 16263 struct tm *curtime; 16264 time_t seconds; 16265 char_u *p; 16266 16267 rettv->v_type = VAR_STRING; 16268 16269 p = get_tv_string(&argvars[0]); 16270 if (argvars[1].v_type == VAR_UNKNOWN) 16271 seconds = time(NULL); 16272 else 16273 seconds = (time_t)get_tv_number(&argvars[1]); 16274 curtime = localtime(&seconds); 16275 /* MSVC returns NULL for an invalid value of seconds. */ 16276 if (curtime == NULL) 16277 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 16278 else 16279 { 16280 # ifdef FEAT_MBYTE 16281 vimconv_T conv; 16282 char_u *enc; 16283 16284 conv.vc_type = CONV_NONE; 16285 enc = enc_locale(); 16286 convert_setup(&conv, p_enc, enc); 16287 if (conv.vc_type != CONV_NONE) 16288 p = string_convert(&conv, p, NULL); 16289 # endif 16290 if (p != NULL) 16291 (void)strftime((char *)result_buf, sizeof(result_buf), 16292 (char *)p, curtime); 16293 else 16294 result_buf[0] = NUL; 16295 16296 # ifdef FEAT_MBYTE 16297 if (conv.vc_type != CONV_NONE) 16298 vim_free(p); 16299 convert_setup(&conv, enc, p_enc); 16300 if (conv.vc_type != CONV_NONE) 16301 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 16302 else 16303 # endif 16304 rettv->vval.v_string = vim_strsave(result_buf); 16305 16306 # ifdef FEAT_MBYTE 16307 /* Release conversion descriptors */ 16308 convert_setup(&conv, NULL, NULL); 16309 vim_free(enc); 16310 # endif 16311 } 16312 } 16313 #endif 16314 16315 /* 16316 * "stridx()" function 16317 */ 16318 static void 16319 f_stridx(argvars, rettv) 16320 typval_T *argvars; 16321 typval_T *rettv; 16322 { 16323 char_u buf[NUMBUFLEN]; 16324 char_u *needle; 16325 char_u *haystack; 16326 char_u *save_haystack; 16327 char_u *pos; 16328 int start_idx; 16329 16330 needle = get_tv_string_chk(&argvars[1]); 16331 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 16332 rettv->vval.v_number = -1; 16333 if (needle == NULL || haystack == NULL) 16334 return; /* type error; errmsg already given */ 16335 16336 if (argvars[2].v_type != VAR_UNKNOWN) 16337 { 16338 int error = FALSE; 16339 16340 start_idx = get_tv_number_chk(&argvars[2], &error); 16341 if (error || start_idx >= (int)STRLEN(haystack)) 16342 return; 16343 if (start_idx >= 0) 16344 haystack += start_idx; 16345 } 16346 16347 pos = (char_u *)strstr((char *)haystack, (char *)needle); 16348 if (pos != NULL) 16349 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 16350 } 16351 16352 /* 16353 * "string()" function 16354 */ 16355 static void 16356 f_string(argvars, rettv) 16357 typval_T *argvars; 16358 typval_T *rettv; 16359 { 16360 char_u *tofree; 16361 char_u numbuf[NUMBUFLEN]; 16362 16363 rettv->v_type = VAR_STRING; 16364 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 16365 /* Make a copy if we have a value but it's not in allocated memory. */ 16366 if (rettv->vval.v_string != NULL && tofree == NULL) 16367 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 16368 } 16369 16370 /* 16371 * "strlen()" function 16372 */ 16373 static void 16374 f_strlen(argvars, rettv) 16375 typval_T *argvars; 16376 typval_T *rettv; 16377 { 16378 rettv->vval.v_number = (varnumber_T)(STRLEN( 16379 get_tv_string(&argvars[0]))); 16380 } 16381 16382 /* 16383 * "strpart()" function 16384 */ 16385 static void 16386 f_strpart(argvars, rettv) 16387 typval_T *argvars; 16388 typval_T *rettv; 16389 { 16390 char_u *p; 16391 int n; 16392 int len; 16393 int slen; 16394 int error = FALSE; 16395 16396 p = get_tv_string(&argvars[0]); 16397 slen = (int)STRLEN(p); 16398 16399 n = get_tv_number_chk(&argvars[1], &error); 16400 if (error) 16401 len = 0; 16402 else if (argvars[2].v_type != VAR_UNKNOWN) 16403 len = get_tv_number(&argvars[2]); 16404 else 16405 len = slen - n; /* default len: all bytes that are available. */ 16406 16407 /* 16408 * Only return the overlap between the specified part and the actual 16409 * string. 16410 */ 16411 if (n < 0) 16412 { 16413 len += n; 16414 n = 0; 16415 } 16416 else if (n > slen) 16417 n = slen; 16418 if (len < 0) 16419 len = 0; 16420 else if (n + len > slen) 16421 len = slen - n; 16422 16423 rettv->v_type = VAR_STRING; 16424 rettv->vval.v_string = vim_strnsave(p + n, len); 16425 } 16426 16427 /* 16428 * "strridx()" function 16429 */ 16430 static void 16431 f_strridx(argvars, rettv) 16432 typval_T *argvars; 16433 typval_T *rettv; 16434 { 16435 char_u buf[NUMBUFLEN]; 16436 char_u *needle; 16437 char_u *haystack; 16438 char_u *rest; 16439 char_u *lastmatch = NULL; 16440 int haystack_len, end_idx; 16441 16442 needle = get_tv_string_chk(&argvars[1]); 16443 haystack = get_tv_string_buf_chk(&argvars[0], buf); 16444 16445 rettv->vval.v_number = -1; 16446 if (needle == NULL || haystack == NULL) 16447 return; /* type error; errmsg already given */ 16448 16449 haystack_len = (int)STRLEN(haystack); 16450 if (argvars[2].v_type != VAR_UNKNOWN) 16451 { 16452 /* Third argument: upper limit for index */ 16453 end_idx = get_tv_number_chk(&argvars[2], NULL); 16454 if (end_idx < 0) 16455 return; /* can never find a match */ 16456 } 16457 else 16458 end_idx = haystack_len; 16459 16460 if (*needle == NUL) 16461 { 16462 /* Empty string matches past the end. */ 16463 lastmatch = haystack + end_idx; 16464 } 16465 else 16466 { 16467 for (rest = haystack; *rest != '\0'; ++rest) 16468 { 16469 rest = (char_u *)strstr((char *)rest, (char *)needle); 16470 if (rest == NULL || rest > haystack + end_idx) 16471 break; 16472 lastmatch = rest; 16473 } 16474 } 16475 16476 if (lastmatch == NULL) 16477 rettv->vval.v_number = -1; 16478 else 16479 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 16480 } 16481 16482 /* 16483 * "strtrans()" function 16484 */ 16485 static void 16486 f_strtrans(argvars, rettv) 16487 typval_T *argvars; 16488 typval_T *rettv; 16489 { 16490 rettv->v_type = VAR_STRING; 16491 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 16492 } 16493 16494 /* 16495 * "submatch()" function 16496 */ 16497 static void 16498 f_submatch(argvars, rettv) 16499 typval_T *argvars; 16500 typval_T *rettv; 16501 { 16502 rettv->v_type = VAR_STRING; 16503 rettv->vval.v_string = 16504 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 16505 } 16506 16507 /* 16508 * "substitute()" function 16509 */ 16510 static void 16511 f_substitute(argvars, rettv) 16512 typval_T *argvars; 16513 typval_T *rettv; 16514 { 16515 char_u patbuf[NUMBUFLEN]; 16516 char_u subbuf[NUMBUFLEN]; 16517 char_u flagsbuf[NUMBUFLEN]; 16518 16519 char_u *str = get_tv_string_chk(&argvars[0]); 16520 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 16521 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 16522 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 16523 16524 rettv->v_type = VAR_STRING; 16525 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 16526 rettv->vval.v_string = NULL; 16527 else 16528 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 16529 } 16530 16531 /* 16532 * "synID(lnum, col, trans)" function 16533 */ 16534 static void 16535 f_synID(argvars, rettv) 16536 typval_T *argvars UNUSED; 16537 typval_T *rettv; 16538 { 16539 int id = 0; 16540 #ifdef FEAT_SYN_HL 16541 long lnum; 16542 long col; 16543 int trans; 16544 int transerr = FALSE; 16545 16546 lnum = get_tv_lnum(argvars); /* -1 on type error */ 16547 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 16548 trans = get_tv_number_chk(&argvars[2], &transerr); 16549 16550 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 16551 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 16552 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE); 16553 #endif 16554 16555 rettv->vval.v_number = id; 16556 } 16557 16558 /* 16559 * "synIDattr(id, what [, mode])" function 16560 */ 16561 static void 16562 f_synIDattr(argvars, rettv) 16563 typval_T *argvars UNUSED; 16564 typval_T *rettv; 16565 { 16566 char_u *p = NULL; 16567 #ifdef FEAT_SYN_HL 16568 int id; 16569 char_u *what; 16570 char_u *mode; 16571 char_u modebuf[NUMBUFLEN]; 16572 int modec; 16573 16574 id = get_tv_number(&argvars[0]); 16575 what = get_tv_string(&argvars[1]); 16576 if (argvars[2].v_type != VAR_UNKNOWN) 16577 { 16578 mode = get_tv_string_buf(&argvars[2], modebuf); 16579 modec = TOLOWER_ASC(mode[0]); 16580 if (modec != 't' && modec != 'c' 16581 #ifdef FEAT_GUI 16582 && modec != 'g' 16583 #endif 16584 ) 16585 modec = 0; /* replace invalid with current */ 16586 } 16587 else 16588 { 16589 #ifdef FEAT_GUI 16590 if (gui.in_use) 16591 modec = 'g'; 16592 else 16593 #endif 16594 if (t_colors > 1) 16595 modec = 'c'; 16596 else 16597 modec = 't'; 16598 } 16599 16600 16601 switch (TOLOWER_ASC(what[0])) 16602 { 16603 case 'b': 16604 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 16605 p = highlight_color(id, what, modec); 16606 else /* bold */ 16607 p = highlight_has_attr(id, HL_BOLD, modec); 16608 break; 16609 16610 case 'f': /* fg[#] */ 16611 p = highlight_color(id, what, modec); 16612 break; 16613 16614 case 'i': 16615 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 16616 p = highlight_has_attr(id, HL_INVERSE, modec); 16617 else /* italic */ 16618 p = highlight_has_attr(id, HL_ITALIC, modec); 16619 break; 16620 16621 case 'n': /* name */ 16622 p = get_highlight_name(NULL, id - 1); 16623 break; 16624 16625 case 'r': /* reverse */ 16626 p = highlight_has_attr(id, HL_INVERSE, modec); 16627 break; 16628 16629 case 's': 16630 if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */ 16631 p = highlight_color(id, what, modec); 16632 else /* standout */ 16633 p = highlight_has_attr(id, HL_STANDOUT, modec); 16634 break; 16635 16636 case 'u': 16637 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 16638 /* underline */ 16639 p = highlight_has_attr(id, HL_UNDERLINE, modec); 16640 else 16641 /* undercurl */ 16642 p = highlight_has_attr(id, HL_UNDERCURL, modec); 16643 break; 16644 } 16645 16646 if (p != NULL) 16647 p = vim_strsave(p); 16648 #endif 16649 rettv->v_type = VAR_STRING; 16650 rettv->vval.v_string = p; 16651 } 16652 16653 /* 16654 * "synIDtrans(id)" function 16655 */ 16656 static void 16657 f_synIDtrans(argvars, rettv) 16658 typval_T *argvars UNUSED; 16659 typval_T *rettv; 16660 { 16661 int id; 16662 16663 #ifdef FEAT_SYN_HL 16664 id = get_tv_number(&argvars[0]); 16665 16666 if (id > 0) 16667 id = syn_get_final_id(id); 16668 else 16669 #endif 16670 id = 0; 16671 16672 rettv->vval.v_number = id; 16673 } 16674 16675 /* 16676 * "synstack(lnum, col)" function 16677 */ 16678 static void 16679 f_synstack(argvars, rettv) 16680 typval_T *argvars UNUSED; 16681 typval_T *rettv; 16682 { 16683 #ifdef FEAT_SYN_HL 16684 long lnum; 16685 long col; 16686 int i; 16687 int id; 16688 #endif 16689 16690 rettv->v_type = VAR_LIST; 16691 rettv->vval.v_list = NULL; 16692 16693 #ifdef FEAT_SYN_HL 16694 lnum = get_tv_lnum(argvars); /* -1 on type error */ 16695 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 16696 16697 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 16698 && col >= 0 && (col == 0 || col < (long)STRLEN(ml_get(lnum))) 16699 && rettv_list_alloc(rettv) != FAIL) 16700 { 16701 (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE); 16702 for (i = 0; ; ++i) 16703 { 16704 id = syn_get_stack_item(i); 16705 if (id < 0) 16706 break; 16707 if (list_append_number(rettv->vval.v_list, id) == FAIL) 16708 break; 16709 } 16710 } 16711 #endif 16712 } 16713 16714 /* 16715 * "system()" function 16716 */ 16717 static void 16718 f_system(argvars, rettv) 16719 typval_T *argvars; 16720 typval_T *rettv; 16721 { 16722 char_u *res = NULL; 16723 char_u *p; 16724 char_u *infile = NULL; 16725 char_u buf[NUMBUFLEN]; 16726 int err = FALSE; 16727 FILE *fd; 16728 16729 if (check_restricted() || check_secure()) 16730 goto done; 16731 16732 if (argvars[1].v_type != VAR_UNKNOWN) 16733 { 16734 /* 16735 * Write the string to a temp file, to be used for input of the shell 16736 * command. 16737 */ 16738 if ((infile = vim_tempname('i')) == NULL) 16739 { 16740 EMSG(_(e_notmp)); 16741 goto done; 16742 } 16743 16744 fd = mch_fopen((char *)infile, WRITEBIN); 16745 if (fd == NULL) 16746 { 16747 EMSG2(_(e_notopen), infile); 16748 goto done; 16749 } 16750 p = get_tv_string_buf_chk(&argvars[1], buf); 16751 if (p == NULL) 16752 { 16753 fclose(fd); 16754 goto done; /* type error; errmsg already given */ 16755 } 16756 if (fwrite(p, STRLEN(p), 1, fd) != 1) 16757 err = TRUE; 16758 if (fclose(fd) != 0) 16759 err = TRUE; 16760 if (err) 16761 { 16762 EMSG(_("E677: Error writing temp file")); 16763 goto done; 16764 } 16765 } 16766 16767 res = get_cmd_output(get_tv_string(&argvars[0]), infile, 16768 SHELL_SILENT | SHELL_COOKED); 16769 16770 #ifdef USE_CR 16771 /* translate <CR> into <NL> */ 16772 if (res != NULL) 16773 { 16774 char_u *s; 16775 16776 for (s = res; *s; ++s) 16777 { 16778 if (*s == CAR) 16779 *s = NL; 16780 } 16781 } 16782 #else 16783 # ifdef USE_CRNL 16784 /* translate <CR><NL> into <NL> */ 16785 if (res != NULL) 16786 { 16787 char_u *s, *d; 16788 16789 d = res; 16790 for (s = res; *s; ++s) 16791 { 16792 if (s[0] == CAR && s[1] == NL) 16793 ++s; 16794 *d++ = *s; 16795 } 16796 *d = NUL; 16797 } 16798 # endif 16799 #endif 16800 16801 done: 16802 if (infile != NULL) 16803 { 16804 mch_remove(infile); 16805 vim_free(infile); 16806 } 16807 rettv->v_type = VAR_STRING; 16808 rettv->vval.v_string = res; 16809 } 16810 16811 /* 16812 * "tabpagebuflist()" function 16813 */ 16814 static void 16815 f_tabpagebuflist(argvars, rettv) 16816 typval_T *argvars UNUSED; 16817 typval_T *rettv UNUSED; 16818 { 16819 #ifdef FEAT_WINDOWS 16820 tabpage_T *tp; 16821 win_T *wp = NULL; 16822 16823 if (argvars[0].v_type == VAR_UNKNOWN) 16824 wp = firstwin; 16825 else 16826 { 16827 tp = find_tabpage((int)get_tv_number(&argvars[0])); 16828 if (tp != NULL) 16829 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 16830 } 16831 if (wp != NULL && rettv_list_alloc(rettv) != FAIL) 16832 { 16833 for (; wp != NULL; wp = wp->w_next) 16834 if (list_append_number(rettv->vval.v_list, 16835 wp->w_buffer->b_fnum) == FAIL) 16836 break; 16837 } 16838 #endif 16839 } 16840 16841 16842 /* 16843 * "tabpagenr()" function 16844 */ 16845 static void 16846 f_tabpagenr(argvars, rettv) 16847 typval_T *argvars UNUSED; 16848 typval_T *rettv; 16849 { 16850 int nr = 1; 16851 #ifdef FEAT_WINDOWS 16852 char_u *arg; 16853 16854 if (argvars[0].v_type != VAR_UNKNOWN) 16855 { 16856 arg = get_tv_string_chk(&argvars[0]); 16857 nr = 0; 16858 if (arg != NULL) 16859 { 16860 if (STRCMP(arg, "$") == 0) 16861 nr = tabpage_index(NULL) - 1; 16862 else 16863 EMSG2(_(e_invexpr2), arg); 16864 } 16865 } 16866 else 16867 nr = tabpage_index(curtab); 16868 #endif 16869 rettv->vval.v_number = nr; 16870 } 16871 16872 16873 #ifdef FEAT_WINDOWS 16874 static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 16875 16876 /* 16877 * Common code for tabpagewinnr() and winnr(). 16878 */ 16879 static int 16880 get_winnr(tp, argvar) 16881 tabpage_T *tp; 16882 typval_T *argvar; 16883 { 16884 win_T *twin; 16885 int nr = 1; 16886 win_T *wp; 16887 char_u *arg; 16888 16889 twin = (tp == curtab) ? curwin : tp->tp_curwin; 16890 if (argvar->v_type != VAR_UNKNOWN) 16891 { 16892 arg = get_tv_string_chk(argvar); 16893 if (arg == NULL) 16894 nr = 0; /* type error; errmsg already given */ 16895 else if (STRCMP(arg, "$") == 0) 16896 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 16897 else if (STRCMP(arg, "#") == 0) 16898 { 16899 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 16900 if (twin == NULL) 16901 nr = 0; 16902 } 16903 else 16904 { 16905 EMSG2(_(e_invexpr2), arg); 16906 nr = 0; 16907 } 16908 } 16909 16910 if (nr > 0) 16911 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 16912 wp != twin; wp = wp->w_next) 16913 { 16914 if (wp == NULL) 16915 { 16916 /* didn't find it in this tabpage */ 16917 nr = 0; 16918 break; 16919 } 16920 ++nr; 16921 } 16922 return nr; 16923 } 16924 #endif 16925 16926 /* 16927 * "tabpagewinnr()" function 16928 */ 16929 static void 16930 f_tabpagewinnr(argvars, rettv) 16931 typval_T *argvars UNUSED; 16932 typval_T *rettv; 16933 { 16934 int nr = 1; 16935 #ifdef FEAT_WINDOWS 16936 tabpage_T *tp; 16937 16938 tp = find_tabpage((int)get_tv_number(&argvars[0])); 16939 if (tp == NULL) 16940 nr = 0; 16941 else 16942 nr = get_winnr(tp, &argvars[1]); 16943 #endif 16944 rettv->vval.v_number = nr; 16945 } 16946 16947 16948 /* 16949 * "tagfiles()" function 16950 */ 16951 static void 16952 f_tagfiles(argvars, rettv) 16953 typval_T *argvars UNUSED; 16954 typval_T *rettv; 16955 { 16956 char_u fname[MAXPATHL + 1]; 16957 tagname_T tn; 16958 int first; 16959 16960 if (rettv_list_alloc(rettv) == FAIL) 16961 return; 16962 16963 for (first = TRUE; ; first = FALSE) 16964 if (get_tagfname(&tn, first, fname) == FAIL 16965 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 16966 break; 16967 tagname_free(&tn); 16968 } 16969 16970 /* 16971 * "taglist()" function 16972 */ 16973 static void 16974 f_taglist(argvars, rettv) 16975 typval_T *argvars; 16976 typval_T *rettv; 16977 { 16978 char_u *tag_pattern; 16979 16980 tag_pattern = get_tv_string(&argvars[0]); 16981 16982 rettv->vval.v_number = FALSE; 16983 if (*tag_pattern == NUL) 16984 return; 16985 16986 if (rettv_list_alloc(rettv) == OK) 16987 (void)get_tags(rettv->vval.v_list, tag_pattern); 16988 } 16989 16990 /* 16991 * "tempname()" function 16992 */ 16993 static void 16994 f_tempname(argvars, rettv) 16995 typval_T *argvars UNUSED; 16996 typval_T *rettv; 16997 { 16998 static int x = 'A'; 16999 17000 rettv->v_type = VAR_STRING; 17001 rettv->vval.v_string = vim_tempname(x); 17002 17003 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 17004 * names. Skip 'I' and 'O', they are used for shell redirection. */ 17005 do 17006 { 17007 if (x == 'Z') 17008 x = '0'; 17009 else if (x == '9') 17010 x = 'A'; 17011 else 17012 { 17013 #ifdef EBCDIC 17014 if (x == 'I') 17015 x = 'J'; 17016 else if (x == 'R') 17017 x = 'S'; 17018 else 17019 #endif 17020 ++x; 17021 } 17022 } while (x == 'I' || x == 'O'); 17023 } 17024 17025 /* 17026 * "test(list)" function: Just checking the walls... 17027 */ 17028 static void 17029 f_test(argvars, rettv) 17030 typval_T *argvars UNUSED; 17031 typval_T *rettv UNUSED; 17032 { 17033 /* Used for unit testing. Change the code below to your liking. */ 17034 #if 0 17035 listitem_T *li; 17036 list_T *l; 17037 char_u *bad, *good; 17038 17039 if (argvars[0].v_type != VAR_LIST) 17040 return; 17041 l = argvars[0].vval.v_list; 17042 if (l == NULL) 17043 return; 17044 li = l->lv_first; 17045 if (li == NULL) 17046 return; 17047 bad = get_tv_string(&li->li_tv); 17048 li = li->li_next; 17049 if (li == NULL) 17050 return; 17051 good = get_tv_string(&li->li_tv); 17052 rettv->vval.v_number = test_edit_score(bad, good); 17053 #endif 17054 } 17055 17056 /* 17057 * "tolower(string)" function 17058 */ 17059 static void 17060 f_tolower(argvars, rettv) 17061 typval_T *argvars; 17062 typval_T *rettv; 17063 { 17064 char_u *p; 17065 17066 p = vim_strsave(get_tv_string(&argvars[0])); 17067 rettv->v_type = VAR_STRING; 17068 rettv->vval.v_string = p; 17069 17070 if (p != NULL) 17071 while (*p != NUL) 17072 { 17073 #ifdef FEAT_MBYTE 17074 int l; 17075 17076 if (enc_utf8) 17077 { 17078 int c, lc; 17079 17080 c = utf_ptr2char(p); 17081 lc = utf_tolower(c); 17082 l = utf_ptr2len(p); 17083 /* TODO: reallocate string when byte count changes. */ 17084 if (utf_char2len(lc) == l) 17085 utf_char2bytes(lc, p); 17086 p += l; 17087 } 17088 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 17089 p += l; /* skip multi-byte character */ 17090 else 17091 #endif 17092 { 17093 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 17094 ++p; 17095 } 17096 } 17097 } 17098 17099 /* 17100 * "toupper(string)" function 17101 */ 17102 static void 17103 f_toupper(argvars, rettv) 17104 typval_T *argvars; 17105 typval_T *rettv; 17106 { 17107 rettv->v_type = VAR_STRING; 17108 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 17109 } 17110 17111 /* 17112 * "tr(string, fromstr, tostr)" function 17113 */ 17114 static void 17115 f_tr(argvars, rettv) 17116 typval_T *argvars; 17117 typval_T *rettv; 17118 { 17119 char_u *instr; 17120 char_u *fromstr; 17121 char_u *tostr; 17122 char_u *p; 17123 #ifdef FEAT_MBYTE 17124 int inlen; 17125 int fromlen; 17126 int tolen; 17127 int idx; 17128 char_u *cpstr; 17129 int cplen; 17130 int first = TRUE; 17131 #endif 17132 char_u buf[NUMBUFLEN]; 17133 char_u buf2[NUMBUFLEN]; 17134 garray_T ga; 17135 17136 instr = get_tv_string(&argvars[0]); 17137 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 17138 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 17139 17140 /* Default return value: empty string. */ 17141 rettv->v_type = VAR_STRING; 17142 rettv->vval.v_string = NULL; 17143 if (fromstr == NULL || tostr == NULL) 17144 return; /* type error; errmsg already given */ 17145 ga_init2(&ga, (int)sizeof(char), 80); 17146 17147 #ifdef FEAT_MBYTE 17148 if (!has_mbyte) 17149 #endif 17150 /* not multi-byte: fromstr and tostr must be the same length */ 17151 if (STRLEN(fromstr) != STRLEN(tostr)) 17152 { 17153 #ifdef FEAT_MBYTE 17154 error: 17155 #endif 17156 EMSG2(_(e_invarg2), fromstr); 17157 ga_clear(&ga); 17158 return; 17159 } 17160 17161 /* fromstr and tostr have to contain the same number of chars */ 17162 while (*instr != NUL) 17163 { 17164 #ifdef FEAT_MBYTE 17165 if (has_mbyte) 17166 { 17167 inlen = (*mb_ptr2len)(instr); 17168 cpstr = instr; 17169 cplen = inlen; 17170 idx = 0; 17171 for (p = fromstr; *p != NUL; p += fromlen) 17172 { 17173 fromlen = (*mb_ptr2len)(p); 17174 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 17175 { 17176 for (p = tostr; *p != NUL; p += tolen) 17177 { 17178 tolen = (*mb_ptr2len)(p); 17179 if (idx-- == 0) 17180 { 17181 cplen = tolen; 17182 cpstr = p; 17183 break; 17184 } 17185 } 17186 if (*p == NUL) /* tostr is shorter than fromstr */ 17187 goto error; 17188 break; 17189 } 17190 ++idx; 17191 } 17192 17193 if (first && cpstr == instr) 17194 { 17195 /* Check that fromstr and tostr have the same number of 17196 * (multi-byte) characters. Done only once when a character 17197 * of instr doesn't appear in fromstr. */ 17198 first = FALSE; 17199 for (p = tostr; *p != NUL; p += tolen) 17200 { 17201 tolen = (*mb_ptr2len)(p); 17202 --idx; 17203 } 17204 if (idx != 0) 17205 goto error; 17206 } 17207 17208 ga_grow(&ga, cplen); 17209 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 17210 ga.ga_len += cplen; 17211 17212 instr += inlen; 17213 } 17214 else 17215 #endif 17216 { 17217 /* When not using multi-byte chars we can do it faster. */ 17218 p = vim_strchr(fromstr, *instr); 17219 if (p != NULL) 17220 ga_append(&ga, tostr[p - fromstr]); 17221 else 17222 ga_append(&ga, *instr); 17223 ++instr; 17224 } 17225 } 17226 17227 /* add a terminating NUL */ 17228 ga_grow(&ga, 1); 17229 ga_append(&ga, NUL); 17230 17231 rettv->vval.v_string = ga.ga_data; 17232 } 17233 17234 #ifdef FEAT_FLOAT 17235 /* 17236 * "trunc({float})" function 17237 */ 17238 static void 17239 f_trunc(argvars, rettv) 17240 typval_T *argvars; 17241 typval_T *rettv; 17242 { 17243 float_T f; 17244 17245 rettv->v_type = VAR_FLOAT; 17246 if (get_float_arg(argvars, &f) == OK) 17247 /* trunc() is not in C90, use floor() or ceil() instead. */ 17248 rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); 17249 else 17250 rettv->vval.v_float = 0.0; 17251 } 17252 #endif 17253 17254 /* 17255 * "type(expr)" function 17256 */ 17257 static void 17258 f_type(argvars, rettv) 17259 typval_T *argvars; 17260 typval_T *rettv; 17261 { 17262 int n; 17263 17264 switch (argvars[0].v_type) 17265 { 17266 case VAR_NUMBER: n = 0; break; 17267 case VAR_STRING: n = 1; break; 17268 case VAR_FUNC: n = 2; break; 17269 case VAR_LIST: n = 3; break; 17270 case VAR_DICT: n = 4; break; 17271 #ifdef FEAT_FLOAT 17272 case VAR_FLOAT: n = 5; break; 17273 #endif 17274 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 17275 } 17276 rettv->vval.v_number = n; 17277 } 17278 17279 /* 17280 * "values(dict)" function 17281 */ 17282 static void 17283 f_values(argvars, rettv) 17284 typval_T *argvars; 17285 typval_T *rettv; 17286 { 17287 dict_list(argvars, rettv, 1); 17288 } 17289 17290 /* 17291 * "virtcol(string)" function 17292 */ 17293 static void 17294 f_virtcol(argvars, rettv) 17295 typval_T *argvars; 17296 typval_T *rettv; 17297 { 17298 colnr_T vcol = 0; 17299 pos_T *fp; 17300 int fnum = curbuf->b_fnum; 17301 17302 fp = var2fpos(&argvars[0], FALSE, &fnum); 17303 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 17304 && fnum == curbuf->b_fnum) 17305 { 17306 getvvcol(curwin, fp, NULL, NULL, &vcol); 17307 ++vcol; 17308 } 17309 17310 rettv->vval.v_number = vcol; 17311 } 17312 17313 /* 17314 * "visualmode()" function 17315 */ 17316 static void 17317 f_visualmode(argvars, rettv) 17318 typval_T *argvars UNUSED; 17319 typval_T *rettv UNUSED; 17320 { 17321 #ifdef FEAT_VISUAL 17322 char_u str[2]; 17323 17324 rettv->v_type = VAR_STRING; 17325 str[0] = curbuf->b_visual_mode_eval; 17326 str[1] = NUL; 17327 rettv->vval.v_string = vim_strsave(str); 17328 17329 /* A non-zero number or non-empty string argument: reset mode. */ 17330 if (non_zero_arg(&argvars[0])) 17331 curbuf->b_visual_mode_eval = NUL; 17332 #endif 17333 } 17334 17335 /* 17336 * "winbufnr(nr)" function 17337 */ 17338 static void 17339 f_winbufnr(argvars, rettv) 17340 typval_T *argvars; 17341 typval_T *rettv; 17342 { 17343 win_T *wp; 17344 17345 wp = find_win_by_nr(&argvars[0], NULL); 17346 if (wp == NULL) 17347 rettv->vval.v_number = -1; 17348 else 17349 rettv->vval.v_number = wp->w_buffer->b_fnum; 17350 } 17351 17352 /* 17353 * "wincol()" function 17354 */ 17355 static void 17356 f_wincol(argvars, rettv) 17357 typval_T *argvars UNUSED; 17358 typval_T *rettv; 17359 { 17360 validate_cursor(); 17361 rettv->vval.v_number = curwin->w_wcol + 1; 17362 } 17363 17364 /* 17365 * "winheight(nr)" function 17366 */ 17367 static void 17368 f_winheight(argvars, rettv) 17369 typval_T *argvars; 17370 typval_T *rettv; 17371 { 17372 win_T *wp; 17373 17374 wp = find_win_by_nr(&argvars[0], NULL); 17375 if (wp == NULL) 17376 rettv->vval.v_number = -1; 17377 else 17378 rettv->vval.v_number = wp->w_height; 17379 } 17380 17381 /* 17382 * "winline()" function 17383 */ 17384 static void 17385 f_winline(argvars, rettv) 17386 typval_T *argvars UNUSED; 17387 typval_T *rettv; 17388 { 17389 validate_cursor(); 17390 rettv->vval.v_number = curwin->w_wrow + 1; 17391 } 17392 17393 /* 17394 * "winnr()" function 17395 */ 17396 static void 17397 f_winnr(argvars, rettv) 17398 typval_T *argvars UNUSED; 17399 typval_T *rettv; 17400 { 17401 int nr = 1; 17402 17403 #ifdef FEAT_WINDOWS 17404 nr = get_winnr(curtab, &argvars[0]); 17405 #endif 17406 rettv->vval.v_number = nr; 17407 } 17408 17409 /* 17410 * "winrestcmd()" function 17411 */ 17412 static void 17413 f_winrestcmd(argvars, rettv) 17414 typval_T *argvars UNUSED; 17415 typval_T *rettv; 17416 { 17417 #ifdef FEAT_WINDOWS 17418 win_T *wp; 17419 int winnr = 1; 17420 garray_T ga; 17421 char_u buf[50]; 17422 17423 ga_init2(&ga, (int)sizeof(char), 70); 17424 for (wp = firstwin; wp != NULL; wp = wp->w_next) 17425 { 17426 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 17427 ga_concat(&ga, buf); 17428 # ifdef FEAT_VERTSPLIT 17429 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 17430 ga_concat(&ga, buf); 17431 # endif 17432 ++winnr; 17433 } 17434 ga_append(&ga, NUL); 17435 17436 rettv->vval.v_string = ga.ga_data; 17437 #else 17438 rettv->vval.v_string = NULL; 17439 #endif 17440 rettv->v_type = VAR_STRING; 17441 } 17442 17443 /* 17444 * "winrestview()" function 17445 */ 17446 static void 17447 f_winrestview(argvars, rettv) 17448 typval_T *argvars; 17449 typval_T *rettv UNUSED; 17450 { 17451 dict_T *dict; 17452 17453 if (argvars[0].v_type != VAR_DICT 17454 || (dict = argvars[0].vval.v_dict) == NULL) 17455 EMSG(_(e_invarg)); 17456 else 17457 { 17458 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 17459 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 17460 #ifdef FEAT_VIRTUALEDIT 17461 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 17462 #endif 17463 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 17464 curwin->w_set_curswant = FALSE; 17465 17466 set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); 17467 #ifdef FEAT_DIFF 17468 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 17469 #endif 17470 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 17471 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 17472 17473 check_cursor(); 17474 changed_cline_bef_curs(); 17475 invalidate_botline(); 17476 redraw_later(VALID); 17477 17478 if (curwin->w_topline == 0) 17479 curwin->w_topline = 1; 17480 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 17481 curwin->w_topline = curbuf->b_ml.ml_line_count; 17482 #ifdef FEAT_DIFF 17483 check_topfill(curwin, TRUE); 17484 #endif 17485 } 17486 } 17487 17488 /* 17489 * "winsaveview()" function 17490 */ 17491 static void 17492 f_winsaveview(argvars, rettv) 17493 typval_T *argvars UNUSED; 17494 typval_T *rettv; 17495 { 17496 dict_T *dict; 17497 17498 dict = dict_alloc(); 17499 if (dict == NULL) 17500 return; 17501 rettv->v_type = VAR_DICT; 17502 rettv->vval.v_dict = dict; 17503 ++dict->dv_refcount; 17504 17505 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 17506 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 17507 #ifdef FEAT_VIRTUALEDIT 17508 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 17509 #endif 17510 update_curswant(); 17511 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 17512 17513 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 17514 #ifdef FEAT_DIFF 17515 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 17516 #endif 17517 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 17518 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 17519 } 17520 17521 /* 17522 * "winwidth(nr)" function 17523 */ 17524 static void 17525 f_winwidth(argvars, rettv) 17526 typval_T *argvars; 17527 typval_T *rettv; 17528 { 17529 win_T *wp; 17530 17531 wp = find_win_by_nr(&argvars[0], NULL); 17532 if (wp == NULL) 17533 rettv->vval.v_number = -1; 17534 else 17535 #ifdef FEAT_VERTSPLIT 17536 rettv->vval.v_number = wp->w_width; 17537 #else 17538 rettv->vval.v_number = Columns; 17539 #endif 17540 } 17541 17542 /* 17543 * "writefile()" function 17544 */ 17545 static void 17546 f_writefile(argvars, rettv) 17547 typval_T *argvars; 17548 typval_T *rettv; 17549 { 17550 int binary = FALSE; 17551 char_u *fname; 17552 FILE *fd; 17553 listitem_T *li; 17554 char_u *s; 17555 int ret = 0; 17556 int c; 17557 17558 if (check_restricted() || check_secure()) 17559 return; 17560 17561 if (argvars[0].v_type != VAR_LIST) 17562 { 17563 EMSG2(_(e_listarg), "writefile()"); 17564 return; 17565 } 17566 if (argvars[0].vval.v_list == NULL) 17567 return; 17568 17569 if (argvars[2].v_type != VAR_UNKNOWN 17570 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 17571 binary = TRUE; 17572 17573 /* Always open the file in binary mode, library functions have a mind of 17574 * their own about CR-LF conversion. */ 17575 fname = get_tv_string(&argvars[1]); 17576 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 17577 { 17578 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 17579 ret = -1; 17580 } 17581 else 17582 { 17583 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 17584 li = li->li_next) 17585 { 17586 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 17587 { 17588 if (*s == '\n') 17589 c = putc(NUL, fd); 17590 else 17591 c = putc(*s, fd); 17592 if (c == EOF) 17593 { 17594 ret = -1; 17595 break; 17596 } 17597 } 17598 if (!binary || li->li_next != NULL) 17599 if (putc('\n', fd) == EOF) 17600 { 17601 ret = -1; 17602 break; 17603 } 17604 if (ret < 0) 17605 { 17606 EMSG(_(e_write)); 17607 break; 17608 } 17609 } 17610 fclose(fd); 17611 } 17612 17613 rettv->vval.v_number = ret; 17614 } 17615 17616 /* 17617 * Translate a String variable into a position. 17618 * Returns NULL when there is an error. 17619 */ 17620 static pos_T * 17621 var2fpos(varp, dollar_lnum, fnum) 17622 typval_T *varp; 17623 int dollar_lnum; /* TRUE when $ is last line */ 17624 int *fnum; /* set to fnum for '0, 'A, etc. */ 17625 { 17626 char_u *name; 17627 static pos_T pos; 17628 pos_T *pp; 17629 17630 /* Argument can be [lnum, col, coladd]. */ 17631 if (varp->v_type == VAR_LIST) 17632 { 17633 list_T *l; 17634 int len; 17635 int error = FALSE; 17636 listitem_T *li; 17637 17638 l = varp->vval.v_list; 17639 if (l == NULL) 17640 return NULL; 17641 17642 /* Get the line number */ 17643 pos.lnum = list_find_nr(l, 0L, &error); 17644 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 17645 return NULL; /* invalid line number */ 17646 17647 /* Get the column number */ 17648 pos.col = list_find_nr(l, 1L, &error); 17649 if (error) 17650 return NULL; 17651 len = (long)STRLEN(ml_get(pos.lnum)); 17652 17653 /* We accept "$" for the column number: last column. */ 17654 li = list_find(l, 1L); 17655 if (li != NULL && li->li_tv.v_type == VAR_STRING 17656 && li->li_tv.vval.v_string != NULL 17657 && STRCMP(li->li_tv.vval.v_string, "$") == 0) 17658 pos.col = len + 1; 17659 17660 /* Accept a position up to the NUL after the line. */ 17661 if (pos.col == 0 || (int)pos.col > len + 1) 17662 return NULL; /* invalid column number */ 17663 --pos.col; 17664 17665 #ifdef FEAT_VIRTUALEDIT 17666 /* Get the virtual offset. Defaults to zero. */ 17667 pos.coladd = list_find_nr(l, 2L, &error); 17668 if (error) 17669 pos.coladd = 0; 17670 #endif 17671 17672 return &pos; 17673 } 17674 17675 name = get_tv_string_chk(varp); 17676 if (name == NULL) 17677 return NULL; 17678 if (name[0] == '.') /* cursor */ 17679 return &curwin->w_cursor; 17680 #ifdef FEAT_VISUAL 17681 if (name[0] == 'v' && name[1] == NUL) /* Visual start */ 17682 { 17683 if (VIsual_active) 17684 return &VIsual; 17685 return &curwin->w_cursor; 17686 } 17687 #endif 17688 if (name[0] == '\'') /* mark */ 17689 { 17690 pp = getmark_fnum(name[1], FALSE, fnum); 17691 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 17692 return NULL; 17693 return pp; 17694 } 17695 17696 #ifdef FEAT_VIRTUALEDIT 17697 pos.coladd = 0; 17698 #endif 17699 17700 if (name[0] == 'w' && dollar_lnum) 17701 { 17702 pos.col = 0; 17703 if (name[1] == '0') /* "w0": first visible line */ 17704 { 17705 update_topline(); 17706 pos.lnum = curwin->w_topline; 17707 return &pos; 17708 } 17709 else if (name[1] == '$') /* "w$": last visible line */ 17710 { 17711 validate_botline(); 17712 pos.lnum = curwin->w_botline - 1; 17713 return &pos; 17714 } 17715 } 17716 else if (name[0] == '$') /* last column or line */ 17717 { 17718 if (dollar_lnum) 17719 { 17720 pos.lnum = curbuf->b_ml.ml_line_count; 17721 pos.col = 0; 17722 } 17723 else 17724 { 17725 pos.lnum = curwin->w_cursor.lnum; 17726 pos.col = (colnr_T)STRLEN(ml_get_curline()); 17727 } 17728 return &pos; 17729 } 17730 return NULL; 17731 } 17732 17733 /* 17734 * Convert list in "arg" into a position and optional file number. 17735 * When "fnump" is NULL there is no file number, only 3 items. 17736 * Note that the column is passed on as-is, the caller may want to decrement 17737 * it to use 1 for the first column. 17738 * Return FAIL when conversion is not possible, doesn't check the position for 17739 * validity. 17740 */ 17741 static int 17742 list2fpos(arg, posp, fnump) 17743 typval_T *arg; 17744 pos_T *posp; 17745 int *fnump; 17746 { 17747 list_T *l = arg->vval.v_list; 17748 long i = 0; 17749 long n; 17750 17751 /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there 17752 * when "fnump" isn't NULL and "coladd" is optional. */ 17753 if (arg->v_type != VAR_LIST 17754 || l == NULL 17755 || l->lv_len < (fnump == NULL ? 2 : 3) 17756 || l->lv_len > (fnump == NULL ? 3 : 4)) 17757 return FAIL; 17758 17759 if (fnump != NULL) 17760 { 17761 n = list_find_nr(l, i++, NULL); /* fnum */ 17762 if (n < 0) 17763 return FAIL; 17764 if (n == 0) 17765 n = curbuf->b_fnum; /* current buffer */ 17766 *fnump = n; 17767 } 17768 17769 n = list_find_nr(l, i++, NULL); /* lnum */ 17770 if (n < 0) 17771 return FAIL; 17772 posp->lnum = n; 17773 17774 n = list_find_nr(l, i++, NULL); /* col */ 17775 if (n < 0) 17776 return FAIL; 17777 posp->col = n; 17778 17779 #ifdef FEAT_VIRTUALEDIT 17780 n = list_find_nr(l, i, NULL); 17781 if (n < 0) 17782 posp->coladd = 0; 17783 else 17784 posp->coladd = n; 17785 #endif 17786 17787 return OK; 17788 } 17789 17790 /* 17791 * Get the length of an environment variable name. 17792 * Advance "arg" to the first character after the name. 17793 * Return 0 for error. 17794 */ 17795 static int 17796 get_env_len(arg) 17797 char_u **arg; 17798 { 17799 char_u *p; 17800 int len; 17801 17802 for (p = *arg; vim_isIDc(*p); ++p) 17803 ; 17804 if (p == *arg) /* no name found */ 17805 return 0; 17806 17807 len = (int)(p - *arg); 17808 *arg = p; 17809 return len; 17810 } 17811 17812 /* 17813 * Get the length of the name of a function or internal variable. 17814 * "arg" is advanced to the first non-white character after the name. 17815 * Return 0 if something is wrong. 17816 */ 17817 static int 17818 get_id_len(arg) 17819 char_u **arg; 17820 { 17821 char_u *p; 17822 int len; 17823 17824 /* Find the end of the name. */ 17825 for (p = *arg; eval_isnamec(*p); ++p) 17826 ; 17827 if (p == *arg) /* no name found */ 17828 return 0; 17829 17830 len = (int)(p - *arg); 17831 *arg = skipwhite(p); 17832 17833 return len; 17834 } 17835 17836 /* 17837 * Get the length of the name of a variable or function. 17838 * Only the name is recognized, does not handle ".key" or "[idx]". 17839 * "arg" is advanced to the first non-white character after the name. 17840 * Return -1 if curly braces expansion failed. 17841 * Return 0 if something else is wrong. 17842 * If the name contains 'magic' {}'s, expand them and return the 17843 * expanded name in an allocated string via 'alias' - caller must free. 17844 */ 17845 static int 17846 get_name_len(arg, alias, evaluate, verbose) 17847 char_u **arg; 17848 char_u **alias; 17849 int evaluate; 17850 int verbose; 17851 { 17852 int len; 17853 char_u *p; 17854 char_u *expr_start; 17855 char_u *expr_end; 17856 17857 *alias = NULL; /* default to no alias */ 17858 17859 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 17860 && (*arg)[2] == (int)KE_SNR) 17861 { 17862 /* hard coded <SNR>, already translated */ 17863 *arg += 3; 17864 return get_id_len(arg) + 3; 17865 } 17866 len = eval_fname_script(*arg); 17867 if (len > 0) 17868 { 17869 /* literal "<SID>", "s:" or "<SNR>" */ 17870 *arg += len; 17871 } 17872 17873 /* 17874 * Find the end of the name; check for {} construction. 17875 */ 17876 p = find_name_end(*arg, &expr_start, &expr_end, 17877 len > 0 ? 0 : FNE_CHECK_START); 17878 if (expr_start != NULL) 17879 { 17880 char_u *temp_string; 17881 17882 if (!evaluate) 17883 { 17884 len += (int)(p - *arg); 17885 *arg = skipwhite(p); 17886 return len; 17887 } 17888 17889 /* 17890 * Include any <SID> etc in the expanded string: 17891 * Thus the -len here. 17892 */ 17893 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 17894 if (temp_string == NULL) 17895 return -1; 17896 *alias = temp_string; 17897 *arg = skipwhite(p); 17898 return (int)STRLEN(temp_string); 17899 } 17900 17901 len += get_id_len(arg); 17902 if (len == 0 && verbose) 17903 EMSG2(_(e_invexpr2), *arg); 17904 17905 return len; 17906 } 17907 17908 /* 17909 * Find the end of a variable or function name, taking care of magic braces. 17910 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 17911 * start and end of the first magic braces item. 17912 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 17913 * Return a pointer to just after the name. Equal to "arg" if there is no 17914 * valid name. 17915 */ 17916 static char_u * 17917 find_name_end(arg, expr_start, expr_end, flags) 17918 char_u *arg; 17919 char_u **expr_start; 17920 char_u **expr_end; 17921 int flags; 17922 { 17923 int mb_nest = 0; 17924 int br_nest = 0; 17925 char_u *p; 17926 17927 if (expr_start != NULL) 17928 { 17929 *expr_start = NULL; 17930 *expr_end = NULL; 17931 } 17932 17933 /* Quick check for valid starting character. */ 17934 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 17935 return arg; 17936 17937 for (p = arg; *p != NUL 17938 && (eval_isnamec(*p) 17939 || *p == '{' 17940 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 17941 || mb_nest != 0 17942 || br_nest != 0); mb_ptr_adv(p)) 17943 { 17944 if (*p == '\'') 17945 { 17946 /* skip over 'string' to avoid counting [ and ] inside it. */ 17947 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 17948 ; 17949 if (*p == NUL) 17950 break; 17951 } 17952 else if (*p == '"') 17953 { 17954 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 17955 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 17956 if (*p == '\\' && p[1] != NUL) 17957 ++p; 17958 if (*p == NUL) 17959 break; 17960 } 17961 17962 if (mb_nest == 0) 17963 { 17964 if (*p == '[') 17965 ++br_nest; 17966 else if (*p == ']') 17967 --br_nest; 17968 } 17969 17970 if (br_nest == 0) 17971 { 17972 if (*p == '{') 17973 { 17974 mb_nest++; 17975 if (expr_start != NULL && *expr_start == NULL) 17976 *expr_start = p; 17977 } 17978 else if (*p == '}') 17979 { 17980 mb_nest--; 17981 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 17982 *expr_end = p; 17983 } 17984 } 17985 } 17986 17987 return p; 17988 } 17989 17990 /* 17991 * Expands out the 'magic' {}'s in a variable/function name. 17992 * Note that this can call itself recursively, to deal with 17993 * constructs like foo{bar}{baz}{bam} 17994 * The four pointer arguments point to "foo{expre}ss{ion}bar" 17995 * "in_start" ^ 17996 * "expr_start" ^ 17997 * "expr_end" ^ 17998 * "in_end" ^ 17999 * 18000 * Returns a new allocated string, which the caller must free. 18001 * Returns NULL for failure. 18002 */ 18003 static char_u * 18004 make_expanded_name(in_start, expr_start, expr_end, in_end) 18005 char_u *in_start; 18006 char_u *expr_start; 18007 char_u *expr_end; 18008 char_u *in_end; 18009 { 18010 char_u c1; 18011 char_u *retval = NULL; 18012 char_u *temp_result; 18013 char_u *nextcmd = NULL; 18014 18015 if (expr_end == NULL || in_end == NULL) 18016 return NULL; 18017 *expr_start = NUL; 18018 *expr_end = NUL; 18019 c1 = *in_end; 18020 *in_end = NUL; 18021 18022 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 18023 if (temp_result != NULL && nextcmd == NULL) 18024 { 18025 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 18026 + (in_end - expr_end) + 1)); 18027 if (retval != NULL) 18028 { 18029 STRCPY(retval, in_start); 18030 STRCAT(retval, temp_result); 18031 STRCAT(retval, expr_end + 1); 18032 } 18033 } 18034 vim_free(temp_result); 18035 18036 *in_end = c1; /* put char back for error messages */ 18037 *expr_start = '{'; 18038 *expr_end = '}'; 18039 18040 if (retval != NULL) 18041 { 18042 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 18043 if (expr_start != NULL) 18044 { 18045 /* Further expansion! */ 18046 temp_result = make_expanded_name(retval, expr_start, 18047 expr_end, temp_result); 18048 vim_free(retval); 18049 retval = temp_result; 18050 } 18051 } 18052 18053 return retval; 18054 } 18055 18056 /* 18057 * Return TRUE if character "c" can be used in a variable or function name. 18058 * Does not include '{' or '}' for magic braces. 18059 */ 18060 static int 18061 eval_isnamec(c) 18062 int c; 18063 { 18064 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 18065 } 18066 18067 /* 18068 * Return TRUE if character "c" can be used as the first character in a 18069 * variable or function name (excluding '{' and '}'). 18070 */ 18071 static int 18072 eval_isnamec1(c) 18073 int c; 18074 { 18075 return (ASCII_ISALPHA(c) || c == '_'); 18076 } 18077 18078 /* 18079 * Set number v: variable to "val". 18080 */ 18081 void 18082 set_vim_var_nr(idx, val) 18083 int idx; 18084 long val; 18085 { 18086 vimvars[idx].vv_nr = val; 18087 } 18088 18089 /* 18090 * Get number v: variable value. 18091 */ 18092 long 18093 get_vim_var_nr(idx) 18094 int idx; 18095 { 18096 return vimvars[idx].vv_nr; 18097 } 18098 18099 /* 18100 * Get string v: variable value. Uses a static buffer, can only be used once. 18101 */ 18102 char_u * 18103 get_vim_var_str(idx) 18104 int idx; 18105 { 18106 return get_tv_string(&vimvars[idx].vv_tv); 18107 } 18108 18109 /* 18110 * Get List v: variable value. Caller must take care of reference count when 18111 * needed. 18112 */ 18113 list_T * 18114 get_vim_var_list(idx) 18115 int idx; 18116 { 18117 return vimvars[idx].vv_list; 18118 } 18119 18120 /* 18121 * Set v:char to character "c". 18122 */ 18123 void 18124 set_vim_var_char(c) 18125 int c; 18126 { 18127 #ifdef FEAT_MBYTE 18128 char_u buf[MB_MAXBYTES]; 18129 #else 18130 char_u buf[2]; 18131 #endif 18132 18133 #ifdef FEAT_MBYTE 18134 if (has_mbyte) 18135 buf[(*mb_char2bytes)(c, buf)] = NUL; 18136 else 18137 #endif 18138 { 18139 buf[0] = c; 18140 buf[1] = NUL; 18141 } 18142 set_vim_var_string(VV_CHAR, buf, -1); 18143 } 18144 18145 /* 18146 * Set v:count to "count" and v:count1 to "count1". 18147 * When "set_prevcount" is TRUE first set v:prevcount from v:count. 18148 */ 18149 void 18150 set_vcount(count, count1, set_prevcount) 18151 long count; 18152 long count1; 18153 int set_prevcount; 18154 { 18155 if (set_prevcount) 18156 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 18157 vimvars[VV_COUNT].vv_nr = count; 18158 vimvars[VV_COUNT1].vv_nr = count1; 18159 } 18160 18161 /* 18162 * Set string v: variable to a copy of "val". 18163 */ 18164 void 18165 set_vim_var_string(idx, val, len) 18166 int idx; 18167 char_u *val; 18168 int len; /* length of "val" to use or -1 (whole string) */ 18169 { 18170 /* Need to do this (at least) once, since we can't initialize a union. 18171 * Will always be invoked when "v:progname" is set. */ 18172 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 18173 18174 vim_free(vimvars[idx].vv_str); 18175 if (val == NULL) 18176 vimvars[idx].vv_str = NULL; 18177 else if (len == -1) 18178 vimvars[idx].vv_str = vim_strsave(val); 18179 else 18180 vimvars[idx].vv_str = vim_strnsave(val, len); 18181 } 18182 18183 /* 18184 * Set List v: variable to "val". 18185 */ 18186 void 18187 set_vim_var_list(idx, val) 18188 int idx; 18189 list_T *val; 18190 { 18191 list_unref(vimvars[idx].vv_list); 18192 vimvars[idx].vv_list = val; 18193 if (val != NULL) 18194 ++val->lv_refcount; 18195 } 18196 18197 /* 18198 * Set v:register if needed. 18199 */ 18200 void 18201 set_reg_var(c) 18202 int c; 18203 { 18204 char_u regname; 18205 18206 if (c == 0 || c == ' ') 18207 regname = '"'; 18208 else 18209 regname = c; 18210 /* Avoid free/alloc when the value is already right. */ 18211 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 18212 set_vim_var_string(VV_REG, ®name, 1); 18213 } 18214 18215 /* 18216 * Get or set v:exception. If "oldval" == NULL, return the current value. 18217 * Otherwise, restore the value to "oldval" and return NULL. 18218 * Must always be called in pairs to save and restore v:exception! Does not 18219 * take care of memory allocations. 18220 */ 18221 char_u * 18222 v_exception(oldval) 18223 char_u *oldval; 18224 { 18225 if (oldval == NULL) 18226 return vimvars[VV_EXCEPTION].vv_str; 18227 18228 vimvars[VV_EXCEPTION].vv_str = oldval; 18229 return NULL; 18230 } 18231 18232 /* 18233 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 18234 * Otherwise, restore the value to "oldval" and return NULL. 18235 * Must always be called in pairs to save and restore v:throwpoint! Does not 18236 * take care of memory allocations. 18237 */ 18238 char_u * 18239 v_throwpoint(oldval) 18240 char_u *oldval; 18241 { 18242 if (oldval == NULL) 18243 return vimvars[VV_THROWPOINT].vv_str; 18244 18245 vimvars[VV_THROWPOINT].vv_str = oldval; 18246 return NULL; 18247 } 18248 18249 #if defined(FEAT_AUTOCMD) || defined(PROTO) 18250 /* 18251 * Set v:cmdarg. 18252 * If "eap" != NULL, use "eap" to generate the value and return the old value. 18253 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 18254 * Must always be called in pairs! 18255 */ 18256 char_u * 18257 set_cmdarg(eap, oldarg) 18258 exarg_T *eap; 18259 char_u *oldarg; 18260 { 18261 char_u *oldval; 18262 char_u *newval; 18263 unsigned len; 18264 18265 oldval = vimvars[VV_CMDARG].vv_str; 18266 if (eap == NULL) 18267 { 18268 vim_free(oldval); 18269 vimvars[VV_CMDARG].vv_str = oldarg; 18270 return NULL; 18271 } 18272 18273 if (eap->force_bin == FORCE_BIN) 18274 len = 6; 18275 else if (eap->force_bin == FORCE_NOBIN) 18276 len = 8; 18277 else 18278 len = 0; 18279 18280 if (eap->read_edit) 18281 len += 7; 18282 18283 if (eap->force_ff != 0) 18284 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 18285 # ifdef FEAT_MBYTE 18286 if (eap->force_enc != 0) 18287 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 18288 if (eap->bad_char != 0) 18289 len += (unsigned)STRLEN(eap->cmd + eap->bad_char) + 7; 18290 # endif 18291 18292 newval = alloc(len + 1); 18293 if (newval == NULL) 18294 return NULL; 18295 18296 if (eap->force_bin == FORCE_BIN) 18297 sprintf((char *)newval, " ++bin"); 18298 else if (eap->force_bin == FORCE_NOBIN) 18299 sprintf((char *)newval, " ++nobin"); 18300 else 18301 *newval = NUL; 18302 18303 if (eap->read_edit) 18304 STRCAT(newval, " ++edit"); 18305 18306 if (eap->force_ff != 0) 18307 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 18308 eap->cmd + eap->force_ff); 18309 # ifdef FEAT_MBYTE 18310 if (eap->force_enc != 0) 18311 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 18312 eap->cmd + eap->force_enc); 18313 if (eap->bad_char != 0) 18314 sprintf((char *)newval + STRLEN(newval), " ++bad=%s", 18315 eap->cmd + eap->bad_char); 18316 # endif 18317 vimvars[VV_CMDARG].vv_str = newval; 18318 return oldval; 18319 } 18320 #endif 18321 18322 /* 18323 * Get the value of internal variable "name". 18324 * Return OK or FAIL. 18325 */ 18326 static int 18327 get_var_tv(name, len, rettv, verbose) 18328 char_u *name; 18329 int len; /* length of "name" */ 18330 typval_T *rettv; /* NULL when only checking existence */ 18331 int verbose; /* may give error message */ 18332 { 18333 int ret = OK; 18334 typval_T *tv = NULL; 18335 typval_T atv; 18336 dictitem_T *v; 18337 int cc; 18338 18339 /* truncate the name, so that we can use strcmp() */ 18340 cc = name[len]; 18341 name[len] = NUL; 18342 18343 /* 18344 * Check for "b:changedtick". 18345 */ 18346 if (STRCMP(name, "b:changedtick") == 0) 18347 { 18348 atv.v_type = VAR_NUMBER; 18349 atv.vval.v_number = curbuf->b_changedtick; 18350 tv = &atv; 18351 } 18352 18353 /* 18354 * Check for user-defined variables. 18355 */ 18356 else 18357 { 18358 v = find_var(name, NULL); 18359 if (v != NULL) 18360 tv = &v->di_tv; 18361 } 18362 18363 if (tv == NULL) 18364 { 18365 if (rettv != NULL && verbose) 18366 EMSG2(_(e_undefvar), name); 18367 ret = FAIL; 18368 } 18369 else if (rettv != NULL) 18370 copy_tv(tv, rettv); 18371 18372 name[len] = cc; 18373 18374 return ret; 18375 } 18376 18377 /* 18378 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 18379 * Also handle function call with Funcref variable: func(expr) 18380 * Can all be combined: dict.func(expr)[idx]['func'](expr) 18381 */ 18382 static int 18383 handle_subscript(arg, rettv, evaluate, verbose) 18384 char_u **arg; 18385 typval_T *rettv; 18386 int evaluate; /* do more than finding the end */ 18387 int verbose; /* give error messages */ 18388 { 18389 int ret = OK; 18390 dict_T *selfdict = NULL; 18391 char_u *s; 18392 int len; 18393 typval_T functv; 18394 18395 while (ret == OK 18396 && (**arg == '[' 18397 || (**arg == '.' && rettv->v_type == VAR_DICT) 18398 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 18399 && !vim_iswhite(*(*arg - 1))) 18400 { 18401 if (**arg == '(') 18402 { 18403 /* need to copy the funcref so that we can clear rettv */ 18404 functv = *rettv; 18405 rettv->v_type = VAR_UNKNOWN; 18406 18407 /* Invoke the function. Recursive! */ 18408 s = functv.vval.v_string; 18409 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 18410 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 18411 &len, evaluate, selfdict); 18412 18413 /* Clear the funcref afterwards, so that deleting it while 18414 * evaluating the arguments is possible (see test55). */ 18415 clear_tv(&functv); 18416 18417 /* Stop the expression evaluation when immediately aborting on 18418 * error, or when an interrupt occurred or an exception was thrown 18419 * but not caught. */ 18420 if (aborting()) 18421 { 18422 if (ret == OK) 18423 clear_tv(rettv); 18424 ret = FAIL; 18425 } 18426 dict_unref(selfdict); 18427 selfdict = NULL; 18428 } 18429 else /* **arg == '[' || **arg == '.' */ 18430 { 18431 dict_unref(selfdict); 18432 if (rettv->v_type == VAR_DICT) 18433 { 18434 selfdict = rettv->vval.v_dict; 18435 if (selfdict != NULL) 18436 ++selfdict->dv_refcount; 18437 } 18438 else 18439 selfdict = NULL; 18440 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 18441 { 18442 clear_tv(rettv); 18443 ret = FAIL; 18444 } 18445 } 18446 } 18447 dict_unref(selfdict); 18448 return ret; 18449 } 18450 18451 /* 18452 * Allocate memory for a variable type-value, and make it empty (0 or NULL 18453 * value). 18454 */ 18455 static typval_T * 18456 alloc_tv() 18457 { 18458 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 18459 } 18460 18461 /* 18462 * Allocate memory for a variable type-value, and assign a string to it. 18463 * The string "s" must have been allocated, it is consumed. 18464 * Return NULL for out of memory, the variable otherwise. 18465 */ 18466 static typval_T * 18467 alloc_string_tv(s) 18468 char_u *s; 18469 { 18470 typval_T *rettv; 18471 18472 rettv = alloc_tv(); 18473 if (rettv != NULL) 18474 { 18475 rettv->v_type = VAR_STRING; 18476 rettv->vval.v_string = s; 18477 } 18478 else 18479 vim_free(s); 18480 return rettv; 18481 } 18482 18483 /* 18484 * Free the memory for a variable type-value. 18485 */ 18486 void 18487 free_tv(varp) 18488 typval_T *varp; 18489 { 18490 if (varp != NULL) 18491 { 18492 switch (varp->v_type) 18493 { 18494 case VAR_FUNC: 18495 func_unref(varp->vval.v_string); 18496 /*FALLTHROUGH*/ 18497 case VAR_STRING: 18498 vim_free(varp->vval.v_string); 18499 break; 18500 case VAR_LIST: 18501 list_unref(varp->vval.v_list); 18502 break; 18503 case VAR_DICT: 18504 dict_unref(varp->vval.v_dict); 18505 break; 18506 case VAR_NUMBER: 18507 #ifdef FEAT_FLOAT 18508 case VAR_FLOAT: 18509 #endif 18510 case VAR_UNKNOWN: 18511 break; 18512 default: 18513 EMSG2(_(e_intern2), "free_tv()"); 18514 break; 18515 } 18516 vim_free(varp); 18517 } 18518 } 18519 18520 /* 18521 * Free the memory for a variable value and set the value to NULL or 0. 18522 */ 18523 void 18524 clear_tv(varp) 18525 typval_T *varp; 18526 { 18527 if (varp != NULL) 18528 { 18529 switch (varp->v_type) 18530 { 18531 case VAR_FUNC: 18532 func_unref(varp->vval.v_string); 18533 /*FALLTHROUGH*/ 18534 case VAR_STRING: 18535 vim_free(varp->vval.v_string); 18536 varp->vval.v_string = NULL; 18537 break; 18538 case VAR_LIST: 18539 list_unref(varp->vval.v_list); 18540 varp->vval.v_list = NULL; 18541 break; 18542 case VAR_DICT: 18543 dict_unref(varp->vval.v_dict); 18544 varp->vval.v_dict = NULL; 18545 break; 18546 case VAR_NUMBER: 18547 varp->vval.v_number = 0; 18548 break; 18549 #ifdef FEAT_FLOAT 18550 case VAR_FLOAT: 18551 varp->vval.v_float = 0.0; 18552 break; 18553 #endif 18554 case VAR_UNKNOWN: 18555 break; 18556 default: 18557 EMSG2(_(e_intern2), "clear_tv()"); 18558 } 18559 varp->v_lock = 0; 18560 } 18561 } 18562 18563 /* 18564 * Set the value of a variable to NULL without freeing items. 18565 */ 18566 static void 18567 init_tv(varp) 18568 typval_T *varp; 18569 { 18570 if (varp != NULL) 18571 vim_memset(varp, 0, sizeof(typval_T)); 18572 } 18573 18574 /* 18575 * Get the number value of a variable. 18576 * If it is a String variable, uses vim_str2nr(). 18577 * For incompatible types, return 0. 18578 * get_tv_number_chk() is similar to get_tv_number(), but informs the 18579 * caller of incompatible types: it sets *denote to TRUE if "denote" 18580 * is not NULL or returns -1 otherwise. 18581 */ 18582 static long 18583 get_tv_number(varp) 18584 typval_T *varp; 18585 { 18586 int error = FALSE; 18587 18588 return get_tv_number_chk(varp, &error); /* return 0L on error */ 18589 } 18590 18591 long 18592 get_tv_number_chk(varp, denote) 18593 typval_T *varp; 18594 int *denote; 18595 { 18596 long n = 0L; 18597 18598 switch (varp->v_type) 18599 { 18600 case VAR_NUMBER: 18601 return (long)(varp->vval.v_number); 18602 #ifdef FEAT_FLOAT 18603 case VAR_FLOAT: 18604 EMSG(_("E805: Using a Float as a Number")); 18605 break; 18606 #endif 18607 case VAR_FUNC: 18608 EMSG(_("E703: Using a Funcref as a Number")); 18609 break; 18610 case VAR_STRING: 18611 if (varp->vval.v_string != NULL) 18612 vim_str2nr(varp->vval.v_string, NULL, NULL, 18613 TRUE, TRUE, &n, NULL); 18614 return n; 18615 case VAR_LIST: 18616 EMSG(_("E745: Using a List as a Number")); 18617 break; 18618 case VAR_DICT: 18619 EMSG(_("E728: Using a Dictionary as a Number")); 18620 break; 18621 default: 18622 EMSG2(_(e_intern2), "get_tv_number()"); 18623 break; 18624 } 18625 if (denote == NULL) /* useful for values that must be unsigned */ 18626 n = -1; 18627 else 18628 *denote = TRUE; 18629 return n; 18630 } 18631 18632 /* 18633 * Get the lnum from the first argument. 18634 * Also accepts ".", "$", etc., but that only works for the current buffer. 18635 * Returns -1 on error. 18636 */ 18637 static linenr_T 18638 get_tv_lnum(argvars) 18639 typval_T *argvars; 18640 { 18641 typval_T rettv; 18642 linenr_T lnum; 18643 18644 lnum = get_tv_number_chk(&argvars[0], NULL); 18645 if (lnum == 0) /* no valid number, try using line() */ 18646 { 18647 rettv.v_type = VAR_NUMBER; 18648 f_line(argvars, &rettv); 18649 lnum = rettv.vval.v_number; 18650 clear_tv(&rettv); 18651 } 18652 return lnum; 18653 } 18654 18655 /* 18656 * Get the lnum from the first argument. 18657 * Also accepts "$", then "buf" is used. 18658 * Returns 0 on error. 18659 */ 18660 static linenr_T 18661 get_tv_lnum_buf(argvars, buf) 18662 typval_T *argvars; 18663 buf_T *buf; 18664 { 18665 if (argvars[0].v_type == VAR_STRING 18666 && argvars[0].vval.v_string != NULL 18667 && argvars[0].vval.v_string[0] == '$' 18668 && buf != NULL) 18669 return buf->b_ml.ml_line_count; 18670 return get_tv_number_chk(&argvars[0], NULL); 18671 } 18672 18673 /* 18674 * Get the string value of a variable. 18675 * If it is a Number variable, the number is converted into a string. 18676 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 18677 * get_tv_string_buf() uses a given buffer. 18678 * If the String variable has never been set, return an empty string. 18679 * Never returns NULL; 18680 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 18681 * NULL on error. 18682 */ 18683 static char_u * 18684 get_tv_string(varp) 18685 typval_T *varp; 18686 { 18687 static char_u mybuf[NUMBUFLEN]; 18688 18689 return get_tv_string_buf(varp, mybuf); 18690 } 18691 18692 static char_u * 18693 get_tv_string_buf(varp, buf) 18694 typval_T *varp; 18695 char_u *buf; 18696 { 18697 char_u *res = get_tv_string_buf_chk(varp, buf); 18698 18699 return res != NULL ? res : (char_u *)""; 18700 } 18701 18702 char_u * 18703 get_tv_string_chk(varp) 18704 typval_T *varp; 18705 { 18706 static char_u mybuf[NUMBUFLEN]; 18707 18708 return get_tv_string_buf_chk(varp, mybuf); 18709 } 18710 18711 static char_u * 18712 get_tv_string_buf_chk(varp, buf) 18713 typval_T *varp; 18714 char_u *buf; 18715 { 18716 switch (varp->v_type) 18717 { 18718 case VAR_NUMBER: 18719 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 18720 return buf; 18721 case VAR_FUNC: 18722 EMSG(_("E729: using Funcref as a String")); 18723 break; 18724 case VAR_LIST: 18725 EMSG(_("E730: using List as a String")); 18726 break; 18727 case VAR_DICT: 18728 EMSG(_("E731: using Dictionary as a String")); 18729 break; 18730 #ifdef FEAT_FLOAT 18731 case VAR_FLOAT: 18732 EMSG(_("E806: using Float as a String")); 18733 break; 18734 #endif 18735 case VAR_STRING: 18736 if (varp->vval.v_string != NULL) 18737 return varp->vval.v_string; 18738 return (char_u *)""; 18739 default: 18740 EMSG2(_(e_intern2), "get_tv_string_buf()"); 18741 break; 18742 } 18743 return NULL; 18744 } 18745 18746 /* 18747 * Find variable "name" in the list of variables. 18748 * Return a pointer to it if found, NULL if not found. 18749 * Careful: "a:0" variables don't have a name. 18750 * When "htp" is not NULL we are writing to the variable, set "htp" to the 18751 * hashtab_T used. 18752 */ 18753 static dictitem_T * 18754 find_var(name, htp) 18755 char_u *name; 18756 hashtab_T **htp; 18757 { 18758 char_u *varname; 18759 hashtab_T *ht; 18760 18761 ht = find_var_ht(name, &varname); 18762 if (htp != NULL) 18763 *htp = ht; 18764 if (ht == NULL) 18765 return NULL; 18766 return find_var_in_ht(ht, varname, htp != NULL); 18767 } 18768 18769 /* 18770 * Find variable "varname" in hashtab "ht". 18771 * Returns NULL if not found. 18772 */ 18773 static dictitem_T * 18774 find_var_in_ht(ht, varname, writing) 18775 hashtab_T *ht; 18776 char_u *varname; 18777 int writing; 18778 { 18779 hashitem_T *hi; 18780 18781 if (*varname == NUL) 18782 { 18783 /* Must be something like "s:", otherwise "ht" would be NULL. */ 18784 switch (varname[-2]) 18785 { 18786 case 's': return &SCRIPT_SV(current_SID).sv_var; 18787 case 'g': return &globvars_var; 18788 case 'v': return &vimvars_var; 18789 case 'b': return &curbuf->b_bufvar; 18790 case 'w': return &curwin->w_winvar; 18791 #ifdef FEAT_WINDOWS 18792 case 't': return &curtab->tp_winvar; 18793 #endif 18794 case 'l': return current_funccal == NULL 18795 ? NULL : ¤t_funccal->l_vars_var; 18796 case 'a': return current_funccal == NULL 18797 ? NULL : ¤t_funccal->l_avars_var; 18798 } 18799 return NULL; 18800 } 18801 18802 hi = hash_find(ht, varname); 18803 if (HASHITEM_EMPTY(hi)) 18804 { 18805 /* For global variables we may try auto-loading the script. If it 18806 * worked find the variable again. Don't auto-load a script if it was 18807 * loaded already, otherwise it would be loaded every time when 18808 * checking if a function name is a Funcref variable. */ 18809 if (ht == &globvarht && !writing 18810 && script_autoload(varname, FALSE) && !aborting()) 18811 hi = hash_find(ht, varname); 18812 if (HASHITEM_EMPTY(hi)) 18813 return NULL; 18814 } 18815 return HI2DI(hi); 18816 } 18817 18818 /* 18819 * Find the hashtab used for a variable name. 18820 * Set "varname" to the start of name without ':'. 18821 */ 18822 static hashtab_T * 18823 find_var_ht(name, varname) 18824 char_u *name; 18825 char_u **varname; 18826 { 18827 hashitem_T *hi; 18828 18829 if (name[1] != ':') 18830 { 18831 /* The name must not start with a colon or #. */ 18832 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 18833 return NULL; 18834 *varname = name; 18835 18836 /* "version" is "v:version" in all scopes */ 18837 hi = hash_find(&compat_hashtab, name); 18838 if (!HASHITEM_EMPTY(hi)) 18839 return &compat_hashtab; 18840 18841 if (current_funccal == NULL) 18842 return &globvarht; /* global variable */ 18843 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 18844 } 18845 *varname = name + 2; 18846 if (*name == 'g') /* global variable */ 18847 return &globvarht; 18848 /* There must be no ':' or '#' in the rest of the name, unless g: is used 18849 */ 18850 if (vim_strchr(name + 2, ':') != NULL 18851 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 18852 return NULL; 18853 if (*name == 'b') /* buffer variable */ 18854 return &curbuf->b_vars.dv_hashtab; 18855 if (*name == 'w') /* window variable */ 18856 return &curwin->w_vars.dv_hashtab; 18857 #ifdef FEAT_WINDOWS 18858 if (*name == 't') /* tab page variable */ 18859 return &curtab->tp_vars.dv_hashtab; 18860 #endif 18861 if (*name == 'v') /* v: variable */ 18862 return &vimvarht; 18863 if (*name == 'a' && current_funccal != NULL) /* function argument */ 18864 return ¤t_funccal->l_avars.dv_hashtab; 18865 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 18866 return ¤t_funccal->l_vars.dv_hashtab; 18867 if (*name == 's' /* script variable */ 18868 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 18869 return &SCRIPT_VARS(current_SID); 18870 return NULL; 18871 } 18872 18873 /* 18874 * Get the string value of a (global/local) variable. 18875 * Returns NULL when it doesn't exist. 18876 */ 18877 char_u * 18878 get_var_value(name) 18879 char_u *name; 18880 { 18881 dictitem_T *v; 18882 18883 v = find_var(name, NULL); 18884 if (v == NULL) 18885 return NULL; 18886 return get_tv_string(&v->di_tv); 18887 } 18888 18889 /* 18890 * Allocate a new hashtab for a sourced script. It will be used while 18891 * sourcing this script and when executing functions defined in the script. 18892 */ 18893 void 18894 new_script_vars(id) 18895 scid_T id; 18896 { 18897 int i; 18898 hashtab_T *ht; 18899 scriptvar_T *sv; 18900 18901 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 18902 { 18903 /* Re-allocating ga_data means that an ht_array pointing to 18904 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 18905 * at its init value. Also reset "v_dict", it's always the same. */ 18906 for (i = 1; i <= ga_scripts.ga_len; ++i) 18907 { 18908 ht = &SCRIPT_VARS(i); 18909 if (ht->ht_mask == HT_INIT_SIZE - 1) 18910 ht->ht_array = ht->ht_smallarray; 18911 sv = &SCRIPT_SV(i); 18912 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 18913 } 18914 18915 while (ga_scripts.ga_len < id) 18916 { 18917 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 18918 init_var_dict(&sv->sv_dict, &sv->sv_var); 18919 ++ga_scripts.ga_len; 18920 } 18921 } 18922 } 18923 18924 /* 18925 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 18926 * point to it. 18927 */ 18928 void 18929 init_var_dict(dict, dict_var) 18930 dict_T *dict; 18931 dictitem_T *dict_var; 18932 { 18933 hash_init(&dict->dv_hashtab); 18934 dict->dv_refcount = DO_NOT_FREE_CNT; 18935 dict->dv_copyID = 0; 18936 dict_var->di_tv.vval.v_dict = dict; 18937 dict_var->di_tv.v_type = VAR_DICT; 18938 dict_var->di_tv.v_lock = VAR_FIXED; 18939 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18940 dict_var->di_key[0] = NUL; 18941 } 18942 18943 /* 18944 * Clean up a list of internal variables. 18945 * Frees all allocated variables and the value they contain. 18946 * Clears hashtab "ht", does not free it. 18947 */ 18948 void 18949 vars_clear(ht) 18950 hashtab_T *ht; 18951 { 18952 vars_clear_ext(ht, TRUE); 18953 } 18954 18955 /* 18956 * Like vars_clear(), but only free the value if "free_val" is TRUE. 18957 */ 18958 static void 18959 vars_clear_ext(ht, free_val) 18960 hashtab_T *ht; 18961 int free_val; 18962 { 18963 int todo; 18964 hashitem_T *hi; 18965 dictitem_T *v; 18966 18967 hash_lock(ht); 18968 todo = (int)ht->ht_used; 18969 for (hi = ht->ht_array; todo > 0; ++hi) 18970 { 18971 if (!HASHITEM_EMPTY(hi)) 18972 { 18973 --todo; 18974 18975 /* Free the variable. Don't remove it from the hashtab, 18976 * ht_array might change then. hash_clear() takes care of it 18977 * later. */ 18978 v = HI2DI(hi); 18979 if (free_val) 18980 clear_tv(&v->di_tv); 18981 if ((v->di_flags & DI_FLAGS_FIX) == 0) 18982 vim_free(v); 18983 } 18984 } 18985 hash_clear(ht); 18986 ht->ht_used = 0; 18987 } 18988 18989 /* 18990 * Delete a variable from hashtab "ht" at item "hi". 18991 * Clear the variable value and free the dictitem. 18992 */ 18993 static void 18994 delete_var(ht, hi) 18995 hashtab_T *ht; 18996 hashitem_T *hi; 18997 { 18998 dictitem_T *di = HI2DI(hi); 18999 19000 hash_remove(ht, hi); 19001 clear_tv(&di->di_tv); 19002 vim_free(di); 19003 } 19004 19005 /* 19006 * List the value of one internal variable. 19007 */ 19008 static void 19009 list_one_var(v, prefix, first) 19010 dictitem_T *v; 19011 char_u *prefix; 19012 int *first; 19013 { 19014 char_u *tofree; 19015 char_u *s; 19016 char_u numbuf[NUMBUFLEN]; 19017 19018 current_copyID += COPYID_INC; 19019 s = echo_string(&v->di_tv, &tofree, numbuf, current_copyID); 19020 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 19021 s == NULL ? (char_u *)"" : s, first); 19022 vim_free(tofree); 19023 } 19024 19025 static void 19026 list_one_var_a(prefix, name, type, string, first) 19027 char_u *prefix; 19028 char_u *name; 19029 int type; 19030 char_u *string; 19031 int *first; /* when TRUE clear rest of screen and set to FALSE */ 19032 { 19033 /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ 19034 msg_start(); 19035 msg_puts(prefix); 19036 if (name != NULL) /* "a:" vars don't have a name stored */ 19037 msg_puts(name); 19038 msg_putchar(' '); 19039 msg_advance(22); 19040 if (type == VAR_NUMBER) 19041 msg_putchar('#'); 19042 else if (type == VAR_FUNC) 19043 msg_putchar('*'); 19044 else if (type == VAR_LIST) 19045 { 19046 msg_putchar('['); 19047 if (*string == '[') 19048 ++string; 19049 } 19050 else if (type == VAR_DICT) 19051 { 19052 msg_putchar('{'); 19053 if (*string == '{') 19054 ++string; 19055 } 19056 else 19057 msg_putchar(' '); 19058 19059 msg_outtrans(string); 19060 19061 if (type == VAR_FUNC) 19062 msg_puts((char_u *)"()"); 19063 if (*first) 19064 { 19065 msg_clr_eos(); 19066 *first = FALSE; 19067 } 19068 } 19069 19070 /* 19071 * Set variable "name" to value in "tv". 19072 * If the variable already exists, the value is updated. 19073 * Otherwise the variable is created. 19074 */ 19075 static void 19076 set_var(name, tv, copy) 19077 char_u *name; 19078 typval_T *tv; 19079 int copy; /* make copy of value in "tv" */ 19080 { 19081 dictitem_T *v; 19082 char_u *varname; 19083 hashtab_T *ht; 19084 char_u *p; 19085 19086 if (tv->v_type == VAR_FUNC) 19087 { 19088 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 19089 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 19090 ? name[2] : name[0])) 19091 { 19092 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 19093 return; 19094 } 19095 if (function_exists(name)) 19096 { 19097 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 19098 name); 19099 return; 19100 } 19101 } 19102 19103 ht = find_var_ht(name, &varname); 19104 if (ht == NULL || *varname == NUL) 19105 { 19106 EMSG2(_(e_illvar), name); 19107 return; 19108 } 19109 19110 v = find_var_in_ht(ht, varname, TRUE); 19111 if (v != NULL) 19112 { 19113 /* existing variable, need to clear the value */ 19114 if (var_check_ro(v->di_flags, name) 19115 || tv_check_lock(v->di_tv.v_lock, name)) 19116 return; 19117 if (v->di_tv.v_type != tv->v_type 19118 && !((v->di_tv.v_type == VAR_STRING 19119 || v->di_tv.v_type == VAR_NUMBER) 19120 && (tv->v_type == VAR_STRING 19121 || tv->v_type == VAR_NUMBER)) 19122 #ifdef FEAT_FLOAT 19123 && !((v->di_tv.v_type == VAR_NUMBER 19124 || v->di_tv.v_type == VAR_FLOAT) 19125 && (tv->v_type == VAR_NUMBER 19126 || tv->v_type == VAR_FLOAT)) 19127 #endif 19128 ) 19129 { 19130 EMSG2(_("E706: Variable type mismatch for: %s"), name); 19131 return; 19132 } 19133 19134 /* 19135 * Handle setting internal v: variables separately: we don't change 19136 * the type. 19137 */ 19138 if (ht == &vimvarht) 19139 { 19140 if (v->di_tv.v_type == VAR_STRING) 19141 { 19142 vim_free(v->di_tv.vval.v_string); 19143 if (copy || tv->v_type != VAR_STRING) 19144 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 19145 else 19146 { 19147 /* Take over the string to avoid an extra alloc/free. */ 19148 v->di_tv.vval.v_string = tv->vval.v_string; 19149 tv->vval.v_string = NULL; 19150 } 19151 } 19152 else if (v->di_tv.v_type != VAR_NUMBER) 19153 EMSG2(_(e_intern2), "set_var()"); 19154 else 19155 { 19156 v->di_tv.vval.v_number = get_tv_number(tv); 19157 if (STRCMP(varname, "searchforward") == 0) 19158 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); 19159 } 19160 return; 19161 } 19162 19163 clear_tv(&v->di_tv); 19164 } 19165 else /* add a new variable */ 19166 { 19167 /* Can't add "v:" variable. */ 19168 if (ht == &vimvarht) 19169 { 19170 EMSG2(_(e_illvar), name); 19171 return; 19172 } 19173 19174 /* Make sure the variable name is valid. */ 19175 for (p = varname; *p != NUL; ++p) 19176 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 19177 && *p != AUTOLOAD_CHAR) 19178 { 19179 EMSG2(_(e_illvar), varname); 19180 return; 19181 } 19182 19183 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19184 + STRLEN(varname))); 19185 if (v == NULL) 19186 return; 19187 STRCPY(v->di_key, varname); 19188 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 19189 { 19190 vim_free(v); 19191 return; 19192 } 19193 v->di_flags = 0; 19194 } 19195 19196 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 19197 copy_tv(tv, &v->di_tv); 19198 else 19199 { 19200 v->di_tv = *tv; 19201 v->di_tv.v_lock = 0; 19202 init_tv(tv); 19203 } 19204 } 19205 19206 /* 19207 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 19208 * Also give an error message. 19209 */ 19210 static int 19211 var_check_ro(flags, name) 19212 int flags; 19213 char_u *name; 19214 { 19215 if (flags & DI_FLAGS_RO) 19216 { 19217 EMSG2(_(e_readonlyvar), name); 19218 return TRUE; 19219 } 19220 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 19221 { 19222 EMSG2(_(e_readonlysbx), name); 19223 return TRUE; 19224 } 19225 return FALSE; 19226 } 19227 19228 /* 19229 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 19230 * Also give an error message. 19231 */ 19232 static int 19233 var_check_fixed(flags, name) 19234 int flags; 19235 char_u *name; 19236 { 19237 if (flags & DI_FLAGS_FIX) 19238 { 19239 EMSG2(_("E795: Cannot delete variable %s"), name); 19240 return TRUE; 19241 } 19242 return FALSE; 19243 } 19244 19245 /* 19246 * Return TRUE if typeval "tv" is set to be locked (immutable). 19247 * Also give an error message, using "name". 19248 */ 19249 static int 19250 tv_check_lock(lock, name) 19251 int lock; 19252 char_u *name; 19253 { 19254 if (lock & VAR_LOCKED) 19255 { 19256 EMSG2(_("E741: Value is locked: %s"), 19257 name == NULL ? (char_u *)_("Unknown") : name); 19258 return TRUE; 19259 } 19260 if (lock & VAR_FIXED) 19261 { 19262 EMSG2(_("E742: Cannot change value of %s"), 19263 name == NULL ? (char_u *)_("Unknown") : name); 19264 return TRUE; 19265 } 19266 return FALSE; 19267 } 19268 19269 /* 19270 * Copy the values from typval_T "from" to typval_T "to". 19271 * When needed allocates string or increases reference count. 19272 * Does not make a copy of a list or dict but copies the reference! 19273 * It is OK for "from" and "to" to point to the same item. This is used to 19274 * make a copy later. 19275 */ 19276 static void 19277 copy_tv(from, to) 19278 typval_T *from; 19279 typval_T *to; 19280 { 19281 to->v_type = from->v_type; 19282 to->v_lock = 0; 19283 switch (from->v_type) 19284 { 19285 case VAR_NUMBER: 19286 to->vval.v_number = from->vval.v_number; 19287 break; 19288 #ifdef FEAT_FLOAT 19289 case VAR_FLOAT: 19290 to->vval.v_float = from->vval.v_float; 19291 break; 19292 #endif 19293 case VAR_STRING: 19294 case VAR_FUNC: 19295 if (from->vval.v_string == NULL) 19296 to->vval.v_string = NULL; 19297 else 19298 { 19299 to->vval.v_string = vim_strsave(from->vval.v_string); 19300 if (from->v_type == VAR_FUNC) 19301 func_ref(to->vval.v_string); 19302 } 19303 break; 19304 case VAR_LIST: 19305 if (from->vval.v_list == NULL) 19306 to->vval.v_list = NULL; 19307 else 19308 { 19309 to->vval.v_list = from->vval.v_list; 19310 ++to->vval.v_list->lv_refcount; 19311 } 19312 break; 19313 case VAR_DICT: 19314 if (from->vval.v_dict == NULL) 19315 to->vval.v_dict = NULL; 19316 else 19317 { 19318 to->vval.v_dict = from->vval.v_dict; 19319 ++to->vval.v_dict->dv_refcount; 19320 } 19321 break; 19322 default: 19323 EMSG2(_(e_intern2), "copy_tv()"); 19324 break; 19325 } 19326 } 19327 19328 /* 19329 * Make a copy of an item. 19330 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 19331 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 19332 * reference to an already copied list/dict can be used. 19333 * Returns FAIL or OK. 19334 */ 19335 static int 19336 item_copy(from, to, deep, copyID) 19337 typval_T *from; 19338 typval_T *to; 19339 int deep; 19340 int copyID; 19341 { 19342 static int recurse = 0; 19343 int ret = OK; 19344 19345 if (recurse >= DICT_MAXNEST) 19346 { 19347 EMSG(_("E698: variable nested too deep for making a copy")); 19348 return FAIL; 19349 } 19350 ++recurse; 19351 19352 switch (from->v_type) 19353 { 19354 case VAR_NUMBER: 19355 #ifdef FEAT_FLOAT 19356 case VAR_FLOAT: 19357 #endif 19358 case VAR_STRING: 19359 case VAR_FUNC: 19360 copy_tv(from, to); 19361 break; 19362 case VAR_LIST: 19363 to->v_type = VAR_LIST; 19364 to->v_lock = 0; 19365 if (from->vval.v_list == NULL) 19366 to->vval.v_list = NULL; 19367 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 19368 { 19369 /* use the copy made earlier */ 19370 to->vval.v_list = from->vval.v_list->lv_copylist; 19371 ++to->vval.v_list->lv_refcount; 19372 } 19373 else 19374 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 19375 if (to->vval.v_list == NULL) 19376 ret = FAIL; 19377 break; 19378 case VAR_DICT: 19379 to->v_type = VAR_DICT; 19380 to->v_lock = 0; 19381 if (from->vval.v_dict == NULL) 19382 to->vval.v_dict = NULL; 19383 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 19384 { 19385 /* use the copy made earlier */ 19386 to->vval.v_dict = from->vval.v_dict->dv_copydict; 19387 ++to->vval.v_dict->dv_refcount; 19388 } 19389 else 19390 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 19391 if (to->vval.v_dict == NULL) 19392 ret = FAIL; 19393 break; 19394 default: 19395 EMSG2(_(e_intern2), "item_copy()"); 19396 ret = FAIL; 19397 } 19398 --recurse; 19399 return ret; 19400 } 19401 19402 /* 19403 * ":echo expr1 ..." print each argument separated with a space, add a 19404 * newline at the end. 19405 * ":echon expr1 ..." print each argument plain. 19406 */ 19407 void 19408 ex_echo(eap) 19409 exarg_T *eap; 19410 { 19411 char_u *arg = eap->arg; 19412 typval_T rettv; 19413 char_u *tofree; 19414 char_u *p; 19415 int needclr = TRUE; 19416 int atstart = TRUE; 19417 char_u numbuf[NUMBUFLEN]; 19418 19419 if (eap->skip) 19420 ++emsg_skip; 19421 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 19422 { 19423 /* If eval1() causes an error message the text from the command may 19424 * still need to be cleared. E.g., "echo 22,44". */ 19425 need_clr_eos = needclr; 19426 19427 p = arg; 19428 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 19429 { 19430 /* 19431 * Report the invalid expression unless the expression evaluation 19432 * has been cancelled due to an aborting error, an interrupt, or an 19433 * exception. 19434 */ 19435 if (!aborting()) 19436 EMSG2(_(e_invexpr2), p); 19437 need_clr_eos = FALSE; 19438 break; 19439 } 19440 need_clr_eos = FALSE; 19441 19442 if (!eap->skip) 19443 { 19444 if (atstart) 19445 { 19446 atstart = FALSE; 19447 /* Call msg_start() after eval1(), evaluating the expression 19448 * may cause a message to appear. */ 19449 if (eap->cmdidx == CMD_echo) 19450 msg_start(); 19451 } 19452 else if (eap->cmdidx == CMD_echo) 19453 msg_puts_attr((char_u *)" ", echo_attr); 19454 current_copyID += COPYID_INC; 19455 p = echo_string(&rettv, &tofree, numbuf, current_copyID); 19456 if (p != NULL) 19457 for ( ; *p != NUL && !got_int; ++p) 19458 { 19459 if (*p == '\n' || *p == '\r' || *p == TAB) 19460 { 19461 if (*p != TAB && needclr) 19462 { 19463 /* remove any text still there from the command */ 19464 msg_clr_eos(); 19465 needclr = FALSE; 19466 } 19467 msg_putchar_attr(*p, echo_attr); 19468 } 19469 else 19470 { 19471 #ifdef FEAT_MBYTE 19472 if (has_mbyte) 19473 { 19474 int i = (*mb_ptr2len)(p); 19475 19476 (void)msg_outtrans_len_attr(p, i, echo_attr); 19477 p += i - 1; 19478 } 19479 else 19480 #endif 19481 (void)msg_outtrans_len_attr(p, 1, echo_attr); 19482 } 19483 } 19484 vim_free(tofree); 19485 } 19486 clear_tv(&rettv); 19487 arg = skipwhite(arg); 19488 } 19489 eap->nextcmd = check_nextcmd(arg); 19490 19491 if (eap->skip) 19492 --emsg_skip; 19493 else 19494 { 19495 /* remove text that may still be there from the command */ 19496 if (needclr) 19497 msg_clr_eos(); 19498 if (eap->cmdidx == CMD_echo) 19499 msg_end(); 19500 } 19501 } 19502 19503 /* 19504 * ":echohl {name}". 19505 */ 19506 void 19507 ex_echohl(eap) 19508 exarg_T *eap; 19509 { 19510 int id; 19511 19512 id = syn_name2id(eap->arg); 19513 if (id == 0) 19514 echo_attr = 0; 19515 else 19516 echo_attr = syn_id2attr(id); 19517 } 19518 19519 /* 19520 * ":execute expr1 ..." execute the result of an expression. 19521 * ":echomsg expr1 ..." Print a message 19522 * ":echoerr expr1 ..." Print an error 19523 * Each gets spaces around each argument and a newline at the end for 19524 * echo commands 19525 */ 19526 void 19527 ex_execute(eap) 19528 exarg_T *eap; 19529 { 19530 char_u *arg = eap->arg; 19531 typval_T rettv; 19532 int ret = OK; 19533 char_u *p; 19534 garray_T ga; 19535 int len; 19536 int save_did_emsg; 19537 19538 ga_init2(&ga, 1, 80); 19539 19540 if (eap->skip) 19541 ++emsg_skip; 19542 while (*arg != NUL && *arg != '|' && *arg != '\n') 19543 { 19544 p = arg; 19545 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 19546 { 19547 /* 19548 * Report the invalid expression unless the expression evaluation 19549 * has been cancelled due to an aborting error, an interrupt, or an 19550 * exception. 19551 */ 19552 if (!aborting()) 19553 EMSG2(_(e_invexpr2), p); 19554 ret = FAIL; 19555 break; 19556 } 19557 19558 if (!eap->skip) 19559 { 19560 p = get_tv_string(&rettv); 19561 len = (int)STRLEN(p); 19562 if (ga_grow(&ga, len + 2) == FAIL) 19563 { 19564 clear_tv(&rettv); 19565 ret = FAIL; 19566 break; 19567 } 19568 if (ga.ga_len) 19569 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 19570 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 19571 ga.ga_len += len; 19572 } 19573 19574 clear_tv(&rettv); 19575 arg = skipwhite(arg); 19576 } 19577 19578 if (ret != FAIL && ga.ga_data != NULL) 19579 { 19580 if (eap->cmdidx == CMD_echomsg) 19581 { 19582 MSG_ATTR(ga.ga_data, echo_attr); 19583 out_flush(); 19584 } 19585 else if (eap->cmdidx == CMD_echoerr) 19586 { 19587 /* We don't want to abort following commands, restore did_emsg. */ 19588 save_did_emsg = did_emsg; 19589 EMSG((char_u *)ga.ga_data); 19590 if (!force_abort) 19591 did_emsg = save_did_emsg; 19592 } 19593 else if (eap->cmdidx == CMD_execute) 19594 do_cmdline((char_u *)ga.ga_data, 19595 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 19596 } 19597 19598 ga_clear(&ga); 19599 19600 if (eap->skip) 19601 --emsg_skip; 19602 19603 eap->nextcmd = check_nextcmd(arg); 19604 } 19605 19606 /* 19607 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 19608 * "arg" points to the "&" or '+' when called, to "option" when returning. 19609 * Returns NULL when no option name found. Otherwise pointer to the char 19610 * after the option name. 19611 */ 19612 static char_u * 19613 find_option_end(arg, opt_flags) 19614 char_u **arg; 19615 int *opt_flags; 19616 { 19617 char_u *p = *arg; 19618 19619 ++p; 19620 if (*p == 'g' && p[1] == ':') 19621 { 19622 *opt_flags = OPT_GLOBAL; 19623 p += 2; 19624 } 19625 else if (*p == 'l' && p[1] == ':') 19626 { 19627 *opt_flags = OPT_LOCAL; 19628 p += 2; 19629 } 19630 else 19631 *opt_flags = 0; 19632 19633 if (!ASCII_ISALPHA(*p)) 19634 return NULL; 19635 *arg = p; 19636 19637 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 19638 p += 4; /* termcap option */ 19639 else 19640 while (ASCII_ISALPHA(*p)) 19641 ++p; 19642 return p; 19643 } 19644 19645 /* 19646 * ":function" 19647 */ 19648 void 19649 ex_function(eap) 19650 exarg_T *eap; 19651 { 19652 char_u *theline; 19653 int j; 19654 int c; 19655 int saved_did_emsg; 19656 char_u *name = NULL; 19657 char_u *p; 19658 char_u *arg; 19659 char_u *line_arg = NULL; 19660 garray_T newargs; 19661 garray_T newlines; 19662 int varargs = FALSE; 19663 int mustend = FALSE; 19664 int flags = 0; 19665 ufunc_T *fp; 19666 int indent; 19667 int nesting; 19668 char_u *skip_until = NULL; 19669 dictitem_T *v; 19670 funcdict_T fudi; 19671 static int func_nr = 0; /* number for nameless function */ 19672 int paren; 19673 hashtab_T *ht; 19674 int todo; 19675 hashitem_T *hi; 19676 int sourcing_lnum_off; 19677 19678 /* 19679 * ":function" without argument: list functions. 19680 */ 19681 if (ends_excmd(*eap->arg)) 19682 { 19683 if (!eap->skip) 19684 { 19685 todo = (int)func_hashtab.ht_used; 19686 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 19687 { 19688 if (!HASHITEM_EMPTY(hi)) 19689 { 19690 --todo; 19691 fp = HI2UF(hi); 19692 if (!isdigit(*fp->uf_name)) 19693 list_func_head(fp, FALSE); 19694 } 19695 } 19696 } 19697 eap->nextcmd = check_nextcmd(eap->arg); 19698 return; 19699 } 19700 19701 /* 19702 * ":function /pat": list functions matching pattern. 19703 */ 19704 if (*eap->arg == '/') 19705 { 19706 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 19707 if (!eap->skip) 19708 { 19709 regmatch_T regmatch; 19710 19711 c = *p; 19712 *p = NUL; 19713 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 19714 *p = c; 19715 if (regmatch.regprog != NULL) 19716 { 19717 regmatch.rm_ic = p_ic; 19718 19719 todo = (int)func_hashtab.ht_used; 19720 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 19721 { 19722 if (!HASHITEM_EMPTY(hi)) 19723 { 19724 --todo; 19725 fp = HI2UF(hi); 19726 if (!isdigit(*fp->uf_name) 19727 && vim_regexec(®match, fp->uf_name, 0)) 19728 list_func_head(fp, FALSE); 19729 } 19730 } 19731 vim_free(regmatch.regprog); 19732 } 19733 } 19734 if (*p == '/') 19735 ++p; 19736 eap->nextcmd = check_nextcmd(p); 19737 return; 19738 } 19739 19740 /* 19741 * Get the function name. There are these situations: 19742 * func normal function name 19743 * "name" == func, "fudi.fd_dict" == NULL 19744 * dict.func new dictionary entry 19745 * "name" == NULL, "fudi.fd_dict" set, 19746 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 19747 * dict.func existing dict entry with a Funcref 19748 * "name" == func, "fudi.fd_dict" set, 19749 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 19750 * dict.func existing dict entry that's not a Funcref 19751 * "name" == NULL, "fudi.fd_dict" set, 19752 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 19753 */ 19754 p = eap->arg; 19755 name = trans_function_name(&p, eap->skip, 0, &fudi); 19756 paren = (vim_strchr(p, '(') != NULL); 19757 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 19758 { 19759 /* 19760 * Return on an invalid expression in braces, unless the expression 19761 * evaluation has been cancelled due to an aborting error, an 19762 * interrupt, or an exception. 19763 */ 19764 if (!aborting()) 19765 { 19766 if (!eap->skip && fudi.fd_newkey != NULL) 19767 EMSG2(_(e_dictkey), fudi.fd_newkey); 19768 vim_free(fudi.fd_newkey); 19769 return; 19770 } 19771 else 19772 eap->skip = TRUE; 19773 } 19774 19775 /* An error in a function call during evaluation of an expression in magic 19776 * braces should not cause the function not to be defined. */ 19777 saved_did_emsg = did_emsg; 19778 did_emsg = FALSE; 19779 19780 /* 19781 * ":function func" with only function name: list function. 19782 */ 19783 if (!paren) 19784 { 19785 if (!ends_excmd(*skipwhite(p))) 19786 { 19787 EMSG(_(e_trailing)); 19788 goto ret_free; 19789 } 19790 eap->nextcmd = check_nextcmd(p); 19791 if (eap->nextcmd != NULL) 19792 *p = NUL; 19793 if (!eap->skip && !got_int) 19794 { 19795 fp = find_func(name); 19796 if (fp != NULL) 19797 { 19798 list_func_head(fp, TRUE); 19799 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 19800 { 19801 if (FUNCLINE(fp, j) == NULL) 19802 continue; 19803 msg_putchar('\n'); 19804 msg_outnum((long)(j + 1)); 19805 if (j < 9) 19806 msg_putchar(' '); 19807 if (j < 99) 19808 msg_putchar(' '); 19809 msg_prt_line(FUNCLINE(fp, j), FALSE); 19810 out_flush(); /* show a line at a time */ 19811 ui_breakcheck(); 19812 } 19813 if (!got_int) 19814 { 19815 msg_putchar('\n'); 19816 msg_puts((char_u *)" endfunction"); 19817 } 19818 } 19819 else 19820 emsg_funcname(N_("E123: Undefined function: %s"), name); 19821 } 19822 goto ret_free; 19823 } 19824 19825 /* 19826 * ":function name(arg1, arg2)" Define function. 19827 */ 19828 p = skipwhite(p); 19829 if (*p != '(') 19830 { 19831 if (!eap->skip) 19832 { 19833 EMSG2(_("E124: Missing '(': %s"), eap->arg); 19834 goto ret_free; 19835 } 19836 /* attempt to continue by skipping some text */ 19837 if (vim_strchr(p, '(') != NULL) 19838 p = vim_strchr(p, '('); 19839 } 19840 p = skipwhite(p + 1); 19841 19842 ga_init2(&newargs, (int)sizeof(char_u *), 3); 19843 ga_init2(&newlines, (int)sizeof(char_u *), 3); 19844 19845 if (!eap->skip) 19846 { 19847 /* Check the name of the function. Unless it's a dictionary function 19848 * (that we are overwriting). */ 19849 if (name != NULL) 19850 arg = name; 19851 else 19852 arg = fudi.fd_newkey; 19853 if (arg != NULL && (fudi.fd_di == NULL 19854 || fudi.fd_di->di_tv.v_type != VAR_FUNC)) 19855 { 19856 if (*arg == K_SPECIAL) 19857 j = 3; 19858 else 19859 j = 0; 19860 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 19861 : eval_isnamec(arg[j]))) 19862 ++j; 19863 if (arg[j] != NUL) 19864 emsg_funcname((char *)e_invarg2, arg); 19865 } 19866 } 19867 19868 /* 19869 * Isolate the arguments: "arg1, arg2, ...)" 19870 */ 19871 while (*p != ')') 19872 { 19873 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 19874 { 19875 varargs = TRUE; 19876 p += 3; 19877 mustend = TRUE; 19878 } 19879 else 19880 { 19881 arg = p; 19882 while (ASCII_ISALNUM(*p) || *p == '_') 19883 ++p; 19884 if (arg == p || isdigit(*arg) 19885 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 19886 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 19887 { 19888 if (!eap->skip) 19889 EMSG2(_("E125: Illegal argument: %s"), arg); 19890 break; 19891 } 19892 if (ga_grow(&newargs, 1) == FAIL) 19893 goto erret; 19894 c = *p; 19895 *p = NUL; 19896 arg = vim_strsave(arg); 19897 if (arg == NULL) 19898 goto erret; 19899 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 19900 *p = c; 19901 newargs.ga_len++; 19902 if (*p == ',') 19903 ++p; 19904 else 19905 mustend = TRUE; 19906 } 19907 p = skipwhite(p); 19908 if (mustend && *p != ')') 19909 { 19910 if (!eap->skip) 19911 EMSG2(_(e_invarg2), eap->arg); 19912 break; 19913 } 19914 } 19915 ++p; /* skip the ')' */ 19916 19917 /* find extra arguments "range", "dict" and "abort" */ 19918 for (;;) 19919 { 19920 p = skipwhite(p); 19921 if (STRNCMP(p, "range", 5) == 0) 19922 { 19923 flags |= FC_RANGE; 19924 p += 5; 19925 } 19926 else if (STRNCMP(p, "dict", 4) == 0) 19927 { 19928 flags |= FC_DICT; 19929 p += 4; 19930 } 19931 else if (STRNCMP(p, "abort", 5) == 0) 19932 { 19933 flags |= FC_ABORT; 19934 p += 5; 19935 } 19936 else 19937 break; 19938 } 19939 19940 /* When there is a line break use what follows for the function body. 19941 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 19942 if (*p == '\n') 19943 line_arg = p + 1; 19944 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 19945 EMSG(_(e_trailing)); 19946 19947 /* 19948 * Read the body of the function, until ":endfunction" is found. 19949 */ 19950 if (KeyTyped) 19951 { 19952 /* Check if the function already exists, don't let the user type the 19953 * whole function before telling him it doesn't work! For a script we 19954 * need to skip the body to be able to find what follows. */ 19955 if (!eap->skip && !eap->forceit) 19956 { 19957 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 19958 EMSG(_(e_funcdict)); 19959 else if (name != NULL && find_func(name) != NULL) 19960 emsg_funcname(e_funcexts, name); 19961 } 19962 19963 if (!eap->skip && did_emsg) 19964 goto erret; 19965 19966 msg_putchar('\n'); /* don't overwrite the function name */ 19967 cmdline_row = msg_row; 19968 } 19969 19970 indent = 2; 19971 nesting = 0; 19972 for (;;) 19973 { 19974 msg_scroll = TRUE; 19975 need_wait_return = FALSE; 19976 sourcing_lnum_off = sourcing_lnum; 19977 19978 if (line_arg != NULL) 19979 { 19980 /* Use eap->arg, split up in parts by line breaks. */ 19981 theline = line_arg; 19982 p = vim_strchr(theline, '\n'); 19983 if (p == NULL) 19984 line_arg += STRLEN(line_arg); 19985 else 19986 { 19987 *p = NUL; 19988 line_arg = p + 1; 19989 } 19990 } 19991 else if (eap->getline == NULL) 19992 theline = getcmdline(':', 0L, indent); 19993 else 19994 theline = eap->getline(':', eap->cookie, indent); 19995 if (KeyTyped) 19996 lines_left = Rows - 1; 19997 if (theline == NULL) 19998 { 19999 EMSG(_("E126: Missing :endfunction")); 20000 goto erret; 20001 } 20002 20003 /* Detect line continuation: sourcing_lnum increased more than one. */ 20004 if (sourcing_lnum > sourcing_lnum_off + 1) 20005 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 20006 else 20007 sourcing_lnum_off = 0; 20008 20009 if (skip_until != NULL) 20010 { 20011 /* between ":append" and "." and between ":python <<EOF" and "EOF" 20012 * don't check for ":endfunc". */ 20013 if (STRCMP(theline, skip_until) == 0) 20014 { 20015 vim_free(skip_until); 20016 skip_until = NULL; 20017 } 20018 } 20019 else 20020 { 20021 /* skip ':' and blanks*/ 20022 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 20023 ; 20024 20025 /* Check for "endfunction". */ 20026 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 20027 { 20028 if (line_arg == NULL) 20029 vim_free(theline); 20030 break; 20031 } 20032 20033 /* Increase indent inside "if", "while", "for" and "try", decrease 20034 * at "end". */ 20035 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 20036 indent -= 2; 20037 else if (STRNCMP(p, "if", 2) == 0 20038 || STRNCMP(p, "wh", 2) == 0 20039 || STRNCMP(p, "for", 3) == 0 20040 || STRNCMP(p, "try", 3) == 0) 20041 indent += 2; 20042 20043 /* Check for defining a function inside this function. */ 20044 if (checkforcmd(&p, "function", 2)) 20045 { 20046 if (*p == '!') 20047 p = skipwhite(p + 1); 20048 p += eval_fname_script(p); 20049 if (ASCII_ISALPHA(*p)) 20050 { 20051 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 20052 if (*skipwhite(p) == '(') 20053 { 20054 ++nesting; 20055 indent += 2; 20056 } 20057 } 20058 } 20059 20060 /* Check for ":append" or ":insert". */ 20061 p = skip_range(p, NULL); 20062 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 20063 || (p[0] == 'i' 20064 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 20065 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 20066 skip_until = vim_strsave((char_u *)"."); 20067 20068 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 20069 arg = skipwhite(skiptowhite(p)); 20070 if (arg[0] == '<' && arg[1] =='<' 20071 && ((p[0] == 'p' && p[1] == 'y' 20072 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 20073 || (p[0] == 'p' && p[1] == 'e' 20074 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 20075 || (p[0] == 't' && p[1] == 'c' 20076 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 20077 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 20078 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 20079 || (p[0] == 'm' && p[1] == 'z' 20080 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 20081 )) 20082 { 20083 /* ":python <<" continues until a dot, like ":append" */ 20084 p = skipwhite(arg + 2); 20085 if (*p == NUL) 20086 skip_until = vim_strsave((char_u *)"."); 20087 else 20088 skip_until = vim_strsave(p); 20089 } 20090 } 20091 20092 /* Add the line to the function. */ 20093 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 20094 { 20095 if (line_arg == NULL) 20096 vim_free(theline); 20097 goto erret; 20098 } 20099 20100 /* Copy the line to newly allocated memory. get_one_sourceline() 20101 * allocates 250 bytes per line, this saves 80% on average. The cost 20102 * is an extra alloc/free. */ 20103 p = vim_strsave(theline); 20104 if (p != NULL) 20105 { 20106 if (line_arg == NULL) 20107 vim_free(theline); 20108 theline = p; 20109 } 20110 20111 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 20112 20113 /* Add NULL lines for continuation lines, so that the line count is 20114 * equal to the index in the growarray. */ 20115 while (sourcing_lnum_off-- > 0) 20116 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 20117 20118 /* Check for end of eap->arg. */ 20119 if (line_arg != NULL && *line_arg == NUL) 20120 line_arg = NULL; 20121 } 20122 20123 /* Don't define the function when skipping commands or when an error was 20124 * detected. */ 20125 if (eap->skip || did_emsg) 20126 goto erret; 20127 20128 /* 20129 * If there are no errors, add the function 20130 */ 20131 if (fudi.fd_dict == NULL) 20132 { 20133 v = find_var(name, &ht); 20134 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 20135 { 20136 emsg_funcname(N_("E707: Function name conflicts with variable: %s"), 20137 name); 20138 goto erret; 20139 } 20140 20141 fp = find_func(name); 20142 if (fp != NULL) 20143 { 20144 if (!eap->forceit) 20145 { 20146 emsg_funcname(e_funcexts, name); 20147 goto erret; 20148 } 20149 if (fp->uf_calls > 0) 20150 { 20151 emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), 20152 name); 20153 goto erret; 20154 } 20155 /* redefine existing function */ 20156 ga_clear_strings(&(fp->uf_args)); 20157 ga_clear_strings(&(fp->uf_lines)); 20158 vim_free(name); 20159 name = NULL; 20160 } 20161 } 20162 else 20163 { 20164 char numbuf[20]; 20165 20166 fp = NULL; 20167 if (fudi.fd_newkey == NULL && !eap->forceit) 20168 { 20169 EMSG(_(e_funcdict)); 20170 goto erret; 20171 } 20172 if (fudi.fd_di == NULL) 20173 { 20174 /* Can't add a function to a locked dictionary */ 20175 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 20176 goto erret; 20177 } 20178 /* Can't change an existing function if it is locked */ 20179 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 20180 goto erret; 20181 20182 /* Give the function a sequential number. Can only be used with a 20183 * Funcref! */ 20184 vim_free(name); 20185 sprintf(numbuf, "%d", ++func_nr); 20186 name = vim_strsave((char_u *)numbuf); 20187 if (name == NULL) 20188 goto erret; 20189 } 20190 20191 if (fp == NULL) 20192 { 20193 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 20194 { 20195 int slen, plen; 20196 char_u *scriptname; 20197 20198 /* Check that the autoload name matches the script name. */ 20199 j = FAIL; 20200 if (sourcing_name != NULL) 20201 { 20202 scriptname = autoload_name(name); 20203 if (scriptname != NULL) 20204 { 20205 p = vim_strchr(scriptname, '/'); 20206 plen = (int)STRLEN(p); 20207 slen = (int)STRLEN(sourcing_name); 20208 if (slen > plen && fnamecmp(p, 20209 sourcing_name + slen - plen) == 0) 20210 j = OK; 20211 vim_free(scriptname); 20212 } 20213 } 20214 if (j == FAIL) 20215 { 20216 EMSG2(_("E746: Function name does not match script file name: %s"), name); 20217 goto erret; 20218 } 20219 } 20220 20221 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 20222 if (fp == NULL) 20223 goto erret; 20224 20225 if (fudi.fd_dict != NULL) 20226 { 20227 if (fudi.fd_di == NULL) 20228 { 20229 /* add new dict entry */ 20230 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 20231 if (fudi.fd_di == NULL) 20232 { 20233 vim_free(fp); 20234 goto erret; 20235 } 20236 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 20237 { 20238 vim_free(fudi.fd_di); 20239 vim_free(fp); 20240 goto erret; 20241 } 20242 } 20243 else 20244 /* overwrite existing dict entry */ 20245 clear_tv(&fudi.fd_di->di_tv); 20246 fudi.fd_di->di_tv.v_type = VAR_FUNC; 20247 fudi.fd_di->di_tv.v_lock = 0; 20248 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 20249 fp->uf_refcount = 1; 20250 20251 /* behave like "dict" was used */ 20252 flags |= FC_DICT; 20253 } 20254 20255 /* insert the new function in the function list */ 20256 STRCPY(fp->uf_name, name); 20257 hash_add(&func_hashtab, UF2HIKEY(fp)); 20258 } 20259 fp->uf_args = newargs; 20260 fp->uf_lines = newlines; 20261 #ifdef FEAT_PROFILE 20262 fp->uf_tml_count = NULL; 20263 fp->uf_tml_total = NULL; 20264 fp->uf_tml_self = NULL; 20265 fp->uf_profiling = FALSE; 20266 if (prof_def_func()) 20267 func_do_profile(fp); 20268 #endif 20269 fp->uf_varargs = varargs; 20270 fp->uf_flags = flags; 20271 fp->uf_calls = 0; 20272 fp->uf_script_ID = current_SID; 20273 goto ret_free; 20274 20275 erret: 20276 ga_clear_strings(&newargs); 20277 ga_clear_strings(&newlines); 20278 ret_free: 20279 vim_free(skip_until); 20280 vim_free(fudi.fd_newkey); 20281 vim_free(name); 20282 did_emsg |= saved_did_emsg; 20283 } 20284 20285 /* 20286 * Get a function name, translating "<SID>" and "<SNR>". 20287 * Also handles a Funcref in a List or Dictionary. 20288 * Returns the function name in allocated memory, or NULL for failure. 20289 * flags: 20290 * TFN_INT: internal function name OK 20291 * TFN_QUIET: be quiet 20292 * Advances "pp" to just after the function name (if no error). 20293 */ 20294 static char_u * 20295 trans_function_name(pp, skip, flags, fdp) 20296 char_u **pp; 20297 int skip; /* only find the end, don't evaluate */ 20298 int flags; 20299 funcdict_T *fdp; /* return: info about dictionary used */ 20300 { 20301 char_u *name = NULL; 20302 char_u *start; 20303 char_u *end; 20304 int lead; 20305 char_u sid_buf[20]; 20306 int len; 20307 lval_T lv; 20308 20309 if (fdp != NULL) 20310 vim_memset(fdp, 0, sizeof(funcdict_T)); 20311 start = *pp; 20312 20313 /* Check for hard coded <SNR>: already translated function ID (from a user 20314 * command). */ 20315 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 20316 && (*pp)[2] == (int)KE_SNR) 20317 { 20318 *pp += 3; 20319 len = get_id_len(pp) + 3; 20320 return vim_strnsave(start, len); 20321 } 20322 20323 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 20324 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 20325 lead = eval_fname_script(start); 20326 if (lead > 2) 20327 start += lead; 20328 20329 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 20330 lead > 2 ? 0 : FNE_CHECK_START); 20331 if (end == start) 20332 { 20333 if (!skip) 20334 EMSG(_("E129: Function name required")); 20335 goto theend; 20336 } 20337 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 20338 { 20339 /* 20340 * Report an invalid expression in braces, unless the expression 20341 * evaluation has been cancelled due to an aborting error, an 20342 * interrupt, or an exception. 20343 */ 20344 if (!aborting()) 20345 { 20346 if (end != NULL) 20347 EMSG2(_(e_invarg2), start); 20348 } 20349 else 20350 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 20351 goto theend; 20352 } 20353 20354 if (lv.ll_tv != NULL) 20355 { 20356 if (fdp != NULL) 20357 { 20358 fdp->fd_dict = lv.ll_dict; 20359 fdp->fd_newkey = lv.ll_newkey; 20360 lv.ll_newkey = NULL; 20361 fdp->fd_di = lv.ll_di; 20362 } 20363 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 20364 { 20365 name = vim_strsave(lv.ll_tv->vval.v_string); 20366 *pp = end; 20367 } 20368 else 20369 { 20370 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 20371 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 20372 EMSG(_(e_funcref)); 20373 else 20374 *pp = end; 20375 name = NULL; 20376 } 20377 goto theend; 20378 } 20379 20380 if (lv.ll_name == NULL) 20381 { 20382 /* Error found, but continue after the function name. */ 20383 *pp = end; 20384 goto theend; 20385 } 20386 20387 /* Check if the name is a Funcref. If so, use the value. */ 20388 if (lv.ll_exp_name != NULL) 20389 { 20390 len = (int)STRLEN(lv.ll_exp_name); 20391 name = deref_func_name(lv.ll_exp_name, &len); 20392 if (name == lv.ll_exp_name) 20393 name = NULL; 20394 } 20395 else 20396 { 20397 len = (int)(end - *pp); 20398 name = deref_func_name(*pp, &len); 20399 if (name == *pp) 20400 name = NULL; 20401 } 20402 if (name != NULL) 20403 { 20404 name = vim_strsave(name); 20405 *pp = end; 20406 goto theend; 20407 } 20408 20409 if (lv.ll_exp_name != NULL) 20410 { 20411 len = (int)STRLEN(lv.ll_exp_name); 20412 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 20413 && STRNCMP(lv.ll_name, "s:", 2) == 0) 20414 { 20415 /* When there was "s:" already or the name expanded to get a 20416 * leading "s:" then remove it. */ 20417 lv.ll_name += 2; 20418 len -= 2; 20419 lead = 2; 20420 } 20421 } 20422 else 20423 { 20424 if (lead == 2) /* skip over "s:" */ 20425 lv.ll_name += 2; 20426 len = (int)(end - lv.ll_name); 20427 } 20428 20429 /* 20430 * Copy the function name to allocated memory. 20431 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 20432 * Accept <SNR>123_name() outside a script. 20433 */ 20434 if (skip) 20435 lead = 0; /* do nothing */ 20436 else if (lead > 0) 20437 { 20438 lead = 3; 20439 if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) 20440 || eval_fname_sid(*pp)) 20441 { 20442 /* It's "s:" or "<SID>" */ 20443 if (current_SID <= 0) 20444 { 20445 EMSG(_(e_usingsid)); 20446 goto theend; 20447 } 20448 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 20449 lead += (int)STRLEN(sid_buf); 20450 } 20451 } 20452 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 20453 { 20454 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 20455 goto theend; 20456 } 20457 name = alloc((unsigned)(len + lead + 1)); 20458 if (name != NULL) 20459 { 20460 if (lead > 0) 20461 { 20462 name[0] = K_SPECIAL; 20463 name[1] = KS_EXTRA; 20464 name[2] = (int)KE_SNR; 20465 if (lead > 3) /* If it's "<SID>" */ 20466 STRCPY(name + 3, sid_buf); 20467 } 20468 mch_memmove(name + lead, lv.ll_name, (size_t)len); 20469 name[len + lead] = NUL; 20470 } 20471 *pp = end; 20472 20473 theend: 20474 clear_lval(&lv); 20475 return name; 20476 } 20477 20478 /* 20479 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 20480 * Return 2 if "p" starts with "s:". 20481 * Return 0 otherwise. 20482 */ 20483 static int 20484 eval_fname_script(p) 20485 char_u *p; 20486 { 20487 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 20488 || STRNICMP(p + 1, "SNR>", 4) == 0)) 20489 return 5; 20490 if (p[0] == 's' && p[1] == ':') 20491 return 2; 20492 return 0; 20493 } 20494 20495 /* 20496 * Return TRUE if "p" starts with "<SID>" or "s:". 20497 * Only works if eval_fname_script() returned non-zero for "p"! 20498 */ 20499 static int 20500 eval_fname_sid(p) 20501 char_u *p; 20502 { 20503 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 20504 } 20505 20506 /* 20507 * List the head of the function: "name(arg1, arg2)". 20508 */ 20509 static void 20510 list_func_head(fp, indent) 20511 ufunc_T *fp; 20512 int indent; 20513 { 20514 int j; 20515 20516 msg_start(); 20517 if (indent) 20518 MSG_PUTS(" "); 20519 MSG_PUTS("function "); 20520 if (fp->uf_name[0] == K_SPECIAL) 20521 { 20522 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 20523 msg_puts(fp->uf_name + 3); 20524 } 20525 else 20526 msg_puts(fp->uf_name); 20527 msg_putchar('('); 20528 for (j = 0; j < fp->uf_args.ga_len; ++j) 20529 { 20530 if (j) 20531 MSG_PUTS(", "); 20532 msg_puts(FUNCARG(fp, j)); 20533 } 20534 if (fp->uf_varargs) 20535 { 20536 if (j) 20537 MSG_PUTS(", "); 20538 MSG_PUTS("..."); 20539 } 20540 msg_putchar(')'); 20541 msg_clr_eos(); 20542 if (p_verbose > 0) 20543 last_set_msg(fp->uf_script_ID); 20544 } 20545 20546 /* 20547 * Find a function by name, return pointer to it in ufuncs. 20548 * Return NULL for unknown function. 20549 */ 20550 static ufunc_T * 20551 find_func(name) 20552 char_u *name; 20553 { 20554 hashitem_T *hi; 20555 20556 hi = hash_find(&func_hashtab, name); 20557 if (!HASHITEM_EMPTY(hi)) 20558 return HI2UF(hi); 20559 return NULL; 20560 } 20561 20562 #if defined(EXITFREE) || defined(PROTO) 20563 void 20564 free_all_functions() 20565 { 20566 hashitem_T *hi; 20567 20568 /* Need to start all over every time, because func_free() may change the 20569 * hash table. */ 20570 while (func_hashtab.ht_used > 0) 20571 for (hi = func_hashtab.ht_array; ; ++hi) 20572 if (!HASHITEM_EMPTY(hi)) 20573 { 20574 func_free(HI2UF(hi)); 20575 break; 20576 } 20577 } 20578 #endif 20579 20580 /* 20581 * Return TRUE if a function "name" exists. 20582 */ 20583 static int 20584 function_exists(name) 20585 char_u *name; 20586 { 20587 char_u *nm = name; 20588 char_u *p; 20589 int n = FALSE; 20590 20591 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL); 20592 nm = skipwhite(nm); 20593 20594 /* Only accept "funcname", "funcname ", "funcname (..." and 20595 * "funcname(...", not "funcname!...". */ 20596 if (p != NULL && (*nm == NUL || *nm == '(')) 20597 { 20598 if (builtin_function(p)) 20599 n = (find_internal_func(p) >= 0); 20600 else 20601 n = (find_func(p) != NULL); 20602 } 20603 vim_free(p); 20604 return n; 20605 } 20606 20607 /* 20608 * Return TRUE if "name" looks like a builtin function name: starts with a 20609 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 20610 */ 20611 static int 20612 builtin_function(name) 20613 char_u *name; 20614 { 20615 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 20616 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 20617 } 20618 20619 #if defined(FEAT_PROFILE) || defined(PROTO) 20620 /* 20621 * Start profiling function "fp". 20622 */ 20623 static void 20624 func_do_profile(fp) 20625 ufunc_T *fp; 20626 { 20627 fp->uf_tm_count = 0; 20628 profile_zero(&fp->uf_tm_self); 20629 profile_zero(&fp->uf_tm_total); 20630 if (fp->uf_tml_count == NULL) 20631 fp->uf_tml_count = (int *)alloc_clear((unsigned) 20632 (sizeof(int) * fp->uf_lines.ga_len)); 20633 if (fp->uf_tml_total == NULL) 20634 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 20635 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 20636 if (fp->uf_tml_self == NULL) 20637 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 20638 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 20639 fp->uf_tml_idx = -1; 20640 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 20641 || fp->uf_tml_self == NULL) 20642 return; /* out of memory */ 20643 20644 fp->uf_profiling = TRUE; 20645 } 20646 20647 /* 20648 * Dump the profiling results for all functions in file "fd". 20649 */ 20650 void 20651 func_dump_profile(fd) 20652 FILE *fd; 20653 { 20654 hashitem_T *hi; 20655 int todo; 20656 ufunc_T *fp; 20657 int i; 20658 ufunc_T **sorttab; 20659 int st_len = 0; 20660 20661 todo = (int)func_hashtab.ht_used; 20662 if (todo == 0) 20663 return; /* nothing to dump */ 20664 20665 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 20666 20667 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 20668 { 20669 if (!HASHITEM_EMPTY(hi)) 20670 { 20671 --todo; 20672 fp = HI2UF(hi); 20673 if (fp->uf_profiling) 20674 { 20675 if (sorttab != NULL) 20676 sorttab[st_len++] = fp; 20677 20678 if (fp->uf_name[0] == K_SPECIAL) 20679 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 20680 else 20681 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 20682 if (fp->uf_tm_count == 1) 20683 fprintf(fd, "Called 1 time\n"); 20684 else 20685 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 20686 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 20687 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 20688 fprintf(fd, "\n"); 20689 fprintf(fd, "count total (s) self (s)\n"); 20690 20691 for (i = 0; i < fp->uf_lines.ga_len; ++i) 20692 { 20693 if (FUNCLINE(fp, i) == NULL) 20694 continue; 20695 prof_func_line(fd, fp->uf_tml_count[i], 20696 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 20697 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 20698 } 20699 fprintf(fd, "\n"); 20700 } 20701 } 20702 } 20703 20704 if (sorttab != NULL && st_len > 0) 20705 { 20706 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 20707 prof_total_cmp); 20708 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 20709 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 20710 prof_self_cmp); 20711 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 20712 } 20713 20714 vim_free(sorttab); 20715 } 20716 20717 static void 20718 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 20719 FILE *fd; 20720 ufunc_T **sorttab; 20721 int st_len; 20722 char *title; 20723 int prefer_self; /* when equal print only self time */ 20724 { 20725 int i; 20726 ufunc_T *fp; 20727 20728 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 20729 fprintf(fd, "count total (s) self (s) function\n"); 20730 for (i = 0; i < 20 && i < st_len; ++i) 20731 { 20732 fp = sorttab[i]; 20733 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 20734 prefer_self); 20735 if (fp->uf_name[0] == K_SPECIAL) 20736 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 20737 else 20738 fprintf(fd, " %s()\n", fp->uf_name); 20739 } 20740 fprintf(fd, "\n"); 20741 } 20742 20743 /* 20744 * Print the count and times for one function or function line. 20745 */ 20746 static void 20747 prof_func_line(fd, count, total, self, prefer_self) 20748 FILE *fd; 20749 int count; 20750 proftime_T *total; 20751 proftime_T *self; 20752 int prefer_self; /* when equal print only self time */ 20753 { 20754 if (count > 0) 20755 { 20756 fprintf(fd, "%5d ", count); 20757 if (prefer_self && profile_equal(total, self)) 20758 fprintf(fd, " "); 20759 else 20760 fprintf(fd, "%s ", profile_msg(total)); 20761 if (!prefer_self && profile_equal(total, self)) 20762 fprintf(fd, " "); 20763 else 20764 fprintf(fd, "%s ", profile_msg(self)); 20765 } 20766 else 20767 fprintf(fd, " "); 20768 } 20769 20770 /* 20771 * Compare function for total time sorting. 20772 */ 20773 static int 20774 #ifdef __BORLANDC__ 20775 _RTLENTRYF 20776 #endif 20777 prof_total_cmp(s1, s2) 20778 const void *s1; 20779 const void *s2; 20780 { 20781 ufunc_T *p1, *p2; 20782 20783 p1 = *(ufunc_T **)s1; 20784 p2 = *(ufunc_T **)s2; 20785 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 20786 } 20787 20788 /* 20789 * Compare function for self time sorting. 20790 */ 20791 static int 20792 #ifdef __BORLANDC__ 20793 _RTLENTRYF 20794 #endif 20795 prof_self_cmp(s1, s2) 20796 const void *s1; 20797 const void *s2; 20798 { 20799 ufunc_T *p1, *p2; 20800 20801 p1 = *(ufunc_T **)s1; 20802 p2 = *(ufunc_T **)s2; 20803 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 20804 } 20805 20806 #endif 20807 20808 /* 20809 * If "name" has a package name try autoloading the script for it. 20810 * Return TRUE if a package was loaded. 20811 */ 20812 static int 20813 script_autoload(name, reload) 20814 char_u *name; 20815 int reload; /* load script again when already loaded */ 20816 { 20817 char_u *p; 20818 char_u *scriptname, *tofree; 20819 int ret = FALSE; 20820 int i; 20821 20822 /* If there is no '#' after name[0] there is no package name. */ 20823 p = vim_strchr(name, AUTOLOAD_CHAR); 20824 if (p == NULL || p == name) 20825 return FALSE; 20826 20827 tofree = scriptname = autoload_name(name); 20828 20829 /* Find the name in the list of previously loaded package names. Skip 20830 * "autoload/", it's always the same. */ 20831 for (i = 0; i < ga_loaded.ga_len; ++i) 20832 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 20833 break; 20834 if (!reload && i < ga_loaded.ga_len) 20835 ret = FALSE; /* was loaded already */ 20836 else 20837 { 20838 /* Remember the name if it wasn't loaded already. */ 20839 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 20840 { 20841 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 20842 tofree = NULL; 20843 } 20844 20845 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 20846 if (source_runtime(scriptname, FALSE) == OK) 20847 ret = TRUE; 20848 } 20849 20850 vim_free(tofree); 20851 return ret; 20852 } 20853 20854 /* 20855 * Return the autoload script name for a function or variable name. 20856 * Returns NULL when out of memory. 20857 */ 20858 static char_u * 20859 autoload_name(name) 20860 char_u *name; 20861 { 20862 char_u *p; 20863 char_u *scriptname; 20864 20865 /* Get the script file name: replace '#' with '/', append ".vim". */ 20866 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 20867 if (scriptname == NULL) 20868 return FALSE; 20869 STRCPY(scriptname, "autoload/"); 20870 STRCAT(scriptname, name); 20871 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 20872 STRCAT(scriptname, ".vim"); 20873 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 20874 *p = '/'; 20875 return scriptname; 20876 } 20877 20878 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 20879 20880 /* 20881 * Function given to ExpandGeneric() to obtain the list of user defined 20882 * function names. 20883 */ 20884 char_u * 20885 get_user_func_name(xp, idx) 20886 expand_T *xp; 20887 int idx; 20888 { 20889 static long_u done; 20890 static hashitem_T *hi; 20891 ufunc_T *fp; 20892 20893 if (idx == 0) 20894 { 20895 done = 0; 20896 hi = func_hashtab.ht_array; 20897 } 20898 if (done < func_hashtab.ht_used) 20899 { 20900 if (done++ > 0) 20901 ++hi; 20902 while (HASHITEM_EMPTY(hi)) 20903 ++hi; 20904 fp = HI2UF(hi); 20905 20906 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 20907 return fp->uf_name; /* prevents overflow */ 20908 20909 cat_func_name(IObuff, fp); 20910 if (xp->xp_context != EXPAND_USER_FUNC) 20911 { 20912 STRCAT(IObuff, "("); 20913 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 20914 STRCAT(IObuff, ")"); 20915 } 20916 return IObuff; 20917 } 20918 return NULL; 20919 } 20920 20921 #endif /* FEAT_CMDL_COMPL */ 20922 20923 /* 20924 * Copy the function name of "fp" to buffer "buf". 20925 * "buf" must be able to hold the function name plus three bytes. 20926 * Takes care of script-local function names. 20927 */ 20928 static void 20929 cat_func_name(buf, fp) 20930 char_u *buf; 20931 ufunc_T *fp; 20932 { 20933 if (fp->uf_name[0] == K_SPECIAL) 20934 { 20935 STRCPY(buf, "<SNR>"); 20936 STRCAT(buf, fp->uf_name + 3); 20937 } 20938 else 20939 STRCPY(buf, fp->uf_name); 20940 } 20941 20942 /* 20943 * ":delfunction {name}" 20944 */ 20945 void 20946 ex_delfunction(eap) 20947 exarg_T *eap; 20948 { 20949 ufunc_T *fp = NULL; 20950 char_u *p; 20951 char_u *name; 20952 funcdict_T fudi; 20953 20954 p = eap->arg; 20955 name = trans_function_name(&p, eap->skip, 0, &fudi); 20956 vim_free(fudi.fd_newkey); 20957 if (name == NULL) 20958 { 20959 if (fudi.fd_dict != NULL && !eap->skip) 20960 EMSG(_(e_funcref)); 20961 return; 20962 } 20963 if (!ends_excmd(*skipwhite(p))) 20964 { 20965 vim_free(name); 20966 EMSG(_(e_trailing)); 20967 return; 20968 } 20969 eap->nextcmd = check_nextcmd(p); 20970 if (eap->nextcmd != NULL) 20971 *p = NUL; 20972 20973 if (!eap->skip) 20974 fp = find_func(name); 20975 vim_free(name); 20976 20977 if (!eap->skip) 20978 { 20979 if (fp == NULL) 20980 { 20981 EMSG2(_(e_nofunc), eap->arg); 20982 return; 20983 } 20984 if (fp->uf_calls > 0) 20985 { 20986 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 20987 return; 20988 } 20989 20990 if (fudi.fd_dict != NULL) 20991 { 20992 /* Delete the dict item that refers to the function, it will 20993 * invoke func_unref() and possibly delete the function. */ 20994 dictitem_remove(fudi.fd_dict, fudi.fd_di); 20995 } 20996 else 20997 func_free(fp); 20998 } 20999 } 21000 21001 /* 21002 * Free a function and remove it from the list of functions. 21003 */ 21004 static void 21005 func_free(fp) 21006 ufunc_T *fp; 21007 { 21008 hashitem_T *hi; 21009 21010 /* clear this function */ 21011 ga_clear_strings(&(fp->uf_args)); 21012 ga_clear_strings(&(fp->uf_lines)); 21013 #ifdef FEAT_PROFILE 21014 vim_free(fp->uf_tml_count); 21015 vim_free(fp->uf_tml_total); 21016 vim_free(fp->uf_tml_self); 21017 #endif 21018 21019 /* remove the function from the function hashtable */ 21020 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 21021 if (HASHITEM_EMPTY(hi)) 21022 EMSG2(_(e_intern2), "func_free()"); 21023 else 21024 hash_remove(&func_hashtab, hi); 21025 21026 vim_free(fp); 21027 } 21028 21029 /* 21030 * Unreference a Function: decrement the reference count and free it when it 21031 * becomes zero. Only for numbered functions. 21032 */ 21033 static void 21034 func_unref(name) 21035 char_u *name; 21036 { 21037 ufunc_T *fp; 21038 21039 if (name != NULL && isdigit(*name)) 21040 { 21041 fp = find_func(name); 21042 if (fp == NULL) 21043 EMSG2(_(e_intern2), "func_unref()"); 21044 else if (--fp->uf_refcount <= 0) 21045 { 21046 /* Only delete it when it's not being used. Otherwise it's done 21047 * when "uf_calls" becomes zero. */ 21048 if (fp->uf_calls == 0) 21049 func_free(fp); 21050 } 21051 } 21052 } 21053 21054 /* 21055 * Count a reference to a Function. 21056 */ 21057 static void 21058 func_ref(name) 21059 char_u *name; 21060 { 21061 ufunc_T *fp; 21062 21063 if (name != NULL && isdigit(*name)) 21064 { 21065 fp = find_func(name); 21066 if (fp == NULL) 21067 EMSG2(_(e_intern2), "func_ref()"); 21068 else 21069 ++fp->uf_refcount; 21070 } 21071 } 21072 21073 /* 21074 * Call a user function. 21075 */ 21076 static void 21077 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 21078 ufunc_T *fp; /* pointer to function */ 21079 int argcount; /* nr of args */ 21080 typval_T *argvars; /* arguments */ 21081 typval_T *rettv; /* return value */ 21082 linenr_T firstline; /* first line of range */ 21083 linenr_T lastline; /* last line of range */ 21084 dict_T *selfdict; /* Dictionary for "self" */ 21085 { 21086 char_u *save_sourcing_name; 21087 linenr_T save_sourcing_lnum; 21088 scid_T save_current_SID; 21089 funccall_T *fc; 21090 int save_did_emsg; 21091 static int depth = 0; 21092 dictitem_T *v; 21093 int fixvar_idx = 0; /* index in fixvar[] */ 21094 int i; 21095 int ai; 21096 char_u numbuf[NUMBUFLEN]; 21097 char_u *name; 21098 #ifdef FEAT_PROFILE 21099 proftime_T wait_start; 21100 proftime_T call_start; 21101 #endif 21102 21103 /* If depth of calling is getting too high, don't execute the function */ 21104 if (depth >= p_mfd) 21105 { 21106 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 21107 rettv->v_type = VAR_NUMBER; 21108 rettv->vval.v_number = -1; 21109 return; 21110 } 21111 ++depth; 21112 21113 line_breakcheck(); /* check for CTRL-C hit */ 21114 21115 fc = (funccall_T *)alloc(sizeof(funccall_T)); 21116 fc->caller = current_funccal; 21117 current_funccal = fc; 21118 fc->func = fp; 21119 fc->rettv = rettv; 21120 rettv->vval.v_number = 0; 21121 fc->linenr = 0; 21122 fc->returned = FALSE; 21123 fc->level = ex_nesting_level; 21124 /* Check if this function has a breakpoint. */ 21125 fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 21126 fc->dbg_tick = debug_tick; 21127 21128 /* 21129 * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables 21130 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 21131 * each argument variable and saves a lot of time. 21132 */ 21133 /* 21134 * Init l: variables. 21135 */ 21136 init_var_dict(&fc->l_vars, &fc->l_vars_var); 21137 if (selfdict != NULL) 21138 { 21139 /* Set l:self to "selfdict". Use "name" to avoid a warning from 21140 * some compiler that checks the destination size. */ 21141 v = &fc->fixvar[fixvar_idx++].var; 21142 name = v->di_key; 21143 STRCPY(name, "self"); 21144 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 21145 hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); 21146 v->di_tv.v_type = VAR_DICT; 21147 v->di_tv.v_lock = 0; 21148 v->di_tv.vval.v_dict = selfdict; 21149 ++selfdict->dv_refcount; 21150 } 21151 21152 /* 21153 * Init a: variables. 21154 * Set a:0 to "argcount". 21155 * Set a:000 to a list with room for the "..." arguments. 21156 */ 21157 init_var_dict(&fc->l_avars, &fc->l_avars_var); 21158 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", 21159 (varnumber_T)(argcount - fp->uf_args.ga_len)); 21160 /* Use "name" to avoid a warning from some compiler that checks the 21161 * destination size. */ 21162 v = &fc->fixvar[fixvar_idx++].var; 21163 name = v->di_key; 21164 STRCPY(name, "000"); 21165 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21166 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 21167 v->di_tv.v_type = VAR_LIST; 21168 v->di_tv.v_lock = VAR_FIXED; 21169 v->di_tv.vval.v_list = &fc->l_varlist; 21170 vim_memset(&fc->l_varlist, 0, sizeof(list_T)); 21171 fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT; 21172 fc->l_varlist.lv_lock = VAR_FIXED; 21173 21174 /* 21175 * Set a:firstline to "firstline" and a:lastline to "lastline". 21176 * Set a:name to named arguments. 21177 * Set a:N to the "..." arguments. 21178 */ 21179 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", 21180 (varnumber_T)firstline); 21181 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", 21182 (varnumber_T)lastline); 21183 for (i = 0; i < argcount; ++i) 21184 { 21185 ai = i - fp->uf_args.ga_len; 21186 if (ai < 0) 21187 /* named argument a:name */ 21188 name = FUNCARG(fp, i); 21189 else 21190 { 21191 /* "..." argument a:1, a:2, etc. */ 21192 sprintf((char *)numbuf, "%d", ai + 1); 21193 name = numbuf; 21194 } 21195 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 21196 { 21197 v = &fc->fixvar[fixvar_idx++].var; 21198 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21199 } 21200 else 21201 { 21202 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 21203 + STRLEN(name))); 21204 if (v == NULL) 21205 break; 21206 v->di_flags = DI_FLAGS_RO; 21207 } 21208 STRCPY(v->di_key, name); 21209 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 21210 21211 /* Note: the values are copied directly to avoid alloc/free. 21212 * "argvars" must have VAR_FIXED for v_lock. */ 21213 v->di_tv = argvars[i]; 21214 v->di_tv.v_lock = VAR_FIXED; 21215 21216 if (ai >= 0 && ai < MAX_FUNC_ARGS) 21217 { 21218 list_append(&fc->l_varlist, &fc->l_listitems[ai]); 21219 fc->l_listitems[ai].li_tv = argvars[i]; 21220 fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED; 21221 } 21222 } 21223 21224 /* Don't redraw while executing the function. */ 21225 ++RedrawingDisabled; 21226 save_sourcing_name = sourcing_name; 21227 save_sourcing_lnum = sourcing_lnum; 21228 sourcing_lnum = 1; 21229 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 21230 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 21231 if (sourcing_name != NULL) 21232 { 21233 if (save_sourcing_name != NULL 21234 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 21235 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 21236 else 21237 STRCPY(sourcing_name, "function "); 21238 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 21239 21240 if (p_verbose >= 12) 21241 { 21242 ++no_wait_return; 21243 verbose_enter_scroll(); 21244 21245 smsg((char_u *)_("calling %s"), sourcing_name); 21246 if (p_verbose >= 14) 21247 { 21248 char_u buf[MSG_BUF_LEN]; 21249 char_u numbuf2[NUMBUFLEN]; 21250 char_u *tofree; 21251 char_u *s; 21252 21253 msg_puts((char_u *)"("); 21254 for (i = 0; i < argcount; ++i) 21255 { 21256 if (i > 0) 21257 msg_puts((char_u *)", "); 21258 if (argvars[i].v_type == VAR_NUMBER) 21259 msg_outnum((long)argvars[i].vval.v_number); 21260 else 21261 { 21262 s = tv2string(&argvars[i], &tofree, numbuf2, 0); 21263 if (s != NULL) 21264 { 21265 trunc_string(s, buf, MSG_BUF_CLEN); 21266 msg_puts(buf); 21267 vim_free(tofree); 21268 } 21269 } 21270 } 21271 msg_puts((char_u *)")"); 21272 } 21273 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 21274 21275 verbose_leave_scroll(); 21276 --no_wait_return; 21277 } 21278 } 21279 #ifdef FEAT_PROFILE 21280 if (do_profiling == PROF_YES) 21281 { 21282 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 21283 func_do_profile(fp); 21284 if (fp->uf_profiling 21285 || (fc->caller != NULL && fc->caller->func->uf_profiling)) 21286 { 21287 ++fp->uf_tm_count; 21288 profile_start(&call_start); 21289 profile_zero(&fp->uf_tm_children); 21290 } 21291 script_prof_save(&wait_start); 21292 } 21293 #endif 21294 21295 save_current_SID = current_SID; 21296 current_SID = fp->uf_script_ID; 21297 save_did_emsg = did_emsg; 21298 did_emsg = FALSE; 21299 21300 /* call do_cmdline() to execute the lines */ 21301 do_cmdline(NULL, get_func_line, (void *)fc, 21302 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 21303 21304 --RedrawingDisabled; 21305 21306 /* when the function was aborted because of an error, return -1 */ 21307 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 21308 { 21309 clear_tv(rettv); 21310 rettv->v_type = VAR_NUMBER; 21311 rettv->vval.v_number = -1; 21312 } 21313 21314 #ifdef FEAT_PROFILE 21315 if (do_profiling == PROF_YES && (fp->uf_profiling 21316 || (fc->caller != NULL && fc->caller->func->uf_profiling))) 21317 { 21318 profile_end(&call_start); 21319 profile_sub_wait(&wait_start, &call_start); 21320 profile_add(&fp->uf_tm_total, &call_start); 21321 profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); 21322 if (fc->caller != NULL && fc->caller->func->uf_profiling) 21323 { 21324 profile_add(&fc->caller->func->uf_tm_children, &call_start); 21325 profile_add(&fc->caller->func->uf_tml_children, &call_start); 21326 } 21327 } 21328 #endif 21329 21330 /* when being verbose, mention the return value */ 21331 if (p_verbose >= 12) 21332 { 21333 ++no_wait_return; 21334 verbose_enter_scroll(); 21335 21336 if (aborting()) 21337 smsg((char_u *)_("%s aborted"), sourcing_name); 21338 else if (fc->rettv->v_type == VAR_NUMBER) 21339 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 21340 (long)fc->rettv->vval.v_number); 21341 else 21342 { 21343 char_u buf[MSG_BUF_LEN]; 21344 char_u numbuf2[NUMBUFLEN]; 21345 char_u *tofree; 21346 char_u *s; 21347 21348 /* The value may be very long. Skip the middle part, so that we 21349 * have some idea how it starts and ends. smsg() would always 21350 * truncate it at the end. */ 21351 s = tv2string(fc->rettv, &tofree, numbuf2, 0); 21352 if (s != NULL) 21353 { 21354 trunc_string(s, buf, MSG_BUF_CLEN); 21355 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 21356 vim_free(tofree); 21357 } 21358 } 21359 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 21360 21361 verbose_leave_scroll(); 21362 --no_wait_return; 21363 } 21364 21365 vim_free(sourcing_name); 21366 sourcing_name = save_sourcing_name; 21367 sourcing_lnum = save_sourcing_lnum; 21368 current_SID = save_current_SID; 21369 #ifdef FEAT_PROFILE 21370 if (do_profiling == PROF_YES) 21371 script_prof_restore(&wait_start); 21372 #endif 21373 21374 if (p_verbose >= 12 && sourcing_name != NULL) 21375 { 21376 ++no_wait_return; 21377 verbose_enter_scroll(); 21378 21379 smsg((char_u *)_("continuing in %s"), sourcing_name); 21380 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 21381 21382 verbose_leave_scroll(); 21383 --no_wait_return; 21384 } 21385 21386 did_emsg |= save_did_emsg; 21387 current_funccal = fc->caller; 21388 --depth; 21389 21390 /* If the a:000 list and the l: and a: dicts are not referenced we can 21391 * free the funccall_T and what's in it. */ 21392 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT 21393 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT 21394 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) 21395 { 21396 free_funccal(fc, FALSE); 21397 } 21398 else 21399 { 21400 hashitem_T *hi; 21401 listitem_T *li; 21402 int todo; 21403 21404 /* "fc" is still in use. This can happen when returning "a:000" or 21405 * assigning "l:" to a global variable. 21406 * Link "fc" in the list for garbage collection later. */ 21407 fc->caller = previous_funccal; 21408 previous_funccal = fc; 21409 21410 /* Make a copy of the a: variables, since we didn't do that above. */ 21411 todo = (int)fc->l_avars.dv_hashtab.ht_used; 21412 for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) 21413 { 21414 if (!HASHITEM_EMPTY(hi)) 21415 { 21416 --todo; 21417 v = HI2DI(hi); 21418 copy_tv(&v->di_tv, &v->di_tv); 21419 } 21420 } 21421 21422 /* Make a copy of the a:000 items, since we didn't do that above. */ 21423 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 21424 copy_tv(&li->li_tv, &li->li_tv); 21425 } 21426 } 21427 21428 /* 21429 * Return TRUE if items in "fc" do not have "copyID". That means they are not 21430 * referenced from anywhere that is in use. 21431 */ 21432 static int 21433 can_free_funccal(fc, copyID) 21434 funccall_T *fc; 21435 int copyID; 21436 { 21437 return (fc->l_varlist.lv_copyID != copyID 21438 && fc->l_vars.dv_copyID != copyID 21439 && fc->l_avars.dv_copyID != copyID); 21440 } 21441 21442 /* 21443 * Free "fc" and what it contains. 21444 */ 21445 static void 21446 free_funccal(fc, free_val) 21447 funccall_T *fc; 21448 int free_val; /* a: vars were allocated */ 21449 { 21450 listitem_T *li; 21451 21452 /* The a: variables typevals may not have been allocated, only free the 21453 * allocated variables. */ 21454 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); 21455 21456 /* free all l: variables */ 21457 vars_clear(&fc->l_vars.dv_hashtab); 21458 21459 /* Free the a:000 variables if they were allocated. */ 21460 if (free_val) 21461 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 21462 clear_tv(&li->li_tv); 21463 21464 vim_free(fc); 21465 } 21466 21467 /* 21468 * Add a number variable "name" to dict "dp" with value "nr". 21469 */ 21470 static void 21471 add_nr_var(dp, v, name, nr) 21472 dict_T *dp; 21473 dictitem_T *v; 21474 char *name; 21475 varnumber_T nr; 21476 { 21477 STRCPY(v->di_key, name); 21478 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21479 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 21480 v->di_tv.v_type = VAR_NUMBER; 21481 v->di_tv.v_lock = VAR_FIXED; 21482 v->di_tv.vval.v_number = nr; 21483 } 21484 21485 /* 21486 * ":return [expr]" 21487 */ 21488 void 21489 ex_return(eap) 21490 exarg_T *eap; 21491 { 21492 char_u *arg = eap->arg; 21493 typval_T rettv; 21494 int returning = FALSE; 21495 21496 if (current_funccal == NULL) 21497 { 21498 EMSG(_("E133: :return not inside a function")); 21499 return; 21500 } 21501 21502 if (eap->skip) 21503 ++emsg_skip; 21504 21505 eap->nextcmd = NULL; 21506 if ((*arg != NUL && *arg != '|' && *arg != '\n') 21507 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 21508 { 21509 if (!eap->skip) 21510 returning = do_return(eap, FALSE, TRUE, &rettv); 21511 else 21512 clear_tv(&rettv); 21513 } 21514 /* It's safer to return also on error. */ 21515 else if (!eap->skip) 21516 { 21517 /* 21518 * Return unless the expression evaluation has been cancelled due to an 21519 * aborting error, an interrupt, or an exception. 21520 */ 21521 if (!aborting()) 21522 returning = do_return(eap, FALSE, TRUE, NULL); 21523 } 21524 21525 /* When skipping or the return gets pending, advance to the next command 21526 * in this line (!returning). Otherwise, ignore the rest of the line. 21527 * Following lines will be ignored by get_func_line(). */ 21528 if (returning) 21529 eap->nextcmd = NULL; 21530 else if (eap->nextcmd == NULL) /* no argument */ 21531 eap->nextcmd = check_nextcmd(arg); 21532 21533 if (eap->skip) 21534 --emsg_skip; 21535 } 21536 21537 /* 21538 * Return from a function. Possibly makes the return pending. Also called 21539 * for a pending return at the ":endtry" or after returning from an extra 21540 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 21541 * when called due to a ":return" command. "rettv" may point to a typval_T 21542 * with the return rettv. Returns TRUE when the return can be carried out, 21543 * FALSE when the return gets pending. 21544 */ 21545 int 21546 do_return(eap, reanimate, is_cmd, rettv) 21547 exarg_T *eap; 21548 int reanimate; 21549 int is_cmd; 21550 void *rettv; 21551 { 21552 int idx; 21553 struct condstack *cstack = eap->cstack; 21554 21555 if (reanimate) 21556 /* Undo the return. */ 21557 current_funccal->returned = FALSE; 21558 21559 /* 21560 * Cleanup (and inactivate) conditionals, but stop when a try conditional 21561 * not in its finally clause (which then is to be executed next) is found. 21562 * In this case, make the ":return" pending for execution at the ":endtry". 21563 * Otherwise, return normally. 21564 */ 21565 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 21566 if (idx >= 0) 21567 { 21568 cstack->cs_pending[idx] = CSTP_RETURN; 21569 21570 if (!is_cmd && !reanimate) 21571 /* A pending return again gets pending. "rettv" points to an 21572 * allocated variable with the rettv of the original ":return"'s 21573 * argument if present or is NULL else. */ 21574 cstack->cs_rettv[idx] = rettv; 21575 else 21576 { 21577 /* When undoing a return in order to make it pending, get the stored 21578 * return rettv. */ 21579 if (reanimate) 21580 rettv = current_funccal->rettv; 21581 21582 if (rettv != NULL) 21583 { 21584 /* Store the value of the pending return. */ 21585 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 21586 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 21587 else 21588 EMSG(_(e_outofmem)); 21589 } 21590 else 21591 cstack->cs_rettv[idx] = NULL; 21592 21593 if (reanimate) 21594 { 21595 /* The pending return value could be overwritten by a ":return" 21596 * without argument in a finally clause; reset the default 21597 * return value. */ 21598 current_funccal->rettv->v_type = VAR_NUMBER; 21599 current_funccal->rettv->vval.v_number = 0; 21600 } 21601 } 21602 report_make_pending(CSTP_RETURN, rettv); 21603 } 21604 else 21605 { 21606 current_funccal->returned = TRUE; 21607 21608 /* If the return is carried out now, store the return value. For 21609 * a return immediately after reanimation, the value is already 21610 * there. */ 21611 if (!reanimate && rettv != NULL) 21612 { 21613 clear_tv(current_funccal->rettv); 21614 *current_funccal->rettv = *(typval_T *)rettv; 21615 if (!is_cmd) 21616 vim_free(rettv); 21617 } 21618 } 21619 21620 return idx < 0; 21621 } 21622 21623 /* 21624 * Free the variable with a pending return value. 21625 */ 21626 void 21627 discard_pending_return(rettv) 21628 void *rettv; 21629 { 21630 free_tv((typval_T *)rettv); 21631 } 21632 21633 /* 21634 * Generate a return command for producing the value of "rettv". The result 21635 * is an allocated string. Used by report_pending() for verbose messages. 21636 */ 21637 char_u * 21638 get_return_cmd(rettv) 21639 void *rettv; 21640 { 21641 char_u *s = NULL; 21642 char_u *tofree = NULL; 21643 char_u numbuf[NUMBUFLEN]; 21644 21645 if (rettv != NULL) 21646 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 21647 if (s == NULL) 21648 s = (char_u *)""; 21649 21650 STRCPY(IObuff, ":return "); 21651 STRNCPY(IObuff + 8, s, IOSIZE - 8); 21652 if (STRLEN(s) + 8 >= IOSIZE) 21653 STRCPY(IObuff + IOSIZE - 4, "..."); 21654 vim_free(tofree); 21655 return vim_strsave(IObuff); 21656 } 21657 21658 /* 21659 * Get next function line. 21660 * Called by do_cmdline() to get the next line. 21661 * Returns allocated string, or NULL for end of function. 21662 */ 21663 char_u * 21664 get_func_line(c, cookie, indent) 21665 int c UNUSED; 21666 void *cookie; 21667 int indent UNUSED; 21668 { 21669 funccall_T *fcp = (funccall_T *)cookie; 21670 ufunc_T *fp = fcp->func; 21671 char_u *retval; 21672 garray_T *gap; /* growarray with function lines */ 21673 21674 /* If breakpoints have been added/deleted need to check for it. */ 21675 if (fcp->dbg_tick != debug_tick) 21676 { 21677 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 21678 sourcing_lnum); 21679 fcp->dbg_tick = debug_tick; 21680 } 21681 #ifdef FEAT_PROFILE 21682 if (do_profiling == PROF_YES) 21683 func_line_end(cookie); 21684 #endif 21685 21686 gap = &fp->uf_lines; 21687 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 21688 || fcp->returned) 21689 retval = NULL; 21690 else 21691 { 21692 /* Skip NULL lines (continuation lines). */ 21693 while (fcp->linenr < gap->ga_len 21694 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 21695 ++fcp->linenr; 21696 if (fcp->linenr >= gap->ga_len) 21697 retval = NULL; 21698 else 21699 { 21700 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 21701 sourcing_lnum = fcp->linenr; 21702 #ifdef FEAT_PROFILE 21703 if (do_profiling == PROF_YES) 21704 func_line_start(cookie); 21705 #endif 21706 } 21707 } 21708 21709 /* Did we encounter a breakpoint? */ 21710 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 21711 { 21712 dbg_breakpoint(fp->uf_name, sourcing_lnum); 21713 /* Find next breakpoint. */ 21714 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 21715 sourcing_lnum); 21716 fcp->dbg_tick = debug_tick; 21717 } 21718 21719 return retval; 21720 } 21721 21722 #if defined(FEAT_PROFILE) || defined(PROTO) 21723 /* 21724 * Called when starting to read a function line. 21725 * "sourcing_lnum" must be correct! 21726 * When skipping lines it may not actually be executed, but we won't find out 21727 * until later and we need to store the time now. 21728 */ 21729 void 21730 func_line_start(cookie) 21731 void *cookie; 21732 { 21733 funccall_T *fcp = (funccall_T *)cookie; 21734 ufunc_T *fp = fcp->func; 21735 21736 if (fp->uf_profiling && sourcing_lnum >= 1 21737 && sourcing_lnum <= fp->uf_lines.ga_len) 21738 { 21739 fp->uf_tml_idx = sourcing_lnum - 1; 21740 /* Skip continuation lines. */ 21741 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 21742 --fp->uf_tml_idx; 21743 fp->uf_tml_execed = FALSE; 21744 profile_start(&fp->uf_tml_start); 21745 profile_zero(&fp->uf_tml_children); 21746 profile_get_wait(&fp->uf_tml_wait); 21747 } 21748 } 21749 21750 /* 21751 * Called when actually executing a function line. 21752 */ 21753 void 21754 func_line_exec(cookie) 21755 void *cookie; 21756 { 21757 funccall_T *fcp = (funccall_T *)cookie; 21758 ufunc_T *fp = fcp->func; 21759 21760 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 21761 fp->uf_tml_execed = TRUE; 21762 } 21763 21764 /* 21765 * Called when done with a function line. 21766 */ 21767 void 21768 func_line_end(cookie) 21769 void *cookie; 21770 { 21771 funccall_T *fcp = (funccall_T *)cookie; 21772 ufunc_T *fp = fcp->func; 21773 21774 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 21775 { 21776 if (fp->uf_tml_execed) 21777 { 21778 ++fp->uf_tml_count[fp->uf_tml_idx]; 21779 profile_end(&fp->uf_tml_start); 21780 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 21781 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 21782 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 21783 &fp->uf_tml_children); 21784 } 21785 fp->uf_tml_idx = -1; 21786 } 21787 } 21788 #endif 21789 21790 /* 21791 * Return TRUE if the currently active function should be ended, because a 21792 * return was encountered or an error occurred. Used inside a ":while". 21793 */ 21794 int 21795 func_has_ended(cookie) 21796 void *cookie; 21797 { 21798 funccall_T *fcp = (funccall_T *)cookie; 21799 21800 /* Ignore the "abort" flag if the abortion behavior has been changed due to 21801 * an error inside a try conditional. */ 21802 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 21803 || fcp->returned); 21804 } 21805 21806 /* 21807 * return TRUE if cookie indicates a function which "abort"s on errors. 21808 */ 21809 int 21810 func_has_abort(cookie) 21811 void *cookie; 21812 { 21813 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 21814 } 21815 21816 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 21817 typedef enum 21818 { 21819 VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ 21820 VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ 21821 VAR_FLAVOUR_VIMINFO /* all uppercase */ 21822 } var_flavour_T; 21823 21824 static var_flavour_T var_flavour __ARGS((char_u *varname)); 21825 21826 static var_flavour_T 21827 var_flavour(varname) 21828 char_u *varname; 21829 { 21830 char_u *p = varname; 21831 21832 if (ASCII_ISUPPER(*p)) 21833 { 21834 while (*(++p)) 21835 if (ASCII_ISLOWER(*p)) 21836 return VAR_FLAVOUR_SESSION; 21837 return VAR_FLAVOUR_VIMINFO; 21838 } 21839 else 21840 return VAR_FLAVOUR_DEFAULT; 21841 } 21842 #endif 21843 21844 #if defined(FEAT_VIMINFO) || defined(PROTO) 21845 /* 21846 * Restore global vars that start with a capital from the viminfo file 21847 */ 21848 int 21849 read_viminfo_varlist(virp, writing) 21850 vir_T *virp; 21851 int writing; 21852 { 21853 char_u *tab; 21854 int type = VAR_NUMBER; 21855 typval_T tv; 21856 21857 if (!writing && (find_viminfo_parameter('!') != NULL)) 21858 { 21859 tab = vim_strchr(virp->vir_line + 1, '\t'); 21860 if (tab != NULL) 21861 { 21862 *tab++ = '\0'; /* isolate the variable name */ 21863 if (*tab == 'S') /* string var */ 21864 type = VAR_STRING; 21865 #ifdef FEAT_FLOAT 21866 else if (*tab == 'F') 21867 type = VAR_FLOAT; 21868 #endif 21869 21870 tab = vim_strchr(tab, '\t'); 21871 if (tab != NULL) 21872 { 21873 tv.v_type = type; 21874 if (type == VAR_STRING) 21875 tv.vval.v_string = viminfo_readstring(virp, 21876 (int)(tab - virp->vir_line + 1), TRUE); 21877 #ifdef FEAT_FLOAT 21878 else if (type == VAR_FLOAT) 21879 (void)string2float(tab + 1, &tv.vval.v_float); 21880 #endif 21881 else 21882 tv.vval.v_number = atol((char *)tab + 1); 21883 set_var(virp->vir_line + 1, &tv, FALSE); 21884 if (type == VAR_STRING) 21885 vim_free(tv.vval.v_string); 21886 } 21887 } 21888 } 21889 21890 return viminfo_readline(virp); 21891 } 21892 21893 /* 21894 * Write global vars that start with a capital to the viminfo file 21895 */ 21896 void 21897 write_viminfo_varlist(fp) 21898 FILE *fp; 21899 { 21900 hashitem_T *hi; 21901 dictitem_T *this_var; 21902 int todo; 21903 char *s; 21904 char_u *p; 21905 char_u *tofree; 21906 char_u numbuf[NUMBUFLEN]; 21907 21908 if (find_viminfo_parameter('!') == NULL) 21909 return; 21910 21911 fprintf(fp, _("\n# global variables:\n")); 21912 21913 todo = (int)globvarht.ht_used; 21914 for (hi = globvarht.ht_array; todo > 0; ++hi) 21915 { 21916 if (!HASHITEM_EMPTY(hi)) 21917 { 21918 --todo; 21919 this_var = HI2DI(hi); 21920 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 21921 { 21922 switch (this_var->di_tv.v_type) 21923 { 21924 case VAR_STRING: s = "STR"; break; 21925 case VAR_NUMBER: s = "NUM"; break; 21926 #ifdef FEAT_FLOAT 21927 case VAR_FLOAT: s = "FLO"; break; 21928 #endif 21929 default: continue; 21930 } 21931 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 21932 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 21933 if (p != NULL) 21934 viminfo_writestring(fp, p); 21935 vim_free(tofree); 21936 } 21937 } 21938 } 21939 } 21940 #endif 21941 21942 #if defined(FEAT_SESSION) || defined(PROTO) 21943 int 21944 store_session_globals(fd) 21945 FILE *fd; 21946 { 21947 hashitem_T *hi; 21948 dictitem_T *this_var; 21949 int todo; 21950 char_u *p, *t; 21951 21952 todo = (int)globvarht.ht_used; 21953 for (hi = globvarht.ht_array; todo > 0; ++hi) 21954 { 21955 if (!HASHITEM_EMPTY(hi)) 21956 { 21957 --todo; 21958 this_var = HI2DI(hi); 21959 if ((this_var->di_tv.v_type == VAR_NUMBER 21960 || this_var->di_tv.v_type == VAR_STRING) 21961 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 21962 { 21963 /* Escape special characters with a backslash. Turn a LF and 21964 * CR into \n and \r. */ 21965 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 21966 (char_u *)"\\\"\n\r"); 21967 if (p == NULL) /* out of memory */ 21968 break; 21969 for (t = p; *t != NUL; ++t) 21970 if (*t == '\n') 21971 *t = 'n'; 21972 else if (*t == '\r') 21973 *t = 'r'; 21974 if ((fprintf(fd, "let %s = %c%s%c", 21975 this_var->di_key, 21976 (this_var->di_tv.v_type == VAR_STRING) ? '"' 21977 : ' ', 21978 p, 21979 (this_var->di_tv.v_type == VAR_STRING) ? '"' 21980 : ' ') < 0) 21981 || put_eol(fd) == FAIL) 21982 { 21983 vim_free(p); 21984 return FAIL; 21985 } 21986 vim_free(p); 21987 } 21988 #ifdef FEAT_FLOAT 21989 else if (this_var->di_tv.v_type == VAR_FLOAT 21990 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 21991 { 21992 float_T f = this_var->di_tv.vval.v_float; 21993 int sign = ' '; 21994 21995 if (f < 0) 21996 { 21997 f = -f; 21998 sign = '-'; 21999 } 22000 if ((fprintf(fd, "let %s = %c&%f", 22001 this_var->di_key, sign, f) < 0) 22002 || put_eol(fd) == FAIL) 22003 return FAIL; 22004 } 22005 #endif 22006 } 22007 } 22008 return OK; 22009 } 22010 #endif 22011 22012 /* 22013 * Display script name where an item was last set. 22014 * Should only be invoked when 'verbose' is non-zero. 22015 */ 22016 void 22017 last_set_msg(scriptID) 22018 scid_T scriptID; 22019 { 22020 char_u *p; 22021 22022 if (scriptID != 0) 22023 { 22024 p = home_replace_save(NULL, get_scriptname(scriptID)); 22025 if (p != NULL) 22026 { 22027 verbose_enter(); 22028 MSG_PUTS(_("\n\tLast set from ")); 22029 MSG_PUTS(p); 22030 vim_free(p); 22031 verbose_leave(); 22032 } 22033 } 22034 } 22035 22036 /* 22037 * List v:oldfiles in a nice way. 22038 */ 22039 void 22040 ex_oldfiles(eap) 22041 exarg_T *eap UNUSED; 22042 { 22043 list_T *l = vimvars[VV_OLDFILES].vv_list; 22044 listitem_T *li; 22045 int nr = 0; 22046 22047 if (l == NULL) 22048 msg((char_u *)_("No old files")); 22049 else 22050 { 22051 msg_start(); 22052 msg_scroll = TRUE; 22053 for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) 22054 { 22055 msg_outnum((long)++nr); 22056 MSG_PUTS(": "); 22057 msg_outtrans(get_tv_string(&li->li_tv)); 22058 msg_putchar('\n'); 22059 out_flush(); /* output one line at a time */ 22060 ui_breakcheck(); 22061 } 22062 /* Assume "got_int" was set to truncate the listing. */ 22063 got_int = FALSE; 22064 22065 #ifdef FEAT_BROWSE_CMD 22066 if (cmdmod.browse) 22067 { 22068 quit_more = FALSE; 22069 nr = prompt_for_number(FALSE); 22070 msg_starthere(); 22071 if (nr > 0) 22072 { 22073 char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES), 22074 (long)nr); 22075 22076 if (p != NULL) 22077 { 22078 p = expand_env_save(p); 22079 eap->arg = p; 22080 eap->cmdidx = CMD_edit; 22081 cmdmod.browse = FALSE; 22082 do_exedit(eap, NULL); 22083 vim_free(p); 22084 } 22085 } 22086 } 22087 #endif 22088 } 22089 } 22090 22091 #endif /* FEAT_EVAL */ 22092 22093 22094 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 22095 22096 #ifdef WIN3264 22097 /* 22098 * Functions for ":8" filename modifier: get 8.3 version of a filename. 22099 */ 22100 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 22101 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 22102 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 22103 22104 /* 22105 * Get the short path (8.3) for the filename in "fnamep". 22106 * Only works for a valid file name. 22107 * When the path gets longer "fnamep" is changed and the allocated buffer 22108 * is put in "bufp". 22109 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path. 22110 * Returns OK on success, FAIL on failure. 22111 */ 22112 static int 22113 get_short_pathname(fnamep, bufp, fnamelen) 22114 char_u **fnamep; 22115 char_u **bufp; 22116 int *fnamelen; 22117 { 22118 int l, len; 22119 char_u *newbuf; 22120 22121 len = *fnamelen; 22122 l = GetShortPathName(*fnamep, *fnamep, len); 22123 if (l > len - 1) 22124 { 22125 /* If that doesn't work (not enough space), then save the string 22126 * and try again with a new buffer big enough. */ 22127 newbuf = vim_strnsave(*fnamep, l); 22128 if (newbuf == NULL) 22129 return FAIL; 22130 22131 vim_free(*bufp); 22132 *fnamep = *bufp = newbuf; 22133 22134 /* Really should always succeed, as the buffer is big enough. */ 22135 l = GetShortPathName(*fnamep, *fnamep, l+1); 22136 } 22137 22138 *fnamelen = l; 22139 return OK; 22140 } 22141 22142 /* 22143 * Get the short path (8.3) for the filename in "fname". The converted 22144 * path is returned in "bufp". 22145 * 22146 * Some of the directories specified in "fname" may not exist. This function 22147 * will shorten the existing directories at the beginning of the path and then 22148 * append the remaining non-existing path. 22149 * 22150 * fname - Pointer to the filename to shorten. On return, contains the 22151 * pointer to the shortened pathname 22152 * bufp - Pointer to an allocated buffer for the filename. 22153 * fnamelen - Length of the filename pointed to by fname 22154 * 22155 * Returns OK on success (or nothing done) and FAIL on failure (out of memory). 22156 */ 22157 static int 22158 shortpath_for_invalid_fname(fname, bufp, fnamelen) 22159 char_u **fname; 22160 char_u **bufp; 22161 int *fnamelen; 22162 { 22163 char_u *short_fname, *save_fname, *pbuf_unused; 22164 char_u *endp, *save_endp; 22165 char_u ch; 22166 int old_len, len; 22167 int new_len, sfx_len; 22168 int retval = OK; 22169 22170 /* Make a copy */ 22171 old_len = *fnamelen; 22172 save_fname = vim_strnsave(*fname, old_len); 22173 pbuf_unused = NULL; 22174 short_fname = NULL; 22175 22176 endp = save_fname + old_len - 1; /* Find the end of the copy */ 22177 save_endp = endp; 22178 22179 /* 22180 * Try shortening the supplied path till it succeeds by removing one 22181 * directory at a time from the tail of the path. 22182 */ 22183 len = 0; 22184 for (;;) 22185 { 22186 /* go back one path-separator */ 22187 while (endp > save_fname && !after_pathsep(save_fname, endp + 1)) 22188 --endp; 22189 if (endp <= save_fname) 22190 break; /* processed the complete path */ 22191 22192 /* 22193 * Replace the path separator with a NUL and try to shorten the 22194 * resulting path. 22195 */ 22196 ch = *endp; 22197 *endp = 0; 22198 short_fname = save_fname; 22199 len = (int)STRLEN(short_fname) + 1; 22200 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL) 22201 { 22202 retval = FAIL; 22203 goto theend; 22204 } 22205 *endp = ch; /* preserve the string */ 22206 22207 if (len > 0) 22208 break; /* successfully shortened the path */ 22209 22210 /* failed to shorten the path. Skip the path separator */ 22211 --endp; 22212 } 22213 22214 if (len > 0) 22215 { 22216 /* 22217 * Succeeded in shortening the path. Now concatenate the shortened 22218 * path with the remaining path at the tail. 22219 */ 22220 22221 /* Compute the length of the new path. */ 22222 sfx_len = (int)(save_endp - endp) + 1; 22223 new_len = len + sfx_len; 22224 22225 *fnamelen = new_len; 22226 vim_free(*bufp); 22227 if (new_len > old_len) 22228 { 22229 /* There is not enough space in the currently allocated string, 22230 * copy it to a buffer big enough. */ 22231 *fname = *bufp = vim_strnsave(short_fname, new_len); 22232 if (*fname == NULL) 22233 { 22234 retval = FAIL; 22235 goto theend; 22236 } 22237 } 22238 else 22239 { 22240 /* Transfer short_fname to the main buffer (it's big enough), 22241 * unless get_short_pathname() did its work in-place. */ 22242 *fname = *bufp = save_fname; 22243 if (short_fname != save_fname) 22244 vim_strncpy(save_fname, short_fname, len); 22245 save_fname = NULL; 22246 } 22247 22248 /* concat the not-shortened part of the path */ 22249 vim_strncpy(*fname + len, endp, sfx_len); 22250 (*fname)[new_len] = NUL; 22251 } 22252 22253 theend: 22254 vim_free(pbuf_unused); 22255 vim_free(save_fname); 22256 22257 return retval; 22258 } 22259 22260 /* 22261 * Get a pathname for a partial path. 22262 * Returns OK for success, FAIL for failure. 22263 */ 22264 static int 22265 shortpath_for_partial(fnamep, bufp, fnamelen) 22266 char_u **fnamep; 22267 char_u **bufp; 22268 int *fnamelen; 22269 { 22270 int sepcount, len, tflen; 22271 char_u *p; 22272 char_u *pbuf, *tfname; 22273 int hasTilde; 22274 22275 /* Count up the path separators from the RHS.. so we know which part 22276 * of the path to return. */ 22277 sepcount = 0; 22278 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 22279 if (vim_ispathsep(*p)) 22280 ++sepcount; 22281 22282 /* Need full path first (use expand_env() to remove a "~/") */ 22283 hasTilde = (**fnamep == '~'); 22284 if (hasTilde) 22285 pbuf = tfname = expand_env_save(*fnamep); 22286 else 22287 pbuf = tfname = FullName_save(*fnamep, FALSE); 22288 22289 len = tflen = (int)STRLEN(tfname); 22290 22291 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) 22292 return FAIL; 22293 22294 if (len == 0) 22295 { 22296 /* Don't have a valid filename, so shorten the rest of the 22297 * path if we can. This CAN give us invalid 8.3 filenames, but 22298 * there's not a lot of point in guessing what it might be. 22299 */ 22300 len = tflen; 22301 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) 22302 return FAIL; 22303 } 22304 22305 /* Count the paths backward to find the beginning of the desired string. */ 22306 for (p = tfname + len - 1; p >= tfname; --p) 22307 { 22308 #ifdef FEAT_MBYTE 22309 if (has_mbyte) 22310 p -= mb_head_off(tfname, p); 22311 #endif 22312 if (vim_ispathsep(*p)) 22313 { 22314 if (sepcount == 0 || (hasTilde && sepcount == 1)) 22315 break; 22316 else 22317 sepcount --; 22318 } 22319 } 22320 if (hasTilde) 22321 { 22322 --p; 22323 if (p >= tfname) 22324 *p = '~'; 22325 else 22326 return FAIL; 22327 } 22328 else 22329 ++p; 22330 22331 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 22332 vim_free(*bufp); 22333 *fnamelen = (int)STRLEN(p); 22334 *bufp = pbuf; 22335 *fnamep = p; 22336 22337 return OK; 22338 } 22339 #endif /* WIN3264 */ 22340 22341 /* 22342 * Adjust a filename, according to a string of modifiers. 22343 * *fnamep must be NUL terminated when called. When returning, the length is 22344 * determined by *fnamelen. 22345 * Returns VALID_ flags or -1 for failure. 22346 * When there is an error, *fnamep is set to NULL. 22347 */ 22348 int 22349 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 22350 char_u *src; /* string with modifiers */ 22351 int *usedlen; /* characters after src that are used */ 22352 char_u **fnamep; /* file name so far */ 22353 char_u **bufp; /* buffer for allocated file name or NULL */ 22354 int *fnamelen; /* length of fnamep */ 22355 { 22356 int valid = 0; 22357 char_u *tail; 22358 char_u *s, *p, *pbuf; 22359 char_u dirname[MAXPATHL]; 22360 int c; 22361 int has_fullname = 0; 22362 #ifdef WIN3264 22363 int has_shortname = 0; 22364 #endif 22365 22366 repeat: 22367 /* ":p" - full path/file_name */ 22368 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 22369 { 22370 has_fullname = 1; 22371 22372 valid |= VALID_PATH; 22373 *usedlen += 2; 22374 22375 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 22376 if ((*fnamep)[0] == '~' 22377 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 22378 && ((*fnamep)[1] == '/' 22379 # ifdef BACKSLASH_IN_FILENAME 22380 || (*fnamep)[1] == '\\' 22381 # endif 22382 || (*fnamep)[1] == NUL) 22383 22384 #endif 22385 ) 22386 { 22387 *fnamep = expand_env_save(*fnamep); 22388 vim_free(*bufp); /* free any allocated file name */ 22389 *bufp = *fnamep; 22390 if (*fnamep == NULL) 22391 return -1; 22392 } 22393 22394 /* When "/." or "/.." is used: force expansion to get rid of it. */ 22395 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 22396 { 22397 if (vim_ispathsep(*p) 22398 && p[1] == '.' 22399 && (p[2] == NUL 22400 || vim_ispathsep(p[2]) 22401 || (p[2] == '.' 22402 && (p[3] == NUL || vim_ispathsep(p[3]))))) 22403 break; 22404 } 22405 22406 /* FullName_save() is slow, don't use it when not needed. */ 22407 if (*p != NUL || !vim_isAbsName(*fnamep)) 22408 { 22409 *fnamep = FullName_save(*fnamep, *p != NUL); 22410 vim_free(*bufp); /* free any allocated file name */ 22411 *bufp = *fnamep; 22412 if (*fnamep == NULL) 22413 return -1; 22414 } 22415 22416 /* Append a path separator to a directory. */ 22417 if (mch_isdir(*fnamep)) 22418 { 22419 /* Make room for one or two extra characters. */ 22420 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 22421 vim_free(*bufp); /* free any allocated file name */ 22422 *bufp = *fnamep; 22423 if (*fnamep == NULL) 22424 return -1; 22425 add_pathsep(*fnamep); 22426 } 22427 } 22428 22429 /* ":." - path relative to the current directory */ 22430 /* ":~" - path relative to the home directory */ 22431 /* ":8" - shortname path - postponed till after */ 22432 while (src[*usedlen] == ':' 22433 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 22434 { 22435 *usedlen += 2; 22436 if (c == '8') 22437 { 22438 #ifdef WIN3264 22439 has_shortname = 1; /* Postpone this. */ 22440 #endif 22441 continue; 22442 } 22443 pbuf = NULL; 22444 /* Need full path first (use expand_env() to remove a "~/") */ 22445 if (!has_fullname) 22446 { 22447 if (c == '.' && **fnamep == '~') 22448 p = pbuf = expand_env_save(*fnamep); 22449 else 22450 p = pbuf = FullName_save(*fnamep, FALSE); 22451 } 22452 else 22453 p = *fnamep; 22454 22455 has_fullname = 0; 22456 22457 if (p != NULL) 22458 { 22459 if (c == '.') 22460 { 22461 mch_dirname(dirname, MAXPATHL); 22462 s = shorten_fname(p, dirname); 22463 if (s != NULL) 22464 { 22465 *fnamep = s; 22466 if (pbuf != NULL) 22467 { 22468 vim_free(*bufp); /* free any allocated file name */ 22469 *bufp = pbuf; 22470 pbuf = NULL; 22471 } 22472 } 22473 } 22474 else 22475 { 22476 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 22477 /* Only replace it when it starts with '~' */ 22478 if (*dirname == '~') 22479 { 22480 s = vim_strsave(dirname); 22481 if (s != NULL) 22482 { 22483 *fnamep = s; 22484 vim_free(*bufp); 22485 *bufp = s; 22486 } 22487 } 22488 } 22489 vim_free(pbuf); 22490 } 22491 } 22492 22493 tail = gettail(*fnamep); 22494 *fnamelen = (int)STRLEN(*fnamep); 22495 22496 /* ":h" - head, remove "/file_name", can be repeated */ 22497 /* Don't remove the first "/" or "c:\" */ 22498 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 22499 { 22500 valid |= VALID_HEAD; 22501 *usedlen += 2; 22502 s = get_past_head(*fnamep); 22503 while (tail > s && after_pathsep(s, tail)) 22504 mb_ptr_back(*fnamep, tail); 22505 *fnamelen = (int)(tail - *fnamep); 22506 #ifdef VMS 22507 if (*fnamelen > 0) 22508 *fnamelen += 1; /* the path separator is part of the path */ 22509 #endif 22510 if (*fnamelen == 0) 22511 { 22512 /* Result is empty. Turn it into "." to make ":cd %:h" work. */ 22513 p = vim_strsave((char_u *)"."); 22514 if (p == NULL) 22515 return -1; 22516 vim_free(*bufp); 22517 *bufp = *fnamep = tail = p; 22518 *fnamelen = 1; 22519 } 22520 else 22521 { 22522 while (tail > s && !after_pathsep(s, tail)) 22523 mb_ptr_back(*fnamep, tail); 22524 } 22525 } 22526 22527 /* ":8" - shortname */ 22528 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 22529 { 22530 *usedlen += 2; 22531 #ifdef WIN3264 22532 has_shortname = 1; 22533 #endif 22534 } 22535 22536 #ifdef WIN3264 22537 /* Check shortname after we have done 'heads' and before we do 'tails' 22538 */ 22539 if (has_shortname) 22540 { 22541 pbuf = NULL; 22542 /* Copy the string if it is shortened by :h */ 22543 if (*fnamelen < (int)STRLEN(*fnamep)) 22544 { 22545 p = vim_strnsave(*fnamep, *fnamelen); 22546 if (p == 0) 22547 return -1; 22548 vim_free(*bufp); 22549 *bufp = *fnamep = p; 22550 } 22551 22552 /* Split into two implementations - makes it easier. First is where 22553 * there isn't a full name already, second is where there is. 22554 */ 22555 if (!has_fullname && !vim_isAbsName(*fnamep)) 22556 { 22557 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) 22558 return -1; 22559 } 22560 else 22561 { 22562 int l; 22563 22564 /* Simple case, already have the full-name 22565 * Nearly always shorter, so try first time. */ 22566 l = *fnamelen; 22567 if (get_short_pathname(fnamep, bufp, &l) == FAIL) 22568 return -1; 22569 22570 if (l == 0) 22571 { 22572 /* Couldn't find the filename.. search the paths. 22573 */ 22574 l = *fnamelen; 22575 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) 22576 return -1; 22577 } 22578 *fnamelen = l; 22579 } 22580 } 22581 #endif /* WIN3264 */ 22582 22583 /* ":t" - tail, just the basename */ 22584 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 22585 { 22586 *usedlen += 2; 22587 *fnamelen -= (int)(tail - *fnamep); 22588 *fnamep = tail; 22589 } 22590 22591 /* ":e" - extension, can be repeated */ 22592 /* ":r" - root, without extension, can be repeated */ 22593 while (src[*usedlen] == ':' 22594 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 22595 { 22596 /* find a '.' in the tail: 22597 * - for second :e: before the current fname 22598 * - otherwise: The last '.' 22599 */ 22600 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 22601 s = *fnamep - 2; 22602 else 22603 s = *fnamep + *fnamelen - 1; 22604 for ( ; s > tail; --s) 22605 if (s[0] == '.') 22606 break; 22607 if (src[*usedlen + 1] == 'e') /* :e */ 22608 { 22609 if (s > tail) 22610 { 22611 *fnamelen += (int)(*fnamep - (s + 1)); 22612 *fnamep = s + 1; 22613 #ifdef VMS 22614 /* cut version from the extension */ 22615 s = *fnamep + *fnamelen - 1; 22616 for ( ; s > *fnamep; --s) 22617 if (s[0] == ';') 22618 break; 22619 if (s > *fnamep) 22620 *fnamelen = s - *fnamep; 22621 #endif 22622 } 22623 else if (*fnamep <= tail) 22624 *fnamelen = 0; 22625 } 22626 else /* :r */ 22627 { 22628 if (s > tail) /* remove one extension */ 22629 *fnamelen = (int)(s - *fnamep); 22630 } 22631 *usedlen += 2; 22632 } 22633 22634 /* ":s?pat?foo?" - substitute */ 22635 /* ":gs?pat?foo?" - global substitute */ 22636 if (src[*usedlen] == ':' 22637 && (src[*usedlen + 1] == 's' 22638 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 22639 { 22640 char_u *str; 22641 char_u *pat; 22642 char_u *sub; 22643 int sep; 22644 char_u *flags; 22645 int didit = FALSE; 22646 22647 flags = (char_u *)""; 22648 s = src + *usedlen + 2; 22649 if (src[*usedlen + 1] == 'g') 22650 { 22651 flags = (char_u *)"g"; 22652 ++s; 22653 } 22654 22655 sep = *s++; 22656 if (sep) 22657 { 22658 /* find end of pattern */ 22659 p = vim_strchr(s, sep); 22660 if (p != NULL) 22661 { 22662 pat = vim_strnsave(s, (int)(p - s)); 22663 if (pat != NULL) 22664 { 22665 s = p + 1; 22666 /* find end of substitution */ 22667 p = vim_strchr(s, sep); 22668 if (p != NULL) 22669 { 22670 sub = vim_strnsave(s, (int)(p - s)); 22671 str = vim_strnsave(*fnamep, *fnamelen); 22672 if (sub != NULL && str != NULL) 22673 { 22674 *usedlen = (int)(p + 1 - src); 22675 s = do_string_sub(str, pat, sub, flags); 22676 if (s != NULL) 22677 { 22678 *fnamep = s; 22679 *fnamelen = (int)STRLEN(s); 22680 vim_free(*bufp); 22681 *bufp = s; 22682 didit = TRUE; 22683 } 22684 } 22685 vim_free(sub); 22686 vim_free(str); 22687 } 22688 vim_free(pat); 22689 } 22690 } 22691 /* after using ":s", repeat all the modifiers */ 22692 if (didit) 22693 goto repeat; 22694 } 22695 } 22696 22697 return valid; 22698 } 22699 22700 /* 22701 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 22702 * "flags" can be "g" to do a global substitute. 22703 * Returns an allocated string, NULL for error. 22704 */ 22705 char_u * 22706 do_string_sub(str, pat, sub, flags) 22707 char_u *str; 22708 char_u *pat; 22709 char_u *sub; 22710 char_u *flags; 22711 { 22712 int sublen; 22713 regmatch_T regmatch; 22714 int i; 22715 int do_all; 22716 char_u *tail; 22717 garray_T ga; 22718 char_u *ret; 22719 char_u *save_cpo; 22720 22721 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 22722 save_cpo = p_cpo; 22723 p_cpo = empty_option; 22724 22725 ga_init2(&ga, 1, 200); 22726 22727 do_all = (flags[0] == 'g'); 22728 22729 regmatch.rm_ic = p_ic; 22730 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 22731 if (regmatch.regprog != NULL) 22732 { 22733 tail = str; 22734 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 22735 { 22736 /* 22737 * Get some space for a temporary buffer to do the substitution 22738 * into. It will contain: 22739 * - The text up to where the match is. 22740 * - The substituted text. 22741 * - The text after the match. 22742 */ 22743 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 22744 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 22745 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 22746 { 22747 ga_clear(&ga); 22748 break; 22749 } 22750 22751 /* copy the text up to where the match is */ 22752 i = (int)(regmatch.startp[0] - tail); 22753 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 22754 /* add the substituted text */ 22755 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 22756 + ga.ga_len + i, TRUE, TRUE, FALSE); 22757 ga.ga_len += i + sublen - 1; 22758 /* avoid getting stuck on a match with an empty string */ 22759 if (tail == regmatch.endp[0]) 22760 { 22761 if (*tail == NUL) 22762 break; 22763 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 22764 ++ga.ga_len; 22765 } 22766 else 22767 { 22768 tail = regmatch.endp[0]; 22769 if (*tail == NUL) 22770 break; 22771 } 22772 if (!do_all) 22773 break; 22774 } 22775 22776 if (ga.ga_data != NULL) 22777 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 22778 22779 vim_free(regmatch.regprog); 22780 } 22781 22782 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 22783 ga_clear(&ga); 22784 if (p_cpo == empty_option) 22785 p_cpo = save_cpo; 22786 else 22787 /* Darn, evaluating {sub} expression changed the value. */ 22788 free_string_option(save_cpo); 22789 22790 return ret; 22791 } 22792 22793 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 22794