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 /* When using exists() don't auto-load a script. */ 130 static int no_autoload = FALSE; 131 132 /* 133 * When recursively copying lists and dicts we need to remember which ones we 134 * have done to avoid endless recursiveness. This unique ID is used for that. 135 * The last bit is used for previous_funccal, ignored when comparing. 136 */ 137 static int current_copyID = 0; 138 #define COPYID_INC 2 139 #define COPYID_MASK (~0x1) 140 141 /* 142 * Array to hold the hashtab with variables local to each sourced script. 143 * Each item holds a variable (nameless) that points to the dict_T. 144 */ 145 typedef struct 146 { 147 dictitem_T sv_var; 148 dict_T sv_dict; 149 } scriptvar_T; 150 151 static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL}; 152 #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1]) 153 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) 154 155 static int echo_attr = 0; /* attributes used for ":echo" */ 156 157 /* Values for trans_function_name() argument: */ 158 #define TFN_INT 1 /* internal function name OK */ 159 #define TFN_QUIET 2 /* no error messages */ 160 161 /* 162 * Structure to hold info for a user function. 163 */ 164 typedef struct ufunc ufunc_T; 165 166 struct ufunc 167 { 168 int uf_varargs; /* variable nr of arguments */ 169 int uf_flags; 170 int uf_calls; /* nr of active calls */ 171 garray_T uf_args; /* arguments */ 172 garray_T uf_lines; /* function lines */ 173 #ifdef FEAT_PROFILE 174 int uf_profiling; /* TRUE when func is being profiled */ 175 /* profiling the function as a whole */ 176 int uf_tm_count; /* nr of calls */ 177 proftime_T uf_tm_total; /* time spent in function + children */ 178 proftime_T uf_tm_self; /* time spent in function itself */ 179 proftime_T uf_tm_children; /* time spent in children this call */ 180 /* profiling the function per line */ 181 int *uf_tml_count; /* nr of times line was executed */ 182 proftime_T *uf_tml_total; /* time spent in a line + children */ 183 proftime_T *uf_tml_self; /* time spent in a line itself */ 184 proftime_T uf_tml_start; /* start time for current line */ 185 proftime_T uf_tml_children; /* time spent in children for this line */ 186 proftime_T uf_tml_wait; /* start wait time for current line */ 187 int uf_tml_idx; /* index of line being timed; -1 if none */ 188 int uf_tml_execed; /* line being timed was executed */ 189 #endif 190 scid_T uf_script_ID; /* ID of script where function was defined, 191 used for s: variables */ 192 int uf_refcount; /* for numbered function: reference count */ 193 char_u uf_name[1]; /* name of function (actually longer); can 194 start with <SNR>123_ (<SNR> is K_SPECIAL 195 KS_EXTRA KE_SNR) */ 196 }; 197 198 /* function flags */ 199 #define FC_ABORT 1 /* abort function on error */ 200 #define FC_RANGE 2 /* function accepts range */ 201 #define FC_DICT 4 /* Dict function, uses "self" */ 202 203 /* 204 * All user-defined functions are found in this hashtable. 205 */ 206 static hashtab_T func_hashtab; 207 208 /* The names of packages that once were loaded are remembered. */ 209 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 210 211 /* list heads for garbage collection */ 212 static dict_T *first_dict = NULL; /* list of all dicts */ 213 static list_T *first_list = NULL; /* list of all lists */ 214 215 /* From user function to hashitem and back. */ 216 static ufunc_T dumuf; 217 #define UF2HIKEY(fp) ((fp)->uf_name) 218 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 219 #define HI2UF(hi) HIKEY2UF((hi)->hi_key) 220 221 #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 222 #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 223 224 #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 225 #define VAR_SHORT_LEN 20 /* short variable name length */ 226 #define FIXVAR_CNT 12 /* number of fixed variables */ 227 228 /* structure to hold info for a function that is currently being executed. */ 229 typedef struct funccall_S funccall_T; 230 231 struct funccall_S 232 { 233 ufunc_T *func; /* function being called */ 234 int linenr; /* next line to be executed */ 235 int returned; /* ":return" used */ 236 struct /* fixed variables for arguments */ 237 { 238 dictitem_T var; /* variable (without room for name) */ 239 char_u room[VAR_SHORT_LEN]; /* room for the name */ 240 } fixvar[FIXVAR_CNT]; 241 dict_T l_vars; /* l: local function variables */ 242 dictitem_T l_vars_var; /* variable for l: scope */ 243 dict_T l_avars; /* a: argument variables */ 244 dictitem_T l_avars_var; /* variable for a: scope */ 245 list_T l_varlist; /* list for a:000 */ 246 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 247 typval_T *rettv; /* return value */ 248 linenr_T breakpoint; /* next line with breakpoint or zero */ 249 int dbg_tick; /* debug_tick when breakpoint was set */ 250 int level; /* top nesting level of executed function */ 251 #ifdef FEAT_PROFILE 252 proftime_T prof_child; /* time spent in a child */ 253 #endif 254 funccall_T *caller; /* calling function or NULL */ 255 }; 256 257 /* 258 * Info used by a ":for" loop. 259 */ 260 typedef struct 261 { 262 int fi_semicolon; /* TRUE if ending in '; var]' */ 263 int fi_varcount; /* nr of variables in the list */ 264 listwatch_T fi_lw; /* keep an eye on the item used. */ 265 list_T *fi_list; /* list being used */ 266 } forinfo_T; 267 268 /* 269 * Struct used by trans_function_name() 270 */ 271 typedef struct 272 { 273 dict_T *fd_dict; /* Dictionary used */ 274 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 275 dictitem_T *fd_di; /* Dictionary item used */ 276 } funcdict_T; 277 278 279 /* 280 * Array to hold the value of v: variables. 281 * The value is in a dictitem, so that it can also be used in the v: scope. 282 * The reason to use this table anyway is for very quick access to the 283 * variables with the VV_ defines. 284 */ 285 #include "version.h" 286 287 /* values for vv_flags: */ 288 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 289 #define VV_RO 2 /* read-only */ 290 #define VV_RO_SBX 4 /* read-only in the sandbox */ 291 292 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}}, {0} 293 294 static struct vimvar 295 { 296 char *vv_name; /* name of variable, without v: */ 297 dictitem_T vv_di; /* value and name for key */ 298 char vv_filler[16]; /* space for LONGEST name below!!! */ 299 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 300 } vimvars[VV_LEN] = 301 { 302 /* 303 * The order here must match the VV_ defines in vim.h! 304 * Initializing a union does not work, leave tv.vval empty to get zero's. 305 */ 306 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 307 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 308 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 309 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 310 {VV_NAME("warningmsg", VAR_STRING), 0}, 311 {VV_NAME("statusmsg", VAR_STRING), 0}, 312 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 313 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 314 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 315 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 316 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 317 {VV_NAME("fname", VAR_STRING), VV_RO}, 318 {VV_NAME("lang", VAR_STRING), VV_RO}, 319 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 320 {VV_NAME("ctype", VAR_STRING), VV_RO}, 321 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 322 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 323 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 324 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 325 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 326 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 327 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 328 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 329 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 330 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 331 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 332 {VV_NAME("progname", VAR_STRING), VV_RO}, 333 {VV_NAME("servername", VAR_STRING), VV_RO}, 334 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 335 {VV_NAME("exception", VAR_STRING), VV_RO}, 336 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 337 {VV_NAME("register", VAR_STRING), VV_RO}, 338 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 339 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 340 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 341 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 342 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 343 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 344 {VV_NAME("fcs_choice", VAR_STRING), 0}, 345 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 346 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 347 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 348 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 349 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 350 {VV_NAME("scrollstart", VAR_STRING), 0}, 351 {VV_NAME("swapname", VAR_STRING), VV_RO}, 352 {VV_NAME("swapchoice", VAR_STRING), 0}, 353 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 354 {VV_NAME("char", VAR_STRING), VV_RO}, 355 {VV_NAME("mouse_win", VAR_NUMBER), 0}, 356 {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, 357 {VV_NAME("mouse_col", VAR_NUMBER), 0}, 358 {VV_NAME("operator", VAR_STRING), VV_RO}, 359 {VV_NAME("searchforward", VAR_NUMBER), 0}, 360 {VV_NAME("oldfiles", VAR_LIST), 0}, 361 }; 362 363 /* shorthand */ 364 #define vv_type vv_di.di_tv.v_type 365 #define vv_nr vv_di.di_tv.vval.v_number 366 #define vv_float vv_di.di_tv.vval.v_float 367 #define vv_str vv_di.di_tv.vval.v_string 368 #define vv_list vv_di.di_tv.vval.v_list 369 #define vv_tv vv_di.di_tv 370 371 /* 372 * The v: variables are stored in dictionary "vimvardict". 373 * "vimvars_var" is the variable that is used for the "l:" scope. 374 */ 375 static dict_T vimvardict; 376 static dictitem_T vimvars_var; 377 #define vimvarht vimvardict.dv_hashtab 378 379 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 380 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 381 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 382 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 383 #endif 384 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 385 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 386 static char_u *skip_var_one __ARGS((char_u *arg)); 387 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty, int *first)); 388 static void list_glob_vars __ARGS((int *first)); 389 static void list_buf_vars __ARGS((int *first)); 390 static void list_win_vars __ARGS((int *first)); 391 #ifdef FEAT_WINDOWS 392 static void list_tab_vars __ARGS((int *first)); 393 #endif 394 static void list_vim_vars __ARGS((int *first)); 395 static void list_script_vars __ARGS((int *first)); 396 static void list_func_vars __ARGS((int *first)); 397 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first)); 398 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 399 static int check_changedtick __ARGS((char_u *arg)); 400 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 401 static void clear_lval __ARGS((lval_T *lp)); 402 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 403 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 404 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 405 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 406 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 407 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 408 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 409 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 410 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 411 static int tv_islocked __ARGS((typval_T *tv)); 412 413 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 414 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 415 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 416 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 417 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 418 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 419 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate, int want_string)); 420 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate, int want_string)); 421 422 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 423 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 424 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 425 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 426 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 427 static int rettv_list_alloc __ARGS((typval_T *rettv)); 428 static listitem_T *listitem_alloc __ARGS((void)); 429 static void listitem_free __ARGS((listitem_T *item)); 430 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 431 static long list_len __ARGS((list_T *l)); 432 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 433 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 434 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 435 static listitem_T *list_find __ARGS((list_T *l, long n)); 436 static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); 437 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 438 static void list_append __ARGS((list_T *l, listitem_T *item)); 439 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 440 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 441 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 442 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 443 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 444 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 445 static char_u *list2string __ARGS((typval_T *tv, int copyID)); 446 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 447 static int free_unref_items __ARGS((int copyID)); 448 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 449 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 450 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 451 static int rettv_dict_alloc __ARGS((typval_T *rettv)); 452 static void dict_unref __ARGS((dict_T *d)); 453 static void dict_free __ARGS((dict_T *d, int recurse)); 454 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 455 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 456 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 457 static long dict_len __ARGS((dict_T *d)); 458 static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 459 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 460 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 461 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 462 static char_u *string_quote __ARGS((char_u *str, int function)); 463 #ifdef FEAT_FLOAT 464 static int string2float __ARGS((char_u *text, float_T *value)); 465 #endif 466 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 467 static int find_internal_func __ARGS((char_u *name)); 468 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 469 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)); 470 static int call_func __ARGS((char_u *funcname, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 471 static void emsg_funcname __ARGS((char *ermsg, char_u *name)); 472 static int non_zero_arg __ARGS((typval_T *argvars)); 473 474 #ifdef FEAT_FLOAT 475 static void f_abs __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_acos __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_asin __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_atan __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_atan2 __ARGS((typval_T *argvars, typval_T *rettv)); 487 #endif 488 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 499 #ifdef FEAT_FLOAT 500 static void f_ceil __ARGS((typval_T *argvars, typval_T *rettv)); 501 #endif 502 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 507 #if defined(FEAT_INS_EXPAND) 508 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 511 #endif 512 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 514 #ifdef FEAT_FLOAT 515 static void f_cos __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_cosh __ARGS((typval_T *argvars, typval_T *rettv)); 517 #endif 518 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 521 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 532 #ifdef FEAT_FLOAT 533 static void f_exp __ARGS((typval_T *argvars, typval_T *rettv)); 534 #endif 535 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 543 #ifdef FEAT_FLOAT 544 static void f_float2nr __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_floor __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_fmod __ARGS((typval_T *argvars, typval_T *rettv)); 547 #endif 548 static void f_fnameescape __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_gettabvar __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_haslocaldir __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 620 #ifdef FEAT_FLOAT 621 static void f_log __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_log10 __ARGS((typval_T *argvars, typval_T *rettv)); 623 #endif 624 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 636 #ifdef vim_mkdir 637 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 638 #endif 639 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 640 #ifdef FEAT_MZSCHEME 641 static void f_mzeval __ARGS((typval_T *argvars, typval_T *rettv)); 642 #endif 643 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 644 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 645 static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); 646 #ifdef FEAT_FLOAT 647 static void f_pow __ARGS((typval_T *argvars, typval_T *rettv)); 648 #endif 649 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 650 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 651 static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 652 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 653 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 654 static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); 655 static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv)); 656 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 657 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 658 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 659 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 660 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 661 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 662 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 663 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 664 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 665 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 666 #ifdef FEAT_FLOAT 667 static void f_round __ARGS((typval_T *argvars, typval_T *rettv)); 668 #endif 669 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 670 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 671 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 672 static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 673 static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 674 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 675 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 676 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 677 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 678 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 679 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 680 static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv)); 681 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 682 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 683 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 684 static void f_settabvar __ARGS((typval_T *argvars, typval_T *rettv)); 685 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 686 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 687 static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv)); 688 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 689 #ifdef FEAT_FLOAT 690 static void f_sin __ARGS((typval_T *argvars, typval_T *rettv)); 691 static void f_sinh __ARGS((typval_T *argvars, typval_T *rettv)); 692 #endif 693 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 694 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 695 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 696 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 697 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 698 #ifdef FEAT_FLOAT 699 static void f_sqrt __ARGS((typval_T *argvars, typval_T *rettv)); 700 static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv)); 701 #endif 702 static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv)); 703 static void f_strchars __ARGS((typval_T *argvars, typval_T *rettv)); 704 #ifdef HAVE_STRFTIME 705 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 706 #endif 707 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 708 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 709 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 710 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 711 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 712 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 713 static void f_strdisplaywidth __ARGS((typval_T *argvars, typval_T *rettv)); 714 static void f_strwidth __ARGS((typval_T *argvars, typval_T *rettv)); 715 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 716 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 717 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 718 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 719 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 720 static void f_synstack __ARGS((typval_T *argvars, typval_T *rettv)); 721 static void f_synconcealed __ARGS((typval_T *argvars, typval_T *rettv)); 722 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 723 static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 724 static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 725 static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 726 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 727 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 728 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 729 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 730 #ifdef FEAT_FLOAT 731 static void f_tan __ARGS((typval_T *argvars, typval_T *rettv)); 732 static void f_tanh __ARGS((typval_T *argvars, typval_T *rettv)); 733 #endif 734 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 735 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 736 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 737 #ifdef FEAT_FLOAT 738 static void f_trunc __ARGS((typval_T *argvars, typval_T *rettv)); 739 #endif 740 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 741 static void f_undofile __ARGS((typval_T *argvars, typval_T *rettv)); 742 static void f_undotree __ARGS((typval_T *argvars, typval_T *rettv)); 743 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 744 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 745 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 746 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 747 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 748 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 749 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 750 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 751 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 752 static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 753 static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 754 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 755 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 756 757 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); 758 static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum)); 759 static int get_env_len __ARGS((char_u **arg)); 760 static int get_id_len __ARGS((char_u **arg)); 761 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 762 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 763 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 764 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 765 valid character */ 766 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 767 static int eval_isnamec __ARGS((int c)); 768 static int eval_isnamec1 __ARGS((int c)); 769 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 770 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 771 static typval_T *alloc_tv __ARGS((void)); 772 static typval_T *alloc_string_tv __ARGS((char_u *string)); 773 static void init_tv __ARGS((typval_T *varp)); 774 static long get_tv_number __ARGS((typval_T *varp)); 775 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 776 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 777 static char_u *get_tv_string __ARGS((typval_T *varp)); 778 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 779 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 780 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 781 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 782 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 783 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 784 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 785 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first)); 786 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first)); 787 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 788 static int var_check_ro __ARGS((int flags, char_u *name)); 789 static int var_check_fixed __ARGS((int flags, char_u *name)); 790 static int tv_check_lock __ARGS((int lock, char_u *name)); 791 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 792 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 793 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 794 static int eval_fname_script __ARGS((char_u *p)); 795 static int eval_fname_sid __ARGS((char_u *p)); 796 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 797 static ufunc_T *find_func __ARGS((char_u *name)); 798 static int function_exists __ARGS((char_u *name)); 799 static int builtin_function __ARGS((char_u *name)); 800 #ifdef FEAT_PROFILE 801 static void func_do_profile __ARGS((ufunc_T *fp)); 802 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 803 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 804 static int 805 # ifdef __BORLANDC__ 806 _RTLENTRYF 807 # endif 808 prof_total_cmp __ARGS((const void *s1, const void *s2)); 809 static int 810 # ifdef __BORLANDC__ 811 _RTLENTRYF 812 # endif 813 prof_self_cmp __ARGS((const void *s1, const void *s2)); 814 #endif 815 static int script_autoload __ARGS((char_u *name, int reload)); 816 static char_u *autoload_name __ARGS((char_u *name)); 817 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 818 static void func_free __ARGS((ufunc_T *fp)); 819 static void func_unref __ARGS((char_u *name)); 820 static void func_ref __ARGS((char_u *name)); 821 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)); 822 static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ; 823 static void free_funccal __ARGS((funccall_T *fc, int free_val)); 824 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 825 static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); 826 static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 827 static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 828 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 829 static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 830 831 832 #ifdef EBCDIC 833 static int compare_func_name __ARGS((const void *s1, const void *s2)); 834 static void sortFunctions __ARGS(()); 835 #endif 836 837 838 /* Character used as separated in autoload function/variable names. */ 839 #define AUTOLOAD_CHAR '#' 840 841 /* 842 * Initialize the global and v: variables. 843 */ 844 void 845 eval_init() 846 { 847 int i; 848 struct vimvar *p; 849 850 init_var_dict(&globvardict, &globvars_var); 851 init_var_dict(&vimvardict, &vimvars_var); 852 hash_init(&compat_hashtab); 853 hash_init(&func_hashtab); 854 855 for (i = 0; i < VV_LEN; ++i) 856 { 857 p = &vimvars[i]; 858 STRCPY(p->vv_di.di_key, p->vv_name); 859 if (p->vv_flags & VV_RO) 860 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 861 else if (p->vv_flags & VV_RO_SBX) 862 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 863 else 864 p->vv_di.di_flags = DI_FLAGS_FIX; 865 866 /* add to v: scope dict, unless the value is not always available */ 867 if (p->vv_type != VAR_UNKNOWN) 868 hash_add(&vimvarht, p->vv_di.di_key); 869 if (p->vv_flags & VV_COMPAT) 870 /* add to compat scope dict */ 871 hash_add(&compat_hashtab, p->vv_di.di_key); 872 } 873 set_vim_var_nr(VV_SEARCHFORWARD, 1L); 874 875 #ifdef EBCDIC 876 /* 877 * Sort the function table, to enable binary sort. 878 */ 879 sortFunctions(); 880 #endif 881 } 882 883 #if defined(EXITFREE) || defined(PROTO) 884 void 885 eval_clear() 886 { 887 int i; 888 struct vimvar *p; 889 890 for (i = 0; i < VV_LEN; ++i) 891 { 892 p = &vimvars[i]; 893 if (p->vv_di.di_tv.v_type == VAR_STRING) 894 { 895 vim_free(p->vv_str); 896 p->vv_str = NULL; 897 } 898 else if (p->vv_di.di_tv.v_type == VAR_LIST) 899 { 900 list_unref(p->vv_list); 901 p->vv_list = NULL; 902 } 903 } 904 hash_clear(&vimvarht); 905 hash_init(&vimvarht); /* garbage_collect() will access it */ 906 hash_clear(&compat_hashtab); 907 908 free_scriptnames(); 909 910 /* global variables */ 911 vars_clear(&globvarht); 912 913 /* autoloaded script names */ 914 ga_clear_strings(&ga_loaded); 915 916 /* script-local variables */ 917 for (i = 1; i <= ga_scripts.ga_len; ++i) 918 { 919 vars_clear(&SCRIPT_VARS(i)); 920 vim_free(SCRIPT_SV(i)); 921 } 922 ga_clear(&ga_scripts); 923 924 /* unreferenced lists and dicts */ 925 (void)garbage_collect(); 926 927 /* functions */ 928 free_all_functions(); 929 hash_clear(&func_hashtab); 930 } 931 #endif 932 933 /* 934 * Return the name of the executed function. 935 */ 936 char_u * 937 func_name(cookie) 938 void *cookie; 939 { 940 return ((funccall_T *)cookie)->func->uf_name; 941 } 942 943 /* 944 * Return the address holding the next breakpoint line for a funccall cookie. 945 */ 946 linenr_T * 947 func_breakpoint(cookie) 948 void *cookie; 949 { 950 return &((funccall_T *)cookie)->breakpoint; 951 } 952 953 /* 954 * Return the address holding the debug tick for a funccall cookie. 955 */ 956 int * 957 func_dbg_tick(cookie) 958 void *cookie; 959 { 960 return &((funccall_T *)cookie)->dbg_tick; 961 } 962 963 /* 964 * Return the nesting level for a funccall cookie. 965 */ 966 int 967 func_level(cookie) 968 void *cookie; 969 { 970 return ((funccall_T *)cookie)->level; 971 } 972 973 /* pointer to funccal for currently active function */ 974 funccall_T *current_funccal = NULL; 975 976 /* pointer to list of previously used funccal, still around because some 977 * item in it is still being used. */ 978 funccall_T *previous_funccal = NULL; 979 980 /* 981 * Return TRUE when a function was ended by a ":return" command. 982 */ 983 int 984 current_func_returned() 985 { 986 return current_funccal->returned; 987 } 988 989 990 /* 991 * Set an internal variable to a string value. Creates the variable if it does 992 * not already exist. 993 */ 994 void 995 set_internal_string_var(name, value) 996 char_u *name; 997 char_u *value; 998 { 999 char_u *val; 1000 typval_T *tvp; 1001 1002 val = vim_strsave(value); 1003 if (val != NULL) 1004 { 1005 tvp = alloc_string_tv(val); 1006 if (tvp != NULL) 1007 { 1008 set_var(name, tvp, FALSE); 1009 free_tv(tvp); 1010 } 1011 } 1012 } 1013 1014 static lval_T *redir_lval = NULL; 1015 static garray_T redir_ga; /* only valid when redir_lval is not NULL */ 1016 static char_u *redir_endp = NULL; 1017 static char_u *redir_varname = NULL; 1018 1019 /* 1020 * Start recording command output to a variable 1021 * Returns OK if successfully completed the setup. FAIL otherwise. 1022 */ 1023 int 1024 var_redir_start(name, append) 1025 char_u *name; 1026 int append; /* append to an existing variable */ 1027 { 1028 int save_emsg; 1029 int err; 1030 typval_T tv; 1031 1032 /* Catch a bad name early. */ 1033 if (!eval_isnamec1(*name)) 1034 { 1035 EMSG(_(e_invarg)); 1036 return FAIL; 1037 } 1038 1039 /* Make a copy of the name, it is used in redir_lval until redir ends. */ 1040 redir_varname = vim_strsave(name); 1041 if (redir_varname == NULL) 1042 return FAIL; 1043 1044 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 1045 if (redir_lval == NULL) 1046 { 1047 var_redir_stop(); 1048 return FAIL; 1049 } 1050 1051 /* The output is stored in growarray "redir_ga" until redirection ends. */ 1052 ga_init2(&redir_ga, (int)sizeof(char), 500); 1053 1054 /* Parse the variable name (can be a dict or list entry). */ 1055 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 1056 FNE_CHECK_START); 1057 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 1058 { 1059 clear_lval(redir_lval); 1060 if (redir_endp != NULL && *redir_endp != NUL) 1061 /* Trailing characters are present after the variable name */ 1062 EMSG(_(e_trailing)); 1063 else 1064 EMSG(_(e_invarg)); 1065 redir_endp = NULL; /* don't store a value, only cleanup */ 1066 var_redir_stop(); 1067 return FAIL; 1068 } 1069 1070 /* check if we can write to the variable: set it to or append an empty 1071 * string */ 1072 save_emsg = did_emsg; 1073 did_emsg = FALSE; 1074 tv.v_type = VAR_STRING; 1075 tv.vval.v_string = (char_u *)""; 1076 if (append) 1077 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 1078 else 1079 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 1080 clear_lval(redir_lval); 1081 err = did_emsg; 1082 did_emsg |= save_emsg; 1083 if (err) 1084 { 1085 redir_endp = NULL; /* don't store a value, only cleanup */ 1086 var_redir_stop(); 1087 return FAIL; 1088 } 1089 1090 return OK; 1091 } 1092 1093 /* 1094 * Append "value[value_len]" to the variable set by var_redir_start(). 1095 * The actual appending is postponed until redirection ends, because the value 1096 * appended may in fact be the string we write to, changing it may cause freed 1097 * memory to be used: 1098 * :redir => foo 1099 * :let foo 1100 * :redir END 1101 */ 1102 void 1103 var_redir_str(value, value_len) 1104 char_u *value; 1105 int value_len; 1106 { 1107 int len; 1108 1109 if (redir_lval == NULL) 1110 return; 1111 1112 if (value_len == -1) 1113 len = (int)STRLEN(value); /* Append the entire string */ 1114 else 1115 len = value_len; /* Append only "value_len" characters */ 1116 1117 if (ga_grow(&redir_ga, len) == OK) 1118 { 1119 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 1120 redir_ga.ga_len += len; 1121 } 1122 else 1123 var_redir_stop(); 1124 } 1125 1126 /* 1127 * Stop redirecting command output to a variable. 1128 * Frees the allocated memory. 1129 */ 1130 void 1131 var_redir_stop() 1132 { 1133 typval_T tv; 1134 1135 if (redir_lval != NULL) 1136 { 1137 /* If there was no error: assign the text to the variable. */ 1138 if (redir_endp != NULL) 1139 { 1140 ga_append(&redir_ga, NUL); /* Append the trailing NUL. */ 1141 tv.v_type = VAR_STRING; 1142 tv.vval.v_string = redir_ga.ga_data; 1143 /* Call get_lval() again, if it's inside a Dict or List it may 1144 * have changed. */ 1145 redir_endp = get_lval(redir_varname, NULL, redir_lval, 1146 FALSE, FALSE, FALSE, FNE_CHECK_START); 1147 if (redir_endp != NULL && redir_lval->ll_name != NULL) 1148 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 1149 clear_lval(redir_lval); 1150 } 1151 1152 /* free the collected output */ 1153 vim_free(redir_ga.ga_data); 1154 redir_ga.ga_data = NULL; 1155 1156 vim_free(redir_lval); 1157 redir_lval = NULL; 1158 } 1159 vim_free(redir_varname); 1160 redir_varname = NULL; 1161 } 1162 1163 # if defined(FEAT_MBYTE) || defined(PROTO) 1164 int 1165 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1166 char_u *enc_from; 1167 char_u *enc_to; 1168 char_u *fname_from; 1169 char_u *fname_to; 1170 { 1171 int err = FALSE; 1172 1173 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1174 set_vim_var_string(VV_CC_TO, enc_to, -1); 1175 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1176 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1177 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1178 err = TRUE; 1179 set_vim_var_string(VV_CC_FROM, NULL, -1); 1180 set_vim_var_string(VV_CC_TO, NULL, -1); 1181 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1182 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1183 1184 if (err) 1185 return FAIL; 1186 return OK; 1187 } 1188 # endif 1189 1190 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1191 int 1192 eval_printexpr(fname, args) 1193 char_u *fname; 1194 char_u *args; 1195 { 1196 int err = FALSE; 1197 1198 set_vim_var_string(VV_FNAME_IN, fname, -1); 1199 set_vim_var_string(VV_CMDARG, args, -1); 1200 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1201 err = TRUE; 1202 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1203 set_vim_var_string(VV_CMDARG, NULL, -1); 1204 1205 if (err) 1206 { 1207 mch_remove(fname); 1208 return FAIL; 1209 } 1210 return OK; 1211 } 1212 # endif 1213 1214 # if defined(FEAT_DIFF) || defined(PROTO) 1215 void 1216 eval_diff(origfile, newfile, outfile) 1217 char_u *origfile; 1218 char_u *newfile; 1219 char_u *outfile; 1220 { 1221 int err = FALSE; 1222 1223 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1224 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1225 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1226 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1227 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1228 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1229 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1230 } 1231 1232 void 1233 eval_patch(origfile, difffile, outfile) 1234 char_u *origfile; 1235 char_u *difffile; 1236 char_u *outfile; 1237 { 1238 int err; 1239 1240 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1241 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1242 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1243 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1244 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1245 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1246 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1247 } 1248 # endif 1249 1250 /* 1251 * Top level evaluation function, returning a boolean. 1252 * Sets "error" to TRUE if there was an error. 1253 * Return TRUE or FALSE. 1254 */ 1255 int 1256 eval_to_bool(arg, error, nextcmd, skip) 1257 char_u *arg; 1258 int *error; 1259 char_u **nextcmd; 1260 int skip; /* only parse, don't execute */ 1261 { 1262 typval_T tv; 1263 int retval = FALSE; 1264 1265 if (skip) 1266 ++emsg_skip; 1267 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1268 *error = TRUE; 1269 else 1270 { 1271 *error = FALSE; 1272 if (!skip) 1273 { 1274 retval = (get_tv_number_chk(&tv, error) != 0); 1275 clear_tv(&tv); 1276 } 1277 } 1278 if (skip) 1279 --emsg_skip; 1280 1281 return retval; 1282 } 1283 1284 /* 1285 * Top level evaluation function, returning a string. If "skip" is TRUE, 1286 * only parsing to "nextcmd" is done, without reporting errors. Return 1287 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1288 */ 1289 char_u * 1290 eval_to_string_skip(arg, nextcmd, skip) 1291 char_u *arg; 1292 char_u **nextcmd; 1293 int skip; /* only parse, don't execute */ 1294 { 1295 typval_T tv; 1296 char_u *retval; 1297 1298 if (skip) 1299 ++emsg_skip; 1300 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1301 retval = NULL; 1302 else 1303 { 1304 retval = vim_strsave(get_tv_string(&tv)); 1305 clear_tv(&tv); 1306 } 1307 if (skip) 1308 --emsg_skip; 1309 1310 return retval; 1311 } 1312 1313 /* 1314 * Skip over an expression at "*pp". 1315 * Return FAIL for an error, OK otherwise. 1316 */ 1317 int 1318 skip_expr(pp) 1319 char_u **pp; 1320 { 1321 typval_T rettv; 1322 1323 *pp = skipwhite(*pp); 1324 return eval1(pp, &rettv, FALSE); 1325 } 1326 1327 /* 1328 * Top level evaluation function, returning a string. 1329 * When "convert" is TRUE convert a List into a sequence of lines and convert 1330 * a Float to a String. 1331 * Return pointer to allocated memory, or NULL for failure. 1332 */ 1333 char_u * 1334 eval_to_string(arg, nextcmd, convert) 1335 char_u *arg; 1336 char_u **nextcmd; 1337 int convert; 1338 { 1339 typval_T tv; 1340 char_u *retval; 1341 garray_T ga; 1342 #ifdef FEAT_FLOAT 1343 char_u numbuf[NUMBUFLEN]; 1344 #endif 1345 1346 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1347 retval = NULL; 1348 else 1349 { 1350 if (convert && tv.v_type == VAR_LIST) 1351 { 1352 ga_init2(&ga, (int)sizeof(char), 80); 1353 if (tv.vval.v_list != NULL) 1354 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1355 ga_append(&ga, NUL); 1356 retval = (char_u *)ga.ga_data; 1357 } 1358 #ifdef FEAT_FLOAT 1359 else if (convert && tv.v_type == VAR_FLOAT) 1360 { 1361 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float); 1362 retval = vim_strsave(numbuf); 1363 } 1364 #endif 1365 else 1366 retval = vim_strsave(get_tv_string(&tv)); 1367 clear_tv(&tv); 1368 } 1369 1370 return retval; 1371 } 1372 1373 /* 1374 * Call eval_to_string() without using current local variables and using 1375 * textlock. When "use_sandbox" is TRUE use the sandbox. 1376 */ 1377 char_u * 1378 eval_to_string_safe(arg, nextcmd, use_sandbox) 1379 char_u *arg; 1380 char_u **nextcmd; 1381 int use_sandbox; 1382 { 1383 char_u *retval; 1384 void *save_funccalp; 1385 1386 save_funccalp = save_funccal(); 1387 if (use_sandbox) 1388 ++sandbox; 1389 ++textlock; 1390 retval = eval_to_string(arg, nextcmd, FALSE); 1391 if (use_sandbox) 1392 --sandbox; 1393 --textlock; 1394 restore_funccal(save_funccalp); 1395 return retval; 1396 } 1397 1398 /* 1399 * Top level evaluation function, returning a number. 1400 * Evaluates "expr" silently. 1401 * Returns -1 for an error. 1402 */ 1403 int 1404 eval_to_number(expr) 1405 char_u *expr; 1406 { 1407 typval_T rettv; 1408 int retval; 1409 char_u *p = skipwhite(expr); 1410 1411 ++emsg_off; 1412 1413 if (eval1(&p, &rettv, TRUE) == FAIL) 1414 retval = -1; 1415 else 1416 { 1417 retval = get_tv_number_chk(&rettv, NULL); 1418 clear_tv(&rettv); 1419 } 1420 --emsg_off; 1421 1422 return retval; 1423 } 1424 1425 /* 1426 * Prepare v: variable "idx" to be used. 1427 * Save the current typeval in "save_tv". 1428 * When not used yet add the variable to the v: hashtable. 1429 */ 1430 static void 1431 prepare_vimvar(idx, save_tv) 1432 int idx; 1433 typval_T *save_tv; 1434 { 1435 *save_tv = vimvars[idx].vv_tv; 1436 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1437 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1438 } 1439 1440 /* 1441 * Restore v: variable "idx" to typeval "save_tv". 1442 * When no longer defined, remove the variable from the v: hashtable. 1443 */ 1444 static void 1445 restore_vimvar(idx, save_tv) 1446 int idx; 1447 typval_T *save_tv; 1448 { 1449 hashitem_T *hi; 1450 1451 vimvars[idx].vv_tv = *save_tv; 1452 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1453 { 1454 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1455 if (HASHITEM_EMPTY(hi)) 1456 EMSG2(_(e_intern2), "restore_vimvar()"); 1457 else 1458 hash_remove(&vimvarht, hi); 1459 } 1460 } 1461 1462 #if defined(FEAT_SPELL) || defined(PROTO) 1463 /* 1464 * Evaluate an expression to a list with suggestions. 1465 * For the "expr:" part of 'spellsuggest'. 1466 * Returns NULL when there is an error. 1467 */ 1468 list_T * 1469 eval_spell_expr(badword, expr) 1470 char_u *badword; 1471 char_u *expr; 1472 { 1473 typval_T save_val; 1474 typval_T rettv; 1475 list_T *list = NULL; 1476 char_u *p = skipwhite(expr); 1477 1478 /* Set "v:val" to the bad word. */ 1479 prepare_vimvar(VV_VAL, &save_val); 1480 vimvars[VV_VAL].vv_type = VAR_STRING; 1481 vimvars[VV_VAL].vv_str = badword; 1482 if (p_verbose == 0) 1483 ++emsg_off; 1484 1485 if (eval1(&p, &rettv, TRUE) == OK) 1486 { 1487 if (rettv.v_type != VAR_LIST) 1488 clear_tv(&rettv); 1489 else 1490 list = rettv.vval.v_list; 1491 } 1492 1493 if (p_verbose == 0) 1494 --emsg_off; 1495 restore_vimvar(VV_VAL, &save_val); 1496 1497 return list; 1498 } 1499 1500 /* 1501 * "list" is supposed to contain two items: a word and a number. Return the 1502 * word in "pp" and the number as the return value. 1503 * Return -1 if anything isn't right. 1504 * Used to get the good word and score from the eval_spell_expr() result. 1505 */ 1506 int 1507 get_spellword(list, pp) 1508 list_T *list; 1509 char_u **pp; 1510 { 1511 listitem_T *li; 1512 1513 li = list->lv_first; 1514 if (li == NULL) 1515 return -1; 1516 *pp = get_tv_string(&li->li_tv); 1517 1518 li = li->li_next; 1519 if (li == NULL) 1520 return -1; 1521 return get_tv_number(&li->li_tv); 1522 } 1523 #endif 1524 1525 /* 1526 * Top level evaluation function. 1527 * Returns an allocated typval_T with the result. 1528 * Returns NULL when there is an error. 1529 */ 1530 typval_T * 1531 eval_expr(arg, nextcmd) 1532 char_u *arg; 1533 char_u **nextcmd; 1534 { 1535 typval_T *tv; 1536 1537 tv = (typval_T *)alloc(sizeof(typval_T)); 1538 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1539 { 1540 vim_free(tv); 1541 tv = NULL; 1542 } 1543 1544 return tv; 1545 } 1546 1547 1548 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \ 1549 || defined(FEAT_COMPL_FUNC) || defined(PROTO) 1550 /* 1551 * Call some vimL function and return the result in "*rettv". 1552 * Uses argv[argc] for the function arguments. Only Number and String 1553 * arguments are currently supported. 1554 * Returns OK or FAIL. 1555 */ 1556 static int 1557 call_vim_function(func, argc, argv, safe, rettv) 1558 char_u *func; 1559 int argc; 1560 char_u **argv; 1561 int safe; /* use the sandbox */ 1562 typval_T *rettv; 1563 { 1564 typval_T *argvars; 1565 long n; 1566 int len; 1567 int i; 1568 int doesrange; 1569 void *save_funccalp = NULL; 1570 int ret; 1571 1572 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1573 if (argvars == NULL) 1574 return FAIL; 1575 1576 for (i = 0; i < argc; i++) 1577 { 1578 /* Pass a NULL or empty argument as an empty string */ 1579 if (argv[i] == NULL || *argv[i] == NUL) 1580 { 1581 argvars[i].v_type = VAR_STRING; 1582 argvars[i].vval.v_string = (char_u *)""; 1583 continue; 1584 } 1585 1586 /* Recognize a number argument, the others must be strings. */ 1587 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1588 if (len != 0 && len == (int)STRLEN(argv[i])) 1589 { 1590 argvars[i].v_type = VAR_NUMBER; 1591 argvars[i].vval.v_number = n; 1592 } 1593 else 1594 { 1595 argvars[i].v_type = VAR_STRING; 1596 argvars[i].vval.v_string = argv[i]; 1597 } 1598 } 1599 1600 if (safe) 1601 { 1602 save_funccalp = save_funccal(); 1603 ++sandbox; 1604 } 1605 1606 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1607 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1608 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1609 &doesrange, TRUE, NULL); 1610 if (safe) 1611 { 1612 --sandbox; 1613 restore_funccal(save_funccalp); 1614 } 1615 vim_free(argvars); 1616 1617 if (ret == FAIL) 1618 clear_tv(rettv); 1619 1620 return ret; 1621 } 1622 1623 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1624 /* 1625 * Call vimL function "func" and return the result as a string. 1626 * Returns NULL when calling the function fails. 1627 * Uses argv[argc] for the function arguments. 1628 */ 1629 void * 1630 call_func_retstr(func, argc, argv, safe) 1631 char_u *func; 1632 int argc; 1633 char_u **argv; 1634 int safe; /* use the sandbox */ 1635 { 1636 typval_T rettv; 1637 char_u *retval; 1638 1639 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1640 return NULL; 1641 1642 retval = vim_strsave(get_tv_string(&rettv)); 1643 clear_tv(&rettv); 1644 return retval; 1645 } 1646 # endif 1647 1648 # if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1649 /* 1650 * Call vimL function "func" and return the result as a number. 1651 * Returns -1 when calling the function fails. 1652 * Uses argv[argc] for the function arguments. 1653 */ 1654 long 1655 call_func_retnr(func, argc, argv, safe) 1656 char_u *func; 1657 int argc; 1658 char_u **argv; 1659 int safe; /* use the sandbox */ 1660 { 1661 typval_T rettv; 1662 long retval; 1663 1664 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1665 return -1; 1666 1667 retval = get_tv_number_chk(&rettv, NULL); 1668 clear_tv(&rettv); 1669 return retval; 1670 } 1671 # endif 1672 1673 /* 1674 * Call vimL function "func" and return the result as a List. 1675 * Uses argv[argc] for the function arguments. 1676 * Returns NULL when there is something wrong. 1677 */ 1678 void * 1679 call_func_retlist(func, argc, argv, safe) 1680 char_u *func; 1681 int argc; 1682 char_u **argv; 1683 int safe; /* use the sandbox */ 1684 { 1685 typval_T rettv; 1686 1687 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1688 return NULL; 1689 1690 if (rettv.v_type != VAR_LIST) 1691 { 1692 clear_tv(&rettv); 1693 return NULL; 1694 } 1695 1696 return rettv.vval.v_list; 1697 } 1698 #endif 1699 1700 1701 /* 1702 * Save the current function call pointer, and set it to NULL. 1703 * Used when executing autocommands and for ":source". 1704 */ 1705 void * 1706 save_funccal() 1707 { 1708 funccall_T *fc = current_funccal; 1709 1710 current_funccal = NULL; 1711 return (void *)fc; 1712 } 1713 1714 void 1715 restore_funccal(vfc) 1716 void *vfc; 1717 { 1718 funccall_T *fc = (funccall_T *)vfc; 1719 1720 current_funccal = fc; 1721 } 1722 1723 #if defined(FEAT_PROFILE) || defined(PROTO) 1724 /* 1725 * Prepare profiling for entering a child or something else that is not 1726 * counted for the script/function itself. 1727 * Should always be called in pair with prof_child_exit(). 1728 */ 1729 void 1730 prof_child_enter(tm) 1731 proftime_T *tm; /* place to store waittime */ 1732 { 1733 funccall_T *fc = current_funccal; 1734 1735 if (fc != NULL && fc->func->uf_profiling) 1736 profile_start(&fc->prof_child); 1737 script_prof_save(tm); 1738 } 1739 1740 /* 1741 * Take care of time spent in a child. 1742 * Should always be called after prof_child_enter(). 1743 */ 1744 void 1745 prof_child_exit(tm) 1746 proftime_T *tm; /* where waittime was stored */ 1747 { 1748 funccall_T *fc = current_funccal; 1749 1750 if (fc != NULL && fc->func->uf_profiling) 1751 { 1752 profile_end(&fc->prof_child); 1753 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1754 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1755 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1756 } 1757 script_prof_restore(tm); 1758 } 1759 #endif 1760 1761 1762 #ifdef FEAT_FOLDING 1763 /* 1764 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1765 * it in "*cp". Doesn't give error messages. 1766 */ 1767 int 1768 eval_foldexpr(arg, cp) 1769 char_u *arg; 1770 int *cp; 1771 { 1772 typval_T tv; 1773 int retval; 1774 char_u *s; 1775 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1776 OPT_LOCAL); 1777 1778 ++emsg_off; 1779 if (use_sandbox) 1780 ++sandbox; 1781 ++textlock; 1782 *cp = NUL; 1783 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1784 retval = 0; 1785 else 1786 { 1787 /* If the result is a number, just return the number. */ 1788 if (tv.v_type == VAR_NUMBER) 1789 retval = tv.vval.v_number; 1790 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1791 retval = 0; 1792 else 1793 { 1794 /* If the result is a string, check if there is a non-digit before 1795 * the number. */ 1796 s = tv.vval.v_string; 1797 if (!VIM_ISDIGIT(*s) && *s != '-') 1798 *cp = *s++; 1799 retval = atol((char *)s); 1800 } 1801 clear_tv(&tv); 1802 } 1803 --emsg_off; 1804 if (use_sandbox) 1805 --sandbox; 1806 --textlock; 1807 1808 return retval; 1809 } 1810 #endif 1811 1812 /* 1813 * ":let" list all variable values 1814 * ":let var1 var2" list variable values 1815 * ":let var = expr" assignment command. 1816 * ":let var += expr" assignment command. 1817 * ":let var -= expr" assignment command. 1818 * ":let var .= expr" assignment command. 1819 * ":let [var1, var2] = expr" unpack list. 1820 */ 1821 void 1822 ex_let(eap) 1823 exarg_T *eap; 1824 { 1825 char_u *arg = eap->arg; 1826 char_u *expr = NULL; 1827 typval_T rettv; 1828 int i; 1829 int var_count = 0; 1830 int semicolon = 0; 1831 char_u op[2]; 1832 char_u *argend; 1833 int first = TRUE; 1834 1835 argend = skip_var_list(arg, &var_count, &semicolon); 1836 if (argend == NULL) 1837 return; 1838 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1839 --argend; 1840 expr = vim_strchr(argend, '='); 1841 if (expr == NULL) 1842 { 1843 /* 1844 * ":let" without "=": list variables 1845 */ 1846 if (*arg == '[') 1847 EMSG(_(e_invarg)); 1848 else if (!ends_excmd(*arg)) 1849 /* ":let var1 var2" */ 1850 arg = list_arg_vars(eap, arg, &first); 1851 else if (!eap->skip) 1852 { 1853 /* ":let" */ 1854 list_glob_vars(&first); 1855 list_buf_vars(&first); 1856 list_win_vars(&first); 1857 #ifdef FEAT_WINDOWS 1858 list_tab_vars(&first); 1859 #endif 1860 list_script_vars(&first); 1861 list_func_vars(&first); 1862 list_vim_vars(&first); 1863 } 1864 eap->nextcmd = check_nextcmd(arg); 1865 } 1866 else 1867 { 1868 op[0] = '='; 1869 op[1] = NUL; 1870 if (expr > argend) 1871 { 1872 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1873 op[0] = expr[-1]; /* +=, -= or .= */ 1874 } 1875 expr = skipwhite(expr + 1); 1876 1877 if (eap->skip) 1878 ++emsg_skip; 1879 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1880 if (eap->skip) 1881 { 1882 if (i != FAIL) 1883 clear_tv(&rettv); 1884 --emsg_skip; 1885 } 1886 else if (i != FAIL) 1887 { 1888 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1889 op); 1890 clear_tv(&rettv); 1891 } 1892 } 1893 } 1894 1895 /* 1896 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1897 * Handles both "var" with any type and "[var, var; var]" with a list type. 1898 * When "nextchars" is not NULL it points to a string with characters that 1899 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1900 * or concatenate. 1901 * Returns OK or FAIL; 1902 */ 1903 static int 1904 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1905 char_u *arg_start; 1906 typval_T *tv; 1907 int copy; /* copy values from "tv", don't move */ 1908 int semicolon; /* from skip_var_list() */ 1909 int var_count; /* from skip_var_list() */ 1910 char_u *nextchars; 1911 { 1912 char_u *arg = arg_start; 1913 list_T *l; 1914 int i; 1915 listitem_T *item; 1916 typval_T ltv; 1917 1918 if (*arg != '[') 1919 { 1920 /* 1921 * ":let var = expr" or ":for var in list" 1922 */ 1923 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1924 return FAIL; 1925 return OK; 1926 } 1927 1928 /* 1929 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1930 */ 1931 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1932 { 1933 EMSG(_(e_listreq)); 1934 return FAIL; 1935 } 1936 1937 i = list_len(l); 1938 if (semicolon == 0 && var_count < i) 1939 { 1940 EMSG(_("E687: Less targets than List items")); 1941 return FAIL; 1942 } 1943 if (var_count - semicolon > i) 1944 { 1945 EMSG(_("E688: More targets than List items")); 1946 return FAIL; 1947 } 1948 1949 item = l->lv_first; 1950 while (*arg != ']') 1951 { 1952 arg = skipwhite(arg + 1); 1953 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1954 item = item->li_next; 1955 if (arg == NULL) 1956 return FAIL; 1957 1958 arg = skipwhite(arg); 1959 if (*arg == ';') 1960 { 1961 /* Put the rest of the list (may be empty) in the var after ';'. 1962 * Create a new list for this. */ 1963 l = list_alloc(); 1964 if (l == NULL) 1965 return FAIL; 1966 while (item != NULL) 1967 { 1968 list_append_tv(l, &item->li_tv); 1969 item = item->li_next; 1970 } 1971 1972 ltv.v_type = VAR_LIST; 1973 ltv.v_lock = 0; 1974 ltv.vval.v_list = l; 1975 l->lv_refcount = 1; 1976 1977 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1978 (char_u *)"]", nextchars); 1979 clear_tv(<v); 1980 if (arg == NULL) 1981 return FAIL; 1982 break; 1983 } 1984 else if (*arg != ',' && *arg != ']') 1985 { 1986 EMSG2(_(e_intern2), "ex_let_vars()"); 1987 return FAIL; 1988 } 1989 } 1990 1991 return OK; 1992 } 1993 1994 /* 1995 * Skip over assignable variable "var" or list of variables "[var, var]". 1996 * Used for ":let varvar = expr" and ":for varvar in expr". 1997 * For "[var, var]" increment "*var_count" for each variable. 1998 * for "[var, var; var]" set "semicolon". 1999 * Return NULL for an error. 2000 */ 2001 static char_u * 2002 skip_var_list(arg, var_count, semicolon) 2003 char_u *arg; 2004 int *var_count; 2005 int *semicolon; 2006 { 2007 char_u *p, *s; 2008 2009 if (*arg == '[') 2010 { 2011 /* "[var, var]": find the matching ']'. */ 2012 p = arg; 2013 for (;;) 2014 { 2015 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 2016 s = skip_var_one(p); 2017 if (s == p) 2018 { 2019 EMSG2(_(e_invarg2), p); 2020 return NULL; 2021 } 2022 ++*var_count; 2023 2024 p = skipwhite(s); 2025 if (*p == ']') 2026 break; 2027 else if (*p == ';') 2028 { 2029 if (*semicolon == 1) 2030 { 2031 EMSG(_("Double ; in list of variables")); 2032 return NULL; 2033 } 2034 *semicolon = 1; 2035 } 2036 else if (*p != ',') 2037 { 2038 EMSG2(_(e_invarg2), p); 2039 return NULL; 2040 } 2041 } 2042 return p + 1; 2043 } 2044 else 2045 return skip_var_one(arg); 2046 } 2047 2048 /* 2049 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 2050 * l[idx]. 2051 */ 2052 static char_u * 2053 skip_var_one(arg) 2054 char_u *arg; 2055 { 2056 if (*arg == '@' && arg[1] != NUL) 2057 return arg + 2; 2058 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 2059 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2060 } 2061 2062 /* 2063 * List variables for hashtab "ht" with prefix "prefix". 2064 * If "empty" is TRUE also list NULL strings as empty strings. 2065 */ 2066 static void 2067 list_hashtable_vars(ht, prefix, empty, first) 2068 hashtab_T *ht; 2069 char_u *prefix; 2070 int empty; 2071 int *first; 2072 { 2073 hashitem_T *hi; 2074 dictitem_T *di; 2075 int todo; 2076 2077 todo = (int)ht->ht_used; 2078 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 2079 { 2080 if (!HASHITEM_EMPTY(hi)) 2081 { 2082 --todo; 2083 di = HI2DI(hi); 2084 if (empty || di->di_tv.v_type != VAR_STRING 2085 || di->di_tv.vval.v_string != NULL) 2086 list_one_var(di, prefix, first); 2087 } 2088 } 2089 } 2090 2091 /* 2092 * List global variables. 2093 */ 2094 static void 2095 list_glob_vars(first) 2096 int *first; 2097 { 2098 list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first); 2099 } 2100 2101 /* 2102 * List buffer variables. 2103 */ 2104 static void 2105 list_buf_vars(first) 2106 int *first; 2107 { 2108 char_u numbuf[NUMBUFLEN]; 2109 2110 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", 2111 TRUE, first); 2112 2113 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 2114 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, 2115 numbuf, first); 2116 } 2117 2118 /* 2119 * List window variables. 2120 */ 2121 static void 2122 list_win_vars(first) 2123 int *first; 2124 { 2125 list_hashtable_vars(&curwin->w_vars.dv_hashtab, 2126 (char_u *)"w:", TRUE, first); 2127 } 2128 2129 #ifdef FEAT_WINDOWS 2130 /* 2131 * List tab page variables. 2132 */ 2133 static void 2134 list_tab_vars(first) 2135 int *first; 2136 { 2137 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, 2138 (char_u *)"t:", TRUE, first); 2139 } 2140 #endif 2141 2142 /* 2143 * List Vim variables. 2144 */ 2145 static void 2146 list_vim_vars(first) 2147 int *first; 2148 { 2149 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first); 2150 } 2151 2152 /* 2153 * List script-local variables, if there is a script. 2154 */ 2155 static void 2156 list_script_vars(first) 2157 int *first; 2158 { 2159 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 2160 list_hashtable_vars(&SCRIPT_VARS(current_SID), 2161 (char_u *)"s:", FALSE, first); 2162 } 2163 2164 /* 2165 * List function variables, if there is a function. 2166 */ 2167 static void 2168 list_func_vars(first) 2169 int *first; 2170 { 2171 if (current_funccal != NULL) 2172 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2173 (char_u *)"l:", FALSE, first); 2174 } 2175 2176 /* 2177 * List variables in "arg". 2178 */ 2179 static char_u * 2180 list_arg_vars(eap, arg, first) 2181 exarg_T *eap; 2182 char_u *arg; 2183 int *first; 2184 { 2185 int error = FALSE; 2186 int len; 2187 char_u *name; 2188 char_u *name_start; 2189 char_u *arg_subsc; 2190 char_u *tofree; 2191 typval_T tv; 2192 2193 while (!ends_excmd(*arg) && !got_int) 2194 { 2195 if (error || eap->skip) 2196 { 2197 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2198 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2199 { 2200 emsg_severe = TRUE; 2201 EMSG(_(e_trailing)); 2202 break; 2203 } 2204 } 2205 else 2206 { 2207 /* get_name_len() takes care of expanding curly braces */ 2208 name_start = name = arg; 2209 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2210 if (len <= 0) 2211 { 2212 /* This is mainly to keep test 49 working: when expanding 2213 * curly braces fails overrule the exception error message. */ 2214 if (len < 0 && !aborting()) 2215 { 2216 emsg_severe = TRUE; 2217 EMSG2(_(e_invarg2), arg); 2218 break; 2219 } 2220 error = TRUE; 2221 } 2222 else 2223 { 2224 if (tofree != NULL) 2225 name = tofree; 2226 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 2227 error = TRUE; 2228 else 2229 { 2230 /* handle d.key, l[idx], f(expr) */ 2231 arg_subsc = arg; 2232 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2233 error = TRUE; 2234 else 2235 { 2236 if (arg == arg_subsc && len == 2 && name[1] == ':') 2237 { 2238 switch (*name) 2239 { 2240 case 'g': list_glob_vars(first); break; 2241 case 'b': list_buf_vars(first); break; 2242 case 'w': list_win_vars(first); break; 2243 #ifdef FEAT_WINDOWS 2244 case 't': list_tab_vars(first); break; 2245 #endif 2246 case 'v': list_vim_vars(first); break; 2247 case 's': list_script_vars(first); break; 2248 case 'l': list_func_vars(first); break; 2249 default: 2250 EMSG2(_("E738: Can't list variables for %s"), name); 2251 } 2252 } 2253 else 2254 { 2255 char_u numbuf[NUMBUFLEN]; 2256 char_u *tf; 2257 int c; 2258 char_u *s; 2259 2260 s = echo_string(&tv, &tf, numbuf, 0); 2261 c = *arg; 2262 *arg = NUL; 2263 list_one_var_a((char_u *)"", 2264 arg == arg_subsc ? name : name_start, 2265 tv.v_type, 2266 s == NULL ? (char_u *)"" : s, 2267 first); 2268 *arg = c; 2269 vim_free(tf); 2270 } 2271 clear_tv(&tv); 2272 } 2273 } 2274 } 2275 2276 vim_free(tofree); 2277 } 2278 2279 arg = skipwhite(arg); 2280 } 2281 2282 return arg; 2283 } 2284 2285 /* 2286 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2287 * Returns a pointer to the char just after the var name. 2288 * Returns NULL if there is an error. 2289 */ 2290 static char_u * 2291 ex_let_one(arg, tv, copy, endchars, op) 2292 char_u *arg; /* points to variable name */ 2293 typval_T *tv; /* value to assign to variable */ 2294 int copy; /* copy value from "tv" */ 2295 char_u *endchars; /* valid chars after variable name or NULL */ 2296 char_u *op; /* "+", "-", "." or NULL*/ 2297 { 2298 int c1; 2299 char_u *name; 2300 char_u *p; 2301 char_u *arg_end = NULL; 2302 int len; 2303 int opt_flags; 2304 char_u *tofree = NULL; 2305 2306 /* 2307 * ":let $VAR = expr": Set environment variable. 2308 */ 2309 if (*arg == '$') 2310 { 2311 /* Find the end of the name. */ 2312 ++arg; 2313 name = arg; 2314 len = get_env_len(&arg); 2315 if (len == 0) 2316 EMSG2(_(e_invarg2), name - 1); 2317 else 2318 { 2319 if (op != NULL && (*op == '+' || *op == '-')) 2320 EMSG2(_(e_letwrong), op); 2321 else if (endchars != NULL 2322 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2323 EMSG(_(e_letunexp)); 2324 else 2325 { 2326 c1 = name[len]; 2327 name[len] = NUL; 2328 p = get_tv_string_chk(tv); 2329 if (p != NULL && op != NULL && *op == '.') 2330 { 2331 int mustfree = FALSE; 2332 char_u *s = vim_getenv(name, &mustfree); 2333 2334 if (s != NULL) 2335 { 2336 p = tofree = concat_str(s, p); 2337 if (mustfree) 2338 vim_free(s); 2339 } 2340 } 2341 if (p != NULL) 2342 { 2343 vim_setenv(name, p); 2344 if (STRICMP(name, "HOME") == 0) 2345 init_homedir(); 2346 else if (didset_vim && STRICMP(name, "VIM") == 0) 2347 didset_vim = FALSE; 2348 else if (didset_vimruntime 2349 && STRICMP(name, "VIMRUNTIME") == 0) 2350 didset_vimruntime = FALSE; 2351 arg_end = arg; 2352 } 2353 name[len] = c1; 2354 vim_free(tofree); 2355 } 2356 } 2357 } 2358 2359 /* 2360 * ":let &option = expr": Set option value. 2361 * ":let &l:option = expr": Set local option value. 2362 * ":let &g:option = expr": Set global option value. 2363 */ 2364 else if (*arg == '&') 2365 { 2366 /* Find the end of the name. */ 2367 p = find_option_end(&arg, &opt_flags); 2368 if (p == NULL || (endchars != NULL 2369 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2370 EMSG(_(e_letunexp)); 2371 else 2372 { 2373 long n; 2374 int opt_type; 2375 long numval; 2376 char_u *stringval = NULL; 2377 char_u *s; 2378 2379 c1 = *p; 2380 *p = NUL; 2381 2382 n = get_tv_number(tv); 2383 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2384 if (s != NULL && op != NULL && *op != '=') 2385 { 2386 opt_type = get_option_value(arg, &numval, 2387 &stringval, opt_flags); 2388 if ((opt_type == 1 && *op == '.') 2389 || (opt_type == 0 && *op != '.')) 2390 EMSG2(_(e_letwrong), op); 2391 else 2392 { 2393 if (opt_type == 1) /* number */ 2394 { 2395 if (*op == '+') 2396 n = numval + n; 2397 else 2398 n = numval - n; 2399 } 2400 else if (opt_type == 0 && stringval != NULL) /* string */ 2401 { 2402 s = concat_str(stringval, s); 2403 vim_free(stringval); 2404 stringval = s; 2405 } 2406 } 2407 } 2408 if (s != NULL) 2409 { 2410 set_option_value(arg, n, s, opt_flags); 2411 arg_end = p; 2412 } 2413 *p = c1; 2414 vim_free(stringval); 2415 } 2416 } 2417 2418 /* 2419 * ":let @r = expr": Set register contents. 2420 */ 2421 else if (*arg == '@') 2422 { 2423 ++arg; 2424 if (op != NULL && (*op == '+' || *op == '-')) 2425 EMSG2(_(e_letwrong), op); 2426 else if (endchars != NULL 2427 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2428 EMSG(_(e_letunexp)); 2429 else 2430 { 2431 char_u *ptofree = NULL; 2432 char_u *s; 2433 2434 p = get_tv_string_chk(tv); 2435 if (p != NULL && op != NULL && *op == '.') 2436 { 2437 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2438 if (s != NULL) 2439 { 2440 p = ptofree = concat_str(s, p); 2441 vim_free(s); 2442 } 2443 } 2444 if (p != NULL) 2445 { 2446 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2447 arg_end = arg + 1; 2448 } 2449 vim_free(ptofree); 2450 } 2451 } 2452 2453 /* 2454 * ":let var = expr": Set internal variable. 2455 * ":let {expr} = expr": Idem, name made with curly braces 2456 */ 2457 else if (eval_isnamec1(*arg) || *arg == '{') 2458 { 2459 lval_T lv; 2460 2461 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2462 if (p != NULL && lv.ll_name != NULL) 2463 { 2464 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2465 EMSG(_(e_letunexp)); 2466 else 2467 { 2468 set_var_lval(&lv, p, tv, copy, op); 2469 arg_end = p; 2470 } 2471 } 2472 clear_lval(&lv); 2473 } 2474 2475 else 2476 EMSG2(_(e_invarg2), arg); 2477 2478 return arg_end; 2479 } 2480 2481 /* 2482 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2483 */ 2484 static int 2485 check_changedtick(arg) 2486 char_u *arg; 2487 { 2488 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2489 { 2490 EMSG2(_(e_readonlyvar), arg); 2491 return TRUE; 2492 } 2493 return FALSE; 2494 } 2495 2496 /* 2497 * Get an lval: variable, Dict item or List item that can be assigned a value 2498 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2499 * "name.key", "name.key[expr]" etc. 2500 * Indexing only works if "name" is an existing List or Dictionary. 2501 * "name" points to the start of the name. 2502 * If "rettv" is not NULL it points to the value to be assigned. 2503 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2504 * wrong; must end in space or cmd separator. 2505 * 2506 * Returns a pointer to just after the name, including indexes. 2507 * When an evaluation error occurs "lp->ll_name" is NULL; 2508 * Returns NULL for a parsing error. Still need to free items in "lp"! 2509 */ 2510 static char_u * 2511 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2512 char_u *name; 2513 typval_T *rettv; 2514 lval_T *lp; 2515 int unlet; 2516 int skip; 2517 int quiet; /* don't give error messages */ 2518 int fne_flags; /* flags for find_name_end() */ 2519 { 2520 char_u *p; 2521 char_u *expr_start, *expr_end; 2522 int cc; 2523 dictitem_T *v; 2524 typval_T var1; 2525 typval_T var2; 2526 int empty1 = FALSE; 2527 listitem_T *ni; 2528 char_u *key = NULL; 2529 int len; 2530 hashtab_T *ht; 2531 2532 /* Clear everything in "lp". */ 2533 vim_memset(lp, 0, sizeof(lval_T)); 2534 2535 if (skip) 2536 { 2537 /* When skipping just find the end of the name. */ 2538 lp->ll_name = name; 2539 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2540 } 2541 2542 /* Find the end of the name. */ 2543 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2544 if (expr_start != NULL) 2545 { 2546 /* Don't expand the name when we already know there is an error. */ 2547 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2548 && *p != '[' && *p != '.') 2549 { 2550 EMSG(_(e_trailing)); 2551 return NULL; 2552 } 2553 2554 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2555 if (lp->ll_exp_name == NULL) 2556 { 2557 /* Report an invalid expression in braces, unless the 2558 * expression evaluation has been cancelled due to an 2559 * aborting error, an interrupt, or an exception. */ 2560 if (!aborting() && !quiet) 2561 { 2562 emsg_severe = TRUE; 2563 EMSG2(_(e_invarg2), name); 2564 return NULL; 2565 } 2566 } 2567 lp->ll_name = lp->ll_exp_name; 2568 } 2569 else 2570 lp->ll_name = name; 2571 2572 /* Without [idx] or .key we are done. */ 2573 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2574 return p; 2575 2576 cc = *p; 2577 *p = NUL; 2578 v = find_var(lp->ll_name, &ht); 2579 if (v == NULL && !quiet) 2580 EMSG2(_(e_undefvar), lp->ll_name); 2581 *p = cc; 2582 if (v == NULL) 2583 return NULL; 2584 2585 /* 2586 * Loop until no more [idx] or .key is following. 2587 */ 2588 lp->ll_tv = &v->di_tv; 2589 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2590 { 2591 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2592 && !(lp->ll_tv->v_type == VAR_DICT 2593 && lp->ll_tv->vval.v_dict != NULL)) 2594 { 2595 if (!quiet) 2596 EMSG(_("E689: Can only index a List or Dictionary")); 2597 return NULL; 2598 } 2599 if (lp->ll_range) 2600 { 2601 if (!quiet) 2602 EMSG(_("E708: [:] must come last")); 2603 return NULL; 2604 } 2605 2606 len = -1; 2607 if (*p == '.') 2608 { 2609 key = p + 1; 2610 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2611 ; 2612 if (len == 0) 2613 { 2614 if (!quiet) 2615 EMSG(_(e_emptykey)); 2616 return NULL; 2617 } 2618 p = key + len; 2619 } 2620 else 2621 { 2622 /* Get the index [expr] or the first index [expr: ]. */ 2623 p = skipwhite(p + 1); 2624 if (*p == ':') 2625 empty1 = TRUE; 2626 else 2627 { 2628 empty1 = FALSE; 2629 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2630 return NULL; 2631 if (get_tv_string_chk(&var1) == NULL) 2632 { 2633 /* not a number or string */ 2634 clear_tv(&var1); 2635 return NULL; 2636 } 2637 } 2638 2639 /* Optionally get the second index [ :expr]. */ 2640 if (*p == ':') 2641 { 2642 if (lp->ll_tv->v_type == VAR_DICT) 2643 { 2644 if (!quiet) 2645 EMSG(_(e_dictrange)); 2646 if (!empty1) 2647 clear_tv(&var1); 2648 return NULL; 2649 } 2650 if (rettv != NULL && (rettv->v_type != VAR_LIST 2651 || rettv->vval.v_list == NULL)) 2652 { 2653 if (!quiet) 2654 EMSG(_("E709: [:] requires a List value")); 2655 if (!empty1) 2656 clear_tv(&var1); 2657 return NULL; 2658 } 2659 p = skipwhite(p + 1); 2660 if (*p == ']') 2661 lp->ll_empty2 = TRUE; 2662 else 2663 { 2664 lp->ll_empty2 = FALSE; 2665 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2666 { 2667 if (!empty1) 2668 clear_tv(&var1); 2669 return NULL; 2670 } 2671 if (get_tv_string_chk(&var2) == NULL) 2672 { 2673 /* not a number or string */ 2674 if (!empty1) 2675 clear_tv(&var1); 2676 clear_tv(&var2); 2677 return NULL; 2678 } 2679 } 2680 lp->ll_range = TRUE; 2681 } 2682 else 2683 lp->ll_range = FALSE; 2684 2685 if (*p != ']') 2686 { 2687 if (!quiet) 2688 EMSG(_(e_missbrac)); 2689 if (!empty1) 2690 clear_tv(&var1); 2691 if (lp->ll_range && !lp->ll_empty2) 2692 clear_tv(&var2); 2693 return NULL; 2694 } 2695 2696 /* Skip to past ']'. */ 2697 ++p; 2698 } 2699 2700 if (lp->ll_tv->v_type == VAR_DICT) 2701 { 2702 if (len == -1) 2703 { 2704 /* "[key]": get key from "var1" */ 2705 key = get_tv_string(&var1); /* is number or string */ 2706 if (*key == NUL) 2707 { 2708 if (!quiet) 2709 EMSG(_(e_emptykey)); 2710 clear_tv(&var1); 2711 return NULL; 2712 } 2713 } 2714 lp->ll_list = NULL; 2715 lp->ll_dict = lp->ll_tv->vval.v_dict; 2716 lp->ll_di = dict_find(lp->ll_dict, key, len); 2717 if (lp->ll_di == NULL) 2718 { 2719 /* Key does not exist in dict: may need to add it. */ 2720 if (*p == '[' || *p == '.' || unlet) 2721 { 2722 if (!quiet) 2723 EMSG2(_(e_dictkey), key); 2724 if (len == -1) 2725 clear_tv(&var1); 2726 return NULL; 2727 } 2728 if (len == -1) 2729 lp->ll_newkey = vim_strsave(key); 2730 else 2731 lp->ll_newkey = vim_strnsave(key, len); 2732 if (len == -1) 2733 clear_tv(&var1); 2734 if (lp->ll_newkey == NULL) 2735 p = NULL; 2736 break; 2737 } 2738 if (len == -1) 2739 clear_tv(&var1); 2740 lp->ll_tv = &lp->ll_di->di_tv; 2741 } 2742 else 2743 { 2744 /* 2745 * Get the number and item for the only or first index of the List. 2746 */ 2747 if (empty1) 2748 lp->ll_n1 = 0; 2749 else 2750 { 2751 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2752 clear_tv(&var1); 2753 } 2754 lp->ll_dict = NULL; 2755 lp->ll_list = lp->ll_tv->vval.v_list; 2756 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2757 if (lp->ll_li == NULL) 2758 { 2759 if (lp->ll_n1 < 0) 2760 { 2761 lp->ll_n1 = 0; 2762 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2763 } 2764 } 2765 if (lp->ll_li == NULL) 2766 { 2767 if (lp->ll_range && !lp->ll_empty2) 2768 clear_tv(&var2); 2769 return NULL; 2770 } 2771 2772 /* 2773 * May need to find the item or absolute index for the second 2774 * index of a range. 2775 * When no index given: "lp->ll_empty2" is TRUE. 2776 * Otherwise "lp->ll_n2" is set to the second index. 2777 */ 2778 if (lp->ll_range && !lp->ll_empty2) 2779 { 2780 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2781 clear_tv(&var2); 2782 if (lp->ll_n2 < 0) 2783 { 2784 ni = list_find(lp->ll_list, lp->ll_n2); 2785 if (ni == NULL) 2786 return NULL; 2787 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2788 } 2789 2790 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2791 if (lp->ll_n1 < 0) 2792 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2793 if (lp->ll_n2 < lp->ll_n1) 2794 return NULL; 2795 } 2796 2797 lp->ll_tv = &lp->ll_li->li_tv; 2798 } 2799 } 2800 2801 return p; 2802 } 2803 2804 /* 2805 * Clear lval "lp" that was filled by get_lval(). 2806 */ 2807 static void 2808 clear_lval(lp) 2809 lval_T *lp; 2810 { 2811 vim_free(lp->ll_exp_name); 2812 vim_free(lp->ll_newkey); 2813 } 2814 2815 /* 2816 * Set a variable that was parsed by get_lval() to "rettv". 2817 * "endp" points to just after the parsed name. 2818 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2819 */ 2820 static void 2821 set_var_lval(lp, endp, rettv, copy, op) 2822 lval_T *lp; 2823 char_u *endp; 2824 typval_T *rettv; 2825 int copy; 2826 char_u *op; 2827 { 2828 int cc; 2829 listitem_T *ri; 2830 dictitem_T *di; 2831 2832 if (lp->ll_tv == NULL) 2833 { 2834 if (!check_changedtick(lp->ll_name)) 2835 { 2836 cc = *endp; 2837 *endp = NUL; 2838 if (op != NULL && *op != '=') 2839 { 2840 typval_T tv; 2841 2842 /* handle +=, -= and .= */ 2843 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2844 &tv, TRUE) == OK) 2845 { 2846 if (tv_op(&tv, rettv, op) == OK) 2847 set_var(lp->ll_name, &tv, FALSE); 2848 clear_tv(&tv); 2849 } 2850 } 2851 else 2852 set_var(lp->ll_name, rettv, copy); 2853 *endp = cc; 2854 } 2855 } 2856 else if (tv_check_lock(lp->ll_newkey == NULL 2857 ? lp->ll_tv->v_lock 2858 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2859 ; 2860 else if (lp->ll_range) 2861 { 2862 /* 2863 * Assign the List values to the list items. 2864 */ 2865 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2866 { 2867 if (op != NULL && *op != '=') 2868 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2869 else 2870 { 2871 clear_tv(&lp->ll_li->li_tv); 2872 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2873 } 2874 ri = ri->li_next; 2875 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2876 break; 2877 if (lp->ll_li->li_next == NULL) 2878 { 2879 /* Need to add an empty item. */ 2880 if (list_append_number(lp->ll_list, 0) == FAIL) 2881 { 2882 ri = NULL; 2883 break; 2884 } 2885 } 2886 lp->ll_li = lp->ll_li->li_next; 2887 ++lp->ll_n1; 2888 } 2889 if (ri != NULL) 2890 EMSG(_("E710: List value has more items than target")); 2891 else if (lp->ll_empty2 2892 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2893 : lp->ll_n1 != lp->ll_n2) 2894 EMSG(_("E711: List value has not enough items")); 2895 } 2896 else 2897 { 2898 /* 2899 * Assign to a List or Dictionary item. 2900 */ 2901 if (lp->ll_newkey != NULL) 2902 { 2903 if (op != NULL && *op != '=') 2904 { 2905 EMSG2(_(e_letwrong), op); 2906 return; 2907 } 2908 2909 /* Need to add an item to the Dictionary. */ 2910 di = dictitem_alloc(lp->ll_newkey); 2911 if (di == NULL) 2912 return; 2913 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2914 { 2915 vim_free(di); 2916 return; 2917 } 2918 lp->ll_tv = &di->di_tv; 2919 } 2920 else if (op != NULL && *op != '=') 2921 { 2922 tv_op(lp->ll_tv, rettv, op); 2923 return; 2924 } 2925 else 2926 clear_tv(lp->ll_tv); 2927 2928 /* 2929 * Assign the value to the variable or list item. 2930 */ 2931 if (copy) 2932 copy_tv(rettv, lp->ll_tv); 2933 else 2934 { 2935 *lp->ll_tv = *rettv; 2936 lp->ll_tv->v_lock = 0; 2937 init_tv(rettv); 2938 } 2939 } 2940 } 2941 2942 /* 2943 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2944 * Returns OK or FAIL. 2945 */ 2946 static int 2947 tv_op(tv1, tv2, op) 2948 typval_T *tv1; 2949 typval_T *tv2; 2950 char_u *op; 2951 { 2952 long n; 2953 char_u numbuf[NUMBUFLEN]; 2954 char_u *s; 2955 2956 /* Can't do anything with a Funcref or a Dict on the right. */ 2957 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2958 { 2959 switch (tv1->v_type) 2960 { 2961 case VAR_DICT: 2962 case VAR_FUNC: 2963 break; 2964 2965 case VAR_LIST: 2966 if (*op != '+' || tv2->v_type != VAR_LIST) 2967 break; 2968 /* List += List */ 2969 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2970 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2971 return OK; 2972 2973 case VAR_NUMBER: 2974 case VAR_STRING: 2975 if (tv2->v_type == VAR_LIST) 2976 break; 2977 if (*op == '+' || *op == '-') 2978 { 2979 /* nr += nr or nr -= nr*/ 2980 n = get_tv_number(tv1); 2981 #ifdef FEAT_FLOAT 2982 if (tv2->v_type == VAR_FLOAT) 2983 { 2984 float_T f = n; 2985 2986 if (*op == '+') 2987 f += tv2->vval.v_float; 2988 else 2989 f -= tv2->vval.v_float; 2990 clear_tv(tv1); 2991 tv1->v_type = VAR_FLOAT; 2992 tv1->vval.v_float = f; 2993 } 2994 else 2995 #endif 2996 { 2997 if (*op == '+') 2998 n += get_tv_number(tv2); 2999 else 3000 n -= get_tv_number(tv2); 3001 clear_tv(tv1); 3002 tv1->v_type = VAR_NUMBER; 3003 tv1->vval.v_number = n; 3004 } 3005 } 3006 else 3007 { 3008 if (tv2->v_type == VAR_FLOAT) 3009 break; 3010 3011 /* str .= str */ 3012 s = get_tv_string(tv1); 3013 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 3014 clear_tv(tv1); 3015 tv1->v_type = VAR_STRING; 3016 tv1->vval.v_string = s; 3017 } 3018 return OK; 3019 3020 #ifdef FEAT_FLOAT 3021 case VAR_FLOAT: 3022 { 3023 float_T f; 3024 3025 if (*op == '.' || (tv2->v_type != VAR_FLOAT 3026 && tv2->v_type != VAR_NUMBER 3027 && tv2->v_type != VAR_STRING)) 3028 break; 3029 if (tv2->v_type == VAR_FLOAT) 3030 f = tv2->vval.v_float; 3031 else 3032 f = get_tv_number(tv2); 3033 if (*op == '+') 3034 tv1->vval.v_float += f; 3035 else 3036 tv1->vval.v_float -= f; 3037 } 3038 return OK; 3039 #endif 3040 } 3041 } 3042 3043 EMSG2(_(e_letwrong), op); 3044 return FAIL; 3045 } 3046 3047 /* 3048 * Add a watcher to a list. 3049 */ 3050 static void 3051 list_add_watch(l, lw) 3052 list_T *l; 3053 listwatch_T *lw; 3054 { 3055 lw->lw_next = l->lv_watch; 3056 l->lv_watch = lw; 3057 } 3058 3059 /* 3060 * Remove a watcher from a list. 3061 * No warning when it isn't found... 3062 */ 3063 static void 3064 list_rem_watch(l, lwrem) 3065 list_T *l; 3066 listwatch_T *lwrem; 3067 { 3068 listwatch_T *lw, **lwp; 3069 3070 lwp = &l->lv_watch; 3071 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3072 { 3073 if (lw == lwrem) 3074 { 3075 *lwp = lw->lw_next; 3076 break; 3077 } 3078 lwp = &lw->lw_next; 3079 } 3080 } 3081 3082 /* 3083 * Just before removing an item from a list: advance watchers to the next 3084 * item. 3085 */ 3086 static void 3087 list_fix_watch(l, item) 3088 list_T *l; 3089 listitem_T *item; 3090 { 3091 listwatch_T *lw; 3092 3093 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3094 if (lw->lw_item == item) 3095 lw->lw_item = item->li_next; 3096 } 3097 3098 /* 3099 * Evaluate the expression used in a ":for var in expr" command. 3100 * "arg" points to "var". 3101 * Set "*errp" to TRUE for an error, FALSE otherwise; 3102 * Return a pointer that holds the info. Null when there is an error. 3103 */ 3104 void * 3105 eval_for_line(arg, errp, nextcmdp, skip) 3106 char_u *arg; 3107 int *errp; 3108 char_u **nextcmdp; 3109 int skip; 3110 { 3111 forinfo_T *fi; 3112 char_u *expr; 3113 typval_T tv; 3114 list_T *l; 3115 3116 *errp = TRUE; /* default: there is an error */ 3117 3118 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 3119 if (fi == NULL) 3120 return NULL; 3121 3122 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 3123 if (expr == NULL) 3124 return fi; 3125 3126 expr = skipwhite(expr); 3127 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 3128 { 3129 EMSG(_("E690: Missing \"in\" after :for")); 3130 return fi; 3131 } 3132 3133 if (skip) 3134 ++emsg_skip; 3135 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 3136 { 3137 *errp = FALSE; 3138 if (!skip) 3139 { 3140 l = tv.vval.v_list; 3141 if (tv.v_type != VAR_LIST || l == NULL) 3142 { 3143 EMSG(_(e_listreq)); 3144 clear_tv(&tv); 3145 } 3146 else 3147 { 3148 /* No need to increment the refcount, it's already set for the 3149 * list being used in "tv". */ 3150 fi->fi_list = l; 3151 list_add_watch(l, &fi->fi_lw); 3152 fi->fi_lw.lw_item = l->lv_first; 3153 } 3154 } 3155 } 3156 if (skip) 3157 --emsg_skip; 3158 3159 return fi; 3160 } 3161 3162 /* 3163 * Use the first item in a ":for" list. Advance to the next. 3164 * Assign the values to the variable (list). "arg" points to the first one. 3165 * Return TRUE when a valid item was found, FALSE when at end of list or 3166 * something wrong. 3167 */ 3168 int 3169 next_for_item(fi_void, arg) 3170 void *fi_void; 3171 char_u *arg; 3172 { 3173 forinfo_T *fi = (forinfo_T *)fi_void; 3174 int result; 3175 listitem_T *item; 3176 3177 item = fi->fi_lw.lw_item; 3178 if (item == NULL) 3179 result = FALSE; 3180 else 3181 { 3182 fi->fi_lw.lw_item = item->li_next; 3183 result = (ex_let_vars(arg, &item->li_tv, TRUE, 3184 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 3185 } 3186 return result; 3187 } 3188 3189 /* 3190 * Free the structure used to store info used by ":for". 3191 */ 3192 void 3193 free_for_info(fi_void) 3194 void *fi_void; 3195 { 3196 forinfo_T *fi = (forinfo_T *)fi_void; 3197 3198 if (fi != NULL && fi->fi_list != NULL) 3199 { 3200 list_rem_watch(fi->fi_list, &fi->fi_lw); 3201 list_unref(fi->fi_list); 3202 } 3203 vim_free(fi); 3204 } 3205 3206 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3207 3208 void 3209 set_context_for_expression(xp, arg, cmdidx) 3210 expand_T *xp; 3211 char_u *arg; 3212 cmdidx_T cmdidx; 3213 { 3214 int got_eq = FALSE; 3215 int c; 3216 char_u *p; 3217 3218 if (cmdidx == CMD_let) 3219 { 3220 xp->xp_context = EXPAND_USER_VARS; 3221 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3222 { 3223 /* ":let var1 var2 ...": find last space. */ 3224 for (p = arg + STRLEN(arg); p >= arg; ) 3225 { 3226 xp->xp_pattern = p; 3227 mb_ptr_back(arg, p); 3228 if (vim_iswhite(*p)) 3229 break; 3230 } 3231 return; 3232 } 3233 } 3234 else 3235 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3236 : EXPAND_EXPRESSION; 3237 while ((xp->xp_pattern = vim_strpbrk(arg, 3238 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3239 { 3240 c = *xp->xp_pattern; 3241 if (c == '&') 3242 { 3243 c = xp->xp_pattern[1]; 3244 if (c == '&') 3245 { 3246 ++xp->xp_pattern; 3247 xp->xp_context = cmdidx != CMD_let || got_eq 3248 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3249 } 3250 else if (c != ' ') 3251 { 3252 xp->xp_context = EXPAND_SETTINGS; 3253 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3254 xp->xp_pattern += 2; 3255 3256 } 3257 } 3258 else if (c == '$') 3259 { 3260 /* environment variable */ 3261 xp->xp_context = EXPAND_ENV_VARS; 3262 } 3263 else if (c == '=') 3264 { 3265 got_eq = TRUE; 3266 xp->xp_context = EXPAND_EXPRESSION; 3267 } 3268 else if (c == '<' 3269 && xp->xp_context == EXPAND_FUNCTIONS 3270 && vim_strchr(xp->xp_pattern, '(') == NULL) 3271 { 3272 /* Function name can start with "<SNR>" */ 3273 break; 3274 } 3275 else if (cmdidx != CMD_let || got_eq) 3276 { 3277 if (c == '"') /* string */ 3278 { 3279 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3280 if (c == '\\' && xp->xp_pattern[1] != NUL) 3281 ++xp->xp_pattern; 3282 xp->xp_context = EXPAND_NOTHING; 3283 } 3284 else if (c == '\'') /* literal string */ 3285 { 3286 /* Trick: '' is like stopping and starting a literal string. */ 3287 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3288 /* skip */ ; 3289 xp->xp_context = EXPAND_NOTHING; 3290 } 3291 else if (c == '|') 3292 { 3293 if (xp->xp_pattern[1] == '|') 3294 { 3295 ++xp->xp_pattern; 3296 xp->xp_context = EXPAND_EXPRESSION; 3297 } 3298 else 3299 xp->xp_context = EXPAND_COMMANDS; 3300 } 3301 else 3302 xp->xp_context = EXPAND_EXPRESSION; 3303 } 3304 else 3305 /* Doesn't look like something valid, expand as an expression 3306 * anyway. */ 3307 xp->xp_context = EXPAND_EXPRESSION; 3308 arg = xp->xp_pattern; 3309 if (*arg != NUL) 3310 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3311 /* skip */ ; 3312 } 3313 xp->xp_pattern = arg; 3314 } 3315 3316 #endif /* FEAT_CMDL_COMPL */ 3317 3318 /* 3319 * ":1,25call func(arg1, arg2)" function call. 3320 */ 3321 void 3322 ex_call(eap) 3323 exarg_T *eap; 3324 { 3325 char_u *arg = eap->arg; 3326 char_u *startarg; 3327 char_u *name; 3328 char_u *tofree; 3329 int len; 3330 typval_T rettv; 3331 linenr_T lnum; 3332 int doesrange; 3333 int failed = FALSE; 3334 funcdict_T fudi; 3335 3336 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3337 if (fudi.fd_newkey != NULL) 3338 { 3339 /* Still need to give an error message for missing key. */ 3340 EMSG2(_(e_dictkey), fudi.fd_newkey); 3341 vim_free(fudi.fd_newkey); 3342 } 3343 if (tofree == NULL) 3344 return; 3345 3346 /* Increase refcount on dictionary, it could get deleted when evaluating 3347 * the arguments. */ 3348 if (fudi.fd_dict != NULL) 3349 ++fudi.fd_dict->dv_refcount; 3350 3351 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3352 len = (int)STRLEN(tofree); 3353 name = deref_func_name(tofree, &len); 3354 3355 /* Skip white space to allow ":call func ()". Not good, but required for 3356 * backward compatibility. */ 3357 startarg = skipwhite(arg); 3358 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3359 3360 if (*startarg != '(') 3361 { 3362 EMSG2(_("E107: Missing parentheses: %s"), eap->arg); 3363 goto end; 3364 } 3365 3366 /* 3367 * When skipping, evaluate the function once, to find the end of the 3368 * arguments. 3369 * When the function takes a range, this is discovered after the first 3370 * call, and the loop is broken. 3371 */ 3372 if (eap->skip) 3373 { 3374 ++emsg_skip; 3375 lnum = eap->line2; /* do it once, also with an invalid range */ 3376 } 3377 else 3378 lnum = eap->line1; 3379 for ( ; lnum <= eap->line2; ++lnum) 3380 { 3381 if (!eap->skip && eap->addr_count > 0) 3382 { 3383 curwin->w_cursor.lnum = lnum; 3384 curwin->w_cursor.col = 0; 3385 } 3386 arg = startarg; 3387 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3388 eap->line1, eap->line2, &doesrange, 3389 !eap->skip, fudi.fd_dict) == FAIL) 3390 { 3391 failed = TRUE; 3392 break; 3393 } 3394 3395 /* Handle a function returning a Funcref, Dictionary or List. */ 3396 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) 3397 { 3398 failed = TRUE; 3399 break; 3400 } 3401 3402 clear_tv(&rettv); 3403 if (doesrange || eap->skip) 3404 break; 3405 3406 /* Stop when immediately aborting on error, or when an interrupt 3407 * occurred or an exception was thrown but not caught. 3408 * get_func_tv() returned OK, so that the check for trailing 3409 * characters below is executed. */ 3410 if (aborting()) 3411 break; 3412 } 3413 if (eap->skip) 3414 --emsg_skip; 3415 3416 if (!failed) 3417 { 3418 /* Check for trailing illegal characters and a following command. */ 3419 if (!ends_excmd(*arg)) 3420 { 3421 emsg_severe = TRUE; 3422 EMSG(_(e_trailing)); 3423 } 3424 else 3425 eap->nextcmd = check_nextcmd(arg); 3426 } 3427 3428 end: 3429 dict_unref(fudi.fd_dict); 3430 vim_free(tofree); 3431 } 3432 3433 /* 3434 * ":unlet[!] var1 ... " command. 3435 */ 3436 void 3437 ex_unlet(eap) 3438 exarg_T *eap; 3439 { 3440 ex_unletlock(eap, eap->arg, 0); 3441 } 3442 3443 /* 3444 * ":lockvar" and ":unlockvar" commands 3445 */ 3446 void 3447 ex_lockvar(eap) 3448 exarg_T *eap; 3449 { 3450 char_u *arg = eap->arg; 3451 int deep = 2; 3452 3453 if (eap->forceit) 3454 deep = -1; 3455 else if (vim_isdigit(*arg)) 3456 { 3457 deep = getdigits(&arg); 3458 arg = skipwhite(arg); 3459 } 3460 3461 ex_unletlock(eap, arg, deep); 3462 } 3463 3464 /* 3465 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3466 */ 3467 static void 3468 ex_unletlock(eap, argstart, deep) 3469 exarg_T *eap; 3470 char_u *argstart; 3471 int deep; 3472 { 3473 char_u *arg = argstart; 3474 char_u *name_end; 3475 int error = FALSE; 3476 lval_T lv; 3477 3478 do 3479 { 3480 /* Parse the name and find the end. */ 3481 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3482 FNE_CHECK_START); 3483 if (lv.ll_name == NULL) 3484 error = TRUE; /* error but continue parsing */ 3485 if (name_end == NULL || (!vim_iswhite(*name_end) 3486 && !ends_excmd(*name_end))) 3487 { 3488 if (name_end != NULL) 3489 { 3490 emsg_severe = TRUE; 3491 EMSG(_(e_trailing)); 3492 } 3493 if (!(eap->skip || error)) 3494 clear_lval(&lv); 3495 break; 3496 } 3497 3498 if (!error && !eap->skip) 3499 { 3500 if (eap->cmdidx == CMD_unlet) 3501 { 3502 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3503 error = TRUE; 3504 } 3505 else 3506 { 3507 if (do_lock_var(&lv, name_end, deep, 3508 eap->cmdidx == CMD_lockvar) == FAIL) 3509 error = TRUE; 3510 } 3511 } 3512 3513 if (!eap->skip) 3514 clear_lval(&lv); 3515 3516 arg = skipwhite(name_end); 3517 } while (!ends_excmd(*arg)); 3518 3519 eap->nextcmd = check_nextcmd(arg); 3520 } 3521 3522 static int 3523 do_unlet_var(lp, name_end, forceit) 3524 lval_T *lp; 3525 char_u *name_end; 3526 int forceit; 3527 { 3528 int ret = OK; 3529 int cc; 3530 3531 if (lp->ll_tv == NULL) 3532 { 3533 cc = *name_end; 3534 *name_end = NUL; 3535 3536 /* Normal name or expanded name. */ 3537 if (check_changedtick(lp->ll_name)) 3538 ret = FAIL; 3539 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3540 ret = FAIL; 3541 *name_end = cc; 3542 } 3543 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3544 return FAIL; 3545 else if (lp->ll_range) 3546 { 3547 listitem_T *li; 3548 3549 /* Delete a range of List items. */ 3550 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3551 { 3552 li = lp->ll_li->li_next; 3553 listitem_remove(lp->ll_list, lp->ll_li); 3554 lp->ll_li = li; 3555 ++lp->ll_n1; 3556 } 3557 } 3558 else 3559 { 3560 if (lp->ll_list != NULL) 3561 /* unlet a List item. */ 3562 listitem_remove(lp->ll_list, lp->ll_li); 3563 else 3564 /* unlet a Dictionary item. */ 3565 dictitem_remove(lp->ll_dict, lp->ll_di); 3566 } 3567 3568 return ret; 3569 } 3570 3571 /* 3572 * "unlet" a variable. Return OK if it existed, FAIL if not. 3573 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3574 */ 3575 int 3576 do_unlet(name, forceit) 3577 char_u *name; 3578 int forceit; 3579 { 3580 hashtab_T *ht; 3581 hashitem_T *hi; 3582 char_u *varname; 3583 dictitem_T *di; 3584 3585 ht = find_var_ht(name, &varname); 3586 if (ht != NULL && *varname != NUL) 3587 { 3588 hi = hash_find(ht, varname); 3589 if (!HASHITEM_EMPTY(hi)) 3590 { 3591 di = HI2DI(hi); 3592 if (var_check_fixed(di->di_flags, name) 3593 || var_check_ro(di->di_flags, name)) 3594 return FAIL; 3595 delete_var(ht, hi); 3596 return OK; 3597 } 3598 } 3599 if (forceit) 3600 return OK; 3601 EMSG2(_("E108: No such variable: \"%s\""), name); 3602 return FAIL; 3603 } 3604 3605 /* 3606 * Lock or unlock variable indicated by "lp". 3607 * "deep" is the levels to go (-1 for unlimited); 3608 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3609 */ 3610 static int 3611 do_lock_var(lp, name_end, deep, lock) 3612 lval_T *lp; 3613 char_u *name_end; 3614 int deep; 3615 int lock; 3616 { 3617 int ret = OK; 3618 int cc; 3619 dictitem_T *di; 3620 3621 if (deep == 0) /* nothing to do */ 3622 return OK; 3623 3624 if (lp->ll_tv == NULL) 3625 { 3626 cc = *name_end; 3627 *name_end = NUL; 3628 3629 /* Normal name or expanded name. */ 3630 if (check_changedtick(lp->ll_name)) 3631 ret = FAIL; 3632 else 3633 { 3634 di = find_var(lp->ll_name, NULL); 3635 if (di == NULL) 3636 ret = FAIL; 3637 else 3638 { 3639 if (lock) 3640 di->di_flags |= DI_FLAGS_LOCK; 3641 else 3642 di->di_flags &= ~DI_FLAGS_LOCK; 3643 item_lock(&di->di_tv, deep, lock); 3644 } 3645 } 3646 *name_end = cc; 3647 } 3648 else if (lp->ll_range) 3649 { 3650 listitem_T *li = lp->ll_li; 3651 3652 /* (un)lock a range of List items. */ 3653 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3654 { 3655 item_lock(&li->li_tv, deep, lock); 3656 li = li->li_next; 3657 ++lp->ll_n1; 3658 } 3659 } 3660 else if (lp->ll_list != NULL) 3661 /* (un)lock a List item. */ 3662 item_lock(&lp->ll_li->li_tv, deep, lock); 3663 else 3664 /* un(lock) a Dictionary item. */ 3665 item_lock(&lp->ll_di->di_tv, deep, lock); 3666 3667 return ret; 3668 } 3669 3670 /* 3671 * Lock or unlock an item. "deep" is nr of levels to go. 3672 */ 3673 static void 3674 item_lock(tv, deep, lock) 3675 typval_T *tv; 3676 int deep; 3677 int lock; 3678 { 3679 static int recurse = 0; 3680 list_T *l; 3681 listitem_T *li; 3682 dict_T *d; 3683 hashitem_T *hi; 3684 int todo; 3685 3686 if (recurse >= DICT_MAXNEST) 3687 { 3688 EMSG(_("E743: variable nested too deep for (un)lock")); 3689 return; 3690 } 3691 if (deep == 0) 3692 return; 3693 ++recurse; 3694 3695 /* lock/unlock the item itself */ 3696 if (lock) 3697 tv->v_lock |= VAR_LOCKED; 3698 else 3699 tv->v_lock &= ~VAR_LOCKED; 3700 3701 switch (tv->v_type) 3702 { 3703 case VAR_LIST: 3704 if ((l = tv->vval.v_list) != NULL) 3705 { 3706 if (lock) 3707 l->lv_lock |= VAR_LOCKED; 3708 else 3709 l->lv_lock &= ~VAR_LOCKED; 3710 if (deep < 0 || deep > 1) 3711 /* recursive: lock/unlock the items the List contains */ 3712 for (li = l->lv_first; li != NULL; li = li->li_next) 3713 item_lock(&li->li_tv, deep - 1, lock); 3714 } 3715 break; 3716 case VAR_DICT: 3717 if ((d = tv->vval.v_dict) != NULL) 3718 { 3719 if (lock) 3720 d->dv_lock |= VAR_LOCKED; 3721 else 3722 d->dv_lock &= ~VAR_LOCKED; 3723 if (deep < 0 || deep > 1) 3724 { 3725 /* recursive: lock/unlock the items the List contains */ 3726 todo = (int)d->dv_hashtab.ht_used; 3727 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3728 { 3729 if (!HASHITEM_EMPTY(hi)) 3730 { 3731 --todo; 3732 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3733 } 3734 } 3735 } 3736 } 3737 } 3738 --recurse; 3739 } 3740 3741 /* 3742 * Return TRUE if typeval "tv" is locked: Either that value is locked itself 3743 * or it refers to a List or Dictionary that is locked. 3744 */ 3745 static int 3746 tv_islocked(tv) 3747 typval_T *tv; 3748 { 3749 return (tv->v_lock & VAR_LOCKED) 3750 || (tv->v_type == VAR_LIST 3751 && tv->vval.v_list != NULL 3752 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3753 || (tv->v_type == VAR_DICT 3754 && tv->vval.v_dict != NULL 3755 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3756 } 3757 3758 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3759 /* 3760 * Delete all "menutrans_" variables. 3761 */ 3762 void 3763 del_menutrans_vars() 3764 { 3765 hashitem_T *hi; 3766 int todo; 3767 3768 hash_lock(&globvarht); 3769 todo = (int)globvarht.ht_used; 3770 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3771 { 3772 if (!HASHITEM_EMPTY(hi)) 3773 { 3774 --todo; 3775 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3776 delete_var(&globvarht, hi); 3777 } 3778 } 3779 hash_unlock(&globvarht); 3780 } 3781 #endif 3782 3783 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3784 3785 /* 3786 * Local string buffer for the next two functions to store a variable name 3787 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3788 * get_user_var_name(). 3789 */ 3790 3791 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3792 3793 static char_u *varnamebuf = NULL; 3794 static int varnamebuflen = 0; 3795 3796 /* 3797 * Function to concatenate a prefix and a variable name. 3798 */ 3799 static char_u * 3800 cat_prefix_varname(prefix, name) 3801 int prefix; 3802 char_u *name; 3803 { 3804 int len; 3805 3806 len = (int)STRLEN(name) + 3; 3807 if (len > varnamebuflen) 3808 { 3809 vim_free(varnamebuf); 3810 len += 10; /* some additional space */ 3811 varnamebuf = alloc(len); 3812 if (varnamebuf == NULL) 3813 { 3814 varnamebuflen = 0; 3815 return NULL; 3816 } 3817 varnamebuflen = len; 3818 } 3819 *varnamebuf = prefix; 3820 varnamebuf[1] = ':'; 3821 STRCPY(varnamebuf + 2, name); 3822 return varnamebuf; 3823 } 3824 3825 /* 3826 * Function given to ExpandGeneric() to obtain the list of user defined 3827 * (global/buffer/window/built-in) variable names. 3828 */ 3829 char_u * 3830 get_user_var_name(xp, idx) 3831 expand_T *xp; 3832 int idx; 3833 { 3834 static long_u gdone; 3835 static long_u bdone; 3836 static long_u wdone; 3837 #ifdef FEAT_WINDOWS 3838 static long_u tdone; 3839 #endif 3840 static int vidx; 3841 static hashitem_T *hi; 3842 hashtab_T *ht; 3843 3844 if (idx == 0) 3845 { 3846 gdone = bdone = wdone = vidx = 0; 3847 #ifdef FEAT_WINDOWS 3848 tdone = 0; 3849 #endif 3850 } 3851 3852 /* Global variables */ 3853 if (gdone < globvarht.ht_used) 3854 { 3855 if (gdone++ == 0) 3856 hi = globvarht.ht_array; 3857 else 3858 ++hi; 3859 while (HASHITEM_EMPTY(hi)) 3860 ++hi; 3861 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3862 return cat_prefix_varname('g', hi->hi_key); 3863 return hi->hi_key; 3864 } 3865 3866 /* b: variables */ 3867 ht = &curbuf->b_vars.dv_hashtab; 3868 if (bdone < ht->ht_used) 3869 { 3870 if (bdone++ == 0) 3871 hi = ht->ht_array; 3872 else 3873 ++hi; 3874 while (HASHITEM_EMPTY(hi)) 3875 ++hi; 3876 return cat_prefix_varname('b', hi->hi_key); 3877 } 3878 if (bdone == ht->ht_used) 3879 { 3880 ++bdone; 3881 return (char_u *)"b:changedtick"; 3882 } 3883 3884 /* w: variables */ 3885 ht = &curwin->w_vars.dv_hashtab; 3886 if (wdone < ht->ht_used) 3887 { 3888 if (wdone++ == 0) 3889 hi = ht->ht_array; 3890 else 3891 ++hi; 3892 while (HASHITEM_EMPTY(hi)) 3893 ++hi; 3894 return cat_prefix_varname('w', hi->hi_key); 3895 } 3896 3897 #ifdef FEAT_WINDOWS 3898 /* t: variables */ 3899 ht = &curtab->tp_vars.dv_hashtab; 3900 if (tdone < ht->ht_used) 3901 { 3902 if (tdone++ == 0) 3903 hi = ht->ht_array; 3904 else 3905 ++hi; 3906 while (HASHITEM_EMPTY(hi)) 3907 ++hi; 3908 return cat_prefix_varname('t', hi->hi_key); 3909 } 3910 #endif 3911 3912 /* v: variables */ 3913 if (vidx < VV_LEN) 3914 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3915 3916 vim_free(varnamebuf); 3917 varnamebuf = NULL; 3918 varnamebuflen = 0; 3919 return NULL; 3920 } 3921 3922 #endif /* FEAT_CMDL_COMPL */ 3923 3924 /* 3925 * types for expressions. 3926 */ 3927 typedef enum 3928 { 3929 TYPE_UNKNOWN = 0 3930 , TYPE_EQUAL /* == */ 3931 , TYPE_NEQUAL /* != */ 3932 , TYPE_GREATER /* > */ 3933 , TYPE_GEQUAL /* >= */ 3934 , TYPE_SMALLER /* < */ 3935 , TYPE_SEQUAL /* <= */ 3936 , TYPE_MATCH /* =~ */ 3937 , TYPE_NOMATCH /* !~ */ 3938 } exptype_T; 3939 3940 /* 3941 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3942 * executed. The function may return OK, but the rettv will be of type 3943 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3944 */ 3945 3946 /* 3947 * Handle zero level expression. 3948 * This calls eval1() and handles error message and nextcmd. 3949 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3950 * Note: "rettv.v_lock" is not set. 3951 * Return OK or FAIL. 3952 */ 3953 static int 3954 eval0(arg, rettv, nextcmd, evaluate) 3955 char_u *arg; 3956 typval_T *rettv; 3957 char_u **nextcmd; 3958 int evaluate; 3959 { 3960 int ret; 3961 char_u *p; 3962 3963 p = skipwhite(arg); 3964 ret = eval1(&p, rettv, evaluate); 3965 if (ret == FAIL || !ends_excmd(*p)) 3966 { 3967 if (ret != FAIL) 3968 clear_tv(rettv); 3969 /* 3970 * Report the invalid expression unless the expression evaluation has 3971 * been cancelled due to an aborting error, an interrupt, or an 3972 * exception. 3973 */ 3974 if (!aborting()) 3975 EMSG2(_(e_invexpr2), arg); 3976 ret = FAIL; 3977 } 3978 if (nextcmd != NULL) 3979 *nextcmd = check_nextcmd(p); 3980 3981 return ret; 3982 } 3983 3984 /* 3985 * Handle top level expression: 3986 * expr2 ? expr1 : expr1 3987 * 3988 * "arg" must point to the first non-white of the expression. 3989 * "arg" is advanced to the next non-white after the recognized expression. 3990 * 3991 * Note: "rettv.v_lock" is not set. 3992 * 3993 * Return OK or FAIL. 3994 */ 3995 static int 3996 eval1(arg, rettv, evaluate) 3997 char_u **arg; 3998 typval_T *rettv; 3999 int evaluate; 4000 { 4001 int result; 4002 typval_T var2; 4003 4004 /* 4005 * Get the first variable. 4006 */ 4007 if (eval2(arg, rettv, evaluate) == FAIL) 4008 return FAIL; 4009 4010 if ((*arg)[0] == '?') 4011 { 4012 result = FALSE; 4013 if (evaluate) 4014 { 4015 int error = FALSE; 4016 4017 if (get_tv_number_chk(rettv, &error) != 0) 4018 result = TRUE; 4019 clear_tv(rettv); 4020 if (error) 4021 return FAIL; 4022 } 4023 4024 /* 4025 * Get the second variable. 4026 */ 4027 *arg = skipwhite(*arg + 1); 4028 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 4029 return FAIL; 4030 4031 /* 4032 * Check for the ":". 4033 */ 4034 if ((*arg)[0] != ':') 4035 { 4036 EMSG(_("E109: Missing ':' after '?'")); 4037 if (evaluate && result) 4038 clear_tv(rettv); 4039 return FAIL; 4040 } 4041 4042 /* 4043 * Get the third variable. 4044 */ 4045 *arg = skipwhite(*arg + 1); 4046 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 4047 { 4048 if (evaluate && result) 4049 clear_tv(rettv); 4050 return FAIL; 4051 } 4052 if (evaluate && !result) 4053 *rettv = var2; 4054 } 4055 4056 return OK; 4057 } 4058 4059 /* 4060 * Handle first level expression: 4061 * expr2 || expr2 || expr2 logical OR 4062 * 4063 * "arg" must point to the first non-white of the expression. 4064 * "arg" is advanced to the next non-white after the recognized expression. 4065 * 4066 * Return OK or FAIL. 4067 */ 4068 static int 4069 eval2(arg, rettv, evaluate) 4070 char_u **arg; 4071 typval_T *rettv; 4072 int evaluate; 4073 { 4074 typval_T var2; 4075 long result; 4076 int first; 4077 int error = FALSE; 4078 4079 /* 4080 * Get the first variable. 4081 */ 4082 if (eval3(arg, rettv, evaluate) == FAIL) 4083 return FAIL; 4084 4085 /* 4086 * Repeat until there is no following "||". 4087 */ 4088 first = TRUE; 4089 result = FALSE; 4090 while ((*arg)[0] == '|' && (*arg)[1] == '|') 4091 { 4092 if (evaluate && first) 4093 { 4094 if (get_tv_number_chk(rettv, &error) != 0) 4095 result = TRUE; 4096 clear_tv(rettv); 4097 if (error) 4098 return FAIL; 4099 first = FALSE; 4100 } 4101 4102 /* 4103 * Get the second variable. 4104 */ 4105 *arg = skipwhite(*arg + 2); 4106 if (eval3(arg, &var2, evaluate && !result) == FAIL) 4107 return FAIL; 4108 4109 /* 4110 * Compute the result. 4111 */ 4112 if (evaluate && !result) 4113 { 4114 if (get_tv_number_chk(&var2, &error) != 0) 4115 result = TRUE; 4116 clear_tv(&var2); 4117 if (error) 4118 return FAIL; 4119 } 4120 if (evaluate) 4121 { 4122 rettv->v_type = VAR_NUMBER; 4123 rettv->vval.v_number = result; 4124 } 4125 } 4126 4127 return OK; 4128 } 4129 4130 /* 4131 * Handle second level expression: 4132 * expr3 && expr3 && expr3 logical AND 4133 * 4134 * "arg" must point to the first non-white of the expression. 4135 * "arg" is advanced to the next non-white after the recognized expression. 4136 * 4137 * Return OK or FAIL. 4138 */ 4139 static int 4140 eval3(arg, rettv, evaluate) 4141 char_u **arg; 4142 typval_T *rettv; 4143 int evaluate; 4144 { 4145 typval_T var2; 4146 long result; 4147 int first; 4148 int error = FALSE; 4149 4150 /* 4151 * Get the first variable. 4152 */ 4153 if (eval4(arg, rettv, evaluate) == FAIL) 4154 return FAIL; 4155 4156 /* 4157 * Repeat until there is no following "&&". 4158 */ 4159 first = TRUE; 4160 result = TRUE; 4161 while ((*arg)[0] == '&' && (*arg)[1] == '&') 4162 { 4163 if (evaluate && first) 4164 { 4165 if (get_tv_number_chk(rettv, &error) == 0) 4166 result = FALSE; 4167 clear_tv(rettv); 4168 if (error) 4169 return FAIL; 4170 first = FALSE; 4171 } 4172 4173 /* 4174 * Get the second variable. 4175 */ 4176 *arg = skipwhite(*arg + 2); 4177 if (eval4(arg, &var2, evaluate && result) == FAIL) 4178 return FAIL; 4179 4180 /* 4181 * Compute the result. 4182 */ 4183 if (evaluate && result) 4184 { 4185 if (get_tv_number_chk(&var2, &error) == 0) 4186 result = FALSE; 4187 clear_tv(&var2); 4188 if (error) 4189 return FAIL; 4190 } 4191 if (evaluate) 4192 { 4193 rettv->v_type = VAR_NUMBER; 4194 rettv->vval.v_number = result; 4195 } 4196 } 4197 4198 return OK; 4199 } 4200 4201 /* 4202 * Handle third level expression: 4203 * var1 == var2 4204 * var1 =~ var2 4205 * var1 != var2 4206 * var1 !~ var2 4207 * var1 > var2 4208 * var1 >= var2 4209 * var1 < var2 4210 * var1 <= var2 4211 * var1 is var2 4212 * var1 isnot var2 4213 * 4214 * "arg" must point to the first non-white of the expression. 4215 * "arg" is advanced to the next non-white after the recognized expression. 4216 * 4217 * Return OK or FAIL. 4218 */ 4219 static int 4220 eval4(arg, rettv, evaluate) 4221 char_u **arg; 4222 typval_T *rettv; 4223 int evaluate; 4224 { 4225 typval_T var2; 4226 char_u *p; 4227 int i; 4228 exptype_T type = TYPE_UNKNOWN; 4229 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 4230 int len = 2; 4231 long n1, n2; 4232 char_u *s1, *s2; 4233 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4234 regmatch_T regmatch; 4235 int ic; 4236 char_u *save_cpo; 4237 4238 /* 4239 * Get the first variable. 4240 */ 4241 if (eval5(arg, rettv, evaluate) == FAIL) 4242 return FAIL; 4243 4244 p = *arg; 4245 switch (p[0]) 4246 { 4247 case '=': if (p[1] == '=') 4248 type = TYPE_EQUAL; 4249 else if (p[1] == '~') 4250 type = TYPE_MATCH; 4251 break; 4252 case '!': if (p[1] == '=') 4253 type = TYPE_NEQUAL; 4254 else if (p[1] == '~') 4255 type = TYPE_NOMATCH; 4256 break; 4257 case '>': if (p[1] != '=') 4258 { 4259 type = TYPE_GREATER; 4260 len = 1; 4261 } 4262 else 4263 type = TYPE_GEQUAL; 4264 break; 4265 case '<': if (p[1] != '=') 4266 { 4267 type = TYPE_SMALLER; 4268 len = 1; 4269 } 4270 else 4271 type = TYPE_SEQUAL; 4272 break; 4273 case 'i': if (p[1] == 's') 4274 { 4275 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4276 len = 5; 4277 if (!vim_isIDc(p[len])) 4278 { 4279 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4280 type_is = TRUE; 4281 } 4282 } 4283 break; 4284 } 4285 4286 /* 4287 * If there is a comparative operator, use it. 4288 */ 4289 if (type != TYPE_UNKNOWN) 4290 { 4291 /* extra question mark appended: ignore case */ 4292 if (p[len] == '?') 4293 { 4294 ic = TRUE; 4295 ++len; 4296 } 4297 /* extra '#' appended: match case */ 4298 else if (p[len] == '#') 4299 { 4300 ic = FALSE; 4301 ++len; 4302 } 4303 /* nothing appended: use 'ignorecase' */ 4304 else 4305 ic = p_ic; 4306 4307 /* 4308 * Get the second variable. 4309 */ 4310 *arg = skipwhite(p + len); 4311 if (eval5(arg, &var2, evaluate) == FAIL) 4312 { 4313 clear_tv(rettv); 4314 return FAIL; 4315 } 4316 4317 if (evaluate) 4318 { 4319 if (type_is && rettv->v_type != var2.v_type) 4320 { 4321 /* For "is" a different type always means FALSE, for "notis" 4322 * it means TRUE. */ 4323 n1 = (type == TYPE_NEQUAL); 4324 } 4325 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4326 { 4327 if (type_is) 4328 { 4329 n1 = (rettv->v_type == var2.v_type 4330 && rettv->vval.v_list == var2.vval.v_list); 4331 if (type == TYPE_NEQUAL) 4332 n1 = !n1; 4333 } 4334 else if (rettv->v_type != var2.v_type 4335 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4336 { 4337 if (rettv->v_type != var2.v_type) 4338 EMSG(_("E691: Can only compare List with List")); 4339 else 4340 EMSG(_("E692: Invalid operation for Lists")); 4341 clear_tv(rettv); 4342 clear_tv(&var2); 4343 return FAIL; 4344 } 4345 else 4346 { 4347 /* Compare two Lists for being equal or unequal. */ 4348 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 4349 if (type == TYPE_NEQUAL) 4350 n1 = !n1; 4351 } 4352 } 4353 4354 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4355 { 4356 if (type_is) 4357 { 4358 n1 = (rettv->v_type == var2.v_type 4359 && rettv->vval.v_dict == var2.vval.v_dict); 4360 if (type == TYPE_NEQUAL) 4361 n1 = !n1; 4362 } 4363 else if (rettv->v_type != var2.v_type 4364 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4365 { 4366 if (rettv->v_type != var2.v_type) 4367 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4368 else 4369 EMSG(_("E736: Invalid operation for Dictionary")); 4370 clear_tv(rettv); 4371 clear_tv(&var2); 4372 return FAIL; 4373 } 4374 else 4375 { 4376 /* Compare two Dictionaries for being equal or unequal. */ 4377 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4378 if (type == TYPE_NEQUAL) 4379 n1 = !n1; 4380 } 4381 } 4382 4383 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4384 { 4385 if (rettv->v_type != var2.v_type 4386 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4387 { 4388 if (rettv->v_type != var2.v_type) 4389 EMSG(_("E693: Can only compare Funcref with Funcref")); 4390 else 4391 EMSG(_("E694: Invalid operation for Funcrefs")); 4392 clear_tv(rettv); 4393 clear_tv(&var2); 4394 return FAIL; 4395 } 4396 else 4397 { 4398 /* Compare two Funcrefs for being equal or unequal. */ 4399 if (rettv->vval.v_string == NULL 4400 || var2.vval.v_string == NULL) 4401 n1 = FALSE; 4402 else 4403 n1 = STRCMP(rettv->vval.v_string, 4404 var2.vval.v_string) == 0; 4405 if (type == TYPE_NEQUAL) 4406 n1 = !n1; 4407 } 4408 } 4409 4410 #ifdef FEAT_FLOAT 4411 /* 4412 * If one of the two variables is a float, compare as a float. 4413 * When using "=~" or "!~", always compare as string. 4414 */ 4415 else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4416 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4417 { 4418 float_T f1, f2; 4419 4420 if (rettv->v_type == VAR_FLOAT) 4421 f1 = rettv->vval.v_float; 4422 else 4423 f1 = get_tv_number(rettv); 4424 if (var2.v_type == VAR_FLOAT) 4425 f2 = var2.vval.v_float; 4426 else 4427 f2 = get_tv_number(&var2); 4428 n1 = FALSE; 4429 switch (type) 4430 { 4431 case TYPE_EQUAL: n1 = (f1 == f2); break; 4432 case TYPE_NEQUAL: n1 = (f1 != f2); break; 4433 case TYPE_GREATER: n1 = (f1 > f2); break; 4434 case TYPE_GEQUAL: n1 = (f1 >= f2); break; 4435 case TYPE_SMALLER: n1 = (f1 < f2); break; 4436 case TYPE_SEQUAL: n1 = (f1 <= f2); break; 4437 case TYPE_UNKNOWN: 4438 case TYPE_MATCH: 4439 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4440 } 4441 } 4442 #endif 4443 4444 /* 4445 * If one of the two variables is a number, compare as a number. 4446 * When using "=~" or "!~", always compare as string. 4447 */ 4448 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4449 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4450 { 4451 n1 = get_tv_number(rettv); 4452 n2 = get_tv_number(&var2); 4453 switch (type) 4454 { 4455 case TYPE_EQUAL: n1 = (n1 == n2); break; 4456 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4457 case TYPE_GREATER: n1 = (n1 > n2); break; 4458 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4459 case TYPE_SMALLER: n1 = (n1 < n2); break; 4460 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4461 case TYPE_UNKNOWN: 4462 case TYPE_MATCH: 4463 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4464 } 4465 } 4466 else 4467 { 4468 s1 = get_tv_string_buf(rettv, buf1); 4469 s2 = get_tv_string_buf(&var2, buf2); 4470 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4471 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4472 else 4473 i = 0; 4474 n1 = FALSE; 4475 switch (type) 4476 { 4477 case TYPE_EQUAL: n1 = (i == 0); break; 4478 case TYPE_NEQUAL: n1 = (i != 0); break; 4479 case TYPE_GREATER: n1 = (i > 0); break; 4480 case TYPE_GEQUAL: n1 = (i >= 0); break; 4481 case TYPE_SMALLER: n1 = (i < 0); break; 4482 case TYPE_SEQUAL: n1 = (i <= 0); break; 4483 4484 case TYPE_MATCH: 4485 case TYPE_NOMATCH: 4486 /* avoid 'l' flag in 'cpoptions' */ 4487 save_cpo = p_cpo; 4488 p_cpo = (char_u *)""; 4489 regmatch.regprog = vim_regcomp(s2, 4490 RE_MAGIC + RE_STRING); 4491 regmatch.rm_ic = ic; 4492 if (regmatch.regprog != NULL) 4493 { 4494 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4495 vim_free(regmatch.regprog); 4496 if (type == TYPE_NOMATCH) 4497 n1 = !n1; 4498 } 4499 p_cpo = save_cpo; 4500 break; 4501 4502 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4503 } 4504 } 4505 clear_tv(rettv); 4506 clear_tv(&var2); 4507 rettv->v_type = VAR_NUMBER; 4508 rettv->vval.v_number = n1; 4509 } 4510 } 4511 4512 return OK; 4513 } 4514 4515 /* 4516 * Handle fourth level expression: 4517 * + number addition 4518 * - number subtraction 4519 * . string concatenation 4520 * 4521 * "arg" must point to the first non-white of the expression. 4522 * "arg" is advanced to the next non-white after the recognized expression. 4523 * 4524 * Return OK or FAIL. 4525 */ 4526 static int 4527 eval5(arg, rettv, evaluate) 4528 char_u **arg; 4529 typval_T *rettv; 4530 int evaluate; 4531 { 4532 typval_T var2; 4533 typval_T var3; 4534 int op; 4535 long n1, n2; 4536 #ifdef FEAT_FLOAT 4537 float_T f1 = 0, f2 = 0; 4538 #endif 4539 char_u *s1, *s2; 4540 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4541 char_u *p; 4542 4543 /* 4544 * Get the first variable. 4545 */ 4546 if (eval6(arg, rettv, evaluate, FALSE) == FAIL) 4547 return FAIL; 4548 4549 /* 4550 * Repeat computing, until no '+', '-' or '.' is following. 4551 */ 4552 for (;;) 4553 { 4554 op = **arg; 4555 if (op != '+' && op != '-' && op != '.') 4556 break; 4557 4558 if ((op != '+' || rettv->v_type != VAR_LIST) 4559 #ifdef FEAT_FLOAT 4560 && (op == '.' || rettv->v_type != VAR_FLOAT) 4561 #endif 4562 ) 4563 { 4564 /* For "list + ...", an illegal use of the first operand as 4565 * a number cannot be determined before evaluating the 2nd 4566 * operand: if this is also a list, all is ok. 4567 * For "something . ...", "something - ..." or "non-list + ...", 4568 * we know that the first operand needs to be a string or number 4569 * without evaluating the 2nd operand. So check before to avoid 4570 * side effects after an error. */ 4571 if (evaluate && get_tv_string_chk(rettv) == NULL) 4572 { 4573 clear_tv(rettv); 4574 return FAIL; 4575 } 4576 } 4577 4578 /* 4579 * Get the second variable. 4580 */ 4581 *arg = skipwhite(*arg + 1); 4582 if (eval6(arg, &var2, evaluate, op == '.') == FAIL) 4583 { 4584 clear_tv(rettv); 4585 return FAIL; 4586 } 4587 4588 if (evaluate) 4589 { 4590 /* 4591 * Compute the result. 4592 */ 4593 if (op == '.') 4594 { 4595 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4596 s2 = get_tv_string_buf_chk(&var2, buf2); 4597 if (s2 == NULL) /* type error ? */ 4598 { 4599 clear_tv(rettv); 4600 clear_tv(&var2); 4601 return FAIL; 4602 } 4603 p = concat_str(s1, s2); 4604 clear_tv(rettv); 4605 rettv->v_type = VAR_STRING; 4606 rettv->vval.v_string = p; 4607 } 4608 else if (op == '+' && rettv->v_type == VAR_LIST 4609 && var2.v_type == VAR_LIST) 4610 { 4611 /* concatenate Lists */ 4612 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4613 &var3) == FAIL) 4614 { 4615 clear_tv(rettv); 4616 clear_tv(&var2); 4617 return FAIL; 4618 } 4619 clear_tv(rettv); 4620 *rettv = var3; 4621 } 4622 else 4623 { 4624 int error = FALSE; 4625 4626 #ifdef FEAT_FLOAT 4627 if (rettv->v_type == VAR_FLOAT) 4628 { 4629 f1 = rettv->vval.v_float; 4630 n1 = 0; 4631 } 4632 else 4633 #endif 4634 { 4635 n1 = get_tv_number_chk(rettv, &error); 4636 if (error) 4637 { 4638 /* This can only happen for "list + non-list". For 4639 * "non-list + ..." or "something - ...", we returned 4640 * before evaluating the 2nd operand. */ 4641 clear_tv(rettv); 4642 return FAIL; 4643 } 4644 #ifdef FEAT_FLOAT 4645 if (var2.v_type == VAR_FLOAT) 4646 f1 = n1; 4647 #endif 4648 } 4649 #ifdef FEAT_FLOAT 4650 if (var2.v_type == VAR_FLOAT) 4651 { 4652 f2 = var2.vval.v_float; 4653 n2 = 0; 4654 } 4655 else 4656 #endif 4657 { 4658 n2 = get_tv_number_chk(&var2, &error); 4659 if (error) 4660 { 4661 clear_tv(rettv); 4662 clear_tv(&var2); 4663 return FAIL; 4664 } 4665 #ifdef FEAT_FLOAT 4666 if (rettv->v_type == VAR_FLOAT) 4667 f2 = n2; 4668 #endif 4669 } 4670 clear_tv(rettv); 4671 4672 #ifdef FEAT_FLOAT 4673 /* If there is a float on either side the result is a float. */ 4674 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4675 { 4676 if (op == '+') 4677 f1 = f1 + f2; 4678 else 4679 f1 = f1 - f2; 4680 rettv->v_type = VAR_FLOAT; 4681 rettv->vval.v_float = f1; 4682 } 4683 else 4684 #endif 4685 { 4686 if (op == '+') 4687 n1 = n1 + n2; 4688 else 4689 n1 = n1 - n2; 4690 rettv->v_type = VAR_NUMBER; 4691 rettv->vval.v_number = n1; 4692 } 4693 } 4694 clear_tv(&var2); 4695 } 4696 } 4697 return OK; 4698 } 4699 4700 /* 4701 * Handle fifth level expression: 4702 * * number multiplication 4703 * / number division 4704 * % number modulo 4705 * 4706 * "arg" must point to the first non-white of the expression. 4707 * "arg" is advanced to the next non-white after the recognized expression. 4708 * 4709 * Return OK or FAIL. 4710 */ 4711 static int 4712 eval6(arg, rettv, evaluate, want_string) 4713 char_u **arg; 4714 typval_T *rettv; 4715 int evaluate; 4716 int want_string; /* after "." operator */ 4717 { 4718 typval_T var2; 4719 int op; 4720 long n1, n2; 4721 #ifdef FEAT_FLOAT 4722 int use_float = FALSE; 4723 float_T f1 = 0, f2; 4724 #endif 4725 int error = FALSE; 4726 4727 /* 4728 * Get the first variable. 4729 */ 4730 if (eval7(arg, rettv, evaluate, want_string) == FAIL) 4731 return FAIL; 4732 4733 /* 4734 * Repeat computing, until no '*', '/' or '%' is following. 4735 */ 4736 for (;;) 4737 { 4738 op = **arg; 4739 if (op != '*' && op != '/' && op != '%') 4740 break; 4741 4742 if (evaluate) 4743 { 4744 #ifdef FEAT_FLOAT 4745 if (rettv->v_type == VAR_FLOAT) 4746 { 4747 f1 = rettv->vval.v_float; 4748 use_float = TRUE; 4749 n1 = 0; 4750 } 4751 else 4752 #endif 4753 n1 = get_tv_number_chk(rettv, &error); 4754 clear_tv(rettv); 4755 if (error) 4756 return FAIL; 4757 } 4758 else 4759 n1 = 0; 4760 4761 /* 4762 * Get the second variable. 4763 */ 4764 *arg = skipwhite(*arg + 1); 4765 if (eval7(arg, &var2, evaluate, FALSE) == FAIL) 4766 return FAIL; 4767 4768 if (evaluate) 4769 { 4770 #ifdef FEAT_FLOAT 4771 if (var2.v_type == VAR_FLOAT) 4772 { 4773 if (!use_float) 4774 { 4775 f1 = n1; 4776 use_float = TRUE; 4777 } 4778 f2 = var2.vval.v_float; 4779 n2 = 0; 4780 } 4781 else 4782 #endif 4783 { 4784 n2 = get_tv_number_chk(&var2, &error); 4785 clear_tv(&var2); 4786 if (error) 4787 return FAIL; 4788 #ifdef FEAT_FLOAT 4789 if (use_float) 4790 f2 = n2; 4791 #endif 4792 } 4793 4794 /* 4795 * Compute the result. 4796 * When either side is a float the result is a float. 4797 */ 4798 #ifdef FEAT_FLOAT 4799 if (use_float) 4800 { 4801 if (op == '*') 4802 f1 = f1 * f2; 4803 else if (op == '/') 4804 { 4805 # ifdef VMS 4806 /* VMS crashes on divide by zero, work around it */ 4807 if (f2 == 0.0) 4808 { 4809 if (f1 == 0) 4810 f1 = -0x7fffffffL - 1L; /* similar to NaN */ 4811 else if (f1 < 0) 4812 f1 = -0x7fffffffL; 4813 else 4814 f1 = 0x7fffffffL; 4815 } 4816 else 4817 f1 = f1 / f2; 4818 # else 4819 /* We rely on the floating point library to handle divide 4820 * by zero to result in "inf" and not a crash. */ 4821 f1 = f1 / f2; 4822 # endif 4823 } 4824 else 4825 { 4826 EMSG(_("E804: Cannot use '%' with Float")); 4827 return FAIL; 4828 } 4829 rettv->v_type = VAR_FLOAT; 4830 rettv->vval.v_float = f1; 4831 } 4832 else 4833 #endif 4834 { 4835 if (op == '*') 4836 n1 = n1 * n2; 4837 else if (op == '/') 4838 { 4839 if (n2 == 0) /* give an error message? */ 4840 { 4841 if (n1 == 0) 4842 n1 = -0x7fffffffL - 1L; /* similar to NaN */ 4843 else if (n1 < 0) 4844 n1 = -0x7fffffffL; 4845 else 4846 n1 = 0x7fffffffL; 4847 } 4848 else 4849 n1 = n1 / n2; 4850 } 4851 else 4852 { 4853 if (n2 == 0) /* give an error message? */ 4854 n1 = 0; 4855 else 4856 n1 = n1 % n2; 4857 } 4858 rettv->v_type = VAR_NUMBER; 4859 rettv->vval.v_number = n1; 4860 } 4861 } 4862 } 4863 4864 return OK; 4865 } 4866 4867 /* 4868 * Handle sixth level expression: 4869 * number number constant 4870 * "string" string constant 4871 * 'string' literal string constant 4872 * &option-name option value 4873 * @r register contents 4874 * identifier variable value 4875 * function() function call 4876 * $VAR environment variable 4877 * (expression) nested expression 4878 * [expr, expr] List 4879 * {key: val, key: val} Dictionary 4880 * 4881 * Also handle: 4882 * ! in front logical NOT 4883 * - in front unary minus 4884 * + in front unary plus (ignored) 4885 * trailing [] subscript in String or List 4886 * trailing .name entry in Dictionary 4887 * 4888 * "arg" must point to the first non-white of the expression. 4889 * "arg" is advanced to the next non-white after the recognized expression. 4890 * 4891 * Return OK or FAIL. 4892 */ 4893 static int 4894 eval7(arg, rettv, evaluate, want_string) 4895 char_u **arg; 4896 typval_T *rettv; 4897 int evaluate; 4898 int want_string UNUSED; /* after "." operator */ 4899 { 4900 long n; 4901 int len; 4902 char_u *s; 4903 char_u *start_leader, *end_leader; 4904 int ret = OK; 4905 char_u *alias; 4906 4907 /* 4908 * Initialise variable so that clear_tv() can't mistake this for a 4909 * string and free a string that isn't there. 4910 */ 4911 rettv->v_type = VAR_UNKNOWN; 4912 4913 /* 4914 * Skip '!' and '-' characters. They are handled later. 4915 */ 4916 start_leader = *arg; 4917 while (**arg == '!' || **arg == '-' || **arg == '+') 4918 *arg = skipwhite(*arg + 1); 4919 end_leader = *arg; 4920 4921 switch (**arg) 4922 { 4923 /* 4924 * Number constant. 4925 */ 4926 case '0': 4927 case '1': 4928 case '2': 4929 case '3': 4930 case '4': 4931 case '5': 4932 case '6': 4933 case '7': 4934 case '8': 4935 case '9': 4936 { 4937 #ifdef FEAT_FLOAT 4938 char_u *p = skipdigits(*arg + 1); 4939 int get_float = FALSE; 4940 4941 /* We accept a float when the format matches 4942 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very 4943 * strict to avoid backwards compatibility problems. 4944 * Don't look for a float after the "." operator, so that 4945 * ":let vers = 1.2.3" doesn't fail. */ 4946 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) 4947 { 4948 get_float = TRUE; 4949 p = skipdigits(p + 2); 4950 if (*p == 'e' || *p == 'E') 4951 { 4952 ++p; 4953 if (*p == '-' || *p == '+') 4954 ++p; 4955 if (!vim_isdigit(*p)) 4956 get_float = FALSE; 4957 else 4958 p = skipdigits(p + 1); 4959 } 4960 if (ASCII_ISALPHA(*p) || *p == '.') 4961 get_float = FALSE; 4962 } 4963 if (get_float) 4964 { 4965 float_T f; 4966 4967 *arg += string2float(*arg, &f); 4968 if (evaluate) 4969 { 4970 rettv->v_type = VAR_FLOAT; 4971 rettv->vval.v_float = f; 4972 } 4973 } 4974 else 4975 #endif 4976 { 4977 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4978 *arg += len; 4979 if (evaluate) 4980 { 4981 rettv->v_type = VAR_NUMBER; 4982 rettv->vval.v_number = n; 4983 } 4984 } 4985 break; 4986 } 4987 4988 /* 4989 * String constant: "string". 4990 */ 4991 case '"': ret = get_string_tv(arg, rettv, evaluate); 4992 break; 4993 4994 /* 4995 * Literal string constant: 'str''ing'. 4996 */ 4997 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4998 break; 4999 5000 /* 5001 * List: [expr, expr] 5002 */ 5003 case '[': ret = get_list_tv(arg, rettv, evaluate); 5004 break; 5005 5006 /* 5007 * Dictionary: {key: val, key: val} 5008 */ 5009 case '{': ret = get_dict_tv(arg, rettv, evaluate); 5010 break; 5011 5012 /* 5013 * Option value: &name 5014 */ 5015 case '&': ret = get_option_tv(arg, rettv, evaluate); 5016 break; 5017 5018 /* 5019 * Environment variable: $VAR. 5020 */ 5021 case '$': ret = get_env_tv(arg, rettv, evaluate); 5022 break; 5023 5024 /* 5025 * Register contents: @r. 5026 */ 5027 case '@': ++*arg; 5028 if (evaluate) 5029 { 5030 rettv->v_type = VAR_STRING; 5031 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 5032 } 5033 if (**arg != NUL) 5034 ++*arg; 5035 break; 5036 5037 /* 5038 * nested expression: (expression). 5039 */ 5040 case '(': *arg = skipwhite(*arg + 1); 5041 ret = eval1(arg, rettv, evaluate); /* recursive! */ 5042 if (**arg == ')') 5043 ++*arg; 5044 else if (ret == OK) 5045 { 5046 EMSG(_("E110: Missing ')'")); 5047 clear_tv(rettv); 5048 ret = FAIL; 5049 } 5050 break; 5051 5052 default: ret = NOTDONE; 5053 break; 5054 } 5055 5056 if (ret == NOTDONE) 5057 { 5058 /* 5059 * Must be a variable or function name. 5060 * Can also be a curly-braces kind of name: {expr}. 5061 */ 5062 s = *arg; 5063 len = get_name_len(arg, &alias, evaluate, TRUE); 5064 if (alias != NULL) 5065 s = alias; 5066 5067 if (len <= 0) 5068 ret = FAIL; 5069 else 5070 { 5071 if (**arg == '(') /* recursive! */ 5072 { 5073 /* If "s" is the name of a variable of type VAR_FUNC 5074 * use its contents. */ 5075 s = deref_func_name(s, &len); 5076 5077 /* Invoke the function. */ 5078 ret = get_func_tv(s, len, rettv, arg, 5079 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 5080 &len, evaluate, NULL); 5081 /* Stop the expression evaluation when immediately 5082 * aborting on error, or when an interrupt occurred or 5083 * an exception was thrown but not caught. */ 5084 if (aborting()) 5085 { 5086 if (ret == OK) 5087 clear_tv(rettv); 5088 ret = FAIL; 5089 } 5090 } 5091 else if (evaluate) 5092 ret = get_var_tv(s, len, rettv, TRUE); 5093 else 5094 ret = OK; 5095 } 5096 5097 if (alias != NULL) 5098 vim_free(alias); 5099 } 5100 5101 *arg = skipwhite(*arg); 5102 5103 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 5104 * expr(expr). */ 5105 if (ret == OK) 5106 ret = handle_subscript(arg, rettv, evaluate, TRUE); 5107 5108 /* 5109 * Apply logical NOT and unary '-', from right to left, ignore '+'. 5110 */ 5111 if (ret == OK && evaluate && end_leader > start_leader) 5112 { 5113 int error = FALSE; 5114 int val = 0; 5115 #ifdef FEAT_FLOAT 5116 float_T f = 0.0; 5117 5118 if (rettv->v_type == VAR_FLOAT) 5119 f = rettv->vval.v_float; 5120 else 5121 #endif 5122 val = get_tv_number_chk(rettv, &error); 5123 if (error) 5124 { 5125 clear_tv(rettv); 5126 ret = FAIL; 5127 } 5128 else 5129 { 5130 while (end_leader > start_leader) 5131 { 5132 --end_leader; 5133 if (*end_leader == '!') 5134 { 5135 #ifdef FEAT_FLOAT 5136 if (rettv->v_type == VAR_FLOAT) 5137 f = !f; 5138 else 5139 #endif 5140 val = !val; 5141 } 5142 else if (*end_leader == '-') 5143 { 5144 #ifdef FEAT_FLOAT 5145 if (rettv->v_type == VAR_FLOAT) 5146 f = -f; 5147 else 5148 #endif 5149 val = -val; 5150 } 5151 } 5152 #ifdef FEAT_FLOAT 5153 if (rettv->v_type == VAR_FLOAT) 5154 { 5155 clear_tv(rettv); 5156 rettv->vval.v_float = f; 5157 } 5158 else 5159 #endif 5160 { 5161 clear_tv(rettv); 5162 rettv->v_type = VAR_NUMBER; 5163 rettv->vval.v_number = val; 5164 } 5165 } 5166 } 5167 5168 return ret; 5169 } 5170 5171 /* 5172 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 5173 * "*arg" points to the '[' or '.'. 5174 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 5175 */ 5176 static int 5177 eval_index(arg, rettv, evaluate, verbose) 5178 char_u **arg; 5179 typval_T *rettv; 5180 int evaluate; 5181 int verbose; /* give error messages */ 5182 { 5183 int empty1 = FALSE, empty2 = FALSE; 5184 typval_T var1, var2; 5185 long n1, n2 = 0; 5186 long len = -1; 5187 int range = FALSE; 5188 char_u *s; 5189 char_u *key = NULL; 5190 5191 if (rettv->v_type == VAR_FUNC 5192 #ifdef FEAT_FLOAT 5193 || rettv->v_type == VAR_FLOAT 5194 #endif 5195 ) 5196 { 5197 if (verbose) 5198 EMSG(_("E695: Cannot index a Funcref")); 5199 return FAIL; 5200 } 5201 5202 if (**arg == '.') 5203 { 5204 /* 5205 * dict.name 5206 */ 5207 key = *arg + 1; 5208 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 5209 ; 5210 if (len == 0) 5211 return FAIL; 5212 *arg = skipwhite(key + len); 5213 } 5214 else 5215 { 5216 /* 5217 * something[idx] 5218 * 5219 * Get the (first) variable from inside the []. 5220 */ 5221 *arg = skipwhite(*arg + 1); 5222 if (**arg == ':') 5223 empty1 = TRUE; 5224 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 5225 return FAIL; 5226 else if (evaluate && get_tv_string_chk(&var1) == NULL) 5227 { 5228 /* not a number or string */ 5229 clear_tv(&var1); 5230 return FAIL; 5231 } 5232 5233 /* 5234 * Get the second variable from inside the [:]. 5235 */ 5236 if (**arg == ':') 5237 { 5238 range = TRUE; 5239 *arg = skipwhite(*arg + 1); 5240 if (**arg == ']') 5241 empty2 = TRUE; 5242 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 5243 { 5244 if (!empty1) 5245 clear_tv(&var1); 5246 return FAIL; 5247 } 5248 else if (evaluate && get_tv_string_chk(&var2) == NULL) 5249 { 5250 /* not a number or string */ 5251 if (!empty1) 5252 clear_tv(&var1); 5253 clear_tv(&var2); 5254 return FAIL; 5255 } 5256 } 5257 5258 /* Check for the ']'. */ 5259 if (**arg != ']') 5260 { 5261 if (verbose) 5262 EMSG(_(e_missbrac)); 5263 clear_tv(&var1); 5264 if (range) 5265 clear_tv(&var2); 5266 return FAIL; 5267 } 5268 *arg = skipwhite(*arg + 1); /* skip the ']' */ 5269 } 5270 5271 if (evaluate) 5272 { 5273 n1 = 0; 5274 if (!empty1 && rettv->v_type != VAR_DICT) 5275 { 5276 n1 = get_tv_number(&var1); 5277 clear_tv(&var1); 5278 } 5279 if (range) 5280 { 5281 if (empty2) 5282 n2 = -1; 5283 else 5284 { 5285 n2 = get_tv_number(&var2); 5286 clear_tv(&var2); 5287 } 5288 } 5289 5290 switch (rettv->v_type) 5291 { 5292 case VAR_NUMBER: 5293 case VAR_STRING: 5294 s = get_tv_string(rettv); 5295 len = (long)STRLEN(s); 5296 if (range) 5297 { 5298 /* The resulting variable is a substring. If the indexes 5299 * are out of range the result is empty. */ 5300 if (n1 < 0) 5301 { 5302 n1 = len + n1; 5303 if (n1 < 0) 5304 n1 = 0; 5305 } 5306 if (n2 < 0) 5307 n2 = len + n2; 5308 else if (n2 >= len) 5309 n2 = len; 5310 if (n1 >= len || n2 < 0 || n1 > n2) 5311 s = NULL; 5312 else 5313 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 5314 } 5315 else 5316 { 5317 /* The resulting variable is a string of a single 5318 * character. If the index is too big or negative the 5319 * result is empty. */ 5320 if (n1 >= len || n1 < 0) 5321 s = NULL; 5322 else 5323 s = vim_strnsave(s + n1, 1); 5324 } 5325 clear_tv(rettv); 5326 rettv->v_type = VAR_STRING; 5327 rettv->vval.v_string = s; 5328 break; 5329 5330 case VAR_LIST: 5331 len = list_len(rettv->vval.v_list); 5332 if (n1 < 0) 5333 n1 = len + n1; 5334 if (!empty1 && (n1 < 0 || n1 >= len)) 5335 { 5336 /* For a range we allow invalid values and return an empty 5337 * list. A list index out of range is an error. */ 5338 if (!range) 5339 { 5340 if (verbose) 5341 EMSGN(_(e_listidx), n1); 5342 return FAIL; 5343 } 5344 n1 = len; 5345 } 5346 if (range) 5347 { 5348 list_T *l; 5349 listitem_T *item; 5350 5351 if (n2 < 0) 5352 n2 = len + n2; 5353 else if (n2 >= len) 5354 n2 = len - 1; 5355 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 5356 n2 = -1; 5357 l = list_alloc(); 5358 if (l == NULL) 5359 return FAIL; 5360 for (item = list_find(rettv->vval.v_list, n1); 5361 n1 <= n2; ++n1) 5362 { 5363 if (list_append_tv(l, &item->li_tv) == FAIL) 5364 { 5365 list_free(l, TRUE); 5366 return FAIL; 5367 } 5368 item = item->li_next; 5369 } 5370 clear_tv(rettv); 5371 rettv->v_type = VAR_LIST; 5372 rettv->vval.v_list = l; 5373 ++l->lv_refcount; 5374 } 5375 else 5376 { 5377 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 5378 clear_tv(rettv); 5379 *rettv = var1; 5380 } 5381 break; 5382 5383 case VAR_DICT: 5384 if (range) 5385 { 5386 if (verbose) 5387 EMSG(_(e_dictrange)); 5388 if (len == -1) 5389 clear_tv(&var1); 5390 return FAIL; 5391 } 5392 { 5393 dictitem_T *item; 5394 5395 if (len == -1) 5396 { 5397 key = get_tv_string(&var1); 5398 if (*key == NUL) 5399 { 5400 if (verbose) 5401 EMSG(_(e_emptykey)); 5402 clear_tv(&var1); 5403 return FAIL; 5404 } 5405 } 5406 5407 item = dict_find(rettv->vval.v_dict, key, (int)len); 5408 5409 if (item == NULL && verbose) 5410 EMSG2(_(e_dictkey), key); 5411 if (len == -1) 5412 clear_tv(&var1); 5413 if (item == NULL) 5414 return FAIL; 5415 5416 copy_tv(&item->di_tv, &var1); 5417 clear_tv(rettv); 5418 *rettv = var1; 5419 } 5420 break; 5421 } 5422 } 5423 5424 return OK; 5425 } 5426 5427 /* 5428 * Get an option value. 5429 * "arg" points to the '&' or '+' before the option name. 5430 * "arg" is advanced to character after the option name. 5431 * Return OK or FAIL. 5432 */ 5433 static int 5434 get_option_tv(arg, rettv, evaluate) 5435 char_u **arg; 5436 typval_T *rettv; /* when NULL, only check if option exists */ 5437 int evaluate; 5438 { 5439 char_u *option_end; 5440 long numval; 5441 char_u *stringval; 5442 int opt_type; 5443 int c; 5444 int working = (**arg == '+'); /* has("+option") */ 5445 int ret = OK; 5446 int opt_flags; 5447 5448 /* 5449 * Isolate the option name and find its value. 5450 */ 5451 option_end = find_option_end(arg, &opt_flags); 5452 if (option_end == NULL) 5453 { 5454 if (rettv != NULL) 5455 EMSG2(_("E112: Option name missing: %s"), *arg); 5456 return FAIL; 5457 } 5458 5459 if (!evaluate) 5460 { 5461 *arg = option_end; 5462 return OK; 5463 } 5464 5465 c = *option_end; 5466 *option_end = NUL; 5467 opt_type = get_option_value(*arg, &numval, 5468 rettv == NULL ? NULL : &stringval, opt_flags); 5469 5470 if (opt_type == -3) /* invalid name */ 5471 { 5472 if (rettv != NULL) 5473 EMSG2(_("E113: Unknown option: %s"), *arg); 5474 ret = FAIL; 5475 } 5476 else if (rettv != NULL) 5477 { 5478 if (opt_type == -2) /* hidden string option */ 5479 { 5480 rettv->v_type = VAR_STRING; 5481 rettv->vval.v_string = NULL; 5482 } 5483 else if (opt_type == -1) /* hidden number option */ 5484 { 5485 rettv->v_type = VAR_NUMBER; 5486 rettv->vval.v_number = 0; 5487 } 5488 else if (opt_type == 1) /* number option */ 5489 { 5490 rettv->v_type = VAR_NUMBER; 5491 rettv->vval.v_number = numval; 5492 } 5493 else /* string option */ 5494 { 5495 rettv->v_type = VAR_STRING; 5496 rettv->vval.v_string = stringval; 5497 } 5498 } 5499 else if (working && (opt_type == -2 || opt_type == -1)) 5500 ret = FAIL; 5501 5502 *option_end = c; /* put back for error messages */ 5503 *arg = option_end; 5504 5505 return ret; 5506 } 5507 5508 /* 5509 * Allocate a variable for a string constant. 5510 * Return OK or FAIL. 5511 */ 5512 static int 5513 get_string_tv(arg, rettv, evaluate) 5514 char_u **arg; 5515 typval_T *rettv; 5516 int evaluate; 5517 { 5518 char_u *p; 5519 char_u *name; 5520 int extra = 0; 5521 5522 /* 5523 * Find the end of the string, skipping backslashed characters. 5524 */ 5525 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5526 { 5527 if (*p == '\\' && p[1] != NUL) 5528 { 5529 ++p; 5530 /* A "\<x>" form occupies at least 4 characters, and produces up 5531 * to 6 characters: reserve space for 2 extra */ 5532 if (*p == '<') 5533 extra += 2; 5534 } 5535 } 5536 5537 if (*p != '"') 5538 { 5539 EMSG2(_("E114: Missing quote: %s"), *arg); 5540 return FAIL; 5541 } 5542 5543 /* If only parsing, set *arg and return here */ 5544 if (!evaluate) 5545 { 5546 *arg = p + 1; 5547 return OK; 5548 } 5549 5550 /* 5551 * Copy the string into allocated memory, handling backslashed 5552 * characters. 5553 */ 5554 name = alloc((unsigned)(p - *arg + extra)); 5555 if (name == NULL) 5556 return FAIL; 5557 rettv->v_type = VAR_STRING; 5558 rettv->vval.v_string = name; 5559 5560 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5561 { 5562 if (*p == '\\') 5563 { 5564 switch (*++p) 5565 { 5566 case 'b': *name++ = BS; ++p; break; 5567 case 'e': *name++ = ESC; ++p; break; 5568 case 'f': *name++ = FF; ++p; break; 5569 case 'n': *name++ = NL; ++p; break; 5570 case 'r': *name++ = CAR; ++p; break; 5571 case 't': *name++ = TAB; ++p; break; 5572 5573 case 'X': /* hex: "\x1", "\x12" */ 5574 case 'x': 5575 case 'u': /* Unicode: "\u0023" */ 5576 case 'U': 5577 if (vim_isxdigit(p[1])) 5578 { 5579 int n, nr; 5580 int c = toupper(*p); 5581 5582 if (c == 'X') 5583 n = 2; 5584 else 5585 n = 4; 5586 nr = 0; 5587 while (--n >= 0 && vim_isxdigit(p[1])) 5588 { 5589 ++p; 5590 nr = (nr << 4) + hex2nr(*p); 5591 } 5592 ++p; 5593 #ifdef FEAT_MBYTE 5594 /* For "\u" store the number according to 5595 * 'encoding'. */ 5596 if (c != 'X') 5597 name += (*mb_char2bytes)(nr, name); 5598 else 5599 #endif 5600 *name++ = nr; 5601 } 5602 break; 5603 5604 /* octal: "\1", "\12", "\123" */ 5605 case '0': 5606 case '1': 5607 case '2': 5608 case '3': 5609 case '4': 5610 case '5': 5611 case '6': 5612 case '7': *name = *p++ - '0'; 5613 if (*p >= '0' && *p <= '7') 5614 { 5615 *name = (*name << 3) + *p++ - '0'; 5616 if (*p >= '0' && *p <= '7') 5617 *name = (*name << 3) + *p++ - '0'; 5618 } 5619 ++name; 5620 break; 5621 5622 /* Special key, e.g.: "\<C-W>" */ 5623 case '<': extra = trans_special(&p, name, TRUE); 5624 if (extra != 0) 5625 { 5626 name += extra; 5627 break; 5628 } 5629 /* FALLTHROUGH */ 5630 5631 default: MB_COPY_CHAR(p, name); 5632 break; 5633 } 5634 } 5635 else 5636 MB_COPY_CHAR(p, name); 5637 5638 } 5639 *name = NUL; 5640 *arg = p + 1; 5641 5642 return OK; 5643 } 5644 5645 /* 5646 * Allocate a variable for a 'str''ing' constant. 5647 * Return OK or FAIL. 5648 */ 5649 static int 5650 get_lit_string_tv(arg, rettv, evaluate) 5651 char_u **arg; 5652 typval_T *rettv; 5653 int evaluate; 5654 { 5655 char_u *p; 5656 char_u *str; 5657 int reduce = 0; 5658 5659 /* 5660 * Find the end of the string, skipping ''. 5661 */ 5662 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5663 { 5664 if (*p == '\'') 5665 { 5666 if (p[1] != '\'') 5667 break; 5668 ++reduce; 5669 ++p; 5670 } 5671 } 5672 5673 if (*p != '\'') 5674 { 5675 EMSG2(_("E115: Missing quote: %s"), *arg); 5676 return FAIL; 5677 } 5678 5679 /* If only parsing return after setting "*arg" */ 5680 if (!evaluate) 5681 { 5682 *arg = p + 1; 5683 return OK; 5684 } 5685 5686 /* 5687 * Copy the string into allocated memory, handling '' to ' reduction. 5688 */ 5689 str = alloc((unsigned)((p - *arg) - reduce)); 5690 if (str == NULL) 5691 return FAIL; 5692 rettv->v_type = VAR_STRING; 5693 rettv->vval.v_string = str; 5694 5695 for (p = *arg + 1; *p != NUL; ) 5696 { 5697 if (*p == '\'') 5698 { 5699 if (p[1] != '\'') 5700 break; 5701 ++p; 5702 } 5703 MB_COPY_CHAR(p, str); 5704 } 5705 *str = NUL; 5706 *arg = p + 1; 5707 5708 return OK; 5709 } 5710 5711 /* 5712 * Allocate a variable for a List and fill it from "*arg". 5713 * Return OK or FAIL. 5714 */ 5715 static int 5716 get_list_tv(arg, rettv, evaluate) 5717 char_u **arg; 5718 typval_T *rettv; 5719 int evaluate; 5720 { 5721 list_T *l = NULL; 5722 typval_T tv; 5723 listitem_T *item; 5724 5725 if (evaluate) 5726 { 5727 l = list_alloc(); 5728 if (l == NULL) 5729 return FAIL; 5730 } 5731 5732 *arg = skipwhite(*arg + 1); 5733 while (**arg != ']' && **arg != NUL) 5734 { 5735 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5736 goto failret; 5737 if (evaluate) 5738 { 5739 item = listitem_alloc(); 5740 if (item != NULL) 5741 { 5742 item->li_tv = tv; 5743 item->li_tv.v_lock = 0; 5744 list_append(l, item); 5745 } 5746 else 5747 clear_tv(&tv); 5748 } 5749 5750 if (**arg == ']') 5751 break; 5752 if (**arg != ',') 5753 { 5754 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5755 goto failret; 5756 } 5757 *arg = skipwhite(*arg + 1); 5758 } 5759 5760 if (**arg != ']') 5761 { 5762 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5763 failret: 5764 if (evaluate) 5765 list_free(l, TRUE); 5766 return FAIL; 5767 } 5768 5769 *arg = skipwhite(*arg + 1); 5770 if (evaluate) 5771 { 5772 rettv->v_type = VAR_LIST; 5773 rettv->vval.v_list = l; 5774 ++l->lv_refcount; 5775 } 5776 5777 return OK; 5778 } 5779 5780 /* 5781 * Allocate an empty header for a list. 5782 * Caller should take care of the reference count. 5783 */ 5784 list_T * 5785 list_alloc() 5786 { 5787 list_T *l; 5788 5789 l = (list_T *)alloc_clear(sizeof(list_T)); 5790 if (l != NULL) 5791 { 5792 /* Prepend the list to the list of lists for garbage collection. */ 5793 if (first_list != NULL) 5794 first_list->lv_used_prev = l; 5795 l->lv_used_prev = NULL; 5796 l->lv_used_next = first_list; 5797 first_list = l; 5798 } 5799 return l; 5800 } 5801 5802 /* 5803 * Allocate an empty list for a return value. 5804 * Returns OK or FAIL. 5805 */ 5806 static int 5807 rettv_list_alloc(rettv) 5808 typval_T *rettv; 5809 { 5810 list_T *l = list_alloc(); 5811 5812 if (l == NULL) 5813 return FAIL; 5814 5815 rettv->vval.v_list = l; 5816 rettv->v_type = VAR_LIST; 5817 ++l->lv_refcount; 5818 return OK; 5819 } 5820 5821 /* 5822 * Unreference a list: decrement the reference count and free it when it 5823 * becomes zero. 5824 */ 5825 void 5826 list_unref(l) 5827 list_T *l; 5828 { 5829 if (l != NULL && --l->lv_refcount <= 0) 5830 list_free(l, TRUE); 5831 } 5832 5833 /* 5834 * Free a list, including all items it points to. 5835 * Ignores the reference count. 5836 */ 5837 void 5838 list_free(l, recurse) 5839 list_T *l; 5840 int recurse; /* Free Lists and Dictionaries recursively. */ 5841 { 5842 listitem_T *item; 5843 5844 /* Remove the list from the list of lists for garbage collection. */ 5845 if (l->lv_used_prev == NULL) 5846 first_list = l->lv_used_next; 5847 else 5848 l->lv_used_prev->lv_used_next = l->lv_used_next; 5849 if (l->lv_used_next != NULL) 5850 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5851 5852 for (item = l->lv_first; item != NULL; item = l->lv_first) 5853 { 5854 /* Remove the item before deleting it. */ 5855 l->lv_first = item->li_next; 5856 if (recurse || (item->li_tv.v_type != VAR_LIST 5857 && item->li_tv.v_type != VAR_DICT)) 5858 clear_tv(&item->li_tv); 5859 vim_free(item); 5860 } 5861 vim_free(l); 5862 } 5863 5864 /* 5865 * Allocate a list item. 5866 */ 5867 static listitem_T * 5868 listitem_alloc() 5869 { 5870 return (listitem_T *)alloc(sizeof(listitem_T)); 5871 } 5872 5873 /* 5874 * Free a list item. Also clears the value. Does not notify watchers. 5875 */ 5876 static void 5877 listitem_free(item) 5878 listitem_T *item; 5879 { 5880 clear_tv(&item->li_tv); 5881 vim_free(item); 5882 } 5883 5884 /* 5885 * Remove a list item from a List and free it. Also clears the value. 5886 */ 5887 static void 5888 listitem_remove(l, item) 5889 list_T *l; 5890 listitem_T *item; 5891 { 5892 list_remove(l, item, item); 5893 listitem_free(item); 5894 } 5895 5896 /* 5897 * Get the number of items in a list. 5898 */ 5899 static long 5900 list_len(l) 5901 list_T *l; 5902 { 5903 if (l == NULL) 5904 return 0L; 5905 return l->lv_len; 5906 } 5907 5908 /* 5909 * Return TRUE when two lists have exactly the same values. 5910 */ 5911 static int 5912 list_equal(l1, l2, ic) 5913 list_T *l1; 5914 list_T *l2; 5915 int ic; /* ignore case for strings */ 5916 { 5917 listitem_T *item1, *item2; 5918 5919 if (l1 == NULL || l2 == NULL) 5920 return FALSE; 5921 if (l1 == l2) 5922 return TRUE; 5923 if (list_len(l1) != list_len(l2)) 5924 return FALSE; 5925 5926 for (item1 = l1->lv_first, item2 = l2->lv_first; 5927 item1 != NULL && item2 != NULL; 5928 item1 = item1->li_next, item2 = item2->li_next) 5929 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5930 return FALSE; 5931 return item1 == NULL && item2 == NULL; 5932 } 5933 5934 #if defined(FEAT_RUBY) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ 5935 || defined(FEAT_MZSCHEME) || defined(FEAT_LUA) || defined(PROTO) 5936 /* 5937 * Return the dictitem that an entry in a hashtable points to. 5938 */ 5939 dictitem_T * 5940 dict_lookup(hi) 5941 hashitem_T *hi; 5942 { 5943 return HI2DI(hi); 5944 } 5945 #endif 5946 5947 /* 5948 * Return TRUE when two dictionaries have exactly the same key/values. 5949 */ 5950 static int 5951 dict_equal(d1, d2, ic) 5952 dict_T *d1; 5953 dict_T *d2; 5954 int ic; /* ignore case for strings */ 5955 { 5956 hashitem_T *hi; 5957 dictitem_T *item2; 5958 int todo; 5959 5960 if (d1 == NULL || d2 == NULL) 5961 return FALSE; 5962 if (d1 == d2) 5963 return TRUE; 5964 if (dict_len(d1) != dict_len(d2)) 5965 return FALSE; 5966 5967 todo = (int)d1->dv_hashtab.ht_used; 5968 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5969 { 5970 if (!HASHITEM_EMPTY(hi)) 5971 { 5972 item2 = dict_find(d2, hi->hi_key, -1); 5973 if (item2 == NULL) 5974 return FALSE; 5975 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5976 return FALSE; 5977 --todo; 5978 } 5979 } 5980 return TRUE; 5981 } 5982 5983 /* 5984 * Return TRUE if "tv1" and "tv2" have the same value. 5985 * Compares the items just like "==" would compare them, but strings and 5986 * numbers are different. Floats and numbers are also different. 5987 */ 5988 static int 5989 tv_equal(tv1, tv2, ic) 5990 typval_T *tv1; 5991 typval_T *tv2; 5992 int ic; /* ignore case */ 5993 { 5994 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5995 char_u *s1, *s2; 5996 static int recursive = 0; /* cach recursive loops */ 5997 int r; 5998 5999 if (tv1->v_type != tv2->v_type) 6000 return FALSE; 6001 /* Catch lists and dicts that have an endless loop by limiting 6002 * recursiveness to 1000. We guess they are equal then. */ 6003 if (recursive >= 1000) 6004 return TRUE; 6005 6006 switch (tv1->v_type) 6007 { 6008 case VAR_LIST: 6009 ++recursive; 6010 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 6011 --recursive; 6012 return r; 6013 6014 case VAR_DICT: 6015 ++recursive; 6016 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 6017 --recursive; 6018 return r; 6019 6020 case VAR_FUNC: 6021 return (tv1->vval.v_string != NULL 6022 && tv2->vval.v_string != NULL 6023 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 6024 6025 case VAR_NUMBER: 6026 return tv1->vval.v_number == tv2->vval.v_number; 6027 6028 #ifdef FEAT_FLOAT 6029 case VAR_FLOAT: 6030 return tv1->vval.v_float == tv2->vval.v_float; 6031 #endif 6032 6033 case VAR_STRING: 6034 s1 = get_tv_string_buf(tv1, buf1); 6035 s2 = get_tv_string_buf(tv2, buf2); 6036 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 6037 } 6038 6039 EMSG2(_(e_intern2), "tv_equal()"); 6040 return TRUE; 6041 } 6042 6043 /* 6044 * Locate item with index "n" in list "l" and return it. 6045 * A negative index is counted from the end; -1 is the last item. 6046 * Returns NULL when "n" is out of range. 6047 */ 6048 static listitem_T * 6049 list_find(l, n) 6050 list_T *l; 6051 long n; 6052 { 6053 listitem_T *item; 6054 long idx; 6055 6056 if (l == NULL) 6057 return NULL; 6058 6059 /* Negative index is relative to the end. */ 6060 if (n < 0) 6061 n = l->lv_len + n; 6062 6063 /* Check for index out of range. */ 6064 if (n < 0 || n >= l->lv_len) 6065 return NULL; 6066 6067 /* When there is a cached index may start search from there. */ 6068 if (l->lv_idx_item != NULL) 6069 { 6070 if (n < l->lv_idx / 2) 6071 { 6072 /* closest to the start of the list */ 6073 item = l->lv_first; 6074 idx = 0; 6075 } 6076 else if (n > (l->lv_idx + l->lv_len) / 2) 6077 { 6078 /* closest to the end of the list */ 6079 item = l->lv_last; 6080 idx = l->lv_len - 1; 6081 } 6082 else 6083 { 6084 /* closest to the cached index */ 6085 item = l->lv_idx_item; 6086 idx = l->lv_idx; 6087 } 6088 } 6089 else 6090 { 6091 if (n < l->lv_len / 2) 6092 { 6093 /* closest to the start of the list */ 6094 item = l->lv_first; 6095 idx = 0; 6096 } 6097 else 6098 { 6099 /* closest to the end of the list */ 6100 item = l->lv_last; 6101 idx = l->lv_len - 1; 6102 } 6103 } 6104 6105 while (n > idx) 6106 { 6107 /* search forward */ 6108 item = item->li_next; 6109 ++idx; 6110 } 6111 while (n < idx) 6112 { 6113 /* search backward */ 6114 item = item->li_prev; 6115 --idx; 6116 } 6117 6118 /* cache the used index */ 6119 l->lv_idx = idx; 6120 l->lv_idx_item = item; 6121 6122 return item; 6123 } 6124 6125 /* 6126 * Get list item "l[idx]" as a number. 6127 */ 6128 static long 6129 list_find_nr(l, idx, errorp) 6130 list_T *l; 6131 long idx; 6132 int *errorp; /* set to TRUE when something wrong */ 6133 { 6134 listitem_T *li; 6135 6136 li = list_find(l, idx); 6137 if (li == NULL) 6138 { 6139 if (errorp != NULL) 6140 *errorp = TRUE; 6141 return -1L; 6142 } 6143 return get_tv_number_chk(&li->li_tv, errorp); 6144 } 6145 6146 /* 6147 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. 6148 */ 6149 char_u * 6150 list_find_str(l, idx) 6151 list_T *l; 6152 long idx; 6153 { 6154 listitem_T *li; 6155 6156 li = list_find(l, idx - 1); 6157 if (li == NULL) 6158 { 6159 EMSGN(_(e_listidx), idx); 6160 return NULL; 6161 } 6162 return get_tv_string(&li->li_tv); 6163 } 6164 6165 /* 6166 * Locate "item" list "l" and return its index. 6167 * Returns -1 when "item" is not in the list. 6168 */ 6169 static long 6170 list_idx_of_item(l, item) 6171 list_T *l; 6172 listitem_T *item; 6173 { 6174 long idx = 0; 6175 listitem_T *li; 6176 6177 if (l == NULL) 6178 return -1; 6179 idx = 0; 6180 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 6181 ++idx; 6182 if (li == NULL) 6183 return -1; 6184 return idx; 6185 } 6186 6187 /* 6188 * Append item "item" to the end of list "l". 6189 */ 6190 static void 6191 list_append(l, item) 6192 list_T *l; 6193 listitem_T *item; 6194 { 6195 if (l->lv_last == NULL) 6196 { 6197 /* empty list */ 6198 l->lv_first = item; 6199 l->lv_last = item; 6200 item->li_prev = NULL; 6201 } 6202 else 6203 { 6204 l->lv_last->li_next = item; 6205 item->li_prev = l->lv_last; 6206 l->lv_last = item; 6207 } 6208 ++l->lv_len; 6209 item->li_next = NULL; 6210 } 6211 6212 /* 6213 * Append typval_T "tv" to the end of list "l". 6214 * Return FAIL when out of memory. 6215 */ 6216 int 6217 list_append_tv(l, tv) 6218 list_T *l; 6219 typval_T *tv; 6220 { 6221 listitem_T *li = listitem_alloc(); 6222 6223 if (li == NULL) 6224 return FAIL; 6225 copy_tv(tv, &li->li_tv); 6226 list_append(l, li); 6227 return OK; 6228 } 6229 6230 /* 6231 * Add a dictionary to a list. Used by getqflist(). 6232 * Return FAIL when out of memory. 6233 */ 6234 int 6235 list_append_dict(list, dict) 6236 list_T *list; 6237 dict_T *dict; 6238 { 6239 listitem_T *li = listitem_alloc(); 6240 6241 if (li == NULL) 6242 return FAIL; 6243 li->li_tv.v_type = VAR_DICT; 6244 li->li_tv.v_lock = 0; 6245 li->li_tv.vval.v_dict = dict; 6246 list_append(list, li); 6247 ++dict->dv_refcount; 6248 return OK; 6249 } 6250 6251 /* 6252 * Make a copy of "str" and append it as an item to list "l". 6253 * When "len" >= 0 use "str[len]". 6254 * Returns FAIL when out of memory. 6255 */ 6256 int 6257 list_append_string(l, str, len) 6258 list_T *l; 6259 char_u *str; 6260 int len; 6261 { 6262 listitem_T *li = listitem_alloc(); 6263 6264 if (li == NULL) 6265 return FAIL; 6266 list_append(l, li); 6267 li->li_tv.v_type = VAR_STRING; 6268 li->li_tv.v_lock = 0; 6269 if (str == NULL) 6270 li->li_tv.vval.v_string = NULL; 6271 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 6272 : vim_strsave(str))) == NULL) 6273 return FAIL; 6274 return OK; 6275 } 6276 6277 /* 6278 * Append "n" to list "l". 6279 * Returns FAIL when out of memory. 6280 */ 6281 static int 6282 list_append_number(l, n) 6283 list_T *l; 6284 varnumber_T n; 6285 { 6286 listitem_T *li; 6287 6288 li = listitem_alloc(); 6289 if (li == NULL) 6290 return FAIL; 6291 li->li_tv.v_type = VAR_NUMBER; 6292 li->li_tv.v_lock = 0; 6293 li->li_tv.vval.v_number = n; 6294 list_append(l, li); 6295 return OK; 6296 } 6297 6298 /* 6299 * Insert typval_T "tv" in list "l" before "item". 6300 * If "item" is NULL append at the end. 6301 * Return FAIL when out of memory. 6302 */ 6303 static int 6304 list_insert_tv(l, tv, item) 6305 list_T *l; 6306 typval_T *tv; 6307 listitem_T *item; 6308 { 6309 listitem_T *ni = listitem_alloc(); 6310 6311 if (ni == NULL) 6312 return FAIL; 6313 copy_tv(tv, &ni->li_tv); 6314 if (item == NULL) 6315 /* Append new item at end of list. */ 6316 list_append(l, ni); 6317 else 6318 { 6319 /* Insert new item before existing item. */ 6320 ni->li_prev = item->li_prev; 6321 ni->li_next = item; 6322 if (item->li_prev == NULL) 6323 { 6324 l->lv_first = ni; 6325 ++l->lv_idx; 6326 } 6327 else 6328 { 6329 item->li_prev->li_next = ni; 6330 l->lv_idx_item = NULL; 6331 } 6332 item->li_prev = ni; 6333 ++l->lv_len; 6334 } 6335 return OK; 6336 } 6337 6338 /* 6339 * Extend "l1" with "l2". 6340 * If "bef" is NULL append at the end, otherwise insert before this item. 6341 * Returns FAIL when out of memory. 6342 */ 6343 static int 6344 list_extend(l1, l2, bef) 6345 list_T *l1; 6346 list_T *l2; 6347 listitem_T *bef; 6348 { 6349 listitem_T *item; 6350 int todo = l2->lv_len; 6351 6352 /* We also quit the loop when we have inserted the original item count of 6353 * the list, avoid a hang when we extend a list with itself. */ 6354 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) 6355 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 6356 return FAIL; 6357 return OK; 6358 } 6359 6360 /* 6361 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 6362 * Return FAIL when out of memory. 6363 */ 6364 static int 6365 list_concat(l1, l2, tv) 6366 list_T *l1; 6367 list_T *l2; 6368 typval_T *tv; 6369 { 6370 list_T *l; 6371 6372 if (l1 == NULL || l2 == NULL) 6373 return FAIL; 6374 6375 /* make a copy of the first list. */ 6376 l = list_copy(l1, FALSE, 0); 6377 if (l == NULL) 6378 return FAIL; 6379 tv->v_type = VAR_LIST; 6380 tv->vval.v_list = l; 6381 6382 /* append all items from the second list */ 6383 return list_extend(l, l2, NULL); 6384 } 6385 6386 /* 6387 * Make a copy of list "orig". Shallow if "deep" is FALSE. 6388 * The refcount of the new list is set to 1. 6389 * See item_copy() for "copyID". 6390 * Returns NULL when out of memory. 6391 */ 6392 static list_T * 6393 list_copy(orig, deep, copyID) 6394 list_T *orig; 6395 int deep; 6396 int copyID; 6397 { 6398 list_T *copy; 6399 listitem_T *item; 6400 listitem_T *ni; 6401 6402 if (orig == NULL) 6403 return NULL; 6404 6405 copy = list_alloc(); 6406 if (copy != NULL) 6407 { 6408 if (copyID != 0) 6409 { 6410 /* Do this before adding the items, because one of the items may 6411 * refer back to this list. */ 6412 orig->lv_copyID = copyID; 6413 orig->lv_copylist = copy; 6414 } 6415 for (item = orig->lv_first; item != NULL && !got_int; 6416 item = item->li_next) 6417 { 6418 ni = listitem_alloc(); 6419 if (ni == NULL) 6420 break; 6421 if (deep) 6422 { 6423 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 6424 { 6425 vim_free(ni); 6426 break; 6427 } 6428 } 6429 else 6430 copy_tv(&item->li_tv, &ni->li_tv); 6431 list_append(copy, ni); 6432 } 6433 ++copy->lv_refcount; 6434 if (item != NULL) 6435 { 6436 list_unref(copy); 6437 copy = NULL; 6438 } 6439 } 6440 6441 return copy; 6442 } 6443 6444 /* 6445 * Remove items "item" to "item2" from list "l". 6446 * Does not free the listitem or the value! 6447 */ 6448 static void 6449 list_remove(l, item, item2) 6450 list_T *l; 6451 listitem_T *item; 6452 listitem_T *item2; 6453 { 6454 listitem_T *ip; 6455 6456 /* notify watchers */ 6457 for (ip = item; ip != NULL; ip = ip->li_next) 6458 { 6459 --l->lv_len; 6460 list_fix_watch(l, ip); 6461 if (ip == item2) 6462 break; 6463 } 6464 6465 if (item2->li_next == NULL) 6466 l->lv_last = item->li_prev; 6467 else 6468 item2->li_next->li_prev = item->li_prev; 6469 if (item->li_prev == NULL) 6470 l->lv_first = item2->li_next; 6471 else 6472 item->li_prev->li_next = item2->li_next; 6473 l->lv_idx_item = NULL; 6474 } 6475 6476 /* 6477 * Return an allocated string with the string representation of a list. 6478 * May return NULL. 6479 */ 6480 static char_u * 6481 list2string(tv, copyID) 6482 typval_T *tv; 6483 int copyID; 6484 { 6485 garray_T ga; 6486 6487 if (tv->vval.v_list == NULL) 6488 return NULL; 6489 ga_init2(&ga, (int)sizeof(char), 80); 6490 ga_append(&ga, '['); 6491 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 6492 { 6493 vim_free(ga.ga_data); 6494 return NULL; 6495 } 6496 ga_append(&ga, ']'); 6497 ga_append(&ga, NUL); 6498 return (char_u *)ga.ga_data; 6499 } 6500 6501 /* 6502 * Join list "l" into a string in "*gap", using separator "sep". 6503 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 6504 * Return FAIL or OK. 6505 */ 6506 static int 6507 list_join(gap, l, sep, echo, copyID) 6508 garray_T *gap; 6509 list_T *l; 6510 char_u *sep; 6511 int echo; 6512 int copyID; 6513 { 6514 int first = TRUE; 6515 char_u *tofree; 6516 char_u numbuf[NUMBUFLEN]; 6517 listitem_T *item; 6518 char_u *s; 6519 6520 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 6521 { 6522 if (first) 6523 first = FALSE; 6524 else 6525 ga_concat(gap, sep); 6526 6527 if (echo) 6528 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6529 else 6530 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6531 if (s != NULL) 6532 ga_concat(gap, s); 6533 vim_free(tofree); 6534 if (s == NULL) 6535 return FAIL; 6536 line_breakcheck(); 6537 } 6538 return OK; 6539 } 6540 6541 /* 6542 * Garbage collection for lists and dictionaries. 6543 * 6544 * We use reference counts to be able to free most items right away when they 6545 * are no longer used. But for composite items it's possible that it becomes 6546 * unused while the reference count is > 0: When there is a recursive 6547 * reference. Example: 6548 * :let l = [1, 2, 3] 6549 * :let d = {9: l} 6550 * :let l[1] = d 6551 * 6552 * Since this is quite unusual we handle this with garbage collection: every 6553 * once in a while find out which lists and dicts are not referenced from any 6554 * variable. 6555 * 6556 * Here is a good reference text about garbage collection (refers to Python 6557 * but it applies to all reference-counting mechanisms): 6558 * http://python.ca/nas/python/gc/ 6559 */ 6560 6561 /* 6562 * Do garbage collection for lists and dicts. 6563 * Return TRUE if some memory was freed. 6564 */ 6565 int 6566 garbage_collect() 6567 { 6568 int copyID; 6569 buf_T *buf; 6570 win_T *wp; 6571 int i; 6572 funccall_T *fc, **pfc; 6573 int did_free; 6574 int did_free_funccal = FALSE; 6575 #ifdef FEAT_WINDOWS 6576 tabpage_T *tp; 6577 #endif 6578 6579 /* Only do this once. */ 6580 want_garbage_collect = FALSE; 6581 may_garbage_collect = FALSE; 6582 garbage_collect_at_exit = FALSE; 6583 6584 /* We advance by two because we add one for items referenced through 6585 * previous_funccal. */ 6586 current_copyID += COPYID_INC; 6587 copyID = current_copyID; 6588 6589 /* 6590 * 1. Go through all accessible variables and mark all lists and dicts 6591 * with copyID. 6592 */ 6593 6594 /* Don't free variables in the previous_funccal list unless they are only 6595 * referenced through previous_funccal. This must be first, because if 6596 * the item is referenced elsewhere the funccal must not be freed. */ 6597 for (fc = previous_funccal; fc != NULL; fc = fc->caller) 6598 { 6599 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1); 6600 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1); 6601 } 6602 6603 /* script-local variables */ 6604 for (i = 1; i <= ga_scripts.ga_len; ++i) 6605 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 6606 6607 /* buffer-local variables */ 6608 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6609 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 6610 6611 /* window-local variables */ 6612 FOR_ALL_TAB_WINDOWS(tp, wp) 6613 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 6614 6615 #ifdef FEAT_WINDOWS 6616 /* tabpage-local variables */ 6617 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6618 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); 6619 #endif 6620 6621 /* global variables */ 6622 set_ref_in_ht(&globvarht, copyID); 6623 6624 /* function-local variables */ 6625 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6626 { 6627 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 6628 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 6629 } 6630 6631 /* v: vars */ 6632 set_ref_in_ht(&vimvarht, copyID); 6633 6634 /* 6635 * 2. Free lists and dictionaries that are not referenced. 6636 */ 6637 did_free = free_unref_items(copyID); 6638 6639 /* 6640 * 3. Check if any funccal can be freed now. 6641 */ 6642 for (pfc = &previous_funccal; *pfc != NULL; ) 6643 { 6644 if (can_free_funccal(*pfc, copyID)) 6645 { 6646 fc = *pfc; 6647 *pfc = fc->caller; 6648 free_funccal(fc, TRUE); 6649 did_free = TRUE; 6650 did_free_funccal = TRUE; 6651 } 6652 else 6653 pfc = &(*pfc)->caller; 6654 } 6655 if (did_free_funccal) 6656 /* When a funccal was freed some more items might be garbage 6657 * collected, so run again. */ 6658 (void)garbage_collect(); 6659 6660 return did_free; 6661 } 6662 6663 /* 6664 * Free lists and dictionaries that are no longer referenced. 6665 */ 6666 static int 6667 free_unref_items(copyID) 6668 int copyID; 6669 { 6670 dict_T *dd; 6671 list_T *ll; 6672 int did_free = FALSE; 6673 6674 /* 6675 * Go through the list of dicts and free items without the copyID. 6676 */ 6677 for (dd = first_dict; dd != NULL; ) 6678 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) 6679 { 6680 /* Free the Dictionary and ordinary items it contains, but don't 6681 * recurse into Lists and Dictionaries, they will be in the list 6682 * of dicts or list of lists. */ 6683 dict_free(dd, FALSE); 6684 did_free = TRUE; 6685 6686 /* restart, next dict may also have been freed */ 6687 dd = first_dict; 6688 } 6689 else 6690 dd = dd->dv_used_next; 6691 6692 /* 6693 * Go through the list of lists and free items without the copyID. 6694 * But don't free a list that has a watcher (used in a for loop), these 6695 * are not referenced anywhere. 6696 */ 6697 for (ll = first_list; ll != NULL; ) 6698 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 6699 && ll->lv_watch == NULL) 6700 { 6701 /* Free the List and ordinary items it contains, but don't recurse 6702 * into Lists and Dictionaries, they will be in the list of dicts 6703 * or list of lists. */ 6704 list_free(ll, FALSE); 6705 did_free = TRUE; 6706 6707 /* restart, next list may also have been freed */ 6708 ll = first_list; 6709 } 6710 else 6711 ll = ll->lv_used_next; 6712 6713 return did_free; 6714 } 6715 6716 /* 6717 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6718 */ 6719 static void 6720 set_ref_in_ht(ht, copyID) 6721 hashtab_T *ht; 6722 int copyID; 6723 { 6724 int todo; 6725 hashitem_T *hi; 6726 6727 todo = (int)ht->ht_used; 6728 for (hi = ht->ht_array; todo > 0; ++hi) 6729 if (!HASHITEM_EMPTY(hi)) 6730 { 6731 --todo; 6732 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 6733 } 6734 } 6735 6736 /* 6737 * Mark all lists and dicts referenced through list "l" with "copyID". 6738 */ 6739 static void 6740 set_ref_in_list(l, copyID) 6741 list_T *l; 6742 int copyID; 6743 { 6744 listitem_T *li; 6745 6746 for (li = l->lv_first; li != NULL; li = li->li_next) 6747 set_ref_in_item(&li->li_tv, copyID); 6748 } 6749 6750 /* 6751 * Mark all lists and dicts referenced through typval "tv" with "copyID". 6752 */ 6753 static void 6754 set_ref_in_item(tv, copyID) 6755 typval_T *tv; 6756 int copyID; 6757 { 6758 dict_T *dd; 6759 list_T *ll; 6760 6761 switch (tv->v_type) 6762 { 6763 case VAR_DICT: 6764 dd = tv->vval.v_dict; 6765 if (dd != NULL && dd->dv_copyID != copyID) 6766 { 6767 /* Didn't see this dict yet. */ 6768 dd->dv_copyID = copyID; 6769 set_ref_in_ht(&dd->dv_hashtab, copyID); 6770 } 6771 break; 6772 6773 case VAR_LIST: 6774 ll = tv->vval.v_list; 6775 if (ll != NULL && ll->lv_copyID != copyID) 6776 { 6777 /* Didn't see this list yet. */ 6778 ll->lv_copyID = copyID; 6779 set_ref_in_list(ll, copyID); 6780 } 6781 break; 6782 } 6783 return; 6784 } 6785 6786 /* 6787 * Allocate an empty header for a dictionary. 6788 */ 6789 dict_T * 6790 dict_alloc() 6791 { 6792 dict_T *d; 6793 6794 d = (dict_T *)alloc(sizeof(dict_T)); 6795 if (d != NULL) 6796 { 6797 /* Add the list to the list of dicts for garbage collection. */ 6798 if (first_dict != NULL) 6799 first_dict->dv_used_prev = d; 6800 d->dv_used_next = first_dict; 6801 d->dv_used_prev = NULL; 6802 first_dict = d; 6803 6804 hash_init(&d->dv_hashtab); 6805 d->dv_lock = 0; 6806 d->dv_refcount = 0; 6807 d->dv_copyID = 0; 6808 } 6809 return d; 6810 } 6811 6812 /* 6813 * Allocate an empty dict for a return value. 6814 * Returns OK or FAIL. 6815 */ 6816 static int 6817 rettv_dict_alloc(rettv) 6818 typval_T *rettv; 6819 { 6820 dict_T *d = dict_alloc(); 6821 6822 if (d == NULL) 6823 return FAIL; 6824 6825 rettv->vval.v_dict = d; 6826 rettv->v_type = VAR_DICT; 6827 ++d->dv_refcount; 6828 return OK; 6829 } 6830 6831 6832 /* 6833 * Unreference a Dictionary: decrement the reference count and free it when it 6834 * becomes zero. 6835 */ 6836 static void 6837 dict_unref(d) 6838 dict_T *d; 6839 { 6840 if (d != NULL && --d->dv_refcount <= 0) 6841 dict_free(d, TRUE); 6842 } 6843 6844 /* 6845 * Free a Dictionary, including all items it contains. 6846 * Ignores the reference count. 6847 */ 6848 static void 6849 dict_free(d, recurse) 6850 dict_T *d; 6851 int recurse; /* Free Lists and Dictionaries recursively. */ 6852 { 6853 int todo; 6854 hashitem_T *hi; 6855 dictitem_T *di; 6856 6857 /* Remove the dict from the list of dicts for garbage collection. */ 6858 if (d->dv_used_prev == NULL) 6859 first_dict = d->dv_used_next; 6860 else 6861 d->dv_used_prev->dv_used_next = d->dv_used_next; 6862 if (d->dv_used_next != NULL) 6863 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6864 6865 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6866 hash_lock(&d->dv_hashtab); 6867 todo = (int)d->dv_hashtab.ht_used; 6868 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6869 { 6870 if (!HASHITEM_EMPTY(hi)) 6871 { 6872 /* Remove the item before deleting it, just in case there is 6873 * something recursive causing trouble. */ 6874 di = HI2DI(hi); 6875 hash_remove(&d->dv_hashtab, hi); 6876 if (recurse || (di->di_tv.v_type != VAR_LIST 6877 && di->di_tv.v_type != VAR_DICT)) 6878 clear_tv(&di->di_tv); 6879 vim_free(di); 6880 --todo; 6881 } 6882 } 6883 hash_clear(&d->dv_hashtab); 6884 vim_free(d); 6885 } 6886 6887 /* 6888 * Allocate a Dictionary item. 6889 * The "key" is copied to the new item. 6890 * Note that the value of the item "di_tv" still needs to be initialized! 6891 * Returns NULL when out of memory. 6892 */ 6893 dictitem_T * 6894 dictitem_alloc(key) 6895 char_u *key; 6896 { 6897 dictitem_T *di; 6898 6899 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 6900 if (di != NULL) 6901 { 6902 STRCPY(di->di_key, key); 6903 di->di_flags = 0; 6904 } 6905 return di; 6906 } 6907 6908 /* 6909 * Make a copy of a Dictionary item. 6910 */ 6911 static dictitem_T * 6912 dictitem_copy(org) 6913 dictitem_T *org; 6914 { 6915 dictitem_T *di; 6916 6917 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 6918 + STRLEN(org->di_key))); 6919 if (di != NULL) 6920 { 6921 STRCPY(di->di_key, org->di_key); 6922 di->di_flags = 0; 6923 copy_tv(&org->di_tv, &di->di_tv); 6924 } 6925 return di; 6926 } 6927 6928 /* 6929 * Remove item "item" from Dictionary "dict" and free it. 6930 */ 6931 static void 6932 dictitem_remove(dict, item) 6933 dict_T *dict; 6934 dictitem_T *item; 6935 { 6936 hashitem_T *hi; 6937 6938 hi = hash_find(&dict->dv_hashtab, item->di_key); 6939 if (HASHITEM_EMPTY(hi)) 6940 EMSG2(_(e_intern2), "dictitem_remove()"); 6941 else 6942 hash_remove(&dict->dv_hashtab, hi); 6943 dictitem_free(item); 6944 } 6945 6946 /* 6947 * Free a dict item. Also clears the value. 6948 */ 6949 void 6950 dictitem_free(item) 6951 dictitem_T *item; 6952 { 6953 clear_tv(&item->di_tv); 6954 vim_free(item); 6955 } 6956 6957 /* 6958 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6959 * The refcount of the new dict is set to 1. 6960 * See item_copy() for "copyID". 6961 * Returns NULL when out of memory. 6962 */ 6963 static dict_T * 6964 dict_copy(orig, deep, copyID) 6965 dict_T *orig; 6966 int deep; 6967 int copyID; 6968 { 6969 dict_T *copy; 6970 dictitem_T *di; 6971 int todo; 6972 hashitem_T *hi; 6973 6974 if (orig == NULL) 6975 return NULL; 6976 6977 copy = dict_alloc(); 6978 if (copy != NULL) 6979 { 6980 if (copyID != 0) 6981 { 6982 orig->dv_copyID = copyID; 6983 orig->dv_copydict = copy; 6984 } 6985 todo = (int)orig->dv_hashtab.ht_used; 6986 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6987 { 6988 if (!HASHITEM_EMPTY(hi)) 6989 { 6990 --todo; 6991 6992 di = dictitem_alloc(hi->hi_key); 6993 if (di == NULL) 6994 break; 6995 if (deep) 6996 { 6997 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6998 copyID) == FAIL) 6999 { 7000 vim_free(di); 7001 break; 7002 } 7003 } 7004 else 7005 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 7006 if (dict_add(copy, di) == FAIL) 7007 { 7008 dictitem_free(di); 7009 break; 7010 } 7011 } 7012 } 7013 7014 ++copy->dv_refcount; 7015 if (todo > 0) 7016 { 7017 dict_unref(copy); 7018 copy = NULL; 7019 } 7020 } 7021 7022 return copy; 7023 } 7024 7025 /* 7026 * Add item "item" to Dictionary "d". 7027 * Returns FAIL when out of memory and when key already exists. 7028 */ 7029 int 7030 dict_add(d, item) 7031 dict_T *d; 7032 dictitem_T *item; 7033 { 7034 return hash_add(&d->dv_hashtab, item->di_key); 7035 } 7036 7037 /* 7038 * Add a number or string entry to dictionary "d". 7039 * When "str" is NULL use number "nr", otherwise use "str". 7040 * Returns FAIL when out of memory and when key already exists. 7041 */ 7042 int 7043 dict_add_nr_str(d, key, nr, str) 7044 dict_T *d; 7045 char *key; 7046 long nr; 7047 char_u *str; 7048 { 7049 dictitem_T *item; 7050 7051 item = dictitem_alloc((char_u *)key); 7052 if (item == NULL) 7053 return FAIL; 7054 item->di_tv.v_lock = 0; 7055 if (str == NULL) 7056 { 7057 item->di_tv.v_type = VAR_NUMBER; 7058 item->di_tv.vval.v_number = nr; 7059 } 7060 else 7061 { 7062 item->di_tv.v_type = VAR_STRING; 7063 item->di_tv.vval.v_string = vim_strsave(str); 7064 } 7065 if (dict_add(d, item) == FAIL) 7066 { 7067 dictitem_free(item); 7068 return FAIL; 7069 } 7070 return OK; 7071 } 7072 7073 /* 7074 * Add a list entry to dictionary "d". 7075 * Returns FAIL when out of memory and when key already exists. 7076 */ 7077 int 7078 dict_add_list(d, key, list) 7079 dict_T *d; 7080 char *key; 7081 list_T *list; 7082 { 7083 dictitem_T *item; 7084 7085 item = dictitem_alloc((char_u *)key); 7086 if (item == NULL) 7087 return FAIL; 7088 item->di_tv.v_lock = 0; 7089 item->di_tv.v_type = VAR_LIST; 7090 item->di_tv.vval.v_list = list; 7091 if (dict_add(d, item) == FAIL) 7092 { 7093 dictitem_free(item); 7094 return FAIL; 7095 } 7096 return OK; 7097 } 7098 7099 /* 7100 * Get the number of items in a Dictionary. 7101 */ 7102 static long 7103 dict_len(d) 7104 dict_T *d; 7105 { 7106 if (d == NULL) 7107 return 0L; 7108 return (long)d->dv_hashtab.ht_used; 7109 } 7110 7111 /* 7112 * Find item "key[len]" in Dictionary "d". 7113 * If "len" is negative use strlen(key). 7114 * Returns NULL when not found. 7115 */ 7116 dictitem_T * 7117 dict_find(d, key, len) 7118 dict_T *d; 7119 char_u *key; 7120 int len; 7121 { 7122 #define AKEYLEN 200 7123 char_u buf[AKEYLEN]; 7124 char_u *akey; 7125 char_u *tofree = NULL; 7126 hashitem_T *hi; 7127 7128 if (len < 0) 7129 akey = key; 7130 else if (len >= AKEYLEN) 7131 { 7132 tofree = akey = vim_strnsave(key, len); 7133 if (akey == NULL) 7134 return NULL; 7135 } 7136 else 7137 { 7138 /* Avoid a malloc/free by using buf[]. */ 7139 vim_strncpy(buf, key, len); 7140 akey = buf; 7141 } 7142 7143 hi = hash_find(&d->dv_hashtab, akey); 7144 vim_free(tofree); 7145 if (HASHITEM_EMPTY(hi)) 7146 return NULL; 7147 return HI2DI(hi); 7148 } 7149 7150 /* 7151 * Get a string item from a dictionary. 7152 * When "save" is TRUE allocate memory for it. 7153 * Returns NULL if the entry doesn't exist or out of memory. 7154 */ 7155 char_u * 7156 get_dict_string(d, key, save) 7157 dict_T *d; 7158 char_u *key; 7159 int save; 7160 { 7161 dictitem_T *di; 7162 char_u *s; 7163 7164 di = dict_find(d, key, -1); 7165 if (di == NULL) 7166 return NULL; 7167 s = get_tv_string(&di->di_tv); 7168 if (save && s != NULL) 7169 s = vim_strsave(s); 7170 return s; 7171 } 7172 7173 /* 7174 * Get a number item from a dictionary. 7175 * Returns 0 if the entry doesn't exist or out of memory. 7176 */ 7177 long 7178 get_dict_number(d, key) 7179 dict_T *d; 7180 char_u *key; 7181 { 7182 dictitem_T *di; 7183 7184 di = dict_find(d, key, -1); 7185 if (di == NULL) 7186 return 0; 7187 return get_tv_number(&di->di_tv); 7188 } 7189 7190 /* 7191 * Return an allocated string with the string representation of a Dictionary. 7192 * May return NULL. 7193 */ 7194 static char_u * 7195 dict2string(tv, copyID) 7196 typval_T *tv; 7197 int copyID; 7198 { 7199 garray_T ga; 7200 int first = TRUE; 7201 char_u *tofree; 7202 char_u numbuf[NUMBUFLEN]; 7203 hashitem_T *hi; 7204 char_u *s; 7205 dict_T *d; 7206 int todo; 7207 7208 if ((d = tv->vval.v_dict) == NULL) 7209 return NULL; 7210 ga_init2(&ga, (int)sizeof(char), 80); 7211 ga_append(&ga, '{'); 7212 7213 todo = (int)d->dv_hashtab.ht_used; 7214 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7215 { 7216 if (!HASHITEM_EMPTY(hi)) 7217 { 7218 --todo; 7219 7220 if (first) 7221 first = FALSE; 7222 else 7223 ga_concat(&ga, (char_u *)", "); 7224 7225 tofree = string_quote(hi->hi_key, FALSE); 7226 if (tofree != NULL) 7227 { 7228 ga_concat(&ga, tofree); 7229 vim_free(tofree); 7230 } 7231 ga_concat(&ga, (char_u *)": "); 7232 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 7233 if (s != NULL) 7234 ga_concat(&ga, s); 7235 vim_free(tofree); 7236 if (s == NULL) 7237 break; 7238 } 7239 } 7240 if (todo > 0) 7241 { 7242 vim_free(ga.ga_data); 7243 return NULL; 7244 } 7245 7246 ga_append(&ga, '}'); 7247 ga_append(&ga, NUL); 7248 return (char_u *)ga.ga_data; 7249 } 7250 7251 /* 7252 * Allocate a variable for a Dictionary and fill it from "*arg". 7253 * Return OK or FAIL. Returns NOTDONE for {expr}. 7254 */ 7255 static int 7256 get_dict_tv(arg, rettv, evaluate) 7257 char_u **arg; 7258 typval_T *rettv; 7259 int evaluate; 7260 { 7261 dict_T *d = NULL; 7262 typval_T tvkey; 7263 typval_T tv; 7264 char_u *key = NULL; 7265 dictitem_T *item; 7266 char_u *start = skipwhite(*arg + 1); 7267 char_u buf[NUMBUFLEN]; 7268 7269 /* 7270 * First check if it's not a curly-braces thing: {expr}. 7271 * Must do this without evaluating, otherwise a function may be called 7272 * twice. Unfortunately this means we need to call eval1() twice for the 7273 * first item. 7274 * But {} is an empty Dictionary. 7275 */ 7276 if (*start != '}') 7277 { 7278 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 7279 return FAIL; 7280 if (*start == '}') 7281 return NOTDONE; 7282 } 7283 7284 if (evaluate) 7285 { 7286 d = dict_alloc(); 7287 if (d == NULL) 7288 return FAIL; 7289 } 7290 tvkey.v_type = VAR_UNKNOWN; 7291 tv.v_type = VAR_UNKNOWN; 7292 7293 *arg = skipwhite(*arg + 1); 7294 while (**arg != '}' && **arg != NUL) 7295 { 7296 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 7297 goto failret; 7298 if (**arg != ':') 7299 { 7300 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 7301 clear_tv(&tvkey); 7302 goto failret; 7303 } 7304 if (evaluate) 7305 { 7306 key = get_tv_string_buf_chk(&tvkey, buf); 7307 if (key == NULL || *key == NUL) 7308 { 7309 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 7310 if (key != NULL) 7311 EMSG(_(e_emptykey)); 7312 clear_tv(&tvkey); 7313 goto failret; 7314 } 7315 } 7316 7317 *arg = skipwhite(*arg + 1); 7318 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 7319 { 7320 if (evaluate) 7321 clear_tv(&tvkey); 7322 goto failret; 7323 } 7324 if (evaluate) 7325 { 7326 item = dict_find(d, key, -1); 7327 if (item != NULL) 7328 { 7329 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 7330 clear_tv(&tvkey); 7331 clear_tv(&tv); 7332 goto failret; 7333 } 7334 item = dictitem_alloc(key); 7335 clear_tv(&tvkey); 7336 if (item != NULL) 7337 { 7338 item->di_tv = tv; 7339 item->di_tv.v_lock = 0; 7340 if (dict_add(d, item) == FAIL) 7341 dictitem_free(item); 7342 } 7343 } 7344 7345 if (**arg == '}') 7346 break; 7347 if (**arg != ',') 7348 { 7349 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 7350 goto failret; 7351 } 7352 *arg = skipwhite(*arg + 1); 7353 } 7354 7355 if (**arg != '}') 7356 { 7357 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 7358 failret: 7359 if (evaluate) 7360 dict_free(d, TRUE); 7361 return FAIL; 7362 } 7363 7364 *arg = skipwhite(*arg + 1); 7365 if (evaluate) 7366 { 7367 rettv->v_type = VAR_DICT; 7368 rettv->vval.v_dict = d; 7369 ++d->dv_refcount; 7370 } 7371 7372 return OK; 7373 } 7374 7375 /* 7376 * Return a string with the string representation of a variable. 7377 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7378 * "numbuf" is used for a number. 7379 * Does not put quotes around strings, as ":echo" displays values. 7380 * When "copyID" is not NULL replace recursive lists and dicts with "...". 7381 * May return NULL. 7382 */ 7383 static char_u * 7384 echo_string(tv, tofree, numbuf, copyID) 7385 typval_T *tv; 7386 char_u **tofree; 7387 char_u *numbuf; 7388 int copyID; 7389 { 7390 static int recurse = 0; 7391 char_u *r = NULL; 7392 7393 if (recurse >= DICT_MAXNEST) 7394 { 7395 EMSG(_("E724: variable nested too deep for displaying")); 7396 *tofree = NULL; 7397 return NULL; 7398 } 7399 ++recurse; 7400 7401 switch (tv->v_type) 7402 { 7403 case VAR_FUNC: 7404 *tofree = NULL; 7405 r = tv->vval.v_string; 7406 break; 7407 7408 case VAR_LIST: 7409 if (tv->vval.v_list == NULL) 7410 { 7411 *tofree = NULL; 7412 r = NULL; 7413 } 7414 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 7415 { 7416 *tofree = NULL; 7417 r = (char_u *)"[...]"; 7418 } 7419 else 7420 { 7421 tv->vval.v_list->lv_copyID = copyID; 7422 *tofree = list2string(tv, copyID); 7423 r = *tofree; 7424 } 7425 break; 7426 7427 case VAR_DICT: 7428 if (tv->vval.v_dict == NULL) 7429 { 7430 *tofree = NULL; 7431 r = NULL; 7432 } 7433 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 7434 { 7435 *tofree = NULL; 7436 r = (char_u *)"{...}"; 7437 } 7438 else 7439 { 7440 tv->vval.v_dict->dv_copyID = copyID; 7441 *tofree = dict2string(tv, copyID); 7442 r = *tofree; 7443 } 7444 break; 7445 7446 case VAR_STRING: 7447 case VAR_NUMBER: 7448 *tofree = NULL; 7449 r = get_tv_string_buf(tv, numbuf); 7450 break; 7451 7452 #ifdef FEAT_FLOAT 7453 case VAR_FLOAT: 7454 *tofree = NULL; 7455 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float); 7456 r = numbuf; 7457 break; 7458 #endif 7459 7460 default: 7461 EMSG2(_(e_intern2), "echo_string()"); 7462 *tofree = NULL; 7463 } 7464 7465 --recurse; 7466 return r; 7467 } 7468 7469 /* 7470 * Return a string with the string representation of a variable. 7471 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7472 * "numbuf" is used for a number. 7473 * Puts quotes around strings, so that they can be parsed back by eval(). 7474 * May return NULL. 7475 */ 7476 static char_u * 7477 tv2string(tv, tofree, numbuf, copyID) 7478 typval_T *tv; 7479 char_u **tofree; 7480 char_u *numbuf; 7481 int copyID; 7482 { 7483 switch (tv->v_type) 7484 { 7485 case VAR_FUNC: 7486 *tofree = string_quote(tv->vval.v_string, TRUE); 7487 return *tofree; 7488 case VAR_STRING: 7489 *tofree = string_quote(tv->vval.v_string, FALSE); 7490 return *tofree; 7491 #ifdef FEAT_FLOAT 7492 case VAR_FLOAT: 7493 *tofree = NULL; 7494 vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); 7495 return numbuf; 7496 #endif 7497 case VAR_NUMBER: 7498 case VAR_LIST: 7499 case VAR_DICT: 7500 break; 7501 default: 7502 EMSG2(_(e_intern2), "tv2string()"); 7503 } 7504 return echo_string(tv, tofree, numbuf, copyID); 7505 } 7506 7507 /* 7508 * Return string "str" in ' quotes, doubling ' characters. 7509 * If "str" is NULL an empty string is assumed. 7510 * If "function" is TRUE make it function('string'). 7511 */ 7512 static char_u * 7513 string_quote(str, function) 7514 char_u *str; 7515 int function; 7516 { 7517 unsigned len; 7518 char_u *p, *r, *s; 7519 7520 len = (function ? 13 : 3); 7521 if (str != NULL) 7522 { 7523 len += (unsigned)STRLEN(str); 7524 for (p = str; *p != NUL; mb_ptr_adv(p)) 7525 if (*p == '\'') 7526 ++len; 7527 } 7528 s = r = alloc(len); 7529 if (r != NULL) 7530 { 7531 if (function) 7532 { 7533 STRCPY(r, "function('"); 7534 r += 10; 7535 } 7536 else 7537 *r++ = '\''; 7538 if (str != NULL) 7539 for (p = str; *p != NUL; ) 7540 { 7541 if (*p == '\'') 7542 *r++ = '\''; 7543 MB_COPY_CHAR(p, r); 7544 } 7545 *r++ = '\''; 7546 if (function) 7547 *r++ = ')'; 7548 *r++ = NUL; 7549 } 7550 return s; 7551 } 7552 7553 #ifdef FEAT_FLOAT 7554 /* 7555 * Convert the string "text" to a floating point number. 7556 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure 7557 * this always uses a decimal point. 7558 * Returns the length of the text that was consumed. 7559 */ 7560 static int 7561 string2float(text, value) 7562 char_u *text; 7563 float_T *value; /* result stored here */ 7564 { 7565 char *s = (char *)text; 7566 float_T f; 7567 7568 f = strtod(s, &s); 7569 *value = f; 7570 return (int)((char_u *)s - text); 7571 } 7572 #endif 7573 7574 /* 7575 * Get the value of an environment variable. 7576 * "arg" is pointing to the '$'. It is advanced to after the name. 7577 * If the environment variable was not set, silently assume it is empty. 7578 * Always return OK. 7579 */ 7580 static int 7581 get_env_tv(arg, rettv, evaluate) 7582 char_u **arg; 7583 typval_T *rettv; 7584 int evaluate; 7585 { 7586 char_u *string = NULL; 7587 int len; 7588 int cc; 7589 char_u *name; 7590 int mustfree = FALSE; 7591 7592 ++*arg; 7593 name = *arg; 7594 len = get_env_len(arg); 7595 if (evaluate) 7596 { 7597 if (len != 0) 7598 { 7599 cc = name[len]; 7600 name[len] = NUL; 7601 /* first try vim_getenv(), fast for normal environment vars */ 7602 string = vim_getenv(name, &mustfree); 7603 if (string != NULL && *string != NUL) 7604 { 7605 if (!mustfree) 7606 string = vim_strsave(string); 7607 } 7608 else 7609 { 7610 if (mustfree) 7611 vim_free(string); 7612 7613 /* next try expanding things like $VIM and ${HOME} */ 7614 string = expand_env_save(name - 1); 7615 if (string != NULL && *string == '$') 7616 { 7617 vim_free(string); 7618 string = NULL; 7619 } 7620 } 7621 name[len] = cc; 7622 } 7623 rettv->v_type = VAR_STRING; 7624 rettv->vval.v_string = string; 7625 } 7626 7627 return OK; 7628 } 7629 7630 /* 7631 * Array with names and number of arguments of all internal functions 7632 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 7633 */ 7634 static struct fst 7635 { 7636 char *f_name; /* function name */ 7637 char f_min_argc; /* minimal number of arguments */ 7638 char f_max_argc; /* maximal number of arguments */ 7639 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 7640 /* implementation of function */ 7641 } functions[] = 7642 { 7643 #ifdef FEAT_FLOAT 7644 {"abs", 1, 1, f_abs}, 7645 {"acos", 1, 1, f_acos}, /* WJMc */ 7646 #endif 7647 {"add", 2, 2, f_add}, 7648 {"append", 2, 2, f_append}, 7649 {"argc", 0, 0, f_argc}, 7650 {"argidx", 0, 0, f_argidx}, 7651 {"argv", 0, 1, f_argv}, 7652 #ifdef FEAT_FLOAT 7653 {"asin", 1, 1, f_asin}, /* WJMc */ 7654 {"atan", 1, 1, f_atan}, 7655 {"atan2", 2, 2, f_atan2}, 7656 #endif 7657 {"browse", 4, 4, f_browse}, 7658 {"browsedir", 2, 2, f_browsedir}, 7659 {"bufexists", 1, 1, f_bufexists}, 7660 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 7661 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 7662 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 7663 {"buflisted", 1, 1, f_buflisted}, 7664 {"bufloaded", 1, 1, f_bufloaded}, 7665 {"bufname", 1, 1, f_bufname}, 7666 {"bufnr", 1, 2, f_bufnr}, 7667 {"bufwinnr", 1, 1, f_bufwinnr}, 7668 {"byte2line", 1, 1, f_byte2line}, 7669 {"byteidx", 2, 2, f_byteidx}, 7670 {"call", 2, 3, f_call}, 7671 #ifdef FEAT_FLOAT 7672 {"ceil", 1, 1, f_ceil}, 7673 #endif 7674 {"changenr", 0, 0, f_changenr}, 7675 {"char2nr", 1, 1, f_char2nr}, 7676 {"cindent", 1, 1, f_cindent}, 7677 {"clearmatches", 0, 0, f_clearmatches}, 7678 {"col", 1, 1, f_col}, 7679 #if defined(FEAT_INS_EXPAND) 7680 {"complete", 2, 2, f_complete}, 7681 {"complete_add", 1, 1, f_complete_add}, 7682 {"complete_check", 0, 0, f_complete_check}, 7683 #endif 7684 {"confirm", 1, 4, f_confirm}, 7685 {"copy", 1, 1, f_copy}, 7686 #ifdef FEAT_FLOAT 7687 {"cos", 1, 1, f_cos}, 7688 {"cosh", 1, 1, f_cosh}, 7689 #endif 7690 {"count", 2, 4, f_count}, 7691 {"cscope_connection",0,3, f_cscope_connection}, 7692 {"cursor", 1, 3, f_cursor}, 7693 {"deepcopy", 1, 2, f_deepcopy}, 7694 {"delete", 1, 1, f_delete}, 7695 {"did_filetype", 0, 0, f_did_filetype}, 7696 {"diff_filler", 1, 1, f_diff_filler}, 7697 {"diff_hlID", 2, 2, f_diff_hlID}, 7698 {"empty", 1, 1, f_empty}, 7699 {"escape", 2, 2, f_escape}, 7700 {"eval", 1, 1, f_eval}, 7701 {"eventhandler", 0, 0, f_eventhandler}, 7702 {"executable", 1, 1, f_executable}, 7703 {"exists", 1, 1, f_exists}, 7704 #ifdef FEAT_FLOAT 7705 {"exp", 1, 1, f_exp}, 7706 #endif 7707 {"expand", 1, 2, f_expand}, 7708 {"extend", 2, 3, f_extend}, 7709 {"feedkeys", 1, 2, f_feedkeys}, 7710 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 7711 {"filereadable", 1, 1, f_filereadable}, 7712 {"filewritable", 1, 1, f_filewritable}, 7713 {"filter", 2, 2, f_filter}, 7714 {"finddir", 1, 3, f_finddir}, 7715 {"findfile", 1, 3, f_findfile}, 7716 #ifdef FEAT_FLOAT 7717 {"float2nr", 1, 1, f_float2nr}, 7718 {"floor", 1, 1, f_floor}, 7719 {"fmod", 2, 2, f_fmod}, 7720 #endif 7721 {"fnameescape", 1, 1, f_fnameescape}, 7722 {"fnamemodify", 2, 2, f_fnamemodify}, 7723 {"foldclosed", 1, 1, f_foldclosed}, 7724 {"foldclosedend", 1, 1, f_foldclosedend}, 7725 {"foldlevel", 1, 1, f_foldlevel}, 7726 {"foldtext", 0, 0, f_foldtext}, 7727 {"foldtextresult", 1, 1, f_foldtextresult}, 7728 {"foreground", 0, 0, f_foreground}, 7729 {"function", 1, 1, f_function}, 7730 {"garbagecollect", 0, 1, f_garbagecollect}, 7731 {"get", 2, 3, f_get}, 7732 {"getbufline", 2, 3, f_getbufline}, 7733 {"getbufvar", 2, 2, f_getbufvar}, 7734 {"getchar", 0, 1, f_getchar}, 7735 {"getcharmod", 0, 0, f_getcharmod}, 7736 {"getcmdline", 0, 0, f_getcmdline}, 7737 {"getcmdpos", 0, 0, f_getcmdpos}, 7738 {"getcmdtype", 0, 0, f_getcmdtype}, 7739 {"getcwd", 0, 0, f_getcwd}, 7740 {"getfontname", 0, 1, f_getfontname}, 7741 {"getfperm", 1, 1, f_getfperm}, 7742 {"getfsize", 1, 1, f_getfsize}, 7743 {"getftime", 1, 1, f_getftime}, 7744 {"getftype", 1, 1, f_getftype}, 7745 {"getline", 1, 2, f_getline}, 7746 {"getloclist", 1, 1, f_getqflist}, 7747 {"getmatches", 0, 0, f_getmatches}, 7748 {"getpid", 0, 0, f_getpid}, 7749 {"getpos", 1, 1, f_getpos}, 7750 {"getqflist", 0, 0, f_getqflist}, 7751 {"getreg", 0, 2, f_getreg}, 7752 {"getregtype", 0, 1, f_getregtype}, 7753 {"gettabvar", 2, 2, f_gettabvar}, 7754 {"gettabwinvar", 3, 3, f_gettabwinvar}, 7755 {"getwinposx", 0, 0, f_getwinposx}, 7756 {"getwinposy", 0, 0, f_getwinposy}, 7757 {"getwinvar", 2, 2, f_getwinvar}, 7758 {"glob", 1, 2, f_glob}, 7759 {"globpath", 2, 3, f_globpath}, 7760 {"has", 1, 1, f_has}, 7761 {"has_key", 2, 2, f_has_key}, 7762 {"haslocaldir", 0, 0, f_haslocaldir}, 7763 {"hasmapto", 1, 3, f_hasmapto}, 7764 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 7765 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 7766 {"histadd", 2, 2, f_histadd}, 7767 {"histdel", 1, 2, f_histdel}, 7768 {"histget", 1, 2, f_histget}, 7769 {"histnr", 1, 1, f_histnr}, 7770 {"hlID", 1, 1, f_hlID}, 7771 {"hlexists", 1, 1, f_hlexists}, 7772 {"hostname", 0, 0, f_hostname}, 7773 {"iconv", 3, 3, f_iconv}, 7774 {"indent", 1, 1, f_indent}, 7775 {"index", 2, 4, f_index}, 7776 {"input", 1, 3, f_input}, 7777 {"inputdialog", 1, 3, f_inputdialog}, 7778 {"inputlist", 1, 1, f_inputlist}, 7779 {"inputrestore", 0, 0, f_inputrestore}, 7780 {"inputsave", 0, 0, f_inputsave}, 7781 {"inputsecret", 1, 2, f_inputsecret}, 7782 {"insert", 2, 3, f_insert}, 7783 {"isdirectory", 1, 1, f_isdirectory}, 7784 {"islocked", 1, 1, f_islocked}, 7785 {"items", 1, 1, f_items}, 7786 {"join", 1, 2, f_join}, 7787 {"keys", 1, 1, f_keys}, 7788 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 7789 {"len", 1, 1, f_len}, 7790 {"libcall", 3, 3, f_libcall}, 7791 {"libcallnr", 3, 3, f_libcallnr}, 7792 {"line", 1, 1, f_line}, 7793 {"line2byte", 1, 1, f_line2byte}, 7794 {"lispindent", 1, 1, f_lispindent}, 7795 {"localtime", 0, 0, f_localtime}, 7796 #ifdef FEAT_FLOAT 7797 {"log", 1, 1, f_log}, 7798 {"log10", 1, 1, f_log10}, 7799 #endif 7800 {"map", 2, 2, f_map}, 7801 {"maparg", 1, 3, f_maparg}, 7802 {"mapcheck", 1, 3, f_mapcheck}, 7803 {"match", 2, 4, f_match}, 7804 {"matchadd", 2, 4, f_matchadd}, 7805 {"matcharg", 1, 1, f_matcharg}, 7806 {"matchdelete", 1, 1, f_matchdelete}, 7807 {"matchend", 2, 4, f_matchend}, 7808 {"matchlist", 2, 4, f_matchlist}, 7809 {"matchstr", 2, 4, f_matchstr}, 7810 {"max", 1, 1, f_max}, 7811 {"min", 1, 1, f_min}, 7812 #ifdef vim_mkdir 7813 {"mkdir", 1, 3, f_mkdir}, 7814 #endif 7815 {"mode", 0, 1, f_mode}, 7816 #ifdef FEAT_MZSCHEME 7817 {"mzeval", 1, 1, f_mzeval}, 7818 #endif 7819 {"nextnonblank", 1, 1, f_nextnonblank}, 7820 {"nr2char", 1, 1, f_nr2char}, 7821 {"pathshorten", 1, 1, f_pathshorten}, 7822 #ifdef FEAT_FLOAT 7823 {"pow", 2, 2, f_pow}, 7824 #endif 7825 {"prevnonblank", 1, 1, f_prevnonblank}, 7826 {"printf", 2, 19, f_printf}, 7827 {"pumvisible", 0, 0, f_pumvisible}, 7828 {"range", 1, 3, f_range}, 7829 {"readfile", 1, 3, f_readfile}, 7830 {"reltime", 0, 2, f_reltime}, 7831 {"reltimestr", 1, 1, f_reltimestr}, 7832 {"remote_expr", 2, 3, f_remote_expr}, 7833 {"remote_foreground", 1, 1, f_remote_foreground}, 7834 {"remote_peek", 1, 2, f_remote_peek}, 7835 {"remote_read", 1, 1, f_remote_read}, 7836 {"remote_send", 2, 3, f_remote_send}, 7837 {"remove", 2, 3, f_remove}, 7838 {"rename", 2, 2, f_rename}, 7839 {"repeat", 2, 2, f_repeat}, 7840 {"resolve", 1, 1, f_resolve}, 7841 {"reverse", 1, 1, f_reverse}, 7842 #ifdef FEAT_FLOAT 7843 {"round", 1, 1, f_round}, 7844 #endif 7845 {"search", 1, 4, f_search}, 7846 {"searchdecl", 1, 3, f_searchdecl}, 7847 {"searchpair", 3, 7, f_searchpair}, 7848 {"searchpairpos", 3, 7, f_searchpairpos}, 7849 {"searchpos", 1, 4, f_searchpos}, 7850 {"server2client", 2, 2, f_server2client}, 7851 {"serverlist", 0, 0, f_serverlist}, 7852 {"setbufvar", 3, 3, f_setbufvar}, 7853 {"setcmdpos", 1, 1, f_setcmdpos}, 7854 {"setline", 2, 2, f_setline}, 7855 {"setloclist", 2, 3, f_setloclist}, 7856 {"setmatches", 1, 1, f_setmatches}, 7857 {"setpos", 2, 2, f_setpos}, 7858 {"setqflist", 1, 2, f_setqflist}, 7859 {"setreg", 2, 3, f_setreg}, 7860 {"settabvar", 3, 3, f_settabvar}, 7861 {"settabwinvar", 4, 4, f_settabwinvar}, 7862 {"setwinvar", 3, 3, f_setwinvar}, 7863 {"shellescape", 1, 2, f_shellescape}, 7864 {"simplify", 1, 1, f_simplify}, 7865 #ifdef FEAT_FLOAT 7866 {"sin", 1, 1, f_sin}, 7867 {"sinh", 1, 1, f_sinh}, 7868 #endif 7869 {"sort", 1, 2, f_sort}, 7870 {"soundfold", 1, 1, f_soundfold}, 7871 {"spellbadword", 0, 1, f_spellbadword}, 7872 {"spellsuggest", 1, 3, f_spellsuggest}, 7873 {"split", 1, 3, f_split}, 7874 #ifdef FEAT_FLOAT 7875 {"sqrt", 1, 1, f_sqrt}, 7876 {"str2float", 1, 1, f_str2float}, 7877 #endif 7878 {"str2nr", 1, 2, f_str2nr}, 7879 {"strchars", 1, 1, f_strchars}, 7880 {"strdisplaywidth", 1, 2, f_strdisplaywidth}, 7881 #ifdef HAVE_STRFTIME 7882 {"strftime", 1, 2, f_strftime}, 7883 #endif 7884 {"stridx", 2, 3, f_stridx}, 7885 {"string", 1, 1, f_string}, 7886 {"strlen", 1, 1, f_strlen}, 7887 {"strpart", 2, 3, f_strpart}, 7888 {"strridx", 2, 3, f_strridx}, 7889 {"strtrans", 1, 1, f_strtrans}, 7890 {"strwidth", 1, 1, f_strwidth}, 7891 {"submatch", 1, 1, f_submatch}, 7892 {"substitute", 4, 4, f_substitute}, 7893 {"synID", 3, 3, f_synID}, 7894 {"synIDattr", 2, 3, f_synIDattr}, 7895 {"synIDtrans", 1, 1, f_synIDtrans}, 7896 {"synconcealed", 2, 2, f_synconcealed}, 7897 {"synstack", 2, 2, f_synstack}, 7898 {"system", 1, 2, f_system}, 7899 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 7900 {"tabpagenr", 0, 1, f_tabpagenr}, 7901 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 7902 {"tagfiles", 0, 0, f_tagfiles}, 7903 {"taglist", 1, 1, f_taglist}, 7904 #ifdef FEAT_FLOAT 7905 {"tan", 1, 1, f_tan}, 7906 {"tanh", 1, 1, f_tanh}, 7907 #endif 7908 {"tempname", 0, 0, f_tempname}, 7909 {"test", 1, 1, f_test}, 7910 {"tolower", 1, 1, f_tolower}, 7911 {"toupper", 1, 1, f_toupper}, 7912 {"tr", 3, 3, f_tr}, 7913 #ifdef FEAT_FLOAT 7914 {"trunc", 1, 1, f_trunc}, 7915 #endif 7916 {"type", 1, 1, f_type}, 7917 {"undofile", 1, 1, f_undofile}, 7918 {"undotree", 0, 0, f_undotree}, 7919 {"values", 1, 1, f_values}, 7920 {"virtcol", 1, 1, f_virtcol}, 7921 {"visualmode", 0, 1, f_visualmode}, 7922 {"winbufnr", 1, 1, f_winbufnr}, 7923 {"wincol", 0, 0, f_wincol}, 7924 {"winheight", 1, 1, f_winheight}, 7925 {"winline", 0, 0, f_winline}, 7926 {"winnr", 0, 1, f_winnr}, 7927 {"winrestcmd", 0, 0, f_winrestcmd}, 7928 {"winrestview", 1, 1, f_winrestview}, 7929 {"winsaveview", 0, 0, f_winsaveview}, 7930 {"winwidth", 1, 1, f_winwidth}, 7931 {"writefile", 2, 3, f_writefile}, 7932 }; 7933 7934 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 7935 7936 /* 7937 * Function given to ExpandGeneric() to obtain the list of internal 7938 * or user defined function names. 7939 */ 7940 char_u * 7941 get_function_name(xp, idx) 7942 expand_T *xp; 7943 int idx; 7944 { 7945 static int intidx = -1; 7946 char_u *name; 7947 7948 if (idx == 0) 7949 intidx = -1; 7950 if (intidx < 0) 7951 { 7952 name = get_user_func_name(xp, idx); 7953 if (name != NULL) 7954 return name; 7955 } 7956 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 7957 { 7958 STRCPY(IObuff, functions[intidx].f_name); 7959 STRCAT(IObuff, "("); 7960 if (functions[intidx].f_max_argc == 0) 7961 STRCAT(IObuff, ")"); 7962 return IObuff; 7963 } 7964 7965 return NULL; 7966 } 7967 7968 /* 7969 * Function given to ExpandGeneric() to obtain the list of internal or 7970 * user defined variable or function names. 7971 */ 7972 char_u * 7973 get_expr_name(xp, idx) 7974 expand_T *xp; 7975 int idx; 7976 { 7977 static int intidx = -1; 7978 char_u *name; 7979 7980 if (idx == 0) 7981 intidx = -1; 7982 if (intidx < 0) 7983 { 7984 name = get_function_name(xp, idx); 7985 if (name != NULL) 7986 return name; 7987 } 7988 return get_user_var_name(xp, ++intidx); 7989 } 7990 7991 #endif /* FEAT_CMDL_COMPL */ 7992 7993 #if defined(EBCDIC) || defined(PROTO) 7994 /* 7995 * Compare struct fst by function name. 7996 */ 7997 static int 7998 compare_func_name(s1, s2) 7999 const void *s1; 8000 const void *s2; 8001 { 8002 struct fst *p1 = (struct fst *)s1; 8003 struct fst *p2 = (struct fst *)s2; 8004 8005 return STRCMP(p1->f_name, p2->f_name); 8006 } 8007 8008 /* 8009 * Sort the function table by function name. 8010 * The sorting of the table above is ASCII dependant. 8011 * On machines using EBCDIC we have to sort it. 8012 */ 8013 static void 8014 sortFunctions() 8015 { 8016 int funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8017 8018 qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name); 8019 } 8020 #endif 8021 8022 8023 /* 8024 * Find internal function in table above. 8025 * Return index, or -1 if not found 8026 */ 8027 static int 8028 find_internal_func(name) 8029 char_u *name; /* name of the function */ 8030 { 8031 int first = 0; 8032 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8033 int cmp; 8034 int x; 8035 8036 /* 8037 * Find the function name in the table. Binary search. 8038 */ 8039 while (first <= last) 8040 { 8041 x = first + ((unsigned)(last - first) >> 1); 8042 cmp = STRCMP(name, functions[x].f_name); 8043 if (cmp < 0) 8044 last = x - 1; 8045 else if (cmp > 0) 8046 first = x + 1; 8047 else 8048 return x; 8049 } 8050 return -1; 8051 } 8052 8053 /* 8054 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 8055 * name it contains, otherwise return "name". 8056 */ 8057 static char_u * 8058 deref_func_name(name, lenp) 8059 char_u *name; 8060 int *lenp; 8061 { 8062 dictitem_T *v; 8063 int cc; 8064 8065 cc = name[*lenp]; 8066 name[*lenp] = NUL; 8067 v = find_var(name, NULL); 8068 name[*lenp] = cc; 8069 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 8070 { 8071 if (v->di_tv.vval.v_string == NULL) 8072 { 8073 *lenp = 0; 8074 return (char_u *)""; /* just in case */ 8075 } 8076 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 8077 return v->di_tv.vval.v_string; 8078 } 8079 8080 return name; 8081 } 8082 8083 /* 8084 * Allocate a variable for the result of a function. 8085 * Return OK or FAIL. 8086 */ 8087 static int 8088 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 8089 evaluate, selfdict) 8090 char_u *name; /* name of the function */ 8091 int len; /* length of "name" */ 8092 typval_T *rettv; 8093 char_u **arg; /* argument, pointing to the '(' */ 8094 linenr_T firstline; /* first line of range */ 8095 linenr_T lastline; /* last line of range */ 8096 int *doesrange; /* return: function handled range */ 8097 int evaluate; 8098 dict_T *selfdict; /* Dictionary for "self" */ 8099 { 8100 char_u *argp; 8101 int ret = OK; 8102 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 8103 int argcount = 0; /* number of arguments found */ 8104 8105 /* 8106 * Get the arguments. 8107 */ 8108 argp = *arg; 8109 while (argcount < MAX_FUNC_ARGS) 8110 { 8111 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 8112 if (*argp == ')' || *argp == ',' || *argp == NUL) 8113 break; 8114 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 8115 { 8116 ret = FAIL; 8117 break; 8118 } 8119 ++argcount; 8120 if (*argp != ',') 8121 break; 8122 } 8123 if (*argp == ')') 8124 ++argp; 8125 else 8126 ret = FAIL; 8127 8128 if (ret == OK) 8129 ret = call_func(name, len, rettv, argcount, argvars, 8130 firstline, lastline, doesrange, evaluate, selfdict); 8131 else if (!aborting()) 8132 { 8133 if (argcount == MAX_FUNC_ARGS) 8134 emsg_funcname(N_("E740: Too many arguments for function %s"), name); 8135 else 8136 emsg_funcname(N_("E116: Invalid arguments for function %s"), name); 8137 } 8138 8139 while (--argcount >= 0) 8140 clear_tv(&argvars[argcount]); 8141 8142 *arg = skipwhite(argp); 8143 return ret; 8144 } 8145 8146 8147 /* 8148 * Call a function with its resolved parameters 8149 * Return OK when the function can't be called, FAIL otherwise. 8150 * Also returns OK when an error was encountered while executing the function. 8151 */ 8152 static int 8153 call_func(funcname, len, rettv, argcount, argvars, firstline, lastline, 8154 doesrange, evaluate, selfdict) 8155 char_u *funcname; /* name of the function */ 8156 int len; /* length of "name" */ 8157 typval_T *rettv; /* return value goes here */ 8158 int argcount; /* number of "argvars" */ 8159 typval_T *argvars; /* vars for arguments, must have "argcount" 8160 PLUS ONE elements! */ 8161 linenr_T firstline; /* first line of range */ 8162 linenr_T lastline; /* last line of range */ 8163 int *doesrange; /* return: function handled range */ 8164 int evaluate; 8165 dict_T *selfdict; /* Dictionary for "self" */ 8166 { 8167 int ret = FAIL; 8168 #define ERROR_UNKNOWN 0 8169 #define ERROR_TOOMANY 1 8170 #define ERROR_TOOFEW 2 8171 #define ERROR_SCRIPT 3 8172 #define ERROR_DICT 4 8173 #define ERROR_NONE 5 8174 #define ERROR_OTHER 6 8175 int error = ERROR_NONE; 8176 int i; 8177 int llen; 8178 ufunc_T *fp; 8179 #define FLEN_FIXED 40 8180 char_u fname_buf[FLEN_FIXED + 1]; 8181 char_u *fname; 8182 char_u *name; 8183 8184 /* Make a copy of the name, if it comes from a funcref variable it could 8185 * be changed or deleted in the called function. */ 8186 name = vim_strnsave(funcname, len); 8187 if (name == NULL) 8188 return ret; 8189 8190 /* 8191 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 8192 * Change <SNR>123_name() to K_SNR 123_name(). 8193 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 8194 */ 8195 llen = eval_fname_script(name); 8196 if (llen > 0) 8197 { 8198 fname_buf[0] = K_SPECIAL; 8199 fname_buf[1] = KS_EXTRA; 8200 fname_buf[2] = (int)KE_SNR; 8201 i = 3; 8202 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 8203 { 8204 if (current_SID <= 0) 8205 error = ERROR_SCRIPT; 8206 else 8207 { 8208 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 8209 i = (int)STRLEN(fname_buf); 8210 } 8211 } 8212 if (i + STRLEN(name + llen) < FLEN_FIXED) 8213 { 8214 STRCPY(fname_buf + i, name + llen); 8215 fname = fname_buf; 8216 } 8217 else 8218 { 8219 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 8220 if (fname == NULL) 8221 error = ERROR_OTHER; 8222 else 8223 { 8224 mch_memmove(fname, fname_buf, (size_t)i); 8225 STRCPY(fname + i, name + llen); 8226 } 8227 } 8228 } 8229 else 8230 fname = name; 8231 8232 *doesrange = FALSE; 8233 8234 8235 /* execute the function if no errors detected and executing */ 8236 if (evaluate && error == ERROR_NONE) 8237 { 8238 rettv->v_type = VAR_NUMBER; /* default rettv is number zero */ 8239 rettv->vval.v_number = 0; 8240 error = ERROR_UNKNOWN; 8241 8242 if (!builtin_function(fname)) 8243 { 8244 /* 8245 * User defined function. 8246 */ 8247 fp = find_func(fname); 8248 8249 #ifdef FEAT_AUTOCMD 8250 /* Trigger FuncUndefined event, may load the function. */ 8251 if (fp == NULL 8252 && apply_autocmds(EVENT_FUNCUNDEFINED, 8253 fname, fname, TRUE, NULL) 8254 && !aborting()) 8255 { 8256 /* executed an autocommand, search for the function again */ 8257 fp = find_func(fname); 8258 } 8259 #endif 8260 /* Try loading a package. */ 8261 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 8262 { 8263 /* loaded a package, search for the function again */ 8264 fp = find_func(fname); 8265 } 8266 8267 if (fp != NULL) 8268 { 8269 if (fp->uf_flags & FC_RANGE) 8270 *doesrange = TRUE; 8271 if (argcount < fp->uf_args.ga_len) 8272 error = ERROR_TOOFEW; 8273 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 8274 error = ERROR_TOOMANY; 8275 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 8276 error = ERROR_DICT; 8277 else 8278 { 8279 /* 8280 * Call the user function. 8281 * Save and restore search patterns, script variables and 8282 * redo buffer. 8283 */ 8284 save_search_patterns(); 8285 saveRedobuff(); 8286 ++fp->uf_calls; 8287 call_user_func(fp, argcount, argvars, rettv, 8288 firstline, lastline, 8289 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 8290 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 8291 && fp->uf_refcount <= 0) 8292 /* Function was unreferenced while being used, free it 8293 * now. */ 8294 func_free(fp); 8295 restoreRedobuff(); 8296 restore_search_patterns(); 8297 error = ERROR_NONE; 8298 } 8299 } 8300 } 8301 else 8302 { 8303 /* 8304 * Find the function name in the table, call its implementation. 8305 */ 8306 i = find_internal_func(fname); 8307 if (i >= 0) 8308 { 8309 if (argcount < functions[i].f_min_argc) 8310 error = ERROR_TOOFEW; 8311 else if (argcount > functions[i].f_max_argc) 8312 error = ERROR_TOOMANY; 8313 else 8314 { 8315 argvars[argcount].v_type = VAR_UNKNOWN; 8316 functions[i].f_func(argvars, rettv); 8317 error = ERROR_NONE; 8318 } 8319 } 8320 } 8321 /* 8322 * The function call (or "FuncUndefined" autocommand sequence) might 8323 * have been aborted by an error, an interrupt, or an explicitly thrown 8324 * exception that has not been caught so far. This situation can be 8325 * tested for by calling aborting(). For an error in an internal 8326 * function or for the "E132" error in call_user_func(), however, the 8327 * throw point at which the "force_abort" flag (temporarily reset by 8328 * emsg()) is normally updated has not been reached yet. We need to 8329 * update that flag first to make aborting() reliable. 8330 */ 8331 update_force_abort(); 8332 } 8333 if (error == ERROR_NONE) 8334 ret = OK; 8335 8336 /* 8337 * Report an error unless the argument evaluation or function call has been 8338 * cancelled due to an aborting error, an interrupt, or an exception. 8339 */ 8340 if (!aborting()) 8341 { 8342 switch (error) 8343 { 8344 case ERROR_UNKNOWN: 8345 emsg_funcname(N_("E117: Unknown function: %s"), name); 8346 break; 8347 case ERROR_TOOMANY: 8348 emsg_funcname(e_toomanyarg, name); 8349 break; 8350 case ERROR_TOOFEW: 8351 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 8352 name); 8353 break; 8354 case ERROR_SCRIPT: 8355 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 8356 name); 8357 break; 8358 case ERROR_DICT: 8359 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 8360 name); 8361 break; 8362 } 8363 } 8364 8365 if (fname != name && fname != fname_buf) 8366 vim_free(fname); 8367 vim_free(name); 8368 8369 return ret; 8370 } 8371 8372 /* 8373 * Give an error message with a function name. Handle <SNR> things. 8374 * "ermsg" is to be passed without translation, use N_() instead of _(). 8375 */ 8376 static void 8377 emsg_funcname(ermsg, name) 8378 char *ermsg; 8379 char_u *name; 8380 { 8381 char_u *p; 8382 8383 if (*name == K_SPECIAL) 8384 p = concat_str((char_u *)"<SNR>", name + 3); 8385 else 8386 p = name; 8387 EMSG2(_(ermsg), p); 8388 if (p != name) 8389 vim_free(p); 8390 } 8391 8392 /* 8393 * Return TRUE for a non-zero Number and a non-empty String. 8394 */ 8395 static int 8396 non_zero_arg(argvars) 8397 typval_T *argvars; 8398 { 8399 return ((argvars[0].v_type == VAR_NUMBER 8400 && argvars[0].vval.v_number != 0) 8401 || (argvars[0].v_type == VAR_STRING 8402 && argvars[0].vval.v_string != NULL 8403 && *argvars[0].vval.v_string != NUL)); 8404 } 8405 8406 /********************************************* 8407 * Implementation of the built-in functions 8408 */ 8409 8410 #ifdef FEAT_FLOAT 8411 static int get_float_arg __ARGS((typval_T *argvars, float_T *f)); 8412 8413 /* 8414 * Get the float value of "argvars[0]" into "f". 8415 * Returns FAIL when the argument is not a Number or Float. 8416 */ 8417 static int 8418 get_float_arg(argvars, f) 8419 typval_T *argvars; 8420 float_T *f; 8421 { 8422 if (argvars[0].v_type == VAR_FLOAT) 8423 { 8424 *f = argvars[0].vval.v_float; 8425 return OK; 8426 } 8427 if (argvars[0].v_type == VAR_NUMBER) 8428 { 8429 *f = (float_T)argvars[0].vval.v_number; 8430 return OK; 8431 } 8432 EMSG(_("E808: Number or Float required")); 8433 return FAIL; 8434 } 8435 8436 /* 8437 * "abs(expr)" function 8438 */ 8439 static void 8440 f_abs(argvars, rettv) 8441 typval_T *argvars; 8442 typval_T *rettv; 8443 { 8444 if (argvars[0].v_type == VAR_FLOAT) 8445 { 8446 rettv->v_type = VAR_FLOAT; 8447 rettv->vval.v_float = fabs(argvars[0].vval.v_float); 8448 } 8449 else 8450 { 8451 varnumber_T n; 8452 int error = FALSE; 8453 8454 n = get_tv_number_chk(&argvars[0], &error); 8455 if (error) 8456 rettv->vval.v_number = -1; 8457 else if (n > 0) 8458 rettv->vval.v_number = n; 8459 else 8460 rettv->vval.v_number = -n; 8461 } 8462 } 8463 8464 /* 8465 * "acos()" function 8466 */ 8467 static void 8468 f_acos(argvars, rettv) 8469 typval_T *argvars; 8470 typval_T *rettv; 8471 { 8472 float_T f; 8473 8474 rettv->v_type = VAR_FLOAT; 8475 if (get_float_arg(argvars, &f) == OK) 8476 rettv->vval.v_float = acos(f); 8477 else 8478 rettv->vval.v_float = 0.0; 8479 } 8480 #endif 8481 8482 /* 8483 * "add(list, item)" function 8484 */ 8485 static void 8486 f_add(argvars, rettv) 8487 typval_T *argvars; 8488 typval_T *rettv; 8489 { 8490 list_T *l; 8491 8492 rettv->vval.v_number = 1; /* Default: Failed */ 8493 if (argvars[0].v_type == VAR_LIST) 8494 { 8495 if ((l = argvars[0].vval.v_list) != NULL 8496 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 8497 && list_append_tv(l, &argvars[1]) == OK) 8498 copy_tv(&argvars[0], rettv); 8499 } 8500 else 8501 EMSG(_(e_listreq)); 8502 } 8503 8504 /* 8505 * "append(lnum, string/list)" function 8506 */ 8507 static void 8508 f_append(argvars, rettv) 8509 typval_T *argvars; 8510 typval_T *rettv; 8511 { 8512 long lnum; 8513 char_u *line; 8514 list_T *l = NULL; 8515 listitem_T *li = NULL; 8516 typval_T *tv; 8517 long added = 0; 8518 8519 lnum = get_tv_lnum(argvars); 8520 if (lnum >= 0 8521 && lnum <= curbuf->b_ml.ml_line_count 8522 && u_save(lnum, lnum + 1) == OK) 8523 { 8524 if (argvars[1].v_type == VAR_LIST) 8525 { 8526 l = argvars[1].vval.v_list; 8527 if (l == NULL) 8528 return; 8529 li = l->lv_first; 8530 } 8531 for (;;) 8532 { 8533 if (l == NULL) 8534 tv = &argvars[1]; /* append a string */ 8535 else if (li == NULL) 8536 break; /* end of list */ 8537 else 8538 tv = &li->li_tv; /* append item from list */ 8539 line = get_tv_string_chk(tv); 8540 if (line == NULL) /* type error */ 8541 { 8542 rettv->vval.v_number = 1; /* Failed */ 8543 break; 8544 } 8545 ml_append(lnum + added, line, (colnr_T)0, FALSE); 8546 ++added; 8547 if (l == NULL) 8548 break; 8549 li = li->li_next; 8550 } 8551 8552 appended_lines_mark(lnum, added); 8553 if (curwin->w_cursor.lnum > lnum) 8554 curwin->w_cursor.lnum += added; 8555 } 8556 else 8557 rettv->vval.v_number = 1; /* Failed */ 8558 } 8559 8560 /* 8561 * "argc()" function 8562 */ 8563 static void 8564 f_argc(argvars, rettv) 8565 typval_T *argvars UNUSED; 8566 typval_T *rettv; 8567 { 8568 rettv->vval.v_number = ARGCOUNT; 8569 } 8570 8571 /* 8572 * "argidx()" function 8573 */ 8574 static void 8575 f_argidx(argvars, rettv) 8576 typval_T *argvars UNUSED; 8577 typval_T *rettv; 8578 { 8579 rettv->vval.v_number = curwin->w_arg_idx; 8580 } 8581 8582 /* 8583 * "argv(nr)" function 8584 */ 8585 static void 8586 f_argv(argvars, rettv) 8587 typval_T *argvars; 8588 typval_T *rettv; 8589 { 8590 int idx; 8591 8592 if (argvars[0].v_type != VAR_UNKNOWN) 8593 { 8594 idx = get_tv_number_chk(&argvars[0], NULL); 8595 if (idx >= 0 && idx < ARGCOUNT) 8596 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 8597 else 8598 rettv->vval.v_string = NULL; 8599 rettv->v_type = VAR_STRING; 8600 } 8601 else if (rettv_list_alloc(rettv) == OK) 8602 for (idx = 0; idx < ARGCOUNT; ++idx) 8603 list_append_string(rettv->vval.v_list, 8604 alist_name(&ARGLIST[idx]), -1); 8605 } 8606 8607 #ifdef FEAT_FLOAT 8608 /* 8609 * "asin()" function 8610 */ 8611 static void 8612 f_asin(argvars, rettv) 8613 typval_T *argvars; 8614 typval_T *rettv; 8615 { 8616 float_T f; 8617 8618 rettv->v_type = VAR_FLOAT; 8619 if (get_float_arg(argvars, &f) == OK) 8620 rettv->vval.v_float = asin(f); 8621 else 8622 rettv->vval.v_float = 0.0; 8623 } 8624 8625 /* 8626 * "atan()" function 8627 */ 8628 static void 8629 f_atan(argvars, rettv) 8630 typval_T *argvars; 8631 typval_T *rettv; 8632 { 8633 float_T f; 8634 8635 rettv->v_type = VAR_FLOAT; 8636 if (get_float_arg(argvars, &f) == OK) 8637 rettv->vval.v_float = atan(f); 8638 else 8639 rettv->vval.v_float = 0.0; 8640 } 8641 8642 /* 8643 * "atan2()" function 8644 */ 8645 static void 8646 f_atan2(argvars, rettv) 8647 typval_T *argvars; 8648 typval_T *rettv; 8649 { 8650 float_T fx, fy; 8651 8652 rettv->v_type = VAR_FLOAT; 8653 if (get_float_arg(argvars, &fx) == OK 8654 && get_float_arg(&argvars[1], &fy) == OK) 8655 rettv->vval.v_float = atan2(fx, fy); 8656 else 8657 rettv->vval.v_float = 0.0; 8658 } 8659 #endif 8660 8661 /* 8662 * "browse(save, title, initdir, default)" function 8663 */ 8664 static void 8665 f_browse(argvars, rettv) 8666 typval_T *argvars UNUSED; 8667 typval_T *rettv; 8668 { 8669 #ifdef FEAT_BROWSE 8670 int save; 8671 char_u *title; 8672 char_u *initdir; 8673 char_u *defname; 8674 char_u buf[NUMBUFLEN]; 8675 char_u buf2[NUMBUFLEN]; 8676 int error = FALSE; 8677 8678 save = get_tv_number_chk(&argvars[0], &error); 8679 title = get_tv_string_chk(&argvars[1]); 8680 initdir = get_tv_string_buf_chk(&argvars[2], buf); 8681 defname = get_tv_string_buf_chk(&argvars[3], buf2); 8682 8683 if (error || title == NULL || initdir == NULL || defname == NULL) 8684 rettv->vval.v_string = NULL; 8685 else 8686 rettv->vval.v_string = 8687 do_browse(save ? BROWSE_SAVE : 0, 8688 title, defname, NULL, initdir, NULL, curbuf); 8689 #else 8690 rettv->vval.v_string = NULL; 8691 #endif 8692 rettv->v_type = VAR_STRING; 8693 } 8694 8695 /* 8696 * "browsedir(title, initdir)" function 8697 */ 8698 static void 8699 f_browsedir(argvars, rettv) 8700 typval_T *argvars UNUSED; 8701 typval_T *rettv; 8702 { 8703 #ifdef FEAT_BROWSE 8704 char_u *title; 8705 char_u *initdir; 8706 char_u buf[NUMBUFLEN]; 8707 8708 title = get_tv_string_chk(&argvars[0]); 8709 initdir = get_tv_string_buf_chk(&argvars[1], buf); 8710 8711 if (title == NULL || initdir == NULL) 8712 rettv->vval.v_string = NULL; 8713 else 8714 rettv->vval.v_string = do_browse(BROWSE_DIR, 8715 title, NULL, NULL, initdir, NULL, curbuf); 8716 #else 8717 rettv->vval.v_string = NULL; 8718 #endif 8719 rettv->v_type = VAR_STRING; 8720 } 8721 8722 static buf_T *find_buffer __ARGS((typval_T *avar)); 8723 8724 /* 8725 * Find a buffer by number or exact name. 8726 */ 8727 static buf_T * 8728 find_buffer(avar) 8729 typval_T *avar; 8730 { 8731 buf_T *buf = NULL; 8732 8733 if (avar->v_type == VAR_NUMBER) 8734 buf = buflist_findnr((int)avar->vval.v_number); 8735 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 8736 { 8737 buf = buflist_findname_exp(avar->vval.v_string); 8738 if (buf == NULL) 8739 { 8740 /* No full path name match, try a match with a URL or a "nofile" 8741 * buffer, these don't use the full path. */ 8742 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 8743 if (buf->b_fname != NULL 8744 && (path_with_url(buf->b_fname) 8745 #ifdef FEAT_QUICKFIX 8746 || bt_nofile(buf) 8747 #endif 8748 ) 8749 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 8750 break; 8751 } 8752 } 8753 return buf; 8754 } 8755 8756 /* 8757 * "bufexists(expr)" function 8758 */ 8759 static void 8760 f_bufexists(argvars, rettv) 8761 typval_T *argvars; 8762 typval_T *rettv; 8763 { 8764 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 8765 } 8766 8767 /* 8768 * "buflisted(expr)" function 8769 */ 8770 static void 8771 f_buflisted(argvars, rettv) 8772 typval_T *argvars; 8773 typval_T *rettv; 8774 { 8775 buf_T *buf; 8776 8777 buf = find_buffer(&argvars[0]); 8778 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 8779 } 8780 8781 /* 8782 * "bufloaded(expr)" function 8783 */ 8784 static void 8785 f_bufloaded(argvars, rettv) 8786 typval_T *argvars; 8787 typval_T *rettv; 8788 { 8789 buf_T *buf; 8790 8791 buf = find_buffer(&argvars[0]); 8792 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 8793 } 8794 8795 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 8796 8797 /* 8798 * Get buffer by number or pattern. 8799 */ 8800 static buf_T * 8801 get_buf_tv(tv) 8802 typval_T *tv; 8803 { 8804 char_u *name = tv->vval.v_string; 8805 int save_magic; 8806 char_u *save_cpo; 8807 buf_T *buf; 8808 8809 if (tv->v_type == VAR_NUMBER) 8810 return buflist_findnr((int)tv->vval.v_number); 8811 if (tv->v_type != VAR_STRING) 8812 return NULL; 8813 if (name == NULL || *name == NUL) 8814 return curbuf; 8815 if (name[0] == '$' && name[1] == NUL) 8816 return lastbuf; 8817 8818 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 8819 save_magic = p_magic; 8820 p_magic = TRUE; 8821 save_cpo = p_cpo; 8822 p_cpo = (char_u *)""; 8823 8824 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 8825 TRUE, FALSE)); 8826 8827 p_magic = save_magic; 8828 p_cpo = save_cpo; 8829 8830 /* If not found, try expanding the name, like done for bufexists(). */ 8831 if (buf == NULL) 8832 buf = find_buffer(tv); 8833 8834 return buf; 8835 } 8836 8837 /* 8838 * "bufname(expr)" function 8839 */ 8840 static void 8841 f_bufname(argvars, rettv) 8842 typval_T *argvars; 8843 typval_T *rettv; 8844 { 8845 buf_T *buf; 8846 8847 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8848 ++emsg_off; 8849 buf = get_buf_tv(&argvars[0]); 8850 rettv->v_type = VAR_STRING; 8851 if (buf != NULL && buf->b_fname != NULL) 8852 rettv->vval.v_string = vim_strsave(buf->b_fname); 8853 else 8854 rettv->vval.v_string = NULL; 8855 --emsg_off; 8856 } 8857 8858 /* 8859 * "bufnr(expr)" function 8860 */ 8861 static void 8862 f_bufnr(argvars, rettv) 8863 typval_T *argvars; 8864 typval_T *rettv; 8865 { 8866 buf_T *buf; 8867 int error = FALSE; 8868 char_u *name; 8869 8870 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8871 ++emsg_off; 8872 buf = get_buf_tv(&argvars[0]); 8873 --emsg_off; 8874 8875 /* If the buffer isn't found and the second argument is not zero create a 8876 * new buffer. */ 8877 if (buf == NULL 8878 && argvars[1].v_type != VAR_UNKNOWN 8879 && get_tv_number_chk(&argvars[1], &error) != 0 8880 && !error 8881 && (name = get_tv_string_chk(&argvars[0])) != NULL 8882 && !error) 8883 buf = buflist_new(name, NULL, (linenr_T)1, 0); 8884 8885 if (buf != NULL) 8886 rettv->vval.v_number = buf->b_fnum; 8887 else 8888 rettv->vval.v_number = -1; 8889 } 8890 8891 /* 8892 * "bufwinnr(nr)" function 8893 */ 8894 static void 8895 f_bufwinnr(argvars, rettv) 8896 typval_T *argvars; 8897 typval_T *rettv; 8898 { 8899 #ifdef FEAT_WINDOWS 8900 win_T *wp; 8901 int winnr = 0; 8902 #endif 8903 buf_T *buf; 8904 8905 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8906 ++emsg_off; 8907 buf = get_buf_tv(&argvars[0]); 8908 #ifdef FEAT_WINDOWS 8909 for (wp = firstwin; wp; wp = wp->w_next) 8910 { 8911 ++winnr; 8912 if (wp->w_buffer == buf) 8913 break; 8914 } 8915 rettv->vval.v_number = (wp != NULL ? winnr : -1); 8916 #else 8917 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 8918 #endif 8919 --emsg_off; 8920 } 8921 8922 /* 8923 * "byte2line(byte)" function 8924 */ 8925 static void 8926 f_byte2line(argvars, rettv) 8927 typval_T *argvars UNUSED; 8928 typval_T *rettv; 8929 { 8930 #ifndef FEAT_BYTEOFF 8931 rettv->vval.v_number = -1; 8932 #else 8933 long boff = 0; 8934 8935 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 8936 if (boff < 0) 8937 rettv->vval.v_number = -1; 8938 else 8939 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 8940 (linenr_T)0, &boff); 8941 #endif 8942 } 8943 8944 /* 8945 * "byteidx()" function 8946 */ 8947 static void 8948 f_byteidx(argvars, rettv) 8949 typval_T *argvars; 8950 typval_T *rettv; 8951 { 8952 #ifdef FEAT_MBYTE 8953 char_u *t; 8954 #endif 8955 char_u *str; 8956 long idx; 8957 8958 str = get_tv_string_chk(&argvars[0]); 8959 idx = get_tv_number_chk(&argvars[1], NULL); 8960 rettv->vval.v_number = -1; 8961 if (str == NULL || idx < 0) 8962 return; 8963 8964 #ifdef FEAT_MBYTE 8965 t = str; 8966 for ( ; idx > 0; idx--) 8967 { 8968 if (*t == NUL) /* EOL reached */ 8969 return; 8970 t += (*mb_ptr2len)(t); 8971 } 8972 rettv->vval.v_number = (varnumber_T)(t - str); 8973 #else 8974 if ((size_t)idx <= STRLEN(str)) 8975 rettv->vval.v_number = idx; 8976 #endif 8977 } 8978 8979 /* 8980 * "call(func, arglist)" function 8981 */ 8982 static void 8983 f_call(argvars, rettv) 8984 typval_T *argvars; 8985 typval_T *rettv; 8986 { 8987 char_u *func; 8988 typval_T argv[MAX_FUNC_ARGS + 1]; 8989 int argc = 0; 8990 listitem_T *item; 8991 int dummy; 8992 dict_T *selfdict = NULL; 8993 8994 if (argvars[1].v_type != VAR_LIST) 8995 { 8996 EMSG(_(e_listreq)); 8997 return; 8998 } 8999 if (argvars[1].vval.v_list == NULL) 9000 return; 9001 9002 if (argvars[0].v_type == VAR_FUNC) 9003 func = argvars[0].vval.v_string; 9004 else 9005 func = get_tv_string(&argvars[0]); 9006 if (*func == NUL) 9007 return; /* type error or empty name */ 9008 9009 if (argvars[2].v_type != VAR_UNKNOWN) 9010 { 9011 if (argvars[2].v_type != VAR_DICT) 9012 { 9013 EMSG(_(e_dictreq)); 9014 return; 9015 } 9016 selfdict = argvars[2].vval.v_dict; 9017 } 9018 9019 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 9020 item = item->li_next) 9021 { 9022 if (argc == MAX_FUNC_ARGS) 9023 { 9024 EMSG(_("E699: Too many arguments")); 9025 break; 9026 } 9027 /* Make a copy of each argument. This is needed to be able to set 9028 * v_lock to VAR_FIXED in the copy without changing the original list. 9029 */ 9030 copy_tv(&item->li_tv, &argv[argc++]); 9031 } 9032 9033 if (item == NULL) 9034 (void)call_func(func, (int)STRLEN(func), rettv, argc, argv, 9035 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 9036 &dummy, TRUE, selfdict); 9037 9038 /* Free the arguments. */ 9039 while (argc > 0) 9040 clear_tv(&argv[--argc]); 9041 } 9042 9043 #ifdef FEAT_FLOAT 9044 /* 9045 * "ceil({float})" function 9046 */ 9047 static void 9048 f_ceil(argvars, rettv) 9049 typval_T *argvars; 9050 typval_T *rettv; 9051 { 9052 float_T f; 9053 9054 rettv->v_type = VAR_FLOAT; 9055 if (get_float_arg(argvars, &f) == OK) 9056 rettv->vval.v_float = ceil(f); 9057 else 9058 rettv->vval.v_float = 0.0; 9059 } 9060 #endif 9061 9062 /* 9063 * "changenr()" function 9064 */ 9065 static void 9066 f_changenr(argvars, rettv) 9067 typval_T *argvars UNUSED; 9068 typval_T *rettv; 9069 { 9070 rettv->vval.v_number = curbuf->b_u_seq_cur; 9071 } 9072 9073 /* 9074 * "char2nr(string)" function 9075 */ 9076 static void 9077 f_char2nr(argvars, rettv) 9078 typval_T *argvars; 9079 typval_T *rettv; 9080 { 9081 #ifdef FEAT_MBYTE 9082 if (has_mbyte) 9083 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 9084 else 9085 #endif 9086 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 9087 } 9088 9089 /* 9090 * "cindent(lnum)" function 9091 */ 9092 static void 9093 f_cindent(argvars, rettv) 9094 typval_T *argvars; 9095 typval_T *rettv; 9096 { 9097 #ifdef FEAT_CINDENT 9098 pos_T pos; 9099 linenr_T lnum; 9100 9101 pos = curwin->w_cursor; 9102 lnum = get_tv_lnum(argvars); 9103 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9104 { 9105 curwin->w_cursor.lnum = lnum; 9106 rettv->vval.v_number = get_c_indent(); 9107 curwin->w_cursor = pos; 9108 } 9109 else 9110 #endif 9111 rettv->vval.v_number = -1; 9112 } 9113 9114 /* 9115 * "clearmatches()" function 9116 */ 9117 static void 9118 f_clearmatches(argvars, rettv) 9119 typval_T *argvars UNUSED; 9120 typval_T *rettv UNUSED; 9121 { 9122 #ifdef FEAT_SEARCH_EXTRA 9123 clear_matches(curwin); 9124 #endif 9125 } 9126 9127 /* 9128 * "col(string)" function 9129 */ 9130 static void 9131 f_col(argvars, rettv) 9132 typval_T *argvars; 9133 typval_T *rettv; 9134 { 9135 colnr_T col = 0; 9136 pos_T *fp; 9137 int fnum = curbuf->b_fnum; 9138 9139 fp = var2fpos(&argvars[0], FALSE, &fnum); 9140 if (fp != NULL && fnum == curbuf->b_fnum) 9141 { 9142 if (fp->col == MAXCOL) 9143 { 9144 /* '> can be MAXCOL, get the length of the line then */ 9145 if (fp->lnum <= curbuf->b_ml.ml_line_count) 9146 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 9147 else 9148 col = MAXCOL; 9149 } 9150 else 9151 { 9152 col = fp->col + 1; 9153 #ifdef FEAT_VIRTUALEDIT 9154 /* col(".") when the cursor is on the NUL at the end of the line 9155 * because of "coladd" can be seen as an extra column. */ 9156 if (virtual_active() && fp == &curwin->w_cursor) 9157 { 9158 char_u *p = ml_get_cursor(); 9159 9160 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 9161 curwin->w_virtcol - curwin->w_cursor.coladd)) 9162 { 9163 # ifdef FEAT_MBYTE 9164 int l; 9165 9166 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 9167 col += l; 9168 # else 9169 if (*p != NUL && p[1] == NUL) 9170 ++col; 9171 # endif 9172 } 9173 } 9174 #endif 9175 } 9176 } 9177 rettv->vval.v_number = col; 9178 } 9179 9180 #if defined(FEAT_INS_EXPAND) 9181 /* 9182 * "complete()" function 9183 */ 9184 static void 9185 f_complete(argvars, rettv) 9186 typval_T *argvars; 9187 typval_T *rettv UNUSED; 9188 { 9189 int startcol; 9190 9191 if ((State & INSERT) == 0) 9192 { 9193 EMSG(_("E785: complete() can only be used in Insert mode")); 9194 return; 9195 } 9196 9197 /* Check for undo allowed here, because if something was already inserted 9198 * the line was already saved for undo and this check isn't done. */ 9199 if (!undo_allowed()) 9200 return; 9201 9202 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 9203 { 9204 EMSG(_(e_invarg)); 9205 return; 9206 } 9207 9208 startcol = get_tv_number_chk(&argvars[0], NULL); 9209 if (startcol <= 0) 9210 return; 9211 9212 set_completion(startcol - 1, argvars[1].vval.v_list); 9213 } 9214 9215 /* 9216 * "complete_add()" function 9217 */ 9218 static void 9219 f_complete_add(argvars, rettv) 9220 typval_T *argvars; 9221 typval_T *rettv; 9222 { 9223 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 9224 } 9225 9226 /* 9227 * "complete_check()" function 9228 */ 9229 static void 9230 f_complete_check(argvars, rettv) 9231 typval_T *argvars UNUSED; 9232 typval_T *rettv; 9233 { 9234 int saved = RedrawingDisabled; 9235 9236 RedrawingDisabled = 0; 9237 ins_compl_check_keys(0); 9238 rettv->vval.v_number = compl_interrupted; 9239 RedrawingDisabled = saved; 9240 } 9241 #endif 9242 9243 /* 9244 * "confirm(message, buttons[, default [, type]])" function 9245 */ 9246 static void 9247 f_confirm(argvars, rettv) 9248 typval_T *argvars UNUSED; 9249 typval_T *rettv UNUSED; 9250 { 9251 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 9252 char_u *message; 9253 char_u *buttons = NULL; 9254 char_u buf[NUMBUFLEN]; 9255 char_u buf2[NUMBUFLEN]; 9256 int def = 1; 9257 int type = VIM_GENERIC; 9258 char_u *typestr; 9259 int error = FALSE; 9260 9261 message = get_tv_string_chk(&argvars[0]); 9262 if (message == NULL) 9263 error = TRUE; 9264 if (argvars[1].v_type != VAR_UNKNOWN) 9265 { 9266 buttons = get_tv_string_buf_chk(&argvars[1], buf); 9267 if (buttons == NULL) 9268 error = TRUE; 9269 if (argvars[2].v_type != VAR_UNKNOWN) 9270 { 9271 def = get_tv_number_chk(&argvars[2], &error); 9272 if (argvars[3].v_type != VAR_UNKNOWN) 9273 { 9274 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 9275 if (typestr == NULL) 9276 error = TRUE; 9277 else 9278 { 9279 switch (TOUPPER_ASC(*typestr)) 9280 { 9281 case 'E': type = VIM_ERROR; break; 9282 case 'Q': type = VIM_QUESTION; break; 9283 case 'I': type = VIM_INFO; break; 9284 case 'W': type = VIM_WARNING; break; 9285 case 'G': type = VIM_GENERIC; break; 9286 } 9287 } 9288 } 9289 } 9290 } 9291 9292 if (buttons == NULL || *buttons == NUL) 9293 buttons = (char_u *)_("&Ok"); 9294 9295 if (!error) 9296 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 9297 def, NULL); 9298 #endif 9299 } 9300 9301 /* 9302 * "copy()" function 9303 */ 9304 static void 9305 f_copy(argvars, rettv) 9306 typval_T *argvars; 9307 typval_T *rettv; 9308 { 9309 item_copy(&argvars[0], rettv, FALSE, 0); 9310 } 9311 9312 #ifdef FEAT_FLOAT 9313 /* 9314 * "cos()" function 9315 */ 9316 static void 9317 f_cos(argvars, rettv) 9318 typval_T *argvars; 9319 typval_T *rettv; 9320 { 9321 float_T f; 9322 9323 rettv->v_type = VAR_FLOAT; 9324 if (get_float_arg(argvars, &f) == OK) 9325 rettv->vval.v_float = cos(f); 9326 else 9327 rettv->vval.v_float = 0.0; 9328 } 9329 9330 /* 9331 * "cosh()" function 9332 */ 9333 static void 9334 f_cosh(argvars, rettv) 9335 typval_T *argvars; 9336 typval_T *rettv; 9337 { 9338 float_T f; 9339 9340 rettv->v_type = VAR_FLOAT; 9341 if (get_float_arg(argvars, &f) == OK) 9342 rettv->vval.v_float = cosh(f); 9343 else 9344 rettv->vval.v_float = 0.0; 9345 } 9346 #endif 9347 9348 /* 9349 * "count()" function 9350 */ 9351 static void 9352 f_count(argvars, rettv) 9353 typval_T *argvars; 9354 typval_T *rettv; 9355 { 9356 long n = 0; 9357 int ic = FALSE; 9358 9359 if (argvars[0].v_type == VAR_LIST) 9360 { 9361 listitem_T *li; 9362 list_T *l; 9363 long idx; 9364 9365 if ((l = argvars[0].vval.v_list) != NULL) 9366 { 9367 li = l->lv_first; 9368 if (argvars[2].v_type != VAR_UNKNOWN) 9369 { 9370 int error = FALSE; 9371 9372 ic = get_tv_number_chk(&argvars[2], &error); 9373 if (argvars[3].v_type != VAR_UNKNOWN) 9374 { 9375 idx = get_tv_number_chk(&argvars[3], &error); 9376 if (!error) 9377 { 9378 li = list_find(l, idx); 9379 if (li == NULL) 9380 EMSGN(_(e_listidx), idx); 9381 } 9382 } 9383 if (error) 9384 li = NULL; 9385 } 9386 9387 for ( ; li != NULL; li = li->li_next) 9388 if (tv_equal(&li->li_tv, &argvars[1], ic)) 9389 ++n; 9390 } 9391 } 9392 else if (argvars[0].v_type == VAR_DICT) 9393 { 9394 int todo; 9395 dict_T *d; 9396 hashitem_T *hi; 9397 9398 if ((d = argvars[0].vval.v_dict) != NULL) 9399 { 9400 int error = FALSE; 9401 9402 if (argvars[2].v_type != VAR_UNKNOWN) 9403 { 9404 ic = get_tv_number_chk(&argvars[2], &error); 9405 if (argvars[3].v_type != VAR_UNKNOWN) 9406 EMSG(_(e_invarg)); 9407 } 9408 9409 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 9410 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 9411 { 9412 if (!HASHITEM_EMPTY(hi)) 9413 { 9414 --todo; 9415 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 9416 ++n; 9417 } 9418 } 9419 } 9420 } 9421 else 9422 EMSG2(_(e_listdictarg), "count()"); 9423 rettv->vval.v_number = n; 9424 } 9425 9426 /* 9427 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 9428 * 9429 * Checks the existence of a cscope connection. 9430 */ 9431 static void 9432 f_cscope_connection(argvars, rettv) 9433 typval_T *argvars UNUSED; 9434 typval_T *rettv UNUSED; 9435 { 9436 #ifdef FEAT_CSCOPE 9437 int num = 0; 9438 char_u *dbpath = NULL; 9439 char_u *prepend = NULL; 9440 char_u buf[NUMBUFLEN]; 9441 9442 if (argvars[0].v_type != VAR_UNKNOWN 9443 && argvars[1].v_type != VAR_UNKNOWN) 9444 { 9445 num = (int)get_tv_number(&argvars[0]); 9446 dbpath = get_tv_string(&argvars[1]); 9447 if (argvars[2].v_type != VAR_UNKNOWN) 9448 prepend = get_tv_string_buf(&argvars[2], buf); 9449 } 9450 9451 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 9452 #endif 9453 } 9454 9455 /* 9456 * "cursor(lnum, col)" function 9457 * 9458 * Moves the cursor to the specified line and column. 9459 * Returns 0 when the position could be set, -1 otherwise. 9460 */ 9461 static void 9462 f_cursor(argvars, rettv) 9463 typval_T *argvars; 9464 typval_T *rettv; 9465 { 9466 long line, col; 9467 #ifdef FEAT_VIRTUALEDIT 9468 long coladd = 0; 9469 #endif 9470 9471 rettv->vval.v_number = -1; 9472 if (argvars[1].v_type == VAR_UNKNOWN) 9473 { 9474 pos_T pos; 9475 9476 if (list2fpos(argvars, &pos, NULL) == FAIL) 9477 return; 9478 line = pos.lnum; 9479 col = pos.col; 9480 #ifdef FEAT_VIRTUALEDIT 9481 coladd = pos.coladd; 9482 #endif 9483 } 9484 else 9485 { 9486 line = get_tv_lnum(argvars); 9487 col = get_tv_number_chk(&argvars[1], NULL); 9488 #ifdef FEAT_VIRTUALEDIT 9489 if (argvars[2].v_type != VAR_UNKNOWN) 9490 coladd = get_tv_number_chk(&argvars[2], NULL); 9491 #endif 9492 } 9493 if (line < 0 || col < 0 9494 #ifdef FEAT_VIRTUALEDIT 9495 || coladd < 0 9496 #endif 9497 ) 9498 return; /* type error; errmsg already given */ 9499 if (line > 0) 9500 curwin->w_cursor.lnum = line; 9501 if (col > 0) 9502 curwin->w_cursor.col = col - 1; 9503 #ifdef FEAT_VIRTUALEDIT 9504 curwin->w_cursor.coladd = coladd; 9505 #endif 9506 9507 /* Make sure the cursor is in a valid position. */ 9508 check_cursor(); 9509 #ifdef FEAT_MBYTE 9510 /* Correct cursor for multi-byte character. */ 9511 if (has_mbyte) 9512 mb_adjust_cursor(); 9513 #endif 9514 9515 curwin->w_set_curswant = TRUE; 9516 rettv->vval.v_number = 0; 9517 } 9518 9519 /* 9520 * "deepcopy()" function 9521 */ 9522 static void 9523 f_deepcopy(argvars, rettv) 9524 typval_T *argvars; 9525 typval_T *rettv; 9526 { 9527 int noref = 0; 9528 9529 if (argvars[1].v_type != VAR_UNKNOWN) 9530 noref = get_tv_number_chk(&argvars[1], NULL); 9531 if (noref < 0 || noref > 1) 9532 EMSG(_(e_invarg)); 9533 else 9534 { 9535 current_copyID += COPYID_INC; 9536 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0); 9537 } 9538 } 9539 9540 /* 9541 * "delete()" function 9542 */ 9543 static void 9544 f_delete(argvars, rettv) 9545 typval_T *argvars; 9546 typval_T *rettv; 9547 { 9548 if (check_restricted() || check_secure()) 9549 rettv->vval.v_number = -1; 9550 else 9551 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 9552 } 9553 9554 /* 9555 * "did_filetype()" function 9556 */ 9557 static void 9558 f_did_filetype(argvars, rettv) 9559 typval_T *argvars UNUSED; 9560 typval_T *rettv UNUSED; 9561 { 9562 #ifdef FEAT_AUTOCMD 9563 rettv->vval.v_number = did_filetype; 9564 #endif 9565 } 9566 9567 /* 9568 * "diff_filler()" function 9569 */ 9570 static void 9571 f_diff_filler(argvars, rettv) 9572 typval_T *argvars UNUSED; 9573 typval_T *rettv UNUSED; 9574 { 9575 #ifdef FEAT_DIFF 9576 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 9577 #endif 9578 } 9579 9580 /* 9581 * "diff_hlID()" function 9582 */ 9583 static void 9584 f_diff_hlID(argvars, rettv) 9585 typval_T *argvars UNUSED; 9586 typval_T *rettv UNUSED; 9587 { 9588 #ifdef FEAT_DIFF 9589 linenr_T lnum = get_tv_lnum(argvars); 9590 static linenr_T prev_lnum = 0; 9591 static int changedtick = 0; 9592 static int fnum = 0; 9593 static int change_start = 0; 9594 static int change_end = 0; 9595 static hlf_T hlID = (hlf_T)0; 9596 int filler_lines; 9597 int col; 9598 9599 if (lnum < 0) /* ignore type error in {lnum} arg */ 9600 lnum = 0; 9601 if (lnum != prev_lnum 9602 || changedtick != curbuf->b_changedtick 9603 || fnum != curbuf->b_fnum) 9604 { 9605 /* New line, buffer, change: need to get the values. */ 9606 filler_lines = diff_check(curwin, lnum); 9607 if (filler_lines < 0) 9608 { 9609 if (filler_lines == -1) 9610 { 9611 change_start = MAXCOL; 9612 change_end = -1; 9613 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 9614 hlID = HLF_ADD; /* added line */ 9615 else 9616 hlID = HLF_CHD; /* changed line */ 9617 } 9618 else 9619 hlID = HLF_ADD; /* added line */ 9620 } 9621 else 9622 hlID = (hlf_T)0; 9623 prev_lnum = lnum; 9624 changedtick = curbuf->b_changedtick; 9625 fnum = curbuf->b_fnum; 9626 } 9627 9628 if (hlID == HLF_CHD || hlID == HLF_TXD) 9629 { 9630 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 9631 if (col >= change_start && col <= change_end) 9632 hlID = HLF_TXD; /* changed text */ 9633 else 9634 hlID = HLF_CHD; /* changed line */ 9635 } 9636 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 9637 #endif 9638 } 9639 9640 /* 9641 * "empty({expr})" function 9642 */ 9643 static void 9644 f_empty(argvars, rettv) 9645 typval_T *argvars; 9646 typval_T *rettv; 9647 { 9648 int n; 9649 9650 switch (argvars[0].v_type) 9651 { 9652 case VAR_STRING: 9653 case VAR_FUNC: 9654 n = argvars[0].vval.v_string == NULL 9655 || *argvars[0].vval.v_string == NUL; 9656 break; 9657 case VAR_NUMBER: 9658 n = argvars[0].vval.v_number == 0; 9659 break; 9660 #ifdef FEAT_FLOAT 9661 case VAR_FLOAT: 9662 n = argvars[0].vval.v_float == 0.0; 9663 break; 9664 #endif 9665 case VAR_LIST: 9666 n = argvars[0].vval.v_list == NULL 9667 || argvars[0].vval.v_list->lv_first == NULL; 9668 break; 9669 case VAR_DICT: 9670 n = argvars[0].vval.v_dict == NULL 9671 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 9672 break; 9673 default: 9674 EMSG2(_(e_intern2), "f_empty()"); 9675 n = 0; 9676 } 9677 9678 rettv->vval.v_number = n; 9679 } 9680 9681 /* 9682 * "escape({string}, {chars})" function 9683 */ 9684 static void 9685 f_escape(argvars, rettv) 9686 typval_T *argvars; 9687 typval_T *rettv; 9688 { 9689 char_u buf[NUMBUFLEN]; 9690 9691 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 9692 get_tv_string_buf(&argvars[1], buf)); 9693 rettv->v_type = VAR_STRING; 9694 } 9695 9696 /* 9697 * "eval()" function 9698 */ 9699 static void 9700 f_eval(argvars, rettv) 9701 typval_T *argvars; 9702 typval_T *rettv; 9703 { 9704 char_u *s; 9705 9706 s = get_tv_string_chk(&argvars[0]); 9707 if (s != NULL) 9708 s = skipwhite(s); 9709 9710 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 9711 { 9712 rettv->v_type = VAR_NUMBER; 9713 rettv->vval.v_number = 0; 9714 } 9715 else if (*s != NUL) 9716 EMSG(_(e_trailing)); 9717 } 9718 9719 /* 9720 * "eventhandler()" function 9721 */ 9722 static void 9723 f_eventhandler(argvars, rettv) 9724 typval_T *argvars UNUSED; 9725 typval_T *rettv; 9726 { 9727 rettv->vval.v_number = vgetc_busy; 9728 } 9729 9730 /* 9731 * "executable()" function 9732 */ 9733 static void 9734 f_executable(argvars, rettv) 9735 typval_T *argvars; 9736 typval_T *rettv; 9737 { 9738 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 9739 } 9740 9741 /* 9742 * "exists()" function 9743 */ 9744 static void 9745 f_exists(argvars, rettv) 9746 typval_T *argvars; 9747 typval_T *rettv; 9748 { 9749 char_u *p; 9750 char_u *name; 9751 int n = FALSE; 9752 int len = 0; 9753 9754 no_autoload = TRUE; 9755 9756 p = get_tv_string(&argvars[0]); 9757 if (*p == '$') /* environment variable */ 9758 { 9759 /* first try "normal" environment variables (fast) */ 9760 if (mch_getenv(p + 1) != NULL) 9761 n = TRUE; 9762 else 9763 { 9764 /* try expanding things like $VIM and ${HOME} */ 9765 p = expand_env_save(p); 9766 if (p != NULL && *p != '$') 9767 n = TRUE; 9768 vim_free(p); 9769 } 9770 } 9771 else if (*p == '&' || *p == '+') /* option */ 9772 { 9773 n = (get_option_tv(&p, NULL, TRUE) == OK); 9774 if (*skipwhite(p) != NUL) 9775 n = FALSE; /* trailing garbage */ 9776 } 9777 else if (*p == '*') /* internal or user defined function */ 9778 { 9779 n = function_exists(p + 1); 9780 } 9781 else if (*p == ':') 9782 { 9783 n = cmd_exists(p + 1); 9784 } 9785 else if (*p == '#') 9786 { 9787 #ifdef FEAT_AUTOCMD 9788 if (p[1] == '#') 9789 n = autocmd_supported(p + 2); 9790 else 9791 n = au_exists(p + 1); 9792 #endif 9793 } 9794 else /* internal variable */ 9795 { 9796 char_u *tofree; 9797 typval_T tv; 9798 9799 /* get_name_len() takes care of expanding curly braces */ 9800 name = p; 9801 len = get_name_len(&p, &tofree, TRUE, FALSE); 9802 if (len > 0) 9803 { 9804 if (tofree != NULL) 9805 name = tofree; 9806 n = (get_var_tv(name, len, &tv, FALSE) == OK); 9807 if (n) 9808 { 9809 /* handle d.key, l[idx], f(expr) */ 9810 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 9811 if (n) 9812 clear_tv(&tv); 9813 } 9814 } 9815 if (*p != NUL) 9816 n = FALSE; 9817 9818 vim_free(tofree); 9819 } 9820 9821 rettv->vval.v_number = n; 9822 9823 no_autoload = FALSE; 9824 } 9825 9826 #ifdef FEAT_FLOAT 9827 /* 9828 * "exp()" function 9829 */ 9830 static void 9831 f_exp(argvars, rettv) 9832 typval_T *argvars; 9833 typval_T *rettv; 9834 { 9835 float_T f; 9836 9837 rettv->v_type = VAR_FLOAT; 9838 if (get_float_arg(argvars, &f) == OK) 9839 rettv->vval.v_float = exp(f); 9840 else 9841 rettv->vval.v_float = 0.0; 9842 } 9843 #endif 9844 9845 /* 9846 * "expand()" function 9847 */ 9848 static void 9849 f_expand(argvars, rettv) 9850 typval_T *argvars; 9851 typval_T *rettv; 9852 { 9853 char_u *s; 9854 int len; 9855 char_u *errormsg; 9856 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 9857 expand_T xpc; 9858 int error = FALSE; 9859 9860 rettv->v_type = VAR_STRING; 9861 s = get_tv_string(&argvars[0]); 9862 if (*s == '%' || *s == '#' || *s == '<') 9863 { 9864 ++emsg_off; 9865 rettv->vval.v_string = eval_vars(s, s, &len, NULL, &errormsg, NULL); 9866 --emsg_off; 9867 } 9868 else 9869 { 9870 /* When the optional second argument is non-zero, don't remove matches 9871 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 9872 if (argvars[1].v_type != VAR_UNKNOWN 9873 && get_tv_number_chk(&argvars[1], &error)) 9874 flags |= WILD_KEEP_ALL; 9875 if (!error) 9876 { 9877 ExpandInit(&xpc); 9878 xpc.xp_context = EXPAND_FILES; 9879 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 9880 } 9881 else 9882 rettv->vval.v_string = NULL; 9883 } 9884 } 9885 9886 /* 9887 * "extend(list, list [, idx])" function 9888 * "extend(dict, dict [, action])" function 9889 */ 9890 static void 9891 f_extend(argvars, rettv) 9892 typval_T *argvars; 9893 typval_T *rettv; 9894 { 9895 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 9896 { 9897 list_T *l1, *l2; 9898 listitem_T *item; 9899 long before; 9900 int error = FALSE; 9901 9902 l1 = argvars[0].vval.v_list; 9903 l2 = argvars[1].vval.v_list; 9904 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 9905 && l2 != NULL) 9906 { 9907 if (argvars[2].v_type != VAR_UNKNOWN) 9908 { 9909 before = get_tv_number_chk(&argvars[2], &error); 9910 if (error) 9911 return; /* type error; errmsg already given */ 9912 9913 if (before == l1->lv_len) 9914 item = NULL; 9915 else 9916 { 9917 item = list_find(l1, before); 9918 if (item == NULL) 9919 { 9920 EMSGN(_(e_listidx), before); 9921 return; 9922 } 9923 } 9924 } 9925 else 9926 item = NULL; 9927 list_extend(l1, l2, item); 9928 9929 copy_tv(&argvars[0], rettv); 9930 } 9931 } 9932 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 9933 { 9934 dict_T *d1, *d2; 9935 dictitem_T *di1; 9936 char_u *action; 9937 int i; 9938 hashitem_T *hi2; 9939 int todo; 9940 9941 d1 = argvars[0].vval.v_dict; 9942 d2 = argvars[1].vval.v_dict; 9943 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 9944 && d2 != NULL) 9945 { 9946 /* Check the third argument. */ 9947 if (argvars[2].v_type != VAR_UNKNOWN) 9948 { 9949 static char *(av[]) = {"keep", "force", "error"}; 9950 9951 action = get_tv_string_chk(&argvars[2]); 9952 if (action == NULL) 9953 return; /* type error; errmsg already given */ 9954 for (i = 0; i < 3; ++i) 9955 if (STRCMP(action, av[i]) == 0) 9956 break; 9957 if (i == 3) 9958 { 9959 EMSG2(_(e_invarg2), action); 9960 return; 9961 } 9962 } 9963 else 9964 action = (char_u *)"force"; 9965 9966 /* Go over all entries in the second dict and add them to the 9967 * first dict. */ 9968 todo = (int)d2->dv_hashtab.ht_used; 9969 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 9970 { 9971 if (!HASHITEM_EMPTY(hi2)) 9972 { 9973 --todo; 9974 di1 = dict_find(d1, hi2->hi_key, -1); 9975 if (di1 == NULL) 9976 { 9977 di1 = dictitem_copy(HI2DI(hi2)); 9978 if (di1 != NULL && dict_add(d1, di1) == FAIL) 9979 dictitem_free(di1); 9980 } 9981 else if (*action == 'e') 9982 { 9983 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 9984 break; 9985 } 9986 else if (*action == 'f') 9987 { 9988 clear_tv(&di1->di_tv); 9989 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 9990 } 9991 } 9992 } 9993 9994 copy_tv(&argvars[0], rettv); 9995 } 9996 } 9997 else 9998 EMSG2(_(e_listdictarg), "extend()"); 9999 } 10000 10001 /* 10002 * "feedkeys()" function 10003 */ 10004 static void 10005 f_feedkeys(argvars, rettv) 10006 typval_T *argvars; 10007 typval_T *rettv UNUSED; 10008 { 10009 int remap = TRUE; 10010 char_u *keys, *flags; 10011 char_u nbuf[NUMBUFLEN]; 10012 int typed = FALSE; 10013 char_u *keys_esc; 10014 10015 /* This is not allowed in the sandbox. If the commands would still be 10016 * executed in the sandbox it would be OK, but it probably happens later, 10017 * when "sandbox" is no longer set. */ 10018 if (check_secure()) 10019 return; 10020 10021 keys = get_tv_string(&argvars[0]); 10022 if (*keys != NUL) 10023 { 10024 if (argvars[1].v_type != VAR_UNKNOWN) 10025 { 10026 flags = get_tv_string_buf(&argvars[1], nbuf); 10027 for ( ; *flags != NUL; ++flags) 10028 { 10029 switch (*flags) 10030 { 10031 case 'n': remap = FALSE; break; 10032 case 'm': remap = TRUE; break; 10033 case 't': typed = TRUE; break; 10034 } 10035 } 10036 } 10037 10038 /* Need to escape K_SPECIAL and CSI before putting the string in the 10039 * typeahead buffer. */ 10040 keys_esc = vim_strsave_escape_csi(keys); 10041 if (keys_esc != NULL) 10042 { 10043 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 10044 typebuf.tb_len, !typed, FALSE); 10045 vim_free(keys_esc); 10046 if (vgetc_busy) 10047 typebuf_was_filled = TRUE; 10048 } 10049 } 10050 } 10051 10052 /* 10053 * "filereadable()" function 10054 */ 10055 static void 10056 f_filereadable(argvars, rettv) 10057 typval_T *argvars; 10058 typval_T *rettv; 10059 { 10060 int fd; 10061 char_u *p; 10062 int n; 10063 10064 #ifndef O_NONBLOCK 10065 # define O_NONBLOCK 0 10066 #endif 10067 p = get_tv_string(&argvars[0]); 10068 if (*p && !mch_isdir(p) && (fd = mch_open((char *)p, 10069 O_RDONLY | O_NONBLOCK, 0)) >= 0) 10070 { 10071 n = TRUE; 10072 close(fd); 10073 } 10074 else 10075 n = FALSE; 10076 10077 rettv->vval.v_number = n; 10078 } 10079 10080 /* 10081 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 10082 * rights to write into. 10083 */ 10084 static void 10085 f_filewritable(argvars, rettv) 10086 typval_T *argvars; 10087 typval_T *rettv; 10088 { 10089 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 10090 } 10091 10092 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what)); 10093 10094 static void 10095 findfilendir(argvars, rettv, find_what) 10096 typval_T *argvars; 10097 typval_T *rettv; 10098 int find_what; 10099 { 10100 #ifdef FEAT_SEARCHPATH 10101 char_u *fname; 10102 char_u *fresult = NULL; 10103 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 10104 char_u *p; 10105 char_u pathbuf[NUMBUFLEN]; 10106 int count = 1; 10107 int first = TRUE; 10108 int error = FALSE; 10109 #endif 10110 10111 rettv->vval.v_string = NULL; 10112 rettv->v_type = VAR_STRING; 10113 10114 #ifdef FEAT_SEARCHPATH 10115 fname = get_tv_string(&argvars[0]); 10116 10117 if (argvars[1].v_type != VAR_UNKNOWN) 10118 { 10119 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 10120 if (p == NULL) 10121 error = TRUE; 10122 else 10123 { 10124 if (*p != NUL) 10125 path = p; 10126 10127 if (argvars[2].v_type != VAR_UNKNOWN) 10128 count = get_tv_number_chk(&argvars[2], &error); 10129 } 10130 } 10131 10132 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 10133 error = TRUE; 10134 10135 if (*fname != NUL && !error) 10136 { 10137 do 10138 { 10139 if (rettv->v_type == VAR_STRING) 10140 vim_free(fresult); 10141 fresult = find_file_in_path_option(first ? fname : NULL, 10142 first ? (int)STRLEN(fname) : 0, 10143 0, first, path, 10144 find_what, 10145 curbuf->b_ffname, 10146 find_what == FINDFILE_DIR 10147 ? (char_u *)"" : curbuf->b_p_sua); 10148 first = FALSE; 10149 10150 if (fresult != NULL && rettv->v_type == VAR_LIST) 10151 list_append_string(rettv->vval.v_list, fresult, -1); 10152 10153 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 10154 } 10155 10156 if (rettv->v_type == VAR_STRING) 10157 rettv->vval.v_string = fresult; 10158 #endif 10159 } 10160 10161 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 10162 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 10163 10164 /* 10165 * Implementation of map() and filter(). 10166 */ 10167 static void 10168 filter_map(argvars, rettv, map) 10169 typval_T *argvars; 10170 typval_T *rettv; 10171 int map; 10172 { 10173 char_u buf[NUMBUFLEN]; 10174 char_u *expr; 10175 listitem_T *li, *nli; 10176 list_T *l = NULL; 10177 dictitem_T *di; 10178 hashtab_T *ht; 10179 hashitem_T *hi; 10180 dict_T *d = NULL; 10181 typval_T save_val; 10182 typval_T save_key; 10183 int rem; 10184 int todo; 10185 char_u *ermsg = map ? (char_u *)"map()" : (char_u *)"filter()"; 10186 int save_did_emsg; 10187 int idx = 0; 10188 10189 if (argvars[0].v_type == VAR_LIST) 10190 { 10191 if ((l = argvars[0].vval.v_list) == NULL 10192 || (map && tv_check_lock(l->lv_lock, ermsg))) 10193 return; 10194 } 10195 else if (argvars[0].v_type == VAR_DICT) 10196 { 10197 if ((d = argvars[0].vval.v_dict) == NULL 10198 || (map && tv_check_lock(d->dv_lock, ermsg))) 10199 return; 10200 } 10201 else 10202 { 10203 EMSG2(_(e_listdictarg), ermsg); 10204 return; 10205 } 10206 10207 expr = get_tv_string_buf_chk(&argvars[1], buf); 10208 /* On type errors, the preceding call has already displayed an error 10209 * message. Avoid a misleading error message for an empty string that 10210 * was not passed as argument. */ 10211 if (expr != NULL) 10212 { 10213 prepare_vimvar(VV_VAL, &save_val); 10214 expr = skipwhite(expr); 10215 10216 /* We reset "did_emsg" to be able to detect whether an error 10217 * occurred during evaluation of the expression. */ 10218 save_did_emsg = did_emsg; 10219 did_emsg = FALSE; 10220 10221 prepare_vimvar(VV_KEY, &save_key); 10222 if (argvars[0].v_type == VAR_DICT) 10223 { 10224 vimvars[VV_KEY].vv_type = VAR_STRING; 10225 10226 ht = &d->dv_hashtab; 10227 hash_lock(ht); 10228 todo = (int)ht->ht_used; 10229 for (hi = ht->ht_array; todo > 0; ++hi) 10230 { 10231 if (!HASHITEM_EMPTY(hi)) 10232 { 10233 --todo; 10234 di = HI2DI(hi); 10235 if (tv_check_lock(di->di_tv.v_lock, ermsg)) 10236 break; 10237 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 10238 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL 10239 || did_emsg) 10240 break; 10241 if (!map && rem) 10242 dictitem_remove(d, di); 10243 clear_tv(&vimvars[VV_KEY].vv_tv); 10244 } 10245 } 10246 hash_unlock(ht); 10247 } 10248 else 10249 { 10250 vimvars[VV_KEY].vv_type = VAR_NUMBER; 10251 10252 for (li = l->lv_first; li != NULL; li = nli) 10253 { 10254 if (tv_check_lock(li->li_tv.v_lock, ermsg)) 10255 break; 10256 nli = li->li_next; 10257 vimvars[VV_KEY].vv_nr = idx; 10258 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 10259 || did_emsg) 10260 break; 10261 if (!map && rem) 10262 listitem_remove(l, li); 10263 ++idx; 10264 } 10265 } 10266 10267 restore_vimvar(VV_KEY, &save_key); 10268 restore_vimvar(VV_VAL, &save_val); 10269 10270 did_emsg |= save_did_emsg; 10271 } 10272 10273 copy_tv(&argvars[0], rettv); 10274 } 10275 10276 static int 10277 filter_map_one(tv, expr, map, remp) 10278 typval_T *tv; 10279 char_u *expr; 10280 int map; 10281 int *remp; 10282 { 10283 typval_T rettv; 10284 char_u *s; 10285 int retval = FAIL; 10286 10287 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 10288 s = expr; 10289 if (eval1(&s, &rettv, TRUE) == FAIL) 10290 goto theend; 10291 if (*s != NUL) /* check for trailing chars after expr */ 10292 { 10293 EMSG2(_(e_invexpr2), s); 10294 goto theend; 10295 } 10296 if (map) 10297 { 10298 /* map(): replace the list item value */ 10299 clear_tv(tv); 10300 rettv.v_lock = 0; 10301 *tv = rettv; 10302 } 10303 else 10304 { 10305 int error = FALSE; 10306 10307 /* filter(): when expr is zero remove the item */ 10308 *remp = (get_tv_number_chk(&rettv, &error) == 0); 10309 clear_tv(&rettv); 10310 /* On type error, nothing has been removed; return FAIL to stop the 10311 * loop. The error message was given by get_tv_number_chk(). */ 10312 if (error) 10313 goto theend; 10314 } 10315 retval = OK; 10316 theend: 10317 clear_tv(&vimvars[VV_VAL].vv_tv); 10318 return retval; 10319 } 10320 10321 /* 10322 * "filter()" function 10323 */ 10324 static void 10325 f_filter(argvars, rettv) 10326 typval_T *argvars; 10327 typval_T *rettv; 10328 { 10329 filter_map(argvars, rettv, FALSE); 10330 } 10331 10332 /* 10333 * "finddir({fname}[, {path}[, {count}]])" function 10334 */ 10335 static void 10336 f_finddir(argvars, rettv) 10337 typval_T *argvars; 10338 typval_T *rettv; 10339 { 10340 findfilendir(argvars, rettv, FINDFILE_DIR); 10341 } 10342 10343 /* 10344 * "findfile({fname}[, {path}[, {count}]])" function 10345 */ 10346 static void 10347 f_findfile(argvars, rettv) 10348 typval_T *argvars; 10349 typval_T *rettv; 10350 { 10351 findfilendir(argvars, rettv, FINDFILE_FILE); 10352 } 10353 10354 #ifdef FEAT_FLOAT 10355 /* 10356 * "float2nr({float})" function 10357 */ 10358 static void 10359 f_float2nr(argvars, rettv) 10360 typval_T *argvars; 10361 typval_T *rettv; 10362 { 10363 float_T f; 10364 10365 if (get_float_arg(argvars, &f) == OK) 10366 { 10367 if (f < -0x7fffffff) 10368 rettv->vval.v_number = -0x7fffffff; 10369 else if (f > 0x7fffffff) 10370 rettv->vval.v_number = 0x7fffffff; 10371 else 10372 rettv->vval.v_number = (varnumber_T)f; 10373 } 10374 } 10375 10376 /* 10377 * "floor({float})" function 10378 */ 10379 static void 10380 f_floor(argvars, rettv) 10381 typval_T *argvars; 10382 typval_T *rettv; 10383 { 10384 float_T f; 10385 10386 rettv->v_type = VAR_FLOAT; 10387 if (get_float_arg(argvars, &f) == OK) 10388 rettv->vval.v_float = floor(f); 10389 else 10390 rettv->vval.v_float = 0.0; 10391 } 10392 10393 /* 10394 * "fmod()" function 10395 */ 10396 static void 10397 f_fmod(argvars, rettv) 10398 typval_T *argvars; 10399 typval_T *rettv; 10400 { 10401 float_T fx, fy; 10402 10403 rettv->v_type = VAR_FLOAT; 10404 if (get_float_arg(argvars, &fx) == OK 10405 && get_float_arg(&argvars[1], &fy) == OK) 10406 rettv->vval.v_float = fmod(fx, fy); 10407 else 10408 rettv->vval.v_float = 0.0; 10409 } 10410 #endif 10411 10412 /* 10413 * "fnameescape({string})" function 10414 */ 10415 static void 10416 f_fnameescape(argvars, rettv) 10417 typval_T *argvars; 10418 typval_T *rettv; 10419 { 10420 rettv->vval.v_string = vim_strsave_fnameescape( 10421 get_tv_string(&argvars[0]), FALSE); 10422 rettv->v_type = VAR_STRING; 10423 } 10424 10425 /* 10426 * "fnamemodify({fname}, {mods})" function 10427 */ 10428 static void 10429 f_fnamemodify(argvars, rettv) 10430 typval_T *argvars; 10431 typval_T *rettv; 10432 { 10433 char_u *fname; 10434 char_u *mods; 10435 int usedlen = 0; 10436 int len; 10437 char_u *fbuf = NULL; 10438 char_u buf[NUMBUFLEN]; 10439 10440 fname = get_tv_string_chk(&argvars[0]); 10441 mods = get_tv_string_buf_chk(&argvars[1], buf); 10442 if (fname == NULL || mods == NULL) 10443 fname = NULL; 10444 else 10445 { 10446 len = (int)STRLEN(fname); 10447 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 10448 } 10449 10450 rettv->v_type = VAR_STRING; 10451 if (fname == NULL) 10452 rettv->vval.v_string = NULL; 10453 else 10454 rettv->vval.v_string = vim_strnsave(fname, len); 10455 vim_free(fbuf); 10456 } 10457 10458 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 10459 10460 /* 10461 * "foldclosed()" function 10462 */ 10463 static void 10464 foldclosed_both(argvars, rettv, end) 10465 typval_T *argvars; 10466 typval_T *rettv; 10467 int end; 10468 { 10469 #ifdef FEAT_FOLDING 10470 linenr_T lnum; 10471 linenr_T first, last; 10472 10473 lnum = get_tv_lnum(argvars); 10474 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10475 { 10476 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 10477 { 10478 if (end) 10479 rettv->vval.v_number = (varnumber_T)last; 10480 else 10481 rettv->vval.v_number = (varnumber_T)first; 10482 return; 10483 } 10484 } 10485 #endif 10486 rettv->vval.v_number = -1; 10487 } 10488 10489 /* 10490 * "foldclosed()" function 10491 */ 10492 static void 10493 f_foldclosed(argvars, rettv) 10494 typval_T *argvars; 10495 typval_T *rettv; 10496 { 10497 foldclosed_both(argvars, rettv, FALSE); 10498 } 10499 10500 /* 10501 * "foldclosedend()" function 10502 */ 10503 static void 10504 f_foldclosedend(argvars, rettv) 10505 typval_T *argvars; 10506 typval_T *rettv; 10507 { 10508 foldclosed_both(argvars, rettv, TRUE); 10509 } 10510 10511 /* 10512 * "foldlevel()" function 10513 */ 10514 static void 10515 f_foldlevel(argvars, rettv) 10516 typval_T *argvars; 10517 typval_T *rettv; 10518 { 10519 #ifdef FEAT_FOLDING 10520 linenr_T lnum; 10521 10522 lnum = get_tv_lnum(argvars); 10523 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10524 rettv->vval.v_number = foldLevel(lnum); 10525 #endif 10526 } 10527 10528 /* 10529 * "foldtext()" function 10530 */ 10531 static void 10532 f_foldtext(argvars, rettv) 10533 typval_T *argvars UNUSED; 10534 typval_T *rettv; 10535 { 10536 #ifdef FEAT_FOLDING 10537 linenr_T lnum; 10538 char_u *s; 10539 char_u *r; 10540 int len; 10541 char *txt; 10542 #endif 10543 10544 rettv->v_type = VAR_STRING; 10545 rettv->vval.v_string = NULL; 10546 #ifdef FEAT_FOLDING 10547 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 10548 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 10549 <= curbuf->b_ml.ml_line_count 10550 && vimvars[VV_FOLDDASHES].vv_str != NULL) 10551 { 10552 /* Find first non-empty line in the fold. */ 10553 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 10554 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 10555 { 10556 if (!linewhite(lnum)) 10557 break; 10558 ++lnum; 10559 } 10560 10561 /* Find interesting text in this line. */ 10562 s = skipwhite(ml_get(lnum)); 10563 /* skip C comment-start */ 10564 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 10565 { 10566 s = skipwhite(s + 2); 10567 if (*skipwhite(s) == NUL 10568 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 10569 { 10570 s = skipwhite(ml_get(lnum + 1)); 10571 if (*s == '*') 10572 s = skipwhite(s + 1); 10573 } 10574 } 10575 txt = _("+-%s%3ld lines: "); 10576 r = alloc((unsigned)(STRLEN(txt) 10577 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 10578 + 20 /* for %3ld */ 10579 + STRLEN(s))); /* concatenated */ 10580 if (r != NULL) 10581 { 10582 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 10583 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 10584 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 10585 len = (int)STRLEN(r); 10586 STRCAT(r, s); 10587 /* remove 'foldmarker' and 'commentstring' */ 10588 foldtext_cleanup(r + len); 10589 rettv->vval.v_string = r; 10590 } 10591 } 10592 #endif 10593 } 10594 10595 /* 10596 * "foldtextresult(lnum)" function 10597 */ 10598 static void 10599 f_foldtextresult(argvars, rettv) 10600 typval_T *argvars UNUSED; 10601 typval_T *rettv; 10602 { 10603 #ifdef FEAT_FOLDING 10604 linenr_T lnum; 10605 char_u *text; 10606 char_u buf[51]; 10607 foldinfo_T foldinfo; 10608 int fold_count; 10609 #endif 10610 10611 rettv->v_type = VAR_STRING; 10612 rettv->vval.v_string = NULL; 10613 #ifdef FEAT_FOLDING 10614 lnum = get_tv_lnum(argvars); 10615 /* treat illegal types and illegal string values for {lnum} the same */ 10616 if (lnum < 0) 10617 lnum = 0; 10618 fold_count = foldedCount(curwin, lnum, &foldinfo); 10619 if (fold_count > 0) 10620 { 10621 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 10622 &foldinfo, buf); 10623 if (text == buf) 10624 text = vim_strsave(text); 10625 rettv->vval.v_string = text; 10626 } 10627 #endif 10628 } 10629 10630 /* 10631 * "foreground()" function 10632 */ 10633 static void 10634 f_foreground(argvars, rettv) 10635 typval_T *argvars UNUSED; 10636 typval_T *rettv UNUSED; 10637 { 10638 #ifdef FEAT_GUI 10639 if (gui.in_use) 10640 gui_mch_set_foreground(); 10641 #else 10642 # ifdef WIN32 10643 win32_set_foreground(); 10644 # endif 10645 #endif 10646 } 10647 10648 /* 10649 * "function()" function 10650 */ 10651 static void 10652 f_function(argvars, rettv) 10653 typval_T *argvars; 10654 typval_T *rettv; 10655 { 10656 char_u *s; 10657 10658 s = get_tv_string(&argvars[0]); 10659 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 10660 EMSG2(_(e_invarg2), s); 10661 /* Don't check an autoload name for existence here. */ 10662 else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s)) 10663 EMSG2(_("E700: Unknown function: %s"), s); 10664 else 10665 { 10666 rettv->vval.v_string = vim_strsave(s); 10667 rettv->v_type = VAR_FUNC; 10668 } 10669 } 10670 10671 /* 10672 * "garbagecollect()" function 10673 */ 10674 static void 10675 f_garbagecollect(argvars, rettv) 10676 typval_T *argvars; 10677 typval_T *rettv UNUSED; 10678 { 10679 /* This is postponed until we are back at the toplevel, because we may be 10680 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ 10681 want_garbage_collect = TRUE; 10682 10683 if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1) 10684 garbage_collect_at_exit = TRUE; 10685 } 10686 10687 /* 10688 * "get()" function 10689 */ 10690 static void 10691 f_get(argvars, rettv) 10692 typval_T *argvars; 10693 typval_T *rettv; 10694 { 10695 listitem_T *li; 10696 list_T *l; 10697 dictitem_T *di; 10698 dict_T *d; 10699 typval_T *tv = NULL; 10700 10701 if (argvars[0].v_type == VAR_LIST) 10702 { 10703 if ((l = argvars[0].vval.v_list) != NULL) 10704 { 10705 int error = FALSE; 10706 10707 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 10708 if (!error && li != NULL) 10709 tv = &li->li_tv; 10710 } 10711 } 10712 else if (argvars[0].v_type == VAR_DICT) 10713 { 10714 if ((d = argvars[0].vval.v_dict) != NULL) 10715 { 10716 di = dict_find(d, get_tv_string(&argvars[1]), -1); 10717 if (di != NULL) 10718 tv = &di->di_tv; 10719 } 10720 } 10721 else 10722 EMSG2(_(e_listdictarg), "get()"); 10723 10724 if (tv == NULL) 10725 { 10726 if (argvars[2].v_type != VAR_UNKNOWN) 10727 copy_tv(&argvars[2], rettv); 10728 } 10729 else 10730 copy_tv(tv, rettv); 10731 } 10732 10733 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 10734 10735 /* 10736 * Get line or list of lines from buffer "buf" into "rettv". 10737 * Return a range (from start to end) of lines in rettv from the specified 10738 * buffer. 10739 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 10740 */ 10741 static void 10742 get_buffer_lines(buf, start, end, retlist, rettv) 10743 buf_T *buf; 10744 linenr_T start; 10745 linenr_T end; 10746 int retlist; 10747 typval_T *rettv; 10748 { 10749 char_u *p; 10750 10751 if (retlist && rettv_list_alloc(rettv) == FAIL) 10752 return; 10753 10754 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 10755 return; 10756 10757 if (!retlist) 10758 { 10759 if (start >= 1 && start <= buf->b_ml.ml_line_count) 10760 p = ml_get_buf(buf, start, FALSE); 10761 else 10762 p = (char_u *)""; 10763 10764 rettv->v_type = VAR_STRING; 10765 rettv->vval.v_string = vim_strsave(p); 10766 } 10767 else 10768 { 10769 if (end < start) 10770 return; 10771 10772 if (start < 1) 10773 start = 1; 10774 if (end > buf->b_ml.ml_line_count) 10775 end = buf->b_ml.ml_line_count; 10776 while (start <= end) 10777 if (list_append_string(rettv->vval.v_list, 10778 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 10779 break; 10780 } 10781 } 10782 10783 /* 10784 * "getbufline()" function 10785 */ 10786 static void 10787 f_getbufline(argvars, rettv) 10788 typval_T *argvars; 10789 typval_T *rettv; 10790 { 10791 linenr_T lnum; 10792 linenr_T end; 10793 buf_T *buf; 10794 10795 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 10796 ++emsg_off; 10797 buf = get_buf_tv(&argvars[0]); 10798 --emsg_off; 10799 10800 lnum = get_tv_lnum_buf(&argvars[1], buf); 10801 if (argvars[2].v_type == VAR_UNKNOWN) 10802 end = lnum; 10803 else 10804 end = get_tv_lnum_buf(&argvars[2], buf); 10805 10806 get_buffer_lines(buf, lnum, end, TRUE, rettv); 10807 } 10808 10809 /* 10810 * "getbufvar()" function 10811 */ 10812 static void 10813 f_getbufvar(argvars, rettv) 10814 typval_T *argvars; 10815 typval_T *rettv; 10816 { 10817 buf_T *buf; 10818 buf_T *save_curbuf; 10819 char_u *varname; 10820 dictitem_T *v; 10821 10822 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 10823 varname = get_tv_string_chk(&argvars[1]); 10824 ++emsg_off; 10825 buf = get_buf_tv(&argvars[0]); 10826 10827 rettv->v_type = VAR_STRING; 10828 rettv->vval.v_string = NULL; 10829 10830 if (buf != NULL && varname != NULL) 10831 { 10832 /* set curbuf to be our buf, temporarily */ 10833 save_curbuf = curbuf; 10834 curbuf = buf; 10835 10836 if (*varname == '&') /* buffer-local-option */ 10837 get_option_tv(&varname, rettv, TRUE); 10838 else 10839 { 10840 if (*varname == NUL) 10841 /* let getbufvar({nr}, "") return the "b:" dictionary. The 10842 * scope prefix before the NUL byte is required by 10843 * find_var_in_ht(). */ 10844 varname = (char_u *)"b:" + 2; 10845 /* look up the variable */ 10846 v = find_var_in_ht(&curbuf->b_vars.dv_hashtab, varname, FALSE); 10847 if (v != NULL) 10848 copy_tv(&v->di_tv, rettv); 10849 } 10850 10851 /* restore previous notion of curbuf */ 10852 curbuf = save_curbuf; 10853 } 10854 10855 --emsg_off; 10856 } 10857 10858 /* 10859 * "getchar()" function 10860 */ 10861 static void 10862 f_getchar(argvars, rettv) 10863 typval_T *argvars; 10864 typval_T *rettv; 10865 { 10866 varnumber_T n; 10867 int error = FALSE; 10868 10869 /* Position the cursor. Needed after a message that ends in a space. */ 10870 windgoto(msg_row, msg_col); 10871 10872 ++no_mapping; 10873 ++allow_keys; 10874 for (;;) 10875 { 10876 if (argvars[0].v_type == VAR_UNKNOWN) 10877 /* getchar(): blocking wait. */ 10878 n = safe_vgetc(); 10879 else if (get_tv_number_chk(&argvars[0], &error) == 1) 10880 /* getchar(1): only check if char avail */ 10881 n = vpeekc(); 10882 else if (error || vpeekc() == NUL) 10883 /* illegal argument or getchar(0) and no char avail: return zero */ 10884 n = 0; 10885 else 10886 /* getchar(0) and char avail: return char */ 10887 n = safe_vgetc(); 10888 if (n == K_IGNORE) 10889 continue; 10890 break; 10891 } 10892 --no_mapping; 10893 --allow_keys; 10894 10895 vimvars[VV_MOUSE_WIN].vv_nr = 0; 10896 vimvars[VV_MOUSE_LNUM].vv_nr = 0; 10897 vimvars[VV_MOUSE_COL].vv_nr = 0; 10898 10899 rettv->vval.v_number = n; 10900 if (IS_SPECIAL(n) || mod_mask != 0) 10901 { 10902 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 10903 int i = 0; 10904 10905 /* Turn a special key into three bytes, plus modifier. */ 10906 if (mod_mask != 0) 10907 { 10908 temp[i++] = K_SPECIAL; 10909 temp[i++] = KS_MODIFIER; 10910 temp[i++] = mod_mask; 10911 } 10912 if (IS_SPECIAL(n)) 10913 { 10914 temp[i++] = K_SPECIAL; 10915 temp[i++] = K_SECOND(n); 10916 temp[i++] = K_THIRD(n); 10917 } 10918 #ifdef FEAT_MBYTE 10919 else if (has_mbyte) 10920 i += (*mb_char2bytes)(n, temp + i); 10921 #endif 10922 else 10923 temp[i++] = n; 10924 temp[i++] = NUL; 10925 rettv->v_type = VAR_STRING; 10926 rettv->vval.v_string = vim_strsave(temp); 10927 10928 #ifdef FEAT_MOUSE 10929 if (n == K_LEFTMOUSE 10930 || n == K_LEFTMOUSE_NM 10931 || n == K_LEFTDRAG 10932 || n == K_LEFTRELEASE 10933 || n == K_LEFTRELEASE_NM 10934 || n == K_MIDDLEMOUSE 10935 || n == K_MIDDLEDRAG 10936 || n == K_MIDDLERELEASE 10937 || n == K_RIGHTMOUSE 10938 || n == K_RIGHTDRAG 10939 || n == K_RIGHTRELEASE 10940 || n == K_X1MOUSE 10941 || n == K_X1DRAG 10942 || n == K_X1RELEASE 10943 || n == K_X2MOUSE 10944 || n == K_X2DRAG 10945 || n == K_X2RELEASE 10946 || n == K_MOUSELEFT 10947 || n == K_MOUSERIGHT 10948 || n == K_MOUSEDOWN 10949 || n == K_MOUSEUP) 10950 { 10951 int row = mouse_row; 10952 int col = mouse_col; 10953 win_T *win; 10954 linenr_T lnum; 10955 # ifdef FEAT_WINDOWS 10956 win_T *wp; 10957 # endif 10958 int winnr = 1; 10959 10960 if (row >= 0 && col >= 0) 10961 { 10962 /* Find the window at the mouse coordinates and compute the 10963 * text position. */ 10964 win = mouse_find_win(&row, &col); 10965 (void)mouse_comp_pos(win, &row, &col, &lnum); 10966 # ifdef FEAT_WINDOWS 10967 for (wp = firstwin; wp != win; wp = wp->w_next) 10968 ++winnr; 10969 # endif 10970 vimvars[VV_MOUSE_WIN].vv_nr = winnr; 10971 vimvars[VV_MOUSE_LNUM].vv_nr = lnum; 10972 vimvars[VV_MOUSE_COL].vv_nr = col + 1; 10973 } 10974 } 10975 #endif 10976 } 10977 } 10978 10979 /* 10980 * "getcharmod()" function 10981 */ 10982 static void 10983 f_getcharmod(argvars, rettv) 10984 typval_T *argvars UNUSED; 10985 typval_T *rettv; 10986 { 10987 rettv->vval.v_number = mod_mask; 10988 } 10989 10990 /* 10991 * "getcmdline()" function 10992 */ 10993 static void 10994 f_getcmdline(argvars, rettv) 10995 typval_T *argvars UNUSED; 10996 typval_T *rettv; 10997 { 10998 rettv->v_type = VAR_STRING; 10999 rettv->vval.v_string = get_cmdline_str(); 11000 } 11001 11002 /* 11003 * "getcmdpos()" function 11004 */ 11005 static void 11006 f_getcmdpos(argvars, rettv) 11007 typval_T *argvars UNUSED; 11008 typval_T *rettv; 11009 { 11010 rettv->vval.v_number = get_cmdline_pos() + 1; 11011 } 11012 11013 /* 11014 * "getcmdtype()" function 11015 */ 11016 static void 11017 f_getcmdtype(argvars, rettv) 11018 typval_T *argvars UNUSED; 11019 typval_T *rettv; 11020 { 11021 rettv->v_type = VAR_STRING; 11022 rettv->vval.v_string = alloc(2); 11023 if (rettv->vval.v_string != NULL) 11024 { 11025 rettv->vval.v_string[0] = get_cmdline_type(); 11026 rettv->vval.v_string[1] = NUL; 11027 } 11028 } 11029 11030 /* 11031 * "getcwd()" function 11032 */ 11033 static void 11034 f_getcwd(argvars, rettv) 11035 typval_T *argvars UNUSED; 11036 typval_T *rettv; 11037 { 11038 char_u cwd[MAXPATHL]; 11039 11040 rettv->v_type = VAR_STRING; 11041 if (mch_dirname(cwd, MAXPATHL) == FAIL) 11042 rettv->vval.v_string = NULL; 11043 else 11044 { 11045 rettv->vval.v_string = vim_strsave(cwd); 11046 #ifdef BACKSLASH_IN_FILENAME 11047 if (rettv->vval.v_string != NULL) 11048 slash_adjust(rettv->vval.v_string); 11049 #endif 11050 } 11051 } 11052 11053 /* 11054 * "getfontname()" function 11055 */ 11056 static void 11057 f_getfontname(argvars, rettv) 11058 typval_T *argvars UNUSED; 11059 typval_T *rettv; 11060 { 11061 rettv->v_type = VAR_STRING; 11062 rettv->vval.v_string = NULL; 11063 #ifdef FEAT_GUI 11064 if (gui.in_use) 11065 { 11066 GuiFont font; 11067 char_u *name = NULL; 11068 11069 if (argvars[0].v_type == VAR_UNKNOWN) 11070 { 11071 /* Get the "Normal" font. Either the name saved by 11072 * hl_set_font_name() or from the font ID. */ 11073 font = gui.norm_font; 11074 name = hl_get_font_name(); 11075 } 11076 else 11077 { 11078 name = get_tv_string(&argvars[0]); 11079 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 11080 return; 11081 font = gui_mch_get_font(name, FALSE); 11082 if (font == NOFONT) 11083 return; /* Invalid font name, return empty string. */ 11084 } 11085 rettv->vval.v_string = gui_mch_get_fontname(font, name); 11086 if (argvars[0].v_type != VAR_UNKNOWN) 11087 gui_mch_free_font(font); 11088 } 11089 #endif 11090 } 11091 11092 /* 11093 * "getfperm({fname})" function 11094 */ 11095 static void 11096 f_getfperm(argvars, rettv) 11097 typval_T *argvars; 11098 typval_T *rettv; 11099 { 11100 char_u *fname; 11101 struct stat st; 11102 char_u *perm = NULL; 11103 char_u flags[] = "rwx"; 11104 int i; 11105 11106 fname = get_tv_string(&argvars[0]); 11107 11108 rettv->v_type = VAR_STRING; 11109 if (mch_stat((char *)fname, &st) >= 0) 11110 { 11111 perm = vim_strsave((char_u *)"---------"); 11112 if (perm != NULL) 11113 { 11114 for (i = 0; i < 9; i++) 11115 { 11116 if (st.st_mode & (1 << (8 - i))) 11117 perm[i] = flags[i % 3]; 11118 } 11119 } 11120 } 11121 rettv->vval.v_string = perm; 11122 } 11123 11124 /* 11125 * "getfsize({fname})" function 11126 */ 11127 static void 11128 f_getfsize(argvars, rettv) 11129 typval_T *argvars; 11130 typval_T *rettv; 11131 { 11132 char_u *fname; 11133 struct stat st; 11134 11135 fname = get_tv_string(&argvars[0]); 11136 11137 rettv->v_type = VAR_NUMBER; 11138 11139 if (mch_stat((char *)fname, &st) >= 0) 11140 { 11141 if (mch_isdir(fname)) 11142 rettv->vval.v_number = 0; 11143 else 11144 { 11145 rettv->vval.v_number = (varnumber_T)st.st_size; 11146 11147 /* non-perfect check for overflow */ 11148 if ((off_t)rettv->vval.v_number != (off_t)st.st_size) 11149 rettv->vval.v_number = -2; 11150 } 11151 } 11152 else 11153 rettv->vval.v_number = -1; 11154 } 11155 11156 /* 11157 * "getftime({fname})" function 11158 */ 11159 static void 11160 f_getftime(argvars, rettv) 11161 typval_T *argvars; 11162 typval_T *rettv; 11163 { 11164 char_u *fname; 11165 struct stat st; 11166 11167 fname = get_tv_string(&argvars[0]); 11168 11169 if (mch_stat((char *)fname, &st) >= 0) 11170 rettv->vval.v_number = (varnumber_T)st.st_mtime; 11171 else 11172 rettv->vval.v_number = -1; 11173 } 11174 11175 /* 11176 * "getftype({fname})" function 11177 */ 11178 static void 11179 f_getftype(argvars, rettv) 11180 typval_T *argvars; 11181 typval_T *rettv; 11182 { 11183 char_u *fname; 11184 struct stat st; 11185 char_u *type = NULL; 11186 char *t; 11187 11188 fname = get_tv_string(&argvars[0]); 11189 11190 rettv->v_type = VAR_STRING; 11191 if (mch_lstat((char *)fname, &st) >= 0) 11192 { 11193 #ifdef S_ISREG 11194 if (S_ISREG(st.st_mode)) 11195 t = "file"; 11196 else if (S_ISDIR(st.st_mode)) 11197 t = "dir"; 11198 # ifdef S_ISLNK 11199 else if (S_ISLNK(st.st_mode)) 11200 t = "link"; 11201 # endif 11202 # ifdef S_ISBLK 11203 else if (S_ISBLK(st.st_mode)) 11204 t = "bdev"; 11205 # endif 11206 # ifdef S_ISCHR 11207 else if (S_ISCHR(st.st_mode)) 11208 t = "cdev"; 11209 # endif 11210 # ifdef S_ISFIFO 11211 else if (S_ISFIFO(st.st_mode)) 11212 t = "fifo"; 11213 # endif 11214 # ifdef S_ISSOCK 11215 else if (S_ISSOCK(st.st_mode)) 11216 t = "fifo"; 11217 # endif 11218 else 11219 t = "other"; 11220 #else 11221 # ifdef S_IFMT 11222 switch (st.st_mode & S_IFMT) 11223 { 11224 case S_IFREG: t = "file"; break; 11225 case S_IFDIR: t = "dir"; break; 11226 # ifdef S_IFLNK 11227 case S_IFLNK: t = "link"; break; 11228 # endif 11229 # ifdef S_IFBLK 11230 case S_IFBLK: t = "bdev"; break; 11231 # endif 11232 # ifdef S_IFCHR 11233 case S_IFCHR: t = "cdev"; break; 11234 # endif 11235 # ifdef S_IFIFO 11236 case S_IFIFO: t = "fifo"; break; 11237 # endif 11238 # ifdef S_IFSOCK 11239 case S_IFSOCK: t = "socket"; break; 11240 # endif 11241 default: t = "other"; 11242 } 11243 # else 11244 if (mch_isdir(fname)) 11245 t = "dir"; 11246 else 11247 t = "file"; 11248 # endif 11249 #endif 11250 type = vim_strsave((char_u *)t); 11251 } 11252 rettv->vval.v_string = type; 11253 } 11254 11255 /* 11256 * "getline(lnum, [end])" function 11257 */ 11258 static void 11259 f_getline(argvars, rettv) 11260 typval_T *argvars; 11261 typval_T *rettv; 11262 { 11263 linenr_T lnum; 11264 linenr_T end; 11265 int retlist; 11266 11267 lnum = get_tv_lnum(argvars); 11268 if (argvars[1].v_type == VAR_UNKNOWN) 11269 { 11270 end = 0; 11271 retlist = FALSE; 11272 } 11273 else 11274 { 11275 end = get_tv_lnum(&argvars[1]); 11276 retlist = TRUE; 11277 } 11278 11279 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 11280 } 11281 11282 /* 11283 * "getmatches()" function 11284 */ 11285 static void 11286 f_getmatches(argvars, rettv) 11287 typval_T *argvars UNUSED; 11288 typval_T *rettv; 11289 { 11290 #ifdef FEAT_SEARCH_EXTRA 11291 dict_T *dict; 11292 matchitem_T *cur = curwin->w_match_head; 11293 11294 if (rettv_list_alloc(rettv) == OK) 11295 { 11296 while (cur != NULL) 11297 { 11298 dict = dict_alloc(); 11299 if (dict == NULL) 11300 return; 11301 dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id)); 11302 dict_add_nr_str(dict, "pattern", 0L, cur->pattern); 11303 dict_add_nr_str(dict, "priority", (long)cur->priority, NULL); 11304 dict_add_nr_str(dict, "id", (long)cur->id, NULL); 11305 list_append_dict(rettv->vval.v_list, dict); 11306 cur = cur->next; 11307 } 11308 } 11309 #endif 11310 } 11311 11312 /* 11313 * "getpid()" function 11314 */ 11315 static void 11316 f_getpid(argvars, rettv) 11317 typval_T *argvars UNUSED; 11318 typval_T *rettv; 11319 { 11320 rettv->vval.v_number = mch_get_pid(); 11321 } 11322 11323 /* 11324 * "getpos(string)" function 11325 */ 11326 static void 11327 f_getpos(argvars, rettv) 11328 typval_T *argvars; 11329 typval_T *rettv; 11330 { 11331 pos_T *fp; 11332 list_T *l; 11333 int fnum = -1; 11334 11335 if (rettv_list_alloc(rettv) == OK) 11336 { 11337 l = rettv->vval.v_list; 11338 fp = var2fpos(&argvars[0], TRUE, &fnum); 11339 if (fnum != -1) 11340 list_append_number(l, (varnumber_T)fnum); 11341 else 11342 list_append_number(l, (varnumber_T)0); 11343 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 11344 : (varnumber_T)0); 11345 list_append_number(l, (fp != NULL) 11346 ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1) 11347 : (varnumber_T)0); 11348 list_append_number(l, 11349 #ifdef FEAT_VIRTUALEDIT 11350 (fp != NULL) ? (varnumber_T)fp->coladd : 11351 #endif 11352 (varnumber_T)0); 11353 } 11354 else 11355 rettv->vval.v_number = FALSE; 11356 } 11357 11358 /* 11359 * "getqflist()" and "getloclist()" functions 11360 */ 11361 static void 11362 f_getqflist(argvars, rettv) 11363 typval_T *argvars UNUSED; 11364 typval_T *rettv UNUSED; 11365 { 11366 #ifdef FEAT_QUICKFIX 11367 win_T *wp; 11368 #endif 11369 11370 #ifdef FEAT_QUICKFIX 11371 if (rettv_list_alloc(rettv) == OK) 11372 { 11373 wp = NULL; 11374 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 11375 { 11376 wp = find_win_by_nr(&argvars[0], NULL); 11377 if (wp == NULL) 11378 return; 11379 } 11380 11381 (void)get_errorlist(wp, rettv->vval.v_list); 11382 } 11383 #endif 11384 } 11385 11386 /* 11387 * "getreg()" function 11388 */ 11389 static void 11390 f_getreg(argvars, rettv) 11391 typval_T *argvars; 11392 typval_T *rettv; 11393 { 11394 char_u *strregname; 11395 int regname; 11396 int arg2 = FALSE; 11397 int error = FALSE; 11398 11399 if (argvars[0].v_type != VAR_UNKNOWN) 11400 { 11401 strregname = get_tv_string_chk(&argvars[0]); 11402 error = strregname == NULL; 11403 if (argvars[1].v_type != VAR_UNKNOWN) 11404 arg2 = get_tv_number_chk(&argvars[1], &error); 11405 } 11406 else 11407 strregname = vimvars[VV_REG].vv_str; 11408 regname = (strregname == NULL ? '"' : *strregname); 11409 if (regname == 0) 11410 regname = '"'; 11411 11412 rettv->v_type = VAR_STRING; 11413 rettv->vval.v_string = error ? NULL : 11414 get_reg_contents(regname, TRUE, arg2); 11415 } 11416 11417 /* 11418 * "getregtype()" function 11419 */ 11420 static void 11421 f_getregtype(argvars, rettv) 11422 typval_T *argvars; 11423 typval_T *rettv; 11424 { 11425 char_u *strregname; 11426 int regname; 11427 char_u buf[NUMBUFLEN + 2]; 11428 long reglen = 0; 11429 11430 if (argvars[0].v_type != VAR_UNKNOWN) 11431 { 11432 strregname = get_tv_string_chk(&argvars[0]); 11433 if (strregname == NULL) /* type error; errmsg already given */ 11434 { 11435 rettv->v_type = VAR_STRING; 11436 rettv->vval.v_string = NULL; 11437 return; 11438 } 11439 } 11440 else 11441 /* Default to v:register */ 11442 strregname = vimvars[VV_REG].vv_str; 11443 11444 regname = (strregname == NULL ? '"' : *strregname); 11445 if (regname == 0) 11446 regname = '"'; 11447 11448 buf[0] = NUL; 11449 buf[1] = NUL; 11450 switch (get_reg_type(regname, ®len)) 11451 { 11452 case MLINE: buf[0] = 'V'; break; 11453 case MCHAR: buf[0] = 'v'; break; 11454 #ifdef FEAT_VISUAL 11455 case MBLOCK: 11456 buf[0] = Ctrl_V; 11457 sprintf((char *)buf + 1, "%ld", reglen + 1); 11458 break; 11459 #endif 11460 } 11461 rettv->v_type = VAR_STRING; 11462 rettv->vval.v_string = vim_strsave(buf); 11463 } 11464 11465 /* 11466 * "gettabvar()" function 11467 */ 11468 static void 11469 f_gettabvar(argvars, rettv) 11470 typval_T *argvars; 11471 typval_T *rettv; 11472 { 11473 tabpage_T *tp; 11474 dictitem_T *v; 11475 char_u *varname; 11476 11477 rettv->v_type = VAR_STRING; 11478 rettv->vval.v_string = NULL; 11479 11480 varname = get_tv_string_chk(&argvars[1]); 11481 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 11482 if (tp != NULL && varname != NULL) 11483 { 11484 /* look up the variable */ 11485 v = find_var_in_ht(&tp->tp_vars.dv_hashtab, varname, FALSE); 11486 if (v != NULL) 11487 copy_tv(&v->di_tv, rettv); 11488 } 11489 } 11490 11491 /* 11492 * "gettabwinvar()" function 11493 */ 11494 static void 11495 f_gettabwinvar(argvars, rettv) 11496 typval_T *argvars; 11497 typval_T *rettv; 11498 { 11499 getwinvar(argvars, rettv, 1); 11500 } 11501 11502 /* 11503 * "getwinposx()" function 11504 */ 11505 static void 11506 f_getwinposx(argvars, rettv) 11507 typval_T *argvars UNUSED; 11508 typval_T *rettv; 11509 { 11510 rettv->vval.v_number = -1; 11511 #ifdef FEAT_GUI 11512 if (gui.in_use) 11513 { 11514 int x, y; 11515 11516 if (gui_mch_get_winpos(&x, &y) == OK) 11517 rettv->vval.v_number = x; 11518 } 11519 #endif 11520 } 11521 11522 /* 11523 * "getwinposy()" function 11524 */ 11525 static void 11526 f_getwinposy(argvars, rettv) 11527 typval_T *argvars UNUSED; 11528 typval_T *rettv; 11529 { 11530 rettv->vval.v_number = -1; 11531 #ifdef FEAT_GUI 11532 if (gui.in_use) 11533 { 11534 int x, y; 11535 11536 if (gui_mch_get_winpos(&x, &y) == OK) 11537 rettv->vval.v_number = y; 11538 } 11539 #endif 11540 } 11541 11542 /* 11543 * Find window specified by "vp" in tabpage "tp". 11544 */ 11545 static win_T * 11546 find_win_by_nr(vp, tp) 11547 typval_T *vp; 11548 tabpage_T *tp; /* NULL for current tab page */ 11549 { 11550 #ifdef FEAT_WINDOWS 11551 win_T *wp; 11552 #endif 11553 int nr; 11554 11555 nr = get_tv_number_chk(vp, NULL); 11556 11557 #ifdef FEAT_WINDOWS 11558 if (nr < 0) 11559 return NULL; 11560 if (nr == 0) 11561 return curwin; 11562 11563 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 11564 wp != NULL; wp = wp->w_next) 11565 if (--nr <= 0) 11566 break; 11567 return wp; 11568 #else 11569 if (nr == 0 || nr == 1) 11570 return curwin; 11571 return NULL; 11572 #endif 11573 } 11574 11575 /* 11576 * "getwinvar()" function 11577 */ 11578 static void 11579 f_getwinvar(argvars, rettv) 11580 typval_T *argvars; 11581 typval_T *rettv; 11582 { 11583 getwinvar(argvars, rettv, 0); 11584 } 11585 11586 /* 11587 * getwinvar() and gettabwinvar() 11588 */ 11589 static void 11590 getwinvar(argvars, rettv, off) 11591 typval_T *argvars; 11592 typval_T *rettv; 11593 int off; /* 1 for gettabwinvar() */ 11594 { 11595 win_T *win, *oldcurwin; 11596 char_u *varname; 11597 dictitem_T *v; 11598 tabpage_T *tp; 11599 11600 #ifdef FEAT_WINDOWS 11601 if (off == 1) 11602 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 11603 else 11604 tp = curtab; 11605 #endif 11606 win = find_win_by_nr(&argvars[off], tp); 11607 varname = get_tv_string_chk(&argvars[off + 1]); 11608 ++emsg_off; 11609 11610 rettv->v_type = VAR_STRING; 11611 rettv->vval.v_string = NULL; 11612 11613 if (win != NULL && varname != NULL) 11614 { 11615 /* Set curwin to be our win, temporarily. Also set curbuf, so 11616 * that we can get buffer-local options. */ 11617 oldcurwin = curwin; 11618 curwin = win; 11619 curbuf = win->w_buffer; 11620 11621 if (*varname == '&') /* window-local-option */ 11622 get_option_tv(&varname, rettv, 1); 11623 else 11624 { 11625 if (*varname == NUL) 11626 /* let getwinvar({nr}, "") return the "w:" dictionary. The 11627 * scope prefix before the NUL byte is required by 11628 * find_var_in_ht(). */ 11629 varname = (char_u *)"w:" + 2; 11630 /* look up the variable */ 11631 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 11632 if (v != NULL) 11633 copy_tv(&v->di_tv, rettv); 11634 } 11635 11636 /* restore previous notion of curwin */ 11637 curwin = oldcurwin; 11638 curbuf = curwin->w_buffer; 11639 } 11640 11641 --emsg_off; 11642 } 11643 11644 /* 11645 * "glob()" function 11646 */ 11647 static void 11648 f_glob(argvars, rettv) 11649 typval_T *argvars; 11650 typval_T *rettv; 11651 { 11652 int flags = WILD_SILENT|WILD_USE_NL; 11653 expand_T xpc; 11654 int error = FALSE; 11655 11656 /* When the optional second argument is non-zero, don't remove matches 11657 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11658 if (argvars[1].v_type != VAR_UNKNOWN 11659 && get_tv_number_chk(&argvars[1], &error)) 11660 flags |= WILD_KEEP_ALL; 11661 rettv->v_type = VAR_STRING; 11662 if (!error) 11663 { 11664 ExpandInit(&xpc); 11665 xpc.xp_context = EXPAND_FILES; 11666 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 11667 NULL, flags, WILD_ALL); 11668 } 11669 else 11670 rettv->vval.v_string = NULL; 11671 } 11672 11673 /* 11674 * "globpath()" function 11675 */ 11676 static void 11677 f_globpath(argvars, rettv) 11678 typval_T *argvars; 11679 typval_T *rettv; 11680 { 11681 int flags = 0; 11682 char_u buf1[NUMBUFLEN]; 11683 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 11684 int error = FALSE; 11685 11686 /* When the optional second argument is non-zero, don't remove matches 11687 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11688 if (argvars[2].v_type != VAR_UNKNOWN 11689 && get_tv_number_chk(&argvars[2], &error)) 11690 flags |= WILD_KEEP_ALL; 11691 rettv->v_type = VAR_STRING; 11692 if (file == NULL || error) 11693 rettv->vval.v_string = NULL; 11694 else 11695 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file, 11696 flags); 11697 } 11698 11699 /* 11700 * "has()" function 11701 */ 11702 static void 11703 f_has(argvars, rettv) 11704 typval_T *argvars; 11705 typval_T *rettv; 11706 { 11707 int i; 11708 char_u *name; 11709 int n = FALSE; 11710 static char *(has_list[]) = 11711 { 11712 #ifdef AMIGA 11713 "amiga", 11714 # ifdef FEAT_ARP 11715 "arp", 11716 # endif 11717 #endif 11718 #ifdef __BEOS__ 11719 "beos", 11720 #endif 11721 #ifdef MSDOS 11722 # ifdef DJGPP 11723 "dos32", 11724 # else 11725 "dos16", 11726 # endif 11727 #endif 11728 #ifdef MACOS 11729 "mac", 11730 #endif 11731 #if defined(MACOS_X_UNIX) 11732 "macunix", 11733 #endif 11734 #ifdef OS2 11735 "os2", 11736 #endif 11737 #ifdef __QNX__ 11738 "qnx", 11739 #endif 11740 #ifdef RISCOS 11741 "riscos", 11742 #endif 11743 #ifdef UNIX 11744 "unix", 11745 #endif 11746 #ifdef VMS 11747 "vms", 11748 #endif 11749 #ifdef WIN16 11750 "win16", 11751 #endif 11752 #ifdef WIN32 11753 "win32", 11754 #endif 11755 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 11756 "win32unix", 11757 #endif 11758 #if defined(WIN64) || defined(_WIN64) 11759 "win64", 11760 #endif 11761 #ifdef EBCDIC 11762 "ebcdic", 11763 #endif 11764 #ifndef CASE_INSENSITIVE_FILENAME 11765 "fname_case", 11766 #endif 11767 #ifdef FEAT_ARABIC 11768 "arabic", 11769 #endif 11770 #ifdef FEAT_AUTOCMD 11771 "autocmd", 11772 #endif 11773 #ifdef FEAT_BEVAL 11774 "balloon_eval", 11775 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 11776 "balloon_multiline", 11777 # endif 11778 #endif 11779 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 11780 "builtin_terms", 11781 # ifdef ALL_BUILTIN_TCAPS 11782 "all_builtin_terms", 11783 # endif 11784 #endif 11785 #ifdef FEAT_BYTEOFF 11786 "byte_offset", 11787 #endif 11788 #ifdef FEAT_CINDENT 11789 "cindent", 11790 #endif 11791 #ifdef FEAT_CLIENTSERVER 11792 "clientserver", 11793 #endif 11794 #ifdef FEAT_CLIPBOARD 11795 "clipboard", 11796 #endif 11797 #ifdef FEAT_CMDL_COMPL 11798 "cmdline_compl", 11799 #endif 11800 #ifdef FEAT_CMDHIST 11801 "cmdline_hist", 11802 #endif 11803 #ifdef FEAT_COMMENTS 11804 "comments", 11805 #endif 11806 #ifdef FEAT_CONCEAL 11807 "conceal", 11808 #endif 11809 #ifdef FEAT_CRYPT 11810 "cryptv", 11811 #endif 11812 #ifdef FEAT_CSCOPE 11813 "cscope", 11814 #endif 11815 #ifdef FEAT_CURSORBIND 11816 "cursorbind", 11817 #endif 11818 #ifdef CURSOR_SHAPE 11819 "cursorshape", 11820 #endif 11821 #ifdef DEBUG 11822 "debug", 11823 #endif 11824 #ifdef FEAT_CON_DIALOG 11825 "dialog_con", 11826 #endif 11827 #ifdef FEAT_GUI_DIALOG 11828 "dialog_gui", 11829 #endif 11830 #ifdef FEAT_DIFF 11831 "diff", 11832 #endif 11833 #ifdef FEAT_DIGRAPHS 11834 "digraphs", 11835 #endif 11836 #ifdef FEAT_DND 11837 "dnd", 11838 #endif 11839 #ifdef FEAT_EMACS_TAGS 11840 "emacs_tags", 11841 #endif 11842 "eval", /* always present, of course! */ 11843 #ifdef FEAT_EX_EXTRA 11844 "ex_extra", 11845 #endif 11846 #ifdef FEAT_SEARCH_EXTRA 11847 "extra_search", 11848 #endif 11849 #ifdef FEAT_FKMAP 11850 "farsi", 11851 #endif 11852 #ifdef FEAT_SEARCHPATH 11853 "file_in_path", 11854 #endif 11855 #if defined(UNIX) && !defined(USE_SYSTEM) 11856 "filterpipe", 11857 #endif 11858 #ifdef FEAT_FIND_ID 11859 "find_in_path", 11860 #endif 11861 #ifdef FEAT_FLOAT 11862 "float", 11863 #endif 11864 #ifdef FEAT_FOLDING 11865 "folding", 11866 #endif 11867 #ifdef FEAT_FOOTER 11868 "footer", 11869 #endif 11870 #if !defined(USE_SYSTEM) && defined(UNIX) 11871 "fork", 11872 #endif 11873 #ifdef FEAT_GETTEXT 11874 "gettext", 11875 #endif 11876 #ifdef FEAT_GUI 11877 "gui", 11878 #endif 11879 #ifdef FEAT_GUI_ATHENA 11880 # ifdef FEAT_GUI_NEXTAW 11881 "gui_neXtaw", 11882 # else 11883 "gui_athena", 11884 # endif 11885 #endif 11886 #ifdef FEAT_GUI_GTK 11887 "gui_gtk", 11888 "gui_gtk2", 11889 #endif 11890 #ifdef FEAT_GUI_GNOME 11891 "gui_gnome", 11892 #endif 11893 #ifdef FEAT_GUI_MAC 11894 "gui_mac", 11895 #endif 11896 #ifdef FEAT_GUI_MOTIF 11897 "gui_motif", 11898 #endif 11899 #ifdef FEAT_GUI_PHOTON 11900 "gui_photon", 11901 #endif 11902 #ifdef FEAT_GUI_W16 11903 "gui_win16", 11904 #endif 11905 #ifdef FEAT_GUI_W32 11906 "gui_win32", 11907 #endif 11908 #ifdef FEAT_HANGULIN 11909 "hangul_input", 11910 #endif 11911 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 11912 "iconv", 11913 #endif 11914 #ifdef FEAT_INS_EXPAND 11915 "insert_expand", 11916 #endif 11917 #ifdef FEAT_JUMPLIST 11918 "jumplist", 11919 #endif 11920 #ifdef FEAT_KEYMAP 11921 "keymap", 11922 #endif 11923 #ifdef FEAT_LANGMAP 11924 "langmap", 11925 #endif 11926 #ifdef FEAT_LIBCALL 11927 "libcall", 11928 #endif 11929 #ifdef FEAT_LINEBREAK 11930 "linebreak", 11931 #endif 11932 #ifdef FEAT_LISP 11933 "lispindent", 11934 #endif 11935 #ifdef FEAT_LISTCMDS 11936 "listcmds", 11937 #endif 11938 #ifdef FEAT_LOCALMAP 11939 "localmap", 11940 #endif 11941 #ifdef FEAT_LUA 11942 # ifndef DYNAMIC_LUA 11943 "lua", 11944 # endif 11945 #endif 11946 #ifdef FEAT_MENU 11947 "menu", 11948 #endif 11949 #ifdef FEAT_SESSION 11950 "mksession", 11951 #endif 11952 #ifdef FEAT_MODIFY_FNAME 11953 "modify_fname", 11954 #endif 11955 #ifdef FEAT_MOUSE 11956 "mouse", 11957 #endif 11958 #ifdef FEAT_MOUSESHAPE 11959 "mouseshape", 11960 #endif 11961 #if defined(UNIX) || defined(VMS) 11962 # ifdef FEAT_MOUSE_DEC 11963 "mouse_dec", 11964 # endif 11965 # ifdef FEAT_MOUSE_GPM 11966 "mouse_gpm", 11967 # endif 11968 # ifdef FEAT_MOUSE_JSB 11969 "mouse_jsbterm", 11970 # endif 11971 # ifdef FEAT_MOUSE_NET 11972 "mouse_netterm", 11973 # endif 11974 # ifdef FEAT_MOUSE_PTERM 11975 "mouse_pterm", 11976 # endif 11977 # ifdef FEAT_SYSMOUSE 11978 "mouse_sysmouse", 11979 # endif 11980 # ifdef FEAT_MOUSE_XTERM 11981 "mouse_xterm", 11982 # endif 11983 #endif 11984 #ifdef FEAT_MBYTE 11985 "multi_byte", 11986 #endif 11987 #ifdef FEAT_MBYTE_IME 11988 "multi_byte_ime", 11989 #endif 11990 #ifdef FEAT_MULTI_LANG 11991 "multi_lang", 11992 #endif 11993 #ifdef FEAT_MZSCHEME 11994 #ifndef DYNAMIC_MZSCHEME 11995 "mzscheme", 11996 #endif 11997 #endif 11998 #ifdef FEAT_OLE 11999 "ole", 12000 #endif 12001 #ifdef FEAT_OSFILETYPE 12002 "osfiletype", 12003 #endif 12004 #ifdef FEAT_PATH_EXTRA 12005 "path_extra", 12006 #endif 12007 #ifdef FEAT_PERL 12008 #ifndef DYNAMIC_PERL 12009 "perl", 12010 #endif 12011 #endif 12012 #ifdef FEAT_PERSISTENT_UNDO 12013 "persistent_undo", 12014 #endif 12015 #ifdef FEAT_PYTHON 12016 #ifndef DYNAMIC_PYTHON 12017 "python", 12018 #endif 12019 #endif 12020 #ifdef FEAT_PYTHON3 12021 #ifndef DYNAMIC_PYTHON3 12022 "python3", 12023 #endif 12024 #endif 12025 #ifdef FEAT_POSTSCRIPT 12026 "postscript", 12027 #endif 12028 #ifdef FEAT_PRINTER 12029 "printer", 12030 #endif 12031 #ifdef FEAT_PROFILE 12032 "profile", 12033 #endif 12034 #ifdef FEAT_RELTIME 12035 "reltime", 12036 #endif 12037 #ifdef FEAT_QUICKFIX 12038 "quickfix", 12039 #endif 12040 #ifdef FEAT_RIGHTLEFT 12041 "rightleft", 12042 #endif 12043 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 12044 "ruby", 12045 #endif 12046 #ifdef FEAT_SCROLLBIND 12047 "scrollbind", 12048 #endif 12049 #ifdef FEAT_CMDL_INFO 12050 "showcmd", 12051 "cmdline_info", 12052 #endif 12053 #ifdef FEAT_SIGNS 12054 "signs", 12055 #endif 12056 #ifdef FEAT_SMARTINDENT 12057 "smartindent", 12058 #endif 12059 #ifdef FEAT_SNIFF 12060 "sniff", 12061 #endif 12062 #ifdef STARTUPTIME 12063 "startuptime", 12064 #endif 12065 #ifdef FEAT_STL_OPT 12066 "statusline", 12067 #endif 12068 #ifdef FEAT_SUN_WORKSHOP 12069 "sun_workshop", 12070 #endif 12071 #ifdef FEAT_NETBEANS_INTG 12072 "netbeans_intg", 12073 #endif 12074 #ifdef FEAT_SPELL 12075 "spell", 12076 #endif 12077 #ifdef FEAT_SYN_HL 12078 "syntax", 12079 #endif 12080 #if defined(USE_SYSTEM) || !defined(UNIX) 12081 "system", 12082 #endif 12083 #ifdef FEAT_TAG_BINS 12084 "tag_binary", 12085 #endif 12086 #ifdef FEAT_TAG_OLDSTATIC 12087 "tag_old_static", 12088 #endif 12089 #ifdef FEAT_TAG_ANYWHITE 12090 "tag_any_white", 12091 #endif 12092 #ifdef FEAT_TCL 12093 # ifndef DYNAMIC_TCL 12094 "tcl", 12095 # endif 12096 #endif 12097 #ifdef TERMINFO 12098 "terminfo", 12099 #endif 12100 #ifdef FEAT_TERMRESPONSE 12101 "termresponse", 12102 #endif 12103 #ifdef FEAT_TEXTOBJ 12104 "textobjects", 12105 #endif 12106 #ifdef HAVE_TGETENT 12107 "tgetent", 12108 #endif 12109 #ifdef FEAT_TITLE 12110 "title", 12111 #endif 12112 #ifdef FEAT_TOOLBAR 12113 "toolbar", 12114 #endif 12115 #ifdef FEAT_USR_CMDS 12116 "user-commands", /* was accidentally included in 5.4 */ 12117 "user_commands", 12118 #endif 12119 #ifdef FEAT_VIMINFO 12120 "viminfo", 12121 #endif 12122 #ifdef FEAT_VERTSPLIT 12123 "vertsplit", 12124 #endif 12125 #ifdef FEAT_VIRTUALEDIT 12126 "virtualedit", 12127 #endif 12128 #ifdef FEAT_VISUAL 12129 "visual", 12130 #endif 12131 #ifdef FEAT_VISUALEXTRA 12132 "visualextra", 12133 #endif 12134 #ifdef FEAT_VREPLACE 12135 "vreplace", 12136 #endif 12137 #ifdef FEAT_WILDIGN 12138 "wildignore", 12139 #endif 12140 #ifdef FEAT_WILDMENU 12141 "wildmenu", 12142 #endif 12143 #ifdef FEAT_WINDOWS 12144 "windows", 12145 #endif 12146 #ifdef FEAT_WAK 12147 "winaltkeys", 12148 #endif 12149 #ifdef FEAT_WRITEBACKUP 12150 "writebackup", 12151 #endif 12152 #ifdef FEAT_XIM 12153 "xim", 12154 #endif 12155 #ifdef FEAT_XFONTSET 12156 "xfontset", 12157 #endif 12158 #ifdef USE_XSMP 12159 "xsmp", 12160 #endif 12161 #ifdef USE_XSMP_INTERACT 12162 "xsmp_interact", 12163 #endif 12164 #ifdef FEAT_XCLIPBOARD 12165 "xterm_clipboard", 12166 #endif 12167 #ifdef FEAT_XTERM_SAVE 12168 "xterm_save", 12169 #endif 12170 #if defined(UNIX) && defined(FEAT_X11) 12171 "X11", 12172 #endif 12173 NULL 12174 }; 12175 12176 name = get_tv_string(&argvars[0]); 12177 for (i = 0; has_list[i] != NULL; ++i) 12178 if (STRICMP(name, has_list[i]) == 0) 12179 { 12180 n = TRUE; 12181 break; 12182 } 12183 12184 if (n == FALSE) 12185 { 12186 if (STRNICMP(name, "patch", 5) == 0) 12187 n = has_patch(atoi((char *)name + 5)); 12188 else if (STRICMP(name, "vim_starting") == 0) 12189 n = (starting != 0); 12190 #ifdef FEAT_MBYTE 12191 else if (STRICMP(name, "multi_byte_encoding") == 0) 12192 n = has_mbyte; 12193 #endif 12194 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 12195 else if (STRICMP(name, "balloon_multiline") == 0) 12196 n = multiline_balloon_available(); 12197 #endif 12198 #ifdef DYNAMIC_TCL 12199 else if (STRICMP(name, "tcl") == 0) 12200 n = tcl_enabled(FALSE); 12201 #endif 12202 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 12203 else if (STRICMP(name, "iconv") == 0) 12204 n = iconv_enabled(FALSE); 12205 #endif 12206 #ifdef DYNAMIC_LUA 12207 else if (STRICMP(name, "lua") == 0) 12208 n = lua_enabled(FALSE); 12209 #endif 12210 #ifdef DYNAMIC_MZSCHEME 12211 else if (STRICMP(name, "mzscheme") == 0) 12212 n = mzscheme_enabled(FALSE); 12213 #endif 12214 #ifdef DYNAMIC_RUBY 12215 else if (STRICMP(name, "ruby") == 0) 12216 n = ruby_enabled(FALSE); 12217 #endif 12218 #ifdef FEAT_PYTHON 12219 #ifdef DYNAMIC_PYTHON 12220 else if (STRICMP(name, "python") == 0) 12221 n = python_enabled(FALSE); 12222 #endif 12223 #endif 12224 #ifdef FEAT_PYTHON3 12225 #ifdef DYNAMIC_PYTHON3 12226 else if (STRICMP(name, "python3") == 0) 12227 n = python3_enabled(FALSE); 12228 #endif 12229 #endif 12230 #ifdef DYNAMIC_PERL 12231 else if (STRICMP(name, "perl") == 0) 12232 n = perl_enabled(FALSE); 12233 #endif 12234 #ifdef FEAT_GUI 12235 else if (STRICMP(name, "gui_running") == 0) 12236 n = (gui.in_use || gui.starting); 12237 # ifdef FEAT_GUI_W32 12238 else if (STRICMP(name, "gui_win32s") == 0) 12239 n = gui_is_win32s(); 12240 # endif 12241 # ifdef FEAT_BROWSE 12242 else if (STRICMP(name, "browse") == 0) 12243 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 12244 # endif 12245 #endif 12246 #ifdef FEAT_SYN_HL 12247 else if (STRICMP(name, "syntax_items") == 0) 12248 n = syntax_present(curwin); 12249 #endif 12250 #if defined(WIN3264) 12251 else if (STRICMP(name, "win95") == 0) 12252 n = mch_windows95(); 12253 #endif 12254 #ifdef FEAT_NETBEANS_INTG 12255 else if (STRICMP(name, "netbeans_enabled") == 0) 12256 n = netbeans_active(); 12257 #endif 12258 } 12259 12260 rettv->vval.v_number = n; 12261 } 12262 12263 /* 12264 * "has_key()" function 12265 */ 12266 static void 12267 f_has_key(argvars, rettv) 12268 typval_T *argvars; 12269 typval_T *rettv; 12270 { 12271 if (argvars[0].v_type != VAR_DICT) 12272 { 12273 EMSG(_(e_dictreq)); 12274 return; 12275 } 12276 if (argvars[0].vval.v_dict == NULL) 12277 return; 12278 12279 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 12280 get_tv_string(&argvars[1]), -1) != NULL; 12281 } 12282 12283 /* 12284 * "haslocaldir()" function 12285 */ 12286 static void 12287 f_haslocaldir(argvars, rettv) 12288 typval_T *argvars UNUSED; 12289 typval_T *rettv; 12290 { 12291 rettv->vval.v_number = (curwin->w_localdir != NULL); 12292 } 12293 12294 /* 12295 * "hasmapto()" function 12296 */ 12297 static void 12298 f_hasmapto(argvars, rettv) 12299 typval_T *argvars; 12300 typval_T *rettv; 12301 { 12302 char_u *name; 12303 char_u *mode; 12304 char_u buf[NUMBUFLEN]; 12305 int abbr = FALSE; 12306 12307 name = get_tv_string(&argvars[0]); 12308 if (argvars[1].v_type == VAR_UNKNOWN) 12309 mode = (char_u *)"nvo"; 12310 else 12311 { 12312 mode = get_tv_string_buf(&argvars[1], buf); 12313 if (argvars[2].v_type != VAR_UNKNOWN) 12314 abbr = get_tv_number(&argvars[2]); 12315 } 12316 12317 if (map_to_exists(name, mode, abbr)) 12318 rettv->vval.v_number = TRUE; 12319 else 12320 rettv->vval.v_number = FALSE; 12321 } 12322 12323 /* 12324 * "histadd()" function 12325 */ 12326 static void 12327 f_histadd(argvars, rettv) 12328 typval_T *argvars UNUSED; 12329 typval_T *rettv; 12330 { 12331 #ifdef FEAT_CMDHIST 12332 int histype; 12333 char_u *str; 12334 char_u buf[NUMBUFLEN]; 12335 #endif 12336 12337 rettv->vval.v_number = FALSE; 12338 if (check_restricted() || check_secure()) 12339 return; 12340 #ifdef FEAT_CMDHIST 12341 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12342 histype = str != NULL ? get_histtype(str) : -1; 12343 if (histype >= 0) 12344 { 12345 str = get_tv_string_buf(&argvars[1], buf); 12346 if (*str != NUL) 12347 { 12348 init_history(); 12349 add_to_history(histype, str, FALSE, NUL); 12350 rettv->vval.v_number = TRUE; 12351 return; 12352 } 12353 } 12354 #endif 12355 } 12356 12357 /* 12358 * "histdel()" function 12359 */ 12360 static void 12361 f_histdel(argvars, rettv) 12362 typval_T *argvars UNUSED; 12363 typval_T *rettv UNUSED; 12364 { 12365 #ifdef FEAT_CMDHIST 12366 int n; 12367 char_u buf[NUMBUFLEN]; 12368 char_u *str; 12369 12370 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12371 if (str == NULL) 12372 n = 0; 12373 else if (argvars[1].v_type == VAR_UNKNOWN) 12374 /* only one argument: clear entire history */ 12375 n = clr_history(get_histtype(str)); 12376 else if (argvars[1].v_type == VAR_NUMBER) 12377 /* index given: remove that entry */ 12378 n = del_history_idx(get_histtype(str), 12379 (int)get_tv_number(&argvars[1])); 12380 else 12381 /* string given: remove all matching entries */ 12382 n = del_history_entry(get_histtype(str), 12383 get_tv_string_buf(&argvars[1], buf)); 12384 rettv->vval.v_number = n; 12385 #endif 12386 } 12387 12388 /* 12389 * "histget()" function 12390 */ 12391 static void 12392 f_histget(argvars, rettv) 12393 typval_T *argvars UNUSED; 12394 typval_T *rettv; 12395 { 12396 #ifdef FEAT_CMDHIST 12397 int type; 12398 int idx; 12399 char_u *str; 12400 12401 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12402 if (str == NULL) 12403 rettv->vval.v_string = NULL; 12404 else 12405 { 12406 type = get_histtype(str); 12407 if (argvars[1].v_type == VAR_UNKNOWN) 12408 idx = get_history_idx(type); 12409 else 12410 idx = (int)get_tv_number_chk(&argvars[1], NULL); 12411 /* -1 on type error */ 12412 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 12413 } 12414 #else 12415 rettv->vval.v_string = NULL; 12416 #endif 12417 rettv->v_type = VAR_STRING; 12418 } 12419 12420 /* 12421 * "histnr()" function 12422 */ 12423 static void 12424 f_histnr(argvars, rettv) 12425 typval_T *argvars UNUSED; 12426 typval_T *rettv; 12427 { 12428 int i; 12429 12430 #ifdef FEAT_CMDHIST 12431 char_u *history = get_tv_string_chk(&argvars[0]); 12432 12433 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 12434 if (i >= HIST_CMD && i < HIST_COUNT) 12435 i = get_history_idx(i); 12436 else 12437 #endif 12438 i = -1; 12439 rettv->vval.v_number = i; 12440 } 12441 12442 /* 12443 * "highlightID(name)" function 12444 */ 12445 static void 12446 f_hlID(argvars, rettv) 12447 typval_T *argvars; 12448 typval_T *rettv; 12449 { 12450 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 12451 } 12452 12453 /* 12454 * "highlight_exists()" function 12455 */ 12456 static void 12457 f_hlexists(argvars, rettv) 12458 typval_T *argvars; 12459 typval_T *rettv; 12460 { 12461 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 12462 } 12463 12464 /* 12465 * "hostname()" function 12466 */ 12467 static void 12468 f_hostname(argvars, rettv) 12469 typval_T *argvars UNUSED; 12470 typval_T *rettv; 12471 { 12472 char_u hostname[256]; 12473 12474 mch_get_host_name(hostname, 256); 12475 rettv->v_type = VAR_STRING; 12476 rettv->vval.v_string = vim_strsave(hostname); 12477 } 12478 12479 /* 12480 * iconv() function 12481 */ 12482 static void 12483 f_iconv(argvars, rettv) 12484 typval_T *argvars UNUSED; 12485 typval_T *rettv; 12486 { 12487 #ifdef FEAT_MBYTE 12488 char_u buf1[NUMBUFLEN]; 12489 char_u buf2[NUMBUFLEN]; 12490 char_u *from, *to, *str; 12491 vimconv_T vimconv; 12492 #endif 12493 12494 rettv->v_type = VAR_STRING; 12495 rettv->vval.v_string = NULL; 12496 12497 #ifdef FEAT_MBYTE 12498 str = get_tv_string(&argvars[0]); 12499 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 12500 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 12501 vimconv.vc_type = CONV_NONE; 12502 convert_setup(&vimconv, from, to); 12503 12504 /* If the encodings are equal, no conversion needed. */ 12505 if (vimconv.vc_type == CONV_NONE) 12506 rettv->vval.v_string = vim_strsave(str); 12507 else 12508 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 12509 12510 convert_setup(&vimconv, NULL, NULL); 12511 vim_free(from); 12512 vim_free(to); 12513 #endif 12514 } 12515 12516 /* 12517 * "indent()" function 12518 */ 12519 static void 12520 f_indent(argvars, rettv) 12521 typval_T *argvars; 12522 typval_T *rettv; 12523 { 12524 linenr_T lnum; 12525 12526 lnum = get_tv_lnum(argvars); 12527 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 12528 rettv->vval.v_number = get_indent_lnum(lnum); 12529 else 12530 rettv->vval.v_number = -1; 12531 } 12532 12533 /* 12534 * "index()" function 12535 */ 12536 static void 12537 f_index(argvars, rettv) 12538 typval_T *argvars; 12539 typval_T *rettv; 12540 { 12541 list_T *l; 12542 listitem_T *item; 12543 long idx = 0; 12544 int ic = FALSE; 12545 12546 rettv->vval.v_number = -1; 12547 if (argvars[0].v_type != VAR_LIST) 12548 { 12549 EMSG(_(e_listreq)); 12550 return; 12551 } 12552 l = argvars[0].vval.v_list; 12553 if (l != NULL) 12554 { 12555 item = l->lv_first; 12556 if (argvars[2].v_type != VAR_UNKNOWN) 12557 { 12558 int error = FALSE; 12559 12560 /* Start at specified item. Use the cached index that list_find() 12561 * sets, so that a negative number also works. */ 12562 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 12563 idx = l->lv_idx; 12564 if (argvars[3].v_type != VAR_UNKNOWN) 12565 ic = get_tv_number_chk(&argvars[3], &error); 12566 if (error) 12567 item = NULL; 12568 } 12569 12570 for ( ; item != NULL; item = item->li_next, ++idx) 12571 if (tv_equal(&item->li_tv, &argvars[1], ic)) 12572 { 12573 rettv->vval.v_number = idx; 12574 break; 12575 } 12576 } 12577 } 12578 12579 static int inputsecret_flag = 0; 12580 12581 static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog)); 12582 12583 /* 12584 * This function is used by f_input() and f_inputdialog() functions. The third 12585 * argument to f_input() specifies the type of completion to use at the 12586 * prompt. The third argument to f_inputdialog() specifies the value to return 12587 * when the user cancels the prompt. 12588 */ 12589 static void 12590 get_user_input(argvars, rettv, inputdialog) 12591 typval_T *argvars; 12592 typval_T *rettv; 12593 int inputdialog; 12594 { 12595 char_u *prompt = get_tv_string_chk(&argvars[0]); 12596 char_u *p = NULL; 12597 int c; 12598 char_u buf[NUMBUFLEN]; 12599 int cmd_silent_save = cmd_silent; 12600 char_u *defstr = (char_u *)""; 12601 int xp_type = EXPAND_NOTHING; 12602 char_u *xp_arg = NULL; 12603 12604 rettv->v_type = VAR_STRING; 12605 rettv->vval.v_string = NULL; 12606 12607 #ifdef NO_CONSOLE_INPUT 12608 /* While starting up, there is no place to enter text. */ 12609 if (no_console_input()) 12610 return; 12611 #endif 12612 12613 cmd_silent = FALSE; /* Want to see the prompt. */ 12614 if (prompt != NULL) 12615 { 12616 /* Only the part of the message after the last NL is considered as 12617 * prompt for the command line */ 12618 p = vim_strrchr(prompt, '\n'); 12619 if (p == NULL) 12620 p = prompt; 12621 else 12622 { 12623 ++p; 12624 c = *p; 12625 *p = NUL; 12626 msg_start(); 12627 msg_clr_eos(); 12628 msg_puts_attr(prompt, echo_attr); 12629 msg_didout = FALSE; 12630 msg_starthere(); 12631 *p = c; 12632 } 12633 cmdline_row = msg_row; 12634 12635 if (argvars[1].v_type != VAR_UNKNOWN) 12636 { 12637 defstr = get_tv_string_buf_chk(&argvars[1], buf); 12638 if (defstr != NULL) 12639 stuffReadbuffSpec(defstr); 12640 12641 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 12642 { 12643 char_u *xp_name; 12644 int xp_namelen; 12645 long argt; 12646 12647 rettv->vval.v_string = NULL; 12648 12649 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 12650 if (xp_name == NULL) 12651 return; 12652 12653 xp_namelen = (int)STRLEN(xp_name); 12654 12655 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 12656 &xp_arg) == FAIL) 12657 return; 12658 } 12659 } 12660 12661 if (defstr != NULL) 12662 rettv->vval.v_string = 12663 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 12664 xp_type, xp_arg); 12665 12666 vim_free(xp_arg); 12667 12668 /* since the user typed this, no need to wait for return */ 12669 need_wait_return = FALSE; 12670 msg_didout = FALSE; 12671 } 12672 cmd_silent = cmd_silent_save; 12673 } 12674 12675 /* 12676 * "input()" function 12677 * Also handles inputsecret() when inputsecret is set. 12678 */ 12679 static void 12680 f_input(argvars, rettv) 12681 typval_T *argvars; 12682 typval_T *rettv; 12683 { 12684 get_user_input(argvars, rettv, FALSE); 12685 } 12686 12687 /* 12688 * "inputdialog()" function 12689 */ 12690 static void 12691 f_inputdialog(argvars, rettv) 12692 typval_T *argvars; 12693 typval_T *rettv; 12694 { 12695 #if defined(FEAT_GUI_TEXTDIALOG) 12696 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 12697 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 12698 { 12699 char_u *message; 12700 char_u buf[NUMBUFLEN]; 12701 char_u *defstr = (char_u *)""; 12702 12703 message = get_tv_string_chk(&argvars[0]); 12704 if (argvars[1].v_type != VAR_UNKNOWN 12705 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 12706 vim_strncpy(IObuff, defstr, IOSIZE - 1); 12707 else 12708 IObuff[0] = NUL; 12709 if (message != NULL && defstr != NULL 12710 && do_dialog(VIM_QUESTION, NULL, message, 12711 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 12712 rettv->vval.v_string = vim_strsave(IObuff); 12713 else 12714 { 12715 if (message != NULL && defstr != NULL 12716 && argvars[1].v_type != VAR_UNKNOWN 12717 && argvars[2].v_type != VAR_UNKNOWN) 12718 rettv->vval.v_string = vim_strsave( 12719 get_tv_string_buf(&argvars[2], buf)); 12720 else 12721 rettv->vval.v_string = NULL; 12722 } 12723 rettv->v_type = VAR_STRING; 12724 } 12725 else 12726 #endif 12727 get_user_input(argvars, rettv, TRUE); 12728 } 12729 12730 /* 12731 * "inputlist()" function 12732 */ 12733 static void 12734 f_inputlist(argvars, rettv) 12735 typval_T *argvars; 12736 typval_T *rettv; 12737 { 12738 listitem_T *li; 12739 int selected; 12740 int mouse_used; 12741 12742 #ifdef NO_CONSOLE_INPUT 12743 /* While starting up, there is no place to enter text. */ 12744 if (no_console_input()) 12745 return; 12746 #endif 12747 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 12748 { 12749 EMSG2(_(e_listarg), "inputlist()"); 12750 return; 12751 } 12752 12753 msg_start(); 12754 msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ 12755 lines_left = Rows; /* avoid more prompt */ 12756 msg_scroll = TRUE; 12757 msg_clr_eos(); 12758 12759 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 12760 { 12761 msg_puts(get_tv_string(&li->li_tv)); 12762 msg_putchar('\n'); 12763 } 12764 12765 /* Ask for choice. */ 12766 selected = prompt_for_number(&mouse_used); 12767 if (mouse_used) 12768 selected -= lines_left; 12769 12770 rettv->vval.v_number = selected; 12771 } 12772 12773 12774 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 12775 12776 /* 12777 * "inputrestore()" function 12778 */ 12779 static void 12780 f_inputrestore(argvars, rettv) 12781 typval_T *argvars UNUSED; 12782 typval_T *rettv; 12783 { 12784 if (ga_userinput.ga_len > 0) 12785 { 12786 --ga_userinput.ga_len; 12787 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 12788 + ga_userinput.ga_len); 12789 /* default return is zero == OK */ 12790 } 12791 else if (p_verbose > 1) 12792 { 12793 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 12794 rettv->vval.v_number = 1; /* Failed */ 12795 } 12796 } 12797 12798 /* 12799 * "inputsave()" function 12800 */ 12801 static void 12802 f_inputsave(argvars, rettv) 12803 typval_T *argvars UNUSED; 12804 typval_T *rettv; 12805 { 12806 /* Add an entry to the stack of typeahead storage. */ 12807 if (ga_grow(&ga_userinput, 1) == OK) 12808 { 12809 save_typeahead((tasave_T *)(ga_userinput.ga_data) 12810 + ga_userinput.ga_len); 12811 ++ga_userinput.ga_len; 12812 /* default return is zero == OK */ 12813 } 12814 else 12815 rettv->vval.v_number = 1; /* Failed */ 12816 } 12817 12818 /* 12819 * "inputsecret()" function 12820 */ 12821 static void 12822 f_inputsecret(argvars, rettv) 12823 typval_T *argvars; 12824 typval_T *rettv; 12825 { 12826 ++cmdline_star; 12827 ++inputsecret_flag; 12828 f_input(argvars, rettv); 12829 --cmdline_star; 12830 --inputsecret_flag; 12831 } 12832 12833 /* 12834 * "insert()" function 12835 */ 12836 static void 12837 f_insert(argvars, rettv) 12838 typval_T *argvars; 12839 typval_T *rettv; 12840 { 12841 long before = 0; 12842 listitem_T *item; 12843 list_T *l; 12844 int error = FALSE; 12845 12846 if (argvars[0].v_type != VAR_LIST) 12847 EMSG2(_(e_listarg), "insert()"); 12848 else if ((l = argvars[0].vval.v_list) != NULL 12849 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 12850 { 12851 if (argvars[2].v_type != VAR_UNKNOWN) 12852 before = get_tv_number_chk(&argvars[2], &error); 12853 if (error) 12854 return; /* type error; errmsg already given */ 12855 12856 if (before == l->lv_len) 12857 item = NULL; 12858 else 12859 { 12860 item = list_find(l, before); 12861 if (item == NULL) 12862 { 12863 EMSGN(_(e_listidx), before); 12864 l = NULL; 12865 } 12866 } 12867 if (l != NULL) 12868 { 12869 list_insert_tv(l, &argvars[1], item); 12870 copy_tv(&argvars[0], rettv); 12871 } 12872 } 12873 } 12874 12875 /* 12876 * "isdirectory()" function 12877 */ 12878 static void 12879 f_isdirectory(argvars, rettv) 12880 typval_T *argvars; 12881 typval_T *rettv; 12882 { 12883 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 12884 } 12885 12886 /* 12887 * "islocked()" function 12888 */ 12889 static void 12890 f_islocked(argvars, rettv) 12891 typval_T *argvars; 12892 typval_T *rettv; 12893 { 12894 lval_T lv; 12895 char_u *end; 12896 dictitem_T *di; 12897 12898 rettv->vval.v_number = -1; 12899 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 12900 FNE_CHECK_START); 12901 if (end != NULL && lv.ll_name != NULL) 12902 { 12903 if (*end != NUL) 12904 EMSG(_(e_trailing)); 12905 else 12906 { 12907 if (lv.ll_tv == NULL) 12908 { 12909 if (check_changedtick(lv.ll_name)) 12910 rettv->vval.v_number = 1; /* always locked */ 12911 else 12912 { 12913 di = find_var(lv.ll_name, NULL); 12914 if (di != NULL) 12915 { 12916 /* Consider a variable locked when: 12917 * 1. the variable itself is locked 12918 * 2. the value of the variable is locked. 12919 * 3. the List or Dict value is locked. 12920 */ 12921 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 12922 || tv_islocked(&di->di_tv)); 12923 } 12924 } 12925 } 12926 else if (lv.ll_range) 12927 EMSG(_("E786: Range not allowed")); 12928 else if (lv.ll_newkey != NULL) 12929 EMSG2(_(e_dictkey), lv.ll_newkey); 12930 else if (lv.ll_list != NULL) 12931 /* List item. */ 12932 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 12933 else 12934 /* Dictionary item. */ 12935 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 12936 } 12937 } 12938 12939 clear_lval(&lv); 12940 } 12941 12942 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 12943 12944 /* 12945 * Turn a dict into a list: 12946 * "what" == 0: list of keys 12947 * "what" == 1: list of values 12948 * "what" == 2: list of items 12949 */ 12950 static void 12951 dict_list(argvars, rettv, what) 12952 typval_T *argvars; 12953 typval_T *rettv; 12954 int what; 12955 { 12956 list_T *l2; 12957 dictitem_T *di; 12958 hashitem_T *hi; 12959 listitem_T *li; 12960 listitem_T *li2; 12961 dict_T *d; 12962 int todo; 12963 12964 if (argvars[0].v_type != VAR_DICT) 12965 { 12966 EMSG(_(e_dictreq)); 12967 return; 12968 } 12969 if ((d = argvars[0].vval.v_dict) == NULL) 12970 return; 12971 12972 if (rettv_list_alloc(rettv) == FAIL) 12973 return; 12974 12975 todo = (int)d->dv_hashtab.ht_used; 12976 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 12977 { 12978 if (!HASHITEM_EMPTY(hi)) 12979 { 12980 --todo; 12981 di = HI2DI(hi); 12982 12983 li = listitem_alloc(); 12984 if (li == NULL) 12985 break; 12986 list_append(rettv->vval.v_list, li); 12987 12988 if (what == 0) 12989 { 12990 /* keys() */ 12991 li->li_tv.v_type = VAR_STRING; 12992 li->li_tv.v_lock = 0; 12993 li->li_tv.vval.v_string = vim_strsave(di->di_key); 12994 } 12995 else if (what == 1) 12996 { 12997 /* values() */ 12998 copy_tv(&di->di_tv, &li->li_tv); 12999 } 13000 else 13001 { 13002 /* items() */ 13003 l2 = list_alloc(); 13004 li->li_tv.v_type = VAR_LIST; 13005 li->li_tv.v_lock = 0; 13006 li->li_tv.vval.v_list = l2; 13007 if (l2 == NULL) 13008 break; 13009 ++l2->lv_refcount; 13010 13011 li2 = listitem_alloc(); 13012 if (li2 == NULL) 13013 break; 13014 list_append(l2, li2); 13015 li2->li_tv.v_type = VAR_STRING; 13016 li2->li_tv.v_lock = 0; 13017 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 13018 13019 li2 = listitem_alloc(); 13020 if (li2 == NULL) 13021 break; 13022 list_append(l2, li2); 13023 copy_tv(&di->di_tv, &li2->li_tv); 13024 } 13025 } 13026 } 13027 } 13028 13029 /* 13030 * "items(dict)" function 13031 */ 13032 static void 13033 f_items(argvars, rettv) 13034 typval_T *argvars; 13035 typval_T *rettv; 13036 { 13037 dict_list(argvars, rettv, 2); 13038 } 13039 13040 /* 13041 * "join()" function 13042 */ 13043 static void 13044 f_join(argvars, rettv) 13045 typval_T *argvars; 13046 typval_T *rettv; 13047 { 13048 garray_T ga; 13049 char_u *sep; 13050 13051 if (argvars[0].v_type != VAR_LIST) 13052 { 13053 EMSG(_(e_listreq)); 13054 return; 13055 } 13056 if (argvars[0].vval.v_list == NULL) 13057 return; 13058 if (argvars[1].v_type == VAR_UNKNOWN) 13059 sep = (char_u *)" "; 13060 else 13061 sep = get_tv_string_chk(&argvars[1]); 13062 13063 rettv->v_type = VAR_STRING; 13064 13065 if (sep != NULL) 13066 { 13067 ga_init2(&ga, (int)sizeof(char), 80); 13068 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 13069 ga_append(&ga, NUL); 13070 rettv->vval.v_string = (char_u *)ga.ga_data; 13071 } 13072 else 13073 rettv->vval.v_string = NULL; 13074 } 13075 13076 /* 13077 * "keys()" function 13078 */ 13079 static void 13080 f_keys(argvars, rettv) 13081 typval_T *argvars; 13082 typval_T *rettv; 13083 { 13084 dict_list(argvars, rettv, 0); 13085 } 13086 13087 /* 13088 * "last_buffer_nr()" function. 13089 */ 13090 static void 13091 f_last_buffer_nr(argvars, rettv) 13092 typval_T *argvars UNUSED; 13093 typval_T *rettv; 13094 { 13095 int n = 0; 13096 buf_T *buf; 13097 13098 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 13099 if (n < buf->b_fnum) 13100 n = buf->b_fnum; 13101 13102 rettv->vval.v_number = n; 13103 } 13104 13105 /* 13106 * "len()" function 13107 */ 13108 static void 13109 f_len(argvars, rettv) 13110 typval_T *argvars; 13111 typval_T *rettv; 13112 { 13113 switch (argvars[0].v_type) 13114 { 13115 case VAR_STRING: 13116 case VAR_NUMBER: 13117 rettv->vval.v_number = (varnumber_T)STRLEN( 13118 get_tv_string(&argvars[0])); 13119 break; 13120 case VAR_LIST: 13121 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 13122 break; 13123 case VAR_DICT: 13124 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 13125 break; 13126 default: 13127 EMSG(_("E701: Invalid type for len()")); 13128 break; 13129 } 13130 } 13131 13132 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 13133 13134 static void 13135 libcall_common(argvars, rettv, type) 13136 typval_T *argvars; 13137 typval_T *rettv; 13138 int type; 13139 { 13140 #ifdef FEAT_LIBCALL 13141 char_u *string_in; 13142 char_u **string_result; 13143 int nr_result; 13144 #endif 13145 13146 rettv->v_type = type; 13147 if (type != VAR_NUMBER) 13148 rettv->vval.v_string = NULL; 13149 13150 if (check_restricted() || check_secure()) 13151 return; 13152 13153 #ifdef FEAT_LIBCALL 13154 /* The first two args must be strings, otherwise its meaningless */ 13155 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 13156 { 13157 string_in = NULL; 13158 if (argvars[2].v_type == VAR_STRING) 13159 string_in = argvars[2].vval.v_string; 13160 if (type == VAR_NUMBER) 13161 string_result = NULL; 13162 else 13163 string_result = &rettv->vval.v_string; 13164 if (mch_libcall(argvars[0].vval.v_string, 13165 argvars[1].vval.v_string, 13166 string_in, 13167 argvars[2].vval.v_number, 13168 string_result, 13169 &nr_result) == OK 13170 && type == VAR_NUMBER) 13171 rettv->vval.v_number = nr_result; 13172 } 13173 #endif 13174 } 13175 13176 /* 13177 * "libcall()" function 13178 */ 13179 static void 13180 f_libcall(argvars, rettv) 13181 typval_T *argvars; 13182 typval_T *rettv; 13183 { 13184 libcall_common(argvars, rettv, VAR_STRING); 13185 } 13186 13187 /* 13188 * "libcallnr()" function 13189 */ 13190 static void 13191 f_libcallnr(argvars, rettv) 13192 typval_T *argvars; 13193 typval_T *rettv; 13194 { 13195 libcall_common(argvars, rettv, VAR_NUMBER); 13196 } 13197 13198 /* 13199 * "line(string)" function 13200 */ 13201 static void 13202 f_line(argvars, rettv) 13203 typval_T *argvars; 13204 typval_T *rettv; 13205 { 13206 linenr_T lnum = 0; 13207 pos_T *fp; 13208 int fnum; 13209 13210 fp = var2fpos(&argvars[0], TRUE, &fnum); 13211 if (fp != NULL) 13212 lnum = fp->lnum; 13213 rettv->vval.v_number = lnum; 13214 } 13215 13216 /* 13217 * "line2byte(lnum)" function 13218 */ 13219 static void 13220 f_line2byte(argvars, rettv) 13221 typval_T *argvars UNUSED; 13222 typval_T *rettv; 13223 { 13224 #ifndef FEAT_BYTEOFF 13225 rettv->vval.v_number = -1; 13226 #else 13227 linenr_T lnum; 13228 13229 lnum = get_tv_lnum(argvars); 13230 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13231 rettv->vval.v_number = -1; 13232 else 13233 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 13234 if (rettv->vval.v_number >= 0) 13235 ++rettv->vval.v_number; 13236 #endif 13237 } 13238 13239 /* 13240 * "lispindent(lnum)" function 13241 */ 13242 static void 13243 f_lispindent(argvars, rettv) 13244 typval_T *argvars; 13245 typval_T *rettv; 13246 { 13247 #ifdef FEAT_LISP 13248 pos_T pos; 13249 linenr_T lnum; 13250 13251 pos = curwin->w_cursor; 13252 lnum = get_tv_lnum(argvars); 13253 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 13254 { 13255 curwin->w_cursor.lnum = lnum; 13256 rettv->vval.v_number = get_lisp_indent(); 13257 curwin->w_cursor = pos; 13258 } 13259 else 13260 #endif 13261 rettv->vval.v_number = -1; 13262 } 13263 13264 /* 13265 * "localtime()" function 13266 */ 13267 static void 13268 f_localtime(argvars, rettv) 13269 typval_T *argvars UNUSED; 13270 typval_T *rettv; 13271 { 13272 rettv->vval.v_number = (varnumber_T)time(NULL); 13273 } 13274 13275 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 13276 13277 static void 13278 get_maparg(argvars, rettv, exact) 13279 typval_T *argvars; 13280 typval_T *rettv; 13281 int exact; 13282 { 13283 char_u *keys; 13284 char_u *which; 13285 char_u buf[NUMBUFLEN]; 13286 char_u *keys_buf = NULL; 13287 char_u *rhs; 13288 int mode; 13289 garray_T ga; 13290 int abbr = FALSE; 13291 13292 /* return empty string for failure */ 13293 rettv->v_type = VAR_STRING; 13294 rettv->vval.v_string = NULL; 13295 13296 keys = get_tv_string(&argvars[0]); 13297 if (*keys == NUL) 13298 return; 13299 13300 if (argvars[1].v_type != VAR_UNKNOWN) 13301 { 13302 which = get_tv_string_buf_chk(&argvars[1], buf); 13303 if (argvars[2].v_type != VAR_UNKNOWN) 13304 abbr = get_tv_number(&argvars[2]); 13305 } 13306 else 13307 which = (char_u *)""; 13308 if (which == NULL) 13309 return; 13310 13311 mode = get_map_mode(&which, 0); 13312 13313 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); 13314 rhs = check_map(keys, mode, exact, FALSE, abbr); 13315 vim_free(keys_buf); 13316 if (rhs != NULL) 13317 { 13318 ga_init(&ga); 13319 ga.ga_itemsize = 1; 13320 ga.ga_growsize = 40; 13321 13322 while (*rhs != NUL) 13323 ga_concat(&ga, str2special(&rhs, FALSE)); 13324 13325 ga_append(&ga, NUL); 13326 rettv->vval.v_string = (char_u *)ga.ga_data; 13327 } 13328 } 13329 13330 #ifdef FEAT_FLOAT 13331 /* 13332 * "log()" function 13333 */ 13334 static void 13335 f_log(argvars, rettv) 13336 typval_T *argvars; 13337 typval_T *rettv; 13338 { 13339 float_T f; 13340 13341 rettv->v_type = VAR_FLOAT; 13342 if (get_float_arg(argvars, &f) == OK) 13343 rettv->vval.v_float = log(f); 13344 else 13345 rettv->vval.v_float = 0.0; 13346 } 13347 13348 /* 13349 * "log10()" function 13350 */ 13351 static void 13352 f_log10(argvars, rettv) 13353 typval_T *argvars; 13354 typval_T *rettv; 13355 { 13356 float_T f; 13357 13358 rettv->v_type = VAR_FLOAT; 13359 if (get_float_arg(argvars, &f) == OK) 13360 rettv->vval.v_float = log10(f); 13361 else 13362 rettv->vval.v_float = 0.0; 13363 } 13364 #endif 13365 13366 /* 13367 * "map()" function 13368 */ 13369 static void 13370 f_map(argvars, rettv) 13371 typval_T *argvars; 13372 typval_T *rettv; 13373 { 13374 filter_map(argvars, rettv, TRUE); 13375 } 13376 13377 /* 13378 * "maparg()" function 13379 */ 13380 static void 13381 f_maparg(argvars, rettv) 13382 typval_T *argvars; 13383 typval_T *rettv; 13384 { 13385 get_maparg(argvars, rettv, TRUE); 13386 } 13387 13388 /* 13389 * "mapcheck()" function 13390 */ 13391 static void 13392 f_mapcheck(argvars, rettv) 13393 typval_T *argvars; 13394 typval_T *rettv; 13395 { 13396 get_maparg(argvars, rettv, FALSE); 13397 } 13398 13399 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 13400 13401 static void 13402 find_some_match(argvars, rettv, type) 13403 typval_T *argvars; 13404 typval_T *rettv; 13405 int type; 13406 { 13407 char_u *str = NULL; 13408 char_u *expr = NULL; 13409 char_u *pat; 13410 regmatch_T regmatch; 13411 char_u patbuf[NUMBUFLEN]; 13412 char_u strbuf[NUMBUFLEN]; 13413 char_u *save_cpo; 13414 long start = 0; 13415 long nth = 1; 13416 colnr_T startcol = 0; 13417 int match = 0; 13418 list_T *l = NULL; 13419 listitem_T *li = NULL; 13420 long idx = 0; 13421 char_u *tofree = NULL; 13422 13423 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13424 save_cpo = p_cpo; 13425 p_cpo = (char_u *)""; 13426 13427 rettv->vval.v_number = -1; 13428 if (type == 3) 13429 { 13430 /* return empty list when there are no matches */ 13431 if (rettv_list_alloc(rettv) == FAIL) 13432 goto theend; 13433 } 13434 else if (type == 2) 13435 { 13436 rettv->v_type = VAR_STRING; 13437 rettv->vval.v_string = NULL; 13438 } 13439 13440 if (argvars[0].v_type == VAR_LIST) 13441 { 13442 if ((l = argvars[0].vval.v_list) == NULL) 13443 goto theend; 13444 li = l->lv_first; 13445 } 13446 else 13447 expr = str = get_tv_string(&argvars[0]); 13448 13449 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13450 if (pat == NULL) 13451 goto theend; 13452 13453 if (argvars[2].v_type != VAR_UNKNOWN) 13454 { 13455 int error = FALSE; 13456 13457 start = get_tv_number_chk(&argvars[2], &error); 13458 if (error) 13459 goto theend; 13460 if (l != NULL) 13461 { 13462 li = list_find(l, start); 13463 if (li == NULL) 13464 goto theend; 13465 idx = l->lv_idx; /* use the cached index */ 13466 } 13467 else 13468 { 13469 if (start < 0) 13470 start = 0; 13471 if (start > (long)STRLEN(str)) 13472 goto theend; 13473 /* When "count" argument is there ignore matches before "start", 13474 * otherwise skip part of the string. Differs when pattern is "^" 13475 * or "\<". */ 13476 if (argvars[3].v_type != VAR_UNKNOWN) 13477 startcol = start; 13478 else 13479 str += start; 13480 } 13481 13482 if (argvars[3].v_type != VAR_UNKNOWN) 13483 nth = get_tv_number_chk(&argvars[3], &error); 13484 if (error) 13485 goto theend; 13486 } 13487 13488 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13489 if (regmatch.regprog != NULL) 13490 { 13491 regmatch.rm_ic = p_ic; 13492 13493 for (;;) 13494 { 13495 if (l != NULL) 13496 { 13497 if (li == NULL) 13498 { 13499 match = FALSE; 13500 break; 13501 } 13502 vim_free(tofree); 13503 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 13504 if (str == NULL) 13505 break; 13506 } 13507 13508 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 13509 13510 if (match && --nth <= 0) 13511 break; 13512 if (l == NULL && !match) 13513 break; 13514 13515 /* Advance to just after the match. */ 13516 if (l != NULL) 13517 { 13518 li = li->li_next; 13519 ++idx; 13520 } 13521 else 13522 { 13523 #ifdef FEAT_MBYTE 13524 startcol = (colnr_T)(regmatch.startp[0] 13525 + (*mb_ptr2len)(regmatch.startp[0]) - str); 13526 #else 13527 startcol = (colnr_T)(regmatch.startp[0] + 1 - str); 13528 #endif 13529 } 13530 } 13531 13532 if (match) 13533 { 13534 if (type == 3) 13535 { 13536 int i; 13537 13538 /* return list with matched string and submatches */ 13539 for (i = 0; i < NSUBEXP; ++i) 13540 { 13541 if (regmatch.endp[i] == NULL) 13542 { 13543 if (list_append_string(rettv->vval.v_list, 13544 (char_u *)"", 0) == FAIL) 13545 break; 13546 } 13547 else if (list_append_string(rettv->vval.v_list, 13548 regmatch.startp[i], 13549 (int)(regmatch.endp[i] - regmatch.startp[i])) 13550 == FAIL) 13551 break; 13552 } 13553 } 13554 else if (type == 2) 13555 { 13556 /* return matched string */ 13557 if (l != NULL) 13558 copy_tv(&li->li_tv, rettv); 13559 else 13560 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 13561 (int)(regmatch.endp[0] - regmatch.startp[0])); 13562 } 13563 else if (l != NULL) 13564 rettv->vval.v_number = idx; 13565 else 13566 { 13567 if (type != 0) 13568 rettv->vval.v_number = 13569 (varnumber_T)(regmatch.startp[0] - str); 13570 else 13571 rettv->vval.v_number = 13572 (varnumber_T)(regmatch.endp[0] - str); 13573 rettv->vval.v_number += (varnumber_T)(str - expr); 13574 } 13575 } 13576 vim_free(regmatch.regprog); 13577 } 13578 13579 theend: 13580 vim_free(tofree); 13581 p_cpo = save_cpo; 13582 } 13583 13584 /* 13585 * "match()" function 13586 */ 13587 static void 13588 f_match(argvars, rettv) 13589 typval_T *argvars; 13590 typval_T *rettv; 13591 { 13592 find_some_match(argvars, rettv, 1); 13593 } 13594 13595 /* 13596 * "matchadd()" function 13597 */ 13598 static void 13599 f_matchadd(argvars, rettv) 13600 typval_T *argvars; 13601 typval_T *rettv; 13602 { 13603 #ifdef FEAT_SEARCH_EXTRA 13604 char_u buf[NUMBUFLEN]; 13605 char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */ 13606 char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */ 13607 int prio = 10; /* default priority */ 13608 int id = -1; 13609 int error = FALSE; 13610 13611 rettv->vval.v_number = -1; 13612 13613 if (grp == NULL || pat == NULL) 13614 return; 13615 if (argvars[2].v_type != VAR_UNKNOWN) 13616 { 13617 prio = get_tv_number_chk(&argvars[2], &error); 13618 if (argvars[3].v_type != VAR_UNKNOWN) 13619 id = get_tv_number_chk(&argvars[3], &error); 13620 } 13621 if (error == TRUE) 13622 return; 13623 if (id >= 1 && id <= 3) 13624 { 13625 EMSGN("E798: ID is reserved for \":match\": %ld", id); 13626 return; 13627 } 13628 13629 rettv->vval.v_number = match_add(curwin, grp, pat, prio, id); 13630 #endif 13631 } 13632 13633 /* 13634 * "matcharg()" function 13635 */ 13636 static void 13637 f_matcharg(argvars, rettv) 13638 typval_T *argvars; 13639 typval_T *rettv; 13640 { 13641 if (rettv_list_alloc(rettv) == OK) 13642 { 13643 #ifdef FEAT_SEARCH_EXTRA 13644 int id = get_tv_number(&argvars[0]); 13645 matchitem_T *m; 13646 13647 if (id >= 1 && id <= 3) 13648 { 13649 if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) 13650 { 13651 list_append_string(rettv->vval.v_list, 13652 syn_id2name(m->hlg_id), -1); 13653 list_append_string(rettv->vval.v_list, m->pattern, -1); 13654 } 13655 else 13656 { 13657 list_append_string(rettv->vval.v_list, NUL, -1); 13658 list_append_string(rettv->vval.v_list, NUL, -1); 13659 } 13660 } 13661 #endif 13662 } 13663 } 13664 13665 /* 13666 * "matchdelete()" function 13667 */ 13668 static void 13669 f_matchdelete(argvars, rettv) 13670 typval_T *argvars; 13671 typval_T *rettv; 13672 { 13673 #ifdef FEAT_SEARCH_EXTRA 13674 rettv->vval.v_number = match_delete(curwin, 13675 (int)get_tv_number(&argvars[0]), TRUE); 13676 #endif 13677 } 13678 13679 /* 13680 * "matchend()" function 13681 */ 13682 static void 13683 f_matchend(argvars, rettv) 13684 typval_T *argvars; 13685 typval_T *rettv; 13686 { 13687 find_some_match(argvars, rettv, 0); 13688 } 13689 13690 /* 13691 * "matchlist()" function 13692 */ 13693 static void 13694 f_matchlist(argvars, rettv) 13695 typval_T *argvars; 13696 typval_T *rettv; 13697 { 13698 find_some_match(argvars, rettv, 3); 13699 } 13700 13701 /* 13702 * "matchstr()" function 13703 */ 13704 static void 13705 f_matchstr(argvars, rettv) 13706 typval_T *argvars; 13707 typval_T *rettv; 13708 { 13709 find_some_match(argvars, rettv, 2); 13710 } 13711 13712 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 13713 13714 static void 13715 max_min(argvars, rettv, domax) 13716 typval_T *argvars; 13717 typval_T *rettv; 13718 int domax; 13719 { 13720 long n = 0; 13721 long i; 13722 int error = FALSE; 13723 13724 if (argvars[0].v_type == VAR_LIST) 13725 { 13726 list_T *l; 13727 listitem_T *li; 13728 13729 l = argvars[0].vval.v_list; 13730 if (l != NULL) 13731 { 13732 li = l->lv_first; 13733 if (li != NULL) 13734 { 13735 n = get_tv_number_chk(&li->li_tv, &error); 13736 for (;;) 13737 { 13738 li = li->li_next; 13739 if (li == NULL) 13740 break; 13741 i = get_tv_number_chk(&li->li_tv, &error); 13742 if (domax ? i > n : i < n) 13743 n = i; 13744 } 13745 } 13746 } 13747 } 13748 else if (argvars[0].v_type == VAR_DICT) 13749 { 13750 dict_T *d; 13751 int first = TRUE; 13752 hashitem_T *hi; 13753 int todo; 13754 13755 d = argvars[0].vval.v_dict; 13756 if (d != NULL) 13757 { 13758 todo = (int)d->dv_hashtab.ht_used; 13759 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 13760 { 13761 if (!HASHITEM_EMPTY(hi)) 13762 { 13763 --todo; 13764 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 13765 if (first) 13766 { 13767 n = i; 13768 first = FALSE; 13769 } 13770 else if (domax ? i > n : i < n) 13771 n = i; 13772 } 13773 } 13774 } 13775 } 13776 else 13777 EMSG(_(e_listdictarg)); 13778 rettv->vval.v_number = error ? 0 : n; 13779 } 13780 13781 /* 13782 * "max()" function 13783 */ 13784 static void 13785 f_max(argvars, rettv) 13786 typval_T *argvars; 13787 typval_T *rettv; 13788 { 13789 max_min(argvars, rettv, TRUE); 13790 } 13791 13792 /* 13793 * "min()" function 13794 */ 13795 static void 13796 f_min(argvars, rettv) 13797 typval_T *argvars; 13798 typval_T *rettv; 13799 { 13800 max_min(argvars, rettv, FALSE); 13801 } 13802 13803 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 13804 13805 /* 13806 * Create the directory in which "dir" is located, and higher levels when 13807 * needed. 13808 */ 13809 static int 13810 mkdir_recurse(dir, prot) 13811 char_u *dir; 13812 int prot; 13813 { 13814 char_u *p; 13815 char_u *updir; 13816 int r = FAIL; 13817 13818 /* Get end of directory name in "dir". 13819 * We're done when it's "/" or "c:/". */ 13820 p = gettail_sep(dir); 13821 if (p <= get_past_head(dir)) 13822 return OK; 13823 13824 /* If the directory exists we're done. Otherwise: create it.*/ 13825 updir = vim_strnsave(dir, (int)(p - dir)); 13826 if (updir == NULL) 13827 return FAIL; 13828 if (mch_isdir(updir)) 13829 r = OK; 13830 else if (mkdir_recurse(updir, prot) == OK) 13831 r = vim_mkdir_emsg(updir, prot); 13832 vim_free(updir); 13833 return r; 13834 } 13835 13836 #ifdef vim_mkdir 13837 /* 13838 * "mkdir()" function 13839 */ 13840 static void 13841 f_mkdir(argvars, rettv) 13842 typval_T *argvars; 13843 typval_T *rettv; 13844 { 13845 char_u *dir; 13846 char_u buf[NUMBUFLEN]; 13847 int prot = 0755; 13848 13849 rettv->vval.v_number = FAIL; 13850 if (check_restricted() || check_secure()) 13851 return; 13852 13853 dir = get_tv_string_buf(&argvars[0], buf); 13854 if (argvars[1].v_type != VAR_UNKNOWN) 13855 { 13856 if (argvars[2].v_type != VAR_UNKNOWN) 13857 prot = get_tv_number_chk(&argvars[2], NULL); 13858 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 13859 mkdir_recurse(dir, prot); 13860 } 13861 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 13862 } 13863 #endif 13864 13865 /* 13866 * "mode()" function 13867 */ 13868 static void 13869 f_mode(argvars, rettv) 13870 typval_T *argvars; 13871 typval_T *rettv; 13872 { 13873 char_u buf[3]; 13874 13875 buf[1] = NUL; 13876 buf[2] = NUL; 13877 13878 #ifdef FEAT_VISUAL 13879 if (VIsual_active) 13880 { 13881 if (VIsual_select) 13882 buf[0] = VIsual_mode + 's' - 'v'; 13883 else 13884 buf[0] = VIsual_mode; 13885 } 13886 else 13887 #endif 13888 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE 13889 || State == CONFIRM) 13890 { 13891 buf[0] = 'r'; 13892 if (State == ASKMORE) 13893 buf[1] = 'm'; 13894 else if (State == CONFIRM) 13895 buf[1] = '?'; 13896 } 13897 else if (State == EXTERNCMD) 13898 buf[0] = '!'; 13899 else if (State & INSERT) 13900 { 13901 #ifdef FEAT_VREPLACE 13902 if (State & VREPLACE_FLAG) 13903 { 13904 buf[0] = 'R'; 13905 buf[1] = 'v'; 13906 } 13907 else 13908 #endif 13909 if (State & REPLACE_FLAG) 13910 buf[0] = 'R'; 13911 else 13912 buf[0] = 'i'; 13913 } 13914 else if (State & CMDLINE) 13915 { 13916 buf[0] = 'c'; 13917 if (exmode_active) 13918 buf[1] = 'v'; 13919 } 13920 else if (exmode_active) 13921 { 13922 buf[0] = 'c'; 13923 buf[1] = 'e'; 13924 } 13925 else 13926 { 13927 buf[0] = 'n'; 13928 if (finish_op) 13929 buf[1] = 'o'; 13930 } 13931 13932 /* Clear out the minor mode when the argument is not a non-zero number or 13933 * non-empty string. */ 13934 if (!non_zero_arg(&argvars[0])) 13935 buf[1] = NUL; 13936 13937 rettv->vval.v_string = vim_strsave(buf); 13938 rettv->v_type = VAR_STRING; 13939 } 13940 13941 #ifdef FEAT_MZSCHEME 13942 /* 13943 * "mzeval()" function 13944 */ 13945 static void 13946 f_mzeval(argvars, rettv) 13947 typval_T *argvars; 13948 typval_T *rettv; 13949 { 13950 char_u *str; 13951 char_u buf[NUMBUFLEN]; 13952 13953 str = get_tv_string_buf(&argvars[0], buf); 13954 do_mzeval(str, rettv); 13955 } 13956 #endif 13957 13958 /* 13959 * "nextnonblank()" function 13960 */ 13961 static void 13962 f_nextnonblank(argvars, rettv) 13963 typval_T *argvars; 13964 typval_T *rettv; 13965 { 13966 linenr_T lnum; 13967 13968 for (lnum = get_tv_lnum(argvars); ; ++lnum) 13969 { 13970 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 13971 { 13972 lnum = 0; 13973 break; 13974 } 13975 if (*skipwhite(ml_get(lnum)) != NUL) 13976 break; 13977 } 13978 rettv->vval.v_number = lnum; 13979 } 13980 13981 /* 13982 * "nr2char()" function 13983 */ 13984 static void 13985 f_nr2char(argvars, rettv) 13986 typval_T *argvars; 13987 typval_T *rettv; 13988 { 13989 char_u buf[NUMBUFLEN]; 13990 13991 #ifdef FEAT_MBYTE 13992 if (has_mbyte) 13993 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 13994 else 13995 #endif 13996 { 13997 buf[0] = (char_u)get_tv_number(&argvars[0]); 13998 buf[1] = NUL; 13999 } 14000 rettv->v_type = VAR_STRING; 14001 rettv->vval.v_string = vim_strsave(buf); 14002 } 14003 14004 /* 14005 * "pathshorten()" function 14006 */ 14007 static void 14008 f_pathshorten(argvars, rettv) 14009 typval_T *argvars; 14010 typval_T *rettv; 14011 { 14012 char_u *p; 14013 14014 rettv->v_type = VAR_STRING; 14015 p = get_tv_string_chk(&argvars[0]); 14016 if (p == NULL) 14017 rettv->vval.v_string = NULL; 14018 else 14019 { 14020 p = vim_strsave(p); 14021 rettv->vval.v_string = p; 14022 if (p != NULL) 14023 shorten_dir(p); 14024 } 14025 } 14026 14027 #ifdef FEAT_FLOAT 14028 /* 14029 * "pow()" function 14030 */ 14031 static void 14032 f_pow(argvars, rettv) 14033 typval_T *argvars; 14034 typval_T *rettv; 14035 { 14036 float_T fx, fy; 14037 14038 rettv->v_type = VAR_FLOAT; 14039 if (get_float_arg(argvars, &fx) == OK 14040 && get_float_arg(&argvars[1], &fy) == OK) 14041 rettv->vval.v_float = pow(fx, fy); 14042 else 14043 rettv->vval.v_float = 0.0; 14044 } 14045 #endif 14046 14047 /* 14048 * "prevnonblank()" function 14049 */ 14050 static void 14051 f_prevnonblank(argvars, rettv) 14052 typval_T *argvars; 14053 typval_T *rettv; 14054 { 14055 linenr_T lnum; 14056 14057 lnum = get_tv_lnum(argvars); 14058 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 14059 lnum = 0; 14060 else 14061 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 14062 --lnum; 14063 rettv->vval.v_number = lnum; 14064 } 14065 14066 #ifdef HAVE_STDARG_H 14067 /* This dummy va_list is here because: 14068 * - passing a NULL pointer doesn't work when va_list isn't a pointer 14069 * - locally in the function results in a "used before set" warning 14070 * - using va_start() to initialize it gives "function with fixed args" error */ 14071 static va_list ap; 14072 #endif 14073 14074 /* 14075 * "printf()" function 14076 */ 14077 static void 14078 f_printf(argvars, rettv) 14079 typval_T *argvars; 14080 typval_T *rettv; 14081 { 14082 rettv->v_type = VAR_STRING; 14083 rettv->vval.v_string = NULL; 14084 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 14085 { 14086 char_u buf[NUMBUFLEN]; 14087 int len; 14088 char_u *s; 14089 int saved_did_emsg = did_emsg; 14090 char *fmt; 14091 14092 /* Get the required length, allocate the buffer and do it for real. */ 14093 did_emsg = FALSE; 14094 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 14095 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 14096 if (!did_emsg) 14097 { 14098 s = alloc(len + 1); 14099 if (s != NULL) 14100 { 14101 rettv->vval.v_string = s; 14102 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 14103 } 14104 } 14105 did_emsg |= saved_did_emsg; 14106 } 14107 #endif 14108 } 14109 14110 /* 14111 * "pumvisible()" function 14112 */ 14113 static void 14114 f_pumvisible(argvars, rettv) 14115 typval_T *argvars UNUSED; 14116 typval_T *rettv UNUSED; 14117 { 14118 #ifdef FEAT_INS_EXPAND 14119 if (pum_visible()) 14120 rettv->vval.v_number = 1; 14121 #endif 14122 } 14123 14124 /* 14125 * "range()" function 14126 */ 14127 static void 14128 f_range(argvars, rettv) 14129 typval_T *argvars; 14130 typval_T *rettv; 14131 { 14132 long start; 14133 long end; 14134 long stride = 1; 14135 long i; 14136 int error = FALSE; 14137 14138 start = get_tv_number_chk(&argvars[0], &error); 14139 if (argvars[1].v_type == VAR_UNKNOWN) 14140 { 14141 end = start - 1; 14142 start = 0; 14143 } 14144 else 14145 { 14146 end = get_tv_number_chk(&argvars[1], &error); 14147 if (argvars[2].v_type != VAR_UNKNOWN) 14148 stride = get_tv_number_chk(&argvars[2], &error); 14149 } 14150 14151 if (error) 14152 return; /* type error; errmsg already given */ 14153 if (stride == 0) 14154 EMSG(_("E726: Stride is zero")); 14155 else if (stride > 0 ? end + 1 < start : end - 1 > start) 14156 EMSG(_("E727: Start past end")); 14157 else 14158 { 14159 if (rettv_list_alloc(rettv) == OK) 14160 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 14161 if (list_append_number(rettv->vval.v_list, 14162 (varnumber_T)i) == FAIL) 14163 break; 14164 } 14165 } 14166 14167 /* 14168 * "readfile()" function 14169 */ 14170 static void 14171 f_readfile(argvars, rettv) 14172 typval_T *argvars; 14173 typval_T *rettv; 14174 { 14175 int binary = FALSE; 14176 char_u *fname; 14177 FILE *fd; 14178 listitem_T *li; 14179 #define FREAD_SIZE 200 /* optimized for text lines */ 14180 char_u buf[FREAD_SIZE]; 14181 int readlen; /* size of last fread() */ 14182 int buflen; /* nr of valid chars in buf[] */ 14183 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 14184 int tolist; /* first byte in buf[] still to be put in list */ 14185 int chop; /* how many CR to chop off */ 14186 char_u *prev = NULL; /* previously read bytes, if any */ 14187 int prevlen = 0; /* length of "prev" if not NULL */ 14188 char_u *s; 14189 int len; 14190 long maxline = MAXLNUM; 14191 long cnt = 0; 14192 14193 if (argvars[1].v_type != VAR_UNKNOWN) 14194 { 14195 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 14196 binary = TRUE; 14197 if (argvars[2].v_type != VAR_UNKNOWN) 14198 maxline = get_tv_number(&argvars[2]); 14199 } 14200 14201 if (rettv_list_alloc(rettv) == FAIL) 14202 return; 14203 14204 /* Always open the file in binary mode, library functions have a mind of 14205 * their own about CR-LF conversion. */ 14206 fname = get_tv_string(&argvars[0]); 14207 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 14208 { 14209 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 14210 return; 14211 } 14212 14213 filtd = 0; 14214 while (cnt < maxline || maxline < 0) 14215 { 14216 readlen = (int)fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 14217 buflen = filtd + readlen; 14218 tolist = 0; 14219 for ( ; filtd < buflen || readlen <= 0; ++filtd) 14220 { 14221 if (buf[filtd] == '\n' || readlen <= 0) 14222 { 14223 /* Only when in binary mode add an empty list item when the 14224 * last line ends in a '\n'. */ 14225 if (!binary && readlen == 0 && filtd == 0) 14226 break; 14227 14228 /* Found end-of-line or end-of-file: add a text line to the 14229 * list. */ 14230 chop = 0; 14231 if (!binary) 14232 while (filtd - chop - 1 >= tolist 14233 && buf[filtd - chop - 1] == '\r') 14234 ++chop; 14235 len = filtd - tolist - chop; 14236 if (prev == NULL) 14237 s = vim_strnsave(buf + tolist, len); 14238 else 14239 { 14240 s = alloc((unsigned)(prevlen + len + 1)); 14241 if (s != NULL) 14242 { 14243 mch_memmove(s, prev, prevlen); 14244 vim_free(prev); 14245 prev = NULL; 14246 mch_memmove(s + prevlen, buf + tolist, len); 14247 s[prevlen + len] = NUL; 14248 } 14249 } 14250 tolist = filtd + 1; 14251 14252 li = listitem_alloc(); 14253 if (li == NULL) 14254 { 14255 vim_free(s); 14256 break; 14257 } 14258 li->li_tv.v_type = VAR_STRING; 14259 li->li_tv.v_lock = 0; 14260 li->li_tv.vval.v_string = s; 14261 list_append(rettv->vval.v_list, li); 14262 14263 if (++cnt >= maxline && maxline >= 0) 14264 break; 14265 if (readlen <= 0) 14266 break; 14267 } 14268 else if (buf[filtd] == NUL) 14269 buf[filtd] = '\n'; 14270 } 14271 if (readlen <= 0) 14272 break; 14273 14274 if (tolist == 0) 14275 { 14276 /* "buf" is full, need to move text to an allocated buffer */ 14277 if (prev == NULL) 14278 { 14279 prev = vim_strnsave(buf, buflen); 14280 prevlen = buflen; 14281 } 14282 else 14283 { 14284 s = alloc((unsigned)(prevlen + buflen)); 14285 if (s != NULL) 14286 { 14287 mch_memmove(s, prev, prevlen); 14288 mch_memmove(s + prevlen, buf, buflen); 14289 vim_free(prev); 14290 prev = s; 14291 prevlen += buflen; 14292 } 14293 } 14294 filtd = 0; 14295 } 14296 else 14297 { 14298 mch_memmove(buf, buf + tolist, buflen - tolist); 14299 filtd -= tolist; 14300 } 14301 } 14302 14303 /* 14304 * For a negative line count use only the lines at the end of the file, 14305 * free the rest. 14306 */ 14307 if (maxline < 0) 14308 while (cnt > -maxline) 14309 { 14310 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 14311 --cnt; 14312 } 14313 14314 vim_free(prev); 14315 fclose(fd); 14316 } 14317 14318 #if defined(FEAT_RELTIME) 14319 static int list2proftime __ARGS((typval_T *arg, proftime_T *tm)); 14320 14321 /* 14322 * Convert a List to proftime_T. 14323 * Return FAIL when there is something wrong. 14324 */ 14325 static int 14326 list2proftime(arg, tm) 14327 typval_T *arg; 14328 proftime_T *tm; 14329 { 14330 long n1, n2; 14331 int error = FALSE; 14332 14333 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 14334 || arg->vval.v_list->lv_len != 2) 14335 return FAIL; 14336 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 14337 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 14338 # ifdef WIN3264 14339 tm->HighPart = n1; 14340 tm->LowPart = n2; 14341 # else 14342 tm->tv_sec = n1; 14343 tm->tv_usec = n2; 14344 # endif 14345 return error ? FAIL : OK; 14346 } 14347 #endif /* FEAT_RELTIME */ 14348 14349 /* 14350 * "reltime()" function 14351 */ 14352 static void 14353 f_reltime(argvars, rettv) 14354 typval_T *argvars; 14355 typval_T *rettv; 14356 { 14357 #ifdef FEAT_RELTIME 14358 proftime_T res; 14359 proftime_T start; 14360 14361 if (argvars[0].v_type == VAR_UNKNOWN) 14362 { 14363 /* No arguments: get current time. */ 14364 profile_start(&res); 14365 } 14366 else if (argvars[1].v_type == VAR_UNKNOWN) 14367 { 14368 if (list2proftime(&argvars[0], &res) == FAIL) 14369 return; 14370 profile_end(&res); 14371 } 14372 else 14373 { 14374 /* Two arguments: compute the difference. */ 14375 if (list2proftime(&argvars[0], &start) == FAIL 14376 || list2proftime(&argvars[1], &res) == FAIL) 14377 return; 14378 profile_sub(&res, &start); 14379 } 14380 14381 if (rettv_list_alloc(rettv) == OK) 14382 { 14383 long n1, n2; 14384 14385 # ifdef WIN3264 14386 n1 = res.HighPart; 14387 n2 = res.LowPart; 14388 # else 14389 n1 = res.tv_sec; 14390 n2 = res.tv_usec; 14391 # endif 14392 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 14393 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 14394 } 14395 #endif 14396 } 14397 14398 /* 14399 * "reltimestr()" function 14400 */ 14401 static void 14402 f_reltimestr(argvars, rettv) 14403 typval_T *argvars; 14404 typval_T *rettv; 14405 { 14406 #ifdef FEAT_RELTIME 14407 proftime_T tm; 14408 #endif 14409 14410 rettv->v_type = VAR_STRING; 14411 rettv->vval.v_string = NULL; 14412 #ifdef FEAT_RELTIME 14413 if (list2proftime(&argvars[0], &tm) == OK) 14414 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 14415 #endif 14416 } 14417 14418 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 14419 static void make_connection __ARGS((void)); 14420 static int check_connection __ARGS((void)); 14421 14422 static void 14423 make_connection() 14424 { 14425 if (X_DISPLAY == NULL 14426 # ifdef FEAT_GUI 14427 && !gui.in_use 14428 # endif 14429 ) 14430 { 14431 x_force_connect = TRUE; 14432 setup_term_clip(); 14433 x_force_connect = FALSE; 14434 } 14435 } 14436 14437 static int 14438 check_connection() 14439 { 14440 make_connection(); 14441 if (X_DISPLAY == NULL) 14442 { 14443 EMSG(_("E240: No connection to Vim server")); 14444 return FAIL; 14445 } 14446 return OK; 14447 } 14448 #endif 14449 14450 #ifdef FEAT_CLIENTSERVER 14451 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 14452 14453 static void 14454 remote_common(argvars, rettv, expr) 14455 typval_T *argvars; 14456 typval_T *rettv; 14457 int expr; 14458 { 14459 char_u *server_name; 14460 char_u *keys; 14461 char_u *r = NULL; 14462 char_u buf[NUMBUFLEN]; 14463 # ifdef WIN32 14464 HWND w; 14465 # else 14466 Window w; 14467 # endif 14468 14469 if (check_restricted() || check_secure()) 14470 return; 14471 14472 # ifdef FEAT_X11 14473 if (check_connection() == FAIL) 14474 return; 14475 # endif 14476 14477 server_name = get_tv_string_chk(&argvars[0]); 14478 if (server_name == NULL) 14479 return; /* type error; errmsg already given */ 14480 keys = get_tv_string_buf(&argvars[1], buf); 14481 # ifdef WIN32 14482 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 14483 # else 14484 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 14485 < 0) 14486 # endif 14487 { 14488 if (r != NULL) 14489 EMSG(r); /* sending worked but evaluation failed */ 14490 else 14491 EMSG2(_("E241: Unable to send to %s"), server_name); 14492 return; 14493 } 14494 14495 rettv->vval.v_string = r; 14496 14497 if (argvars[2].v_type != VAR_UNKNOWN) 14498 { 14499 dictitem_T v; 14500 char_u str[30]; 14501 char_u *idvar; 14502 14503 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 14504 v.di_tv.v_type = VAR_STRING; 14505 v.di_tv.vval.v_string = vim_strsave(str); 14506 idvar = get_tv_string_chk(&argvars[2]); 14507 if (idvar != NULL) 14508 set_var(idvar, &v.di_tv, FALSE); 14509 vim_free(v.di_tv.vval.v_string); 14510 } 14511 } 14512 #endif 14513 14514 /* 14515 * "remote_expr()" function 14516 */ 14517 static void 14518 f_remote_expr(argvars, rettv) 14519 typval_T *argvars UNUSED; 14520 typval_T *rettv; 14521 { 14522 rettv->v_type = VAR_STRING; 14523 rettv->vval.v_string = NULL; 14524 #ifdef FEAT_CLIENTSERVER 14525 remote_common(argvars, rettv, TRUE); 14526 #endif 14527 } 14528 14529 /* 14530 * "remote_foreground()" function 14531 */ 14532 static void 14533 f_remote_foreground(argvars, rettv) 14534 typval_T *argvars UNUSED; 14535 typval_T *rettv UNUSED; 14536 { 14537 #ifdef FEAT_CLIENTSERVER 14538 # ifdef WIN32 14539 /* On Win32 it's done in this application. */ 14540 { 14541 char_u *server_name = get_tv_string_chk(&argvars[0]); 14542 14543 if (server_name != NULL) 14544 serverForeground(server_name); 14545 } 14546 # else 14547 /* Send a foreground() expression to the server. */ 14548 argvars[1].v_type = VAR_STRING; 14549 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 14550 argvars[2].v_type = VAR_UNKNOWN; 14551 remote_common(argvars, rettv, TRUE); 14552 vim_free(argvars[1].vval.v_string); 14553 # endif 14554 #endif 14555 } 14556 14557 static void 14558 f_remote_peek(argvars, rettv) 14559 typval_T *argvars UNUSED; 14560 typval_T *rettv; 14561 { 14562 #ifdef FEAT_CLIENTSERVER 14563 dictitem_T v; 14564 char_u *s = NULL; 14565 # ifdef WIN32 14566 long_u n = 0; 14567 # endif 14568 char_u *serverid; 14569 14570 if (check_restricted() || check_secure()) 14571 { 14572 rettv->vval.v_number = -1; 14573 return; 14574 } 14575 serverid = get_tv_string_chk(&argvars[0]); 14576 if (serverid == NULL) 14577 { 14578 rettv->vval.v_number = -1; 14579 return; /* type error; errmsg already given */ 14580 } 14581 # ifdef WIN32 14582 sscanf(serverid, SCANF_HEX_LONG_U, &n); 14583 if (n == 0) 14584 rettv->vval.v_number = -1; 14585 else 14586 { 14587 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 14588 rettv->vval.v_number = (s != NULL); 14589 } 14590 # else 14591 if (check_connection() == FAIL) 14592 return; 14593 14594 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 14595 serverStrToWin(serverid), &s); 14596 # endif 14597 14598 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 14599 { 14600 char_u *retvar; 14601 14602 v.di_tv.v_type = VAR_STRING; 14603 v.di_tv.vval.v_string = vim_strsave(s); 14604 retvar = get_tv_string_chk(&argvars[1]); 14605 if (retvar != NULL) 14606 set_var(retvar, &v.di_tv, FALSE); 14607 vim_free(v.di_tv.vval.v_string); 14608 } 14609 #else 14610 rettv->vval.v_number = -1; 14611 #endif 14612 } 14613 14614 static void 14615 f_remote_read(argvars, rettv) 14616 typval_T *argvars UNUSED; 14617 typval_T *rettv; 14618 { 14619 char_u *r = NULL; 14620 14621 #ifdef FEAT_CLIENTSERVER 14622 char_u *serverid = get_tv_string_chk(&argvars[0]); 14623 14624 if (serverid != NULL && !check_restricted() && !check_secure()) 14625 { 14626 # ifdef WIN32 14627 /* The server's HWND is encoded in the 'id' parameter */ 14628 long_u n = 0; 14629 14630 sscanf(serverid, SCANF_HEX_LONG_U, &n); 14631 if (n != 0) 14632 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 14633 if (r == NULL) 14634 # else 14635 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 14636 serverStrToWin(serverid), &r, FALSE) < 0) 14637 # endif 14638 EMSG(_("E277: Unable to read a server reply")); 14639 } 14640 #endif 14641 rettv->v_type = VAR_STRING; 14642 rettv->vval.v_string = r; 14643 } 14644 14645 /* 14646 * "remote_send()" function 14647 */ 14648 static void 14649 f_remote_send(argvars, rettv) 14650 typval_T *argvars UNUSED; 14651 typval_T *rettv; 14652 { 14653 rettv->v_type = VAR_STRING; 14654 rettv->vval.v_string = NULL; 14655 #ifdef FEAT_CLIENTSERVER 14656 remote_common(argvars, rettv, FALSE); 14657 #endif 14658 } 14659 14660 /* 14661 * "remove()" function 14662 */ 14663 static void 14664 f_remove(argvars, rettv) 14665 typval_T *argvars; 14666 typval_T *rettv; 14667 { 14668 list_T *l; 14669 listitem_T *item, *item2; 14670 listitem_T *li; 14671 long idx; 14672 long end; 14673 char_u *key; 14674 dict_T *d; 14675 dictitem_T *di; 14676 14677 if (argvars[0].v_type == VAR_DICT) 14678 { 14679 if (argvars[2].v_type != VAR_UNKNOWN) 14680 EMSG2(_(e_toomanyarg), "remove()"); 14681 else if ((d = argvars[0].vval.v_dict) != NULL 14682 && !tv_check_lock(d->dv_lock, (char_u *)"remove() argument")) 14683 { 14684 key = get_tv_string_chk(&argvars[1]); 14685 if (key != NULL) 14686 { 14687 di = dict_find(d, key, -1); 14688 if (di == NULL) 14689 EMSG2(_(e_dictkey), key); 14690 else 14691 { 14692 *rettv = di->di_tv; 14693 init_tv(&di->di_tv); 14694 dictitem_remove(d, di); 14695 } 14696 } 14697 } 14698 } 14699 else if (argvars[0].v_type != VAR_LIST) 14700 EMSG2(_(e_listdictarg), "remove()"); 14701 else if ((l = argvars[0].vval.v_list) != NULL 14702 && !tv_check_lock(l->lv_lock, (char_u *)"remove() argument")) 14703 { 14704 int error = FALSE; 14705 14706 idx = get_tv_number_chk(&argvars[1], &error); 14707 if (error) 14708 ; /* type error: do nothing, errmsg already given */ 14709 else if ((item = list_find(l, idx)) == NULL) 14710 EMSGN(_(e_listidx), idx); 14711 else 14712 { 14713 if (argvars[2].v_type == VAR_UNKNOWN) 14714 { 14715 /* Remove one item, return its value. */ 14716 list_remove(l, item, item); 14717 *rettv = item->li_tv; 14718 vim_free(item); 14719 } 14720 else 14721 { 14722 /* Remove range of items, return list with values. */ 14723 end = get_tv_number_chk(&argvars[2], &error); 14724 if (error) 14725 ; /* type error: do nothing */ 14726 else if ((item2 = list_find(l, end)) == NULL) 14727 EMSGN(_(e_listidx), end); 14728 else 14729 { 14730 int cnt = 0; 14731 14732 for (li = item; li != NULL; li = li->li_next) 14733 { 14734 ++cnt; 14735 if (li == item2) 14736 break; 14737 } 14738 if (li == NULL) /* didn't find "item2" after "item" */ 14739 EMSG(_(e_invrange)); 14740 else 14741 { 14742 list_remove(l, item, item2); 14743 if (rettv_list_alloc(rettv) == OK) 14744 { 14745 l = rettv->vval.v_list; 14746 l->lv_first = item; 14747 l->lv_last = item2; 14748 item->li_prev = NULL; 14749 item2->li_next = NULL; 14750 l->lv_len = cnt; 14751 } 14752 } 14753 } 14754 } 14755 } 14756 } 14757 } 14758 14759 /* 14760 * "rename({from}, {to})" function 14761 */ 14762 static void 14763 f_rename(argvars, rettv) 14764 typval_T *argvars; 14765 typval_T *rettv; 14766 { 14767 char_u buf[NUMBUFLEN]; 14768 14769 if (check_restricted() || check_secure()) 14770 rettv->vval.v_number = -1; 14771 else 14772 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 14773 get_tv_string_buf(&argvars[1], buf)); 14774 } 14775 14776 /* 14777 * "repeat()" function 14778 */ 14779 static void 14780 f_repeat(argvars, rettv) 14781 typval_T *argvars; 14782 typval_T *rettv; 14783 { 14784 char_u *p; 14785 int n; 14786 int slen; 14787 int len; 14788 char_u *r; 14789 int i; 14790 14791 n = get_tv_number(&argvars[1]); 14792 if (argvars[0].v_type == VAR_LIST) 14793 { 14794 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 14795 while (n-- > 0) 14796 if (list_extend(rettv->vval.v_list, 14797 argvars[0].vval.v_list, NULL) == FAIL) 14798 break; 14799 } 14800 else 14801 { 14802 p = get_tv_string(&argvars[0]); 14803 rettv->v_type = VAR_STRING; 14804 rettv->vval.v_string = NULL; 14805 14806 slen = (int)STRLEN(p); 14807 len = slen * n; 14808 if (len <= 0) 14809 return; 14810 14811 r = alloc(len + 1); 14812 if (r != NULL) 14813 { 14814 for (i = 0; i < n; i++) 14815 mch_memmove(r + i * slen, p, (size_t)slen); 14816 r[len] = NUL; 14817 } 14818 14819 rettv->vval.v_string = r; 14820 } 14821 } 14822 14823 /* 14824 * "resolve()" function 14825 */ 14826 static void 14827 f_resolve(argvars, rettv) 14828 typval_T *argvars; 14829 typval_T *rettv; 14830 { 14831 char_u *p; 14832 14833 p = get_tv_string(&argvars[0]); 14834 #ifdef FEAT_SHORTCUT 14835 { 14836 char_u *v = NULL; 14837 14838 v = mch_resolve_shortcut(p); 14839 if (v != NULL) 14840 rettv->vval.v_string = v; 14841 else 14842 rettv->vval.v_string = vim_strsave(p); 14843 } 14844 #else 14845 # ifdef HAVE_READLINK 14846 { 14847 char_u buf[MAXPATHL + 1]; 14848 char_u *cpy; 14849 int len; 14850 char_u *remain = NULL; 14851 char_u *q; 14852 int is_relative_to_current = FALSE; 14853 int has_trailing_pathsep = FALSE; 14854 int limit = 100; 14855 14856 p = vim_strsave(p); 14857 14858 if (p[0] == '.' && (vim_ispathsep(p[1]) 14859 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 14860 is_relative_to_current = TRUE; 14861 14862 len = STRLEN(p); 14863 if (len > 0 && after_pathsep(p, p + len)) 14864 has_trailing_pathsep = TRUE; 14865 14866 q = getnextcomp(p); 14867 if (*q != NUL) 14868 { 14869 /* Separate the first path component in "p", and keep the 14870 * remainder (beginning with the path separator). */ 14871 remain = vim_strsave(q - 1); 14872 q[-1] = NUL; 14873 } 14874 14875 for (;;) 14876 { 14877 for (;;) 14878 { 14879 len = readlink((char *)p, (char *)buf, MAXPATHL); 14880 if (len <= 0) 14881 break; 14882 buf[len] = NUL; 14883 14884 if (limit-- == 0) 14885 { 14886 vim_free(p); 14887 vim_free(remain); 14888 EMSG(_("E655: Too many symbolic links (cycle?)")); 14889 rettv->vval.v_string = NULL; 14890 goto fail; 14891 } 14892 14893 /* Ensure that the result will have a trailing path separator 14894 * if the argument has one. */ 14895 if (remain == NULL && has_trailing_pathsep) 14896 add_pathsep(buf); 14897 14898 /* Separate the first path component in the link value and 14899 * concatenate the remainders. */ 14900 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 14901 if (*q != NUL) 14902 { 14903 if (remain == NULL) 14904 remain = vim_strsave(q - 1); 14905 else 14906 { 14907 cpy = concat_str(q - 1, remain); 14908 if (cpy != NULL) 14909 { 14910 vim_free(remain); 14911 remain = cpy; 14912 } 14913 } 14914 q[-1] = NUL; 14915 } 14916 14917 q = gettail(p); 14918 if (q > p && *q == NUL) 14919 { 14920 /* Ignore trailing path separator. */ 14921 q[-1] = NUL; 14922 q = gettail(p); 14923 } 14924 if (q > p && !mch_isFullName(buf)) 14925 { 14926 /* symlink is relative to directory of argument */ 14927 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 14928 if (cpy != NULL) 14929 { 14930 STRCPY(cpy, p); 14931 STRCPY(gettail(cpy), buf); 14932 vim_free(p); 14933 p = cpy; 14934 } 14935 } 14936 else 14937 { 14938 vim_free(p); 14939 p = vim_strsave(buf); 14940 } 14941 } 14942 14943 if (remain == NULL) 14944 break; 14945 14946 /* Append the first path component of "remain" to "p". */ 14947 q = getnextcomp(remain + 1); 14948 len = q - remain - (*q != NUL); 14949 cpy = vim_strnsave(p, STRLEN(p) + len); 14950 if (cpy != NULL) 14951 { 14952 STRNCAT(cpy, remain, len); 14953 vim_free(p); 14954 p = cpy; 14955 } 14956 /* Shorten "remain". */ 14957 if (*q != NUL) 14958 STRMOVE(remain, q - 1); 14959 else 14960 { 14961 vim_free(remain); 14962 remain = NULL; 14963 } 14964 } 14965 14966 /* If the result is a relative path name, make it explicitly relative to 14967 * the current directory if and only if the argument had this form. */ 14968 if (!vim_ispathsep(*p)) 14969 { 14970 if (is_relative_to_current 14971 && *p != NUL 14972 && !(p[0] == '.' 14973 && (p[1] == NUL 14974 || vim_ispathsep(p[1]) 14975 || (p[1] == '.' 14976 && (p[2] == NUL 14977 || vim_ispathsep(p[2])))))) 14978 { 14979 /* Prepend "./". */ 14980 cpy = concat_str((char_u *)"./", p); 14981 if (cpy != NULL) 14982 { 14983 vim_free(p); 14984 p = cpy; 14985 } 14986 } 14987 else if (!is_relative_to_current) 14988 { 14989 /* Strip leading "./". */ 14990 q = p; 14991 while (q[0] == '.' && vim_ispathsep(q[1])) 14992 q += 2; 14993 if (q > p) 14994 STRMOVE(p, p + 2); 14995 } 14996 } 14997 14998 /* Ensure that the result will have no trailing path separator 14999 * if the argument had none. But keep "/" or "//". */ 15000 if (!has_trailing_pathsep) 15001 { 15002 q = p + STRLEN(p); 15003 if (after_pathsep(p, q)) 15004 *gettail_sep(p) = NUL; 15005 } 15006 15007 rettv->vval.v_string = p; 15008 } 15009 # else 15010 rettv->vval.v_string = vim_strsave(p); 15011 # endif 15012 #endif 15013 15014 simplify_filename(rettv->vval.v_string); 15015 15016 #ifdef HAVE_READLINK 15017 fail: 15018 #endif 15019 rettv->v_type = VAR_STRING; 15020 } 15021 15022 /* 15023 * "reverse({list})" function 15024 */ 15025 static void 15026 f_reverse(argvars, rettv) 15027 typval_T *argvars; 15028 typval_T *rettv; 15029 { 15030 list_T *l; 15031 listitem_T *li, *ni; 15032 15033 if (argvars[0].v_type != VAR_LIST) 15034 EMSG2(_(e_listarg), "reverse()"); 15035 else if ((l = argvars[0].vval.v_list) != NULL 15036 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 15037 { 15038 li = l->lv_last; 15039 l->lv_first = l->lv_last = NULL; 15040 l->lv_len = 0; 15041 while (li != NULL) 15042 { 15043 ni = li->li_prev; 15044 list_append(l, li); 15045 li = ni; 15046 } 15047 rettv->vval.v_list = l; 15048 rettv->v_type = VAR_LIST; 15049 ++l->lv_refcount; 15050 l->lv_idx = l->lv_len - l->lv_idx - 1; 15051 } 15052 } 15053 15054 #define SP_NOMOVE 0x01 /* don't move cursor */ 15055 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 15056 #define SP_RETCOUNT 0x04 /* return matchcount */ 15057 #define SP_SETPCMARK 0x08 /* set previous context mark */ 15058 #define SP_START 0x10 /* accept match at start position */ 15059 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 15060 #define SP_END 0x40 /* leave cursor at end of match */ 15061 15062 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 15063 15064 /* 15065 * Get flags for a search function. 15066 * Possibly sets "p_ws". 15067 * Returns BACKWARD, FORWARD or zero (for an error). 15068 */ 15069 static int 15070 get_search_arg(varp, flagsp) 15071 typval_T *varp; 15072 int *flagsp; 15073 { 15074 int dir = FORWARD; 15075 char_u *flags; 15076 char_u nbuf[NUMBUFLEN]; 15077 int mask; 15078 15079 if (varp->v_type != VAR_UNKNOWN) 15080 { 15081 flags = get_tv_string_buf_chk(varp, nbuf); 15082 if (flags == NULL) 15083 return 0; /* type error; errmsg already given */ 15084 while (*flags != NUL) 15085 { 15086 switch (*flags) 15087 { 15088 case 'b': dir = BACKWARD; break; 15089 case 'w': p_ws = TRUE; break; 15090 case 'W': p_ws = FALSE; break; 15091 default: mask = 0; 15092 if (flagsp != NULL) 15093 switch (*flags) 15094 { 15095 case 'c': mask = SP_START; break; 15096 case 'e': mask = SP_END; break; 15097 case 'm': mask = SP_RETCOUNT; break; 15098 case 'n': mask = SP_NOMOVE; break; 15099 case 'p': mask = SP_SUBPAT; break; 15100 case 'r': mask = SP_REPEAT; break; 15101 case 's': mask = SP_SETPCMARK; break; 15102 } 15103 if (mask == 0) 15104 { 15105 EMSG2(_(e_invarg2), flags); 15106 dir = 0; 15107 } 15108 else 15109 *flagsp |= mask; 15110 } 15111 if (dir == 0) 15112 break; 15113 ++flags; 15114 } 15115 } 15116 return dir; 15117 } 15118 15119 /* 15120 * Shared by search() and searchpos() functions 15121 */ 15122 static int 15123 search_cmn(argvars, match_pos, flagsp) 15124 typval_T *argvars; 15125 pos_T *match_pos; 15126 int *flagsp; 15127 { 15128 int flags; 15129 char_u *pat; 15130 pos_T pos; 15131 pos_T save_cursor; 15132 int save_p_ws = p_ws; 15133 int dir; 15134 int retval = 0; /* default: FAIL */ 15135 long lnum_stop = 0; 15136 proftime_T tm; 15137 #ifdef FEAT_RELTIME 15138 long time_limit = 0; 15139 #endif 15140 int options = SEARCH_KEEP; 15141 int subpatnum; 15142 15143 pat = get_tv_string(&argvars[0]); 15144 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 15145 if (dir == 0) 15146 goto theend; 15147 flags = *flagsp; 15148 if (flags & SP_START) 15149 options |= SEARCH_START; 15150 if (flags & SP_END) 15151 options |= SEARCH_END; 15152 15153 /* Optional arguments: line number to stop searching and timeout. */ 15154 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) 15155 { 15156 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 15157 if (lnum_stop < 0) 15158 goto theend; 15159 #ifdef FEAT_RELTIME 15160 if (argvars[3].v_type != VAR_UNKNOWN) 15161 { 15162 time_limit = get_tv_number_chk(&argvars[3], NULL); 15163 if (time_limit < 0) 15164 goto theend; 15165 } 15166 #endif 15167 } 15168 15169 #ifdef FEAT_RELTIME 15170 /* Set the time limit, if there is one. */ 15171 profile_setlimit(time_limit, &tm); 15172 #endif 15173 15174 /* 15175 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 15176 * Check to make sure only those flags are set. 15177 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 15178 * flags cannot be set. Check for that condition also. 15179 */ 15180 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 15181 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 15182 { 15183 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 15184 goto theend; 15185 } 15186 15187 pos = save_cursor = curwin->w_cursor; 15188 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 15189 options, RE_SEARCH, (linenr_T)lnum_stop, &tm); 15190 if (subpatnum != FAIL) 15191 { 15192 if (flags & SP_SUBPAT) 15193 retval = subpatnum; 15194 else 15195 retval = pos.lnum; 15196 if (flags & SP_SETPCMARK) 15197 setpcmark(); 15198 curwin->w_cursor = pos; 15199 if (match_pos != NULL) 15200 { 15201 /* Store the match cursor position */ 15202 match_pos->lnum = pos.lnum; 15203 match_pos->col = pos.col + 1; 15204 } 15205 /* "/$" will put the cursor after the end of the line, may need to 15206 * correct that here */ 15207 check_cursor(); 15208 } 15209 15210 /* If 'n' flag is used: restore cursor position. */ 15211 if (flags & SP_NOMOVE) 15212 curwin->w_cursor = save_cursor; 15213 else 15214 curwin->w_set_curswant = TRUE; 15215 theend: 15216 p_ws = save_p_ws; 15217 15218 return retval; 15219 } 15220 15221 #ifdef FEAT_FLOAT 15222 /* 15223 * "round({float})" function 15224 */ 15225 static void 15226 f_round(argvars, rettv) 15227 typval_T *argvars; 15228 typval_T *rettv; 15229 { 15230 float_T f; 15231 15232 rettv->v_type = VAR_FLOAT; 15233 if (get_float_arg(argvars, &f) == OK) 15234 /* round() is not in C90, use ceil() or floor() instead. */ 15235 rettv->vval.v_float = f > 0 ? floor(f + 0.5) : ceil(f - 0.5); 15236 else 15237 rettv->vval.v_float = 0.0; 15238 } 15239 #endif 15240 15241 /* 15242 * "search()" function 15243 */ 15244 static void 15245 f_search(argvars, rettv) 15246 typval_T *argvars; 15247 typval_T *rettv; 15248 { 15249 int flags = 0; 15250 15251 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 15252 } 15253 15254 /* 15255 * "searchdecl()" function 15256 */ 15257 static void 15258 f_searchdecl(argvars, rettv) 15259 typval_T *argvars; 15260 typval_T *rettv; 15261 { 15262 int locally = 1; 15263 int thisblock = 0; 15264 int error = FALSE; 15265 char_u *name; 15266 15267 rettv->vval.v_number = 1; /* default: FAIL */ 15268 15269 name = get_tv_string_chk(&argvars[0]); 15270 if (argvars[1].v_type != VAR_UNKNOWN) 15271 { 15272 locally = get_tv_number_chk(&argvars[1], &error) == 0; 15273 if (!error && argvars[2].v_type != VAR_UNKNOWN) 15274 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 15275 } 15276 if (!error && name != NULL) 15277 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 15278 locally, thisblock, SEARCH_KEEP) == FAIL; 15279 } 15280 15281 /* 15282 * Used by searchpair() and searchpairpos() 15283 */ 15284 static int 15285 searchpair_cmn(argvars, match_pos) 15286 typval_T *argvars; 15287 pos_T *match_pos; 15288 { 15289 char_u *spat, *mpat, *epat; 15290 char_u *skip; 15291 int save_p_ws = p_ws; 15292 int dir; 15293 int flags = 0; 15294 char_u nbuf1[NUMBUFLEN]; 15295 char_u nbuf2[NUMBUFLEN]; 15296 char_u nbuf3[NUMBUFLEN]; 15297 int retval = 0; /* default: FAIL */ 15298 long lnum_stop = 0; 15299 long time_limit = 0; 15300 15301 /* Get the three pattern arguments: start, middle, end. */ 15302 spat = get_tv_string_chk(&argvars[0]); 15303 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 15304 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 15305 if (spat == NULL || mpat == NULL || epat == NULL) 15306 goto theend; /* type error */ 15307 15308 /* Handle the optional fourth argument: flags */ 15309 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 15310 if (dir == 0) 15311 goto theend; 15312 15313 /* Don't accept SP_END or SP_SUBPAT. 15314 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 15315 */ 15316 if ((flags & (SP_END | SP_SUBPAT)) != 0 15317 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 15318 { 15319 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 15320 goto theend; 15321 } 15322 15323 /* Using 'r' implies 'W', otherwise it doesn't work. */ 15324 if (flags & SP_REPEAT) 15325 p_ws = FALSE; 15326 15327 /* Optional fifth argument: skip expression */ 15328 if (argvars[3].v_type == VAR_UNKNOWN 15329 || argvars[4].v_type == VAR_UNKNOWN) 15330 skip = (char_u *)""; 15331 else 15332 { 15333 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 15334 if (argvars[5].v_type != VAR_UNKNOWN) 15335 { 15336 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 15337 if (lnum_stop < 0) 15338 goto theend; 15339 #ifdef FEAT_RELTIME 15340 if (argvars[6].v_type != VAR_UNKNOWN) 15341 { 15342 time_limit = get_tv_number_chk(&argvars[6], NULL); 15343 if (time_limit < 0) 15344 goto theend; 15345 } 15346 #endif 15347 } 15348 } 15349 if (skip == NULL) 15350 goto theend; /* type error */ 15351 15352 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 15353 match_pos, lnum_stop, time_limit); 15354 15355 theend: 15356 p_ws = save_p_ws; 15357 15358 return retval; 15359 } 15360 15361 /* 15362 * "searchpair()" function 15363 */ 15364 static void 15365 f_searchpair(argvars, rettv) 15366 typval_T *argvars; 15367 typval_T *rettv; 15368 { 15369 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 15370 } 15371 15372 /* 15373 * "searchpairpos()" function 15374 */ 15375 static void 15376 f_searchpairpos(argvars, rettv) 15377 typval_T *argvars; 15378 typval_T *rettv; 15379 { 15380 pos_T match_pos; 15381 int lnum = 0; 15382 int col = 0; 15383 15384 if (rettv_list_alloc(rettv) == FAIL) 15385 return; 15386 15387 if (searchpair_cmn(argvars, &match_pos) > 0) 15388 { 15389 lnum = match_pos.lnum; 15390 col = match_pos.col; 15391 } 15392 15393 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 15394 list_append_number(rettv->vval.v_list, (varnumber_T)col); 15395 } 15396 15397 /* 15398 * Search for a start/middle/end thing. 15399 * Used by searchpair(), see its documentation for the details. 15400 * Returns 0 or -1 for no match, 15401 */ 15402 long 15403 do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, 15404 lnum_stop, time_limit) 15405 char_u *spat; /* start pattern */ 15406 char_u *mpat; /* middle pattern */ 15407 char_u *epat; /* end pattern */ 15408 int dir; /* BACKWARD or FORWARD */ 15409 char_u *skip; /* skip expression */ 15410 int flags; /* SP_SETPCMARK and other SP_ values */ 15411 pos_T *match_pos; 15412 linenr_T lnum_stop; /* stop at this line if not zero */ 15413 long time_limit; /* stop after this many msec */ 15414 { 15415 char_u *save_cpo; 15416 char_u *pat, *pat2 = NULL, *pat3 = NULL; 15417 long retval = 0; 15418 pos_T pos; 15419 pos_T firstpos; 15420 pos_T foundpos; 15421 pos_T save_cursor; 15422 pos_T save_pos; 15423 int n; 15424 int r; 15425 int nest = 1; 15426 int err; 15427 int options = SEARCH_KEEP; 15428 proftime_T tm; 15429 15430 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 15431 save_cpo = p_cpo; 15432 p_cpo = empty_option; 15433 15434 #ifdef FEAT_RELTIME 15435 /* Set the time limit, if there is one. */ 15436 profile_setlimit(time_limit, &tm); 15437 #endif 15438 15439 /* Make two search patterns: start/end (pat2, for in nested pairs) and 15440 * start/middle/end (pat3, for the top pair). */ 15441 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 15442 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 15443 if (pat2 == NULL || pat3 == NULL) 15444 goto theend; 15445 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 15446 if (*mpat == NUL) 15447 STRCPY(pat3, pat2); 15448 else 15449 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 15450 spat, epat, mpat); 15451 if (flags & SP_START) 15452 options |= SEARCH_START; 15453 15454 save_cursor = curwin->w_cursor; 15455 pos = curwin->w_cursor; 15456 clearpos(&firstpos); 15457 clearpos(&foundpos); 15458 pat = pat3; 15459 for (;;) 15460 { 15461 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 15462 options, RE_SEARCH, lnum_stop, &tm); 15463 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 15464 /* didn't find it or found the first match again: FAIL */ 15465 break; 15466 15467 if (firstpos.lnum == 0) 15468 firstpos = pos; 15469 if (equalpos(pos, foundpos)) 15470 { 15471 /* Found the same position again. Can happen with a pattern that 15472 * has "\zs" at the end and searching backwards. Advance one 15473 * character and try again. */ 15474 if (dir == BACKWARD) 15475 decl(&pos); 15476 else 15477 incl(&pos); 15478 } 15479 foundpos = pos; 15480 15481 /* clear the start flag to avoid getting stuck here */ 15482 options &= ~SEARCH_START; 15483 15484 /* If the skip pattern matches, ignore this match. */ 15485 if (*skip != NUL) 15486 { 15487 save_pos = curwin->w_cursor; 15488 curwin->w_cursor = pos; 15489 r = eval_to_bool(skip, &err, NULL, FALSE); 15490 curwin->w_cursor = save_pos; 15491 if (err) 15492 { 15493 /* Evaluating {skip} caused an error, break here. */ 15494 curwin->w_cursor = save_cursor; 15495 retval = -1; 15496 break; 15497 } 15498 if (r) 15499 continue; 15500 } 15501 15502 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 15503 { 15504 /* Found end when searching backwards or start when searching 15505 * forward: nested pair. */ 15506 ++nest; 15507 pat = pat2; /* nested, don't search for middle */ 15508 } 15509 else 15510 { 15511 /* Found end when searching forward or start when searching 15512 * backward: end of (nested) pair; or found middle in outer pair. */ 15513 if (--nest == 1) 15514 pat = pat3; /* outer level, search for middle */ 15515 } 15516 15517 if (nest == 0) 15518 { 15519 /* Found the match: return matchcount or line number. */ 15520 if (flags & SP_RETCOUNT) 15521 ++retval; 15522 else 15523 retval = pos.lnum; 15524 if (flags & SP_SETPCMARK) 15525 setpcmark(); 15526 curwin->w_cursor = pos; 15527 if (!(flags & SP_REPEAT)) 15528 break; 15529 nest = 1; /* search for next unmatched */ 15530 } 15531 } 15532 15533 if (match_pos != NULL) 15534 { 15535 /* Store the match cursor position */ 15536 match_pos->lnum = curwin->w_cursor.lnum; 15537 match_pos->col = curwin->w_cursor.col + 1; 15538 } 15539 15540 /* If 'n' flag is used or search failed: restore cursor position. */ 15541 if ((flags & SP_NOMOVE) || retval == 0) 15542 curwin->w_cursor = save_cursor; 15543 15544 theend: 15545 vim_free(pat2); 15546 vim_free(pat3); 15547 if (p_cpo == empty_option) 15548 p_cpo = save_cpo; 15549 else 15550 /* Darn, evaluating the {skip} expression changed the value. */ 15551 free_string_option(save_cpo); 15552 15553 return retval; 15554 } 15555 15556 /* 15557 * "searchpos()" function 15558 */ 15559 static void 15560 f_searchpos(argvars, rettv) 15561 typval_T *argvars; 15562 typval_T *rettv; 15563 { 15564 pos_T match_pos; 15565 int lnum = 0; 15566 int col = 0; 15567 int n; 15568 int flags = 0; 15569 15570 if (rettv_list_alloc(rettv) == FAIL) 15571 return; 15572 15573 n = search_cmn(argvars, &match_pos, &flags); 15574 if (n > 0) 15575 { 15576 lnum = match_pos.lnum; 15577 col = match_pos.col; 15578 } 15579 15580 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 15581 list_append_number(rettv->vval.v_list, (varnumber_T)col); 15582 if (flags & SP_SUBPAT) 15583 list_append_number(rettv->vval.v_list, (varnumber_T)n); 15584 } 15585 15586 15587 static void 15588 f_server2client(argvars, rettv) 15589 typval_T *argvars UNUSED; 15590 typval_T *rettv; 15591 { 15592 #ifdef FEAT_CLIENTSERVER 15593 char_u buf[NUMBUFLEN]; 15594 char_u *server = get_tv_string_chk(&argvars[0]); 15595 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 15596 15597 rettv->vval.v_number = -1; 15598 if (server == NULL || reply == NULL) 15599 return; 15600 if (check_restricted() || check_secure()) 15601 return; 15602 # ifdef FEAT_X11 15603 if (check_connection() == FAIL) 15604 return; 15605 # endif 15606 15607 if (serverSendReply(server, reply) < 0) 15608 { 15609 EMSG(_("E258: Unable to send to client")); 15610 return; 15611 } 15612 rettv->vval.v_number = 0; 15613 #else 15614 rettv->vval.v_number = -1; 15615 #endif 15616 } 15617 15618 static void 15619 f_serverlist(argvars, rettv) 15620 typval_T *argvars UNUSED; 15621 typval_T *rettv; 15622 { 15623 char_u *r = NULL; 15624 15625 #ifdef FEAT_CLIENTSERVER 15626 # ifdef WIN32 15627 r = serverGetVimNames(); 15628 # else 15629 make_connection(); 15630 if (X_DISPLAY != NULL) 15631 r = serverGetVimNames(X_DISPLAY); 15632 # endif 15633 #endif 15634 rettv->v_type = VAR_STRING; 15635 rettv->vval.v_string = r; 15636 } 15637 15638 /* 15639 * "setbufvar()" function 15640 */ 15641 static void 15642 f_setbufvar(argvars, rettv) 15643 typval_T *argvars; 15644 typval_T *rettv UNUSED; 15645 { 15646 buf_T *buf; 15647 aco_save_T aco; 15648 char_u *varname, *bufvarname; 15649 typval_T *varp; 15650 char_u nbuf[NUMBUFLEN]; 15651 15652 if (check_restricted() || check_secure()) 15653 return; 15654 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 15655 varname = get_tv_string_chk(&argvars[1]); 15656 buf = get_buf_tv(&argvars[0]); 15657 varp = &argvars[2]; 15658 15659 if (buf != NULL && varname != NULL && varp != NULL) 15660 { 15661 /* set curbuf to be our buf, temporarily */ 15662 aucmd_prepbuf(&aco, buf); 15663 15664 if (*varname == '&') 15665 { 15666 long numval; 15667 char_u *strval; 15668 int error = FALSE; 15669 15670 ++varname; 15671 numval = get_tv_number_chk(varp, &error); 15672 strval = get_tv_string_buf_chk(varp, nbuf); 15673 if (!error && strval != NULL) 15674 set_option_value(varname, numval, strval, OPT_LOCAL); 15675 } 15676 else 15677 { 15678 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 15679 if (bufvarname != NULL) 15680 { 15681 STRCPY(bufvarname, "b:"); 15682 STRCPY(bufvarname + 2, varname); 15683 set_var(bufvarname, varp, TRUE); 15684 vim_free(bufvarname); 15685 } 15686 } 15687 15688 /* reset notion of buffer */ 15689 aucmd_restbuf(&aco); 15690 } 15691 } 15692 15693 /* 15694 * "setcmdpos()" function 15695 */ 15696 static void 15697 f_setcmdpos(argvars, rettv) 15698 typval_T *argvars; 15699 typval_T *rettv; 15700 { 15701 int pos = (int)get_tv_number(&argvars[0]) - 1; 15702 15703 if (pos >= 0) 15704 rettv->vval.v_number = set_cmdline_pos(pos); 15705 } 15706 15707 /* 15708 * "setline()" function 15709 */ 15710 static void 15711 f_setline(argvars, rettv) 15712 typval_T *argvars; 15713 typval_T *rettv; 15714 { 15715 linenr_T lnum; 15716 char_u *line = NULL; 15717 list_T *l = NULL; 15718 listitem_T *li = NULL; 15719 long added = 0; 15720 linenr_T lcount = curbuf->b_ml.ml_line_count; 15721 15722 lnum = get_tv_lnum(&argvars[0]); 15723 if (argvars[1].v_type == VAR_LIST) 15724 { 15725 l = argvars[1].vval.v_list; 15726 li = l->lv_first; 15727 } 15728 else 15729 line = get_tv_string_chk(&argvars[1]); 15730 15731 /* default result is zero == OK */ 15732 for (;;) 15733 { 15734 if (l != NULL) 15735 { 15736 /* list argument, get next string */ 15737 if (li == NULL) 15738 break; 15739 line = get_tv_string_chk(&li->li_tv); 15740 li = li->li_next; 15741 } 15742 15743 rettv->vval.v_number = 1; /* FAIL */ 15744 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 15745 break; 15746 if (lnum <= curbuf->b_ml.ml_line_count) 15747 { 15748 /* existing line, replace it */ 15749 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 15750 { 15751 changed_bytes(lnum, 0); 15752 if (lnum == curwin->w_cursor.lnum) 15753 check_cursor_col(); 15754 rettv->vval.v_number = 0; /* OK */ 15755 } 15756 } 15757 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 15758 { 15759 /* lnum is one past the last line, append the line */ 15760 ++added; 15761 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 15762 rettv->vval.v_number = 0; /* OK */ 15763 } 15764 15765 if (l == NULL) /* only one string argument */ 15766 break; 15767 ++lnum; 15768 } 15769 15770 if (added > 0) 15771 appended_lines_mark(lcount, added); 15772 } 15773 15774 static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv)); 15775 15776 /* 15777 * Used by "setqflist()" and "setloclist()" functions 15778 */ 15779 static void 15780 set_qf_ll_list(wp, list_arg, action_arg, rettv) 15781 win_T *wp UNUSED; 15782 typval_T *list_arg UNUSED; 15783 typval_T *action_arg UNUSED; 15784 typval_T *rettv; 15785 { 15786 #ifdef FEAT_QUICKFIX 15787 char_u *act; 15788 int action = ' '; 15789 #endif 15790 15791 rettv->vval.v_number = -1; 15792 15793 #ifdef FEAT_QUICKFIX 15794 if (list_arg->v_type != VAR_LIST) 15795 EMSG(_(e_listreq)); 15796 else 15797 { 15798 list_T *l = list_arg->vval.v_list; 15799 15800 if (action_arg->v_type == VAR_STRING) 15801 { 15802 act = get_tv_string_chk(action_arg); 15803 if (act == NULL) 15804 return; /* type error; errmsg already given */ 15805 if (*act == 'a' || *act == 'r') 15806 action = *act; 15807 } 15808 15809 if (l != NULL && set_errorlist(wp, l, action) == OK) 15810 rettv->vval.v_number = 0; 15811 } 15812 #endif 15813 } 15814 15815 /* 15816 * "setloclist()" function 15817 */ 15818 static void 15819 f_setloclist(argvars, rettv) 15820 typval_T *argvars; 15821 typval_T *rettv; 15822 { 15823 win_T *win; 15824 15825 rettv->vval.v_number = -1; 15826 15827 win = find_win_by_nr(&argvars[0], NULL); 15828 if (win != NULL) 15829 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 15830 } 15831 15832 /* 15833 * "setmatches()" function 15834 */ 15835 static void 15836 f_setmatches(argvars, rettv) 15837 typval_T *argvars; 15838 typval_T *rettv; 15839 { 15840 #ifdef FEAT_SEARCH_EXTRA 15841 list_T *l; 15842 listitem_T *li; 15843 dict_T *d; 15844 15845 rettv->vval.v_number = -1; 15846 if (argvars[0].v_type != VAR_LIST) 15847 { 15848 EMSG(_(e_listreq)); 15849 return; 15850 } 15851 if ((l = argvars[0].vval.v_list) != NULL) 15852 { 15853 15854 /* To some extent make sure that we are dealing with a list from 15855 * "getmatches()". */ 15856 li = l->lv_first; 15857 while (li != NULL) 15858 { 15859 if (li->li_tv.v_type != VAR_DICT 15860 || (d = li->li_tv.vval.v_dict) == NULL) 15861 { 15862 EMSG(_(e_invarg)); 15863 return; 15864 } 15865 if (!(dict_find(d, (char_u *)"group", -1) != NULL 15866 && dict_find(d, (char_u *)"pattern", -1) != NULL 15867 && dict_find(d, (char_u *)"priority", -1) != NULL 15868 && dict_find(d, (char_u *)"id", -1) != NULL)) 15869 { 15870 EMSG(_(e_invarg)); 15871 return; 15872 } 15873 li = li->li_next; 15874 } 15875 15876 clear_matches(curwin); 15877 li = l->lv_first; 15878 while (li != NULL) 15879 { 15880 d = li->li_tv.vval.v_dict; 15881 match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE), 15882 get_dict_string(d, (char_u *)"pattern", FALSE), 15883 (int)get_dict_number(d, (char_u *)"priority"), 15884 (int)get_dict_number(d, (char_u *)"id")); 15885 li = li->li_next; 15886 } 15887 rettv->vval.v_number = 0; 15888 } 15889 #endif 15890 } 15891 15892 /* 15893 * "setpos()" function 15894 */ 15895 static void 15896 f_setpos(argvars, rettv) 15897 typval_T *argvars; 15898 typval_T *rettv; 15899 { 15900 pos_T pos; 15901 int fnum; 15902 char_u *name; 15903 15904 rettv->vval.v_number = -1; 15905 name = get_tv_string_chk(argvars); 15906 if (name != NULL) 15907 { 15908 if (list2fpos(&argvars[1], &pos, &fnum) == OK) 15909 { 15910 if (--pos.col < 0) 15911 pos.col = 0; 15912 if (name[0] == '.' && name[1] == NUL) 15913 { 15914 /* set cursor */ 15915 if (fnum == curbuf->b_fnum) 15916 { 15917 curwin->w_cursor = pos; 15918 check_cursor(); 15919 rettv->vval.v_number = 0; 15920 } 15921 else 15922 EMSG(_(e_invarg)); 15923 } 15924 else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) 15925 { 15926 /* set mark */ 15927 if (setmark_pos(name[1], &pos, fnum) == OK) 15928 rettv->vval.v_number = 0; 15929 } 15930 else 15931 EMSG(_(e_invarg)); 15932 } 15933 } 15934 } 15935 15936 /* 15937 * "setqflist()" function 15938 */ 15939 static void 15940 f_setqflist(argvars, rettv) 15941 typval_T *argvars; 15942 typval_T *rettv; 15943 { 15944 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 15945 } 15946 15947 /* 15948 * "setreg()" function 15949 */ 15950 static void 15951 f_setreg(argvars, rettv) 15952 typval_T *argvars; 15953 typval_T *rettv; 15954 { 15955 int regname; 15956 char_u *strregname; 15957 char_u *stropt; 15958 char_u *strval; 15959 int append; 15960 char_u yank_type; 15961 long block_len; 15962 15963 block_len = -1; 15964 yank_type = MAUTO; 15965 append = FALSE; 15966 15967 strregname = get_tv_string_chk(argvars); 15968 rettv->vval.v_number = 1; /* FAIL is default */ 15969 15970 if (strregname == NULL) 15971 return; /* type error; errmsg already given */ 15972 regname = *strregname; 15973 if (regname == 0 || regname == '@') 15974 regname = '"'; 15975 else if (regname == '=') 15976 return; 15977 15978 if (argvars[2].v_type != VAR_UNKNOWN) 15979 { 15980 stropt = get_tv_string_chk(&argvars[2]); 15981 if (stropt == NULL) 15982 return; /* type error */ 15983 for (; *stropt != NUL; ++stropt) 15984 switch (*stropt) 15985 { 15986 case 'a': case 'A': /* append */ 15987 append = TRUE; 15988 break; 15989 case 'v': case 'c': /* character-wise selection */ 15990 yank_type = MCHAR; 15991 break; 15992 case 'V': case 'l': /* line-wise selection */ 15993 yank_type = MLINE; 15994 break; 15995 #ifdef FEAT_VISUAL 15996 case 'b': case Ctrl_V: /* block-wise selection */ 15997 yank_type = MBLOCK; 15998 if (VIM_ISDIGIT(stropt[1])) 15999 { 16000 ++stropt; 16001 block_len = getdigits(&stropt) - 1; 16002 --stropt; 16003 } 16004 break; 16005 #endif 16006 } 16007 } 16008 16009 strval = get_tv_string_chk(&argvars[1]); 16010 if (strval != NULL) 16011 write_reg_contents_ex(regname, strval, -1, 16012 append, yank_type, block_len); 16013 rettv->vval.v_number = 0; 16014 } 16015 16016 /* 16017 * "settabvar()" function 16018 */ 16019 static void 16020 f_settabvar(argvars, rettv) 16021 typval_T *argvars; 16022 typval_T *rettv; 16023 { 16024 tabpage_T *save_curtab; 16025 char_u *varname, *tabvarname; 16026 typval_T *varp; 16027 tabpage_T *tp; 16028 16029 rettv->vval.v_number = 0; 16030 16031 if (check_restricted() || check_secure()) 16032 return; 16033 16034 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 16035 varname = get_tv_string_chk(&argvars[1]); 16036 varp = &argvars[2]; 16037 16038 if (tp != NULL && varname != NULL && varp != NULL) 16039 { 16040 save_curtab = curtab; 16041 goto_tabpage_tp(tp); 16042 16043 tabvarname = alloc((unsigned)STRLEN(varname) + 3); 16044 if (tabvarname != NULL) 16045 { 16046 STRCPY(tabvarname, "t:"); 16047 STRCPY(tabvarname + 2, varname); 16048 set_var(tabvarname, varp, TRUE); 16049 vim_free(tabvarname); 16050 } 16051 16052 /* Restore current tabpage */ 16053 if (valid_tabpage(save_curtab)) 16054 goto_tabpage_tp(save_curtab); 16055 } 16056 } 16057 16058 /* 16059 * "settabwinvar()" function 16060 */ 16061 static void 16062 f_settabwinvar(argvars, rettv) 16063 typval_T *argvars; 16064 typval_T *rettv; 16065 { 16066 setwinvar(argvars, rettv, 1); 16067 } 16068 16069 /* 16070 * "setwinvar()" function 16071 */ 16072 static void 16073 f_setwinvar(argvars, rettv) 16074 typval_T *argvars; 16075 typval_T *rettv; 16076 { 16077 setwinvar(argvars, rettv, 0); 16078 } 16079 16080 /* 16081 * "setwinvar()" and "settabwinvar()" functions 16082 */ 16083 static void 16084 setwinvar(argvars, rettv, off) 16085 typval_T *argvars; 16086 typval_T *rettv UNUSED; 16087 int off; 16088 { 16089 win_T *win; 16090 #ifdef FEAT_WINDOWS 16091 win_T *save_curwin; 16092 tabpage_T *save_curtab; 16093 #endif 16094 char_u *varname, *winvarname; 16095 typval_T *varp; 16096 char_u nbuf[NUMBUFLEN]; 16097 tabpage_T *tp; 16098 16099 if (check_restricted() || check_secure()) 16100 return; 16101 16102 #ifdef FEAT_WINDOWS 16103 if (off == 1) 16104 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 16105 else 16106 tp = curtab; 16107 #endif 16108 win = find_win_by_nr(&argvars[off], tp); 16109 varname = get_tv_string_chk(&argvars[off + 1]); 16110 varp = &argvars[off + 2]; 16111 16112 if (win != NULL && varname != NULL && varp != NULL) 16113 { 16114 #ifdef FEAT_WINDOWS 16115 /* set curwin to be our win, temporarily */ 16116 save_curwin = curwin; 16117 save_curtab = curtab; 16118 goto_tabpage_tp(tp); 16119 if (!win_valid(win)) 16120 return; 16121 curwin = win; 16122 curbuf = curwin->w_buffer; 16123 #endif 16124 16125 if (*varname == '&') 16126 { 16127 long numval; 16128 char_u *strval; 16129 int error = FALSE; 16130 16131 ++varname; 16132 numval = get_tv_number_chk(varp, &error); 16133 strval = get_tv_string_buf_chk(varp, nbuf); 16134 if (!error && strval != NULL) 16135 set_option_value(varname, numval, strval, OPT_LOCAL); 16136 } 16137 else 16138 { 16139 winvarname = alloc((unsigned)STRLEN(varname) + 3); 16140 if (winvarname != NULL) 16141 { 16142 STRCPY(winvarname, "w:"); 16143 STRCPY(winvarname + 2, varname); 16144 set_var(winvarname, varp, TRUE); 16145 vim_free(winvarname); 16146 } 16147 } 16148 16149 #ifdef FEAT_WINDOWS 16150 /* Restore current tabpage and window, if still valid (autocomands can 16151 * make them invalid). */ 16152 if (valid_tabpage(save_curtab)) 16153 goto_tabpage_tp(save_curtab); 16154 if (win_valid(save_curwin)) 16155 { 16156 curwin = save_curwin; 16157 curbuf = curwin->w_buffer; 16158 } 16159 #endif 16160 } 16161 } 16162 16163 /* 16164 * "shellescape({string})" function 16165 */ 16166 static void 16167 f_shellescape(argvars, rettv) 16168 typval_T *argvars; 16169 typval_T *rettv; 16170 { 16171 rettv->vval.v_string = vim_strsave_shellescape( 16172 get_tv_string(&argvars[0]), non_zero_arg(&argvars[1])); 16173 rettv->v_type = VAR_STRING; 16174 } 16175 16176 /* 16177 * "simplify()" function 16178 */ 16179 static void 16180 f_simplify(argvars, rettv) 16181 typval_T *argvars; 16182 typval_T *rettv; 16183 { 16184 char_u *p; 16185 16186 p = get_tv_string(&argvars[0]); 16187 rettv->vval.v_string = vim_strsave(p); 16188 simplify_filename(rettv->vval.v_string); /* simplify in place */ 16189 rettv->v_type = VAR_STRING; 16190 } 16191 16192 #ifdef FEAT_FLOAT 16193 /* 16194 * "sin()" function 16195 */ 16196 static void 16197 f_sin(argvars, rettv) 16198 typval_T *argvars; 16199 typval_T *rettv; 16200 { 16201 float_T f; 16202 16203 rettv->v_type = VAR_FLOAT; 16204 if (get_float_arg(argvars, &f) == OK) 16205 rettv->vval.v_float = sin(f); 16206 else 16207 rettv->vval.v_float = 0.0; 16208 } 16209 16210 /* 16211 * "sinh()" function 16212 */ 16213 static void 16214 f_sinh(argvars, rettv) 16215 typval_T *argvars; 16216 typval_T *rettv; 16217 { 16218 float_T f; 16219 16220 rettv->v_type = VAR_FLOAT; 16221 if (get_float_arg(argvars, &f) == OK) 16222 rettv->vval.v_float = sinh(f); 16223 else 16224 rettv->vval.v_float = 0.0; 16225 } 16226 #endif 16227 16228 static int 16229 #ifdef __BORLANDC__ 16230 _RTLENTRYF 16231 #endif 16232 item_compare __ARGS((const void *s1, const void *s2)); 16233 static int 16234 #ifdef __BORLANDC__ 16235 _RTLENTRYF 16236 #endif 16237 item_compare2 __ARGS((const void *s1, const void *s2)); 16238 16239 static int item_compare_ic; 16240 static char_u *item_compare_func; 16241 static int item_compare_func_err; 16242 #define ITEM_COMPARE_FAIL 999 16243 16244 /* 16245 * Compare functions for f_sort() below. 16246 */ 16247 static int 16248 #ifdef __BORLANDC__ 16249 _RTLENTRYF 16250 #endif 16251 item_compare(s1, s2) 16252 const void *s1; 16253 const void *s2; 16254 { 16255 char_u *p1, *p2; 16256 char_u *tofree1, *tofree2; 16257 int res; 16258 char_u numbuf1[NUMBUFLEN]; 16259 char_u numbuf2[NUMBUFLEN]; 16260 16261 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0); 16262 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0); 16263 if (p1 == NULL) 16264 p1 = (char_u *)""; 16265 if (p2 == NULL) 16266 p2 = (char_u *)""; 16267 if (item_compare_ic) 16268 res = STRICMP(p1, p2); 16269 else 16270 res = STRCMP(p1, p2); 16271 vim_free(tofree1); 16272 vim_free(tofree2); 16273 return res; 16274 } 16275 16276 static int 16277 #ifdef __BORLANDC__ 16278 _RTLENTRYF 16279 #endif 16280 item_compare2(s1, s2) 16281 const void *s1; 16282 const void *s2; 16283 { 16284 int res; 16285 typval_T rettv; 16286 typval_T argv[3]; 16287 int dummy; 16288 16289 /* shortcut after failure in previous call; compare all items equal */ 16290 if (item_compare_func_err) 16291 return 0; 16292 16293 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 16294 * in the copy without changing the original list items. */ 16295 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 16296 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 16297 16298 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 16299 res = call_func(item_compare_func, (int)STRLEN(item_compare_func), 16300 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 16301 clear_tv(&argv[0]); 16302 clear_tv(&argv[1]); 16303 16304 if (res == FAIL) 16305 res = ITEM_COMPARE_FAIL; 16306 else 16307 res = get_tv_number_chk(&rettv, &item_compare_func_err); 16308 if (item_compare_func_err) 16309 res = ITEM_COMPARE_FAIL; /* return value has wrong type */ 16310 clear_tv(&rettv); 16311 return res; 16312 } 16313 16314 /* 16315 * "sort({list})" function 16316 */ 16317 static void 16318 f_sort(argvars, rettv) 16319 typval_T *argvars; 16320 typval_T *rettv; 16321 { 16322 list_T *l; 16323 listitem_T *li; 16324 listitem_T **ptrs; 16325 long len; 16326 long i; 16327 16328 if (argvars[0].v_type != VAR_LIST) 16329 EMSG2(_(e_listarg), "sort()"); 16330 else 16331 { 16332 l = argvars[0].vval.v_list; 16333 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 16334 return; 16335 rettv->vval.v_list = l; 16336 rettv->v_type = VAR_LIST; 16337 ++l->lv_refcount; 16338 16339 len = list_len(l); 16340 if (len <= 1) 16341 return; /* short list sorts pretty quickly */ 16342 16343 item_compare_ic = FALSE; 16344 item_compare_func = NULL; 16345 if (argvars[1].v_type != VAR_UNKNOWN) 16346 { 16347 if (argvars[1].v_type == VAR_FUNC) 16348 item_compare_func = argvars[1].vval.v_string; 16349 else 16350 { 16351 int error = FALSE; 16352 16353 i = get_tv_number_chk(&argvars[1], &error); 16354 if (error) 16355 return; /* type error; errmsg already given */ 16356 if (i == 1) 16357 item_compare_ic = TRUE; 16358 else 16359 item_compare_func = get_tv_string(&argvars[1]); 16360 } 16361 } 16362 16363 /* Make an array with each entry pointing to an item in the List. */ 16364 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 16365 if (ptrs == NULL) 16366 return; 16367 i = 0; 16368 for (li = l->lv_first; li != NULL; li = li->li_next) 16369 ptrs[i++] = li; 16370 16371 item_compare_func_err = FALSE; 16372 /* test the compare function */ 16373 if (item_compare_func != NULL 16374 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 16375 == ITEM_COMPARE_FAIL) 16376 EMSG(_("E702: Sort compare function failed")); 16377 else 16378 { 16379 /* Sort the array with item pointers. */ 16380 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 16381 item_compare_func == NULL ? item_compare : item_compare2); 16382 16383 if (!item_compare_func_err) 16384 { 16385 /* Clear the List and append the items in the sorted order. */ 16386 l->lv_first = l->lv_last = l->lv_idx_item = NULL; 16387 l->lv_len = 0; 16388 for (i = 0; i < len; ++i) 16389 list_append(l, ptrs[i]); 16390 } 16391 } 16392 16393 vim_free(ptrs); 16394 } 16395 } 16396 16397 /* 16398 * "soundfold({word})" function 16399 */ 16400 static void 16401 f_soundfold(argvars, rettv) 16402 typval_T *argvars; 16403 typval_T *rettv; 16404 { 16405 char_u *s; 16406 16407 rettv->v_type = VAR_STRING; 16408 s = get_tv_string(&argvars[0]); 16409 #ifdef FEAT_SPELL 16410 rettv->vval.v_string = eval_soundfold(s); 16411 #else 16412 rettv->vval.v_string = vim_strsave(s); 16413 #endif 16414 } 16415 16416 /* 16417 * "spellbadword()" function 16418 */ 16419 static void 16420 f_spellbadword(argvars, rettv) 16421 typval_T *argvars UNUSED; 16422 typval_T *rettv; 16423 { 16424 char_u *word = (char_u *)""; 16425 hlf_T attr = HLF_COUNT; 16426 int len = 0; 16427 16428 if (rettv_list_alloc(rettv) == FAIL) 16429 return; 16430 16431 #ifdef FEAT_SPELL 16432 if (argvars[0].v_type == VAR_UNKNOWN) 16433 { 16434 /* Find the start and length of the badly spelled word. */ 16435 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 16436 if (len != 0) 16437 word = ml_get_cursor(); 16438 } 16439 else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL) 16440 { 16441 char_u *str = get_tv_string_chk(&argvars[0]); 16442 int capcol = -1; 16443 16444 if (str != NULL) 16445 { 16446 /* Check the argument for spelling. */ 16447 while (*str != NUL) 16448 { 16449 len = spell_check(curwin, str, &attr, &capcol, FALSE); 16450 if (attr != HLF_COUNT) 16451 { 16452 word = str; 16453 break; 16454 } 16455 str += len; 16456 } 16457 } 16458 } 16459 #endif 16460 16461 list_append_string(rettv->vval.v_list, word, len); 16462 list_append_string(rettv->vval.v_list, (char_u *)( 16463 attr == HLF_SPB ? "bad" : 16464 attr == HLF_SPR ? "rare" : 16465 attr == HLF_SPL ? "local" : 16466 attr == HLF_SPC ? "caps" : 16467 ""), -1); 16468 } 16469 16470 /* 16471 * "spellsuggest()" function 16472 */ 16473 static void 16474 f_spellsuggest(argvars, rettv) 16475 typval_T *argvars UNUSED; 16476 typval_T *rettv; 16477 { 16478 #ifdef FEAT_SPELL 16479 char_u *str; 16480 int typeerr = FALSE; 16481 int maxcount; 16482 garray_T ga; 16483 int i; 16484 listitem_T *li; 16485 int need_capital = FALSE; 16486 #endif 16487 16488 if (rettv_list_alloc(rettv) == FAIL) 16489 return; 16490 16491 #ifdef FEAT_SPELL 16492 if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) 16493 { 16494 str = get_tv_string(&argvars[0]); 16495 if (argvars[1].v_type != VAR_UNKNOWN) 16496 { 16497 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 16498 if (maxcount <= 0) 16499 return; 16500 if (argvars[2].v_type != VAR_UNKNOWN) 16501 { 16502 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 16503 if (typeerr) 16504 return; 16505 } 16506 } 16507 else 16508 maxcount = 25; 16509 16510 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 16511 16512 for (i = 0; i < ga.ga_len; ++i) 16513 { 16514 str = ((char_u **)ga.ga_data)[i]; 16515 16516 li = listitem_alloc(); 16517 if (li == NULL) 16518 vim_free(str); 16519 else 16520 { 16521 li->li_tv.v_type = VAR_STRING; 16522 li->li_tv.v_lock = 0; 16523 li->li_tv.vval.v_string = str; 16524 list_append(rettv->vval.v_list, li); 16525 } 16526 } 16527 ga_clear(&ga); 16528 } 16529 #endif 16530 } 16531 16532 static void 16533 f_split(argvars, rettv) 16534 typval_T *argvars; 16535 typval_T *rettv; 16536 { 16537 char_u *str; 16538 char_u *end; 16539 char_u *pat = NULL; 16540 regmatch_T regmatch; 16541 char_u patbuf[NUMBUFLEN]; 16542 char_u *save_cpo; 16543 int match; 16544 colnr_T col = 0; 16545 int keepempty = FALSE; 16546 int typeerr = FALSE; 16547 16548 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 16549 save_cpo = p_cpo; 16550 p_cpo = (char_u *)""; 16551 16552 str = get_tv_string(&argvars[0]); 16553 if (argvars[1].v_type != VAR_UNKNOWN) 16554 { 16555 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 16556 if (pat == NULL) 16557 typeerr = TRUE; 16558 if (argvars[2].v_type != VAR_UNKNOWN) 16559 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 16560 } 16561 if (pat == NULL || *pat == NUL) 16562 pat = (char_u *)"[\\x01- ]\\+"; 16563 16564 if (rettv_list_alloc(rettv) == FAIL) 16565 return; 16566 if (typeerr) 16567 return; 16568 16569 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 16570 if (regmatch.regprog != NULL) 16571 { 16572 regmatch.rm_ic = FALSE; 16573 while (*str != NUL || keepempty) 16574 { 16575 if (*str == NUL) 16576 match = FALSE; /* empty item at the end */ 16577 else 16578 match = vim_regexec_nl(®match, str, col); 16579 if (match) 16580 end = regmatch.startp[0]; 16581 else 16582 end = str + STRLEN(str); 16583 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 16584 && *str != NUL && match && end < regmatch.endp[0])) 16585 { 16586 if (list_append_string(rettv->vval.v_list, str, 16587 (int)(end - str)) == FAIL) 16588 break; 16589 } 16590 if (!match) 16591 break; 16592 /* Advance to just after the match. */ 16593 if (regmatch.endp[0] > str) 16594 col = 0; 16595 else 16596 { 16597 /* Don't get stuck at the same match. */ 16598 #ifdef FEAT_MBYTE 16599 col = (*mb_ptr2len)(regmatch.endp[0]); 16600 #else 16601 col = 1; 16602 #endif 16603 } 16604 str = regmatch.endp[0]; 16605 } 16606 16607 vim_free(regmatch.regprog); 16608 } 16609 16610 p_cpo = save_cpo; 16611 } 16612 16613 #ifdef FEAT_FLOAT 16614 /* 16615 * "sqrt()" function 16616 */ 16617 static void 16618 f_sqrt(argvars, rettv) 16619 typval_T *argvars; 16620 typval_T *rettv; 16621 { 16622 float_T f; 16623 16624 rettv->v_type = VAR_FLOAT; 16625 if (get_float_arg(argvars, &f) == OK) 16626 rettv->vval.v_float = sqrt(f); 16627 else 16628 rettv->vval.v_float = 0.0; 16629 } 16630 16631 /* 16632 * "str2float()" function 16633 */ 16634 static void 16635 f_str2float(argvars, rettv) 16636 typval_T *argvars; 16637 typval_T *rettv; 16638 { 16639 char_u *p = skipwhite(get_tv_string(&argvars[0])); 16640 16641 if (*p == '+') 16642 p = skipwhite(p + 1); 16643 (void)string2float(p, &rettv->vval.v_float); 16644 rettv->v_type = VAR_FLOAT; 16645 } 16646 #endif 16647 16648 /* 16649 * "str2nr()" function 16650 */ 16651 static void 16652 f_str2nr(argvars, rettv) 16653 typval_T *argvars; 16654 typval_T *rettv; 16655 { 16656 int base = 10; 16657 char_u *p; 16658 long n; 16659 16660 if (argvars[1].v_type != VAR_UNKNOWN) 16661 { 16662 base = get_tv_number(&argvars[1]); 16663 if (base != 8 && base != 10 && base != 16) 16664 { 16665 EMSG(_(e_invarg)); 16666 return; 16667 } 16668 } 16669 16670 p = skipwhite(get_tv_string(&argvars[0])); 16671 if (*p == '+') 16672 p = skipwhite(p + 1); 16673 vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL); 16674 rettv->vval.v_number = n; 16675 } 16676 16677 #ifdef HAVE_STRFTIME 16678 /* 16679 * "strftime({format}[, {time}])" function 16680 */ 16681 static void 16682 f_strftime(argvars, rettv) 16683 typval_T *argvars; 16684 typval_T *rettv; 16685 { 16686 char_u result_buf[256]; 16687 struct tm *curtime; 16688 time_t seconds; 16689 char_u *p; 16690 16691 rettv->v_type = VAR_STRING; 16692 16693 p = get_tv_string(&argvars[0]); 16694 if (argvars[1].v_type == VAR_UNKNOWN) 16695 seconds = time(NULL); 16696 else 16697 seconds = (time_t)get_tv_number(&argvars[1]); 16698 curtime = localtime(&seconds); 16699 /* MSVC returns NULL for an invalid value of seconds. */ 16700 if (curtime == NULL) 16701 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 16702 else 16703 { 16704 # ifdef FEAT_MBYTE 16705 vimconv_T conv; 16706 char_u *enc; 16707 16708 conv.vc_type = CONV_NONE; 16709 enc = enc_locale(); 16710 convert_setup(&conv, p_enc, enc); 16711 if (conv.vc_type != CONV_NONE) 16712 p = string_convert(&conv, p, NULL); 16713 # endif 16714 if (p != NULL) 16715 (void)strftime((char *)result_buf, sizeof(result_buf), 16716 (char *)p, curtime); 16717 else 16718 result_buf[0] = NUL; 16719 16720 # ifdef FEAT_MBYTE 16721 if (conv.vc_type != CONV_NONE) 16722 vim_free(p); 16723 convert_setup(&conv, enc, p_enc); 16724 if (conv.vc_type != CONV_NONE) 16725 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 16726 else 16727 # endif 16728 rettv->vval.v_string = vim_strsave(result_buf); 16729 16730 # ifdef FEAT_MBYTE 16731 /* Release conversion descriptors */ 16732 convert_setup(&conv, NULL, NULL); 16733 vim_free(enc); 16734 # endif 16735 } 16736 } 16737 #endif 16738 16739 /* 16740 * "stridx()" function 16741 */ 16742 static void 16743 f_stridx(argvars, rettv) 16744 typval_T *argvars; 16745 typval_T *rettv; 16746 { 16747 char_u buf[NUMBUFLEN]; 16748 char_u *needle; 16749 char_u *haystack; 16750 char_u *save_haystack; 16751 char_u *pos; 16752 int start_idx; 16753 16754 needle = get_tv_string_chk(&argvars[1]); 16755 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 16756 rettv->vval.v_number = -1; 16757 if (needle == NULL || haystack == NULL) 16758 return; /* type error; errmsg already given */ 16759 16760 if (argvars[2].v_type != VAR_UNKNOWN) 16761 { 16762 int error = FALSE; 16763 16764 start_idx = get_tv_number_chk(&argvars[2], &error); 16765 if (error || start_idx >= (int)STRLEN(haystack)) 16766 return; 16767 if (start_idx >= 0) 16768 haystack += start_idx; 16769 } 16770 16771 pos = (char_u *)strstr((char *)haystack, (char *)needle); 16772 if (pos != NULL) 16773 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 16774 } 16775 16776 /* 16777 * "string()" function 16778 */ 16779 static void 16780 f_string(argvars, rettv) 16781 typval_T *argvars; 16782 typval_T *rettv; 16783 { 16784 char_u *tofree; 16785 char_u numbuf[NUMBUFLEN]; 16786 16787 rettv->v_type = VAR_STRING; 16788 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 16789 /* Make a copy if we have a value but it's not in allocated memory. */ 16790 if (rettv->vval.v_string != NULL && tofree == NULL) 16791 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 16792 } 16793 16794 /* 16795 * "strlen()" function 16796 */ 16797 static void 16798 f_strlen(argvars, rettv) 16799 typval_T *argvars; 16800 typval_T *rettv; 16801 { 16802 rettv->vval.v_number = (varnumber_T)(STRLEN( 16803 get_tv_string(&argvars[0]))); 16804 } 16805 16806 /* 16807 * "strchars()" function 16808 */ 16809 static void 16810 f_strchars(argvars, rettv) 16811 typval_T *argvars; 16812 typval_T *rettv; 16813 { 16814 char_u *s = get_tv_string(&argvars[0]); 16815 #ifdef FEAT_MBYTE 16816 varnumber_T len = 0; 16817 16818 while (*s != NUL) 16819 { 16820 mb_cptr2char_adv(&s); 16821 ++len; 16822 } 16823 rettv->vval.v_number = len; 16824 #else 16825 rettv->vval.v_number = (varnumber_T)(STRLEN(s)); 16826 #endif 16827 } 16828 16829 /* 16830 * "strdisplaywidth()" function 16831 */ 16832 static void 16833 f_strdisplaywidth(argvars, rettv) 16834 typval_T *argvars; 16835 typval_T *rettv; 16836 { 16837 char_u *s = get_tv_string(&argvars[0]); 16838 int col = 0; 16839 16840 if (argvars[1].v_type != VAR_UNKNOWN) 16841 col = get_tv_number(&argvars[1]); 16842 16843 rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col); 16844 } 16845 16846 /* 16847 * "strwidth()" function 16848 */ 16849 static void 16850 f_strwidth(argvars, rettv) 16851 typval_T *argvars; 16852 typval_T *rettv; 16853 { 16854 char_u *s = get_tv_string(&argvars[0]); 16855 16856 rettv->vval.v_number = (varnumber_T)( 16857 #ifdef FEAT_MBYTE 16858 mb_string2cells(s, -1) 16859 #else 16860 STRLEN(s) 16861 #endif 16862 ); 16863 } 16864 16865 /* 16866 * "strpart()" function 16867 */ 16868 static void 16869 f_strpart(argvars, rettv) 16870 typval_T *argvars; 16871 typval_T *rettv; 16872 { 16873 char_u *p; 16874 int n; 16875 int len; 16876 int slen; 16877 int error = FALSE; 16878 16879 p = get_tv_string(&argvars[0]); 16880 slen = (int)STRLEN(p); 16881 16882 n = get_tv_number_chk(&argvars[1], &error); 16883 if (error) 16884 len = 0; 16885 else if (argvars[2].v_type != VAR_UNKNOWN) 16886 len = get_tv_number(&argvars[2]); 16887 else 16888 len = slen - n; /* default len: all bytes that are available. */ 16889 16890 /* 16891 * Only return the overlap between the specified part and the actual 16892 * string. 16893 */ 16894 if (n < 0) 16895 { 16896 len += n; 16897 n = 0; 16898 } 16899 else if (n > slen) 16900 n = slen; 16901 if (len < 0) 16902 len = 0; 16903 else if (n + len > slen) 16904 len = slen - n; 16905 16906 rettv->v_type = VAR_STRING; 16907 rettv->vval.v_string = vim_strnsave(p + n, len); 16908 } 16909 16910 /* 16911 * "strridx()" function 16912 */ 16913 static void 16914 f_strridx(argvars, rettv) 16915 typval_T *argvars; 16916 typval_T *rettv; 16917 { 16918 char_u buf[NUMBUFLEN]; 16919 char_u *needle; 16920 char_u *haystack; 16921 char_u *rest; 16922 char_u *lastmatch = NULL; 16923 int haystack_len, end_idx; 16924 16925 needle = get_tv_string_chk(&argvars[1]); 16926 haystack = get_tv_string_buf_chk(&argvars[0], buf); 16927 16928 rettv->vval.v_number = -1; 16929 if (needle == NULL || haystack == NULL) 16930 return; /* type error; errmsg already given */ 16931 16932 haystack_len = (int)STRLEN(haystack); 16933 if (argvars[2].v_type != VAR_UNKNOWN) 16934 { 16935 /* Third argument: upper limit for index */ 16936 end_idx = get_tv_number_chk(&argvars[2], NULL); 16937 if (end_idx < 0) 16938 return; /* can never find a match */ 16939 } 16940 else 16941 end_idx = haystack_len; 16942 16943 if (*needle == NUL) 16944 { 16945 /* Empty string matches past the end. */ 16946 lastmatch = haystack + end_idx; 16947 } 16948 else 16949 { 16950 for (rest = haystack; *rest != '\0'; ++rest) 16951 { 16952 rest = (char_u *)strstr((char *)rest, (char *)needle); 16953 if (rest == NULL || rest > haystack + end_idx) 16954 break; 16955 lastmatch = rest; 16956 } 16957 } 16958 16959 if (lastmatch == NULL) 16960 rettv->vval.v_number = -1; 16961 else 16962 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 16963 } 16964 16965 /* 16966 * "strtrans()" function 16967 */ 16968 static void 16969 f_strtrans(argvars, rettv) 16970 typval_T *argvars; 16971 typval_T *rettv; 16972 { 16973 rettv->v_type = VAR_STRING; 16974 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 16975 } 16976 16977 /* 16978 * "submatch()" function 16979 */ 16980 static void 16981 f_submatch(argvars, rettv) 16982 typval_T *argvars; 16983 typval_T *rettv; 16984 { 16985 rettv->v_type = VAR_STRING; 16986 rettv->vval.v_string = 16987 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 16988 } 16989 16990 /* 16991 * "substitute()" function 16992 */ 16993 static void 16994 f_substitute(argvars, rettv) 16995 typval_T *argvars; 16996 typval_T *rettv; 16997 { 16998 char_u patbuf[NUMBUFLEN]; 16999 char_u subbuf[NUMBUFLEN]; 17000 char_u flagsbuf[NUMBUFLEN]; 17001 17002 char_u *str = get_tv_string_chk(&argvars[0]); 17003 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 17004 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 17005 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 17006 17007 rettv->v_type = VAR_STRING; 17008 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 17009 rettv->vval.v_string = NULL; 17010 else 17011 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 17012 } 17013 17014 /* 17015 * "synID(lnum, col, trans)" function 17016 */ 17017 static void 17018 f_synID(argvars, rettv) 17019 typval_T *argvars UNUSED; 17020 typval_T *rettv; 17021 { 17022 int id = 0; 17023 #ifdef FEAT_SYN_HL 17024 long lnum; 17025 long col; 17026 int trans; 17027 int transerr = FALSE; 17028 17029 lnum = get_tv_lnum(argvars); /* -1 on type error */ 17030 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 17031 trans = get_tv_number_chk(&argvars[2], &transerr); 17032 17033 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 17034 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 17035 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE); 17036 #endif 17037 17038 rettv->vval.v_number = id; 17039 } 17040 17041 /* 17042 * "synIDattr(id, what [, mode])" function 17043 */ 17044 static void 17045 f_synIDattr(argvars, rettv) 17046 typval_T *argvars UNUSED; 17047 typval_T *rettv; 17048 { 17049 char_u *p = NULL; 17050 #ifdef FEAT_SYN_HL 17051 int id; 17052 char_u *what; 17053 char_u *mode; 17054 char_u modebuf[NUMBUFLEN]; 17055 int modec; 17056 17057 id = get_tv_number(&argvars[0]); 17058 what = get_tv_string(&argvars[1]); 17059 if (argvars[2].v_type != VAR_UNKNOWN) 17060 { 17061 mode = get_tv_string_buf(&argvars[2], modebuf); 17062 modec = TOLOWER_ASC(mode[0]); 17063 if (modec != 't' && modec != 'c' && modec != 'g') 17064 modec = 0; /* replace invalid with current */ 17065 } 17066 else 17067 { 17068 #ifdef FEAT_GUI 17069 if (gui.in_use) 17070 modec = 'g'; 17071 else 17072 #endif 17073 if (t_colors > 1) 17074 modec = 'c'; 17075 else 17076 modec = 't'; 17077 } 17078 17079 17080 switch (TOLOWER_ASC(what[0])) 17081 { 17082 case 'b': 17083 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 17084 p = highlight_color(id, what, modec); 17085 else /* bold */ 17086 p = highlight_has_attr(id, HL_BOLD, modec); 17087 break; 17088 17089 case 'f': /* fg[#] or font */ 17090 p = highlight_color(id, what, modec); 17091 break; 17092 17093 case 'i': 17094 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 17095 p = highlight_has_attr(id, HL_INVERSE, modec); 17096 else /* italic */ 17097 p = highlight_has_attr(id, HL_ITALIC, modec); 17098 break; 17099 17100 case 'n': /* name */ 17101 p = get_highlight_name(NULL, id - 1); 17102 break; 17103 17104 case 'r': /* reverse */ 17105 p = highlight_has_attr(id, HL_INVERSE, modec); 17106 break; 17107 17108 case 's': 17109 if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */ 17110 p = highlight_color(id, what, modec); 17111 else /* standout */ 17112 p = highlight_has_attr(id, HL_STANDOUT, modec); 17113 break; 17114 17115 case 'u': 17116 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 17117 /* underline */ 17118 p = highlight_has_attr(id, HL_UNDERLINE, modec); 17119 else 17120 /* undercurl */ 17121 p = highlight_has_attr(id, HL_UNDERCURL, modec); 17122 break; 17123 } 17124 17125 if (p != NULL) 17126 p = vim_strsave(p); 17127 #endif 17128 rettv->v_type = VAR_STRING; 17129 rettv->vval.v_string = p; 17130 } 17131 17132 /* 17133 * "synIDtrans(id)" function 17134 */ 17135 static void 17136 f_synIDtrans(argvars, rettv) 17137 typval_T *argvars UNUSED; 17138 typval_T *rettv; 17139 { 17140 int id; 17141 17142 #ifdef FEAT_SYN_HL 17143 id = get_tv_number(&argvars[0]); 17144 17145 if (id > 0) 17146 id = syn_get_final_id(id); 17147 else 17148 #endif 17149 id = 0; 17150 17151 rettv->vval.v_number = id; 17152 } 17153 17154 /* 17155 * "synconcealed(lnum, col)" function 17156 */ 17157 static void 17158 f_synconcealed(argvars, rettv) 17159 typval_T *argvars UNUSED; 17160 typval_T *rettv; 17161 { 17162 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 17163 long lnum; 17164 long col; 17165 int syntax_flags = 0; 17166 int cchar; 17167 int matchid = 0; 17168 char_u str[NUMBUFLEN]; 17169 #endif 17170 17171 rettv->v_type = VAR_LIST; 17172 rettv->vval.v_list = NULL; 17173 17174 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 17175 lnum = get_tv_lnum(argvars); /* -1 on type error */ 17176 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 17177 17178 vim_memset(str, NUL, sizeof(str)); 17179 17180 if (rettv_list_alloc(rettv) != FAIL) 17181 { 17182 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 17183 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 17184 && curwin->w_p_cole > 0) 17185 { 17186 (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE); 17187 syntax_flags = get_syntax_info(&matchid); 17188 17189 /* get the conceal character */ 17190 if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) 17191 { 17192 cchar = syn_get_sub_char(); 17193 if (cchar == NUL && curwin->w_p_cole == 1 && lcs_conceal != NUL) 17194 cchar = lcs_conceal; 17195 if (cchar != NUL) 17196 { 17197 # ifdef FEAT_MBYTE 17198 if (has_mbyte) 17199 (*mb_char2bytes)(cchar, str); 17200 else 17201 # endif 17202 str[0] = cchar; 17203 } 17204 } 17205 } 17206 17207 list_append_number(rettv->vval.v_list, 17208 (syntax_flags & HL_CONCEAL) != 0); 17209 /* -1 to auto-determine strlen */ 17210 list_append_string(rettv->vval.v_list, str, -1); 17211 list_append_number(rettv->vval.v_list, matchid); 17212 } 17213 #endif 17214 } 17215 17216 /* 17217 * "synstack(lnum, col)" function 17218 */ 17219 static void 17220 f_synstack(argvars, rettv) 17221 typval_T *argvars UNUSED; 17222 typval_T *rettv; 17223 { 17224 #ifdef FEAT_SYN_HL 17225 long lnum; 17226 long col; 17227 int i; 17228 int id; 17229 #endif 17230 17231 rettv->v_type = VAR_LIST; 17232 rettv->vval.v_list = NULL; 17233 17234 #ifdef FEAT_SYN_HL 17235 lnum = get_tv_lnum(argvars); /* -1 on type error */ 17236 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 17237 17238 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 17239 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 17240 && rettv_list_alloc(rettv) != FAIL) 17241 { 17242 (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE); 17243 for (i = 0; ; ++i) 17244 { 17245 id = syn_get_stack_item(i); 17246 if (id < 0) 17247 break; 17248 if (list_append_number(rettv->vval.v_list, id) == FAIL) 17249 break; 17250 } 17251 } 17252 #endif 17253 } 17254 17255 /* 17256 * "system()" function 17257 */ 17258 static void 17259 f_system(argvars, rettv) 17260 typval_T *argvars; 17261 typval_T *rettv; 17262 { 17263 char_u *res = NULL; 17264 char_u *p; 17265 char_u *infile = NULL; 17266 char_u buf[NUMBUFLEN]; 17267 int err = FALSE; 17268 FILE *fd; 17269 17270 if (check_restricted() || check_secure()) 17271 goto done; 17272 17273 if (argvars[1].v_type != VAR_UNKNOWN) 17274 { 17275 /* 17276 * Write the string to a temp file, to be used for input of the shell 17277 * command. 17278 */ 17279 if ((infile = vim_tempname('i')) == NULL) 17280 { 17281 EMSG(_(e_notmp)); 17282 goto done; 17283 } 17284 17285 fd = mch_fopen((char *)infile, WRITEBIN); 17286 if (fd == NULL) 17287 { 17288 EMSG2(_(e_notopen), infile); 17289 goto done; 17290 } 17291 p = get_tv_string_buf_chk(&argvars[1], buf); 17292 if (p == NULL) 17293 { 17294 fclose(fd); 17295 goto done; /* type error; errmsg already given */ 17296 } 17297 if (fwrite(p, STRLEN(p), 1, fd) != 1) 17298 err = TRUE; 17299 if (fclose(fd) != 0) 17300 err = TRUE; 17301 if (err) 17302 { 17303 EMSG(_("E677: Error writing temp file")); 17304 goto done; 17305 } 17306 } 17307 17308 res = get_cmd_output(get_tv_string(&argvars[0]), infile, 17309 SHELL_SILENT | SHELL_COOKED); 17310 17311 #ifdef USE_CR 17312 /* translate <CR> into <NL> */ 17313 if (res != NULL) 17314 { 17315 char_u *s; 17316 17317 for (s = res; *s; ++s) 17318 { 17319 if (*s == CAR) 17320 *s = NL; 17321 } 17322 } 17323 #else 17324 # ifdef USE_CRNL 17325 /* translate <CR><NL> into <NL> */ 17326 if (res != NULL) 17327 { 17328 char_u *s, *d; 17329 17330 d = res; 17331 for (s = res; *s; ++s) 17332 { 17333 if (s[0] == CAR && s[1] == NL) 17334 ++s; 17335 *d++ = *s; 17336 } 17337 *d = NUL; 17338 } 17339 # endif 17340 #endif 17341 17342 done: 17343 if (infile != NULL) 17344 { 17345 mch_remove(infile); 17346 vim_free(infile); 17347 } 17348 rettv->v_type = VAR_STRING; 17349 rettv->vval.v_string = res; 17350 } 17351 17352 /* 17353 * "tabpagebuflist()" function 17354 */ 17355 static void 17356 f_tabpagebuflist(argvars, rettv) 17357 typval_T *argvars UNUSED; 17358 typval_T *rettv UNUSED; 17359 { 17360 #ifdef FEAT_WINDOWS 17361 tabpage_T *tp; 17362 win_T *wp = NULL; 17363 17364 if (argvars[0].v_type == VAR_UNKNOWN) 17365 wp = firstwin; 17366 else 17367 { 17368 tp = find_tabpage((int)get_tv_number(&argvars[0])); 17369 if (tp != NULL) 17370 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 17371 } 17372 if (wp != NULL && rettv_list_alloc(rettv) != FAIL) 17373 { 17374 for (; wp != NULL; wp = wp->w_next) 17375 if (list_append_number(rettv->vval.v_list, 17376 wp->w_buffer->b_fnum) == FAIL) 17377 break; 17378 } 17379 #endif 17380 } 17381 17382 17383 /* 17384 * "tabpagenr()" function 17385 */ 17386 static void 17387 f_tabpagenr(argvars, rettv) 17388 typval_T *argvars UNUSED; 17389 typval_T *rettv; 17390 { 17391 int nr = 1; 17392 #ifdef FEAT_WINDOWS 17393 char_u *arg; 17394 17395 if (argvars[0].v_type != VAR_UNKNOWN) 17396 { 17397 arg = get_tv_string_chk(&argvars[0]); 17398 nr = 0; 17399 if (arg != NULL) 17400 { 17401 if (STRCMP(arg, "$") == 0) 17402 nr = tabpage_index(NULL) - 1; 17403 else 17404 EMSG2(_(e_invexpr2), arg); 17405 } 17406 } 17407 else 17408 nr = tabpage_index(curtab); 17409 #endif 17410 rettv->vval.v_number = nr; 17411 } 17412 17413 17414 #ifdef FEAT_WINDOWS 17415 static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 17416 17417 /* 17418 * Common code for tabpagewinnr() and winnr(). 17419 */ 17420 static int 17421 get_winnr(tp, argvar) 17422 tabpage_T *tp; 17423 typval_T *argvar; 17424 { 17425 win_T *twin; 17426 int nr = 1; 17427 win_T *wp; 17428 char_u *arg; 17429 17430 twin = (tp == curtab) ? curwin : tp->tp_curwin; 17431 if (argvar->v_type != VAR_UNKNOWN) 17432 { 17433 arg = get_tv_string_chk(argvar); 17434 if (arg == NULL) 17435 nr = 0; /* type error; errmsg already given */ 17436 else if (STRCMP(arg, "$") == 0) 17437 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 17438 else if (STRCMP(arg, "#") == 0) 17439 { 17440 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 17441 if (twin == NULL) 17442 nr = 0; 17443 } 17444 else 17445 { 17446 EMSG2(_(e_invexpr2), arg); 17447 nr = 0; 17448 } 17449 } 17450 17451 if (nr > 0) 17452 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 17453 wp != twin; wp = wp->w_next) 17454 { 17455 if (wp == NULL) 17456 { 17457 /* didn't find it in this tabpage */ 17458 nr = 0; 17459 break; 17460 } 17461 ++nr; 17462 } 17463 return nr; 17464 } 17465 #endif 17466 17467 /* 17468 * "tabpagewinnr()" function 17469 */ 17470 static void 17471 f_tabpagewinnr(argvars, rettv) 17472 typval_T *argvars UNUSED; 17473 typval_T *rettv; 17474 { 17475 int nr = 1; 17476 #ifdef FEAT_WINDOWS 17477 tabpage_T *tp; 17478 17479 tp = find_tabpage((int)get_tv_number(&argvars[0])); 17480 if (tp == NULL) 17481 nr = 0; 17482 else 17483 nr = get_winnr(tp, &argvars[1]); 17484 #endif 17485 rettv->vval.v_number = nr; 17486 } 17487 17488 17489 /* 17490 * "tagfiles()" function 17491 */ 17492 static void 17493 f_tagfiles(argvars, rettv) 17494 typval_T *argvars UNUSED; 17495 typval_T *rettv; 17496 { 17497 char_u fname[MAXPATHL + 1]; 17498 tagname_T tn; 17499 int first; 17500 17501 if (rettv_list_alloc(rettv) == FAIL) 17502 return; 17503 17504 for (first = TRUE; ; first = FALSE) 17505 if (get_tagfname(&tn, first, fname) == FAIL 17506 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 17507 break; 17508 tagname_free(&tn); 17509 } 17510 17511 /* 17512 * "taglist()" function 17513 */ 17514 static void 17515 f_taglist(argvars, rettv) 17516 typval_T *argvars; 17517 typval_T *rettv; 17518 { 17519 char_u *tag_pattern; 17520 17521 tag_pattern = get_tv_string(&argvars[0]); 17522 17523 rettv->vval.v_number = FALSE; 17524 if (*tag_pattern == NUL) 17525 return; 17526 17527 if (rettv_list_alloc(rettv) == OK) 17528 (void)get_tags(rettv->vval.v_list, tag_pattern); 17529 } 17530 17531 /* 17532 * "tempname()" function 17533 */ 17534 static void 17535 f_tempname(argvars, rettv) 17536 typval_T *argvars UNUSED; 17537 typval_T *rettv; 17538 { 17539 static int x = 'A'; 17540 17541 rettv->v_type = VAR_STRING; 17542 rettv->vval.v_string = vim_tempname(x); 17543 17544 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 17545 * names. Skip 'I' and 'O', they are used for shell redirection. */ 17546 do 17547 { 17548 if (x == 'Z') 17549 x = '0'; 17550 else if (x == '9') 17551 x = 'A'; 17552 else 17553 { 17554 #ifdef EBCDIC 17555 if (x == 'I') 17556 x = 'J'; 17557 else if (x == 'R') 17558 x = 'S'; 17559 else 17560 #endif 17561 ++x; 17562 } 17563 } while (x == 'I' || x == 'O'); 17564 } 17565 17566 /* 17567 * "test(list)" function: Just checking the walls... 17568 */ 17569 static void 17570 f_test(argvars, rettv) 17571 typval_T *argvars UNUSED; 17572 typval_T *rettv UNUSED; 17573 { 17574 /* Used for unit testing. Change the code below to your liking. */ 17575 #if 0 17576 listitem_T *li; 17577 list_T *l; 17578 char_u *bad, *good; 17579 17580 if (argvars[0].v_type != VAR_LIST) 17581 return; 17582 l = argvars[0].vval.v_list; 17583 if (l == NULL) 17584 return; 17585 li = l->lv_first; 17586 if (li == NULL) 17587 return; 17588 bad = get_tv_string(&li->li_tv); 17589 li = li->li_next; 17590 if (li == NULL) 17591 return; 17592 good = get_tv_string(&li->li_tv); 17593 rettv->vval.v_number = test_edit_score(bad, good); 17594 #endif 17595 } 17596 17597 #ifdef FEAT_FLOAT 17598 /* 17599 * "tan()" function 17600 */ 17601 static void 17602 f_tan(argvars, rettv) 17603 typval_T *argvars; 17604 typval_T *rettv; 17605 { 17606 float_T f; 17607 17608 rettv->v_type = VAR_FLOAT; 17609 if (get_float_arg(argvars, &f) == OK) 17610 rettv->vval.v_float = tan(f); 17611 else 17612 rettv->vval.v_float = 0.0; 17613 } 17614 17615 /* 17616 * "tanh()" function 17617 */ 17618 static void 17619 f_tanh(argvars, rettv) 17620 typval_T *argvars; 17621 typval_T *rettv; 17622 { 17623 float_T f; 17624 17625 rettv->v_type = VAR_FLOAT; 17626 if (get_float_arg(argvars, &f) == OK) 17627 rettv->vval.v_float = tanh(f); 17628 else 17629 rettv->vval.v_float = 0.0; 17630 } 17631 #endif 17632 17633 /* 17634 * "tolower(string)" function 17635 */ 17636 static void 17637 f_tolower(argvars, rettv) 17638 typval_T *argvars; 17639 typval_T *rettv; 17640 { 17641 char_u *p; 17642 17643 p = vim_strsave(get_tv_string(&argvars[0])); 17644 rettv->v_type = VAR_STRING; 17645 rettv->vval.v_string = p; 17646 17647 if (p != NULL) 17648 while (*p != NUL) 17649 { 17650 #ifdef FEAT_MBYTE 17651 int l; 17652 17653 if (enc_utf8) 17654 { 17655 int c, lc; 17656 17657 c = utf_ptr2char(p); 17658 lc = utf_tolower(c); 17659 l = utf_ptr2len(p); 17660 /* TODO: reallocate string when byte count changes. */ 17661 if (utf_char2len(lc) == l) 17662 utf_char2bytes(lc, p); 17663 p += l; 17664 } 17665 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 17666 p += l; /* skip multi-byte character */ 17667 else 17668 #endif 17669 { 17670 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 17671 ++p; 17672 } 17673 } 17674 } 17675 17676 /* 17677 * "toupper(string)" function 17678 */ 17679 static void 17680 f_toupper(argvars, rettv) 17681 typval_T *argvars; 17682 typval_T *rettv; 17683 { 17684 rettv->v_type = VAR_STRING; 17685 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 17686 } 17687 17688 /* 17689 * "tr(string, fromstr, tostr)" function 17690 */ 17691 static void 17692 f_tr(argvars, rettv) 17693 typval_T *argvars; 17694 typval_T *rettv; 17695 { 17696 char_u *instr; 17697 char_u *fromstr; 17698 char_u *tostr; 17699 char_u *p; 17700 #ifdef FEAT_MBYTE 17701 int inlen; 17702 int fromlen; 17703 int tolen; 17704 int idx; 17705 char_u *cpstr; 17706 int cplen; 17707 int first = TRUE; 17708 #endif 17709 char_u buf[NUMBUFLEN]; 17710 char_u buf2[NUMBUFLEN]; 17711 garray_T ga; 17712 17713 instr = get_tv_string(&argvars[0]); 17714 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 17715 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 17716 17717 /* Default return value: empty string. */ 17718 rettv->v_type = VAR_STRING; 17719 rettv->vval.v_string = NULL; 17720 if (fromstr == NULL || tostr == NULL) 17721 return; /* type error; errmsg already given */ 17722 ga_init2(&ga, (int)sizeof(char), 80); 17723 17724 #ifdef FEAT_MBYTE 17725 if (!has_mbyte) 17726 #endif 17727 /* not multi-byte: fromstr and tostr must be the same length */ 17728 if (STRLEN(fromstr) != STRLEN(tostr)) 17729 { 17730 #ifdef FEAT_MBYTE 17731 error: 17732 #endif 17733 EMSG2(_(e_invarg2), fromstr); 17734 ga_clear(&ga); 17735 return; 17736 } 17737 17738 /* fromstr and tostr have to contain the same number of chars */ 17739 while (*instr != NUL) 17740 { 17741 #ifdef FEAT_MBYTE 17742 if (has_mbyte) 17743 { 17744 inlen = (*mb_ptr2len)(instr); 17745 cpstr = instr; 17746 cplen = inlen; 17747 idx = 0; 17748 for (p = fromstr; *p != NUL; p += fromlen) 17749 { 17750 fromlen = (*mb_ptr2len)(p); 17751 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 17752 { 17753 for (p = tostr; *p != NUL; p += tolen) 17754 { 17755 tolen = (*mb_ptr2len)(p); 17756 if (idx-- == 0) 17757 { 17758 cplen = tolen; 17759 cpstr = p; 17760 break; 17761 } 17762 } 17763 if (*p == NUL) /* tostr is shorter than fromstr */ 17764 goto error; 17765 break; 17766 } 17767 ++idx; 17768 } 17769 17770 if (first && cpstr == instr) 17771 { 17772 /* Check that fromstr and tostr have the same number of 17773 * (multi-byte) characters. Done only once when a character 17774 * of instr doesn't appear in fromstr. */ 17775 first = FALSE; 17776 for (p = tostr; *p != NUL; p += tolen) 17777 { 17778 tolen = (*mb_ptr2len)(p); 17779 --idx; 17780 } 17781 if (idx != 0) 17782 goto error; 17783 } 17784 17785 ga_grow(&ga, cplen); 17786 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 17787 ga.ga_len += cplen; 17788 17789 instr += inlen; 17790 } 17791 else 17792 #endif 17793 { 17794 /* When not using multi-byte chars we can do it faster. */ 17795 p = vim_strchr(fromstr, *instr); 17796 if (p != NULL) 17797 ga_append(&ga, tostr[p - fromstr]); 17798 else 17799 ga_append(&ga, *instr); 17800 ++instr; 17801 } 17802 } 17803 17804 /* add a terminating NUL */ 17805 ga_grow(&ga, 1); 17806 ga_append(&ga, NUL); 17807 17808 rettv->vval.v_string = ga.ga_data; 17809 } 17810 17811 #ifdef FEAT_FLOAT 17812 /* 17813 * "trunc({float})" function 17814 */ 17815 static void 17816 f_trunc(argvars, rettv) 17817 typval_T *argvars; 17818 typval_T *rettv; 17819 { 17820 float_T f; 17821 17822 rettv->v_type = VAR_FLOAT; 17823 if (get_float_arg(argvars, &f) == OK) 17824 /* trunc() is not in C90, use floor() or ceil() instead. */ 17825 rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); 17826 else 17827 rettv->vval.v_float = 0.0; 17828 } 17829 #endif 17830 17831 /* 17832 * "type(expr)" function 17833 */ 17834 static void 17835 f_type(argvars, rettv) 17836 typval_T *argvars; 17837 typval_T *rettv; 17838 { 17839 int n; 17840 17841 switch (argvars[0].v_type) 17842 { 17843 case VAR_NUMBER: n = 0; break; 17844 case VAR_STRING: n = 1; break; 17845 case VAR_FUNC: n = 2; break; 17846 case VAR_LIST: n = 3; break; 17847 case VAR_DICT: n = 4; break; 17848 #ifdef FEAT_FLOAT 17849 case VAR_FLOAT: n = 5; break; 17850 #endif 17851 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 17852 } 17853 rettv->vval.v_number = n; 17854 } 17855 17856 /* 17857 * "undofile(name)" function 17858 */ 17859 static void 17860 f_undofile(argvars, rettv) 17861 typval_T *argvars; 17862 typval_T *rettv; 17863 { 17864 rettv->v_type = VAR_STRING; 17865 #ifdef FEAT_PERSISTENT_UNDO 17866 { 17867 char_u *ffname = FullName_save(get_tv_string(&argvars[0]), FALSE); 17868 17869 if (ffname != NULL) 17870 rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE); 17871 vim_free(ffname); 17872 } 17873 #else 17874 rettv->vval.v_string = NULL; 17875 #endif 17876 } 17877 17878 /* 17879 * "undotree()" function 17880 */ 17881 static void 17882 f_undotree(argvars, rettv) 17883 typval_T *argvars UNUSED; 17884 typval_T *rettv; 17885 { 17886 if (rettv_dict_alloc(rettv) == OK) 17887 { 17888 dict_T *dict = rettv->vval.v_dict; 17889 list_T *list; 17890 17891 dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL); 17892 dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL); 17893 dict_add_nr_str(dict, "save_last", 17894 (long)curbuf->b_u_save_nr_last, NULL); 17895 dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL); 17896 dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL); 17897 dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL); 17898 17899 list = list_alloc(); 17900 if (list != NULL) 17901 { 17902 u_eval_tree(curbuf->b_u_oldhead, list); 17903 dict_add_list(dict, "entries", list); 17904 } 17905 } 17906 } 17907 17908 /* 17909 * "values(dict)" function 17910 */ 17911 static void 17912 f_values(argvars, rettv) 17913 typval_T *argvars; 17914 typval_T *rettv; 17915 { 17916 dict_list(argvars, rettv, 1); 17917 } 17918 17919 /* 17920 * "virtcol(string)" function 17921 */ 17922 static void 17923 f_virtcol(argvars, rettv) 17924 typval_T *argvars; 17925 typval_T *rettv; 17926 { 17927 colnr_T vcol = 0; 17928 pos_T *fp; 17929 int fnum = curbuf->b_fnum; 17930 17931 fp = var2fpos(&argvars[0], FALSE, &fnum); 17932 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 17933 && fnum == curbuf->b_fnum) 17934 { 17935 getvvcol(curwin, fp, NULL, NULL, &vcol); 17936 ++vcol; 17937 } 17938 17939 rettv->vval.v_number = vcol; 17940 } 17941 17942 /* 17943 * "visualmode()" function 17944 */ 17945 static void 17946 f_visualmode(argvars, rettv) 17947 typval_T *argvars UNUSED; 17948 typval_T *rettv UNUSED; 17949 { 17950 #ifdef FEAT_VISUAL 17951 char_u str[2]; 17952 17953 rettv->v_type = VAR_STRING; 17954 str[0] = curbuf->b_visual_mode_eval; 17955 str[1] = NUL; 17956 rettv->vval.v_string = vim_strsave(str); 17957 17958 /* A non-zero number or non-empty string argument: reset mode. */ 17959 if (non_zero_arg(&argvars[0])) 17960 curbuf->b_visual_mode_eval = NUL; 17961 #endif 17962 } 17963 17964 /* 17965 * "winbufnr(nr)" function 17966 */ 17967 static void 17968 f_winbufnr(argvars, rettv) 17969 typval_T *argvars; 17970 typval_T *rettv; 17971 { 17972 win_T *wp; 17973 17974 wp = find_win_by_nr(&argvars[0], NULL); 17975 if (wp == NULL) 17976 rettv->vval.v_number = -1; 17977 else 17978 rettv->vval.v_number = wp->w_buffer->b_fnum; 17979 } 17980 17981 /* 17982 * "wincol()" function 17983 */ 17984 static void 17985 f_wincol(argvars, rettv) 17986 typval_T *argvars UNUSED; 17987 typval_T *rettv; 17988 { 17989 validate_cursor(); 17990 rettv->vval.v_number = curwin->w_wcol + 1; 17991 } 17992 17993 /* 17994 * "winheight(nr)" function 17995 */ 17996 static void 17997 f_winheight(argvars, rettv) 17998 typval_T *argvars; 17999 typval_T *rettv; 18000 { 18001 win_T *wp; 18002 18003 wp = find_win_by_nr(&argvars[0], NULL); 18004 if (wp == NULL) 18005 rettv->vval.v_number = -1; 18006 else 18007 rettv->vval.v_number = wp->w_height; 18008 } 18009 18010 /* 18011 * "winline()" function 18012 */ 18013 static void 18014 f_winline(argvars, rettv) 18015 typval_T *argvars UNUSED; 18016 typval_T *rettv; 18017 { 18018 validate_cursor(); 18019 rettv->vval.v_number = curwin->w_wrow + 1; 18020 } 18021 18022 /* 18023 * "winnr()" function 18024 */ 18025 static void 18026 f_winnr(argvars, rettv) 18027 typval_T *argvars UNUSED; 18028 typval_T *rettv; 18029 { 18030 int nr = 1; 18031 18032 #ifdef FEAT_WINDOWS 18033 nr = get_winnr(curtab, &argvars[0]); 18034 #endif 18035 rettv->vval.v_number = nr; 18036 } 18037 18038 /* 18039 * "winrestcmd()" function 18040 */ 18041 static void 18042 f_winrestcmd(argvars, rettv) 18043 typval_T *argvars UNUSED; 18044 typval_T *rettv; 18045 { 18046 #ifdef FEAT_WINDOWS 18047 win_T *wp; 18048 int winnr = 1; 18049 garray_T ga; 18050 char_u buf[50]; 18051 18052 ga_init2(&ga, (int)sizeof(char), 70); 18053 for (wp = firstwin; wp != NULL; wp = wp->w_next) 18054 { 18055 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 18056 ga_concat(&ga, buf); 18057 # ifdef FEAT_VERTSPLIT 18058 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 18059 ga_concat(&ga, buf); 18060 # endif 18061 ++winnr; 18062 } 18063 ga_append(&ga, NUL); 18064 18065 rettv->vval.v_string = ga.ga_data; 18066 #else 18067 rettv->vval.v_string = NULL; 18068 #endif 18069 rettv->v_type = VAR_STRING; 18070 } 18071 18072 /* 18073 * "winrestview()" function 18074 */ 18075 static void 18076 f_winrestview(argvars, rettv) 18077 typval_T *argvars; 18078 typval_T *rettv UNUSED; 18079 { 18080 dict_T *dict; 18081 18082 if (argvars[0].v_type != VAR_DICT 18083 || (dict = argvars[0].vval.v_dict) == NULL) 18084 EMSG(_(e_invarg)); 18085 else 18086 { 18087 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 18088 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 18089 #ifdef FEAT_VIRTUALEDIT 18090 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 18091 #endif 18092 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 18093 curwin->w_set_curswant = FALSE; 18094 18095 set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); 18096 #ifdef FEAT_DIFF 18097 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 18098 #endif 18099 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 18100 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 18101 18102 check_cursor(); 18103 changed_cline_bef_curs(); 18104 invalidate_botline(); 18105 redraw_later(VALID); 18106 18107 if (curwin->w_topline == 0) 18108 curwin->w_topline = 1; 18109 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 18110 curwin->w_topline = curbuf->b_ml.ml_line_count; 18111 #ifdef FEAT_DIFF 18112 check_topfill(curwin, TRUE); 18113 #endif 18114 } 18115 } 18116 18117 /* 18118 * "winsaveview()" function 18119 */ 18120 static void 18121 f_winsaveview(argvars, rettv) 18122 typval_T *argvars UNUSED; 18123 typval_T *rettv; 18124 { 18125 dict_T *dict; 18126 18127 if (rettv_dict_alloc(rettv) == FAIL) 18128 return; 18129 dict = rettv->vval.v_dict; 18130 18131 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 18132 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 18133 #ifdef FEAT_VIRTUALEDIT 18134 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 18135 #endif 18136 update_curswant(); 18137 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 18138 18139 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 18140 #ifdef FEAT_DIFF 18141 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 18142 #endif 18143 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 18144 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 18145 } 18146 18147 /* 18148 * "winwidth(nr)" function 18149 */ 18150 static void 18151 f_winwidth(argvars, rettv) 18152 typval_T *argvars; 18153 typval_T *rettv; 18154 { 18155 win_T *wp; 18156 18157 wp = find_win_by_nr(&argvars[0], NULL); 18158 if (wp == NULL) 18159 rettv->vval.v_number = -1; 18160 else 18161 #ifdef FEAT_VERTSPLIT 18162 rettv->vval.v_number = wp->w_width; 18163 #else 18164 rettv->vval.v_number = Columns; 18165 #endif 18166 } 18167 18168 /* 18169 * "writefile()" function 18170 */ 18171 static void 18172 f_writefile(argvars, rettv) 18173 typval_T *argvars; 18174 typval_T *rettv; 18175 { 18176 int binary = FALSE; 18177 char_u *fname; 18178 FILE *fd; 18179 listitem_T *li; 18180 char_u *s; 18181 int ret = 0; 18182 int c; 18183 18184 if (check_restricted() || check_secure()) 18185 return; 18186 18187 if (argvars[0].v_type != VAR_LIST) 18188 { 18189 EMSG2(_(e_listarg), "writefile()"); 18190 return; 18191 } 18192 if (argvars[0].vval.v_list == NULL) 18193 return; 18194 18195 if (argvars[2].v_type != VAR_UNKNOWN 18196 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 18197 binary = TRUE; 18198 18199 /* Always open the file in binary mode, library functions have a mind of 18200 * their own about CR-LF conversion. */ 18201 fname = get_tv_string(&argvars[1]); 18202 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 18203 { 18204 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 18205 ret = -1; 18206 } 18207 else 18208 { 18209 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 18210 li = li->li_next) 18211 { 18212 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 18213 { 18214 if (*s == '\n') 18215 c = putc(NUL, fd); 18216 else 18217 c = putc(*s, fd); 18218 if (c == EOF) 18219 { 18220 ret = -1; 18221 break; 18222 } 18223 } 18224 if (!binary || li->li_next != NULL) 18225 if (putc('\n', fd) == EOF) 18226 { 18227 ret = -1; 18228 break; 18229 } 18230 if (ret < 0) 18231 { 18232 EMSG(_(e_write)); 18233 break; 18234 } 18235 } 18236 fclose(fd); 18237 } 18238 18239 rettv->vval.v_number = ret; 18240 } 18241 18242 /* 18243 * Translate a String variable into a position. 18244 * Returns NULL when there is an error. 18245 */ 18246 static pos_T * 18247 var2fpos(varp, dollar_lnum, fnum) 18248 typval_T *varp; 18249 int dollar_lnum; /* TRUE when $ is last line */ 18250 int *fnum; /* set to fnum for '0, 'A, etc. */ 18251 { 18252 char_u *name; 18253 static pos_T pos; 18254 pos_T *pp; 18255 18256 /* Argument can be [lnum, col, coladd]. */ 18257 if (varp->v_type == VAR_LIST) 18258 { 18259 list_T *l; 18260 int len; 18261 int error = FALSE; 18262 listitem_T *li; 18263 18264 l = varp->vval.v_list; 18265 if (l == NULL) 18266 return NULL; 18267 18268 /* Get the line number */ 18269 pos.lnum = list_find_nr(l, 0L, &error); 18270 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 18271 return NULL; /* invalid line number */ 18272 18273 /* Get the column number */ 18274 pos.col = list_find_nr(l, 1L, &error); 18275 if (error) 18276 return NULL; 18277 len = (long)STRLEN(ml_get(pos.lnum)); 18278 18279 /* We accept "$" for the column number: last column. */ 18280 li = list_find(l, 1L); 18281 if (li != NULL && li->li_tv.v_type == VAR_STRING 18282 && li->li_tv.vval.v_string != NULL 18283 && STRCMP(li->li_tv.vval.v_string, "$") == 0) 18284 pos.col = len + 1; 18285 18286 /* Accept a position up to the NUL after the line. */ 18287 if (pos.col == 0 || (int)pos.col > len + 1) 18288 return NULL; /* invalid column number */ 18289 --pos.col; 18290 18291 #ifdef FEAT_VIRTUALEDIT 18292 /* Get the virtual offset. Defaults to zero. */ 18293 pos.coladd = list_find_nr(l, 2L, &error); 18294 if (error) 18295 pos.coladd = 0; 18296 #endif 18297 18298 return &pos; 18299 } 18300 18301 name = get_tv_string_chk(varp); 18302 if (name == NULL) 18303 return NULL; 18304 if (name[0] == '.') /* cursor */ 18305 return &curwin->w_cursor; 18306 #ifdef FEAT_VISUAL 18307 if (name[0] == 'v' && name[1] == NUL) /* Visual start */ 18308 { 18309 if (VIsual_active) 18310 return &VIsual; 18311 return &curwin->w_cursor; 18312 } 18313 #endif 18314 if (name[0] == '\'') /* mark */ 18315 { 18316 pp = getmark_fnum(name[1], FALSE, fnum); 18317 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 18318 return NULL; 18319 return pp; 18320 } 18321 18322 #ifdef FEAT_VIRTUALEDIT 18323 pos.coladd = 0; 18324 #endif 18325 18326 if (name[0] == 'w' && dollar_lnum) 18327 { 18328 pos.col = 0; 18329 if (name[1] == '0') /* "w0": first visible line */ 18330 { 18331 update_topline(); 18332 pos.lnum = curwin->w_topline; 18333 return &pos; 18334 } 18335 else if (name[1] == '$') /* "w$": last visible line */ 18336 { 18337 validate_botline(); 18338 pos.lnum = curwin->w_botline - 1; 18339 return &pos; 18340 } 18341 } 18342 else if (name[0] == '$') /* last column or line */ 18343 { 18344 if (dollar_lnum) 18345 { 18346 pos.lnum = curbuf->b_ml.ml_line_count; 18347 pos.col = 0; 18348 } 18349 else 18350 { 18351 pos.lnum = curwin->w_cursor.lnum; 18352 pos.col = (colnr_T)STRLEN(ml_get_curline()); 18353 } 18354 return &pos; 18355 } 18356 return NULL; 18357 } 18358 18359 /* 18360 * Convert list in "arg" into a position and optional file number. 18361 * When "fnump" is NULL there is no file number, only 3 items. 18362 * Note that the column is passed on as-is, the caller may want to decrement 18363 * it to use 1 for the first column. 18364 * Return FAIL when conversion is not possible, doesn't check the position for 18365 * validity. 18366 */ 18367 static int 18368 list2fpos(arg, posp, fnump) 18369 typval_T *arg; 18370 pos_T *posp; 18371 int *fnump; 18372 { 18373 list_T *l = arg->vval.v_list; 18374 long i = 0; 18375 long n; 18376 18377 /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there 18378 * when "fnump" isn't NULL and "coladd" is optional. */ 18379 if (arg->v_type != VAR_LIST 18380 || l == NULL 18381 || l->lv_len < (fnump == NULL ? 2 : 3) 18382 || l->lv_len > (fnump == NULL ? 3 : 4)) 18383 return FAIL; 18384 18385 if (fnump != NULL) 18386 { 18387 n = list_find_nr(l, i++, NULL); /* fnum */ 18388 if (n < 0) 18389 return FAIL; 18390 if (n == 0) 18391 n = curbuf->b_fnum; /* current buffer */ 18392 *fnump = n; 18393 } 18394 18395 n = list_find_nr(l, i++, NULL); /* lnum */ 18396 if (n < 0) 18397 return FAIL; 18398 posp->lnum = n; 18399 18400 n = list_find_nr(l, i++, NULL); /* col */ 18401 if (n < 0) 18402 return FAIL; 18403 posp->col = n; 18404 18405 #ifdef FEAT_VIRTUALEDIT 18406 n = list_find_nr(l, i, NULL); 18407 if (n < 0) 18408 posp->coladd = 0; 18409 else 18410 posp->coladd = n; 18411 #endif 18412 18413 return OK; 18414 } 18415 18416 /* 18417 * Get the length of an environment variable name. 18418 * Advance "arg" to the first character after the name. 18419 * Return 0 for error. 18420 */ 18421 static int 18422 get_env_len(arg) 18423 char_u **arg; 18424 { 18425 char_u *p; 18426 int len; 18427 18428 for (p = *arg; vim_isIDc(*p); ++p) 18429 ; 18430 if (p == *arg) /* no name found */ 18431 return 0; 18432 18433 len = (int)(p - *arg); 18434 *arg = p; 18435 return len; 18436 } 18437 18438 /* 18439 * Get the length of the name of a function or internal variable. 18440 * "arg" is advanced to the first non-white character after the name. 18441 * Return 0 if something is wrong. 18442 */ 18443 static int 18444 get_id_len(arg) 18445 char_u **arg; 18446 { 18447 char_u *p; 18448 int len; 18449 18450 /* Find the end of the name. */ 18451 for (p = *arg; eval_isnamec(*p); ++p) 18452 ; 18453 if (p == *arg) /* no name found */ 18454 return 0; 18455 18456 len = (int)(p - *arg); 18457 *arg = skipwhite(p); 18458 18459 return len; 18460 } 18461 18462 /* 18463 * Get the length of the name of a variable or function. 18464 * Only the name is recognized, does not handle ".key" or "[idx]". 18465 * "arg" is advanced to the first non-white character after the name. 18466 * Return -1 if curly braces expansion failed. 18467 * Return 0 if something else is wrong. 18468 * If the name contains 'magic' {}'s, expand them and return the 18469 * expanded name in an allocated string via 'alias' - caller must free. 18470 */ 18471 static int 18472 get_name_len(arg, alias, evaluate, verbose) 18473 char_u **arg; 18474 char_u **alias; 18475 int evaluate; 18476 int verbose; 18477 { 18478 int len; 18479 char_u *p; 18480 char_u *expr_start; 18481 char_u *expr_end; 18482 18483 *alias = NULL; /* default to no alias */ 18484 18485 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 18486 && (*arg)[2] == (int)KE_SNR) 18487 { 18488 /* hard coded <SNR>, already translated */ 18489 *arg += 3; 18490 return get_id_len(arg) + 3; 18491 } 18492 len = eval_fname_script(*arg); 18493 if (len > 0) 18494 { 18495 /* literal "<SID>", "s:" or "<SNR>" */ 18496 *arg += len; 18497 } 18498 18499 /* 18500 * Find the end of the name; check for {} construction. 18501 */ 18502 p = find_name_end(*arg, &expr_start, &expr_end, 18503 len > 0 ? 0 : FNE_CHECK_START); 18504 if (expr_start != NULL) 18505 { 18506 char_u *temp_string; 18507 18508 if (!evaluate) 18509 { 18510 len += (int)(p - *arg); 18511 *arg = skipwhite(p); 18512 return len; 18513 } 18514 18515 /* 18516 * Include any <SID> etc in the expanded string: 18517 * Thus the -len here. 18518 */ 18519 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 18520 if (temp_string == NULL) 18521 return -1; 18522 *alias = temp_string; 18523 *arg = skipwhite(p); 18524 return (int)STRLEN(temp_string); 18525 } 18526 18527 len += get_id_len(arg); 18528 if (len == 0 && verbose) 18529 EMSG2(_(e_invexpr2), *arg); 18530 18531 return len; 18532 } 18533 18534 /* 18535 * Find the end of a variable or function name, taking care of magic braces. 18536 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 18537 * start and end of the first magic braces item. 18538 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 18539 * Return a pointer to just after the name. Equal to "arg" if there is no 18540 * valid name. 18541 */ 18542 static char_u * 18543 find_name_end(arg, expr_start, expr_end, flags) 18544 char_u *arg; 18545 char_u **expr_start; 18546 char_u **expr_end; 18547 int flags; 18548 { 18549 int mb_nest = 0; 18550 int br_nest = 0; 18551 char_u *p; 18552 18553 if (expr_start != NULL) 18554 { 18555 *expr_start = NULL; 18556 *expr_end = NULL; 18557 } 18558 18559 /* Quick check for valid starting character. */ 18560 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 18561 return arg; 18562 18563 for (p = arg; *p != NUL 18564 && (eval_isnamec(*p) 18565 || *p == '{' 18566 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 18567 || mb_nest != 0 18568 || br_nest != 0); mb_ptr_adv(p)) 18569 { 18570 if (*p == '\'') 18571 { 18572 /* skip over 'string' to avoid counting [ and ] inside it. */ 18573 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 18574 ; 18575 if (*p == NUL) 18576 break; 18577 } 18578 else if (*p == '"') 18579 { 18580 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 18581 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 18582 if (*p == '\\' && p[1] != NUL) 18583 ++p; 18584 if (*p == NUL) 18585 break; 18586 } 18587 18588 if (mb_nest == 0) 18589 { 18590 if (*p == '[') 18591 ++br_nest; 18592 else if (*p == ']') 18593 --br_nest; 18594 } 18595 18596 if (br_nest == 0) 18597 { 18598 if (*p == '{') 18599 { 18600 mb_nest++; 18601 if (expr_start != NULL && *expr_start == NULL) 18602 *expr_start = p; 18603 } 18604 else if (*p == '}') 18605 { 18606 mb_nest--; 18607 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 18608 *expr_end = p; 18609 } 18610 } 18611 } 18612 18613 return p; 18614 } 18615 18616 /* 18617 * Expands out the 'magic' {}'s in a variable/function name. 18618 * Note that this can call itself recursively, to deal with 18619 * constructs like foo{bar}{baz}{bam} 18620 * The four pointer arguments point to "foo{expre}ss{ion}bar" 18621 * "in_start" ^ 18622 * "expr_start" ^ 18623 * "expr_end" ^ 18624 * "in_end" ^ 18625 * 18626 * Returns a new allocated string, which the caller must free. 18627 * Returns NULL for failure. 18628 */ 18629 static char_u * 18630 make_expanded_name(in_start, expr_start, expr_end, in_end) 18631 char_u *in_start; 18632 char_u *expr_start; 18633 char_u *expr_end; 18634 char_u *in_end; 18635 { 18636 char_u c1; 18637 char_u *retval = NULL; 18638 char_u *temp_result; 18639 char_u *nextcmd = NULL; 18640 18641 if (expr_end == NULL || in_end == NULL) 18642 return NULL; 18643 *expr_start = NUL; 18644 *expr_end = NUL; 18645 c1 = *in_end; 18646 *in_end = NUL; 18647 18648 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 18649 if (temp_result != NULL && nextcmd == NULL) 18650 { 18651 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 18652 + (in_end - expr_end) + 1)); 18653 if (retval != NULL) 18654 { 18655 STRCPY(retval, in_start); 18656 STRCAT(retval, temp_result); 18657 STRCAT(retval, expr_end + 1); 18658 } 18659 } 18660 vim_free(temp_result); 18661 18662 *in_end = c1; /* put char back for error messages */ 18663 *expr_start = '{'; 18664 *expr_end = '}'; 18665 18666 if (retval != NULL) 18667 { 18668 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 18669 if (expr_start != NULL) 18670 { 18671 /* Further expansion! */ 18672 temp_result = make_expanded_name(retval, expr_start, 18673 expr_end, temp_result); 18674 vim_free(retval); 18675 retval = temp_result; 18676 } 18677 } 18678 18679 return retval; 18680 } 18681 18682 /* 18683 * Return TRUE if character "c" can be used in a variable or function name. 18684 * Does not include '{' or '}' for magic braces. 18685 */ 18686 static int 18687 eval_isnamec(c) 18688 int c; 18689 { 18690 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 18691 } 18692 18693 /* 18694 * Return TRUE if character "c" can be used as the first character in a 18695 * variable or function name (excluding '{' and '}'). 18696 */ 18697 static int 18698 eval_isnamec1(c) 18699 int c; 18700 { 18701 return (ASCII_ISALPHA(c) || c == '_'); 18702 } 18703 18704 /* 18705 * Set number v: variable to "val". 18706 */ 18707 void 18708 set_vim_var_nr(idx, val) 18709 int idx; 18710 long val; 18711 { 18712 vimvars[idx].vv_nr = val; 18713 } 18714 18715 /* 18716 * Get number v: variable value. 18717 */ 18718 long 18719 get_vim_var_nr(idx) 18720 int idx; 18721 { 18722 return vimvars[idx].vv_nr; 18723 } 18724 18725 /* 18726 * Get string v: variable value. Uses a static buffer, can only be used once. 18727 */ 18728 char_u * 18729 get_vim_var_str(idx) 18730 int idx; 18731 { 18732 return get_tv_string(&vimvars[idx].vv_tv); 18733 } 18734 18735 /* 18736 * Get List v: variable value. Caller must take care of reference count when 18737 * needed. 18738 */ 18739 list_T * 18740 get_vim_var_list(idx) 18741 int idx; 18742 { 18743 return vimvars[idx].vv_list; 18744 } 18745 18746 /* 18747 * Set v:char to character "c". 18748 */ 18749 void 18750 set_vim_var_char(c) 18751 int c; 18752 { 18753 #ifdef FEAT_MBYTE 18754 char_u buf[MB_MAXBYTES]; 18755 #else 18756 char_u buf[2]; 18757 #endif 18758 18759 #ifdef FEAT_MBYTE 18760 if (has_mbyte) 18761 buf[(*mb_char2bytes)(c, buf)] = NUL; 18762 else 18763 #endif 18764 { 18765 buf[0] = c; 18766 buf[1] = NUL; 18767 } 18768 set_vim_var_string(VV_CHAR, buf, -1); 18769 } 18770 18771 /* 18772 * Set v:count to "count" and v:count1 to "count1". 18773 * When "set_prevcount" is TRUE first set v:prevcount from v:count. 18774 */ 18775 void 18776 set_vcount(count, count1, set_prevcount) 18777 long count; 18778 long count1; 18779 int set_prevcount; 18780 { 18781 if (set_prevcount) 18782 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 18783 vimvars[VV_COUNT].vv_nr = count; 18784 vimvars[VV_COUNT1].vv_nr = count1; 18785 } 18786 18787 /* 18788 * Set string v: variable to a copy of "val". 18789 */ 18790 void 18791 set_vim_var_string(idx, val, len) 18792 int idx; 18793 char_u *val; 18794 int len; /* length of "val" to use or -1 (whole string) */ 18795 { 18796 /* Need to do this (at least) once, since we can't initialize a union. 18797 * Will always be invoked when "v:progname" is set. */ 18798 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 18799 18800 vim_free(vimvars[idx].vv_str); 18801 if (val == NULL) 18802 vimvars[idx].vv_str = NULL; 18803 else if (len == -1) 18804 vimvars[idx].vv_str = vim_strsave(val); 18805 else 18806 vimvars[idx].vv_str = vim_strnsave(val, len); 18807 } 18808 18809 /* 18810 * Set List v: variable to "val". 18811 */ 18812 void 18813 set_vim_var_list(idx, val) 18814 int idx; 18815 list_T *val; 18816 { 18817 list_unref(vimvars[idx].vv_list); 18818 vimvars[idx].vv_list = val; 18819 if (val != NULL) 18820 ++val->lv_refcount; 18821 } 18822 18823 /* 18824 * Set v:register if needed. 18825 */ 18826 void 18827 set_reg_var(c) 18828 int c; 18829 { 18830 char_u regname; 18831 18832 if (c == 0 || c == ' ') 18833 regname = '"'; 18834 else 18835 regname = c; 18836 /* Avoid free/alloc when the value is already right. */ 18837 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 18838 set_vim_var_string(VV_REG, ®name, 1); 18839 } 18840 18841 /* 18842 * Get or set v:exception. If "oldval" == NULL, return the current value. 18843 * Otherwise, restore the value to "oldval" and return NULL. 18844 * Must always be called in pairs to save and restore v:exception! Does not 18845 * take care of memory allocations. 18846 */ 18847 char_u * 18848 v_exception(oldval) 18849 char_u *oldval; 18850 { 18851 if (oldval == NULL) 18852 return vimvars[VV_EXCEPTION].vv_str; 18853 18854 vimvars[VV_EXCEPTION].vv_str = oldval; 18855 return NULL; 18856 } 18857 18858 /* 18859 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 18860 * Otherwise, restore the value to "oldval" and return NULL. 18861 * Must always be called in pairs to save and restore v:throwpoint! Does not 18862 * take care of memory allocations. 18863 */ 18864 char_u * 18865 v_throwpoint(oldval) 18866 char_u *oldval; 18867 { 18868 if (oldval == NULL) 18869 return vimvars[VV_THROWPOINT].vv_str; 18870 18871 vimvars[VV_THROWPOINT].vv_str = oldval; 18872 return NULL; 18873 } 18874 18875 #if defined(FEAT_AUTOCMD) || defined(PROTO) 18876 /* 18877 * Set v:cmdarg. 18878 * If "eap" != NULL, use "eap" to generate the value and return the old value. 18879 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 18880 * Must always be called in pairs! 18881 */ 18882 char_u * 18883 set_cmdarg(eap, oldarg) 18884 exarg_T *eap; 18885 char_u *oldarg; 18886 { 18887 char_u *oldval; 18888 char_u *newval; 18889 unsigned len; 18890 18891 oldval = vimvars[VV_CMDARG].vv_str; 18892 if (eap == NULL) 18893 { 18894 vim_free(oldval); 18895 vimvars[VV_CMDARG].vv_str = oldarg; 18896 return NULL; 18897 } 18898 18899 if (eap->force_bin == FORCE_BIN) 18900 len = 6; 18901 else if (eap->force_bin == FORCE_NOBIN) 18902 len = 8; 18903 else 18904 len = 0; 18905 18906 if (eap->read_edit) 18907 len += 7; 18908 18909 if (eap->force_ff != 0) 18910 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 18911 # ifdef FEAT_MBYTE 18912 if (eap->force_enc != 0) 18913 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 18914 if (eap->bad_char != 0) 18915 len += 7 + 4; /* " ++bad=" + "keep" or "drop" */ 18916 # endif 18917 18918 newval = alloc(len + 1); 18919 if (newval == NULL) 18920 return NULL; 18921 18922 if (eap->force_bin == FORCE_BIN) 18923 sprintf((char *)newval, " ++bin"); 18924 else if (eap->force_bin == FORCE_NOBIN) 18925 sprintf((char *)newval, " ++nobin"); 18926 else 18927 *newval = NUL; 18928 18929 if (eap->read_edit) 18930 STRCAT(newval, " ++edit"); 18931 18932 if (eap->force_ff != 0) 18933 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 18934 eap->cmd + eap->force_ff); 18935 # ifdef FEAT_MBYTE 18936 if (eap->force_enc != 0) 18937 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 18938 eap->cmd + eap->force_enc); 18939 if (eap->bad_char == BAD_KEEP) 18940 STRCPY(newval + STRLEN(newval), " ++bad=keep"); 18941 else if (eap->bad_char == BAD_DROP) 18942 STRCPY(newval + STRLEN(newval), " ++bad=drop"); 18943 else if (eap->bad_char != 0) 18944 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char); 18945 # endif 18946 vimvars[VV_CMDARG].vv_str = newval; 18947 return oldval; 18948 } 18949 #endif 18950 18951 /* 18952 * Get the value of internal variable "name". 18953 * Return OK or FAIL. 18954 */ 18955 static int 18956 get_var_tv(name, len, rettv, verbose) 18957 char_u *name; 18958 int len; /* length of "name" */ 18959 typval_T *rettv; /* NULL when only checking existence */ 18960 int verbose; /* may give error message */ 18961 { 18962 int ret = OK; 18963 typval_T *tv = NULL; 18964 typval_T atv; 18965 dictitem_T *v; 18966 int cc; 18967 18968 /* truncate the name, so that we can use strcmp() */ 18969 cc = name[len]; 18970 name[len] = NUL; 18971 18972 /* 18973 * Check for "b:changedtick". 18974 */ 18975 if (STRCMP(name, "b:changedtick") == 0) 18976 { 18977 atv.v_type = VAR_NUMBER; 18978 atv.vval.v_number = curbuf->b_changedtick; 18979 tv = &atv; 18980 } 18981 18982 /* 18983 * Check for user-defined variables. 18984 */ 18985 else 18986 { 18987 v = find_var(name, NULL); 18988 if (v != NULL) 18989 tv = &v->di_tv; 18990 } 18991 18992 if (tv == NULL) 18993 { 18994 if (rettv != NULL && verbose) 18995 EMSG2(_(e_undefvar), name); 18996 ret = FAIL; 18997 } 18998 else if (rettv != NULL) 18999 copy_tv(tv, rettv); 19000 19001 name[len] = cc; 19002 19003 return ret; 19004 } 19005 19006 /* 19007 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 19008 * Also handle function call with Funcref variable: func(expr) 19009 * Can all be combined: dict.func(expr)[idx]['func'](expr) 19010 */ 19011 static int 19012 handle_subscript(arg, rettv, evaluate, verbose) 19013 char_u **arg; 19014 typval_T *rettv; 19015 int evaluate; /* do more than finding the end */ 19016 int verbose; /* give error messages */ 19017 { 19018 int ret = OK; 19019 dict_T *selfdict = NULL; 19020 char_u *s; 19021 int len; 19022 typval_T functv; 19023 19024 while (ret == OK 19025 && (**arg == '[' 19026 || (**arg == '.' && rettv->v_type == VAR_DICT) 19027 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 19028 && !vim_iswhite(*(*arg - 1))) 19029 { 19030 if (**arg == '(') 19031 { 19032 /* need to copy the funcref so that we can clear rettv */ 19033 functv = *rettv; 19034 rettv->v_type = VAR_UNKNOWN; 19035 19036 /* Invoke the function. Recursive! */ 19037 s = functv.vval.v_string; 19038 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 19039 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 19040 &len, evaluate, selfdict); 19041 19042 /* Clear the funcref afterwards, so that deleting it while 19043 * evaluating the arguments is possible (see test55). */ 19044 clear_tv(&functv); 19045 19046 /* Stop the expression evaluation when immediately aborting on 19047 * error, or when an interrupt occurred or an exception was thrown 19048 * but not caught. */ 19049 if (aborting()) 19050 { 19051 if (ret == OK) 19052 clear_tv(rettv); 19053 ret = FAIL; 19054 } 19055 dict_unref(selfdict); 19056 selfdict = NULL; 19057 } 19058 else /* **arg == '[' || **arg == '.' */ 19059 { 19060 dict_unref(selfdict); 19061 if (rettv->v_type == VAR_DICT) 19062 { 19063 selfdict = rettv->vval.v_dict; 19064 if (selfdict != NULL) 19065 ++selfdict->dv_refcount; 19066 } 19067 else 19068 selfdict = NULL; 19069 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 19070 { 19071 clear_tv(rettv); 19072 ret = FAIL; 19073 } 19074 } 19075 } 19076 dict_unref(selfdict); 19077 return ret; 19078 } 19079 19080 /* 19081 * Allocate memory for a variable type-value, and make it empty (0 or NULL 19082 * value). 19083 */ 19084 static typval_T * 19085 alloc_tv() 19086 { 19087 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 19088 } 19089 19090 /* 19091 * Allocate memory for a variable type-value, and assign a string to it. 19092 * The string "s" must have been allocated, it is consumed. 19093 * Return NULL for out of memory, the variable otherwise. 19094 */ 19095 static typval_T * 19096 alloc_string_tv(s) 19097 char_u *s; 19098 { 19099 typval_T *rettv; 19100 19101 rettv = alloc_tv(); 19102 if (rettv != NULL) 19103 { 19104 rettv->v_type = VAR_STRING; 19105 rettv->vval.v_string = s; 19106 } 19107 else 19108 vim_free(s); 19109 return rettv; 19110 } 19111 19112 /* 19113 * Free the memory for a variable type-value. 19114 */ 19115 void 19116 free_tv(varp) 19117 typval_T *varp; 19118 { 19119 if (varp != NULL) 19120 { 19121 switch (varp->v_type) 19122 { 19123 case VAR_FUNC: 19124 func_unref(varp->vval.v_string); 19125 /*FALLTHROUGH*/ 19126 case VAR_STRING: 19127 vim_free(varp->vval.v_string); 19128 break; 19129 case VAR_LIST: 19130 list_unref(varp->vval.v_list); 19131 break; 19132 case VAR_DICT: 19133 dict_unref(varp->vval.v_dict); 19134 break; 19135 case VAR_NUMBER: 19136 #ifdef FEAT_FLOAT 19137 case VAR_FLOAT: 19138 #endif 19139 case VAR_UNKNOWN: 19140 break; 19141 default: 19142 EMSG2(_(e_intern2), "free_tv()"); 19143 break; 19144 } 19145 vim_free(varp); 19146 } 19147 } 19148 19149 /* 19150 * Free the memory for a variable value and set the value to NULL or 0. 19151 */ 19152 void 19153 clear_tv(varp) 19154 typval_T *varp; 19155 { 19156 if (varp != NULL) 19157 { 19158 switch (varp->v_type) 19159 { 19160 case VAR_FUNC: 19161 func_unref(varp->vval.v_string); 19162 /*FALLTHROUGH*/ 19163 case VAR_STRING: 19164 vim_free(varp->vval.v_string); 19165 varp->vval.v_string = NULL; 19166 break; 19167 case VAR_LIST: 19168 list_unref(varp->vval.v_list); 19169 varp->vval.v_list = NULL; 19170 break; 19171 case VAR_DICT: 19172 dict_unref(varp->vval.v_dict); 19173 varp->vval.v_dict = NULL; 19174 break; 19175 case VAR_NUMBER: 19176 varp->vval.v_number = 0; 19177 break; 19178 #ifdef FEAT_FLOAT 19179 case VAR_FLOAT: 19180 varp->vval.v_float = 0.0; 19181 break; 19182 #endif 19183 case VAR_UNKNOWN: 19184 break; 19185 default: 19186 EMSG2(_(e_intern2), "clear_tv()"); 19187 } 19188 varp->v_lock = 0; 19189 } 19190 } 19191 19192 /* 19193 * Set the value of a variable to NULL without freeing items. 19194 */ 19195 static void 19196 init_tv(varp) 19197 typval_T *varp; 19198 { 19199 if (varp != NULL) 19200 vim_memset(varp, 0, sizeof(typval_T)); 19201 } 19202 19203 /* 19204 * Get the number value of a variable. 19205 * If it is a String variable, uses vim_str2nr(). 19206 * For incompatible types, return 0. 19207 * get_tv_number_chk() is similar to get_tv_number(), but informs the 19208 * caller of incompatible types: it sets *denote to TRUE if "denote" 19209 * is not NULL or returns -1 otherwise. 19210 */ 19211 static long 19212 get_tv_number(varp) 19213 typval_T *varp; 19214 { 19215 int error = FALSE; 19216 19217 return get_tv_number_chk(varp, &error); /* return 0L on error */ 19218 } 19219 19220 long 19221 get_tv_number_chk(varp, denote) 19222 typval_T *varp; 19223 int *denote; 19224 { 19225 long n = 0L; 19226 19227 switch (varp->v_type) 19228 { 19229 case VAR_NUMBER: 19230 return (long)(varp->vval.v_number); 19231 #ifdef FEAT_FLOAT 19232 case VAR_FLOAT: 19233 EMSG(_("E805: Using a Float as a Number")); 19234 break; 19235 #endif 19236 case VAR_FUNC: 19237 EMSG(_("E703: Using a Funcref as a Number")); 19238 break; 19239 case VAR_STRING: 19240 if (varp->vval.v_string != NULL) 19241 vim_str2nr(varp->vval.v_string, NULL, NULL, 19242 TRUE, TRUE, &n, NULL); 19243 return n; 19244 case VAR_LIST: 19245 EMSG(_("E745: Using a List as a Number")); 19246 break; 19247 case VAR_DICT: 19248 EMSG(_("E728: Using a Dictionary as a Number")); 19249 break; 19250 default: 19251 EMSG2(_(e_intern2), "get_tv_number()"); 19252 break; 19253 } 19254 if (denote == NULL) /* useful for values that must be unsigned */ 19255 n = -1; 19256 else 19257 *denote = TRUE; 19258 return n; 19259 } 19260 19261 /* 19262 * Get the lnum from the first argument. 19263 * Also accepts ".", "$", etc., but that only works for the current buffer. 19264 * Returns -1 on error. 19265 */ 19266 static linenr_T 19267 get_tv_lnum(argvars) 19268 typval_T *argvars; 19269 { 19270 typval_T rettv; 19271 linenr_T lnum; 19272 19273 lnum = get_tv_number_chk(&argvars[0], NULL); 19274 if (lnum == 0) /* no valid number, try using line() */ 19275 { 19276 rettv.v_type = VAR_NUMBER; 19277 f_line(argvars, &rettv); 19278 lnum = rettv.vval.v_number; 19279 clear_tv(&rettv); 19280 } 19281 return lnum; 19282 } 19283 19284 /* 19285 * Get the lnum from the first argument. 19286 * Also accepts "$", then "buf" is used. 19287 * Returns 0 on error. 19288 */ 19289 static linenr_T 19290 get_tv_lnum_buf(argvars, buf) 19291 typval_T *argvars; 19292 buf_T *buf; 19293 { 19294 if (argvars[0].v_type == VAR_STRING 19295 && argvars[0].vval.v_string != NULL 19296 && argvars[0].vval.v_string[0] == '$' 19297 && buf != NULL) 19298 return buf->b_ml.ml_line_count; 19299 return get_tv_number_chk(&argvars[0], NULL); 19300 } 19301 19302 /* 19303 * Get the string value of a variable. 19304 * If it is a Number variable, the number is converted into a string. 19305 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 19306 * get_tv_string_buf() uses a given buffer. 19307 * If the String variable has never been set, return an empty string. 19308 * Never returns NULL; 19309 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 19310 * NULL on error. 19311 */ 19312 static char_u * 19313 get_tv_string(varp) 19314 typval_T *varp; 19315 { 19316 static char_u mybuf[NUMBUFLEN]; 19317 19318 return get_tv_string_buf(varp, mybuf); 19319 } 19320 19321 static char_u * 19322 get_tv_string_buf(varp, buf) 19323 typval_T *varp; 19324 char_u *buf; 19325 { 19326 char_u *res = get_tv_string_buf_chk(varp, buf); 19327 19328 return res != NULL ? res : (char_u *)""; 19329 } 19330 19331 char_u * 19332 get_tv_string_chk(varp) 19333 typval_T *varp; 19334 { 19335 static char_u mybuf[NUMBUFLEN]; 19336 19337 return get_tv_string_buf_chk(varp, mybuf); 19338 } 19339 19340 static char_u * 19341 get_tv_string_buf_chk(varp, buf) 19342 typval_T *varp; 19343 char_u *buf; 19344 { 19345 switch (varp->v_type) 19346 { 19347 case VAR_NUMBER: 19348 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 19349 return buf; 19350 case VAR_FUNC: 19351 EMSG(_("E729: using Funcref as a String")); 19352 break; 19353 case VAR_LIST: 19354 EMSG(_("E730: using List as a String")); 19355 break; 19356 case VAR_DICT: 19357 EMSG(_("E731: using Dictionary as a String")); 19358 break; 19359 #ifdef FEAT_FLOAT 19360 case VAR_FLOAT: 19361 EMSG(_("E806: using Float as a String")); 19362 break; 19363 #endif 19364 case VAR_STRING: 19365 if (varp->vval.v_string != NULL) 19366 return varp->vval.v_string; 19367 return (char_u *)""; 19368 default: 19369 EMSG2(_(e_intern2), "get_tv_string_buf()"); 19370 break; 19371 } 19372 return NULL; 19373 } 19374 19375 /* 19376 * Find variable "name" in the list of variables. 19377 * Return a pointer to it if found, NULL if not found. 19378 * Careful: "a:0" variables don't have a name. 19379 * When "htp" is not NULL we are writing to the variable, set "htp" to the 19380 * hashtab_T used. 19381 */ 19382 static dictitem_T * 19383 find_var(name, htp) 19384 char_u *name; 19385 hashtab_T **htp; 19386 { 19387 char_u *varname; 19388 hashtab_T *ht; 19389 19390 ht = find_var_ht(name, &varname); 19391 if (htp != NULL) 19392 *htp = ht; 19393 if (ht == NULL) 19394 return NULL; 19395 return find_var_in_ht(ht, varname, htp != NULL); 19396 } 19397 19398 /* 19399 * Find variable "varname" in hashtab "ht". 19400 * Returns NULL if not found. 19401 */ 19402 static dictitem_T * 19403 find_var_in_ht(ht, varname, writing) 19404 hashtab_T *ht; 19405 char_u *varname; 19406 int writing; 19407 { 19408 hashitem_T *hi; 19409 19410 if (*varname == NUL) 19411 { 19412 /* Must be something like "s:", otherwise "ht" would be NULL. */ 19413 switch (varname[-2]) 19414 { 19415 case 's': return &SCRIPT_SV(current_SID)->sv_var; 19416 case 'g': return &globvars_var; 19417 case 'v': return &vimvars_var; 19418 case 'b': return &curbuf->b_bufvar; 19419 case 'w': return &curwin->w_winvar; 19420 #ifdef FEAT_WINDOWS 19421 case 't': return &curtab->tp_winvar; 19422 #endif 19423 case 'l': return current_funccal == NULL 19424 ? NULL : ¤t_funccal->l_vars_var; 19425 case 'a': return current_funccal == NULL 19426 ? NULL : ¤t_funccal->l_avars_var; 19427 } 19428 return NULL; 19429 } 19430 19431 hi = hash_find(ht, varname); 19432 if (HASHITEM_EMPTY(hi)) 19433 { 19434 /* For global variables we may try auto-loading the script. If it 19435 * worked find the variable again. Don't auto-load a script if it was 19436 * loaded already, otherwise it would be loaded every time when 19437 * checking if a function name is a Funcref variable. */ 19438 if (ht == &globvarht && !writing 19439 && script_autoload(varname, FALSE) && !aborting()) 19440 hi = hash_find(ht, varname); 19441 if (HASHITEM_EMPTY(hi)) 19442 return NULL; 19443 } 19444 return HI2DI(hi); 19445 } 19446 19447 /* 19448 * Find the hashtab used for a variable name. 19449 * Set "varname" to the start of name without ':'. 19450 */ 19451 static hashtab_T * 19452 find_var_ht(name, varname) 19453 char_u *name; 19454 char_u **varname; 19455 { 19456 hashitem_T *hi; 19457 19458 if (name[1] != ':') 19459 { 19460 /* The name must not start with a colon or #. */ 19461 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 19462 return NULL; 19463 *varname = name; 19464 19465 /* "version" is "v:version" in all scopes */ 19466 hi = hash_find(&compat_hashtab, name); 19467 if (!HASHITEM_EMPTY(hi)) 19468 return &compat_hashtab; 19469 19470 if (current_funccal == NULL) 19471 return &globvarht; /* global variable */ 19472 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 19473 } 19474 *varname = name + 2; 19475 if (*name == 'g') /* global variable */ 19476 return &globvarht; 19477 /* There must be no ':' or '#' in the rest of the name, unless g: is used 19478 */ 19479 if (vim_strchr(name + 2, ':') != NULL 19480 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 19481 return NULL; 19482 if (*name == 'b') /* buffer variable */ 19483 return &curbuf->b_vars.dv_hashtab; 19484 if (*name == 'w') /* window variable */ 19485 return &curwin->w_vars.dv_hashtab; 19486 #ifdef FEAT_WINDOWS 19487 if (*name == 't') /* tab page variable */ 19488 return &curtab->tp_vars.dv_hashtab; 19489 #endif 19490 if (*name == 'v') /* v: variable */ 19491 return &vimvarht; 19492 if (*name == 'a' && current_funccal != NULL) /* function argument */ 19493 return ¤t_funccal->l_avars.dv_hashtab; 19494 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 19495 return ¤t_funccal->l_vars.dv_hashtab; 19496 if (*name == 's' /* script variable */ 19497 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 19498 return &SCRIPT_VARS(current_SID); 19499 return NULL; 19500 } 19501 19502 /* 19503 * Get the string value of a (global/local) variable. 19504 * Note: see get_tv_string() for how long the pointer remains valid. 19505 * Returns NULL when it doesn't exist. 19506 */ 19507 char_u * 19508 get_var_value(name) 19509 char_u *name; 19510 { 19511 dictitem_T *v; 19512 19513 v = find_var(name, NULL); 19514 if (v == NULL) 19515 return NULL; 19516 return get_tv_string(&v->di_tv); 19517 } 19518 19519 /* 19520 * Allocate a new hashtab for a sourced script. It will be used while 19521 * sourcing this script and when executing functions defined in the script. 19522 */ 19523 void 19524 new_script_vars(id) 19525 scid_T id; 19526 { 19527 int i; 19528 hashtab_T *ht; 19529 scriptvar_T *sv; 19530 19531 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 19532 { 19533 /* Re-allocating ga_data means that an ht_array pointing to 19534 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 19535 * at its init value. Also reset "v_dict", it's always the same. */ 19536 for (i = 1; i <= ga_scripts.ga_len; ++i) 19537 { 19538 ht = &SCRIPT_VARS(i); 19539 if (ht->ht_mask == HT_INIT_SIZE - 1) 19540 ht->ht_array = ht->ht_smallarray; 19541 sv = SCRIPT_SV(i); 19542 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 19543 } 19544 19545 while (ga_scripts.ga_len < id) 19546 { 19547 sv = SCRIPT_SV(ga_scripts.ga_len + 1) = 19548 (scriptvar_T *)alloc_clear(sizeof(scriptvar_T)); 19549 init_var_dict(&sv->sv_dict, &sv->sv_var); 19550 ++ga_scripts.ga_len; 19551 } 19552 } 19553 } 19554 19555 /* 19556 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 19557 * point to it. 19558 */ 19559 void 19560 init_var_dict(dict, dict_var) 19561 dict_T *dict; 19562 dictitem_T *dict_var; 19563 { 19564 hash_init(&dict->dv_hashtab); 19565 dict->dv_refcount = DO_NOT_FREE_CNT; 19566 dict->dv_copyID = 0; 19567 dict_var->di_tv.vval.v_dict = dict; 19568 dict_var->di_tv.v_type = VAR_DICT; 19569 dict_var->di_tv.v_lock = VAR_FIXED; 19570 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19571 dict_var->di_key[0] = NUL; 19572 } 19573 19574 /* 19575 * Clean up a list of internal variables. 19576 * Frees all allocated variables and the value they contain. 19577 * Clears hashtab "ht", does not free it. 19578 */ 19579 void 19580 vars_clear(ht) 19581 hashtab_T *ht; 19582 { 19583 vars_clear_ext(ht, TRUE); 19584 } 19585 19586 /* 19587 * Like vars_clear(), but only free the value if "free_val" is TRUE. 19588 */ 19589 static void 19590 vars_clear_ext(ht, free_val) 19591 hashtab_T *ht; 19592 int free_val; 19593 { 19594 int todo; 19595 hashitem_T *hi; 19596 dictitem_T *v; 19597 19598 hash_lock(ht); 19599 todo = (int)ht->ht_used; 19600 for (hi = ht->ht_array; todo > 0; ++hi) 19601 { 19602 if (!HASHITEM_EMPTY(hi)) 19603 { 19604 --todo; 19605 19606 /* Free the variable. Don't remove it from the hashtab, 19607 * ht_array might change then. hash_clear() takes care of it 19608 * later. */ 19609 v = HI2DI(hi); 19610 if (free_val) 19611 clear_tv(&v->di_tv); 19612 if ((v->di_flags & DI_FLAGS_FIX) == 0) 19613 vim_free(v); 19614 } 19615 } 19616 hash_clear(ht); 19617 ht->ht_used = 0; 19618 } 19619 19620 /* 19621 * Delete a variable from hashtab "ht" at item "hi". 19622 * Clear the variable value and free the dictitem. 19623 */ 19624 static void 19625 delete_var(ht, hi) 19626 hashtab_T *ht; 19627 hashitem_T *hi; 19628 { 19629 dictitem_T *di = HI2DI(hi); 19630 19631 hash_remove(ht, hi); 19632 clear_tv(&di->di_tv); 19633 vim_free(di); 19634 } 19635 19636 /* 19637 * List the value of one internal variable. 19638 */ 19639 static void 19640 list_one_var(v, prefix, first) 19641 dictitem_T *v; 19642 char_u *prefix; 19643 int *first; 19644 { 19645 char_u *tofree; 19646 char_u *s; 19647 char_u numbuf[NUMBUFLEN]; 19648 19649 current_copyID += COPYID_INC; 19650 s = echo_string(&v->di_tv, &tofree, numbuf, current_copyID); 19651 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 19652 s == NULL ? (char_u *)"" : s, first); 19653 vim_free(tofree); 19654 } 19655 19656 static void 19657 list_one_var_a(prefix, name, type, string, first) 19658 char_u *prefix; 19659 char_u *name; 19660 int type; 19661 char_u *string; 19662 int *first; /* when TRUE clear rest of screen and set to FALSE */ 19663 { 19664 /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ 19665 msg_start(); 19666 msg_puts(prefix); 19667 if (name != NULL) /* "a:" vars don't have a name stored */ 19668 msg_puts(name); 19669 msg_putchar(' '); 19670 msg_advance(22); 19671 if (type == VAR_NUMBER) 19672 msg_putchar('#'); 19673 else if (type == VAR_FUNC) 19674 msg_putchar('*'); 19675 else if (type == VAR_LIST) 19676 { 19677 msg_putchar('['); 19678 if (*string == '[') 19679 ++string; 19680 } 19681 else if (type == VAR_DICT) 19682 { 19683 msg_putchar('{'); 19684 if (*string == '{') 19685 ++string; 19686 } 19687 else 19688 msg_putchar(' '); 19689 19690 msg_outtrans(string); 19691 19692 if (type == VAR_FUNC) 19693 msg_puts((char_u *)"()"); 19694 if (*first) 19695 { 19696 msg_clr_eos(); 19697 *first = FALSE; 19698 } 19699 } 19700 19701 /* 19702 * Set variable "name" to value in "tv". 19703 * If the variable already exists, the value is updated. 19704 * Otherwise the variable is created. 19705 */ 19706 static void 19707 set_var(name, tv, copy) 19708 char_u *name; 19709 typval_T *tv; 19710 int copy; /* make copy of value in "tv" */ 19711 { 19712 dictitem_T *v; 19713 char_u *varname; 19714 hashtab_T *ht; 19715 char_u *p; 19716 19717 ht = find_var_ht(name, &varname); 19718 if (ht == NULL || *varname == NUL) 19719 { 19720 EMSG2(_(e_illvar), name); 19721 return; 19722 } 19723 v = find_var_in_ht(ht, varname, TRUE); 19724 19725 if (tv->v_type == VAR_FUNC) 19726 { 19727 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 19728 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 19729 ? name[2] : name[0])) 19730 { 19731 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 19732 return; 19733 } 19734 /* Don't allow hiding a function. When "v" is not NULL we migth be 19735 * assigning another function to the same var, the type is checked 19736 * below. */ 19737 if (v == NULL && function_exists(name)) 19738 { 19739 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 19740 name); 19741 return; 19742 } 19743 } 19744 19745 if (v != NULL) 19746 { 19747 /* existing variable, need to clear the value */ 19748 if (var_check_ro(v->di_flags, name) 19749 || tv_check_lock(v->di_tv.v_lock, name)) 19750 return; 19751 if (v->di_tv.v_type != tv->v_type 19752 && !((v->di_tv.v_type == VAR_STRING 19753 || v->di_tv.v_type == VAR_NUMBER) 19754 && (tv->v_type == VAR_STRING 19755 || tv->v_type == VAR_NUMBER)) 19756 #ifdef FEAT_FLOAT 19757 && !((v->di_tv.v_type == VAR_NUMBER 19758 || v->di_tv.v_type == VAR_FLOAT) 19759 && (tv->v_type == VAR_NUMBER 19760 || tv->v_type == VAR_FLOAT)) 19761 #endif 19762 ) 19763 { 19764 EMSG2(_("E706: Variable type mismatch for: %s"), name); 19765 return; 19766 } 19767 19768 /* 19769 * Handle setting internal v: variables separately: we don't change 19770 * the type. 19771 */ 19772 if (ht == &vimvarht) 19773 { 19774 if (v->di_tv.v_type == VAR_STRING) 19775 { 19776 vim_free(v->di_tv.vval.v_string); 19777 if (copy || tv->v_type != VAR_STRING) 19778 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 19779 else 19780 { 19781 /* Take over the string to avoid an extra alloc/free. */ 19782 v->di_tv.vval.v_string = tv->vval.v_string; 19783 tv->vval.v_string = NULL; 19784 } 19785 } 19786 else if (v->di_tv.v_type != VAR_NUMBER) 19787 EMSG2(_(e_intern2), "set_var()"); 19788 else 19789 { 19790 v->di_tv.vval.v_number = get_tv_number(tv); 19791 if (STRCMP(varname, "searchforward") == 0) 19792 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); 19793 } 19794 return; 19795 } 19796 19797 clear_tv(&v->di_tv); 19798 } 19799 else /* add a new variable */ 19800 { 19801 /* Can't add "v:" variable. */ 19802 if (ht == &vimvarht) 19803 { 19804 EMSG2(_(e_illvar), name); 19805 return; 19806 } 19807 19808 /* Make sure the variable name is valid. */ 19809 for (p = varname; *p != NUL; ++p) 19810 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 19811 && *p != AUTOLOAD_CHAR) 19812 { 19813 EMSG2(_(e_illvar), varname); 19814 return; 19815 } 19816 19817 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19818 + STRLEN(varname))); 19819 if (v == NULL) 19820 return; 19821 STRCPY(v->di_key, varname); 19822 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 19823 { 19824 vim_free(v); 19825 return; 19826 } 19827 v->di_flags = 0; 19828 } 19829 19830 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 19831 copy_tv(tv, &v->di_tv); 19832 else 19833 { 19834 v->di_tv = *tv; 19835 v->di_tv.v_lock = 0; 19836 init_tv(tv); 19837 } 19838 } 19839 19840 /* 19841 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 19842 * Also give an error message. 19843 */ 19844 static int 19845 var_check_ro(flags, name) 19846 int flags; 19847 char_u *name; 19848 { 19849 if (flags & DI_FLAGS_RO) 19850 { 19851 EMSG2(_(e_readonlyvar), name); 19852 return TRUE; 19853 } 19854 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 19855 { 19856 EMSG2(_(e_readonlysbx), name); 19857 return TRUE; 19858 } 19859 return FALSE; 19860 } 19861 19862 /* 19863 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 19864 * Also give an error message. 19865 */ 19866 static int 19867 var_check_fixed(flags, name) 19868 int flags; 19869 char_u *name; 19870 { 19871 if (flags & DI_FLAGS_FIX) 19872 { 19873 EMSG2(_("E795: Cannot delete variable %s"), name); 19874 return TRUE; 19875 } 19876 return FALSE; 19877 } 19878 19879 /* 19880 * Return TRUE if typeval "tv" is set to be locked (immutable). 19881 * Also give an error message, using "name". 19882 */ 19883 static int 19884 tv_check_lock(lock, name) 19885 int lock; 19886 char_u *name; 19887 { 19888 if (lock & VAR_LOCKED) 19889 { 19890 EMSG2(_("E741: Value is locked: %s"), 19891 name == NULL ? (char_u *)_("Unknown") : name); 19892 return TRUE; 19893 } 19894 if (lock & VAR_FIXED) 19895 { 19896 EMSG2(_("E742: Cannot change value of %s"), 19897 name == NULL ? (char_u *)_("Unknown") : name); 19898 return TRUE; 19899 } 19900 return FALSE; 19901 } 19902 19903 /* 19904 * Copy the values from typval_T "from" to typval_T "to". 19905 * When needed allocates string or increases reference count. 19906 * Does not make a copy of a list or dict but copies the reference! 19907 * It is OK for "from" and "to" to point to the same item. This is used to 19908 * make a copy later. 19909 */ 19910 void 19911 copy_tv(from, to) 19912 typval_T *from; 19913 typval_T *to; 19914 { 19915 to->v_type = from->v_type; 19916 to->v_lock = 0; 19917 switch (from->v_type) 19918 { 19919 case VAR_NUMBER: 19920 to->vval.v_number = from->vval.v_number; 19921 break; 19922 #ifdef FEAT_FLOAT 19923 case VAR_FLOAT: 19924 to->vval.v_float = from->vval.v_float; 19925 break; 19926 #endif 19927 case VAR_STRING: 19928 case VAR_FUNC: 19929 if (from->vval.v_string == NULL) 19930 to->vval.v_string = NULL; 19931 else 19932 { 19933 to->vval.v_string = vim_strsave(from->vval.v_string); 19934 if (from->v_type == VAR_FUNC) 19935 func_ref(to->vval.v_string); 19936 } 19937 break; 19938 case VAR_LIST: 19939 if (from->vval.v_list == NULL) 19940 to->vval.v_list = NULL; 19941 else 19942 { 19943 to->vval.v_list = from->vval.v_list; 19944 ++to->vval.v_list->lv_refcount; 19945 } 19946 break; 19947 case VAR_DICT: 19948 if (from->vval.v_dict == NULL) 19949 to->vval.v_dict = NULL; 19950 else 19951 { 19952 to->vval.v_dict = from->vval.v_dict; 19953 ++to->vval.v_dict->dv_refcount; 19954 } 19955 break; 19956 default: 19957 EMSG2(_(e_intern2), "copy_tv()"); 19958 break; 19959 } 19960 } 19961 19962 /* 19963 * Make a copy of an item. 19964 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 19965 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 19966 * reference to an already copied list/dict can be used. 19967 * Returns FAIL or OK. 19968 */ 19969 static int 19970 item_copy(from, to, deep, copyID) 19971 typval_T *from; 19972 typval_T *to; 19973 int deep; 19974 int copyID; 19975 { 19976 static int recurse = 0; 19977 int ret = OK; 19978 19979 if (recurse >= DICT_MAXNEST) 19980 { 19981 EMSG(_("E698: variable nested too deep for making a copy")); 19982 return FAIL; 19983 } 19984 ++recurse; 19985 19986 switch (from->v_type) 19987 { 19988 case VAR_NUMBER: 19989 #ifdef FEAT_FLOAT 19990 case VAR_FLOAT: 19991 #endif 19992 case VAR_STRING: 19993 case VAR_FUNC: 19994 copy_tv(from, to); 19995 break; 19996 case VAR_LIST: 19997 to->v_type = VAR_LIST; 19998 to->v_lock = 0; 19999 if (from->vval.v_list == NULL) 20000 to->vval.v_list = NULL; 20001 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 20002 { 20003 /* use the copy made earlier */ 20004 to->vval.v_list = from->vval.v_list->lv_copylist; 20005 ++to->vval.v_list->lv_refcount; 20006 } 20007 else 20008 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 20009 if (to->vval.v_list == NULL) 20010 ret = FAIL; 20011 break; 20012 case VAR_DICT: 20013 to->v_type = VAR_DICT; 20014 to->v_lock = 0; 20015 if (from->vval.v_dict == NULL) 20016 to->vval.v_dict = NULL; 20017 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 20018 { 20019 /* use the copy made earlier */ 20020 to->vval.v_dict = from->vval.v_dict->dv_copydict; 20021 ++to->vval.v_dict->dv_refcount; 20022 } 20023 else 20024 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 20025 if (to->vval.v_dict == NULL) 20026 ret = FAIL; 20027 break; 20028 default: 20029 EMSG2(_(e_intern2), "item_copy()"); 20030 ret = FAIL; 20031 } 20032 --recurse; 20033 return ret; 20034 } 20035 20036 /* 20037 * ":echo expr1 ..." print each argument separated with a space, add a 20038 * newline at the end. 20039 * ":echon expr1 ..." print each argument plain. 20040 */ 20041 void 20042 ex_echo(eap) 20043 exarg_T *eap; 20044 { 20045 char_u *arg = eap->arg; 20046 typval_T rettv; 20047 char_u *tofree; 20048 char_u *p; 20049 int needclr = TRUE; 20050 int atstart = TRUE; 20051 char_u numbuf[NUMBUFLEN]; 20052 20053 if (eap->skip) 20054 ++emsg_skip; 20055 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 20056 { 20057 /* If eval1() causes an error message the text from the command may 20058 * still need to be cleared. E.g., "echo 22,44". */ 20059 need_clr_eos = needclr; 20060 20061 p = arg; 20062 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 20063 { 20064 /* 20065 * Report the invalid expression unless the expression evaluation 20066 * has been cancelled due to an aborting error, an interrupt, or an 20067 * exception. 20068 */ 20069 if (!aborting()) 20070 EMSG2(_(e_invexpr2), p); 20071 need_clr_eos = FALSE; 20072 break; 20073 } 20074 need_clr_eos = FALSE; 20075 20076 if (!eap->skip) 20077 { 20078 if (atstart) 20079 { 20080 atstart = FALSE; 20081 /* Call msg_start() after eval1(), evaluating the expression 20082 * may cause a message to appear. */ 20083 if (eap->cmdidx == CMD_echo) 20084 msg_start(); 20085 } 20086 else if (eap->cmdidx == CMD_echo) 20087 msg_puts_attr((char_u *)" ", echo_attr); 20088 current_copyID += COPYID_INC; 20089 p = echo_string(&rettv, &tofree, numbuf, current_copyID); 20090 if (p != NULL) 20091 for ( ; *p != NUL && !got_int; ++p) 20092 { 20093 if (*p == '\n' || *p == '\r' || *p == TAB) 20094 { 20095 if (*p != TAB && needclr) 20096 { 20097 /* remove any text still there from the command */ 20098 msg_clr_eos(); 20099 needclr = FALSE; 20100 } 20101 msg_putchar_attr(*p, echo_attr); 20102 } 20103 else 20104 { 20105 #ifdef FEAT_MBYTE 20106 if (has_mbyte) 20107 { 20108 int i = (*mb_ptr2len)(p); 20109 20110 (void)msg_outtrans_len_attr(p, i, echo_attr); 20111 p += i - 1; 20112 } 20113 else 20114 #endif 20115 (void)msg_outtrans_len_attr(p, 1, echo_attr); 20116 } 20117 } 20118 vim_free(tofree); 20119 } 20120 clear_tv(&rettv); 20121 arg = skipwhite(arg); 20122 } 20123 eap->nextcmd = check_nextcmd(arg); 20124 20125 if (eap->skip) 20126 --emsg_skip; 20127 else 20128 { 20129 /* remove text that may still be there from the command */ 20130 if (needclr) 20131 msg_clr_eos(); 20132 if (eap->cmdidx == CMD_echo) 20133 msg_end(); 20134 } 20135 } 20136 20137 /* 20138 * ":echohl {name}". 20139 */ 20140 void 20141 ex_echohl(eap) 20142 exarg_T *eap; 20143 { 20144 int id; 20145 20146 id = syn_name2id(eap->arg); 20147 if (id == 0) 20148 echo_attr = 0; 20149 else 20150 echo_attr = syn_id2attr(id); 20151 } 20152 20153 /* 20154 * ":execute expr1 ..." execute the result of an expression. 20155 * ":echomsg expr1 ..." Print a message 20156 * ":echoerr expr1 ..." Print an error 20157 * Each gets spaces around each argument and a newline at the end for 20158 * echo commands 20159 */ 20160 void 20161 ex_execute(eap) 20162 exarg_T *eap; 20163 { 20164 char_u *arg = eap->arg; 20165 typval_T rettv; 20166 int ret = OK; 20167 char_u *p; 20168 garray_T ga; 20169 int len; 20170 int save_did_emsg; 20171 20172 ga_init2(&ga, 1, 80); 20173 20174 if (eap->skip) 20175 ++emsg_skip; 20176 while (*arg != NUL && *arg != '|' && *arg != '\n') 20177 { 20178 p = arg; 20179 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 20180 { 20181 /* 20182 * Report the invalid expression unless the expression evaluation 20183 * has been cancelled due to an aborting error, an interrupt, or an 20184 * exception. 20185 */ 20186 if (!aborting()) 20187 EMSG2(_(e_invexpr2), p); 20188 ret = FAIL; 20189 break; 20190 } 20191 20192 if (!eap->skip) 20193 { 20194 p = get_tv_string(&rettv); 20195 len = (int)STRLEN(p); 20196 if (ga_grow(&ga, len + 2) == FAIL) 20197 { 20198 clear_tv(&rettv); 20199 ret = FAIL; 20200 break; 20201 } 20202 if (ga.ga_len) 20203 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 20204 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 20205 ga.ga_len += len; 20206 } 20207 20208 clear_tv(&rettv); 20209 arg = skipwhite(arg); 20210 } 20211 20212 if (ret != FAIL && ga.ga_data != NULL) 20213 { 20214 if (eap->cmdidx == CMD_echomsg) 20215 { 20216 MSG_ATTR(ga.ga_data, echo_attr); 20217 out_flush(); 20218 } 20219 else if (eap->cmdidx == CMD_echoerr) 20220 { 20221 /* We don't want to abort following commands, restore did_emsg. */ 20222 save_did_emsg = did_emsg; 20223 EMSG((char_u *)ga.ga_data); 20224 if (!force_abort) 20225 did_emsg = save_did_emsg; 20226 } 20227 else if (eap->cmdidx == CMD_execute) 20228 do_cmdline((char_u *)ga.ga_data, 20229 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 20230 } 20231 20232 ga_clear(&ga); 20233 20234 if (eap->skip) 20235 --emsg_skip; 20236 20237 eap->nextcmd = check_nextcmd(arg); 20238 } 20239 20240 /* 20241 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 20242 * "arg" points to the "&" or '+' when called, to "option" when returning. 20243 * Returns NULL when no option name found. Otherwise pointer to the char 20244 * after the option name. 20245 */ 20246 static char_u * 20247 find_option_end(arg, opt_flags) 20248 char_u **arg; 20249 int *opt_flags; 20250 { 20251 char_u *p = *arg; 20252 20253 ++p; 20254 if (*p == 'g' && p[1] == ':') 20255 { 20256 *opt_flags = OPT_GLOBAL; 20257 p += 2; 20258 } 20259 else if (*p == 'l' && p[1] == ':') 20260 { 20261 *opt_flags = OPT_LOCAL; 20262 p += 2; 20263 } 20264 else 20265 *opt_flags = 0; 20266 20267 if (!ASCII_ISALPHA(*p)) 20268 return NULL; 20269 *arg = p; 20270 20271 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 20272 p += 4; /* termcap option */ 20273 else 20274 while (ASCII_ISALPHA(*p)) 20275 ++p; 20276 return p; 20277 } 20278 20279 /* 20280 * ":function" 20281 */ 20282 void 20283 ex_function(eap) 20284 exarg_T *eap; 20285 { 20286 char_u *theline; 20287 int j; 20288 int c; 20289 int saved_did_emsg; 20290 char_u *name = NULL; 20291 char_u *p; 20292 char_u *arg; 20293 char_u *line_arg = NULL; 20294 garray_T newargs; 20295 garray_T newlines; 20296 int varargs = FALSE; 20297 int mustend = FALSE; 20298 int flags = 0; 20299 ufunc_T *fp; 20300 int indent; 20301 int nesting; 20302 char_u *skip_until = NULL; 20303 dictitem_T *v; 20304 funcdict_T fudi; 20305 static int func_nr = 0; /* number for nameless function */ 20306 int paren; 20307 hashtab_T *ht; 20308 int todo; 20309 hashitem_T *hi; 20310 int sourcing_lnum_off; 20311 20312 /* 20313 * ":function" without argument: list functions. 20314 */ 20315 if (ends_excmd(*eap->arg)) 20316 { 20317 if (!eap->skip) 20318 { 20319 todo = (int)func_hashtab.ht_used; 20320 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 20321 { 20322 if (!HASHITEM_EMPTY(hi)) 20323 { 20324 --todo; 20325 fp = HI2UF(hi); 20326 if (!isdigit(*fp->uf_name)) 20327 list_func_head(fp, FALSE); 20328 } 20329 } 20330 } 20331 eap->nextcmd = check_nextcmd(eap->arg); 20332 return; 20333 } 20334 20335 /* 20336 * ":function /pat": list functions matching pattern. 20337 */ 20338 if (*eap->arg == '/') 20339 { 20340 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 20341 if (!eap->skip) 20342 { 20343 regmatch_T regmatch; 20344 20345 c = *p; 20346 *p = NUL; 20347 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 20348 *p = c; 20349 if (regmatch.regprog != NULL) 20350 { 20351 regmatch.rm_ic = p_ic; 20352 20353 todo = (int)func_hashtab.ht_used; 20354 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 20355 { 20356 if (!HASHITEM_EMPTY(hi)) 20357 { 20358 --todo; 20359 fp = HI2UF(hi); 20360 if (!isdigit(*fp->uf_name) 20361 && vim_regexec(®match, fp->uf_name, 0)) 20362 list_func_head(fp, FALSE); 20363 } 20364 } 20365 vim_free(regmatch.regprog); 20366 } 20367 } 20368 if (*p == '/') 20369 ++p; 20370 eap->nextcmd = check_nextcmd(p); 20371 return; 20372 } 20373 20374 /* 20375 * Get the function name. There are these situations: 20376 * func normal function name 20377 * "name" == func, "fudi.fd_dict" == NULL 20378 * dict.func new dictionary entry 20379 * "name" == NULL, "fudi.fd_dict" set, 20380 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 20381 * dict.func existing dict entry with a Funcref 20382 * "name" == func, "fudi.fd_dict" set, 20383 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 20384 * dict.func existing dict entry that's not a Funcref 20385 * "name" == NULL, "fudi.fd_dict" set, 20386 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 20387 */ 20388 p = eap->arg; 20389 name = trans_function_name(&p, eap->skip, 0, &fudi); 20390 paren = (vim_strchr(p, '(') != NULL); 20391 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 20392 { 20393 /* 20394 * Return on an invalid expression in braces, unless the expression 20395 * evaluation has been cancelled due to an aborting error, an 20396 * interrupt, or an exception. 20397 */ 20398 if (!aborting()) 20399 { 20400 if (!eap->skip && fudi.fd_newkey != NULL) 20401 EMSG2(_(e_dictkey), fudi.fd_newkey); 20402 vim_free(fudi.fd_newkey); 20403 return; 20404 } 20405 else 20406 eap->skip = TRUE; 20407 } 20408 20409 /* An error in a function call during evaluation of an expression in magic 20410 * braces should not cause the function not to be defined. */ 20411 saved_did_emsg = did_emsg; 20412 did_emsg = FALSE; 20413 20414 /* 20415 * ":function func" with only function name: list function. 20416 */ 20417 if (!paren) 20418 { 20419 if (!ends_excmd(*skipwhite(p))) 20420 { 20421 EMSG(_(e_trailing)); 20422 goto ret_free; 20423 } 20424 eap->nextcmd = check_nextcmd(p); 20425 if (eap->nextcmd != NULL) 20426 *p = NUL; 20427 if (!eap->skip && !got_int) 20428 { 20429 fp = find_func(name); 20430 if (fp != NULL) 20431 { 20432 list_func_head(fp, TRUE); 20433 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 20434 { 20435 if (FUNCLINE(fp, j) == NULL) 20436 continue; 20437 msg_putchar('\n'); 20438 msg_outnum((long)(j + 1)); 20439 if (j < 9) 20440 msg_putchar(' '); 20441 if (j < 99) 20442 msg_putchar(' '); 20443 msg_prt_line(FUNCLINE(fp, j), FALSE); 20444 out_flush(); /* show a line at a time */ 20445 ui_breakcheck(); 20446 } 20447 if (!got_int) 20448 { 20449 msg_putchar('\n'); 20450 msg_puts((char_u *)" endfunction"); 20451 } 20452 } 20453 else 20454 emsg_funcname(N_("E123: Undefined function: %s"), name); 20455 } 20456 goto ret_free; 20457 } 20458 20459 /* 20460 * ":function name(arg1, arg2)" Define function. 20461 */ 20462 p = skipwhite(p); 20463 if (*p != '(') 20464 { 20465 if (!eap->skip) 20466 { 20467 EMSG2(_("E124: Missing '(': %s"), eap->arg); 20468 goto ret_free; 20469 } 20470 /* attempt to continue by skipping some text */ 20471 if (vim_strchr(p, '(') != NULL) 20472 p = vim_strchr(p, '('); 20473 } 20474 p = skipwhite(p + 1); 20475 20476 ga_init2(&newargs, (int)sizeof(char_u *), 3); 20477 ga_init2(&newlines, (int)sizeof(char_u *), 3); 20478 20479 if (!eap->skip) 20480 { 20481 /* Check the name of the function. Unless it's a dictionary function 20482 * (that we are overwriting). */ 20483 if (name != NULL) 20484 arg = name; 20485 else 20486 arg = fudi.fd_newkey; 20487 if (arg != NULL && (fudi.fd_di == NULL 20488 || fudi.fd_di->di_tv.v_type != VAR_FUNC)) 20489 { 20490 if (*arg == K_SPECIAL) 20491 j = 3; 20492 else 20493 j = 0; 20494 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 20495 : eval_isnamec(arg[j]))) 20496 ++j; 20497 if (arg[j] != NUL) 20498 emsg_funcname((char *)e_invarg2, arg); 20499 } 20500 } 20501 20502 /* 20503 * Isolate the arguments: "arg1, arg2, ...)" 20504 */ 20505 while (*p != ')') 20506 { 20507 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 20508 { 20509 varargs = TRUE; 20510 p += 3; 20511 mustend = TRUE; 20512 } 20513 else 20514 { 20515 arg = p; 20516 while (ASCII_ISALNUM(*p) || *p == '_') 20517 ++p; 20518 if (arg == p || isdigit(*arg) 20519 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 20520 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 20521 { 20522 if (!eap->skip) 20523 EMSG2(_("E125: Illegal argument: %s"), arg); 20524 break; 20525 } 20526 if (ga_grow(&newargs, 1) == FAIL) 20527 goto erret; 20528 c = *p; 20529 *p = NUL; 20530 arg = vim_strsave(arg); 20531 if (arg == NULL) 20532 goto erret; 20533 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 20534 *p = c; 20535 newargs.ga_len++; 20536 if (*p == ',') 20537 ++p; 20538 else 20539 mustend = TRUE; 20540 } 20541 p = skipwhite(p); 20542 if (mustend && *p != ')') 20543 { 20544 if (!eap->skip) 20545 EMSG2(_(e_invarg2), eap->arg); 20546 break; 20547 } 20548 } 20549 ++p; /* skip the ')' */ 20550 20551 /* find extra arguments "range", "dict" and "abort" */ 20552 for (;;) 20553 { 20554 p = skipwhite(p); 20555 if (STRNCMP(p, "range", 5) == 0) 20556 { 20557 flags |= FC_RANGE; 20558 p += 5; 20559 } 20560 else if (STRNCMP(p, "dict", 4) == 0) 20561 { 20562 flags |= FC_DICT; 20563 p += 4; 20564 } 20565 else if (STRNCMP(p, "abort", 5) == 0) 20566 { 20567 flags |= FC_ABORT; 20568 p += 5; 20569 } 20570 else 20571 break; 20572 } 20573 20574 /* When there is a line break use what follows for the function body. 20575 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 20576 if (*p == '\n') 20577 line_arg = p + 1; 20578 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 20579 EMSG(_(e_trailing)); 20580 20581 /* 20582 * Read the body of the function, until ":endfunction" is found. 20583 */ 20584 if (KeyTyped) 20585 { 20586 /* Check if the function already exists, don't let the user type the 20587 * whole function before telling him it doesn't work! For a script we 20588 * need to skip the body to be able to find what follows. */ 20589 if (!eap->skip && !eap->forceit) 20590 { 20591 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 20592 EMSG(_(e_funcdict)); 20593 else if (name != NULL && find_func(name) != NULL) 20594 emsg_funcname(e_funcexts, name); 20595 } 20596 20597 if (!eap->skip && did_emsg) 20598 goto erret; 20599 20600 msg_putchar('\n'); /* don't overwrite the function name */ 20601 cmdline_row = msg_row; 20602 } 20603 20604 indent = 2; 20605 nesting = 0; 20606 for (;;) 20607 { 20608 msg_scroll = TRUE; 20609 need_wait_return = FALSE; 20610 sourcing_lnum_off = sourcing_lnum; 20611 20612 if (line_arg != NULL) 20613 { 20614 /* Use eap->arg, split up in parts by line breaks. */ 20615 theline = line_arg; 20616 p = vim_strchr(theline, '\n'); 20617 if (p == NULL) 20618 line_arg += STRLEN(line_arg); 20619 else 20620 { 20621 *p = NUL; 20622 line_arg = p + 1; 20623 } 20624 } 20625 else if (eap->getline == NULL) 20626 theline = getcmdline(':', 0L, indent); 20627 else 20628 theline = eap->getline(':', eap->cookie, indent); 20629 if (KeyTyped) 20630 lines_left = Rows - 1; 20631 if (theline == NULL) 20632 { 20633 EMSG(_("E126: Missing :endfunction")); 20634 goto erret; 20635 } 20636 20637 /* Detect line continuation: sourcing_lnum increased more than one. */ 20638 if (sourcing_lnum > sourcing_lnum_off + 1) 20639 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 20640 else 20641 sourcing_lnum_off = 0; 20642 20643 if (skip_until != NULL) 20644 { 20645 /* between ":append" and "." and between ":python <<EOF" and "EOF" 20646 * don't check for ":endfunc". */ 20647 if (STRCMP(theline, skip_until) == 0) 20648 { 20649 vim_free(skip_until); 20650 skip_until = NULL; 20651 } 20652 } 20653 else 20654 { 20655 /* skip ':' and blanks*/ 20656 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 20657 ; 20658 20659 /* Check for "endfunction". */ 20660 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 20661 { 20662 if (line_arg == NULL) 20663 vim_free(theline); 20664 break; 20665 } 20666 20667 /* Increase indent inside "if", "while", "for" and "try", decrease 20668 * at "end". */ 20669 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 20670 indent -= 2; 20671 else if (STRNCMP(p, "if", 2) == 0 20672 || STRNCMP(p, "wh", 2) == 0 20673 || STRNCMP(p, "for", 3) == 0 20674 || STRNCMP(p, "try", 3) == 0) 20675 indent += 2; 20676 20677 /* Check for defining a function inside this function. */ 20678 if (checkforcmd(&p, "function", 2)) 20679 { 20680 if (*p == '!') 20681 p = skipwhite(p + 1); 20682 p += eval_fname_script(p); 20683 if (ASCII_ISALPHA(*p)) 20684 { 20685 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 20686 if (*skipwhite(p) == '(') 20687 { 20688 ++nesting; 20689 indent += 2; 20690 } 20691 } 20692 } 20693 20694 /* Check for ":append" or ":insert". */ 20695 p = skip_range(p, NULL); 20696 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 20697 || (p[0] == 'i' 20698 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 20699 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 20700 skip_until = vim_strsave((char_u *)"."); 20701 20702 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 20703 arg = skipwhite(skiptowhite(p)); 20704 if (arg[0] == '<' && arg[1] =='<' 20705 && ((p[0] == 'p' && p[1] == 'y' 20706 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 20707 || (p[0] == 'p' && p[1] == 'e' 20708 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 20709 || (p[0] == 't' && p[1] == 'c' 20710 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 20711 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 20712 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 20713 || (p[0] == 'm' && p[1] == 'z' 20714 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 20715 )) 20716 { 20717 /* ":python <<" continues until a dot, like ":append" */ 20718 p = skipwhite(arg + 2); 20719 if (*p == NUL) 20720 skip_until = vim_strsave((char_u *)"."); 20721 else 20722 skip_until = vim_strsave(p); 20723 } 20724 } 20725 20726 /* Add the line to the function. */ 20727 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 20728 { 20729 if (line_arg == NULL) 20730 vim_free(theline); 20731 goto erret; 20732 } 20733 20734 /* Copy the line to newly allocated memory. get_one_sourceline() 20735 * allocates 250 bytes per line, this saves 80% on average. The cost 20736 * is an extra alloc/free. */ 20737 p = vim_strsave(theline); 20738 if (p != NULL) 20739 { 20740 if (line_arg == NULL) 20741 vim_free(theline); 20742 theline = p; 20743 } 20744 20745 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 20746 20747 /* Add NULL lines for continuation lines, so that the line count is 20748 * equal to the index in the growarray. */ 20749 while (sourcing_lnum_off-- > 0) 20750 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 20751 20752 /* Check for end of eap->arg. */ 20753 if (line_arg != NULL && *line_arg == NUL) 20754 line_arg = NULL; 20755 } 20756 20757 /* Don't define the function when skipping commands or when an error was 20758 * detected. */ 20759 if (eap->skip || did_emsg) 20760 goto erret; 20761 20762 /* 20763 * If there are no errors, add the function 20764 */ 20765 if (fudi.fd_dict == NULL) 20766 { 20767 v = find_var(name, &ht); 20768 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 20769 { 20770 emsg_funcname(N_("E707: Function name conflicts with variable: %s"), 20771 name); 20772 goto erret; 20773 } 20774 20775 fp = find_func(name); 20776 if (fp != NULL) 20777 { 20778 if (!eap->forceit) 20779 { 20780 emsg_funcname(e_funcexts, name); 20781 goto erret; 20782 } 20783 if (fp->uf_calls > 0) 20784 { 20785 emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), 20786 name); 20787 goto erret; 20788 } 20789 /* redefine existing function */ 20790 ga_clear_strings(&(fp->uf_args)); 20791 ga_clear_strings(&(fp->uf_lines)); 20792 vim_free(name); 20793 name = NULL; 20794 } 20795 } 20796 else 20797 { 20798 char numbuf[20]; 20799 20800 fp = NULL; 20801 if (fudi.fd_newkey == NULL && !eap->forceit) 20802 { 20803 EMSG(_(e_funcdict)); 20804 goto erret; 20805 } 20806 if (fudi.fd_di == NULL) 20807 { 20808 /* Can't add a function to a locked dictionary */ 20809 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 20810 goto erret; 20811 } 20812 /* Can't change an existing function if it is locked */ 20813 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 20814 goto erret; 20815 20816 /* Give the function a sequential number. Can only be used with a 20817 * Funcref! */ 20818 vim_free(name); 20819 sprintf(numbuf, "%d", ++func_nr); 20820 name = vim_strsave((char_u *)numbuf); 20821 if (name == NULL) 20822 goto erret; 20823 } 20824 20825 if (fp == NULL) 20826 { 20827 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 20828 { 20829 int slen, plen; 20830 char_u *scriptname; 20831 20832 /* Check that the autoload name matches the script name. */ 20833 j = FAIL; 20834 if (sourcing_name != NULL) 20835 { 20836 scriptname = autoload_name(name); 20837 if (scriptname != NULL) 20838 { 20839 p = vim_strchr(scriptname, '/'); 20840 plen = (int)STRLEN(p); 20841 slen = (int)STRLEN(sourcing_name); 20842 if (slen > plen && fnamecmp(p, 20843 sourcing_name + slen - plen) == 0) 20844 j = OK; 20845 vim_free(scriptname); 20846 } 20847 } 20848 if (j == FAIL) 20849 { 20850 EMSG2(_("E746: Function name does not match script file name: %s"), name); 20851 goto erret; 20852 } 20853 } 20854 20855 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 20856 if (fp == NULL) 20857 goto erret; 20858 20859 if (fudi.fd_dict != NULL) 20860 { 20861 if (fudi.fd_di == NULL) 20862 { 20863 /* add new dict entry */ 20864 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 20865 if (fudi.fd_di == NULL) 20866 { 20867 vim_free(fp); 20868 goto erret; 20869 } 20870 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 20871 { 20872 vim_free(fudi.fd_di); 20873 vim_free(fp); 20874 goto erret; 20875 } 20876 } 20877 else 20878 /* overwrite existing dict entry */ 20879 clear_tv(&fudi.fd_di->di_tv); 20880 fudi.fd_di->di_tv.v_type = VAR_FUNC; 20881 fudi.fd_di->di_tv.v_lock = 0; 20882 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 20883 fp->uf_refcount = 1; 20884 20885 /* behave like "dict" was used */ 20886 flags |= FC_DICT; 20887 } 20888 20889 /* insert the new function in the function list */ 20890 STRCPY(fp->uf_name, name); 20891 hash_add(&func_hashtab, UF2HIKEY(fp)); 20892 } 20893 fp->uf_args = newargs; 20894 fp->uf_lines = newlines; 20895 #ifdef FEAT_PROFILE 20896 fp->uf_tml_count = NULL; 20897 fp->uf_tml_total = NULL; 20898 fp->uf_tml_self = NULL; 20899 fp->uf_profiling = FALSE; 20900 if (prof_def_func()) 20901 func_do_profile(fp); 20902 #endif 20903 fp->uf_varargs = varargs; 20904 fp->uf_flags = flags; 20905 fp->uf_calls = 0; 20906 fp->uf_script_ID = current_SID; 20907 goto ret_free; 20908 20909 erret: 20910 ga_clear_strings(&newargs); 20911 ga_clear_strings(&newlines); 20912 ret_free: 20913 vim_free(skip_until); 20914 vim_free(fudi.fd_newkey); 20915 vim_free(name); 20916 did_emsg |= saved_did_emsg; 20917 } 20918 20919 /* 20920 * Get a function name, translating "<SID>" and "<SNR>". 20921 * Also handles a Funcref in a List or Dictionary. 20922 * Returns the function name in allocated memory, or NULL for failure. 20923 * flags: 20924 * TFN_INT: internal function name OK 20925 * TFN_QUIET: be quiet 20926 * Advances "pp" to just after the function name (if no error). 20927 */ 20928 static char_u * 20929 trans_function_name(pp, skip, flags, fdp) 20930 char_u **pp; 20931 int skip; /* only find the end, don't evaluate */ 20932 int flags; 20933 funcdict_T *fdp; /* return: info about dictionary used */ 20934 { 20935 char_u *name = NULL; 20936 char_u *start; 20937 char_u *end; 20938 int lead; 20939 char_u sid_buf[20]; 20940 int len; 20941 lval_T lv; 20942 20943 if (fdp != NULL) 20944 vim_memset(fdp, 0, sizeof(funcdict_T)); 20945 start = *pp; 20946 20947 /* Check for hard coded <SNR>: already translated function ID (from a user 20948 * command). */ 20949 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 20950 && (*pp)[2] == (int)KE_SNR) 20951 { 20952 *pp += 3; 20953 len = get_id_len(pp) + 3; 20954 return vim_strnsave(start, len); 20955 } 20956 20957 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 20958 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 20959 lead = eval_fname_script(start); 20960 if (lead > 2) 20961 start += lead; 20962 20963 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 20964 lead > 2 ? 0 : FNE_CHECK_START); 20965 if (end == start) 20966 { 20967 if (!skip) 20968 EMSG(_("E129: Function name required")); 20969 goto theend; 20970 } 20971 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 20972 { 20973 /* 20974 * Report an invalid expression in braces, unless the expression 20975 * evaluation has been cancelled due to an aborting error, an 20976 * interrupt, or an exception. 20977 */ 20978 if (!aborting()) 20979 { 20980 if (end != NULL) 20981 EMSG2(_(e_invarg2), start); 20982 } 20983 else 20984 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 20985 goto theend; 20986 } 20987 20988 if (lv.ll_tv != NULL) 20989 { 20990 if (fdp != NULL) 20991 { 20992 fdp->fd_dict = lv.ll_dict; 20993 fdp->fd_newkey = lv.ll_newkey; 20994 lv.ll_newkey = NULL; 20995 fdp->fd_di = lv.ll_di; 20996 } 20997 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 20998 { 20999 name = vim_strsave(lv.ll_tv->vval.v_string); 21000 *pp = end; 21001 } 21002 else 21003 { 21004 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 21005 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 21006 EMSG(_(e_funcref)); 21007 else 21008 *pp = end; 21009 name = NULL; 21010 } 21011 goto theend; 21012 } 21013 21014 if (lv.ll_name == NULL) 21015 { 21016 /* Error found, but continue after the function name. */ 21017 *pp = end; 21018 goto theend; 21019 } 21020 21021 /* Check if the name is a Funcref. If so, use the value. */ 21022 if (lv.ll_exp_name != NULL) 21023 { 21024 len = (int)STRLEN(lv.ll_exp_name); 21025 name = deref_func_name(lv.ll_exp_name, &len); 21026 if (name == lv.ll_exp_name) 21027 name = NULL; 21028 } 21029 else 21030 { 21031 len = (int)(end - *pp); 21032 name = deref_func_name(*pp, &len); 21033 if (name == *pp) 21034 name = NULL; 21035 } 21036 if (name != NULL) 21037 { 21038 name = vim_strsave(name); 21039 *pp = end; 21040 goto theend; 21041 } 21042 21043 if (lv.ll_exp_name != NULL) 21044 { 21045 len = (int)STRLEN(lv.ll_exp_name); 21046 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 21047 && STRNCMP(lv.ll_name, "s:", 2) == 0) 21048 { 21049 /* When there was "s:" already or the name expanded to get a 21050 * leading "s:" then remove it. */ 21051 lv.ll_name += 2; 21052 len -= 2; 21053 lead = 2; 21054 } 21055 } 21056 else 21057 { 21058 if (lead == 2) /* skip over "s:" */ 21059 lv.ll_name += 2; 21060 len = (int)(end - lv.ll_name); 21061 } 21062 21063 /* 21064 * Copy the function name to allocated memory. 21065 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 21066 * Accept <SNR>123_name() outside a script. 21067 */ 21068 if (skip) 21069 lead = 0; /* do nothing */ 21070 else if (lead > 0) 21071 { 21072 lead = 3; 21073 if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) 21074 || eval_fname_sid(*pp)) 21075 { 21076 /* It's "s:" or "<SID>" */ 21077 if (current_SID <= 0) 21078 { 21079 EMSG(_(e_usingsid)); 21080 goto theend; 21081 } 21082 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 21083 lead += (int)STRLEN(sid_buf); 21084 } 21085 } 21086 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 21087 { 21088 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 21089 goto theend; 21090 } 21091 name = alloc((unsigned)(len + lead + 1)); 21092 if (name != NULL) 21093 { 21094 if (lead > 0) 21095 { 21096 name[0] = K_SPECIAL; 21097 name[1] = KS_EXTRA; 21098 name[2] = (int)KE_SNR; 21099 if (lead > 3) /* If it's "<SID>" */ 21100 STRCPY(name + 3, sid_buf); 21101 } 21102 mch_memmove(name + lead, lv.ll_name, (size_t)len); 21103 name[len + lead] = NUL; 21104 } 21105 *pp = end; 21106 21107 theend: 21108 clear_lval(&lv); 21109 return name; 21110 } 21111 21112 /* 21113 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 21114 * Return 2 if "p" starts with "s:". 21115 * Return 0 otherwise. 21116 */ 21117 static int 21118 eval_fname_script(p) 21119 char_u *p; 21120 { 21121 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 21122 || STRNICMP(p + 1, "SNR>", 4) == 0)) 21123 return 5; 21124 if (p[0] == 's' && p[1] == ':') 21125 return 2; 21126 return 0; 21127 } 21128 21129 /* 21130 * Return TRUE if "p" starts with "<SID>" or "s:". 21131 * Only works if eval_fname_script() returned non-zero for "p"! 21132 */ 21133 static int 21134 eval_fname_sid(p) 21135 char_u *p; 21136 { 21137 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 21138 } 21139 21140 /* 21141 * List the head of the function: "name(arg1, arg2)". 21142 */ 21143 static void 21144 list_func_head(fp, indent) 21145 ufunc_T *fp; 21146 int indent; 21147 { 21148 int j; 21149 21150 msg_start(); 21151 if (indent) 21152 MSG_PUTS(" "); 21153 MSG_PUTS("function "); 21154 if (fp->uf_name[0] == K_SPECIAL) 21155 { 21156 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 21157 msg_puts(fp->uf_name + 3); 21158 } 21159 else 21160 msg_puts(fp->uf_name); 21161 msg_putchar('('); 21162 for (j = 0; j < fp->uf_args.ga_len; ++j) 21163 { 21164 if (j) 21165 MSG_PUTS(", "); 21166 msg_puts(FUNCARG(fp, j)); 21167 } 21168 if (fp->uf_varargs) 21169 { 21170 if (j) 21171 MSG_PUTS(", "); 21172 MSG_PUTS("..."); 21173 } 21174 msg_putchar(')'); 21175 msg_clr_eos(); 21176 if (p_verbose > 0) 21177 last_set_msg(fp->uf_script_ID); 21178 } 21179 21180 /* 21181 * Find a function by name, return pointer to it in ufuncs. 21182 * Return NULL for unknown function. 21183 */ 21184 static ufunc_T * 21185 find_func(name) 21186 char_u *name; 21187 { 21188 hashitem_T *hi; 21189 21190 hi = hash_find(&func_hashtab, name); 21191 if (!HASHITEM_EMPTY(hi)) 21192 return HI2UF(hi); 21193 return NULL; 21194 } 21195 21196 #if defined(EXITFREE) || defined(PROTO) 21197 void 21198 free_all_functions() 21199 { 21200 hashitem_T *hi; 21201 21202 /* Need to start all over every time, because func_free() may change the 21203 * hash table. */ 21204 while (func_hashtab.ht_used > 0) 21205 for (hi = func_hashtab.ht_array; ; ++hi) 21206 if (!HASHITEM_EMPTY(hi)) 21207 { 21208 func_free(HI2UF(hi)); 21209 break; 21210 } 21211 } 21212 #endif 21213 21214 /* 21215 * Return TRUE if a function "name" exists. 21216 */ 21217 static int 21218 function_exists(name) 21219 char_u *name; 21220 { 21221 char_u *nm = name; 21222 char_u *p; 21223 int n = FALSE; 21224 21225 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL); 21226 nm = skipwhite(nm); 21227 21228 /* Only accept "funcname", "funcname ", "funcname (..." and 21229 * "funcname(...", not "funcname!...". */ 21230 if (p != NULL && (*nm == NUL || *nm == '(')) 21231 { 21232 if (builtin_function(p)) 21233 n = (find_internal_func(p) >= 0); 21234 else 21235 n = (find_func(p) != NULL); 21236 } 21237 vim_free(p); 21238 return n; 21239 } 21240 21241 /* 21242 * Return TRUE if "name" looks like a builtin function name: starts with a 21243 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 21244 */ 21245 static int 21246 builtin_function(name) 21247 char_u *name; 21248 { 21249 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 21250 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 21251 } 21252 21253 #if defined(FEAT_PROFILE) || defined(PROTO) 21254 /* 21255 * Start profiling function "fp". 21256 */ 21257 static void 21258 func_do_profile(fp) 21259 ufunc_T *fp; 21260 { 21261 int len = fp->uf_lines.ga_len; 21262 21263 if (len == 0) 21264 len = 1; /* avoid getting error for allocating zero bytes */ 21265 fp->uf_tm_count = 0; 21266 profile_zero(&fp->uf_tm_self); 21267 profile_zero(&fp->uf_tm_total); 21268 if (fp->uf_tml_count == NULL) 21269 fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len)); 21270 if (fp->uf_tml_total == NULL) 21271 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 21272 (sizeof(proftime_T) * len)); 21273 if (fp->uf_tml_self == NULL) 21274 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 21275 (sizeof(proftime_T) * len)); 21276 fp->uf_tml_idx = -1; 21277 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 21278 || fp->uf_tml_self == NULL) 21279 return; /* out of memory */ 21280 21281 fp->uf_profiling = TRUE; 21282 } 21283 21284 /* 21285 * Dump the profiling results for all functions in file "fd". 21286 */ 21287 void 21288 func_dump_profile(fd) 21289 FILE *fd; 21290 { 21291 hashitem_T *hi; 21292 int todo; 21293 ufunc_T *fp; 21294 int i; 21295 ufunc_T **sorttab; 21296 int st_len = 0; 21297 21298 todo = (int)func_hashtab.ht_used; 21299 if (todo == 0) 21300 return; /* nothing to dump */ 21301 21302 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 21303 21304 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 21305 { 21306 if (!HASHITEM_EMPTY(hi)) 21307 { 21308 --todo; 21309 fp = HI2UF(hi); 21310 if (fp->uf_profiling) 21311 { 21312 if (sorttab != NULL) 21313 sorttab[st_len++] = fp; 21314 21315 if (fp->uf_name[0] == K_SPECIAL) 21316 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 21317 else 21318 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 21319 if (fp->uf_tm_count == 1) 21320 fprintf(fd, "Called 1 time\n"); 21321 else 21322 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 21323 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 21324 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 21325 fprintf(fd, "\n"); 21326 fprintf(fd, "count total (s) self (s)\n"); 21327 21328 for (i = 0; i < fp->uf_lines.ga_len; ++i) 21329 { 21330 if (FUNCLINE(fp, i) == NULL) 21331 continue; 21332 prof_func_line(fd, fp->uf_tml_count[i], 21333 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 21334 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 21335 } 21336 fprintf(fd, "\n"); 21337 } 21338 } 21339 } 21340 21341 if (sorttab != NULL && st_len > 0) 21342 { 21343 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 21344 prof_total_cmp); 21345 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 21346 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 21347 prof_self_cmp); 21348 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 21349 } 21350 21351 vim_free(sorttab); 21352 } 21353 21354 static void 21355 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 21356 FILE *fd; 21357 ufunc_T **sorttab; 21358 int st_len; 21359 char *title; 21360 int prefer_self; /* when equal print only self time */ 21361 { 21362 int i; 21363 ufunc_T *fp; 21364 21365 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 21366 fprintf(fd, "count total (s) self (s) function\n"); 21367 for (i = 0; i < 20 && i < st_len; ++i) 21368 { 21369 fp = sorttab[i]; 21370 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 21371 prefer_self); 21372 if (fp->uf_name[0] == K_SPECIAL) 21373 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 21374 else 21375 fprintf(fd, " %s()\n", fp->uf_name); 21376 } 21377 fprintf(fd, "\n"); 21378 } 21379 21380 /* 21381 * Print the count and times for one function or function line. 21382 */ 21383 static void 21384 prof_func_line(fd, count, total, self, prefer_self) 21385 FILE *fd; 21386 int count; 21387 proftime_T *total; 21388 proftime_T *self; 21389 int prefer_self; /* when equal print only self time */ 21390 { 21391 if (count > 0) 21392 { 21393 fprintf(fd, "%5d ", count); 21394 if (prefer_self && profile_equal(total, self)) 21395 fprintf(fd, " "); 21396 else 21397 fprintf(fd, "%s ", profile_msg(total)); 21398 if (!prefer_self && profile_equal(total, self)) 21399 fprintf(fd, " "); 21400 else 21401 fprintf(fd, "%s ", profile_msg(self)); 21402 } 21403 else 21404 fprintf(fd, " "); 21405 } 21406 21407 /* 21408 * Compare function for total time sorting. 21409 */ 21410 static int 21411 #ifdef __BORLANDC__ 21412 _RTLENTRYF 21413 #endif 21414 prof_total_cmp(s1, s2) 21415 const void *s1; 21416 const void *s2; 21417 { 21418 ufunc_T *p1, *p2; 21419 21420 p1 = *(ufunc_T **)s1; 21421 p2 = *(ufunc_T **)s2; 21422 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 21423 } 21424 21425 /* 21426 * Compare function for self time sorting. 21427 */ 21428 static int 21429 #ifdef __BORLANDC__ 21430 _RTLENTRYF 21431 #endif 21432 prof_self_cmp(s1, s2) 21433 const void *s1; 21434 const void *s2; 21435 { 21436 ufunc_T *p1, *p2; 21437 21438 p1 = *(ufunc_T **)s1; 21439 p2 = *(ufunc_T **)s2; 21440 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 21441 } 21442 21443 #endif 21444 21445 /* 21446 * If "name" has a package name try autoloading the script for it. 21447 * Return TRUE if a package was loaded. 21448 */ 21449 static int 21450 script_autoload(name, reload) 21451 char_u *name; 21452 int reload; /* load script again when already loaded */ 21453 { 21454 char_u *p; 21455 char_u *scriptname, *tofree; 21456 int ret = FALSE; 21457 int i; 21458 21459 /* Return quickly when autoload disabled. */ 21460 if (no_autoload) 21461 return FALSE; 21462 21463 /* If there is no '#' after name[0] there is no package name. */ 21464 p = vim_strchr(name, AUTOLOAD_CHAR); 21465 if (p == NULL || p == name) 21466 return FALSE; 21467 21468 tofree = scriptname = autoload_name(name); 21469 21470 /* Find the name in the list of previously loaded package names. Skip 21471 * "autoload/", it's always the same. */ 21472 for (i = 0; i < ga_loaded.ga_len; ++i) 21473 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 21474 break; 21475 if (!reload && i < ga_loaded.ga_len) 21476 ret = FALSE; /* was loaded already */ 21477 else 21478 { 21479 /* Remember the name if it wasn't loaded already. */ 21480 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 21481 { 21482 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 21483 tofree = NULL; 21484 } 21485 21486 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 21487 if (source_runtime(scriptname, FALSE) == OK) 21488 ret = TRUE; 21489 } 21490 21491 vim_free(tofree); 21492 return ret; 21493 } 21494 21495 /* 21496 * Return the autoload script name for a function or variable name. 21497 * Returns NULL when out of memory. 21498 */ 21499 static char_u * 21500 autoload_name(name) 21501 char_u *name; 21502 { 21503 char_u *p; 21504 char_u *scriptname; 21505 21506 /* Get the script file name: replace '#' with '/', append ".vim". */ 21507 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 21508 if (scriptname == NULL) 21509 return FALSE; 21510 STRCPY(scriptname, "autoload/"); 21511 STRCAT(scriptname, name); 21512 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 21513 STRCAT(scriptname, ".vim"); 21514 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 21515 *p = '/'; 21516 return scriptname; 21517 } 21518 21519 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 21520 21521 /* 21522 * Function given to ExpandGeneric() to obtain the list of user defined 21523 * function names. 21524 */ 21525 char_u * 21526 get_user_func_name(xp, idx) 21527 expand_T *xp; 21528 int idx; 21529 { 21530 static long_u done; 21531 static hashitem_T *hi; 21532 ufunc_T *fp; 21533 21534 if (idx == 0) 21535 { 21536 done = 0; 21537 hi = func_hashtab.ht_array; 21538 } 21539 if (done < func_hashtab.ht_used) 21540 { 21541 if (done++ > 0) 21542 ++hi; 21543 while (HASHITEM_EMPTY(hi)) 21544 ++hi; 21545 fp = HI2UF(hi); 21546 21547 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 21548 return fp->uf_name; /* prevents overflow */ 21549 21550 cat_func_name(IObuff, fp); 21551 if (xp->xp_context != EXPAND_USER_FUNC) 21552 { 21553 STRCAT(IObuff, "("); 21554 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 21555 STRCAT(IObuff, ")"); 21556 } 21557 return IObuff; 21558 } 21559 return NULL; 21560 } 21561 21562 #endif /* FEAT_CMDL_COMPL */ 21563 21564 /* 21565 * Copy the function name of "fp" to buffer "buf". 21566 * "buf" must be able to hold the function name plus three bytes. 21567 * Takes care of script-local function names. 21568 */ 21569 static void 21570 cat_func_name(buf, fp) 21571 char_u *buf; 21572 ufunc_T *fp; 21573 { 21574 if (fp->uf_name[0] == K_SPECIAL) 21575 { 21576 STRCPY(buf, "<SNR>"); 21577 STRCAT(buf, fp->uf_name + 3); 21578 } 21579 else 21580 STRCPY(buf, fp->uf_name); 21581 } 21582 21583 /* 21584 * ":delfunction {name}" 21585 */ 21586 void 21587 ex_delfunction(eap) 21588 exarg_T *eap; 21589 { 21590 ufunc_T *fp = NULL; 21591 char_u *p; 21592 char_u *name; 21593 funcdict_T fudi; 21594 21595 p = eap->arg; 21596 name = trans_function_name(&p, eap->skip, 0, &fudi); 21597 vim_free(fudi.fd_newkey); 21598 if (name == NULL) 21599 { 21600 if (fudi.fd_dict != NULL && !eap->skip) 21601 EMSG(_(e_funcref)); 21602 return; 21603 } 21604 if (!ends_excmd(*skipwhite(p))) 21605 { 21606 vim_free(name); 21607 EMSG(_(e_trailing)); 21608 return; 21609 } 21610 eap->nextcmd = check_nextcmd(p); 21611 if (eap->nextcmd != NULL) 21612 *p = NUL; 21613 21614 if (!eap->skip) 21615 fp = find_func(name); 21616 vim_free(name); 21617 21618 if (!eap->skip) 21619 { 21620 if (fp == NULL) 21621 { 21622 EMSG2(_(e_nofunc), eap->arg); 21623 return; 21624 } 21625 if (fp->uf_calls > 0) 21626 { 21627 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 21628 return; 21629 } 21630 21631 if (fudi.fd_dict != NULL) 21632 { 21633 /* Delete the dict item that refers to the function, it will 21634 * invoke func_unref() and possibly delete the function. */ 21635 dictitem_remove(fudi.fd_dict, fudi.fd_di); 21636 } 21637 else 21638 func_free(fp); 21639 } 21640 } 21641 21642 /* 21643 * Free a function and remove it from the list of functions. 21644 */ 21645 static void 21646 func_free(fp) 21647 ufunc_T *fp; 21648 { 21649 hashitem_T *hi; 21650 21651 /* clear this function */ 21652 ga_clear_strings(&(fp->uf_args)); 21653 ga_clear_strings(&(fp->uf_lines)); 21654 #ifdef FEAT_PROFILE 21655 vim_free(fp->uf_tml_count); 21656 vim_free(fp->uf_tml_total); 21657 vim_free(fp->uf_tml_self); 21658 #endif 21659 21660 /* remove the function from the function hashtable */ 21661 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 21662 if (HASHITEM_EMPTY(hi)) 21663 EMSG2(_(e_intern2), "func_free()"); 21664 else 21665 hash_remove(&func_hashtab, hi); 21666 21667 vim_free(fp); 21668 } 21669 21670 /* 21671 * Unreference a Function: decrement the reference count and free it when it 21672 * becomes zero. Only for numbered functions. 21673 */ 21674 static void 21675 func_unref(name) 21676 char_u *name; 21677 { 21678 ufunc_T *fp; 21679 21680 if (name != NULL && isdigit(*name)) 21681 { 21682 fp = find_func(name); 21683 if (fp == NULL) 21684 EMSG2(_(e_intern2), "func_unref()"); 21685 else if (--fp->uf_refcount <= 0) 21686 { 21687 /* Only delete it when it's not being used. Otherwise it's done 21688 * when "uf_calls" becomes zero. */ 21689 if (fp->uf_calls == 0) 21690 func_free(fp); 21691 } 21692 } 21693 } 21694 21695 /* 21696 * Count a reference to a Function. 21697 */ 21698 static void 21699 func_ref(name) 21700 char_u *name; 21701 { 21702 ufunc_T *fp; 21703 21704 if (name != NULL && isdigit(*name)) 21705 { 21706 fp = find_func(name); 21707 if (fp == NULL) 21708 EMSG2(_(e_intern2), "func_ref()"); 21709 else 21710 ++fp->uf_refcount; 21711 } 21712 } 21713 21714 /* 21715 * Call a user function. 21716 */ 21717 static void 21718 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 21719 ufunc_T *fp; /* pointer to function */ 21720 int argcount; /* nr of args */ 21721 typval_T *argvars; /* arguments */ 21722 typval_T *rettv; /* return value */ 21723 linenr_T firstline; /* first line of range */ 21724 linenr_T lastline; /* last line of range */ 21725 dict_T *selfdict; /* Dictionary for "self" */ 21726 { 21727 char_u *save_sourcing_name; 21728 linenr_T save_sourcing_lnum; 21729 scid_T save_current_SID; 21730 funccall_T *fc; 21731 int save_did_emsg; 21732 static int depth = 0; 21733 dictitem_T *v; 21734 int fixvar_idx = 0; /* index in fixvar[] */ 21735 int i; 21736 int ai; 21737 char_u numbuf[NUMBUFLEN]; 21738 char_u *name; 21739 #ifdef FEAT_PROFILE 21740 proftime_T wait_start; 21741 proftime_T call_start; 21742 #endif 21743 21744 /* If depth of calling is getting too high, don't execute the function */ 21745 if (depth >= p_mfd) 21746 { 21747 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 21748 rettv->v_type = VAR_NUMBER; 21749 rettv->vval.v_number = -1; 21750 return; 21751 } 21752 ++depth; 21753 21754 line_breakcheck(); /* check for CTRL-C hit */ 21755 21756 fc = (funccall_T *)alloc(sizeof(funccall_T)); 21757 fc->caller = current_funccal; 21758 current_funccal = fc; 21759 fc->func = fp; 21760 fc->rettv = rettv; 21761 rettv->vval.v_number = 0; 21762 fc->linenr = 0; 21763 fc->returned = FALSE; 21764 fc->level = ex_nesting_level; 21765 /* Check if this function has a breakpoint. */ 21766 fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 21767 fc->dbg_tick = debug_tick; 21768 21769 /* 21770 * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables 21771 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 21772 * each argument variable and saves a lot of time. 21773 */ 21774 /* 21775 * Init l: variables. 21776 */ 21777 init_var_dict(&fc->l_vars, &fc->l_vars_var); 21778 if (selfdict != NULL) 21779 { 21780 /* Set l:self to "selfdict". Use "name" to avoid a warning from 21781 * some compiler that checks the destination size. */ 21782 v = &fc->fixvar[fixvar_idx++].var; 21783 name = v->di_key; 21784 STRCPY(name, "self"); 21785 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 21786 hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); 21787 v->di_tv.v_type = VAR_DICT; 21788 v->di_tv.v_lock = 0; 21789 v->di_tv.vval.v_dict = selfdict; 21790 ++selfdict->dv_refcount; 21791 } 21792 21793 /* 21794 * Init a: variables. 21795 * Set a:0 to "argcount". 21796 * Set a:000 to a list with room for the "..." arguments. 21797 */ 21798 init_var_dict(&fc->l_avars, &fc->l_avars_var); 21799 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", 21800 (varnumber_T)(argcount - fp->uf_args.ga_len)); 21801 /* Use "name" to avoid a warning from some compiler that checks the 21802 * destination size. */ 21803 v = &fc->fixvar[fixvar_idx++].var; 21804 name = v->di_key; 21805 STRCPY(name, "000"); 21806 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21807 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 21808 v->di_tv.v_type = VAR_LIST; 21809 v->di_tv.v_lock = VAR_FIXED; 21810 v->di_tv.vval.v_list = &fc->l_varlist; 21811 vim_memset(&fc->l_varlist, 0, sizeof(list_T)); 21812 fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT; 21813 fc->l_varlist.lv_lock = VAR_FIXED; 21814 21815 /* 21816 * Set a:firstline to "firstline" and a:lastline to "lastline". 21817 * Set a:name to named arguments. 21818 * Set a:N to the "..." arguments. 21819 */ 21820 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", 21821 (varnumber_T)firstline); 21822 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", 21823 (varnumber_T)lastline); 21824 for (i = 0; i < argcount; ++i) 21825 { 21826 ai = i - fp->uf_args.ga_len; 21827 if (ai < 0) 21828 /* named argument a:name */ 21829 name = FUNCARG(fp, i); 21830 else 21831 { 21832 /* "..." argument a:1, a:2, etc. */ 21833 sprintf((char *)numbuf, "%d", ai + 1); 21834 name = numbuf; 21835 } 21836 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 21837 { 21838 v = &fc->fixvar[fixvar_idx++].var; 21839 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21840 } 21841 else 21842 { 21843 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 21844 + STRLEN(name))); 21845 if (v == NULL) 21846 break; 21847 v->di_flags = DI_FLAGS_RO; 21848 } 21849 STRCPY(v->di_key, name); 21850 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 21851 21852 /* Note: the values are copied directly to avoid alloc/free. 21853 * "argvars" must have VAR_FIXED for v_lock. */ 21854 v->di_tv = argvars[i]; 21855 v->di_tv.v_lock = VAR_FIXED; 21856 21857 if (ai >= 0 && ai < MAX_FUNC_ARGS) 21858 { 21859 list_append(&fc->l_varlist, &fc->l_listitems[ai]); 21860 fc->l_listitems[ai].li_tv = argvars[i]; 21861 fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED; 21862 } 21863 } 21864 21865 /* Don't redraw while executing the function. */ 21866 ++RedrawingDisabled; 21867 save_sourcing_name = sourcing_name; 21868 save_sourcing_lnum = sourcing_lnum; 21869 sourcing_lnum = 1; 21870 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 21871 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 21872 if (sourcing_name != NULL) 21873 { 21874 if (save_sourcing_name != NULL 21875 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 21876 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 21877 else 21878 STRCPY(sourcing_name, "function "); 21879 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 21880 21881 if (p_verbose >= 12) 21882 { 21883 ++no_wait_return; 21884 verbose_enter_scroll(); 21885 21886 smsg((char_u *)_("calling %s"), sourcing_name); 21887 if (p_verbose >= 14) 21888 { 21889 char_u buf[MSG_BUF_LEN]; 21890 char_u numbuf2[NUMBUFLEN]; 21891 char_u *tofree; 21892 char_u *s; 21893 21894 msg_puts((char_u *)"("); 21895 for (i = 0; i < argcount; ++i) 21896 { 21897 if (i > 0) 21898 msg_puts((char_u *)", "); 21899 if (argvars[i].v_type == VAR_NUMBER) 21900 msg_outnum((long)argvars[i].vval.v_number); 21901 else 21902 { 21903 s = tv2string(&argvars[i], &tofree, numbuf2, 0); 21904 if (s != NULL) 21905 { 21906 trunc_string(s, buf, MSG_BUF_CLEN); 21907 msg_puts(buf); 21908 vim_free(tofree); 21909 } 21910 } 21911 } 21912 msg_puts((char_u *)")"); 21913 } 21914 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 21915 21916 verbose_leave_scroll(); 21917 --no_wait_return; 21918 } 21919 } 21920 #ifdef FEAT_PROFILE 21921 if (do_profiling == PROF_YES) 21922 { 21923 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 21924 func_do_profile(fp); 21925 if (fp->uf_profiling 21926 || (fc->caller != NULL && fc->caller->func->uf_profiling)) 21927 { 21928 ++fp->uf_tm_count; 21929 profile_start(&call_start); 21930 profile_zero(&fp->uf_tm_children); 21931 } 21932 script_prof_save(&wait_start); 21933 } 21934 #endif 21935 21936 save_current_SID = current_SID; 21937 current_SID = fp->uf_script_ID; 21938 save_did_emsg = did_emsg; 21939 did_emsg = FALSE; 21940 21941 /* call do_cmdline() to execute the lines */ 21942 do_cmdline(NULL, get_func_line, (void *)fc, 21943 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 21944 21945 --RedrawingDisabled; 21946 21947 /* when the function was aborted because of an error, return -1 */ 21948 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 21949 { 21950 clear_tv(rettv); 21951 rettv->v_type = VAR_NUMBER; 21952 rettv->vval.v_number = -1; 21953 } 21954 21955 #ifdef FEAT_PROFILE 21956 if (do_profiling == PROF_YES && (fp->uf_profiling 21957 || (fc->caller != NULL && fc->caller->func->uf_profiling))) 21958 { 21959 profile_end(&call_start); 21960 profile_sub_wait(&wait_start, &call_start); 21961 profile_add(&fp->uf_tm_total, &call_start); 21962 profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); 21963 if (fc->caller != NULL && fc->caller->func->uf_profiling) 21964 { 21965 profile_add(&fc->caller->func->uf_tm_children, &call_start); 21966 profile_add(&fc->caller->func->uf_tml_children, &call_start); 21967 } 21968 } 21969 #endif 21970 21971 /* when being verbose, mention the return value */ 21972 if (p_verbose >= 12) 21973 { 21974 ++no_wait_return; 21975 verbose_enter_scroll(); 21976 21977 if (aborting()) 21978 smsg((char_u *)_("%s aborted"), sourcing_name); 21979 else if (fc->rettv->v_type == VAR_NUMBER) 21980 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 21981 (long)fc->rettv->vval.v_number); 21982 else 21983 { 21984 char_u buf[MSG_BUF_LEN]; 21985 char_u numbuf2[NUMBUFLEN]; 21986 char_u *tofree; 21987 char_u *s; 21988 21989 /* The value may be very long. Skip the middle part, so that we 21990 * have some idea how it starts and ends. smsg() would always 21991 * truncate it at the end. */ 21992 s = tv2string(fc->rettv, &tofree, numbuf2, 0); 21993 if (s != NULL) 21994 { 21995 trunc_string(s, buf, MSG_BUF_CLEN); 21996 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 21997 vim_free(tofree); 21998 } 21999 } 22000 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 22001 22002 verbose_leave_scroll(); 22003 --no_wait_return; 22004 } 22005 22006 vim_free(sourcing_name); 22007 sourcing_name = save_sourcing_name; 22008 sourcing_lnum = save_sourcing_lnum; 22009 current_SID = save_current_SID; 22010 #ifdef FEAT_PROFILE 22011 if (do_profiling == PROF_YES) 22012 script_prof_restore(&wait_start); 22013 #endif 22014 22015 if (p_verbose >= 12 && sourcing_name != NULL) 22016 { 22017 ++no_wait_return; 22018 verbose_enter_scroll(); 22019 22020 smsg((char_u *)_("continuing in %s"), sourcing_name); 22021 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 22022 22023 verbose_leave_scroll(); 22024 --no_wait_return; 22025 } 22026 22027 did_emsg |= save_did_emsg; 22028 current_funccal = fc->caller; 22029 --depth; 22030 22031 /* If the a:000 list and the l: and a: dicts are not referenced we can 22032 * free the funccall_T and what's in it. */ 22033 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT 22034 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT 22035 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) 22036 { 22037 free_funccal(fc, FALSE); 22038 } 22039 else 22040 { 22041 hashitem_T *hi; 22042 listitem_T *li; 22043 int todo; 22044 22045 /* "fc" is still in use. This can happen when returning "a:000" or 22046 * assigning "l:" to a global variable. 22047 * Link "fc" in the list for garbage collection later. */ 22048 fc->caller = previous_funccal; 22049 previous_funccal = fc; 22050 22051 /* Make a copy of the a: variables, since we didn't do that above. */ 22052 todo = (int)fc->l_avars.dv_hashtab.ht_used; 22053 for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) 22054 { 22055 if (!HASHITEM_EMPTY(hi)) 22056 { 22057 --todo; 22058 v = HI2DI(hi); 22059 copy_tv(&v->di_tv, &v->di_tv); 22060 } 22061 } 22062 22063 /* Make a copy of the a:000 items, since we didn't do that above. */ 22064 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 22065 copy_tv(&li->li_tv, &li->li_tv); 22066 } 22067 } 22068 22069 /* 22070 * Return TRUE if items in "fc" do not have "copyID". That means they are not 22071 * referenced from anywhere that is in use. 22072 */ 22073 static int 22074 can_free_funccal(fc, copyID) 22075 funccall_T *fc; 22076 int copyID; 22077 { 22078 return (fc->l_varlist.lv_copyID != copyID 22079 && fc->l_vars.dv_copyID != copyID 22080 && fc->l_avars.dv_copyID != copyID); 22081 } 22082 22083 /* 22084 * Free "fc" and what it contains. 22085 */ 22086 static void 22087 free_funccal(fc, free_val) 22088 funccall_T *fc; 22089 int free_val; /* a: vars were allocated */ 22090 { 22091 listitem_T *li; 22092 22093 /* The a: variables typevals may not have been allocated, only free the 22094 * allocated variables. */ 22095 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); 22096 22097 /* free all l: variables */ 22098 vars_clear(&fc->l_vars.dv_hashtab); 22099 22100 /* Free the a:000 variables if they were allocated. */ 22101 if (free_val) 22102 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 22103 clear_tv(&li->li_tv); 22104 22105 vim_free(fc); 22106 } 22107 22108 /* 22109 * Add a number variable "name" to dict "dp" with value "nr". 22110 */ 22111 static void 22112 add_nr_var(dp, v, name, nr) 22113 dict_T *dp; 22114 dictitem_T *v; 22115 char *name; 22116 varnumber_T nr; 22117 { 22118 STRCPY(v->di_key, name); 22119 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 22120 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 22121 v->di_tv.v_type = VAR_NUMBER; 22122 v->di_tv.v_lock = VAR_FIXED; 22123 v->di_tv.vval.v_number = nr; 22124 } 22125 22126 /* 22127 * ":return [expr]" 22128 */ 22129 void 22130 ex_return(eap) 22131 exarg_T *eap; 22132 { 22133 char_u *arg = eap->arg; 22134 typval_T rettv; 22135 int returning = FALSE; 22136 22137 if (current_funccal == NULL) 22138 { 22139 EMSG(_("E133: :return not inside a function")); 22140 return; 22141 } 22142 22143 if (eap->skip) 22144 ++emsg_skip; 22145 22146 eap->nextcmd = NULL; 22147 if ((*arg != NUL && *arg != '|' && *arg != '\n') 22148 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 22149 { 22150 if (!eap->skip) 22151 returning = do_return(eap, FALSE, TRUE, &rettv); 22152 else 22153 clear_tv(&rettv); 22154 } 22155 /* It's safer to return also on error. */ 22156 else if (!eap->skip) 22157 { 22158 /* 22159 * Return unless the expression evaluation has been cancelled due to an 22160 * aborting error, an interrupt, or an exception. 22161 */ 22162 if (!aborting()) 22163 returning = do_return(eap, FALSE, TRUE, NULL); 22164 } 22165 22166 /* When skipping or the return gets pending, advance to the next command 22167 * in this line (!returning). Otherwise, ignore the rest of the line. 22168 * Following lines will be ignored by get_func_line(). */ 22169 if (returning) 22170 eap->nextcmd = NULL; 22171 else if (eap->nextcmd == NULL) /* no argument */ 22172 eap->nextcmd = check_nextcmd(arg); 22173 22174 if (eap->skip) 22175 --emsg_skip; 22176 } 22177 22178 /* 22179 * Return from a function. Possibly makes the return pending. Also called 22180 * for a pending return at the ":endtry" or after returning from an extra 22181 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 22182 * when called due to a ":return" command. "rettv" may point to a typval_T 22183 * with the return rettv. Returns TRUE when the return can be carried out, 22184 * FALSE when the return gets pending. 22185 */ 22186 int 22187 do_return(eap, reanimate, is_cmd, rettv) 22188 exarg_T *eap; 22189 int reanimate; 22190 int is_cmd; 22191 void *rettv; 22192 { 22193 int idx; 22194 struct condstack *cstack = eap->cstack; 22195 22196 if (reanimate) 22197 /* Undo the return. */ 22198 current_funccal->returned = FALSE; 22199 22200 /* 22201 * Cleanup (and inactivate) conditionals, but stop when a try conditional 22202 * not in its finally clause (which then is to be executed next) is found. 22203 * In this case, make the ":return" pending for execution at the ":endtry". 22204 * Otherwise, return normally. 22205 */ 22206 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 22207 if (idx >= 0) 22208 { 22209 cstack->cs_pending[idx] = CSTP_RETURN; 22210 22211 if (!is_cmd && !reanimate) 22212 /* A pending return again gets pending. "rettv" points to an 22213 * allocated variable with the rettv of the original ":return"'s 22214 * argument if present or is NULL else. */ 22215 cstack->cs_rettv[idx] = rettv; 22216 else 22217 { 22218 /* When undoing a return in order to make it pending, get the stored 22219 * return rettv. */ 22220 if (reanimate) 22221 rettv = current_funccal->rettv; 22222 22223 if (rettv != NULL) 22224 { 22225 /* Store the value of the pending return. */ 22226 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 22227 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 22228 else 22229 EMSG(_(e_outofmem)); 22230 } 22231 else 22232 cstack->cs_rettv[idx] = NULL; 22233 22234 if (reanimate) 22235 { 22236 /* The pending return value could be overwritten by a ":return" 22237 * without argument in a finally clause; reset the default 22238 * return value. */ 22239 current_funccal->rettv->v_type = VAR_NUMBER; 22240 current_funccal->rettv->vval.v_number = 0; 22241 } 22242 } 22243 report_make_pending(CSTP_RETURN, rettv); 22244 } 22245 else 22246 { 22247 current_funccal->returned = TRUE; 22248 22249 /* If the return is carried out now, store the return value. For 22250 * a return immediately after reanimation, the value is already 22251 * there. */ 22252 if (!reanimate && rettv != NULL) 22253 { 22254 clear_tv(current_funccal->rettv); 22255 *current_funccal->rettv = *(typval_T *)rettv; 22256 if (!is_cmd) 22257 vim_free(rettv); 22258 } 22259 } 22260 22261 return idx < 0; 22262 } 22263 22264 /* 22265 * Free the variable with a pending return value. 22266 */ 22267 void 22268 discard_pending_return(rettv) 22269 void *rettv; 22270 { 22271 free_tv((typval_T *)rettv); 22272 } 22273 22274 /* 22275 * Generate a return command for producing the value of "rettv". The result 22276 * is an allocated string. Used by report_pending() for verbose messages. 22277 */ 22278 char_u * 22279 get_return_cmd(rettv) 22280 void *rettv; 22281 { 22282 char_u *s = NULL; 22283 char_u *tofree = NULL; 22284 char_u numbuf[NUMBUFLEN]; 22285 22286 if (rettv != NULL) 22287 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 22288 if (s == NULL) 22289 s = (char_u *)""; 22290 22291 STRCPY(IObuff, ":return "); 22292 STRNCPY(IObuff + 8, s, IOSIZE - 8); 22293 if (STRLEN(s) + 8 >= IOSIZE) 22294 STRCPY(IObuff + IOSIZE - 4, "..."); 22295 vim_free(tofree); 22296 return vim_strsave(IObuff); 22297 } 22298 22299 /* 22300 * Get next function line. 22301 * Called by do_cmdline() to get the next line. 22302 * Returns allocated string, or NULL for end of function. 22303 */ 22304 char_u * 22305 get_func_line(c, cookie, indent) 22306 int c UNUSED; 22307 void *cookie; 22308 int indent UNUSED; 22309 { 22310 funccall_T *fcp = (funccall_T *)cookie; 22311 ufunc_T *fp = fcp->func; 22312 char_u *retval; 22313 garray_T *gap; /* growarray with function lines */ 22314 22315 /* If breakpoints have been added/deleted need to check for it. */ 22316 if (fcp->dbg_tick != debug_tick) 22317 { 22318 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 22319 sourcing_lnum); 22320 fcp->dbg_tick = debug_tick; 22321 } 22322 #ifdef FEAT_PROFILE 22323 if (do_profiling == PROF_YES) 22324 func_line_end(cookie); 22325 #endif 22326 22327 gap = &fp->uf_lines; 22328 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 22329 || fcp->returned) 22330 retval = NULL; 22331 else 22332 { 22333 /* Skip NULL lines (continuation lines). */ 22334 while (fcp->linenr < gap->ga_len 22335 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 22336 ++fcp->linenr; 22337 if (fcp->linenr >= gap->ga_len) 22338 retval = NULL; 22339 else 22340 { 22341 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 22342 sourcing_lnum = fcp->linenr; 22343 #ifdef FEAT_PROFILE 22344 if (do_profiling == PROF_YES) 22345 func_line_start(cookie); 22346 #endif 22347 } 22348 } 22349 22350 /* Did we encounter a breakpoint? */ 22351 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 22352 { 22353 dbg_breakpoint(fp->uf_name, sourcing_lnum); 22354 /* Find next breakpoint. */ 22355 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 22356 sourcing_lnum); 22357 fcp->dbg_tick = debug_tick; 22358 } 22359 22360 return retval; 22361 } 22362 22363 #if defined(FEAT_PROFILE) || defined(PROTO) 22364 /* 22365 * Called when starting to read a function line. 22366 * "sourcing_lnum" must be correct! 22367 * When skipping lines it may not actually be executed, but we won't find out 22368 * until later and we need to store the time now. 22369 */ 22370 void 22371 func_line_start(cookie) 22372 void *cookie; 22373 { 22374 funccall_T *fcp = (funccall_T *)cookie; 22375 ufunc_T *fp = fcp->func; 22376 22377 if (fp->uf_profiling && sourcing_lnum >= 1 22378 && sourcing_lnum <= fp->uf_lines.ga_len) 22379 { 22380 fp->uf_tml_idx = sourcing_lnum - 1; 22381 /* Skip continuation lines. */ 22382 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 22383 --fp->uf_tml_idx; 22384 fp->uf_tml_execed = FALSE; 22385 profile_start(&fp->uf_tml_start); 22386 profile_zero(&fp->uf_tml_children); 22387 profile_get_wait(&fp->uf_tml_wait); 22388 } 22389 } 22390 22391 /* 22392 * Called when actually executing a function line. 22393 */ 22394 void 22395 func_line_exec(cookie) 22396 void *cookie; 22397 { 22398 funccall_T *fcp = (funccall_T *)cookie; 22399 ufunc_T *fp = fcp->func; 22400 22401 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 22402 fp->uf_tml_execed = TRUE; 22403 } 22404 22405 /* 22406 * Called when done with a function line. 22407 */ 22408 void 22409 func_line_end(cookie) 22410 void *cookie; 22411 { 22412 funccall_T *fcp = (funccall_T *)cookie; 22413 ufunc_T *fp = fcp->func; 22414 22415 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 22416 { 22417 if (fp->uf_tml_execed) 22418 { 22419 ++fp->uf_tml_count[fp->uf_tml_idx]; 22420 profile_end(&fp->uf_tml_start); 22421 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 22422 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 22423 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 22424 &fp->uf_tml_children); 22425 } 22426 fp->uf_tml_idx = -1; 22427 } 22428 } 22429 #endif 22430 22431 /* 22432 * Return TRUE if the currently active function should be ended, because a 22433 * return was encountered or an error occurred. Used inside a ":while". 22434 */ 22435 int 22436 func_has_ended(cookie) 22437 void *cookie; 22438 { 22439 funccall_T *fcp = (funccall_T *)cookie; 22440 22441 /* Ignore the "abort" flag if the abortion behavior has been changed due to 22442 * an error inside a try conditional. */ 22443 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 22444 || fcp->returned); 22445 } 22446 22447 /* 22448 * return TRUE if cookie indicates a function which "abort"s on errors. 22449 */ 22450 int 22451 func_has_abort(cookie) 22452 void *cookie; 22453 { 22454 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 22455 } 22456 22457 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 22458 typedef enum 22459 { 22460 VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ 22461 VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ 22462 VAR_FLAVOUR_VIMINFO /* all uppercase */ 22463 } var_flavour_T; 22464 22465 static var_flavour_T var_flavour __ARGS((char_u *varname)); 22466 22467 static var_flavour_T 22468 var_flavour(varname) 22469 char_u *varname; 22470 { 22471 char_u *p = varname; 22472 22473 if (ASCII_ISUPPER(*p)) 22474 { 22475 while (*(++p)) 22476 if (ASCII_ISLOWER(*p)) 22477 return VAR_FLAVOUR_SESSION; 22478 return VAR_FLAVOUR_VIMINFO; 22479 } 22480 else 22481 return VAR_FLAVOUR_DEFAULT; 22482 } 22483 #endif 22484 22485 #if defined(FEAT_VIMINFO) || defined(PROTO) 22486 /* 22487 * Restore global vars that start with a capital from the viminfo file 22488 */ 22489 int 22490 read_viminfo_varlist(virp, writing) 22491 vir_T *virp; 22492 int writing; 22493 { 22494 char_u *tab; 22495 int type = VAR_NUMBER; 22496 typval_T tv; 22497 22498 if (!writing && (find_viminfo_parameter('!') != NULL)) 22499 { 22500 tab = vim_strchr(virp->vir_line + 1, '\t'); 22501 if (tab != NULL) 22502 { 22503 *tab++ = '\0'; /* isolate the variable name */ 22504 if (*tab == 'S') /* string var */ 22505 type = VAR_STRING; 22506 #ifdef FEAT_FLOAT 22507 else if (*tab == 'F') 22508 type = VAR_FLOAT; 22509 #endif 22510 22511 tab = vim_strchr(tab, '\t'); 22512 if (tab != NULL) 22513 { 22514 tv.v_type = type; 22515 if (type == VAR_STRING) 22516 tv.vval.v_string = viminfo_readstring(virp, 22517 (int)(tab - virp->vir_line + 1), TRUE); 22518 #ifdef FEAT_FLOAT 22519 else if (type == VAR_FLOAT) 22520 (void)string2float(tab + 1, &tv.vval.v_float); 22521 #endif 22522 else 22523 tv.vval.v_number = atol((char *)tab + 1); 22524 set_var(virp->vir_line + 1, &tv, FALSE); 22525 if (type == VAR_STRING) 22526 vim_free(tv.vval.v_string); 22527 } 22528 } 22529 } 22530 22531 return viminfo_readline(virp); 22532 } 22533 22534 /* 22535 * Write global vars that start with a capital to the viminfo file 22536 */ 22537 void 22538 write_viminfo_varlist(fp) 22539 FILE *fp; 22540 { 22541 hashitem_T *hi; 22542 dictitem_T *this_var; 22543 int todo; 22544 char *s; 22545 char_u *p; 22546 char_u *tofree; 22547 char_u numbuf[NUMBUFLEN]; 22548 22549 if (find_viminfo_parameter('!') == NULL) 22550 return; 22551 22552 fputs(_("\n# global variables:\n"), fp); 22553 22554 todo = (int)globvarht.ht_used; 22555 for (hi = globvarht.ht_array; todo > 0; ++hi) 22556 { 22557 if (!HASHITEM_EMPTY(hi)) 22558 { 22559 --todo; 22560 this_var = HI2DI(hi); 22561 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 22562 { 22563 switch (this_var->di_tv.v_type) 22564 { 22565 case VAR_STRING: s = "STR"; break; 22566 case VAR_NUMBER: s = "NUM"; break; 22567 #ifdef FEAT_FLOAT 22568 case VAR_FLOAT: s = "FLO"; break; 22569 #endif 22570 default: continue; 22571 } 22572 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 22573 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 22574 if (p != NULL) 22575 viminfo_writestring(fp, p); 22576 vim_free(tofree); 22577 } 22578 } 22579 } 22580 } 22581 #endif 22582 22583 #if defined(FEAT_SESSION) || defined(PROTO) 22584 int 22585 store_session_globals(fd) 22586 FILE *fd; 22587 { 22588 hashitem_T *hi; 22589 dictitem_T *this_var; 22590 int todo; 22591 char_u *p, *t; 22592 22593 todo = (int)globvarht.ht_used; 22594 for (hi = globvarht.ht_array; todo > 0; ++hi) 22595 { 22596 if (!HASHITEM_EMPTY(hi)) 22597 { 22598 --todo; 22599 this_var = HI2DI(hi); 22600 if ((this_var->di_tv.v_type == VAR_NUMBER 22601 || this_var->di_tv.v_type == VAR_STRING) 22602 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 22603 { 22604 /* Escape special characters with a backslash. Turn a LF and 22605 * CR into \n and \r. */ 22606 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 22607 (char_u *)"\\\"\n\r"); 22608 if (p == NULL) /* out of memory */ 22609 break; 22610 for (t = p; *t != NUL; ++t) 22611 if (*t == '\n') 22612 *t = 'n'; 22613 else if (*t == '\r') 22614 *t = 'r'; 22615 if ((fprintf(fd, "let %s = %c%s%c", 22616 this_var->di_key, 22617 (this_var->di_tv.v_type == VAR_STRING) ? '"' 22618 : ' ', 22619 p, 22620 (this_var->di_tv.v_type == VAR_STRING) ? '"' 22621 : ' ') < 0) 22622 || put_eol(fd) == FAIL) 22623 { 22624 vim_free(p); 22625 return FAIL; 22626 } 22627 vim_free(p); 22628 } 22629 #ifdef FEAT_FLOAT 22630 else if (this_var->di_tv.v_type == VAR_FLOAT 22631 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 22632 { 22633 float_T f = this_var->di_tv.vval.v_float; 22634 int sign = ' '; 22635 22636 if (f < 0) 22637 { 22638 f = -f; 22639 sign = '-'; 22640 } 22641 if ((fprintf(fd, "let %s = %c&%f", 22642 this_var->di_key, sign, f) < 0) 22643 || put_eol(fd) == FAIL) 22644 return FAIL; 22645 } 22646 #endif 22647 } 22648 } 22649 return OK; 22650 } 22651 #endif 22652 22653 /* 22654 * Display script name where an item was last set. 22655 * Should only be invoked when 'verbose' is non-zero. 22656 */ 22657 void 22658 last_set_msg(scriptID) 22659 scid_T scriptID; 22660 { 22661 char_u *p; 22662 22663 if (scriptID != 0) 22664 { 22665 p = home_replace_save(NULL, get_scriptname(scriptID)); 22666 if (p != NULL) 22667 { 22668 verbose_enter(); 22669 MSG_PUTS(_("\n\tLast set from ")); 22670 MSG_PUTS(p); 22671 vim_free(p); 22672 verbose_leave(); 22673 } 22674 } 22675 } 22676 22677 /* 22678 * List v:oldfiles in a nice way. 22679 */ 22680 void 22681 ex_oldfiles(eap) 22682 exarg_T *eap UNUSED; 22683 { 22684 list_T *l = vimvars[VV_OLDFILES].vv_list; 22685 listitem_T *li; 22686 int nr = 0; 22687 22688 if (l == NULL) 22689 msg((char_u *)_("No old files")); 22690 else 22691 { 22692 msg_start(); 22693 msg_scroll = TRUE; 22694 for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) 22695 { 22696 msg_outnum((long)++nr); 22697 MSG_PUTS(": "); 22698 msg_outtrans(get_tv_string(&li->li_tv)); 22699 msg_putchar('\n'); 22700 out_flush(); /* output one line at a time */ 22701 ui_breakcheck(); 22702 } 22703 /* Assume "got_int" was set to truncate the listing. */ 22704 got_int = FALSE; 22705 22706 #ifdef FEAT_BROWSE_CMD 22707 if (cmdmod.browse) 22708 { 22709 quit_more = FALSE; 22710 nr = prompt_for_number(FALSE); 22711 msg_starthere(); 22712 if (nr > 0) 22713 { 22714 char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES), 22715 (long)nr); 22716 22717 if (p != NULL) 22718 { 22719 p = expand_env_save(p); 22720 eap->arg = p; 22721 eap->cmdidx = CMD_edit; 22722 cmdmod.browse = FALSE; 22723 do_exedit(eap, NULL); 22724 vim_free(p); 22725 } 22726 } 22727 } 22728 #endif 22729 } 22730 } 22731 22732 #endif /* FEAT_EVAL */ 22733 22734 22735 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 22736 22737 #ifdef WIN3264 22738 /* 22739 * Functions for ":8" filename modifier: get 8.3 version of a filename. 22740 */ 22741 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 22742 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 22743 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 22744 22745 /* 22746 * Get the short path (8.3) for the filename in "fnamep". 22747 * Only works for a valid file name. 22748 * When the path gets longer "fnamep" is changed and the allocated buffer 22749 * is put in "bufp". 22750 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path. 22751 * Returns OK on success, FAIL on failure. 22752 */ 22753 static int 22754 get_short_pathname(fnamep, bufp, fnamelen) 22755 char_u **fnamep; 22756 char_u **bufp; 22757 int *fnamelen; 22758 { 22759 int l, len; 22760 char_u *newbuf; 22761 22762 len = *fnamelen; 22763 l = GetShortPathName(*fnamep, *fnamep, len); 22764 if (l > len - 1) 22765 { 22766 /* If that doesn't work (not enough space), then save the string 22767 * and try again with a new buffer big enough. */ 22768 newbuf = vim_strnsave(*fnamep, l); 22769 if (newbuf == NULL) 22770 return FAIL; 22771 22772 vim_free(*bufp); 22773 *fnamep = *bufp = newbuf; 22774 22775 /* Really should always succeed, as the buffer is big enough. */ 22776 l = GetShortPathName(*fnamep, *fnamep, l+1); 22777 } 22778 22779 *fnamelen = l; 22780 return OK; 22781 } 22782 22783 /* 22784 * Get the short path (8.3) for the filename in "fname". The converted 22785 * path is returned in "bufp". 22786 * 22787 * Some of the directories specified in "fname" may not exist. This function 22788 * will shorten the existing directories at the beginning of the path and then 22789 * append the remaining non-existing path. 22790 * 22791 * fname - Pointer to the filename to shorten. On return, contains the 22792 * pointer to the shortened pathname 22793 * bufp - Pointer to an allocated buffer for the filename. 22794 * fnamelen - Length of the filename pointed to by fname 22795 * 22796 * Returns OK on success (or nothing done) and FAIL on failure (out of memory). 22797 */ 22798 static int 22799 shortpath_for_invalid_fname(fname, bufp, fnamelen) 22800 char_u **fname; 22801 char_u **bufp; 22802 int *fnamelen; 22803 { 22804 char_u *short_fname, *save_fname, *pbuf_unused; 22805 char_u *endp, *save_endp; 22806 char_u ch; 22807 int old_len, len; 22808 int new_len, sfx_len; 22809 int retval = OK; 22810 22811 /* Make a copy */ 22812 old_len = *fnamelen; 22813 save_fname = vim_strnsave(*fname, old_len); 22814 pbuf_unused = NULL; 22815 short_fname = NULL; 22816 22817 endp = save_fname + old_len - 1; /* Find the end of the copy */ 22818 save_endp = endp; 22819 22820 /* 22821 * Try shortening the supplied path till it succeeds by removing one 22822 * directory at a time from the tail of the path. 22823 */ 22824 len = 0; 22825 for (;;) 22826 { 22827 /* go back one path-separator */ 22828 while (endp > save_fname && !after_pathsep(save_fname, endp + 1)) 22829 --endp; 22830 if (endp <= save_fname) 22831 break; /* processed the complete path */ 22832 22833 /* 22834 * Replace the path separator with a NUL and try to shorten the 22835 * resulting path. 22836 */ 22837 ch = *endp; 22838 *endp = 0; 22839 short_fname = save_fname; 22840 len = (int)STRLEN(short_fname) + 1; 22841 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL) 22842 { 22843 retval = FAIL; 22844 goto theend; 22845 } 22846 *endp = ch; /* preserve the string */ 22847 22848 if (len > 0) 22849 break; /* successfully shortened the path */ 22850 22851 /* failed to shorten the path. Skip the path separator */ 22852 --endp; 22853 } 22854 22855 if (len > 0) 22856 { 22857 /* 22858 * Succeeded in shortening the path. Now concatenate the shortened 22859 * path with the remaining path at the tail. 22860 */ 22861 22862 /* Compute the length of the new path. */ 22863 sfx_len = (int)(save_endp - endp) + 1; 22864 new_len = len + sfx_len; 22865 22866 *fnamelen = new_len; 22867 vim_free(*bufp); 22868 if (new_len > old_len) 22869 { 22870 /* There is not enough space in the currently allocated string, 22871 * copy it to a buffer big enough. */ 22872 *fname = *bufp = vim_strnsave(short_fname, new_len); 22873 if (*fname == NULL) 22874 { 22875 retval = FAIL; 22876 goto theend; 22877 } 22878 } 22879 else 22880 { 22881 /* Transfer short_fname to the main buffer (it's big enough), 22882 * unless get_short_pathname() did its work in-place. */ 22883 *fname = *bufp = save_fname; 22884 if (short_fname != save_fname) 22885 vim_strncpy(save_fname, short_fname, len); 22886 save_fname = NULL; 22887 } 22888 22889 /* concat the not-shortened part of the path */ 22890 vim_strncpy(*fname + len, endp, sfx_len); 22891 (*fname)[new_len] = NUL; 22892 } 22893 22894 theend: 22895 vim_free(pbuf_unused); 22896 vim_free(save_fname); 22897 22898 return retval; 22899 } 22900 22901 /* 22902 * Get a pathname for a partial path. 22903 * Returns OK for success, FAIL for failure. 22904 */ 22905 static int 22906 shortpath_for_partial(fnamep, bufp, fnamelen) 22907 char_u **fnamep; 22908 char_u **bufp; 22909 int *fnamelen; 22910 { 22911 int sepcount, len, tflen; 22912 char_u *p; 22913 char_u *pbuf, *tfname; 22914 int hasTilde; 22915 22916 /* Count up the path separators from the RHS.. so we know which part 22917 * of the path to return. */ 22918 sepcount = 0; 22919 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 22920 if (vim_ispathsep(*p)) 22921 ++sepcount; 22922 22923 /* Need full path first (use expand_env() to remove a "~/") */ 22924 hasTilde = (**fnamep == '~'); 22925 if (hasTilde) 22926 pbuf = tfname = expand_env_save(*fnamep); 22927 else 22928 pbuf = tfname = FullName_save(*fnamep, FALSE); 22929 22930 len = tflen = (int)STRLEN(tfname); 22931 22932 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) 22933 return FAIL; 22934 22935 if (len == 0) 22936 { 22937 /* Don't have a valid filename, so shorten the rest of the 22938 * path if we can. This CAN give us invalid 8.3 filenames, but 22939 * there's not a lot of point in guessing what it might be. 22940 */ 22941 len = tflen; 22942 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) 22943 return FAIL; 22944 } 22945 22946 /* Count the paths backward to find the beginning of the desired string. */ 22947 for (p = tfname + len - 1; p >= tfname; --p) 22948 { 22949 #ifdef FEAT_MBYTE 22950 if (has_mbyte) 22951 p -= mb_head_off(tfname, p); 22952 #endif 22953 if (vim_ispathsep(*p)) 22954 { 22955 if (sepcount == 0 || (hasTilde && sepcount == 1)) 22956 break; 22957 else 22958 sepcount --; 22959 } 22960 } 22961 if (hasTilde) 22962 { 22963 --p; 22964 if (p >= tfname) 22965 *p = '~'; 22966 else 22967 return FAIL; 22968 } 22969 else 22970 ++p; 22971 22972 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 22973 vim_free(*bufp); 22974 *fnamelen = (int)STRLEN(p); 22975 *bufp = pbuf; 22976 *fnamep = p; 22977 22978 return OK; 22979 } 22980 #endif /* WIN3264 */ 22981 22982 /* 22983 * Adjust a filename, according to a string of modifiers. 22984 * *fnamep must be NUL terminated when called. When returning, the length is 22985 * determined by *fnamelen. 22986 * Returns VALID_ flags or -1 for failure. 22987 * When there is an error, *fnamep is set to NULL. 22988 */ 22989 int 22990 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 22991 char_u *src; /* string with modifiers */ 22992 int *usedlen; /* characters after src that are used */ 22993 char_u **fnamep; /* file name so far */ 22994 char_u **bufp; /* buffer for allocated file name or NULL */ 22995 int *fnamelen; /* length of fnamep */ 22996 { 22997 int valid = 0; 22998 char_u *tail; 22999 char_u *s, *p, *pbuf; 23000 char_u dirname[MAXPATHL]; 23001 int c; 23002 int has_fullname = 0; 23003 #ifdef WIN3264 23004 int has_shortname = 0; 23005 #endif 23006 23007 repeat: 23008 /* ":p" - full path/file_name */ 23009 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 23010 { 23011 has_fullname = 1; 23012 23013 valid |= VALID_PATH; 23014 *usedlen += 2; 23015 23016 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 23017 if ((*fnamep)[0] == '~' 23018 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 23019 && ((*fnamep)[1] == '/' 23020 # ifdef BACKSLASH_IN_FILENAME 23021 || (*fnamep)[1] == '\\' 23022 # endif 23023 || (*fnamep)[1] == NUL) 23024 23025 #endif 23026 ) 23027 { 23028 *fnamep = expand_env_save(*fnamep); 23029 vim_free(*bufp); /* free any allocated file name */ 23030 *bufp = *fnamep; 23031 if (*fnamep == NULL) 23032 return -1; 23033 } 23034 23035 /* When "/." or "/.." is used: force expansion to get rid of it. */ 23036 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 23037 { 23038 if (vim_ispathsep(*p) 23039 && p[1] == '.' 23040 && (p[2] == NUL 23041 || vim_ispathsep(p[2]) 23042 || (p[2] == '.' 23043 && (p[3] == NUL || vim_ispathsep(p[3]))))) 23044 break; 23045 } 23046 23047 /* FullName_save() is slow, don't use it when not needed. */ 23048 if (*p != NUL || !vim_isAbsName(*fnamep)) 23049 { 23050 *fnamep = FullName_save(*fnamep, *p != NUL); 23051 vim_free(*bufp); /* free any allocated file name */ 23052 *bufp = *fnamep; 23053 if (*fnamep == NULL) 23054 return -1; 23055 } 23056 23057 /* Append a path separator to a directory. */ 23058 if (mch_isdir(*fnamep)) 23059 { 23060 /* Make room for one or two extra characters. */ 23061 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 23062 vim_free(*bufp); /* free any allocated file name */ 23063 *bufp = *fnamep; 23064 if (*fnamep == NULL) 23065 return -1; 23066 add_pathsep(*fnamep); 23067 } 23068 } 23069 23070 /* ":." - path relative to the current directory */ 23071 /* ":~" - path relative to the home directory */ 23072 /* ":8" - shortname path - postponed till after */ 23073 while (src[*usedlen] == ':' 23074 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 23075 { 23076 *usedlen += 2; 23077 if (c == '8') 23078 { 23079 #ifdef WIN3264 23080 has_shortname = 1; /* Postpone this. */ 23081 #endif 23082 continue; 23083 } 23084 pbuf = NULL; 23085 /* Need full path first (use expand_env() to remove a "~/") */ 23086 if (!has_fullname) 23087 { 23088 if (c == '.' && **fnamep == '~') 23089 p = pbuf = expand_env_save(*fnamep); 23090 else 23091 p = pbuf = FullName_save(*fnamep, FALSE); 23092 } 23093 else 23094 p = *fnamep; 23095 23096 has_fullname = 0; 23097 23098 if (p != NULL) 23099 { 23100 if (c == '.') 23101 { 23102 mch_dirname(dirname, MAXPATHL); 23103 s = shorten_fname(p, dirname); 23104 if (s != NULL) 23105 { 23106 *fnamep = s; 23107 if (pbuf != NULL) 23108 { 23109 vim_free(*bufp); /* free any allocated file name */ 23110 *bufp = pbuf; 23111 pbuf = NULL; 23112 } 23113 } 23114 } 23115 else 23116 { 23117 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 23118 /* Only replace it when it starts with '~' */ 23119 if (*dirname == '~') 23120 { 23121 s = vim_strsave(dirname); 23122 if (s != NULL) 23123 { 23124 *fnamep = s; 23125 vim_free(*bufp); 23126 *bufp = s; 23127 } 23128 } 23129 } 23130 vim_free(pbuf); 23131 } 23132 } 23133 23134 tail = gettail(*fnamep); 23135 *fnamelen = (int)STRLEN(*fnamep); 23136 23137 /* ":h" - head, remove "/file_name", can be repeated */ 23138 /* Don't remove the first "/" or "c:\" */ 23139 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 23140 { 23141 valid |= VALID_HEAD; 23142 *usedlen += 2; 23143 s = get_past_head(*fnamep); 23144 while (tail > s && after_pathsep(s, tail)) 23145 mb_ptr_back(*fnamep, tail); 23146 *fnamelen = (int)(tail - *fnamep); 23147 #ifdef VMS 23148 if (*fnamelen > 0) 23149 *fnamelen += 1; /* the path separator is part of the path */ 23150 #endif 23151 if (*fnamelen == 0) 23152 { 23153 /* Result is empty. Turn it into "." to make ":cd %:h" work. */ 23154 p = vim_strsave((char_u *)"."); 23155 if (p == NULL) 23156 return -1; 23157 vim_free(*bufp); 23158 *bufp = *fnamep = tail = p; 23159 *fnamelen = 1; 23160 } 23161 else 23162 { 23163 while (tail > s && !after_pathsep(s, tail)) 23164 mb_ptr_back(*fnamep, tail); 23165 } 23166 } 23167 23168 /* ":8" - shortname */ 23169 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 23170 { 23171 *usedlen += 2; 23172 #ifdef WIN3264 23173 has_shortname = 1; 23174 #endif 23175 } 23176 23177 #ifdef WIN3264 23178 /* Check shortname after we have done 'heads' and before we do 'tails' 23179 */ 23180 if (has_shortname) 23181 { 23182 pbuf = NULL; 23183 /* Copy the string if it is shortened by :h */ 23184 if (*fnamelen < (int)STRLEN(*fnamep)) 23185 { 23186 p = vim_strnsave(*fnamep, *fnamelen); 23187 if (p == 0) 23188 return -1; 23189 vim_free(*bufp); 23190 *bufp = *fnamep = p; 23191 } 23192 23193 /* Split into two implementations - makes it easier. First is where 23194 * there isn't a full name already, second is where there is. 23195 */ 23196 if (!has_fullname && !vim_isAbsName(*fnamep)) 23197 { 23198 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) 23199 return -1; 23200 } 23201 else 23202 { 23203 int l; 23204 23205 /* Simple case, already have the full-name 23206 * Nearly always shorter, so try first time. */ 23207 l = *fnamelen; 23208 if (get_short_pathname(fnamep, bufp, &l) == FAIL) 23209 return -1; 23210 23211 if (l == 0) 23212 { 23213 /* Couldn't find the filename.. search the paths. 23214 */ 23215 l = *fnamelen; 23216 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) 23217 return -1; 23218 } 23219 *fnamelen = l; 23220 } 23221 } 23222 #endif /* WIN3264 */ 23223 23224 /* ":t" - tail, just the basename */ 23225 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 23226 { 23227 *usedlen += 2; 23228 *fnamelen -= (int)(tail - *fnamep); 23229 *fnamep = tail; 23230 } 23231 23232 /* ":e" - extension, can be repeated */ 23233 /* ":r" - root, without extension, can be repeated */ 23234 while (src[*usedlen] == ':' 23235 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 23236 { 23237 /* find a '.' in the tail: 23238 * - for second :e: before the current fname 23239 * - otherwise: The last '.' 23240 */ 23241 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 23242 s = *fnamep - 2; 23243 else 23244 s = *fnamep + *fnamelen - 1; 23245 for ( ; s > tail; --s) 23246 if (s[0] == '.') 23247 break; 23248 if (src[*usedlen + 1] == 'e') /* :e */ 23249 { 23250 if (s > tail) 23251 { 23252 *fnamelen += (int)(*fnamep - (s + 1)); 23253 *fnamep = s + 1; 23254 #ifdef VMS 23255 /* cut version from the extension */ 23256 s = *fnamep + *fnamelen - 1; 23257 for ( ; s > *fnamep; --s) 23258 if (s[0] == ';') 23259 break; 23260 if (s > *fnamep) 23261 *fnamelen = s - *fnamep; 23262 #endif 23263 } 23264 else if (*fnamep <= tail) 23265 *fnamelen = 0; 23266 } 23267 else /* :r */ 23268 { 23269 if (s > tail) /* remove one extension */ 23270 *fnamelen = (int)(s - *fnamep); 23271 } 23272 *usedlen += 2; 23273 } 23274 23275 /* ":s?pat?foo?" - substitute */ 23276 /* ":gs?pat?foo?" - global substitute */ 23277 if (src[*usedlen] == ':' 23278 && (src[*usedlen + 1] == 's' 23279 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 23280 { 23281 char_u *str; 23282 char_u *pat; 23283 char_u *sub; 23284 int sep; 23285 char_u *flags; 23286 int didit = FALSE; 23287 23288 flags = (char_u *)""; 23289 s = src + *usedlen + 2; 23290 if (src[*usedlen + 1] == 'g') 23291 { 23292 flags = (char_u *)"g"; 23293 ++s; 23294 } 23295 23296 sep = *s++; 23297 if (sep) 23298 { 23299 /* find end of pattern */ 23300 p = vim_strchr(s, sep); 23301 if (p != NULL) 23302 { 23303 pat = vim_strnsave(s, (int)(p - s)); 23304 if (pat != NULL) 23305 { 23306 s = p + 1; 23307 /* find end of substitution */ 23308 p = vim_strchr(s, sep); 23309 if (p != NULL) 23310 { 23311 sub = vim_strnsave(s, (int)(p - s)); 23312 str = vim_strnsave(*fnamep, *fnamelen); 23313 if (sub != NULL && str != NULL) 23314 { 23315 *usedlen = (int)(p + 1 - src); 23316 s = do_string_sub(str, pat, sub, flags); 23317 if (s != NULL) 23318 { 23319 *fnamep = s; 23320 *fnamelen = (int)STRLEN(s); 23321 vim_free(*bufp); 23322 *bufp = s; 23323 didit = TRUE; 23324 } 23325 } 23326 vim_free(sub); 23327 vim_free(str); 23328 } 23329 vim_free(pat); 23330 } 23331 } 23332 /* after using ":s", repeat all the modifiers */ 23333 if (didit) 23334 goto repeat; 23335 } 23336 } 23337 23338 return valid; 23339 } 23340 23341 /* 23342 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 23343 * "flags" can be "g" to do a global substitute. 23344 * Returns an allocated string, NULL for error. 23345 */ 23346 char_u * 23347 do_string_sub(str, pat, sub, flags) 23348 char_u *str; 23349 char_u *pat; 23350 char_u *sub; 23351 char_u *flags; 23352 { 23353 int sublen; 23354 regmatch_T regmatch; 23355 int i; 23356 int do_all; 23357 char_u *tail; 23358 garray_T ga; 23359 char_u *ret; 23360 char_u *save_cpo; 23361 23362 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 23363 save_cpo = p_cpo; 23364 p_cpo = empty_option; 23365 23366 ga_init2(&ga, 1, 200); 23367 23368 do_all = (flags[0] == 'g'); 23369 23370 regmatch.rm_ic = p_ic; 23371 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 23372 if (regmatch.regprog != NULL) 23373 { 23374 tail = str; 23375 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 23376 { 23377 /* 23378 * Get some space for a temporary buffer to do the substitution 23379 * into. It will contain: 23380 * - The text up to where the match is. 23381 * - The substituted text. 23382 * - The text after the match. 23383 */ 23384 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 23385 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 23386 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 23387 { 23388 ga_clear(&ga); 23389 break; 23390 } 23391 23392 /* copy the text up to where the match is */ 23393 i = (int)(regmatch.startp[0] - tail); 23394 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 23395 /* add the substituted text */ 23396 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 23397 + ga.ga_len + i, TRUE, TRUE, FALSE); 23398 ga.ga_len += i + sublen - 1; 23399 /* avoid getting stuck on a match with an empty string */ 23400 if (tail == regmatch.endp[0]) 23401 { 23402 if (*tail == NUL) 23403 break; 23404 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 23405 ++ga.ga_len; 23406 } 23407 else 23408 { 23409 tail = regmatch.endp[0]; 23410 if (*tail == NUL) 23411 break; 23412 } 23413 if (!do_all) 23414 break; 23415 } 23416 23417 if (ga.ga_data != NULL) 23418 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 23419 23420 vim_free(regmatch.regprog); 23421 } 23422 23423 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 23424 ga_clear(&ga); 23425 if (p_cpo == empty_option) 23426 p_cpo = save_cpo; 23427 else 23428 /* Darn, evaluating {sub} expression changed the value. */ 23429 free_string_option(save_cpo); 23430 23431 return ret; 23432 } 23433 23434 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 23435