1 /* vi:set ts=8 sts=4 sw=4: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * eval.c: Expression evaluation. 12 */ 13 #if defined(MSDOS) || defined(MSWIN) 14 # include "vimio.h" /* for mch_open(), must be before vim.h */ 15 #endif 16 17 #include "vim.h" 18 19 #ifdef AMIGA 20 # include <time.h> /* for strftime() */ 21 #endif 22 23 #ifdef MACOS 24 # include <time.h> /* for time_t */ 25 #endif 26 27 #ifdef HAVE_FCNTL_H 28 # include <fcntl.h> 29 #endif 30 31 #if defined(FEAT_EVAL) || defined(PROTO) 32 33 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ 34 35 /* 36 * In a hashtab item "hi_key" points to "di_key" in a dictitem. 37 * This avoids adding a pointer to the hashtab item. 38 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. 39 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. 40 * HI2DI() converts a hashitem pointer to a dictitem pointer. 41 */ 42 static dictitem_T dumdi; 43 #define DI2HIKEY(di) ((di)->di_key) 44 #define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) 45 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) 46 47 /* 48 * Structure returned by get_lval() and used by set_var_lval(). 49 * For a plain name: 50 * "name" points to the variable name. 51 * "exp_name" is NULL. 52 * "tv" is NULL 53 * For a magic braces name: 54 * "name" points to the expanded variable name. 55 * "exp_name" is non-NULL, to be freed later. 56 * "tv" is NULL 57 * For an index in a list: 58 * "name" points to the (expanded) variable name. 59 * "exp_name" NULL or non-NULL, to be freed later. 60 * "tv" points to the (first) list item value 61 * "li" points to the (first) list item 62 * "range", "n1", "n2" and "empty2" indicate what items are used. 63 * For an existing Dict item: 64 * "name" points to the (expanded) variable name. 65 * "exp_name" NULL or non-NULL, to be freed later. 66 * "tv" points to the dict item value 67 * "newkey" is NULL 68 * For a non-existing Dict item: 69 * "name" points to the (expanded) variable name. 70 * "exp_name" NULL or non-NULL, to be freed later. 71 * "tv" points to the Dictionary typval_T 72 * "newkey" is the key for the new item. 73 */ 74 typedef struct lval_S 75 { 76 char_u *ll_name; /* start of variable name (can be NULL) */ 77 char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ 78 typval_T *ll_tv; /* Typeval of item being used. If "newkey" 79 isn't NULL it's the Dict to which to add 80 the item. */ 81 listitem_T *ll_li; /* The list item or NULL. */ 82 list_T *ll_list; /* The list or NULL. */ 83 int ll_range; /* TRUE when a [i:j] range was used */ 84 long ll_n1; /* First index for list */ 85 long ll_n2; /* Second index for list range */ 86 int ll_empty2; /* Second index is empty: [i:] */ 87 dict_T *ll_dict; /* The Dictionary or NULL */ 88 dictitem_T *ll_di; /* The dictitem or NULL */ 89 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 90 } lval_T; 91 92 93 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 94 static char *e_listidx = N_("E684: list index out of range: %ld"); 95 static char *e_undefvar = N_("E121: Undefined variable: %s"); 96 static char *e_missbrac = N_("E111: Missing ']'"); 97 static char *e_listarg = N_("E686: Argument of %s must be a List"); 98 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); 99 static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary"); 100 static char *e_listreq = N_("E714: List required"); 101 static char *e_dictreq = N_("E715: Dictionary required"); 102 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 103 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 104 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 105 static char *e_funcdict = N_("E717: Dictionary entry already exists"); 106 static char *e_funcref = N_("E718: Funcref required"); 107 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 108 static char *e_letwrong = N_("E734: Wrong variable type for %s="); 109 static char *e_nofunc = N_("E130: Unknown function: %s"); 110 static char *e_illvar = N_("E461: Illegal variable name: %s"); 111 /* 112 * All user-defined global variables are stored in dictionary "globvardict". 113 * "globvars_var" is the variable that is used for "g:". 114 */ 115 static dict_T globvardict; 116 static dictitem_T globvars_var; 117 #define globvarht globvardict.dv_hashtab 118 119 /* 120 * Old Vim variables such as "v:version" are also available without the "v:". 121 * Also in functions. We need a special hashtable for them. 122 */ 123 static hashtab_T compat_hashtab; 124 125 /* 126 * When recursively copying lists and dicts we need to remember which ones we 127 * have done to avoid endless recursiveness. This unique ID is used for that. 128 */ 129 static int current_copyID = 0; 130 131 /* 132 * Array to hold the hashtab with variables local to each sourced script. 133 * Each item holds a variable (nameless) that points to the dict_T. 134 */ 135 typedef struct 136 { 137 dictitem_T sv_var; 138 dict_T sv_dict; 139 } scriptvar_T; 140 141 static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T), 4, NULL}; 142 #define SCRIPT_SV(id) (((scriptvar_T *)ga_scripts.ga_data)[(id) - 1]) 143 #define SCRIPT_VARS(id) (SCRIPT_SV(id).sv_dict.dv_hashtab) 144 145 static int echo_attr = 0; /* attributes used for ":echo" */ 146 147 /* Values for trans_function_name() argument: */ 148 #define TFN_INT 1 /* internal function name OK */ 149 #define TFN_QUIET 2 /* no error messages */ 150 151 /* 152 * Structure to hold info for a user function. 153 */ 154 typedef struct ufunc ufunc_T; 155 156 struct ufunc 157 { 158 int uf_varargs; /* variable nr of arguments */ 159 int uf_flags; 160 int uf_calls; /* nr of active calls */ 161 garray_T uf_args; /* arguments */ 162 garray_T uf_lines; /* function lines */ 163 #ifdef FEAT_PROFILE 164 int uf_profiling; /* TRUE when func is being profiled */ 165 /* profiling the function as a whole */ 166 int uf_tm_count; /* nr of calls */ 167 proftime_T uf_tm_total; /* time spend in function + children */ 168 proftime_T uf_tm_self; /* time spend in function itself */ 169 proftime_T uf_tm_start; /* time at function call */ 170 proftime_T uf_tm_children; /* time spent in children this call */ 171 /* profiling the function per line */ 172 int *uf_tml_count; /* nr of times line was executed */ 173 proftime_T *uf_tml_total; /* time spend in a line + children */ 174 proftime_T *uf_tml_self; /* time spend in a line itself */ 175 proftime_T uf_tml_start; /* start time for current line */ 176 proftime_T uf_tml_children; /* time spent in children for this line */ 177 proftime_T uf_tml_wait; /* start wait time for current line */ 178 int uf_tml_idx; /* index of line being timed; -1 if none */ 179 int uf_tml_execed; /* line being timed was executed */ 180 #endif 181 scid_T uf_script_ID; /* ID of script where function was defined, 182 used for s: variables */ 183 int uf_refcount; /* for numbered function: reference count */ 184 char_u uf_name[1]; /* name of function (actually longer); can 185 start with <SNR>123_ (<SNR> is K_SPECIAL 186 KS_EXTRA KE_SNR) */ 187 }; 188 189 /* function flags */ 190 #define FC_ABORT 1 /* abort function on error */ 191 #define FC_RANGE 2 /* function accepts range */ 192 #define FC_DICT 4 /* Dict function, uses "self" */ 193 194 #define DEL_REFCOUNT 999999 /* list/dict is being deleted */ 195 196 /* 197 * All user-defined functions are found in this hashtable. 198 */ 199 static hashtab_T func_hashtab; 200 201 /* list heads for garbage collection */ 202 static dict_T *first_dict = NULL; /* list of all dicts */ 203 static list_T *first_list = NULL; /* list of all lists */ 204 205 /* From user function to hashitem and back. */ 206 static ufunc_T dumuf; 207 #define UF2HIKEY(fp) ((fp)->uf_name) 208 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 209 #define HI2UF(hi) HIKEY2UF((hi)->hi_key) 210 211 #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 212 #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 213 214 #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 215 #define VAR_SHORT_LEN 20 /* short variable name length */ 216 #define FIXVAR_CNT 12 /* number of fixed variables */ 217 218 /* structure to hold info for a function that is currently being executed. */ 219 typedef struct funccall_S funccall_T; 220 221 struct funccall_S 222 { 223 ufunc_T *func; /* function being called */ 224 int linenr; /* next line to be executed */ 225 int returned; /* ":return" used */ 226 struct /* fixed variables for arguments */ 227 { 228 dictitem_T var; /* variable (without room for name) */ 229 char_u room[VAR_SHORT_LEN]; /* room for the name */ 230 } fixvar[FIXVAR_CNT]; 231 dict_T l_vars; /* l: local function variables */ 232 dictitem_T l_vars_var; /* variable for l: scope */ 233 dict_T l_avars; /* a: argument variables */ 234 dictitem_T l_avars_var; /* variable for a: scope */ 235 list_T l_varlist; /* list for a:000 */ 236 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 237 typval_T *rettv; /* return value */ 238 linenr_T breakpoint; /* next line with breakpoint or zero */ 239 int dbg_tick; /* debug_tick when breakpoint was set */ 240 int level; /* top nesting level of executed function */ 241 #ifdef FEAT_PROFILE 242 proftime_T prof_child; /* time spent in a child */ 243 #endif 244 funccall_T *caller; /* calling function or NULL */ 245 }; 246 247 /* 248 * Info used by a ":for" loop. 249 */ 250 typedef struct 251 { 252 int fi_semicolon; /* TRUE if ending in '; var]' */ 253 int fi_varcount; /* nr of variables in the list */ 254 listwatch_T fi_lw; /* keep an eye on the item used. */ 255 list_T *fi_list; /* list being used */ 256 } forinfo_T; 257 258 /* 259 * Struct used by trans_function_name() 260 */ 261 typedef struct 262 { 263 dict_T *fd_dict; /* Dictionary used */ 264 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 265 dictitem_T *fd_di; /* Dictionary item used */ 266 } funcdict_T; 267 268 269 /* 270 * Array to hold the value of v: variables. 271 * The value is in a dictitem, so that it can also be used in the v: scope. 272 * The reason to use this table anyway is for very quick access to the 273 * variables with the VV_ defines. 274 */ 275 #include "version.h" 276 277 /* values for vv_flags: */ 278 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 279 #define VV_RO 2 /* read-only */ 280 #define VV_RO_SBX 4 /* read-only in the sandbox */ 281 282 #define VV_NAME(s, t) s, {{t}}, {0} 283 284 static struct vimvar 285 { 286 char *vv_name; /* name of variable, without v: */ 287 dictitem_T vv_di; /* value and name for key */ 288 char vv_filler[16]; /* space for LONGEST name below!!! */ 289 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 290 } vimvars[VV_LEN] = 291 { 292 /* 293 * The order here must match the VV_ defines in vim.h! 294 * Initializing a union does not work, leave tv.vval empty to get zero's. 295 */ 296 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 297 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 298 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 299 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 300 {VV_NAME("warningmsg", VAR_STRING), 0}, 301 {VV_NAME("statusmsg", VAR_STRING), 0}, 302 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 303 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 304 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 305 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 306 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 307 {VV_NAME("fname", VAR_STRING), VV_RO}, 308 {VV_NAME("lang", VAR_STRING), VV_RO}, 309 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 310 {VV_NAME("ctype", VAR_STRING), VV_RO}, 311 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 312 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 313 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 314 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 315 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 316 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 317 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 318 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 319 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 320 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 321 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 322 {VV_NAME("progname", VAR_STRING), VV_RO}, 323 {VV_NAME("servername", VAR_STRING), VV_RO}, 324 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 325 {VV_NAME("exception", VAR_STRING), VV_RO}, 326 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 327 {VV_NAME("register", VAR_STRING), VV_RO}, 328 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 329 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 330 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 331 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 332 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 333 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 334 {VV_NAME("fcs_choice", VAR_STRING), 0}, 335 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 336 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 337 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 338 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 339 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 340 {VV_NAME("scrollstart", VAR_STRING), 0}, 341 {VV_NAME("swapname", VAR_STRING), VV_RO}, 342 {VV_NAME("swapchoice", VAR_STRING), 0}, 343 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 344 }; 345 346 /* shorthand */ 347 #define vv_type vv_di.di_tv.v_type 348 #define vv_nr vv_di.di_tv.vval.v_number 349 #define vv_str vv_di.di_tv.vval.v_string 350 #define vv_tv vv_di.di_tv 351 352 /* 353 * The v: variables are stored in dictionary "vimvardict". 354 * "vimvars_var" is the variable that is used for the "l:" scope. 355 */ 356 static dict_T vimvardict; 357 static dictitem_T vimvars_var; 358 #define vimvarht vimvardict.dv_hashtab 359 360 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 361 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 362 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 363 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 364 #endif 365 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 366 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 367 static char_u *skip_var_one __ARGS((char_u *arg)); 368 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 369 static void list_glob_vars __ARGS((void)); 370 static void list_buf_vars __ARGS((void)); 371 static void list_win_vars __ARGS((void)); 372 static void list_vim_vars __ARGS((void)); 373 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 374 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 375 static int check_changedtick __ARGS((char_u *arg)); 376 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 377 static void clear_lval __ARGS((lval_T *lp)); 378 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 379 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 380 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 381 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 382 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 383 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 384 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 385 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 386 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 387 static int tv_islocked __ARGS((typval_T *tv)); 388 389 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 390 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 391 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 392 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 393 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 394 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 395 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 396 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 397 398 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 399 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 400 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 401 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 402 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 403 static int rettv_list_alloc __ARGS((typval_T *rettv)); 404 static listitem_T *listitem_alloc __ARGS((void)); 405 static void listitem_free __ARGS((listitem_T *item)); 406 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 407 static long list_len __ARGS((list_T *l)); 408 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 409 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 410 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 411 static listitem_T *list_find __ARGS((list_T *l, long n)); 412 static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); 413 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 414 static void list_append __ARGS((list_T *l, listitem_T *item)); 415 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 416 static int list_append_string __ARGS((list_T *l, char_u *str, int len)); 417 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 418 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 419 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 420 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 421 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 422 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 423 static char_u *list2string __ARGS((typval_T *tv, int copyID)); 424 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 425 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 426 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 427 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 428 static void dict_unref __ARGS((dict_T *d)); 429 static void dict_free __ARGS((dict_T *d)); 430 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 431 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 432 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 433 static void dictitem_free __ARGS((dictitem_T *item)); 434 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 435 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 436 static long dict_len __ARGS((dict_T *d)); 437 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 438 static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 439 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 440 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 441 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 442 static char_u *string_quote __ARGS((char_u *str, int function)); 443 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 444 static int find_internal_func __ARGS((char_u *name)); 445 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 446 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)); 447 static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 448 static void emsg_funcname __ARGS((char *msg, char_u *name)); 449 450 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 468 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 469 #if defined(FEAT_INS_EXPAND) 470 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 472 #endif 473 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 478 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 571 #ifdef vim_mkdir 572 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 573 #endif 574 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 613 #ifdef HAVE_STRFTIME 614 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 615 #endif 616 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 636 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 637 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 640 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 641 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 642 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 643 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 644 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 645 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 646 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 647 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 648 static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 649 static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 650 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 651 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 652 653 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); 654 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum)); 655 static int get_env_len __ARGS((char_u **arg)); 656 static int get_id_len __ARGS((char_u **arg)); 657 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 658 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 659 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 660 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 661 valid character */ 662 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 663 static int eval_isnamec __ARGS((int c)); 664 static int eval_isnamec1 __ARGS((int c)); 665 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 666 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 667 static typval_T *alloc_tv __ARGS((void)); 668 static typval_T *alloc_string_tv __ARGS((char_u *string)); 669 static void init_tv __ARGS((typval_T *varp)); 670 static long get_tv_number __ARGS((typval_T *varp)); 671 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 672 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 673 static char_u *get_tv_string __ARGS((typval_T *varp)); 674 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 675 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 676 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 677 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 678 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 679 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 680 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 681 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 682 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 683 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 684 static int var_check_ro __ARGS((int flags, char_u *name)); 685 static int tv_check_lock __ARGS((int lock, char_u *name)); 686 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 687 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 688 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 689 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 690 static int eval_fname_script __ARGS((char_u *p)); 691 static int eval_fname_sid __ARGS((char_u *p)); 692 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 693 static ufunc_T *find_func __ARGS((char_u *name)); 694 static int function_exists __ARGS((char_u *name)); 695 static int builtin_function __ARGS((char_u *name)); 696 #ifdef FEAT_PROFILE 697 static void func_do_profile __ARGS((ufunc_T *fp)); 698 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 699 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 700 static int 701 # ifdef __BORLANDC__ 702 _RTLENTRYF 703 # endif 704 prof_total_cmp __ARGS((const void *s1, const void *s2)); 705 static int 706 # ifdef __BORLANDC__ 707 _RTLENTRYF 708 # endif 709 prof_self_cmp __ARGS((const void *s1, const void *s2)); 710 #endif 711 static int script_autoload __ARGS((char_u *name, int reload)); 712 static char_u *autoload_name __ARGS((char_u *name)); 713 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 714 static void func_free __ARGS((ufunc_T *fp)); 715 static void func_unref __ARGS((char_u *name)); 716 static void func_ref __ARGS((char_u *name)); 717 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)); 718 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 719 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 720 static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 721 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 722 723 /* Character used as separated in autoload function/variable names. */ 724 #define AUTOLOAD_CHAR '#' 725 726 /* 727 * Initialize the global and v: variables. 728 */ 729 void 730 eval_init() 731 { 732 int i; 733 struct vimvar *p; 734 735 init_var_dict(&globvardict, &globvars_var); 736 init_var_dict(&vimvardict, &vimvars_var); 737 hash_init(&compat_hashtab); 738 hash_init(&func_hashtab); 739 740 for (i = 0; i < VV_LEN; ++i) 741 { 742 p = &vimvars[i]; 743 STRCPY(p->vv_di.di_key, p->vv_name); 744 if (p->vv_flags & VV_RO) 745 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 746 else if (p->vv_flags & VV_RO_SBX) 747 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 748 else 749 p->vv_di.di_flags = DI_FLAGS_FIX; 750 751 /* add to v: scope dict, unless the value is not always available */ 752 if (p->vv_type != VAR_UNKNOWN) 753 hash_add(&vimvarht, p->vv_di.di_key); 754 if (p->vv_flags & VV_COMPAT) 755 /* add to compat scope dict */ 756 hash_add(&compat_hashtab, p->vv_di.di_key); 757 } 758 } 759 760 #if defined(EXITFREE) || defined(PROTO) 761 void 762 eval_clear() 763 { 764 int i; 765 struct vimvar *p; 766 767 for (i = 0; i < VV_LEN; ++i) 768 { 769 p = &vimvars[i]; 770 if (p->vv_di.di_tv.v_type == VAR_STRING) 771 { 772 vim_free(p->vv_di.di_tv.vval.v_string); 773 p->vv_di.di_tv.vval.v_string = NULL; 774 } 775 } 776 hash_clear(&vimvarht); 777 hash_clear(&compat_hashtab); 778 779 /* script-local variables */ 780 for (i = 1; i <= ga_scripts.ga_len; ++i) 781 vars_clear(&SCRIPT_VARS(i)); 782 ga_clear(&ga_scripts); 783 free_scriptnames(); 784 785 /* global variables */ 786 vars_clear(&globvarht); 787 788 /* functions */ 789 free_all_functions(); 790 hash_clear(&func_hashtab); 791 792 /* unreferenced lists and dicts */ 793 (void)garbage_collect(); 794 } 795 #endif 796 797 /* 798 * Return the name of the executed function. 799 */ 800 char_u * 801 func_name(cookie) 802 void *cookie; 803 { 804 return ((funccall_T *)cookie)->func->uf_name; 805 } 806 807 /* 808 * Return the address holding the next breakpoint line for a funccall cookie. 809 */ 810 linenr_T * 811 func_breakpoint(cookie) 812 void *cookie; 813 { 814 return &((funccall_T *)cookie)->breakpoint; 815 } 816 817 /* 818 * Return the address holding the debug tick for a funccall cookie. 819 */ 820 int * 821 func_dbg_tick(cookie) 822 void *cookie; 823 { 824 return &((funccall_T *)cookie)->dbg_tick; 825 } 826 827 /* 828 * Return the nesting level for a funccall cookie. 829 */ 830 int 831 func_level(cookie) 832 void *cookie; 833 { 834 return ((funccall_T *)cookie)->level; 835 } 836 837 /* pointer to funccal for currently active function */ 838 funccall_T *current_funccal = NULL; 839 840 /* 841 * Return TRUE when a function was ended by a ":return" command. 842 */ 843 int 844 current_func_returned() 845 { 846 return current_funccal->returned; 847 } 848 849 850 /* 851 * Set an internal variable to a string value. Creates the variable if it does 852 * not already exist. 853 */ 854 void 855 set_internal_string_var(name, value) 856 char_u *name; 857 char_u *value; 858 { 859 char_u *val; 860 typval_T *tvp; 861 862 val = vim_strsave(value); 863 if (val != NULL) 864 { 865 tvp = alloc_string_tv(val); 866 if (tvp != NULL) 867 { 868 set_var(name, tvp, FALSE); 869 free_tv(tvp); 870 } 871 } 872 } 873 874 static lval_T *redir_lval = NULL; 875 static char_u *redir_endp = NULL; 876 static char_u *redir_varname = NULL; 877 878 /* 879 * Start recording command output to a variable 880 * Returns OK if successfully completed the setup. FAIL otherwise. 881 */ 882 int 883 var_redir_start(name, append) 884 char_u *name; 885 int append; /* append to an existing variable */ 886 { 887 int save_emsg; 888 int err; 889 typval_T tv; 890 891 /* Make sure a valid variable name is specified */ 892 if (!eval_isnamec1(*name)) 893 { 894 EMSG(_(e_invarg)); 895 return FAIL; 896 } 897 898 redir_varname = vim_strsave(name); 899 if (redir_varname == NULL) 900 return FAIL; 901 902 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 903 if (redir_lval == NULL) 904 { 905 var_redir_stop(); 906 return FAIL; 907 } 908 909 /* Parse the variable name (can be a dict or list entry). */ 910 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 911 FNE_CHECK_START); 912 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 913 { 914 if (redir_endp != NULL && *redir_endp != NUL) 915 /* Trailing characters are present after the variable name */ 916 EMSG(_(e_trailing)); 917 else 918 EMSG(_(e_invarg)); 919 var_redir_stop(); 920 return FAIL; 921 } 922 923 /* check if we can write to the variable: set it to or append an empty 924 * string */ 925 save_emsg = did_emsg; 926 did_emsg = FALSE; 927 tv.v_type = VAR_STRING; 928 tv.vval.v_string = (char_u *)""; 929 if (append) 930 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 931 else 932 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 933 err = did_emsg; 934 did_emsg |= save_emsg; 935 if (err) 936 { 937 var_redir_stop(); 938 return FAIL; 939 } 940 if (redir_lval->ll_newkey != NULL) 941 { 942 /* Dictionary item was created, don't do it again. */ 943 vim_free(redir_lval->ll_newkey); 944 redir_lval->ll_newkey = NULL; 945 } 946 947 return OK; 948 } 949 950 /* 951 * Append "value[len]" to the variable set by var_redir_start(). 952 */ 953 void 954 var_redir_str(value, len) 955 char_u *value; 956 int len; 957 { 958 char_u *val; 959 typval_T tv; 960 int save_emsg; 961 int err; 962 963 if (redir_lval == NULL) 964 return; 965 966 if (len == -1) 967 /* Append the entire string */ 968 val = vim_strsave(value); 969 else 970 /* Append only the specified number of characters */ 971 val = vim_strnsave(value, len); 972 if (val == NULL) 973 return; 974 975 tv.v_type = VAR_STRING; 976 tv.vval.v_string = val; 977 978 save_emsg = did_emsg; 979 did_emsg = FALSE; 980 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 981 err = did_emsg; 982 did_emsg |= save_emsg; 983 if (err) 984 var_redir_stop(); 985 986 vim_free(tv.vval.v_string); 987 } 988 989 /* 990 * Stop redirecting command output to a variable. 991 */ 992 void 993 var_redir_stop() 994 { 995 if (redir_lval != NULL) 996 { 997 clear_lval(redir_lval); 998 vim_free(redir_lval); 999 redir_lval = NULL; 1000 } 1001 vim_free(redir_varname); 1002 redir_varname = NULL; 1003 } 1004 1005 # if defined(FEAT_MBYTE) || defined(PROTO) 1006 int 1007 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1008 char_u *enc_from; 1009 char_u *enc_to; 1010 char_u *fname_from; 1011 char_u *fname_to; 1012 { 1013 int err = FALSE; 1014 1015 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1016 set_vim_var_string(VV_CC_TO, enc_to, -1); 1017 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1018 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1019 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1020 err = TRUE; 1021 set_vim_var_string(VV_CC_FROM, NULL, -1); 1022 set_vim_var_string(VV_CC_TO, NULL, -1); 1023 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1024 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1025 1026 if (err) 1027 return FAIL; 1028 return OK; 1029 } 1030 # endif 1031 1032 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1033 int 1034 eval_printexpr(fname, args) 1035 char_u *fname; 1036 char_u *args; 1037 { 1038 int err = FALSE; 1039 1040 set_vim_var_string(VV_FNAME_IN, fname, -1); 1041 set_vim_var_string(VV_CMDARG, args, -1); 1042 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1043 err = TRUE; 1044 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1045 set_vim_var_string(VV_CMDARG, NULL, -1); 1046 1047 if (err) 1048 { 1049 mch_remove(fname); 1050 return FAIL; 1051 } 1052 return OK; 1053 } 1054 # endif 1055 1056 # if defined(FEAT_DIFF) || defined(PROTO) 1057 void 1058 eval_diff(origfile, newfile, outfile) 1059 char_u *origfile; 1060 char_u *newfile; 1061 char_u *outfile; 1062 { 1063 int err = FALSE; 1064 1065 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1066 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1067 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1068 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1069 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1070 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1071 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1072 } 1073 1074 void 1075 eval_patch(origfile, difffile, outfile) 1076 char_u *origfile; 1077 char_u *difffile; 1078 char_u *outfile; 1079 { 1080 int err; 1081 1082 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1083 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1084 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1085 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1086 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1087 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1088 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1089 } 1090 # endif 1091 1092 /* 1093 * Top level evaluation function, returning a boolean. 1094 * Sets "error" to TRUE if there was an error. 1095 * Return TRUE or FALSE. 1096 */ 1097 int 1098 eval_to_bool(arg, error, nextcmd, skip) 1099 char_u *arg; 1100 int *error; 1101 char_u **nextcmd; 1102 int skip; /* only parse, don't execute */ 1103 { 1104 typval_T tv; 1105 int retval = FALSE; 1106 1107 if (skip) 1108 ++emsg_skip; 1109 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1110 *error = TRUE; 1111 else 1112 { 1113 *error = FALSE; 1114 if (!skip) 1115 { 1116 retval = (get_tv_number_chk(&tv, error) != 0); 1117 clear_tv(&tv); 1118 } 1119 } 1120 if (skip) 1121 --emsg_skip; 1122 1123 return retval; 1124 } 1125 1126 /* 1127 * Top level evaluation function, returning a string. If "skip" is TRUE, 1128 * only parsing to "nextcmd" is done, without reporting errors. Return 1129 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1130 */ 1131 char_u * 1132 eval_to_string_skip(arg, nextcmd, skip) 1133 char_u *arg; 1134 char_u **nextcmd; 1135 int skip; /* only parse, don't execute */ 1136 { 1137 typval_T tv; 1138 char_u *retval; 1139 1140 if (skip) 1141 ++emsg_skip; 1142 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1143 retval = NULL; 1144 else 1145 { 1146 retval = vim_strsave(get_tv_string(&tv)); 1147 clear_tv(&tv); 1148 } 1149 if (skip) 1150 --emsg_skip; 1151 1152 return retval; 1153 } 1154 1155 /* 1156 * Skip over an expression at "*pp". 1157 * Return FAIL for an error, OK otherwise. 1158 */ 1159 int 1160 skip_expr(pp) 1161 char_u **pp; 1162 { 1163 typval_T rettv; 1164 1165 *pp = skipwhite(*pp); 1166 return eval1(pp, &rettv, FALSE); 1167 } 1168 1169 /* 1170 * Top level evaluation function, returning a string. 1171 * Return pointer to allocated memory, or NULL for failure. 1172 */ 1173 char_u * 1174 eval_to_string(arg, nextcmd, dolist) 1175 char_u *arg; 1176 char_u **nextcmd; 1177 int dolist; /* turn List into sequence of lines */ 1178 { 1179 typval_T tv; 1180 char_u *retval; 1181 garray_T ga; 1182 1183 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1184 retval = NULL; 1185 else 1186 { 1187 if (dolist && tv.v_type == VAR_LIST) 1188 { 1189 ga_init2(&ga, (int)sizeof(char), 80); 1190 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1191 ga_append(&ga, NUL); 1192 retval = (char_u *)ga.ga_data; 1193 } 1194 else 1195 retval = vim_strsave(get_tv_string(&tv)); 1196 clear_tv(&tv); 1197 } 1198 1199 return retval; 1200 } 1201 1202 /* 1203 * Call eval_to_string() without using current local variables and using 1204 * textlock. When "use_sandbox" is TRUE use the sandbox. 1205 */ 1206 char_u * 1207 eval_to_string_safe(arg, nextcmd, use_sandbox) 1208 char_u *arg; 1209 char_u **nextcmd; 1210 int use_sandbox; 1211 { 1212 char_u *retval; 1213 void *save_funccalp; 1214 1215 save_funccalp = save_funccal(); 1216 if (use_sandbox) 1217 ++sandbox; 1218 ++textlock; 1219 retval = eval_to_string(arg, nextcmd, FALSE); 1220 if (use_sandbox) 1221 --sandbox; 1222 --textlock; 1223 restore_funccal(save_funccalp); 1224 return retval; 1225 } 1226 1227 /* 1228 * Top level evaluation function, returning a number. 1229 * Evaluates "expr" silently. 1230 * Returns -1 for an error. 1231 */ 1232 int 1233 eval_to_number(expr) 1234 char_u *expr; 1235 { 1236 typval_T rettv; 1237 int retval; 1238 char_u *p = skipwhite(expr); 1239 1240 ++emsg_off; 1241 1242 if (eval1(&p, &rettv, TRUE) == FAIL) 1243 retval = -1; 1244 else 1245 { 1246 retval = get_tv_number_chk(&rettv, NULL); 1247 clear_tv(&rettv); 1248 } 1249 --emsg_off; 1250 1251 return retval; 1252 } 1253 1254 /* 1255 * Prepare v: variable "idx" to be used. 1256 * Save the current typeval in "save_tv". 1257 * When not used yet add the variable to the v: hashtable. 1258 */ 1259 static void 1260 prepare_vimvar(idx, save_tv) 1261 int idx; 1262 typval_T *save_tv; 1263 { 1264 *save_tv = vimvars[idx].vv_tv; 1265 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1266 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1267 } 1268 1269 /* 1270 * Restore v: variable "idx" to typeval "save_tv". 1271 * When no longer defined, remove the variable from the v: hashtable. 1272 */ 1273 static void 1274 restore_vimvar(idx, save_tv) 1275 int idx; 1276 typval_T *save_tv; 1277 { 1278 hashitem_T *hi; 1279 1280 clear_tv(&vimvars[idx].vv_tv); 1281 vimvars[idx].vv_tv = *save_tv; 1282 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1283 { 1284 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1285 if (HASHITEM_EMPTY(hi)) 1286 EMSG2(_(e_intern2), "restore_vimvar()"); 1287 else 1288 hash_remove(&vimvarht, hi); 1289 } 1290 } 1291 1292 #if defined(FEAT_SYN_HL) || defined(PROTO) 1293 /* 1294 * Evaluate an expression to a list with suggestions. 1295 * For the "expr:" part of 'spellsuggest'. 1296 */ 1297 list_T * 1298 eval_spell_expr(badword, expr) 1299 char_u *badword; 1300 char_u *expr; 1301 { 1302 typval_T save_val; 1303 typval_T rettv; 1304 list_T *list = NULL; 1305 char_u *p = skipwhite(expr); 1306 1307 /* Set "v:val" to the bad word. */ 1308 prepare_vimvar(VV_VAL, &save_val); 1309 vimvars[VV_VAL].vv_type = VAR_STRING; 1310 vimvars[VV_VAL].vv_str = badword; 1311 if (p_verbose == 0) 1312 ++emsg_off; 1313 1314 if (eval1(&p, &rettv, TRUE) == OK) 1315 { 1316 if (rettv.v_type != VAR_LIST) 1317 clear_tv(&rettv); 1318 else 1319 list = rettv.vval.v_list; 1320 } 1321 1322 if (p_verbose == 0) 1323 --emsg_off; 1324 vimvars[VV_VAL].vv_str = NULL; 1325 restore_vimvar(VV_VAL, &save_val); 1326 1327 return list; 1328 } 1329 1330 /* 1331 * "list" is supposed to contain two items: a word and a number. Return the 1332 * word in "pp" and the number as the return value. 1333 * Return -1 if anything isn't right. 1334 * Used to get the good word and score from the eval_spell_expr() result. 1335 */ 1336 int 1337 get_spellword(list, pp) 1338 list_T *list; 1339 char_u **pp; 1340 { 1341 listitem_T *li; 1342 1343 li = list->lv_first; 1344 if (li == NULL) 1345 return -1; 1346 *pp = get_tv_string(&li->li_tv); 1347 1348 li = li->li_next; 1349 if (li == NULL) 1350 return -1; 1351 return get_tv_number(&li->li_tv); 1352 } 1353 #endif 1354 1355 /* 1356 * Top level evaluation function. 1357 * Returns an allocated typval_T with the result. 1358 * Returns NULL when there is an error. 1359 */ 1360 typval_T * 1361 eval_expr(arg, nextcmd) 1362 char_u *arg; 1363 char_u **nextcmd; 1364 { 1365 typval_T *tv; 1366 1367 tv = (typval_T *)alloc(sizeof(typval_T)); 1368 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1369 { 1370 vim_free(tv); 1371 tv = NULL; 1372 } 1373 1374 return tv; 1375 } 1376 1377 1378 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1379 /* 1380 * Call some vimL function and return the result in "*rettv". 1381 * Uses argv[argc] for the function arguments. 1382 * Returns OK or FAIL. 1383 */ 1384 static int 1385 call_vim_function(func, argc, argv, safe, rettv) 1386 char_u *func; 1387 int argc; 1388 char_u **argv; 1389 int safe; /* use the sandbox */ 1390 typval_T *rettv; 1391 { 1392 typval_T *argvars; 1393 long n; 1394 int len; 1395 int i; 1396 int doesrange; 1397 void *save_funccalp = NULL; 1398 int ret; 1399 1400 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1401 if (argvars == NULL) 1402 return FAIL; 1403 1404 for (i = 0; i < argc; i++) 1405 { 1406 /* Pass a NULL or empty argument as an empty string */ 1407 if (argv[i] == NULL || *argv[i] == NUL) 1408 { 1409 argvars[i].v_type = VAR_STRING; 1410 argvars[i].vval.v_string = (char_u *)""; 1411 continue; 1412 } 1413 1414 /* Recognize a number argument, the others must be strings. */ 1415 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1416 if (len != 0 && len == (int)STRLEN(argv[i])) 1417 { 1418 argvars[i].v_type = VAR_NUMBER; 1419 argvars[i].vval.v_number = n; 1420 } 1421 else 1422 { 1423 argvars[i].v_type = VAR_STRING; 1424 argvars[i].vval.v_string = argv[i]; 1425 } 1426 } 1427 1428 if (safe) 1429 { 1430 save_funccalp = save_funccal(); 1431 ++sandbox; 1432 } 1433 1434 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1435 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1436 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1437 &doesrange, TRUE, NULL); 1438 if (safe) 1439 { 1440 --sandbox; 1441 restore_funccal(save_funccalp); 1442 } 1443 vim_free(argvars); 1444 1445 if (ret == FAIL) 1446 clear_tv(rettv); 1447 1448 return ret; 1449 } 1450 1451 /* 1452 * Call vimL function "func" and return the result as a string. 1453 * Returns NULL when calling the function fails. 1454 * Uses argv[argc] for the function arguments. 1455 */ 1456 void * 1457 call_func_retstr(func, argc, argv, safe) 1458 char_u *func; 1459 int argc; 1460 char_u **argv; 1461 int safe; /* use the sandbox */ 1462 { 1463 typval_T rettv; 1464 char_u *retval; 1465 1466 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1467 return NULL; 1468 1469 retval = vim_strsave(get_tv_string(&rettv)); 1470 clear_tv(&rettv); 1471 return retval; 1472 } 1473 1474 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1475 /* 1476 * Call vimL function "func" and return the result as a number. 1477 * Returns -1 when calling the function fails. 1478 * Uses argv[argc] for the function arguments. 1479 */ 1480 long 1481 call_func_retnr(func, argc, argv, safe) 1482 char_u *func; 1483 int argc; 1484 char_u **argv; 1485 int safe; /* use the sandbox */ 1486 { 1487 typval_T rettv; 1488 long retval; 1489 1490 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1491 return -1; 1492 1493 retval = get_tv_number_chk(&rettv, NULL); 1494 clear_tv(&rettv); 1495 return retval; 1496 } 1497 #endif 1498 1499 /* 1500 * Call vimL function "func" and return the result as a list 1501 * Uses argv[argc] for the function arguments. 1502 */ 1503 void * 1504 call_func_retlist(func, argc, argv, safe) 1505 char_u *func; 1506 int argc; 1507 char_u **argv; 1508 int safe; /* use the sandbox */ 1509 { 1510 typval_T rettv; 1511 1512 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1513 return NULL; 1514 1515 if (rettv.v_type != VAR_LIST) 1516 { 1517 clear_tv(&rettv); 1518 return NULL; 1519 } 1520 1521 return rettv.vval.v_list; 1522 } 1523 1524 #endif 1525 1526 /* 1527 * Save the current function call pointer, and set it to NULL. 1528 * Used when executing autocommands and for ":source". 1529 */ 1530 void * 1531 save_funccal() 1532 { 1533 funccall_T *fc = current_funccal; 1534 1535 current_funccal = NULL; 1536 return (void *)fc; 1537 } 1538 1539 void 1540 restore_funccal(vfc) 1541 void *vfc; 1542 { 1543 funccall_T *fc = (funccall_T *)vfc; 1544 1545 current_funccal = fc; 1546 } 1547 1548 #if defined(FEAT_PROFILE) || defined(PROTO) 1549 /* 1550 * Prepare profiling for entering a child or something else that is not 1551 * counted for the script/function itself. 1552 * Should always be called in pair with prof_child_exit(). 1553 */ 1554 void 1555 prof_child_enter(tm) 1556 proftime_T *tm; /* place to store waittime */ 1557 { 1558 funccall_T *fc = current_funccal; 1559 1560 if (fc != NULL && fc->func->uf_profiling) 1561 profile_start(&fc->prof_child); 1562 script_prof_save(tm); 1563 } 1564 1565 /* 1566 * Take care of time spent in a child. 1567 * Should always be called after prof_child_enter(). 1568 */ 1569 void 1570 prof_child_exit(tm) 1571 proftime_T *tm; /* where waittime was stored */ 1572 { 1573 funccall_T *fc = current_funccal; 1574 1575 if (fc != NULL && fc->func->uf_profiling) 1576 { 1577 profile_end(&fc->prof_child); 1578 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1579 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1580 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1581 } 1582 script_prof_restore(tm); 1583 } 1584 #endif 1585 1586 1587 #ifdef FEAT_FOLDING 1588 /* 1589 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1590 * it in "*cp". Doesn't give error messages. 1591 */ 1592 int 1593 eval_foldexpr(arg, cp) 1594 char_u *arg; 1595 int *cp; 1596 { 1597 typval_T tv; 1598 int retval; 1599 char_u *s; 1600 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1601 OPT_LOCAL); 1602 1603 ++emsg_off; 1604 if (use_sandbox) 1605 ++sandbox; 1606 ++textlock; 1607 *cp = NUL; 1608 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1609 retval = 0; 1610 else 1611 { 1612 /* If the result is a number, just return the number. */ 1613 if (tv.v_type == VAR_NUMBER) 1614 retval = tv.vval.v_number; 1615 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1616 retval = 0; 1617 else 1618 { 1619 /* If the result is a string, check if there is a non-digit before 1620 * the number. */ 1621 s = tv.vval.v_string; 1622 if (!VIM_ISDIGIT(*s) && *s != '-') 1623 *cp = *s++; 1624 retval = atol((char *)s); 1625 } 1626 clear_tv(&tv); 1627 } 1628 --emsg_off; 1629 if (use_sandbox) 1630 --sandbox; 1631 --textlock; 1632 1633 return retval; 1634 } 1635 #endif 1636 1637 /* 1638 * ":let" list all variable values 1639 * ":let var1 var2" list variable values 1640 * ":let var = expr" assignment command. 1641 * ":let var += expr" assignment command. 1642 * ":let var -= expr" assignment command. 1643 * ":let var .= expr" assignment command. 1644 * ":let [var1, var2] = expr" unpack list. 1645 */ 1646 void 1647 ex_let(eap) 1648 exarg_T *eap; 1649 { 1650 char_u *arg = eap->arg; 1651 char_u *expr = NULL; 1652 typval_T rettv; 1653 int i; 1654 int var_count = 0; 1655 int semicolon = 0; 1656 char_u op[2]; 1657 1658 expr = skip_var_list(arg, &var_count, &semicolon); 1659 if (expr == NULL) 1660 return; 1661 expr = vim_strchr(expr, '='); 1662 if (expr == NULL) 1663 { 1664 /* 1665 * ":let" without "=": list variables 1666 */ 1667 if (*arg == '[') 1668 EMSG(_(e_invarg)); 1669 else if (!ends_excmd(*arg)) 1670 /* ":let var1 var2" */ 1671 arg = list_arg_vars(eap, arg); 1672 else if (!eap->skip) 1673 { 1674 /* ":let" */ 1675 list_glob_vars(); 1676 list_buf_vars(); 1677 list_win_vars(); 1678 list_vim_vars(); 1679 } 1680 eap->nextcmd = check_nextcmd(arg); 1681 } 1682 else 1683 { 1684 op[0] = '='; 1685 op[1] = NUL; 1686 if (expr > arg) 1687 { 1688 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1689 op[0] = expr[-1]; /* +=, -= or .= */ 1690 } 1691 expr = skipwhite(expr + 1); 1692 1693 if (eap->skip) 1694 ++emsg_skip; 1695 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1696 if (eap->skip) 1697 { 1698 if (i != FAIL) 1699 clear_tv(&rettv); 1700 --emsg_skip; 1701 } 1702 else if (i != FAIL) 1703 { 1704 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1705 op); 1706 clear_tv(&rettv); 1707 } 1708 } 1709 } 1710 1711 /* 1712 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1713 * Handles both "var" with any type and "[var, var; var]" with a list type. 1714 * When "nextchars" is not NULL it points to a string with characters that 1715 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1716 * or concatenate. 1717 * Returns OK or FAIL; 1718 */ 1719 static int 1720 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1721 char_u *arg_start; 1722 typval_T *tv; 1723 int copy; /* copy values from "tv", don't move */ 1724 int semicolon; /* from skip_var_list() */ 1725 int var_count; /* from skip_var_list() */ 1726 char_u *nextchars; 1727 { 1728 char_u *arg = arg_start; 1729 list_T *l; 1730 int i; 1731 listitem_T *item; 1732 typval_T ltv; 1733 1734 if (*arg != '[') 1735 { 1736 /* 1737 * ":let var = expr" or ":for var in list" 1738 */ 1739 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1740 return FAIL; 1741 return OK; 1742 } 1743 1744 /* 1745 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1746 */ 1747 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1748 { 1749 EMSG(_(e_listreq)); 1750 return FAIL; 1751 } 1752 1753 i = list_len(l); 1754 if (semicolon == 0 && var_count < i) 1755 { 1756 EMSG(_("E687: Less targets than List items")); 1757 return FAIL; 1758 } 1759 if (var_count - semicolon > i) 1760 { 1761 EMSG(_("E688: More targets than List items")); 1762 return FAIL; 1763 } 1764 1765 item = l->lv_first; 1766 while (*arg != ']') 1767 { 1768 arg = skipwhite(arg + 1); 1769 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1770 item = item->li_next; 1771 if (arg == NULL) 1772 return FAIL; 1773 1774 arg = skipwhite(arg); 1775 if (*arg == ';') 1776 { 1777 /* Put the rest of the list (may be empty) in the var after ';'. 1778 * Create a new list for this. */ 1779 l = list_alloc(); 1780 if (l == NULL) 1781 return FAIL; 1782 while (item != NULL) 1783 { 1784 list_append_tv(l, &item->li_tv); 1785 item = item->li_next; 1786 } 1787 1788 ltv.v_type = VAR_LIST; 1789 ltv.v_lock = 0; 1790 ltv.vval.v_list = l; 1791 l->lv_refcount = 1; 1792 1793 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1794 (char_u *)"]", nextchars); 1795 clear_tv(<v); 1796 if (arg == NULL) 1797 return FAIL; 1798 break; 1799 } 1800 else if (*arg != ',' && *arg != ']') 1801 { 1802 EMSG2(_(e_intern2), "ex_let_vars()"); 1803 return FAIL; 1804 } 1805 } 1806 1807 return OK; 1808 } 1809 1810 /* 1811 * Skip over assignable variable "var" or list of variables "[var, var]". 1812 * Used for ":let varvar = expr" and ":for varvar in expr". 1813 * For "[var, var]" increment "*var_count" for each variable. 1814 * for "[var, var; var]" set "semicolon". 1815 * Return NULL for an error. 1816 */ 1817 static char_u * 1818 skip_var_list(arg, var_count, semicolon) 1819 char_u *arg; 1820 int *var_count; 1821 int *semicolon; 1822 { 1823 char_u *p, *s; 1824 1825 if (*arg == '[') 1826 { 1827 /* "[var, var]": find the matching ']'. */ 1828 p = arg; 1829 for (;;) 1830 { 1831 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1832 s = skip_var_one(p); 1833 if (s == p) 1834 { 1835 EMSG2(_(e_invarg2), p); 1836 return NULL; 1837 } 1838 ++*var_count; 1839 1840 p = skipwhite(s); 1841 if (*p == ']') 1842 break; 1843 else if (*p == ';') 1844 { 1845 if (*semicolon == 1) 1846 { 1847 EMSG(_("Double ; in list of variables")); 1848 return NULL; 1849 } 1850 *semicolon = 1; 1851 } 1852 else if (*p != ',') 1853 { 1854 EMSG2(_(e_invarg2), p); 1855 return NULL; 1856 } 1857 } 1858 return p + 1; 1859 } 1860 else 1861 return skip_var_one(arg); 1862 } 1863 1864 /* 1865 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1866 * l[idx]. 1867 */ 1868 static char_u * 1869 skip_var_one(arg) 1870 char_u *arg; 1871 { 1872 if (*arg == '@' && arg[1] != NUL) 1873 return arg + 2; 1874 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1875 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1876 } 1877 1878 /* 1879 * List variables for hashtab "ht" with prefix "prefix". 1880 * If "empty" is TRUE also list NULL strings as empty strings. 1881 */ 1882 static void 1883 list_hashtable_vars(ht, prefix, empty) 1884 hashtab_T *ht; 1885 char_u *prefix; 1886 int empty; 1887 { 1888 hashitem_T *hi; 1889 dictitem_T *di; 1890 int todo; 1891 1892 todo = ht->ht_used; 1893 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1894 { 1895 if (!HASHITEM_EMPTY(hi)) 1896 { 1897 --todo; 1898 di = HI2DI(hi); 1899 if (empty || di->di_tv.v_type != VAR_STRING 1900 || di->di_tv.vval.v_string != NULL) 1901 list_one_var(di, prefix); 1902 } 1903 } 1904 } 1905 1906 /* 1907 * List global variables. 1908 */ 1909 static void 1910 list_glob_vars() 1911 { 1912 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1913 } 1914 1915 /* 1916 * List buffer variables. 1917 */ 1918 static void 1919 list_buf_vars() 1920 { 1921 char_u numbuf[NUMBUFLEN]; 1922 1923 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1924 1925 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1926 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1927 } 1928 1929 /* 1930 * List window variables. 1931 */ 1932 static void 1933 list_win_vars() 1934 { 1935 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1936 } 1937 1938 /* 1939 * List Vim variables. 1940 */ 1941 static void 1942 list_vim_vars() 1943 { 1944 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1945 } 1946 1947 /* 1948 * List variables in "arg". 1949 */ 1950 static char_u * 1951 list_arg_vars(eap, arg) 1952 exarg_T *eap; 1953 char_u *arg; 1954 { 1955 int error = FALSE; 1956 int len; 1957 char_u *name; 1958 char_u *name_start; 1959 char_u *arg_subsc; 1960 char_u *tofree; 1961 typval_T tv; 1962 1963 while (!ends_excmd(*arg) && !got_int) 1964 { 1965 if (error || eap->skip) 1966 { 1967 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1968 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1969 { 1970 emsg_severe = TRUE; 1971 EMSG(_(e_trailing)); 1972 break; 1973 } 1974 } 1975 else 1976 { 1977 /* get_name_len() takes care of expanding curly braces */ 1978 name_start = name = arg; 1979 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1980 if (len <= 0) 1981 { 1982 /* This is mainly to keep test 49 working: when expanding 1983 * curly braces fails overrule the exception error message. */ 1984 if (len < 0 && !aborting()) 1985 { 1986 emsg_severe = TRUE; 1987 EMSG2(_(e_invarg2), arg); 1988 break; 1989 } 1990 error = TRUE; 1991 } 1992 else 1993 { 1994 if (tofree != NULL) 1995 name = tofree; 1996 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1997 error = TRUE; 1998 else 1999 { 2000 /* handle d.key, l[idx], f(expr) */ 2001 arg_subsc = arg; 2002 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2003 error = TRUE; 2004 else 2005 { 2006 if (arg == arg_subsc && len == 2 && name[1] == ':') 2007 { 2008 switch (*name) 2009 { 2010 case 'g': list_glob_vars(); break; 2011 case 'b': list_buf_vars(); break; 2012 case 'w': list_win_vars(); break; 2013 case 'v': list_vim_vars(); break; 2014 default: 2015 EMSG2(_("E738: Can't list variables for %s"), name); 2016 } 2017 } 2018 else 2019 { 2020 char_u numbuf[NUMBUFLEN]; 2021 char_u *tf; 2022 int c; 2023 char_u *s; 2024 2025 s = echo_string(&tv, &tf, numbuf, 0); 2026 c = *arg; 2027 *arg = NUL; 2028 list_one_var_a((char_u *)"", 2029 arg == arg_subsc ? name : name_start, 2030 tv.v_type, s == NULL ? (char_u *)"" : s); 2031 *arg = c; 2032 vim_free(tf); 2033 } 2034 clear_tv(&tv); 2035 } 2036 } 2037 } 2038 2039 vim_free(tofree); 2040 } 2041 2042 arg = skipwhite(arg); 2043 } 2044 2045 return arg; 2046 } 2047 2048 /* 2049 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2050 * Returns a pointer to the char just after the var name. 2051 * Returns NULL if there is an error. 2052 */ 2053 static char_u * 2054 ex_let_one(arg, tv, copy, endchars, op) 2055 char_u *arg; /* points to variable name */ 2056 typval_T *tv; /* value to assign to variable */ 2057 int copy; /* copy value from "tv" */ 2058 char_u *endchars; /* valid chars after variable name or NULL */ 2059 char_u *op; /* "+", "-", "." or NULL*/ 2060 { 2061 int c1; 2062 char_u *name; 2063 char_u *p; 2064 char_u *arg_end = NULL; 2065 int len; 2066 int opt_flags; 2067 char_u *tofree = NULL; 2068 2069 /* 2070 * ":let $VAR = expr": Set environment variable. 2071 */ 2072 if (*arg == '$') 2073 { 2074 /* Find the end of the name. */ 2075 ++arg; 2076 name = arg; 2077 len = get_env_len(&arg); 2078 if (len == 0) 2079 EMSG2(_(e_invarg2), name - 1); 2080 else 2081 { 2082 if (op != NULL && (*op == '+' || *op == '-')) 2083 EMSG2(_(e_letwrong), op); 2084 else if (endchars != NULL 2085 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2086 EMSG(_(e_letunexp)); 2087 else 2088 { 2089 c1 = name[len]; 2090 name[len] = NUL; 2091 p = get_tv_string_chk(tv); 2092 if (p != NULL && op != NULL && *op == '.') 2093 { 2094 int mustfree = FALSE; 2095 char_u *s = vim_getenv(name, &mustfree); 2096 2097 if (s != NULL) 2098 { 2099 p = tofree = concat_str(s, p); 2100 if (mustfree) 2101 vim_free(s); 2102 } 2103 } 2104 if (p != NULL) 2105 { 2106 vim_setenv(name, p); 2107 if (STRICMP(name, "HOME") == 0) 2108 init_homedir(); 2109 else if (didset_vim && STRICMP(name, "VIM") == 0) 2110 didset_vim = FALSE; 2111 else if (didset_vimruntime 2112 && STRICMP(name, "VIMRUNTIME") == 0) 2113 didset_vimruntime = FALSE; 2114 arg_end = arg; 2115 } 2116 name[len] = c1; 2117 vim_free(tofree); 2118 } 2119 } 2120 } 2121 2122 /* 2123 * ":let &option = expr": Set option value. 2124 * ":let &l:option = expr": Set local option value. 2125 * ":let &g:option = expr": Set global option value. 2126 */ 2127 else if (*arg == '&') 2128 { 2129 /* Find the end of the name. */ 2130 p = find_option_end(&arg, &opt_flags); 2131 if (p == NULL || (endchars != NULL 2132 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2133 EMSG(_(e_letunexp)); 2134 else 2135 { 2136 long n; 2137 int opt_type; 2138 long numval; 2139 char_u *stringval = NULL; 2140 char_u *s; 2141 2142 c1 = *p; 2143 *p = NUL; 2144 2145 n = get_tv_number(tv); 2146 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2147 if (s != NULL && op != NULL && *op != '=') 2148 { 2149 opt_type = get_option_value(arg, &numval, 2150 &stringval, opt_flags); 2151 if ((opt_type == 1 && *op == '.') 2152 || (opt_type == 0 && *op != '.')) 2153 EMSG2(_(e_letwrong), op); 2154 else 2155 { 2156 if (opt_type == 1) /* number */ 2157 { 2158 if (*op == '+') 2159 n = numval + n; 2160 else 2161 n = numval - n; 2162 } 2163 else if (opt_type == 0 && stringval != NULL) /* string */ 2164 { 2165 s = concat_str(stringval, s); 2166 vim_free(stringval); 2167 stringval = s; 2168 } 2169 } 2170 } 2171 if (s != NULL) 2172 { 2173 set_option_value(arg, n, s, opt_flags); 2174 arg_end = p; 2175 } 2176 *p = c1; 2177 vim_free(stringval); 2178 } 2179 } 2180 2181 /* 2182 * ":let @r = expr": Set register contents. 2183 */ 2184 else if (*arg == '@') 2185 { 2186 ++arg; 2187 if (op != NULL && (*op == '+' || *op == '-')) 2188 EMSG2(_(e_letwrong), op); 2189 else if (endchars != NULL 2190 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2191 EMSG(_(e_letunexp)); 2192 else 2193 { 2194 char_u *tofree = NULL; 2195 char_u *s; 2196 2197 p = get_tv_string_chk(tv); 2198 if (p != NULL && op != NULL && *op == '.') 2199 { 2200 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2201 if (s != NULL) 2202 { 2203 p = tofree = concat_str(s, p); 2204 vim_free(s); 2205 } 2206 } 2207 if (p != NULL) 2208 { 2209 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2210 arg_end = arg + 1; 2211 } 2212 vim_free(tofree); 2213 } 2214 } 2215 2216 /* 2217 * ":let var = expr": Set internal variable. 2218 * ":let {expr} = expr": Idem, name made with curly braces 2219 */ 2220 else if (eval_isnamec1(*arg) || *arg == '{') 2221 { 2222 lval_T lv; 2223 2224 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2225 if (p != NULL && lv.ll_name != NULL) 2226 { 2227 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2228 EMSG(_(e_letunexp)); 2229 else 2230 { 2231 set_var_lval(&lv, p, tv, copy, op); 2232 arg_end = p; 2233 } 2234 } 2235 clear_lval(&lv); 2236 } 2237 2238 else 2239 EMSG2(_(e_invarg2), arg); 2240 2241 return arg_end; 2242 } 2243 2244 /* 2245 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2246 */ 2247 static int 2248 check_changedtick(arg) 2249 char_u *arg; 2250 { 2251 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2252 { 2253 EMSG2(_(e_readonlyvar), arg); 2254 return TRUE; 2255 } 2256 return FALSE; 2257 } 2258 2259 /* 2260 * Get an lval: variable, Dict item or List item that can be assigned a value 2261 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2262 * "name.key", "name.key[expr]" etc. 2263 * Indexing only works if "name" is an existing List or Dictionary. 2264 * "name" points to the start of the name. 2265 * If "rettv" is not NULL it points to the value to be assigned. 2266 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2267 * wrong; must end in space or cmd separator. 2268 * 2269 * Returns a pointer to just after the name, including indexes. 2270 * When an evaluation error occurs "lp->ll_name" is NULL; 2271 * Returns NULL for a parsing error. Still need to free items in "lp"! 2272 */ 2273 static char_u * 2274 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2275 char_u *name; 2276 typval_T *rettv; 2277 lval_T *lp; 2278 int unlet; 2279 int skip; 2280 int quiet; /* don't give error messages */ 2281 int fne_flags; /* flags for find_name_end() */ 2282 { 2283 char_u *p; 2284 char_u *expr_start, *expr_end; 2285 int cc; 2286 dictitem_T *v; 2287 typval_T var1; 2288 typval_T var2; 2289 int empty1 = FALSE; 2290 listitem_T *ni; 2291 char_u *key = NULL; 2292 int len; 2293 hashtab_T *ht; 2294 2295 /* Clear everything in "lp". */ 2296 vim_memset(lp, 0, sizeof(lval_T)); 2297 2298 if (skip) 2299 { 2300 /* When skipping just find the end of the name. */ 2301 lp->ll_name = name; 2302 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2303 } 2304 2305 /* Find the end of the name. */ 2306 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2307 if (expr_start != NULL) 2308 { 2309 /* Don't expand the name when we already know there is an error. */ 2310 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2311 && *p != '[' && *p != '.') 2312 { 2313 EMSG(_(e_trailing)); 2314 return NULL; 2315 } 2316 2317 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2318 if (lp->ll_exp_name == NULL) 2319 { 2320 /* Report an invalid expression in braces, unless the 2321 * expression evaluation has been cancelled due to an 2322 * aborting error, an interrupt, or an exception. */ 2323 if (!aborting() && !quiet) 2324 { 2325 emsg_severe = TRUE; 2326 EMSG2(_(e_invarg2), name); 2327 return NULL; 2328 } 2329 } 2330 lp->ll_name = lp->ll_exp_name; 2331 } 2332 else 2333 lp->ll_name = name; 2334 2335 /* Without [idx] or .key we are done. */ 2336 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2337 return p; 2338 2339 cc = *p; 2340 *p = NUL; 2341 v = find_var(lp->ll_name, &ht); 2342 if (v == NULL && !quiet) 2343 EMSG2(_(e_undefvar), lp->ll_name); 2344 *p = cc; 2345 if (v == NULL) 2346 return NULL; 2347 2348 /* 2349 * Loop until no more [idx] or .key is following. 2350 */ 2351 lp->ll_tv = &v->di_tv; 2352 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2353 { 2354 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2355 && !(lp->ll_tv->v_type == VAR_DICT 2356 && lp->ll_tv->vval.v_dict != NULL)) 2357 { 2358 if (!quiet) 2359 EMSG(_("E689: Can only index a List or Dictionary")); 2360 return NULL; 2361 } 2362 if (lp->ll_range) 2363 { 2364 if (!quiet) 2365 EMSG(_("E708: [:] must come last")); 2366 return NULL; 2367 } 2368 2369 len = -1; 2370 if (*p == '.') 2371 { 2372 key = p + 1; 2373 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2374 ; 2375 if (len == 0) 2376 { 2377 if (!quiet) 2378 EMSG(_(e_emptykey)); 2379 return NULL; 2380 } 2381 p = key + len; 2382 } 2383 else 2384 { 2385 /* Get the index [expr] or the first index [expr: ]. */ 2386 p = skipwhite(p + 1); 2387 if (*p == ':') 2388 empty1 = TRUE; 2389 else 2390 { 2391 empty1 = FALSE; 2392 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2393 return NULL; 2394 if (get_tv_string_chk(&var1) == NULL) 2395 { 2396 /* not a number or string */ 2397 clear_tv(&var1); 2398 return NULL; 2399 } 2400 } 2401 2402 /* Optionally get the second index [ :expr]. */ 2403 if (*p == ':') 2404 { 2405 if (lp->ll_tv->v_type == VAR_DICT) 2406 { 2407 if (!quiet) 2408 EMSG(_(e_dictrange)); 2409 if (!empty1) 2410 clear_tv(&var1); 2411 return NULL; 2412 } 2413 if (rettv != NULL && (rettv->v_type != VAR_LIST 2414 || rettv->vval.v_list == NULL)) 2415 { 2416 if (!quiet) 2417 EMSG(_("E709: [:] requires a List value")); 2418 if (!empty1) 2419 clear_tv(&var1); 2420 return NULL; 2421 } 2422 p = skipwhite(p + 1); 2423 if (*p == ']') 2424 lp->ll_empty2 = TRUE; 2425 else 2426 { 2427 lp->ll_empty2 = FALSE; 2428 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2429 { 2430 if (!empty1) 2431 clear_tv(&var1); 2432 return NULL; 2433 } 2434 if (get_tv_string_chk(&var2) == NULL) 2435 { 2436 /* not a number or string */ 2437 if (!empty1) 2438 clear_tv(&var1); 2439 clear_tv(&var2); 2440 return NULL; 2441 } 2442 } 2443 lp->ll_range = TRUE; 2444 } 2445 else 2446 lp->ll_range = FALSE; 2447 2448 if (*p != ']') 2449 { 2450 if (!quiet) 2451 EMSG(_(e_missbrac)); 2452 if (!empty1) 2453 clear_tv(&var1); 2454 if (lp->ll_range && !lp->ll_empty2) 2455 clear_tv(&var2); 2456 return NULL; 2457 } 2458 2459 /* Skip to past ']'. */ 2460 ++p; 2461 } 2462 2463 if (lp->ll_tv->v_type == VAR_DICT) 2464 { 2465 if (len == -1) 2466 { 2467 /* "[key]": get key from "var1" */ 2468 key = get_tv_string(&var1); /* is number or string */ 2469 if (*key == NUL) 2470 { 2471 if (!quiet) 2472 EMSG(_(e_emptykey)); 2473 clear_tv(&var1); 2474 return NULL; 2475 } 2476 } 2477 lp->ll_list = NULL; 2478 lp->ll_dict = lp->ll_tv->vval.v_dict; 2479 lp->ll_di = dict_find(lp->ll_dict, key, len); 2480 if (lp->ll_di == NULL) 2481 { 2482 /* Key does not exist in dict: may need to add it. */ 2483 if (*p == '[' || *p == '.' || unlet) 2484 { 2485 if (!quiet) 2486 EMSG2(_(e_dictkey), key); 2487 if (len == -1) 2488 clear_tv(&var1); 2489 return NULL; 2490 } 2491 if (len == -1) 2492 lp->ll_newkey = vim_strsave(key); 2493 else 2494 lp->ll_newkey = vim_strnsave(key, len); 2495 if (len == -1) 2496 clear_tv(&var1); 2497 if (lp->ll_newkey == NULL) 2498 p = NULL; 2499 break; 2500 } 2501 if (len == -1) 2502 clear_tv(&var1); 2503 lp->ll_tv = &lp->ll_di->di_tv; 2504 } 2505 else 2506 { 2507 /* 2508 * Get the number and item for the only or first index of the List. 2509 */ 2510 if (empty1) 2511 lp->ll_n1 = 0; 2512 else 2513 { 2514 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2515 clear_tv(&var1); 2516 } 2517 lp->ll_dict = NULL; 2518 lp->ll_list = lp->ll_tv->vval.v_list; 2519 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2520 if (lp->ll_li == NULL) 2521 { 2522 if (!quiet) 2523 EMSGN(_(e_listidx), lp->ll_n1); 2524 if (lp->ll_range && !lp->ll_empty2) 2525 clear_tv(&var2); 2526 return NULL; 2527 } 2528 2529 /* 2530 * May need to find the item or absolute index for the second 2531 * index of a range. 2532 * When no index given: "lp->ll_empty2" is TRUE. 2533 * Otherwise "lp->ll_n2" is set to the second index. 2534 */ 2535 if (lp->ll_range && !lp->ll_empty2) 2536 { 2537 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2538 clear_tv(&var2); 2539 if (lp->ll_n2 < 0) 2540 { 2541 ni = list_find(lp->ll_list, lp->ll_n2); 2542 if (ni == NULL) 2543 { 2544 if (!quiet) 2545 EMSGN(_(e_listidx), lp->ll_n2); 2546 return NULL; 2547 } 2548 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2549 } 2550 2551 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2552 if (lp->ll_n1 < 0) 2553 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2554 if (lp->ll_n2 < lp->ll_n1) 2555 { 2556 if (!quiet) 2557 EMSGN(_(e_listidx), lp->ll_n2); 2558 return NULL; 2559 } 2560 } 2561 2562 lp->ll_tv = &lp->ll_li->li_tv; 2563 } 2564 } 2565 2566 return p; 2567 } 2568 2569 /* 2570 * Clear lval "lp" that was filled by get_lval(). 2571 */ 2572 static void 2573 clear_lval(lp) 2574 lval_T *lp; 2575 { 2576 vim_free(lp->ll_exp_name); 2577 vim_free(lp->ll_newkey); 2578 } 2579 2580 /* 2581 * Set a variable that was parsed by get_lval() to "rettv". 2582 * "endp" points to just after the parsed name. 2583 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2584 */ 2585 static void 2586 set_var_lval(lp, endp, rettv, copy, op) 2587 lval_T *lp; 2588 char_u *endp; 2589 typval_T *rettv; 2590 int copy; 2591 char_u *op; 2592 { 2593 int cc; 2594 listitem_T *ri; 2595 dictitem_T *di; 2596 2597 if (lp->ll_tv == NULL) 2598 { 2599 if (!check_changedtick(lp->ll_name)) 2600 { 2601 cc = *endp; 2602 *endp = NUL; 2603 if (op != NULL && *op != '=') 2604 { 2605 typval_T tv; 2606 2607 /* handle +=, -= and .= */ 2608 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2609 &tv, TRUE) == OK) 2610 { 2611 if (tv_op(&tv, rettv, op) == OK) 2612 set_var(lp->ll_name, &tv, FALSE); 2613 clear_tv(&tv); 2614 } 2615 } 2616 else 2617 set_var(lp->ll_name, rettv, copy); 2618 *endp = cc; 2619 } 2620 } 2621 else if (tv_check_lock(lp->ll_newkey == NULL 2622 ? lp->ll_tv->v_lock 2623 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2624 ; 2625 else if (lp->ll_range) 2626 { 2627 /* 2628 * Assign the List values to the list items. 2629 */ 2630 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2631 { 2632 if (op != NULL && *op != '=') 2633 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2634 else 2635 { 2636 clear_tv(&lp->ll_li->li_tv); 2637 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2638 } 2639 ri = ri->li_next; 2640 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2641 break; 2642 if (lp->ll_li->li_next == NULL) 2643 { 2644 /* Need to add an empty item. */ 2645 if (list_append_number(lp->ll_list, 0) == FAIL) 2646 { 2647 ri = NULL; 2648 break; 2649 } 2650 } 2651 lp->ll_li = lp->ll_li->li_next; 2652 ++lp->ll_n1; 2653 } 2654 if (ri != NULL) 2655 EMSG(_("E710: List value has more items than target")); 2656 else if (lp->ll_empty2 2657 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2658 : lp->ll_n1 != lp->ll_n2) 2659 EMSG(_("E711: List value has not enough items")); 2660 } 2661 else 2662 { 2663 /* 2664 * Assign to a List or Dictionary item. 2665 */ 2666 if (lp->ll_newkey != NULL) 2667 { 2668 if (op != NULL && *op != '=') 2669 { 2670 EMSG2(_(e_letwrong), op); 2671 return; 2672 } 2673 2674 /* Need to add an item to the Dictionary. */ 2675 di = dictitem_alloc(lp->ll_newkey); 2676 if (di == NULL) 2677 return; 2678 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2679 { 2680 vim_free(di); 2681 return; 2682 } 2683 lp->ll_tv = &di->di_tv; 2684 } 2685 else if (op != NULL && *op != '=') 2686 { 2687 tv_op(lp->ll_tv, rettv, op); 2688 return; 2689 } 2690 else 2691 clear_tv(lp->ll_tv); 2692 2693 /* 2694 * Assign the value to the variable or list item. 2695 */ 2696 if (copy) 2697 copy_tv(rettv, lp->ll_tv); 2698 else 2699 { 2700 *lp->ll_tv = *rettv; 2701 lp->ll_tv->v_lock = 0; 2702 init_tv(rettv); 2703 } 2704 } 2705 } 2706 2707 /* 2708 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2709 * Returns OK or FAIL. 2710 */ 2711 static int 2712 tv_op(tv1, tv2, op) 2713 typval_T *tv1; 2714 typval_T *tv2; 2715 char_u *op; 2716 { 2717 long n; 2718 char_u numbuf[NUMBUFLEN]; 2719 char_u *s; 2720 2721 /* Can't do anything with a Funcref or a Dict on the right. */ 2722 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2723 { 2724 switch (tv1->v_type) 2725 { 2726 case VAR_DICT: 2727 case VAR_FUNC: 2728 break; 2729 2730 case VAR_LIST: 2731 if (*op != '+' || tv2->v_type != VAR_LIST) 2732 break; 2733 /* List += List */ 2734 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2735 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2736 return OK; 2737 2738 case VAR_NUMBER: 2739 case VAR_STRING: 2740 if (tv2->v_type == VAR_LIST) 2741 break; 2742 if (*op == '+' || *op == '-') 2743 { 2744 /* nr += nr or nr -= nr*/ 2745 n = get_tv_number(tv1); 2746 if (*op == '+') 2747 n += get_tv_number(tv2); 2748 else 2749 n -= get_tv_number(tv2); 2750 clear_tv(tv1); 2751 tv1->v_type = VAR_NUMBER; 2752 tv1->vval.v_number = n; 2753 } 2754 else 2755 { 2756 /* str .= str */ 2757 s = get_tv_string(tv1); 2758 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2759 clear_tv(tv1); 2760 tv1->v_type = VAR_STRING; 2761 tv1->vval.v_string = s; 2762 } 2763 return OK; 2764 } 2765 } 2766 2767 EMSG2(_(e_letwrong), op); 2768 return FAIL; 2769 } 2770 2771 /* 2772 * Add a watcher to a list. 2773 */ 2774 static void 2775 list_add_watch(l, lw) 2776 list_T *l; 2777 listwatch_T *lw; 2778 { 2779 lw->lw_next = l->lv_watch; 2780 l->lv_watch = lw; 2781 } 2782 2783 /* 2784 * Remove a watcher from a list. 2785 * No warning when it isn't found... 2786 */ 2787 static void 2788 list_rem_watch(l, lwrem) 2789 list_T *l; 2790 listwatch_T *lwrem; 2791 { 2792 listwatch_T *lw, **lwp; 2793 2794 lwp = &l->lv_watch; 2795 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2796 { 2797 if (lw == lwrem) 2798 { 2799 *lwp = lw->lw_next; 2800 break; 2801 } 2802 lwp = &lw->lw_next; 2803 } 2804 } 2805 2806 /* 2807 * Just before removing an item from a list: advance watchers to the next 2808 * item. 2809 */ 2810 static void 2811 list_fix_watch(l, item) 2812 list_T *l; 2813 listitem_T *item; 2814 { 2815 listwatch_T *lw; 2816 2817 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2818 if (lw->lw_item == item) 2819 lw->lw_item = item->li_next; 2820 } 2821 2822 /* 2823 * Evaluate the expression used in a ":for var in expr" command. 2824 * "arg" points to "var". 2825 * Set "*errp" to TRUE for an error, FALSE otherwise; 2826 * Return a pointer that holds the info. Null when there is an error. 2827 */ 2828 void * 2829 eval_for_line(arg, errp, nextcmdp, skip) 2830 char_u *arg; 2831 int *errp; 2832 char_u **nextcmdp; 2833 int skip; 2834 { 2835 forinfo_T *fi; 2836 char_u *expr; 2837 typval_T tv; 2838 list_T *l; 2839 2840 *errp = TRUE; /* default: there is an error */ 2841 2842 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2843 if (fi == NULL) 2844 return NULL; 2845 2846 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2847 if (expr == NULL) 2848 return fi; 2849 2850 expr = skipwhite(expr); 2851 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2852 { 2853 EMSG(_("E690: Missing \"in\" after :for")); 2854 return fi; 2855 } 2856 2857 if (skip) 2858 ++emsg_skip; 2859 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2860 { 2861 *errp = FALSE; 2862 if (!skip) 2863 { 2864 l = tv.vval.v_list; 2865 if (tv.v_type != VAR_LIST || l == NULL) 2866 { 2867 EMSG(_(e_listreq)); 2868 clear_tv(&tv); 2869 } 2870 else 2871 { 2872 /* No need to increment the refcount, it's already set for the 2873 * list being used in "tv". */ 2874 fi->fi_list = l; 2875 list_add_watch(l, &fi->fi_lw); 2876 fi->fi_lw.lw_item = l->lv_first; 2877 } 2878 } 2879 } 2880 if (skip) 2881 --emsg_skip; 2882 2883 return fi; 2884 } 2885 2886 /* 2887 * Use the first item in a ":for" list. Advance to the next. 2888 * Assign the values to the variable (list). "arg" points to the first one. 2889 * Return TRUE when a valid item was found, FALSE when at end of list or 2890 * something wrong. 2891 */ 2892 int 2893 next_for_item(fi_void, arg) 2894 void *fi_void; 2895 char_u *arg; 2896 { 2897 forinfo_T *fi = (forinfo_T *)fi_void; 2898 int result; 2899 listitem_T *item; 2900 2901 item = fi->fi_lw.lw_item; 2902 if (item == NULL) 2903 result = FALSE; 2904 else 2905 { 2906 fi->fi_lw.lw_item = item->li_next; 2907 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2908 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2909 } 2910 return result; 2911 } 2912 2913 /* 2914 * Free the structure used to store info used by ":for". 2915 */ 2916 void 2917 free_for_info(fi_void) 2918 void *fi_void; 2919 { 2920 forinfo_T *fi = (forinfo_T *)fi_void; 2921 2922 if (fi != NULL && fi->fi_list != NULL) 2923 { 2924 list_rem_watch(fi->fi_list, &fi->fi_lw); 2925 list_unref(fi->fi_list); 2926 } 2927 vim_free(fi); 2928 } 2929 2930 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2931 2932 void 2933 set_context_for_expression(xp, arg, cmdidx) 2934 expand_T *xp; 2935 char_u *arg; 2936 cmdidx_T cmdidx; 2937 { 2938 int got_eq = FALSE; 2939 int c; 2940 char_u *p; 2941 2942 if (cmdidx == CMD_let) 2943 { 2944 xp->xp_context = EXPAND_USER_VARS; 2945 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2946 { 2947 /* ":let var1 var2 ...": find last space. */ 2948 for (p = arg + STRLEN(arg); p >= arg; ) 2949 { 2950 xp->xp_pattern = p; 2951 mb_ptr_back(arg, p); 2952 if (vim_iswhite(*p)) 2953 break; 2954 } 2955 return; 2956 } 2957 } 2958 else 2959 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2960 : EXPAND_EXPRESSION; 2961 while ((xp->xp_pattern = vim_strpbrk(arg, 2962 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2963 { 2964 c = *xp->xp_pattern; 2965 if (c == '&') 2966 { 2967 c = xp->xp_pattern[1]; 2968 if (c == '&') 2969 { 2970 ++xp->xp_pattern; 2971 xp->xp_context = cmdidx != CMD_let || got_eq 2972 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2973 } 2974 else if (c != ' ') 2975 { 2976 xp->xp_context = EXPAND_SETTINGS; 2977 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2978 xp->xp_pattern += 2; 2979 2980 } 2981 } 2982 else if (c == '$') 2983 { 2984 /* environment variable */ 2985 xp->xp_context = EXPAND_ENV_VARS; 2986 } 2987 else if (c == '=') 2988 { 2989 got_eq = TRUE; 2990 xp->xp_context = EXPAND_EXPRESSION; 2991 } 2992 else if (c == '<' 2993 && xp->xp_context == EXPAND_FUNCTIONS 2994 && vim_strchr(xp->xp_pattern, '(') == NULL) 2995 { 2996 /* Function name can start with "<SNR>" */ 2997 break; 2998 } 2999 else if (cmdidx != CMD_let || got_eq) 3000 { 3001 if (c == '"') /* string */ 3002 { 3003 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3004 if (c == '\\' && xp->xp_pattern[1] != NUL) 3005 ++xp->xp_pattern; 3006 xp->xp_context = EXPAND_NOTHING; 3007 } 3008 else if (c == '\'') /* literal string */ 3009 { 3010 /* Trick: '' is like stopping and starting a literal string. */ 3011 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3012 /* skip */ ; 3013 xp->xp_context = EXPAND_NOTHING; 3014 } 3015 else if (c == '|') 3016 { 3017 if (xp->xp_pattern[1] == '|') 3018 { 3019 ++xp->xp_pattern; 3020 xp->xp_context = EXPAND_EXPRESSION; 3021 } 3022 else 3023 xp->xp_context = EXPAND_COMMANDS; 3024 } 3025 else 3026 xp->xp_context = EXPAND_EXPRESSION; 3027 } 3028 else 3029 /* Doesn't look like something valid, expand as an expression 3030 * anyway. */ 3031 xp->xp_context = EXPAND_EXPRESSION; 3032 arg = xp->xp_pattern; 3033 if (*arg != NUL) 3034 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3035 /* skip */ ; 3036 } 3037 xp->xp_pattern = arg; 3038 } 3039 3040 #endif /* FEAT_CMDL_COMPL */ 3041 3042 /* 3043 * ":1,25call func(arg1, arg2)" function call. 3044 */ 3045 void 3046 ex_call(eap) 3047 exarg_T *eap; 3048 { 3049 char_u *arg = eap->arg; 3050 char_u *startarg; 3051 char_u *name; 3052 char_u *tofree; 3053 int len; 3054 typval_T rettv; 3055 linenr_T lnum; 3056 int doesrange; 3057 int failed = FALSE; 3058 funcdict_T fudi; 3059 3060 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3061 vim_free(fudi.fd_newkey); 3062 if (tofree == NULL) 3063 return; 3064 3065 /* Increase refcount on dictionary, it could get deleted when evaluating 3066 * the arguments. */ 3067 if (fudi.fd_dict != NULL) 3068 ++fudi.fd_dict->dv_refcount; 3069 3070 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3071 len = STRLEN(tofree); 3072 name = deref_func_name(tofree, &len); 3073 3074 /* Skip white space to allow ":call func ()". Not good, but required for 3075 * backward compatibility. */ 3076 startarg = skipwhite(arg); 3077 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3078 3079 if (*startarg != '(') 3080 { 3081 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3082 goto end; 3083 } 3084 3085 /* 3086 * When skipping, evaluate the function once, to find the end of the 3087 * arguments. 3088 * When the function takes a range, this is discovered after the first 3089 * call, and the loop is broken. 3090 */ 3091 if (eap->skip) 3092 { 3093 ++emsg_skip; 3094 lnum = eap->line2; /* do it once, also with an invalid range */ 3095 } 3096 else 3097 lnum = eap->line1; 3098 for ( ; lnum <= eap->line2; ++lnum) 3099 { 3100 if (!eap->skip && eap->addr_count > 0) 3101 { 3102 curwin->w_cursor.lnum = lnum; 3103 curwin->w_cursor.col = 0; 3104 } 3105 arg = startarg; 3106 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3107 eap->line1, eap->line2, &doesrange, 3108 !eap->skip, fudi.fd_dict) == FAIL) 3109 { 3110 failed = TRUE; 3111 break; 3112 } 3113 clear_tv(&rettv); 3114 if (doesrange || eap->skip) 3115 break; 3116 /* Stop when immediately aborting on error, or when an interrupt 3117 * occurred or an exception was thrown but not caught. 3118 * get_func_tv() returned OK, so that the check for trailing 3119 * characters below is executed. */ 3120 if (aborting()) 3121 break; 3122 } 3123 if (eap->skip) 3124 --emsg_skip; 3125 3126 if (!failed) 3127 { 3128 /* Check for trailing illegal characters and a following command. */ 3129 if (!ends_excmd(*arg)) 3130 { 3131 emsg_severe = TRUE; 3132 EMSG(_(e_trailing)); 3133 } 3134 else 3135 eap->nextcmd = check_nextcmd(arg); 3136 } 3137 3138 end: 3139 dict_unref(fudi.fd_dict); 3140 vim_free(tofree); 3141 } 3142 3143 /* 3144 * ":unlet[!] var1 ... " command. 3145 */ 3146 void 3147 ex_unlet(eap) 3148 exarg_T *eap; 3149 { 3150 ex_unletlock(eap, eap->arg, 0); 3151 } 3152 3153 /* 3154 * ":lockvar" and ":unlockvar" commands 3155 */ 3156 void 3157 ex_lockvar(eap) 3158 exarg_T *eap; 3159 { 3160 char_u *arg = eap->arg; 3161 int deep = 2; 3162 3163 if (eap->forceit) 3164 deep = -1; 3165 else if (vim_isdigit(*arg)) 3166 { 3167 deep = getdigits(&arg); 3168 arg = skipwhite(arg); 3169 } 3170 3171 ex_unletlock(eap, arg, deep); 3172 } 3173 3174 /* 3175 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3176 */ 3177 static void 3178 ex_unletlock(eap, argstart, deep) 3179 exarg_T *eap; 3180 char_u *argstart; 3181 int deep; 3182 { 3183 char_u *arg = argstart; 3184 char_u *name_end; 3185 int error = FALSE; 3186 lval_T lv; 3187 3188 do 3189 { 3190 /* Parse the name and find the end. */ 3191 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3192 FNE_CHECK_START); 3193 if (lv.ll_name == NULL) 3194 error = TRUE; /* error but continue parsing */ 3195 if (name_end == NULL || (!vim_iswhite(*name_end) 3196 && !ends_excmd(*name_end))) 3197 { 3198 if (name_end != NULL) 3199 { 3200 emsg_severe = TRUE; 3201 EMSG(_(e_trailing)); 3202 } 3203 if (!(eap->skip || error)) 3204 clear_lval(&lv); 3205 break; 3206 } 3207 3208 if (!error && !eap->skip) 3209 { 3210 if (eap->cmdidx == CMD_unlet) 3211 { 3212 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3213 error = TRUE; 3214 } 3215 else 3216 { 3217 if (do_lock_var(&lv, name_end, deep, 3218 eap->cmdidx == CMD_lockvar) == FAIL) 3219 error = TRUE; 3220 } 3221 } 3222 3223 if (!eap->skip) 3224 clear_lval(&lv); 3225 3226 arg = skipwhite(name_end); 3227 } while (!ends_excmd(*arg)); 3228 3229 eap->nextcmd = check_nextcmd(arg); 3230 } 3231 3232 static int 3233 do_unlet_var(lp, name_end, forceit) 3234 lval_T *lp; 3235 char_u *name_end; 3236 int forceit; 3237 { 3238 int ret = OK; 3239 int cc; 3240 3241 if (lp->ll_tv == NULL) 3242 { 3243 cc = *name_end; 3244 *name_end = NUL; 3245 3246 /* Normal name or expanded name. */ 3247 if (check_changedtick(lp->ll_name)) 3248 ret = FAIL; 3249 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3250 ret = FAIL; 3251 *name_end = cc; 3252 } 3253 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3254 return FAIL; 3255 else if (lp->ll_range) 3256 { 3257 listitem_T *li; 3258 3259 /* Delete a range of List items. */ 3260 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3261 { 3262 li = lp->ll_li->li_next; 3263 listitem_remove(lp->ll_list, lp->ll_li); 3264 lp->ll_li = li; 3265 ++lp->ll_n1; 3266 } 3267 } 3268 else 3269 { 3270 if (lp->ll_list != NULL) 3271 /* unlet a List item. */ 3272 listitem_remove(lp->ll_list, lp->ll_li); 3273 else 3274 /* unlet a Dictionary item. */ 3275 dictitem_remove(lp->ll_dict, lp->ll_di); 3276 } 3277 3278 return ret; 3279 } 3280 3281 /* 3282 * "unlet" a variable. Return OK if it existed, FAIL if not. 3283 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3284 */ 3285 int 3286 do_unlet(name, forceit) 3287 char_u *name; 3288 int forceit; 3289 { 3290 hashtab_T *ht; 3291 hashitem_T *hi; 3292 char_u *varname; 3293 3294 ht = find_var_ht(name, &varname); 3295 if (ht != NULL && *varname != NUL) 3296 { 3297 hi = hash_find(ht, varname); 3298 if (!HASHITEM_EMPTY(hi)) 3299 { 3300 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3301 return FAIL; 3302 delete_var(ht, hi); 3303 return OK; 3304 } 3305 } 3306 if (forceit) 3307 return OK; 3308 EMSG2(_("E108: No such variable: \"%s\""), name); 3309 return FAIL; 3310 } 3311 3312 /* 3313 * Lock or unlock variable indicated by "lp". 3314 * "deep" is the levels to go (-1 for unlimited); 3315 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3316 */ 3317 static int 3318 do_lock_var(lp, name_end, deep, lock) 3319 lval_T *lp; 3320 char_u *name_end; 3321 int deep; 3322 int lock; 3323 { 3324 int ret = OK; 3325 int cc; 3326 dictitem_T *di; 3327 3328 if (deep == 0) /* nothing to do */ 3329 return OK; 3330 3331 if (lp->ll_tv == NULL) 3332 { 3333 cc = *name_end; 3334 *name_end = NUL; 3335 3336 /* Normal name or expanded name. */ 3337 if (check_changedtick(lp->ll_name)) 3338 ret = FAIL; 3339 else 3340 { 3341 di = find_var(lp->ll_name, NULL); 3342 if (di == NULL) 3343 ret = FAIL; 3344 else 3345 { 3346 if (lock) 3347 di->di_flags |= DI_FLAGS_LOCK; 3348 else 3349 di->di_flags &= ~DI_FLAGS_LOCK; 3350 item_lock(&di->di_tv, deep, lock); 3351 } 3352 } 3353 *name_end = cc; 3354 } 3355 else if (lp->ll_range) 3356 { 3357 listitem_T *li = lp->ll_li; 3358 3359 /* (un)lock a range of List items. */ 3360 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3361 { 3362 item_lock(&li->li_tv, deep, lock); 3363 li = li->li_next; 3364 ++lp->ll_n1; 3365 } 3366 } 3367 else if (lp->ll_list != NULL) 3368 /* (un)lock a List item. */ 3369 item_lock(&lp->ll_li->li_tv, deep, lock); 3370 else 3371 /* un(lock) a Dictionary item. */ 3372 item_lock(&lp->ll_di->di_tv, deep, lock); 3373 3374 return ret; 3375 } 3376 3377 /* 3378 * Lock or unlock an item. "deep" is nr of levels to go. 3379 */ 3380 static void 3381 item_lock(tv, deep, lock) 3382 typval_T *tv; 3383 int deep; 3384 int lock; 3385 { 3386 static int recurse = 0; 3387 list_T *l; 3388 listitem_T *li; 3389 dict_T *d; 3390 hashitem_T *hi; 3391 int todo; 3392 3393 if (recurse >= DICT_MAXNEST) 3394 { 3395 EMSG(_("E743: variable nested too deep for (un)lock")); 3396 return; 3397 } 3398 if (deep == 0) 3399 return; 3400 ++recurse; 3401 3402 /* lock/unlock the item itself */ 3403 if (lock) 3404 tv->v_lock |= VAR_LOCKED; 3405 else 3406 tv->v_lock &= ~VAR_LOCKED; 3407 3408 switch (tv->v_type) 3409 { 3410 case VAR_LIST: 3411 if ((l = tv->vval.v_list) != NULL) 3412 { 3413 if (lock) 3414 l->lv_lock |= VAR_LOCKED; 3415 else 3416 l->lv_lock &= ~VAR_LOCKED; 3417 if (deep < 0 || deep > 1) 3418 /* recursive: lock/unlock the items the List contains */ 3419 for (li = l->lv_first; li != NULL; li = li->li_next) 3420 item_lock(&li->li_tv, deep - 1, lock); 3421 } 3422 break; 3423 case VAR_DICT: 3424 if ((d = tv->vval.v_dict) != NULL) 3425 { 3426 if (lock) 3427 d->dv_lock |= VAR_LOCKED; 3428 else 3429 d->dv_lock &= ~VAR_LOCKED; 3430 if (deep < 0 || deep > 1) 3431 { 3432 /* recursive: lock/unlock the items the List contains */ 3433 todo = d->dv_hashtab.ht_used; 3434 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3435 { 3436 if (!HASHITEM_EMPTY(hi)) 3437 { 3438 --todo; 3439 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3440 } 3441 } 3442 } 3443 } 3444 } 3445 --recurse; 3446 } 3447 3448 /* 3449 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3450 * it refers to a List or Dictionary that is locked. 3451 */ 3452 static int 3453 tv_islocked(tv) 3454 typval_T *tv; 3455 { 3456 return (tv->v_lock & VAR_LOCKED) 3457 || (tv->v_type == VAR_LIST 3458 && tv->vval.v_list != NULL 3459 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3460 || (tv->v_type == VAR_DICT 3461 && tv->vval.v_dict != NULL 3462 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3463 } 3464 3465 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3466 /* 3467 * Delete all "menutrans_" variables. 3468 */ 3469 void 3470 del_menutrans_vars() 3471 { 3472 hashitem_T *hi; 3473 int todo; 3474 3475 hash_lock(&globvarht); 3476 todo = globvarht.ht_used; 3477 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3478 { 3479 if (!HASHITEM_EMPTY(hi)) 3480 { 3481 --todo; 3482 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3483 delete_var(&globvarht, hi); 3484 } 3485 } 3486 hash_unlock(&globvarht); 3487 } 3488 #endif 3489 3490 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3491 3492 /* 3493 * Local string buffer for the next two functions to store a variable name 3494 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3495 * get_user_var_name(). 3496 */ 3497 3498 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3499 3500 static char_u *varnamebuf = NULL; 3501 static int varnamebuflen = 0; 3502 3503 /* 3504 * Function to concatenate a prefix and a variable name. 3505 */ 3506 static char_u * 3507 cat_prefix_varname(prefix, name) 3508 int prefix; 3509 char_u *name; 3510 { 3511 int len; 3512 3513 len = (int)STRLEN(name) + 3; 3514 if (len > varnamebuflen) 3515 { 3516 vim_free(varnamebuf); 3517 len += 10; /* some additional space */ 3518 varnamebuf = alloc(len); 3519 if (varnamebuf == NULL) 3520 { 3521 varnamebuflen = 0; 3522 return NULL; 3523 } 3524 varnamebuflen = len; 3525 } 3526 *varnamebuf = prefix; 3527 varnamebuf[1] = ':'; 3528 STRCPY(varnamebuf + 2, name); 3529 return varnamebuf; 3530 } 3531 3532 /* 3533 * Function given to ExpandGeneric() to obtain the list of user defined 3534 * (global/buffer/window/built-in) variable names. 3535 */ 3536 /*ARGSUSED*/ 3537 char_u * 3538 get_user_var_name(xp, idx) 3539 expand_T *xp; 3540 int idx; 3541 { 3542 static long_u gdone; 3543 static long_u bdone; 3544 static long_u wdone; 3545 static int vidx; 3546 static hashitem_T *hi; 3547 hashtab_T *ht; 3548 3549 if (idx == 0) 3550 gdone = bdone = wdone = vidx = 0; 3551 3552 /* Global variables */ 3553 if (gdone < globvarht.ht_used) 3554 { 3555 if (gdone++ == 0) 3556 hi = globvarht.ht_array; 3557 else 3558 ++hi; 3559 while (HASHITEM_EMPTY(hi)) 3560 ++hi; 3561 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3562 return cat_prefix_varname('g', hi->hi_key); 3563 return hi->hi_key; 3564 } 3565 3566 /* b: variables */ 3567 ht = &curbuf->b_vars.dv_hashtab; 3568 if (bdone < ht->ht_used) 3569 { 3570 if (bdone++ == 0) 3571 hi = ht->ht_array; 3572 else 3573 ++hi; 3574 while (HASHITEM_EMPTY(hi)) 3575 ++hi; 3576 return cat_prefix_varname('b', hi->hi_key); 3577 } 3578 if (bdone == ht->ht_used) 3579 { 3580 ++bdone; 3581 return (char_u *)"b:changedtick"; 3582 } 3583 3584 /* w: variables */ 3585 ht = &curwin->w_vars.dv_hashtab; 3586 if (wdone < ht->ht_used) 3587 { 3588 if (wdone++ == 0) 3589 hi = ht->ht_array; 3590 else 3591 ++hi; 3592 while (HASHITEM_EMPTY(hi)) 3593 ++hi; 3594 return cat_prefix_varname('w', hi->hi_key); 3595 } 3596 3597 /* v: variables */ 3598 if (vidx < VV_LEN) 3599 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3600 3601 vim_free(varnamebuf); 3602 varnamebuf = NULL; 3603 varnamebuflen = 0; 3604 return NULL; 3605 } 3606 3607 #endif /* FEAT_CMDL_COMPL */ 3608 3609 /* 3610 * types for expressions. 3611 */ 3612 typedef enum 3613 { 3614 TYPE_UNKNOWN = 0 3615 , TYPE_EQUAL /* == */ 3616 , TYPE_NEQUAL /* != */ 3617 , TYPE_GREATER /* > */ 3618 , TYPE_GEQUAL /* >= */ 3619 , TYPE_SMALLER /* < */ 3620 , TYPE_SEQUAL /* <= */ 3621 , TYPE_MATCH /* =~ */ 3622 , TYPE_NOMATCH /* !~ */ 3623 } exptype_T; 3624 3625 /* 3626 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3627 * executed. The function may return OK, but the rettv will be of type 3628 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3629 */ 3630 3631 /* 3632 * Handle zero level expression. 3633 * This calls eval1() and handles error message and nextcmd. 3634 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3635 * Note: "rettv.v_lock" is not set. 3636 * Return OK or FAIL. 3637 */ 3638 static int 3639 eval0(arg, rettv, nextcmd, evaluate) 3640 char_u *arg; 3641 typval_T *rettv; 3642 char_u **nextcmd; 3643 int evaluate; 3644 { 3645 int ret; 3646 char_u *p; 3647 3648 p = skipwhite(arg); 3649 ret = eval1(&p, rettv, evaluate); 3650 if (ret == FAIL || !ends_excmd(*p)) 3651 { 3652 if (ret != FAIL) 3653 clear_tv(rettv); 3654 /* 3655 * Report the invalid expression unless the expression evaluation has 3656 * been cancelled due to an aborting error, an interrupt, or an 3657 * exception. 3658 */ 3659 if (!aborting()) 3660 EMSG2(_(e_invexpr2), arg); 3661 ret = FAIL; 3662 } 3663 if (nextcmd != NULL) 3664 *nextcmd = check_nextcmd(p); 3665 3666 return ret; 3667 } 3668 3669 /* 3670 * Handle top level expression: 3671 * expr1 ? expr0 : expr0 3672 * 3673 * "arg" must point to the first non-white of the expression. 3674 * "arg" is advanced to the next non-white after the recognized expression. 3675 * 3676 * Note: "rettv.v_lock" is not set. 3677 * 3678 * Return OK or FAIL. 3679 */ 3680 static int 3681 eval1(arg, rettv, evaluate) 3682 char_u **arg; 3683 typval_T *rettv; 3684 int evaluate; 3685 { 3686 int result; 3687 typval_T var2; 3688 3689 /* 3690 * Get the first variable. 3691 */ 3692 if (eval2(arg, rettv, evaluate) == FAIL) 3693 return FAIL; 3694 3695 if ((*arg)[0] == '?') 3696 { 3697 result = FALSE; 3698 if (evaluate) 3699 { 3700 int error = FALSE; 3701 3702 if (get_tv_number_chk(rettv, &error) != 0) 3703 result = TRUE; 3704 clear_tv(rettv); 3705 if (error) 3706 return FAIL; 3707 } 3708 3709 /* 3710 * Get the second variable. 3711 */ 3712 *arg = skipwhite(*arg + 1); 3713 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3714 return FAIL; 3715 3716 /* 3717 * Check for the ":". 3718 */ 3719 if ((*arg)[0] != ':') 3720 { 3721 EMSG(_("E109: Missing ':' after '?'")); 3722 if (evaluate && result) 3723 clear_tv(rettv); 3724 return FAIL; 3725 } 3726 3727 /* 3728 * Get the third variable. 3729 */ 3730 *arg = skipwhite(*arg + 1); 3731 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3732 { 3733 if (evaluate && result) 3734 clear_tv(rettv); 3735 return FAIL; 3736 } 3737 if (evaluate && !result) 3738 *rettv = var2; 3739 } 3740 3741 return OK; 3742 } 3743 3744 /* 3745 * Handle first level expression: 3746 * expr2 || expr2 || expr2 logical OR 3747 * 3748 * "arg" must point to the first non-white of the expression. 3749 * "arg" is advanced to the next non-white after the recognized expression. 3750 * 3751 * Return OK or FAIL. 3752 */ 3753 static int 3754 eval2(arg, rettv, evaluate) 3755 char_u **arg; 3756 typval_T *rettv; 3757 int evaluate; 3758 { 3759 typval_T var2; 3760 long result; 3761 int first; 3762 int error = FALSE; 3763 3764 /* 3765 * Get the first variable. 3766 */ 3767 if (eval3(arg, rettv, evaluate) == FAIL) 3768 return FAIL; 3769 3770 /* 3771 * Repeat until there is no following "||". 3772 */ 3773 first = TRUE; 3774 result = FALSE; 3775 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3776 { 3777 if (evaluate && first) 3778 { 3779 if (get_tv_number_chk(rettv, &error) != 0) 3780 result = TRUE; 3781 clear_tv(rettv); 3782 if (error) 3783 return FAIL; 3784 first = FALSE; 3785 } 3786 3787 /* 3788 * Get the second variable. 3789 */ 3790 *arg = skipwhite(*arg + 2); 3791 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3792 return FAIL; 3793 3794 /* 3795 * Compute the result. 3796 */ 3797 if (evaluate && !result) 3798 { 3799 if (get_tv_number_chk(&var2, &error) != 0) 3800 result = TRUE; 3801 clear_tv(&var2); 3802 if (error) 3803 return FAIL; 3804 } 3805 if (evaluate) 3806 { 3807 rettv->v_type = VAR_NUMBER; 3808 rettv->vval.v_number = result; 3809 } 3810 } 3811 3812 return OK; 3813 } 3814 3815 /* 3816 * Handle second level expression: 3817 * expr3 && expr3 && expr3 logical AND 3818 * 3819 * "arg" must point to the first non-white of the expression. 3820 * "arg" is advanced to the next non-white after the recognized expression. 3821 * 3822 * Return OK or FAIL. 3823 */ 3824 static int 3825 eval3(arg, rettv, evaluate) 3826 char_u **arg; 3827 typval_T *rettv; 3828 int evaluate; 3829 { 3830 typval_T var2; 3831 long result; 3832 int first; 3833 int error = FALSE; 3834 3835 /* 3836 * Get the first variable. 3837 */ 3838 if (eval4(arg, rettv, evaluate) == FAIL) 3839 return FAIL; 3840 3841 /* 3842 * Repeat until there is no following "&&". 3843 */ 3844 first = TRUE; 3845 result = TRUE; 3846 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3847 { 3848 if (evaluate && first) 3849 { 3850 if (get_tv_number_chk(rettv, &error) == 0) 3851 result = FALSE; 3852 clear_tv(rettv); 3853 if (error) 3854 return FAIL; 3855 first = FALSE; 3856 } 3857 3858 /* 3859 * Get the second variable. 3860 */ 3861 *arg = skipwhite(*arg + 2); 3862 if (eval4(arg, &var2, evaluate && result) == FAIL) 3863 return FAIL; 3864 3865 /* 3866 * Compute the result. 3867 */ 3868 if (evaluate && result) 3869 { 3870 if (get_tv_number_chk(&var2, &error) == 0) 3871 result = FALSE; 3872 clear_tv(&var2); 3873 if (error) 3874 return FAIL; 3875 } 3876 if (evaluate) 3877 { 3878 rettv->v_type = VAR_NUMBER; 3879 rettv->vval.v_number = result; 3880 } 3881 } 3882 3883 return OK; 3884 } 3885 3886 /* 3887 * Handle third level expression: 3888 * var1 == var2 3889 * var1 =~ var2 3890 * var1 != var2 3891 * var1 !~ var2 3892 * var1 > var2 3893 * var1 >= var2 3894 * var1 < var2 3895 * var1 <= var2 3896 * var1 is var2 3897 * var1 isnot var2 3898 * 3899 * "arg" must point to the first non-white of the expression. 3900 * "arg" is advanced to the next non-white after the recognized expression. 3901 * 3902 * Return OK or FAIL. 3903 */ 3904 static int 3905 eval4(arg, rettv, evaluate) 3906 char_u **arg; 3907 typval_T *rettv; 3908 int evaluate; 3909 { 3910 typval_T var2; 3911 char_u *p; 3912 int i; 3913 exptype_T type = TYPE_UNKNOWN; 3914 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3915 int len = 2; 3916 long n1, n2; 3917 char_u *s1, *s2; 3918 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3919 regmatch_T regmatch; 3920 int ic; 3921 char_u *save_cpo; 3922 3923 /* 3924 * Get the first variable. 3925 */ 3926 if (eval5(arg, rettv, evaluate) == FAIL) 3927 return FAIL; 3928 3929 p = *arg; 3930 switch (p[0]) 3931 { 3932 case '=': if (p[1] == '=') 3933 type = TYPE_EQUAL; 3934 else if (p[1] == '~') 3935 type = TYPE_MATCH; 3936 break; 3937 case '!': if (p[1] == '=') 3938 type = TYPE_NEQUAL; 3939 else if (p[1] == '~') 3940 type = TYPE_NOMATCH; 3941 break; 3942 case '>': if (p[1] != '=') 3943 { 3944 type = TYPE_GREATER; 3945 len = 1; 3946 } 3947 else 3948 type = TYPE_GEQUAL; 3949 break; 3950 case '<': if (p[1] != '=') 3951 { 3952 type = TYPE_SMALLER; 3953 len = 1; 3954 } 3955 else 3956 type = TYPE_SEQUAL; 3957 break; 3958 case 'i': if (p[1] == 's') 3959 { 3960 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3961 len = 5; 3962 if (!vim_isIDc(p[len])) 3963 { 3964 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3965 type_is = TRUE; 3966 } 3967 } 3968 break; 3969 } 3970 3971 /* 3972 * If there is a comparitive operator, use it. 3973 */ 3974 if (type != TYPE_UNKNOWN) 3975 { 3976 /* extra question mark appended: ignore case */ 3977 if (p[len] == '?') 3978 { 3979 ic = TRUE; 3980 ++len; 3981 } 3982 /* extra '#' appended: match case */ 3983 else if (p[len] == '#') 3984 { 3985 ic = FALSE; 3986 ++len; 3987 } 3988 /* nothing appened: use 'ignorecase' */ 3989 else 3990 ic = p_ic; 3991 3992 /* 3993 * Get the second variable. 3994 */ 3995 *arg = skipwhite(p + len); 3996 if (eval5(arg, &var2, evaluate) == FAIL) 3997 { 3998 clear_tv(rettv); 3999 return FAIL; 4000 } 4001 4002 if (evaluate) 4003 { 4004 if (type_is && rettv->v_type != var2.v_type) 4005 { 4006 /* For "is" a different type always means FALSE, for "notis" 4007 * it means TRUE. */ 4008 n1 = (type == TYPE_NEQUAL); 4009 } 4010 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4011 { 4012 if (type_is) 4013 { 4014 n1 = (rettv->v_type == var2.v_type 4015 && rettv->vval.v_list == var2.vval.v_list); 4016 if (type == TYPE_NEQUAL) 4017 n1 = !n1; 4018 } 4019 else if (rettv->v_type != var2.v_type 4020 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4021 { 4022 if (rettv->v_type != var2.v_type) 4023 EMSG(_("E691: Can only compare List with List")); 4024 else 4025 EMSG(_("E692: Invalid operation for Lists")); 4026 clear_tv(rettv); 4027 clear_tv(&var2); 4028 return FAIL; 4029 } 4030 else 4031 { 4032 /* Compare two Lists for being equal or unequal. */ 4033 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 4034 if (type == TYPE_NEQUAL) 4035 n1 = !n1; 4036 } 4037 } 4038 4039 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4040 { 4041 if (type_is) 4042 { 4043 n1 = (rettv->v_type == var2.v_type 4044 && rettv->vval.v_dict == var2.vval.v_dict); 4045 if (type == TYPE_NEQUAL) 4046 n1 = !n1; 4047 } 4048 else if (rettv->v_type != var2.v_type 4049 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4050 { 4051 if (rettv->v_type != var2.v_type) 4052 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4053 else 4054 EMSG(_("E736: Invalid operation for Dictionary")); 4055 clear_tv(rettv); 4056 clear_tv(&var2); 4057 return FAIL; 4058 } 4059 else 4060 { 4061 /* Compare two Dictionaries for being equal or unequal. */ 4062 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4063 if (type == TYPE_NEQUAL) 4064 n1 = !n1; 4065 } 4066 } 4067 4068 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4069 { 4070 if (rettv->v_type != var2.v_type 4071 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4072 { 4073 if (rettv->v_type != var2.v_type) 4074 EMSG(_("E693: Can only compare Funcref with Funcref")); 4075 else 4076 EMSG(_("E694: Invalid operation for Funcrefs")); 4077 clear_tv(rettv); 4078 clear_tv(&var2); 4079 return FAIL; 4080 } 4081 else 4082 { 4083 /* Compare two Funcrefs for being equal or unequal. */ 4084 if (rettv->vval.v_string == NULL 4085 || var2.vval.v_string == NULL) 4086 n1 = FALSE; 4087 else 4088 n1 = STRCMP(rettv->vval.v_string, 4089 var2.vval.v_string) == 0; 4090 if (type == TYPE_NEQUAL) 4091 n1 = !n1; 4092 } 4093 } 4094 4095 /* 4096 * If one of the two variables is a number, compare as a number. 4097 * When using "=~" or "!~", always compare as string. 4098 */ 4099 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4100 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4101 { 4102 n1 = get_tv_number(rettv); 4103 n2 = get_tv_number(&var2); 4104 switch (type) 4105 { 4106 case TYPE_EQUAL: n1 = (n1 == n2); break; 4107 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4108 case TYPE_GREATER: n1 = (n1 > n2); break; 4109 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4110 case TYPE_SMALLER: n1 = (n1 < n2); break; 4111 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4112 case TYPE_UNKNOWN: 4113 case TYPE_MATCH: 4114 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4115 } 4116 } 4117 else 4118 { 4119 s1 = get_tv_string_buf(rettv, buf1); 4120 s2 = get_tv_string_buf(&var2, buf2); 4121 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4122 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4123 else 4124 i = 0; 4125 n1 = FALSE; 4126 switch (type) 4127 { 4128 case TYPE_EQUAL: n1 = (i == 0); break; 4129 case TYPE_NEQUAL: n1 = (i != 0); break; 4130 case TYPE_GREATER: n1 = (i > 0); break; 4131 case TYPE_GEQUAL: n1 = (i >= 0); break; 4132 case TYPE_SMALLER: n1 = (i < 0); break; 4133 case TYPE_SEQUAL: n1 = (i <= 0); break; 4134 4135 case TYPE_MATCH: 4136 case TYPE_NOMATCH: 4137 /* avoid 'l' flag in 'cpoptions' */ 4138 save_cpo = p_cpo; 4139 p_cpo = (char_u *)""; 4140 regmatch.regprog = vim_regcomp(s2, 4141 RE_MAGIC + RE_STRING); 4142 regmatch.rm_ic = ic; 4143 if (regmatch.regprog != NULL) 4144 { 4145 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4146 vim_free(regmatch.regprog); 4147 if (type == TYPE_NOMATCH) 4148 n1 = !n1; 4149 } 4150 p_cpo = save_cpo; 4151 break; 4152 4153 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4154 } 4155 } 4156 clear_tv(rettv); 4157 clear_tv(&var2); 4158 rettv->v_type = VAR_NUMBER; 4159 rettv->vval.v_number = n1; 4160 } 4161 } 4162 4163 return OK; 4164 } 4165 4166 /* 4167 * Handle fourth level expression: 4168 * + number addition 4169 * - number subtraction 4170 * . string concatenation 4171 * 4172 * "arg" must point to the first non-white of the expression. 4173 * "arg" is advanced to the next non-white after the recognized expression. 4174 * 4175 * Return OK or FAIL. 4176 */ 4177 static int 4178 eval5(arg, rettv, evaluate) 4179 char_u **arg; 4180 typval_T *rettv; 4181 int evaluate; 4182 { 4183 typval_T var2; 4184 typval_T var3; 4185 int op; 4186 long n1, n2; 4187 char_u *s1, *s2; 4188 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4189 char_u *p; 4190 4191 /* 4192 * Get the first variable. 4193 */ 4194 if (eval6(arg, rettv, evaluate) == FAIL) 4195 return FAIL; 4196 4197 /* 4198 * Repeat computing, until no '+', '-' or '.' is following. 4199 */ 4200 for (;;) 4201 { 4202 op = **arg; 4203 if (op != '+' && op != '-' && op != '.') 4204 break; 4205 4206 if (op != '+' || rettv->v_type != VAR_LIST) 4207 { 4208 /* For "list + ...", an illegal use of the first operand as 4209 * a number cannot be determined before evaluating the 2nd 4210 * operand: if this is also a list, all is ok. 4211 * For "something . ...", "something - ..." or "non-list + ...", 4212 * we know that the first operand needs to be a string or number 4213 * without evaluating the 2nd operand. So check before to avoid 4214 * side effects after an error. */ 4215 if (evaluate && get_tv_string_chk(rettv) == NULL) 4216 { 4217 clear_tv(rettv); 4218 return FAIL; 4219 } 4220 } 4221 4222 /* 4223 * Get the second variable. 4224 */ 4225 *arg = skipwhite(*arg + 1); 4226 if (eval6(arg, &var2, evaluate) == FAIL) 4227 { 4228 clear_tv(rettv); 4229 return FAIL; 4230 } 4231 4232 if (evaluate) 4233 { 4234 /* 4235 * Compute the result. 4236 */ 4237 if (op == '.') 4238 { 4239 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4240 s2 = get_tv_string_buf_chk(&var2, buf2); 4241 if (s2 == NULL) /* type error ? */ 4242 { 4243 clear_tv(rettv); 4244 clear_tv(&var2); 4245 return FAIL; 4246 } 4247 p = concat_str(s1, s2); 4248 clear_tv(rettv); 4249 rettv->v_type = VAR_STRING; 4250 rettv->vval.v_string = p; 4251 } 4252 else if (op == '+' && rettv->v_type == VAR_LIST 4253 && var2.v_type == VAR_LIST) 4254 { 4255 /* concatenate Lists */ 4256 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4257 &var3) == FAIL) 4258 { 4259 clear_tv(rettv); 4260 clear_tv(&var2); 4261 return FAIL; 4262 } 4263 clear_tv(rettv); 4264 *rettv = var3; 4265 } 4266 else 4267 { 4268 int error = FALSE; 4269 4270 n1 = get_tv_number_chk(rettv, &error); 4271 if (error) 4272 { 4273 /* This can only happen for "list + non-list". 4274 * For "non-list + ..." or "something - ...", we returned 4275 * before evaluating the 2nd operand. */ 4276 clear_tv(rettv); 4277 return FAIL; 4278 } 4279 n2 = get_tv_number_chk(&var2, &error); 4280 if (error) 4281 { 4282 clear_tv(rettv); 4283 clear_tv(&var2); 4284 return FAIL; 4285 } 4286 clear_tv(rettv); 4287 if (op == '+') 4288 n1 = n1 + n2; 4289 else 4290 n1 = n1 - n2; 4291 rettv->v_type = VAR_NUMBER; 4292 rettv->vval.v_number = n1; 4293 } 4294 clear_tv(&var2); 4295 } 4296 } 4297 return OK; 4298 } 4299 4300 /* 4301 * Handle fifth level expression: 4302 * * number multiplication 4303 * / number division 4304 * % number modulo 4305 * 4306 * "arg" must point to the first non-white of the expression. 4307 * "arg" is advanced to the next non-white after the recognized expression. 4308 * 4309 * Return OK or FAIL. 4310 */ 4311 static int 4312 eval6(arg, rettv, evaluate) 4313 char_u **arg; 4314 typval_T *rettv; 4315 int evaluate; 4316 { 4317 typval_T var2; 4318 int op; 4319 long n1, n2; 4320 int error = FALSE; 4321 4322 /* 4323 * Get the first variable. 4324 */ 4325 if (eval7(arg, rettv, evaluate) == FAIL) 4326 return FAIL; 4327 4328 /* 4329 * Repeat computing, until no '*', '/' or '%' is following. 4330 */ 4331 for (;;) 4332 { 4333 op = **arg; 4334 if (op != '*' && op != '/' && op != '%') 4335 break; 4336 4337 if (evaluate) 4338 { 4339 n1 = get_tv_number_chk(rettv, &error); 4340 clear_tv(rettv); 4341 if (error) 4342 return FAIL; 4343 } 4344 else 4345 n1 = 0; 4346 4347 /* 4348 * Get the second variable. 4349 */ 4350 *arg = skipwhite(*arg + 1); 4351 if (eval7(arg, &var2, evaluate) == FAIL) 4352 return FAIL; 4353 4354 if (evaluate) 4355 { 4356 n2 = get_tv_number_chk(&var2, &error); 4357 clear_tv(&var2); 4358 if (error) 4359 return FAIL; 4360 4361 /* 4362 * Compute the result. 4363 */ 4364 if (op == '*') 4365 n1 = n1 * n2; 4366 else if (op == '/') 4367 { 4368 if (n2 == 0) /* give an error message? */ 4369 n1 = 0x7fffffffL; 4370 else 4371 n1 = n1 / n2; 4372 } 4373 else 4374 { 4375 if (n2 == 0) /* give an error message? */ 4376 n1 = 0; 4377 else 4378 n1 = n1 % n2; 4379 } 4380 rettv->v_type = VAR_NUMBER; 4381 rettv->vval.v_number = n1; 4382 } 4383 } 4384 4385 return OK; 4386 } 4387 4388 /* 4389 * Handle sixth level expression: 4390 * number number constant 4391 * "string" string contstant 4392 * 'string' literal string contstant 4393 * &option-name option value 4394 * @r register contents 4395 * identifier variable value 4396 * function() function call 4397 * $VAR environment variable 4398 * (expression) nested expression 4399 * [expr, expr] List 4400 * {key: val, key: val} Dictionary 4401 * 4402 * Also handle: 4403 * ! in front logical NOT 4404 * - in front unary minus 4405 * + in front unary plus (ignored) 4406 * trailing [] subscript in String or List 4407 * trailing .name entry in Dictionary 4408 * 4409 * "arg" must point to the first non-white of the expression. 4410 * "arg" is advanced to the next non-white after the recognized expression. 4411 * 4412 * Return OK or FAIL. 4413 */ 4414 static int 4415 eval7(arg, rettv, evaluate) 4416 char_u **arg; 4417 typval_T *rettv; 4418 int evaluate; 4419 { 4420 long n; 4421 int len; 4422 char_u *s; 4423 int val; 4424 char_u *start_leader, *end_leader; 4425 int ret = OK; 4426 char_u *alias; 4427 4428 /* 4429 * Initialise variable so that clear_tv() can't mistake this for a 4430 * string and free a string that isn't there. 4431 */ 4432 rettv->v_type = VAR_UNKNOWN; 4433 4434 /* 4435 * Skip '!' and '-' characters. They are handled later. 4436 */ 4437 start_leader = *arg; 4438 while (**arg == '!' || **arg == '-' || **arg == '+') 4439 *arg = skipwhite(*arg + 1); 4440 end_leader = *arg; 4441 4442 switch (**arg) 4443 { 4444 /* 4445 * Number constant. 4446 */ 4447 case '0': 4448 case '1': 4449 case '2': 4450 case '3': 4451 case '4': 4452 case '5': 4453 case '6': 4454 case '7': 4455 case '8': 4456 case '9': 4457 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4458 *arg += len; 4459 if (evaluate) 4460 { 4461 rettv->v_type = VAR_NUMBER; 4462 rettv->vval.v_number = n; 4463 } 4464 break; 4465 4466 /* 4467 * String constant: "string". 4468 */ 4469 case '"': ret = get_string_tv(arg, rettv, evaluate); 4470 break; 4471 4472 /* 4473 * Literal string constant: 'str''ing'. 4474 */ 4475 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4476 break; 4477 4478 /* 4479 * List: [expr, expr] 4480 */ 4481 case '[': ret = get_list_tv(arg, rettv, evaluate); 4482 break; 4483 4484 /* 4485 * Dictionary: {key: val, key: val} 4486 */ 4487 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4488 break; 4489 4490 /* 4491 * Option value: &name 4492 */ 4493 case '&': ret = get_option_tv(arg, rettv, evaluate); 4494 break; 4495 4496 /* 4497 * Environment variable: $VAR. 4498 */ 4499 case '$': ret = get_env_tv(arg, rettv, evaluate); 4500 break; 4501 4502 /* 4503 * Register contents: @r. 4504 */ 4505 case '@': ++*arg; 4506 if (evaluate) 4507 { 4508 rettv->v_type = VAR_STRING; 4509 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4510 } 4511 if (**arg != NUL) 4512 ++*arg; 4513 break; 4514 4515 /* 4516 * nested expression: (expression). 4517 */ 4518 case '(': *arg = skipwhite(*arg + 1); 4519 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4520 if (**arg == ')') 4521 ++*arg; 4522 else if (ret == OK) 4523 { 4524 EMSG(_("E110: Missing ')'")); 4525 clear_tv(rettv); 4526 ret = FAIL; 4527 } 4528 break; 4529 4530 default: ret = NOTDONE; 4531 break; 4532 } 4533 4534 if (ret == NOTDONE) 4535 { 4536 /* 4537 * Must be a variable or function name. 4538 * Can also be a curly-braces kind of name: {expr}. 4539 */ 4540 s = *arg; 4541 len = get_name_len(arg, &alias, evaluate, TRUE); 4542 if (alias != NULL) 4543 s = alias; 4544 4545 if (len <= 0) 4546 ret = FAIL; 4547 else 4548 { 4549 if (**arg == '(') /* recursive! */ 4550 { 4551 /* If "s" is the name of a variable of type VAR_FUNC 4552 * use its contents. */ 4553 s = deref_func_name(s, &len); 4554 4555 /* Invoke the function. */ 4556 ret = get_func_tv(s, len, rettv, arg, 4557 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4558 &len, evaluate, NULL); 4559 /* Stop the expression evaluation when immediately 4560 * aborting on error, or when an interrupt occurred or 4561 * an exception was thrown but not caught. */ 4562 if (aborting()) 4563 { 4564 if (ret == OK) 4565 clear_tv(rettv); 4566 ret = FAIL; 4567 } 4568 } 4569 else if (evaluate) 4570 ret = get_var_tv(s, len, rettv, TRUE); 4571 else 4572 ret = OK; 4573 } 4574 4575 if (alias != NULL) 4576 vim_free(alias); 4577 } 4578 4579 *arg = skipwhite(*arg); 4580 4581 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4582 * expr(expr). */ 4583 if (ret == OK) 4584 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4585 4586 /* 4587 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4588 */ 4589 if (ret == OK && evaluate && end_leader > start_leader) 4590 { 4591 int error = FALSE; 4592 4593 val = get_tv_number_chk(rettv, &error); 4594 if (error) 4595 { 4596 clear_tv(rettv); 4597 ret = FAIL; 4598 } 4599 else 4600 { 4601 while (end_leader > start_leader) 4602 { 4603 --end_leader; 4604 if (*end_leader == '!') 4605 val = !val; 4606 else if (*end_leader == '-') 4607 val = -val; 4608 } 4609 clear_tv(rettv); 4610 rettv->v_type = VAR_NUMBER; 4611 rettv->vval.v_number = val; 4612 } 4613 } 4614 4615 return ret; 4616 } 4617 4618 /* 4619 * Evaluate an "[expr]" or "[expr:expr]" index. 4620 * "*arg" points to the '['. 4621 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4622 */ 4623 static int 4624 eval_index(arg, rettv, evaluate, verbose) 4625 char_u **arg; 4626 typval_T *rettv; 4627 int evaluate; 4628 int verbose; /* give error messages */ 4629 { 4630 int empty1 = FALSE, empty2 = FALSE; 4631 typval_T var1, var2; 4632 long n1, n2 = 0; 4633 long len = -1; 4634 int range = FALSE; 4635 char_u *s; 4636 char_u *key = NULL; 4637 4638 if (rettv->v_type == VAR_FUNC) 4639 { 4640 if (verbose) 4641 EMSG(_("E695: Cannot index a Funcref")); 4642 return FAIL; 4643 } 4644 4645 if (**arg == '.') 4646 { 4647 /* 4648 * dict.name 4649 */ 4650 key = *arg + 1; 4651 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4652 ; 4653 if (len == 0) 4654 return FAIL; 4655 *arg = skipwhite(key + len); 4656 } 4657 else 4658 { 4659 /* 4660 * something[idx] 4661 * 4662 * Get the (first) variable from inside the []. 4663 */ 4664 *arg = skipwhite(*arg + 1); 4665 if (**arg == ':') 4666 empty1 = TRUE; 4667 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4668 return FAIL; 4669 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4670 { 4671 /* not a number or string */ 4672 clear_tv(&var1); 4673 return FAIL; 4674 } 4675 4676 /* 4677 * Get the second variable from inside the [:]. 4678 */ 4679 if (**arg == ':') 4680 { 4681 range = TRUE; 4682 *arg = skipwhite(*arg + 1); 4683 if (**arg == ']') 4684 empty2 = TRUE; 4685 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4686 { 4687 if (!empty1) 4688 clear_tv(&var1); 4689 return FAIL; 4690 } 4691 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4692 { 4693 /* not a number or string */ 4694 if (!empty1) 4695 clear_tv(&var1); 4696 clear_tv(&var2); 4697 return FAIL; 4698 } 4699 } 4700 4701 /* Check for the ']'. */ 4702 if (**arg != ']') 4703 { 4704 if (verbose) 4705 EMSG(_(e_missbrac)); 4706 clear_tv(&var1); 4707 if (range) 4708 clear_tv(&var2); 4709 return FAIL; 4710 } 4711 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4712 } 4713 4714 if (evaluate) 4715 { 4716 n1 = 0; 4717 if (!empty1 && rettv->v_type != VAR_DICT) 4718 { 4719 n1 = get_tv_number(&var1); 4720 clear_tv(&var1); 4721 } 4722 if (range) 4723 { 4724 if (empty2) 4725 n2 = -1; 4726 else 4727 { 4728 n2 = get_tv_number(&var2); 4729 clear_tv(&var2); 4730 } 4731 } 4732 4733 switch (rettv->v_type) 4734 { 4735 case VAR_NUMBER: 4736 case VAR_STRING: 4737 s = get_tv_string(rettv); 4738 len = (long)STRLEN(s); 4739 if (range) 4740 { 4741 /* The resulting variable is a substring. If the indexes 4742 * are out of range the result is empty. */ 4743 if (n1 < 0) 4744 { 4745 n1 = len + n1; 4746 if (n1 < 0) 4747 n1 = 0; 4748 } 4749 if (n2 < 0) 4750 n2 = len + n2; 4751 else if (n2 >= len) 4752 n2 = len; 4753 if (n1 >= len || n2 < 0 || n1 > n2) 4754 s = NULL; 4755 else 4756 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4757 } 4758 else 4759 { 4760 /* The resulting variable is a string of a single 4761 * character. If the index is too big or negative the 4762 * result is empty. */ 4763 if (n1 >= len || n1 < 0) 4764 s = NULL; 4765 else 4766 s = vim_strnsave(s + n1, 1); 4767 } 4768 clear_tv(rettv); 4769 rettv->v_type = VAR_STRING; 4770 rettv->vval.v_string = s; 4771 break; 4772 4773 case VAR_LIST: 4774 len = list_len(rettv->vval.v_list); 4775 if (n1 < 0) 4776 n1 = len + n1; 4777 if (!empty1 && (n1 < 0 || n1 >= len)) 4778 { 4779 if (verbose) 4780 EMSGN(_(e_listidx), n1); 4781 return FAIL; 4782 } 4783 if (range) 4784 { 4785 list_T *l; 4786 listitem_T *item; 4787 4788 if (n2 < 0) 4789 n2 = len + n2; 4790 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4791 { 4792 if (verbose) 4793 EMSGN(_(e_listidx), n2); 4794 return FAIL; 4795 } 4796 l = list_alloc(); 4797 if (l == NULL) 4798 return FAIL; 4799 for (item = list_find(rettv->vval.v_list, n1); 4800 n1 <= n2; ++n1) 4801 { 4802 if (list_append_tv(l, &item->li_tv) == FAIL) 4803 { 4804 list_free(l); 4805 return FAIL; 4806 } 4807 item = item->li_next; 4808 } 4809 clear_tv(rettv); 4810 rettv->v_type = VAR_LIST; 4811 rettv->vval.v_list = l; 4812 ++l->lv_refcount; 4813 } 4814 else 4815 { 4816 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4817 &var1); 4818 clear_tv(rettv); 4819 *rettv = var1; 4820 } 4821 break; 4822 4823 case VAR_DICT: 4824 if (range) 4825 { 4826 if (verbose) 4827 EMSG(_(e_dictrange)); 4828 if (len == -1) 4829 clear_tv(&var1); 4830 return FAIL; 4831 } 4832 { 4833 dictitem_T *item; 4834 4835 if (len == -1) 4836 { 4837 key = get_tv_string(&var1); 4838 if (*key == NUL) 4839 { 4840 if (verbose) 4841 EMSG(_(e_emptykey)); 4842 clear_tv(&var1); 4843 return FAIL; 4844 } 4845 } 4846 4847 item = dict_find(rettv->vval.v_dict, key, (int)len); 4848 4849 if (item == NULL && verbose) 4850 EMSG2(_(e_dictkey), key); 4851 if (len == -1) 4852 clear_tv(&var1); 4853 if (item == NULL) 4854 return FAIL; 4855 4856 copy_tv(&item->di_tv, &var1); 4857 clear_tv(rettv); 4858 *rettv = var1; 4859 } 4860 break; 4861 } 4862 } 4863 4864 return OK; 4865 } 4866 4867 /* 4868 * Get an option value. 4869 * "arg" points to the '&' or '+' before the option name. 4870 * "arg" is advanced to character after the option name. 4871 * Return OK or FAIL. 4872 */ 4873 static int 4874 get_option_tv(arg, rettv, evaluate) 4875 char_u **arg; 4876 typval_T *rettv; /* when NULL, only check if option exists */ 4877 int evaluate; 4878 { 4879 char_u *option_end; 4880 long numval; 4881 char_u *stringval; 4882 int opt_type; 4883 int c; 4884 int working = (**arg == '+'); /* has("+option") */ 4885 int ret = OK; 4886 int opt_flags; 4887 4888 /* 4889 * Isolate the option name and find its value. 4890 */ 4891 option_end = find_option_end(arg, &opt_flags); 4892 if (option_end == NULL) 4893 { 4894 if (rettv != NULL) 4895 EMSG2(_("E112: Option name missing: %s"), *arg); 4896 return FAIL; 4897 } 4898 4899 if (!evaluate) 4900 { 4901 *arg = option_end; 4902 return OK; 4903 } 4904 4905 c = *option_end; 4906 *option_end = NUL; 4907 opt_type = get_option_value(*arg, &numval, 4908 rettv == NULL ? NULL : &stringval, opt_flags); 4909 4910 if (opt_type == -3) /* invalid name */ 4911 { 4912 if (rettv != NULL) 4913 EMSG2(_("E113: Unknown option: %s"), *arg); 4914 ret = FAIL; 4915 } 4916 else if (rettv != NULL) 4917 { 4918 if (opt_type == -2) /* hidden string option */ 4919 { 4920 rettv->v_type = VAR_STRING; 4921 rettv->vval.v_string = NULL; 4922 } 4923 else if (opt_type == -1) /* hidden number option */ 4924 { 4925 rettv->v_type = VAR_NUMBER; 4926 rettv->vval.v_number = 0; 4927 } 4928 else if (opt_type == 1) /* number option */ 4929 { 4930 rettv->v_type = VAR_NUMBER; 4931 rettv->vval.v_number = numval; 4932 } 4933 else /* string option */ 4934 { 4935 rettv->v_type = VAR_STRING; 4936 rettv->vval.v_string = stringval; 4937 } 4938 } 4939 else if (working && (opt_type == -2 || opt_type == -1)) 4940 ret = FAIL; 4941 4942 *option_end = c; /* put back for error messages */ 4943 *arg = option_end; 4944 4945 return ret; 4946 } 4947 4948 /* 4949 * Allocate a variable for a string constant. 4950 * Return OK or FAIL. 4951 */ 4952 static int 4953 get_string_tv(arg, rettv, evaluate) 4954 char_u **arg; 4955 typval_T *rettv; 4956 int evaluate; 4957 { 4958 char_u *p; 4959 char_u *name; 4960 int extra = 0; 4961 4962 /* 4963 * Find the end of the string, skipping backslashed characters. 4964 */ 4965 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4966 { 4967 if (*p == '\\' && p[1] != NUL) 4968 { 4969 ++p; 4970 /* A "\<x>" form occupies at least 4 characters, and produces up 4971 * to 6 characters: reserve space for 2 extra */ 4972 if (*p == '<') 4973 extra += 2; 4974 } 4975 } 4976 4977 if (*p != '"') 4978 { 4979 EMSG2(_("E114: Missing quote: %s"), *arg); 4980 return FAIL; 4981 } 4982 4983 /* If only parsing, set *arg and return here */ 4984 if (!evaluate) 4985 { 4986 *arg = p + 1; 4987 return OK; 4988 } 4989 4990 /* 4991 * Copy the string into allocated memory, handling backslashed 4992 * characters. 4993 */ 4994 name = alloc((unsigned)(p - *arg + extra)); 4995 if (name == NULL) 4996 return FAIL; 4997 rettv->v_type = VAR_STRING; 4998 rettv->vval.v_string = name; 4999 5000 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5001 { 5002 if (*p == '\\') 5003 { 5004 switch (*++p) 5005 { 5006 case 'b': *name++ = BS; ++p; break; 5007 case 'e': *name++ = ESC; ++p; break; 5008 case 'f': *name++ = FF; ++p; break; 5009 case 'n': *name++ = NL; ++p; break; 5010 case 'r': *name++ = CAR; ++p; break; 5011 case 't': *name++ = TAB; ++p; break; 5012 5013 case 'X': /* hex: "\x1", "\x12" */ 5014 case 'x': 5015 case 'u': /* Unicode: "\u0023" */ 5016 case 'U': 5017 if (vim_isxdigit(p[1])) 5018 { 5019 int n, nr; 5020 int c = toupper(*p); 5021 5022 if (c == 'X') 5023 n = 2; 5024 else 5025 n = 4; 5026 nr = 0; 5027 while (--n >= 0 && vim_isxdigit(p[1])) 5028 { 5029 ++p; 5030 nr = (nr << 4) + hex2nr(*p); 5031 } 5032 ++p; 5033 #ifdef FEAT_MBYTE 5034 /* For "\u" store the number according to 5035 * 'encoding'. */ 5036 if (c != 'X') 5037 name += (*mb_char2bytes)(nr, name); 5038 else 5039 #endif 5040 *name++ = nr; 5041 } 5042 break; 5043 5044 /* octal: "\1", "\12", "\123" */ 5045 case '0': 5046 case '1': 5047 case '2': 5048 case '3': 5049 case '4': 5050 case '5': 5051 case '6': 5052 case '7': *name = *p++ - '0'; 5053 if (*p >= '0' && *p <= '7') 5054 { 5055 *name = (*name << 3) + *p++ - '0'; 5056 if (*p >= '0' && *p <= '7') 5057 *name = (*name << 3) + *p++ - '0'; 5058 } 5059 ++name; 5060 break; 5061 5062 /* Special key, e.g.: "\<C-W>" */ 5063 case '<': extra = trans_special(&p, name, TRUE); 5064 if (extra != 0) 5065 { 5066 name += extra; 5067 break; 5068 } 5069 /* FALLTHROUGH */ 5070 5071 default: MB_COPY_CHAR(p, name); 5072 break; 5073 } 5074 } 5075 else 5076 MB_COPY_CHAR(p, name); 5077 5078 } 5079 *name = NUL; 5080 *arg = p + 1; 5081 5082 return OK; 5083 } 5084 5085 /* 5086 * Allocate a variable for a 'str''ing' constant. 5087 * Return OK or FAIL. 5088 */ 5089 static int 5090 get_lit_string_tv(arg, rettv, evaluate) 5091 char_u **arg; 5092 typval_T *rettv; 5093 int evaluate; 5094 { 5095 char_u *p; 5096 char_u *str; 5097 int reduce = 0; 5098 5099 /* 5100 * Find the end of the string, skipping ''. 5101 */ 5102 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5103 { 5104 if (*p == '\'') 5105 { 5106 if (p[1] != '\'') 5107 break; 5108 ++reduce; 5109 ++p; 5110 } 5111 } 5112 5113 if (*p != '\'') 5114 { 5115 EMSG2(_("E115: Missing quote: %s"), *arg); 5116 return FAIL; 5117 } 5118 5119 /* If only parsing return after setting "*arg" */ 5120 if (!evaluate) 5121 { 5122 *arg = p + 1; 5123 return OK; 5124 } 5125 5126 /* 5127 * Copy the string into allocated memory, handling '' to ' reduction. 5128 */ 5129 str = alloc((unsigned)((p - *arg) - reduce)); 5130 if (str == NULL) 5131 return FAIL; 5132 rettv->v_type = VAR_STRING; 5133 rettv->vval.v_string = str; 5134 5135 for (p = *arg + 1; *p != NUL; ) 5136 { 5137 if (*p == '\'') 5138 { 5139 if (p[1] != '\'') 5140 break; 5141 ++p; 5142 } 5143 MB_COPY_CHAR(p, str); 5144 } 5145 *str = NUL; 5146 *arg = p + 1; 5147 5148 return OK; 5149 } 5150 5151 /* 5152 * Allocate a variable for a List and fill it from "*arg". 5153 * Return OK or FAIL. 5154 */ 5155 static int 5156 get_list_tv(arg, rettv, evaluate) 5157 char_u **arg; 5158 typval_T *rettv; 5159 int evaluate; 5160 { 5161 list_T *l = NULL; 5162 typval_T tv; 5163 listitem_T *item; 5164 5165 if (evaluate) 5166 { 5167 l = list_alloc(); 5168 if (l == NULL) 5169 return FAIL; 5170 } 5171 5172 *arg = skipwhite(*arg + 1); 5173 while (**arg != ']' && **arg != NUL) 5174 { 5175 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5176 goto failret; 5177 if (evaluate) 5178 { 5179 item = listitem_alloc(); 5180 if (item != NULL) 5181 { 5182 item->li_tv = tv; 5183 item->li_tv.v_lock = 0; 5184 list_append(l, item); 5185 } 5186 else 5187 clear_tv(&tv); 5188 } 5189 5190 if (**arg == ']') 5191 break; 5192 if (**arg != ',') 5193 { 5194 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5195 goto failret; 5196 } 5197 *arg = skipwhite(*arg + 1); 5198 } 5199 5200 if (**arg != ']') 5201 { 5202 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5203 failret: 5204 if (evaluate) 5205 list_free(l); 5206 return FAIL; 5207 } 5208 5209 *arg = skipwhite(*arg + 1); 5210 if (evaluate) 5211 { 5212 rettv->v_type = VAR_LIST; 5213 rettv->vval.v_list = l; 5214 ++l->lv_refcount; 5215 } 5216 5217 return OK; 5218 } 5219 5220 /* 5221 * Allocate an empty header for a list. 5222 * Caller should take care of the reference count. 5223 */ 5224 list_T * 5225 list_alloc() 5226 { 5227 list_T *l; 5228 5229 l = (list_T *)alloc_clear(sizeof(list_T)); 5230 if (l != NULL) 5231 { 5232 /* Prepend the list to the list of lists for garbage collection. */ 5233 if (first_list != NULL) 5234 first_list->lv_used_prev = l; 5235 l->lv_used_prev = NULL; 5236 l->lv_used_next = first_list; 5237 first_list = l; 5238 } 5239 return l; 5240 } 5241 5242 /* 5243 * Allocate an empty list for a return value. 5244 * Returns OK or FAIL. 5245 */ 5246 static int 5247 rettv_list_alloc(rettv) 5248 typval_T *rettv; 5249 { 5250 list_T *l = list_alloc(); 5251 5252 if (l == NULL) 5253 return FAIL; 5254 5255 rettv->vval.v_list = l; 5256 rettv->v_type = VAR_LIST; 5257 ++l->lv_refcount; 5258 return OK; 5259 } 5260 5261 /* 5262 * Unreference a list: decrement the reference count and free it when it 5263 * becomes zero. 5264 */ 5265 void 5266 list_unref(l) 5267 list_T *l; 5268 { 5269 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5270 list_free(l); 5271 } 5272 5273 /* 5274 * Free a list, including all items it points to. 5275 * Ignores the reference count. 5276 */ 5277 void 5278 list_free(l) 5279 list_T *l; 5280 { 5281 listitem_T *item; 5282 5283 /* Avoid that recursive reference to the list frees us again. */ 5284 l->lv_refcount = DEL_REFCOUNT; 5285 5286 /* Remove the list from the list of lists for garbage collection. */ 5287 if (l->lv_used_prev == NULL) 5288 first_list = l->lv_used_next; 5289 else 5290 l->lv_used_prev->lv_used_next = l->lv_used_next; 5291 if (l->lv_used_next != NULL) 5292 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5293 5294 for (item = l->lv_first; item != NULL; item = l->lv_first) 5295 { 5296 /* Remove the item before deleting it. */ 5297 l->lv_first = item->li_next; 5298 listitem_free(item); 5299 } 5300 vim_free(l); 5301 } 5302 5303 /* 5304 * Allocate a list item. 5305 */ 5306 static listitem_T * 5307 listitem_alloc() 5308 { 5309 return (listitem_T *)alloc(sizeof(listitem_T)); 5310 } 5311 5312 /* 5313 * Free a list item. Also clears the value. Does not notify watchers. 5314 */ 5315 static void 5316 listitem_free(item) 5317 listitem_T *item; 5318 { 5319 clear_tv(&item->li_tv); 5320 vim_free(item); 5321 } 5322 5323 /* 5324 * Remove a list item from a List and free it. Also clears the value. 5325 */ 5326 static void 5327 listitem_remove(l, item) 5328 list_T *l; 5329 listitem_T *item; 5330 { 5331 list_remove(l, item, item); 5332 listitem_free(item); 5333 } 5334 5335 /* 5336 * Get the number of items in a list. 5337 */ 5338 static long 5339 list_len(l) 5340 list_T *l; 5341 { 5342 if (l == NULL) 5343 return 0L; 5344 return l->lv_len; 5345 } 5346 5347 /* 5348 * Return TRUE when two lists have exactly the same values. 5349 */ 5350 static int 5351 list_equal(l1, l2, ic) 5352 list_T *l1; 5353 list_T *l2; 5354 int ic; /* ignore case for strings */ 5355 { 5356 listitem_T *item1, *item2; 5357 5358 if (list_len(l1) != list_len(l2)) 5359 return FALSE; 5360 5361 for (item1 = l1->lv_first, item2 = l2->lv_first; 5362 item1 != NULL && item2 != NULL; 5363 item1 = item1->li_next, item2 = item2->li_next) 5364 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5365 return FALSE; 5366 return item1 == NULL && item2 == NULL; 5367 } 5368 5369 #if defined(FEAT_PYTHON) || defined(PROTO) 5370 /* 5371 * Return the dictitem that an entry in a hashtable points to. 5372 */ 5373 dictitem_T * 5374 dict_lookup(hi) 5375 hashitem_T *hi; 5376 { 5377 return HI2DI(hi); 5378 } 5379 #endif 5380 5381 /* 5382 * Return TRUE when two dictionaries have exactly the same key/values. 5383 */ 5384 static int 5385 dict_equal(d1, d2, ic) 5386 dict_T *d1; 5387 dict_T *d2; 5388 int ic; /* ignore case for strings */ 5389 { 5390 hashitem_T *hi; 5391 dictitem_T *item2; 5392 int todo; 5393 5394 if (dict_len(d1) != dict_len(d2)) 5395 return FALSE; 5396 5397 todo = d1->dv_hashtab.ht_used; 5398 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5399 { 5400 if (!HASHITEM_EMPTY(hi)) 5401 { 5402 item2 = dict_find(d2, hi->hi_key, -1); 5403 if (item2 == NULL) 5404 return FALSE; 5405 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5406 return FALSE; 5407 --todo; 5408 } 5409 } 5410 return TRUE; 5411 } 5412 5413 /* 5414 * Return TRUE if "tv1" and "tv2" have the same value. 5415 * Compares the items just like "==" would compare them, but strings and 5416 * numbers are different. 5417 */ 5418 static int 5419 tv_equal(tv1, tv2, ic) 5420 typval_T *tv1; 5421 typval_T *tv2; 5422 int ic; /* ignore case */ 5423 { 5424 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5425 char_u *s1, *s2; 5426 5427 if (tv1->v_type != tv2->v_type) 5428 return FALSE; 5429 5430 switch (tv1->v_type) 5431 { 5432 case VAR_LIST: 5433 /* recursive! */ 5434 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5435 5436 case VAR_DICT: 5437 /* recursive! */ 5438 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5439 5440 case VAR_FUNC: 5441 return (tv1->vval.v_string != NULL 5442 && tv2->vval.v_string != NULL 5443 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5444 5445 case VAR_NUMBER: 5446 return tv1->vval.v_number == tv2->vval.v_number; 5447 5448 case VAR_STRING: 5449 s1 = get_tv_string_buf(tv1, buf1); 5450 s2 = get_tv_string_buf(tv2, buf2); 5451 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5452 } 5453 5454 EMSG2(_(e_intern2), "tv_equal()"); 5455 return TRUE; 5456 } 5457 5458 /* 5459 * Locate item with index "n" in list "l" and return it. 5460 * A negative index is counted from the end; -1 is the last item. 5461 * Returns NULL when "n" is out of range. 5462 */ 5463 static listitem_T * 5464 list_find(l, n) 5465 list_T *l; 5466 long n; 5467 { 5468 listitem_T *item; 5469 long idx; 5470 5471 if (l == NULL) 5472 return NULL; 5473 5474 /* Negative index is relative to the end. */ 5475 if (n < 0) 5476 n = l->lv_len + n; 5477 5478 /* Check for index out of range. */ 5479 if (n < 0 || n >= l->lv_len) 5480 return NULL; 5481 5482 /* When there is a cached index may start search from there. */ 5483 if (l->lv_idx_item != NULL) 5484 { 5485 if (n < l->lv_idx / 2) 5486 { 5487 /* closest to the start of the list */ 5488 item = l->lv_first; 5489 idx = 0; 5490 } 5491 else if (n > (l->lv_idx + l->lv_len) / 2) 5492 { 5493 /* closest to the end of the list */ 5494 item = l->lv_last; 5495 idx = l->lv_len - 1; 5496 } 5497 else 5498 { 5499 /* closest to the cached index */ 5500 item = l->lv_idx_item; 5501 idx = l->lv_idx; 5502 } 5503 } 5504 else 5505 { 5506 if (n < l->lv_len / 2) 5507 { 5508 /* closest to the start of the list */ 5509 item = l->lv_first; 5510 idx = 0; 5511 } 5512 else 5513 { 5514 /* closest to the end of the list */ 5515 item = l->lv_last; 5516 idx = l->lv_len - 1; 5517 } 5518 } 5519 5520 while (n > idx) 5521 { 5522 /* search forward */ 5523 item = item->li_next; 5524 ++idx; 5525 } 5526 while (n < idx) 5527 { 5528 /* search backward */ 5529 item = item->li_prev; 5530 --idx; 5531 } 5532 5533 /* cache the used index */ 5534 l->lv_idx = idx; 5535 l->lv_idx_item = item; 5536 5537 return item; 5538 } 5539 5540 /* 5541 * Get list item "l[idx]" as a number. 5542 */ 5543 static long 5544 list_find_nr(l, idx, errorp) 5545 list_T *l; 5546 long idx; 5547 int *errorp; /* set to TRUE when something wrong */ 5548 { 5549 listitem_T *li; 5550 5551 li = list_find(l, idx); 5552 if (li == NULL) 5553 { 5554 if (errorp != NULL) 5555 *errorp = TRUE; 5556 return -1L; 5557 } 5558 return get_tv_number_chk(&li->li_tv, errorp); 5559 } 5560 5561 /* 5562 * Locate "item" list "l" and return its index. 5563 * Returns -1 when "item" is not in the list. 5564 */ 5565 static long 5566 list_idx_of_item(l, item) 5567 list_T *l; 5568 listitem_T *item; 5569 { 5570 long idx = 0; 5571 listitem_T *li; 5572 5573 if (l == NULL) 5574 return -1; 5575 idx = 0; 5576 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5577 ++idx; 5578 if (li == NULL) 5579 return -1; 5580 return idx; 5581 } 5582 5583 /* 5584 * Append item "item" to the end of list "l". 5585 */ 5586 static void 5587 list_append(l, item) 5588 list_T *l; 5589 listitem_T *item; 5590 { 5591 if (l->lv_last == NULL) 5592 { 5593 /* empty list */ 5594 l->lv_first = item; 5595 l->lv_last = item; 5596 item->li_prev = NULL; 5597 } 5598 else 5599 { 5600 l->lv_last->li_next = item; 5601 item->li_prev = l->lv_last; 5602 l->lv_last = item; 5603 } 5604 ++l->lv_len; 5605 item->li_next = NULL; 5606 } 5607 5608 /* 5609 * Append typval_T "tv" to the end of list "l". 5610 * Return FAIL when out of memory. 5611 */ 5612 static int 5613 list_append_tv(l, tv) 5614 list_T *l; 5615 typval_T *tv; 5616 { 5617 listitem_T *li = listitem_alloc(); 5618 5619 if (li == NULL) 5620 return FAIL; 5621 copy_tv(tv, &li->li_tv); 5622 list_append(l, li); 5623 return OK; 5624 } 5625 5626 /* 5627 * Add a dictionary to a list. Used by getqflist(). 5628 * Return FAIL when out of memory. 5629 */ 5630 int 5631 list_append_dict(list, dict) 5632 list_T *list; 5633 dict_T *dict; 5634 { 5635 listitem_T *li = listitem_alloc(); 5636 5637 if (li == NULL) 5638 return FAIL; 5639 li->li_tv.v_type = VAR_DICT; 5640 li->li_tv.v_lock = 0; 5641 li->li_tv.vval.v_dict = dict; 5642 list_append(list, li); 5643 ++dict->dv_refcount; 5644 return OK; 5645 } 5646 5647 /* 5648 * Make a copy of "str" and append it as an item to list "l". 5649 * When "len" >= 0 use "str[len]". 5650 * Returns FAIL when out of memory. 5651 */ 5652 static int 5653 list_append_string(l, str, len) 5654 list_T *l; 5655 char_u *str; 5656 int len; 5657 { 5658 listitem_T *li = listitem_alloc(); 5659 5660 if (li == NULL) 5661 return FAIL; 5662 list_append(l, li); 5663 li->li_tv.v_type = VAR_STRING; 5664 li->li_tv.v_lock = 0; 5665 if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 5666 : vim_strsave(str))) == NULL) 5667 return FAIL; 5668 return OK; 5669 } 5670 5671 /* 5672 * Append "n" to list "l". 5673 * Returns FAIL when out of memory. 5674 */ 5675 static int 5676 list_append_number(l, n) 5677 list_T *l; 5678 varnumber_T n; 5679 { 5680 listitem_T *li; 5681 5682 li = listitem_alloc(); 5683 if (li == NULL) 5684 return FAIL; 5685 li->li_tv.v_type = VAR_NUMBER; 5686 li->li_tv.v_lock = 0; 5687 li->li_tv.vval.v_number = n; 5688 list_append(l, li); 5689 return OK; 5690 } 5691 5692 /* 5693 * Insert typval_T "tv" in list "l" before "item". 5694 * If "item" is NULL append at the end. 5695 * Return FAIL when out of memory. 5696 */ 5697 static int 5698 list_insert_tv(l, tv, item) 5699 list_T *l; 5700 typval_T *tv; 5701 listitem_T *item; 5702 { 5703 listitem_T *ni = listitem_alloc(); 5704 5705 if (ni == NULL) 5706 return FAIL; 5707 copy_tv(tv, &ni->li_tv); 5708 if (item == NULL) 5709 /* Append new item at end of list. */ 5710 list_append(l, ni); 5711 else 5712 { 5713 /* Insert new item before existing item. */ 5714 ni->li_prev = item->li_prev; 5715 ni->li_next = item; 5716 if (item->li_prev == NULL) 5717 { 5718 l->lv_first = ni; 5719 ++l->lv_idx; 5720 } 5721 else 5722 { 5723 item->li_prev->li_next = ni; 5724 l->lv_idx_item = NULL; 5725 } 5726 item->li_prev = ni; 5727 ++l->lv_len; 5728 } 5729 return OK; 5730 } 5731 5732 /* 5733 * Extend "l1" with "l2". 5734 * If "bef" is NULL append at the end, otherwise insert before this item. 5735 * Returns FAIL when out of memory. 5736 */ 5737 static int 5738 list_extend(l1, l2, bef) 5739 list_T *l1; 5740 list_T *l2; 5741 listitem_T *bef; 5742 { 5743 listitem_T *item; 5744 5745 for (item = l2->lv_first; item != NULL; item = item->li_next) 5746 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5747 return FAIL; 5748 return OK; 5749 } 5750 5751 /* 5752 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5753 * Return FAIL when out of memory. 5754 */ 5755 static int 5756 list_concat(l1, l2, tv) 5757 list_T *l1; 5758 list_T *l2; 5759 typval_T *tv; 5760 { 5761 list_T *l; 5762 5763 /* make a copy of the first list. */ 5764 l = list_copy(l1, FALSE, 0); 5765 if (l == NULL) 5766 return FAIL; 5767 tv->v_type = VAR_LIST; 5768 tv->vval.v_list = l; 5769 5770 /* append all items from the second list */ 5771 return list_extend(l, l2, NULL); 5772 } 5773 5774 /* 5775 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5776 * The refcount of the new list is set to 1. 5777 * See item_copy() for "copyID". 5778 * Returns NULL when out of memory. 5779 */ 5780 static list_T * 5781 list_copy(orig, deep, copyID) 5782 list_T *orig; 5783 int deep; 5784 int copyID; 5785 { 5786 list_T *copy; 5787 listitem_T *item; 5788 listitem_T *ni; 5789 5790 if (orig == NULL) 5791 return NULL; 5792 5793 copy = list_alloc(); 5794 if (copy != NULL) 5795 { 5796 if (copyID != 0) 5797 { 5798 /* Do this before adding the items, because one of the items may 5799 * refer back to this list. */ 5800 orig->lv_copyID = copyID; 5801 orig->lv_copylist = copy; 5802 } 5803 for (item = orig->lv_first; item != NULL && !got_int; 5804 item = item->li_next) 5805 { 5806 ni = listitem_alloc(); 5807 if (ni == NULL) 5808 break; 5809 if (deep) 5810 { 5811 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5812 { 5813 vim_free(ni); 5814 break; 5815 } 5816 } 5817 else 5818 copy_tv(&item->li_tv, &ni->li_tv); 5819 list_append(copy, ni); 5820 } 5821 ++copy->lv_refcount; 5822 if (item != NULL) 5823 { 5824 list_unref(copy); 5825 copy = NULL; 5826 } 5827 } 5828 5829 return copy; 5830 } 5831 5832 /* 5833 * Remove items "item" to "item2" from list "l". 5834 * Does not free the listitem or the value! 5835 */ 5836 static void 5837 list_remove(l, item, item2) 5838 list_T *l; 5839 listitem_T *item; 5840 listitem_T *item2; 5841 { 5842 listitem_T *ip; 5843 5844 /* notify watchers */ 5845 for (ip = item; ip != NULL; ip = ip->li_next) 5846 { 5847 --l->lv_len; 5848 list_fix_watch(l, ip); 5849 if (ip == item2) 5850 break; 5851 } 5852 5853 if (item2->li_next == NULL) 5854 l->lv_last = item->li_prev; 5855 else 5856 item2->li_next->li_prev = item->li_prev; 5857 if (item->li_prev == NULL) 5858 l->lv_first = item2->li_next; 5859 else 5860 item->li_prev->li_next = item2->li_next; 5861 l->lv_idx_item = NULL; 5862 } 5863 5864 /* 5865 * Return an allocated string with the string representation of a list. 5866 * May return NULL. 5867 */ 5868 static char_u * 5869 list2string(tv, copyID) 5870 typval_T *tv; 5871 int copyID; 5872 { 5873 garray_T ga; 5874 5875 if (tv->vval.v_list == NULL) 5876 return NULL; 5877 ga_init2(&ga, (int)sizeof(char), 80); 5878 ga_append(&ga, '['); 5879 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 5880 { 5881 vim_free(ga.ga_data); 5882 return NULL; 5883 } 5884 ga_append(&ga, ']'); 5885 ga_append(&ga, NUL); 5886 return (char_u *)ga.ga_data; 5887 } 5888 5889 /* 5890 * Join list "l" into a string in "*gap", using separator "sep". 5891 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5892 * Return FAIL or OK. 5893 */ 5894 static int 5895 list_join(gap, l, sep, echo, copyID) 5896 garray_T *gap; 5897 list_T *l; 5898 char_u *sep; 5899 int echo; 5900 int copyID; 5901 { 5902 int first = TRUE; 5903 char_u *tofree; 5904 char_u numbuf[NUMBUFLEN]; 5905 listitem_T *item; 5906 char_u *s; 5907 5908 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5909 { 5910 if (first) 5911 first = FALSE; 5912 else 5913 ga_concat(gap, sep); 5914 5915 if (echo) 5916 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 5917 else 5918 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 5919 if (s != NULL) 5920 ga_concat(gap, s); 5921 vim_free(tofree); 5922 if (s == NULL) 5923 return FAIL; 5924 } 5925 return OK; 5926 } 5927 5928 /* 5929 * Garbage collection for lists and dictionaries. 5930 * 5931 * We use reference counts to be able to free most items right away when they 5932 * are no longer used. But for composite items it's possible that it becomes 5933 * unused while the reference count is > 0: When there is a recursive 5934 * reference. Example: 5935 * :let l = [1, 2, 3] 5936 * :let d = {9: l} 5937 * :let l[1] = d 5938 * 5939 * Since this is quite unusual we handle this with garbage collection: every 5940 * once in a while find out which lists and dicts are not referenced from any 5941 * variable. 5942 * 5943 * Here is a good reference text about garbage collection (refers to Python 5944 * but it applies to all reference-counting mechanisms): 5945 * http://python.ca/nas/python/gc/ 5946 */ 5947 5948 /* 5949 * Do garbage collection for lists and dicts. 5950 * Return TRUE if some memory was freed. 5951 */ 5952 int 5953 garbage_collect() 5954 { 5955 dict_T *dd; 5956 list_T *ll; 5957 int copyID = ++current_copyID; 5958 buf_T *buf; 5959 win_T *wp; 5960 int i; 5961 funccall_T *fc; 5962 int did_free = FALSE; 5963 5964 /* 5965 * 1. Go through all accessible variables and mark all lists and dicts 5966 * with copyID. 5967 */ 5968 /* script-local variables */ 5969 for (i = 1; i <= ga_scripts.ga_len; ++i) 5970 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5971 5972 /* buffer-local variables */ 5973 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5974 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5975 5976 /* window-local variables */ 5977 FOR_ALL_WINDOWS(wp) 5978 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5979 5980 /* global variables */ 5981 set_ref_in_ht(&globvarht, copyID); 5982 5983 /* function-local variables */ 5984 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5985 { 5986 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5987 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5988 } 5989 5990 /* 5991 * 2. Go through the list of dicts and free items without the copyID. 5992 */ 5993 for (dd = first_dict; dd != NULL; ) 5994 if (dd->dv_copyID != copyID) 5995 { 5996 dict_free(dd); 5997 did_free = TRUE; 5998 5999 /* restart, next dict may also have been freed */ 6000 dd = first_dict; 6001 } 6002 else 6003 dd = dd->dv_used_next; 6004 6005 /* 6006 * 3. Go through the list of lists and free items without the copyID. 6007 * But don't free a list that has a watcher (used in a for loop), these 6008 * are not referenced anywhere. 6009 */ 6010 for (ll = first_list; ll != NULL; ) 6011 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 6012 { 6013 list_free(ll); 6014 did_free = TRUE; 6015 6016 /* restart, next list may also have been freed */ 6017 ll = first_list; 6018 } 6019 else 6020 ll = ll->lv_used_next; 6021 6022 return did_free; 6023 } 6024 6025 /* 6026 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6027 */ 6028 static void 6029 set_ref_in_ht(ht, copyID) 6030 hashtab_T *ht; 6031 int copyID; 6032 { 6033 int todo; 6034 hashitem_T *hi; 6035 6036 todo = ht->ht_used; 6037 for (hi = ht->ht_array; todo > 0; ++hi) 6038 if (!HASHITEM_EMPTY(hi)) 6039 { 6040 --todo; 6041 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 6042 } 6043 } 6044 6045 /* 6046 * Mark all lists and dicts referenced through list "l" with "copyID". 6047 */ 6048 static void 6049 set_ref_in_list(l, copyID) 6050 list_T *l; 6051 int copyID; 6052 { 6053 listitem_T *li; 6054 6055 for (li = l->lv_first; li != NULL; li = li->li_next) 6056 set_ref_in_item(&li->li_tv, copyID); 6057 } 6058 6059 /* 6060 * Mark all lists and dicts referenced through typval "tv" with "copyID". 6061 */ 6062 static void 6063 set_ref_in_item(tv, copyID) 6064 typval_T *tv; 6065 int copyID; 6066 { 6067 dict_T *dd; 6068 list_T *ll; 6069 6070 switch (tv->v_type) 6071 { 6072 case VAR_DICT: 6073 dd = tv->vval.v_dict; 6074 if (dd->dv_copyID != copyID) 6075 { 6076 /* Didn't see this dict yet. */ 6077 dd->dv_copyID = copyID; 6078 set_ref_in_ht(&dd->dv_hashtab, copyID); 6079 } 6080 break; 6081 6082 case VAR_LIST: 6083 ll = tv->vval.v_list; 6084 if (ll->lv_copyID != copyID) 6085 { 6086 /* Didn't see this list yet. */ 6087 ll->lv_copyID = copyID; 6088 set_ref_in_list(ll, copyID); 6089 } 6090 break; 6091 } 6092 return; 6093 } 6094 6095 /* 6096 * Allocate an empty header for a dictionary. 6097 */ 6098 dict_T * 6099 dict_alloc() 6100 { 6101 dict_T *d; 6102 6103 d = (dict_T *)alloc(sizeof(dict_T)); 6104 if (d != NULL) 6105 { 6106 /* Add the list to the hashtable for garbage collection. */ 6107 if (first_dict != NULL) 6108 first_dict->dv_used_prev = d; 6109 d->dv_used_next = first_dict; 6110 d->dv_used_prev = NULL; 6111 6112 hash_init(&d->dv_hashtab); 6113 d->dv_lock = 0; 6114 d->dv_refcount = 0; 6115 d->dv_copyID = 0; 6116 } 6117 return d; 6118 } 6119 6120 /* 6121 * Unreference a Dictionary: decrement the reference count and free it when it 6122 * becomes zero. 6123 */ 6124 static void 6125 dict_unref(d) 6126 dict_T *d; 6127 { 6128 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6129 dict_free(d); 6130 } 6131 6132 /* 6133 * Free a Dictionary, including all items it contains. 6134 * Ignores the reference count. 6135 */ 6136 static void 6137 dict_free(d) 6138 dict_T *d; 6139 { 6140 int todo; 6141 hashitem_T *hi; 6142 dictitem_T *di; 6143 6144 /* Avoid that recursive reference to the dict frees us again. */ 6145 d->dv_refcount = DEL_REFCOUNT; 6146 6147 /* Remove the dict from the list of dicts for garbage collection. */ 6148 if (d->dv_used_prev == NULL) 6149 first_dict = d->dv_used_next; 6150 else 6151 d->dv_used_prev->dv_used_next = d->dv_used_next; 6152 if (d->dv_used_next != NULL) 6153 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6154 6155 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6156 hash_lock(&d->dv_hashtab); 6157 todo = d->dv_hashtab.ht_used; 6158 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6159 { 6160 if (!HASHITEM_EMPTY(hi)) 6161 { 6162 /* Remove the item before deleting it, just in case there is 6163 * something recursive causing trouble. */ 6164 di = HI2DI(hi); 6165 hash_remove(&d->dv_hashtab, hi); 6166 dictitem_free(di); 6167 --todo; 6168 } 6169 } 6170 hash_clear(&d->dv_hashtab); 6171 vim_free(d); 6172 } 6173 6174 /* 6175 * Allocate a Dictionary item. 6176 * The "key" is copied to the new item. 6177 * Note that the value of the item "di_tv" still needs to be initialized! 6178 * Returns NULL when out of memory. 6179 */ 6180 static dictitem_T * 6181 dictitem_alloc(key) 6182 char_u *key; 6183 { 6184 dictitem_T *di; 6185 6186 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6187 if (di != NULL) 6188 { 6189 STRCPY(di->di_key, key); 6190 di->di_flags = 0; 6191 } 6192 return di; 6193 } 6194 6195 /* 6196 * Make a copy of a Dictionary item. 6197 */ 6198 static dictitem_T * 6199 dictitem_copy(org) 6200 dictitem_T *org; 6201 { 6202 dictitem_T *di; 6203 6204 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6205 if (di != NULL) 6206 { 6207 STRCPY(di->di_key, org->di_key); 6208 di->di_flags = 0; 6209 copy_tv(&org->di_tv, &di->di_tv); 6210 } 6211 return di; 6212 } 6213 6214 /* 6215 * Remove item "item" from Dictionary "dict" and free it. 6216 */ 6217 static void 6218 dictitem_remove(dict, item) 6219 dict_T *dict; 6220 dictitem_T *item; 6221 { 6222 hashitem_T *hi; 6223 6224 hi = hash_find(&dict->dv_hashtab, item->di_key); 6225 if (HASHITEM_EMPTY(hi)) 6226 EMSG2(_(e_intern2), "dictitem_remove()"); 6227 else 6228 hash_remove(&dict->dv_hashtab, hi); 6229 dictitem_free(item); 6230 } 6231 6232 /* 6233 * Free a dict item. Also clears the value. 6234 */ 6235 static void 6236 dictitem_free(item) 6237 dictitem_T *item; 6238 { 6239 clear_tv(&item->di_tv); 6240 vim_free(item); 6241 } 6242 6243 /* 6244 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6245 * The refcount of the new dict is set to 1. 6246 * See item_copy() for "copyID". 6247 * Returns NULL when out of memory. 6248 */ 6249 static dict_T * 6250 dict_copy(orig, deep, copyID) 6251 dict_T *orig; 6252 int deep; 6253 int copyID; 6254 { 6255 dict_T *copy; 6256 dictitem_T *di; 6257 int todo; 6258 hashitem_T *hi; 6259 6260 if (orig == NULL) 6261 return NULL; 6262 6263 copy = dict_alloc(); 6264 if (copy != NULL) 6265 { 6266 if (copyID != 0) 6267 { 6268 orig->dv_copyID = copyID; 6269 orig->dv_copydict = copy; 6270 } 6271 todo = orig->dv_hashtab.ht_used; 6272 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6273 { 6274 if (!HASHITEM_EMPTY(hi)) 6275 { 6276 --todo; 6277 6278 di = dictitem_alloc(hi->hi_key); 6279 if (di == NULL) 6280 break; 6281 if (deep) 6282 { 6283 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6284 copyID) == FAIL) 6285 { 6286 vim_free(di); 6287 break; 6288 } 6289 } 6290 else 6291 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6292 if (dict_add(copy, di) == FAIL) 6293 { 6294 dictitem_free(di); 6295 break; 6296 } 6297 } 6298 } 6299 6300 ++copy->dv_refcount; 6301 if (todo > 0) 6302 { 6303 dict_unref(copy); 6304 copy = NULL; 6305 } 6306 } 6307 6308 return copy; 6309 } 6310 6311 /* 6312 * Add item "item" to Dictionary "d". 6313 * Returns FAIL when out of memory and when key already existed. 6314 */ 6315 static int 6316 dict_add(d, item) 6317 dict_T *d; 6318 dictitem_T *item; 6319 { 6320 return hash_add(&d->dv_hashtab, item->di_key); 6321 } 6322 6323 /* 6324 * Add a number or string entry to dictionary "d". 6325 * When "str" is NULL use number "nr", otherwise use "str". 6326 * Returns FAIL when out of memory and when key already exists. 6327 */ 6328 int 6329 dict_add_nr_str(d, key, nr, str) 6330 dict_T *d; 6331 char *key; 6332 long nr; 6333 char_u *str; 6334 { 6335 dictitem_T *item; 6336 6337 item = dictitem_alloc((char_u *)key); 6338 if (item == NULL) 6339 return FAIL; 6340 item->di_tv.v_lock = 0; 6341 if (str == NULL) 6342 { 6343 item->di_tv.v_type = VAR_NUMBER; 6344 item->di_tv.vval.v_number = nr; 6345 } 6346 else 6347 { 6348 item->di_tv.v_type = VAR_STRING; 6349 item->di_tv.vval.v_string = vim_strsave(str); 6350 } 6351 if (dict_add(d, item) == FAIL) 6352 { 6353 dictitem_free(item); 6354 return FAIL; 6355 } 6356 return OK; 6357 } 6358 6359 /* 6360 * Get the number of items in a Dictionary. 6361 */ 6362 static long 6363 dict_len(d) 6364 dict_T *d; 6365 { 6366 if (d == NULL) 6367 return 0L; 6368 return d->dv_hashtab.ht_used; 6369 } 6370 6371 /* 6372 * Find item "key[len]" in Dictionary "d". 6373 * If "len" is negative use strlen(key). 6374 * Returns NULL when not found. 6375 */ 6376 static dictitem_T * 6377 dict_find(d, key, len) 6378 dict_T *d; 6379 char_u *key; 6380 int len; 6381 { 6382 #define AKEYLEN 200 6383 char_u buf[AKEYLEN]; 6384 char_u *akey; 6385 char_u *tofree = NULL; 6386 hashitem_T *hi; 6387 6388 if (len < 0) 6389 akey = key; 6390 else if (len >= AKEYLEN) 6391 { 6392 tofree = akey = vim_strnsave(key, len); 6393 if (akey == NULL) 6394 return NULL; 6395 } 6396 else 6397 { 6398 /* Avoid a malloc/free by using buf[]. */ 6399 vim_strncpy(buf, key, len); 6400 akey = buf; 6401 } 6402 6403 hi = hash_find(&d->dv_hashtab, akey); 6404 vim_free(tofree); 6405 if (HASHITEM_EMPTY(hi)) 6406 return NULL; 6407 return HI2DI(hi); 6408 } 6409 6410 /* 6411 * Get a string item from a dictionary. 6412 * When "save" is TRUE allocate memory for it. 6413 * Returns NULL if the entry doesn't exist or out of memory. 6414 */ 6415 char_u * 6416 get_dict_string(d, key, save) 6417 dict_T *d; 6418 char_u *key; 6419 int save; 6420 { 6421 dictitem_T *di; 6422 char_u *s; 6423 6424 di = dict_find(d, key, -1); 6425 if (di == NULL) 6426 return NULL; 6427 s = get_tv_string(&di->di_tv); 6428 if (save && s != NULL) 6429 s = vim_strsave(s); 6430 return s; 6431 } 6432 6433 /* 6434 * Get a number item from a dictionary. 6435 * Returns 0 if the entry doesn't exist or out of memory. 6436 */ 6437 long 6438 get_dict_number(d, key) 6439 dict_T *d; 6440 char_u *key; 6441 { 6442 dictitem_T *di; 6443 6444 di = dict_find(d, key, -1); 6445 if (di == NULL) 6446 return 0; 6447 return get_tv_number(&di->di_tv); 6448 } 6449 6450 /* 6451 * Return an allocated string with the string representation of a Dictionary. 6452 * May return NULL. 6453 */ 6454 static char_u * 6455 dict2string(tv, copyID) 6456 typval_T *tv; 6457 int copyID; 6458 { 6459 garray_T ga; 6460 int first = TRUE; 6461 char_u *tofree; 6462 char_u numbuf[NUMBUFLEN]; 6463 hashitem_T *hi; 6464 char_u *s; 6465 dict_T *d; 6466 int todo; 6467 6468 if ((d = tv->vval.v_dict) == NULL) 6469 return NULL; 6470 ga_init2(&ga, (int)sizeof(char), 80); 6471 ga_append(&ga, '{'); 6472 6473 todo = d->dv_hashtab.ht_used; 6474 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6475 { 6476 if (!HASHITEM_EMPTY(hi)) 6477 { 6478 --todo; 6479 6480 if (first) 6481 first = FALSE; 6482 else 6483 ga_concat(&ga, (char_u *)", "); 6484 6485 tofree = string_quote(hi->hi_key, FALSE); 6486 if (tofree != NULL) 6487 { 6488 ga_concat(&ga, tofree); 6489 vim_free(tofree); 6490 } 6491 ga_concat(&ga, (char_u *)": "); 6492 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 6493 if (s != NULL) 6494 ga_concat(&ga, s); 6495 vim_free(tofree); 6496 if (s == NULL) 6497 break; 6498 } 6499 } 6500 if (todo > 0) 6501 { 6502 vim_free(ga.ga_data); 6503 return NULL; 6504 } 6505 6506 ga_append(&ga, '}'); 6507 ga_append(&ga, NUL); 6508 return (char_u *)ga.ga_data; 6509 } 6510 6511 /* 6512 * Allocate a variable for a Dictionary and fill it from "*arg". 6513 * Return OK or FAIL. Returns NOTDONE for {expr}. 6514 */ 6515 static int 6516 get_dict_tv(arg, rettv, evaluate) 6517 char_u **arg; 6518 typval_T *rettv; 6519 int evaluate; 6520 { 6521 dict_T *d = NULL; 6522 typval_T tvkey; 6523 typval_T tv; 6524 char_u *key; 6525 dictitem_T *item; 6526 char_u *start = skipwhite(*arg + 1); 6527 char_u buf[NUMBUFLEN]; 6528 6529 /* 6530 * First check if it's not a curly-braces thing: {expr}. 6531 * Must do this without evaluating, otherwise a function may be called 6532 * twice. Unfortunately this means we need to call eval1() twice for the 6533 * first item. 6534 * But {} is an empty Dictionary. 6535 */ 6536 if (*start != '}') 6537 { 6538 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6539 return FAIL; 6540 if (*start == '}') 6541 return NOTDONE; 6542 } 6543 6544 if (evaluate) 6545 { 6546 d = dict_alloc(); 6547 if (d == NULL) 6548 return FAIL; 6549 } 6550 tvkey.v_type = VAR_UNKNOWN; 6551 tv.v_type = VAR_UNKNOWN; 6552 6553 *arg = skipwhite(*arg + 1); 6554 while (**arg != '}' && **arg != NUL) 6555 { 6556 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6557 goto failret; 6558 if (**arg != ':') 6559 { 6560 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6561 clear_tv(&tvkey); 6562 goto failret; 6563 } 6564 key = get_tv_string_buf_chk(&tvkey, buf); 6565 if (key == NULL || *key == NUL) 6566 { 6567 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6568 if (key != NULL) 6569 EMSG(_(e_emptykey)); 6570 clear_tv(&tvkey); 6571 goto failret; 6572 } 6573 6574 *arg = skipwhite(*arg + 1); 6575 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6576 { 6577 clear_tv(&tvkey); 6578 goto failret; 6579 } 6580 if (evaluate) 6581 { 6582 item = dict_find(d, key, -1); 6583 if (item != NULL) 6584 { 6585 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6586 clear_tv(&tvkey); 6587 clear_tv(&tv); 6588 goto failret; 6589 } 6590 item = dictitem_alloc(key); 6591 clear_tv(&tvkey); 6592 if (item != NULL) 6593 { 6594 item->di_tv = tv; 6595 item->di_tv.v_lock = 0; 6596 if (dict_add(d, item) == FAIL) 6597 dictitem_free(item); 6598 } 6599 } 6600 6601 if (**arg == '}') 6602 break; 6603 if (**arg != ',') 6604 { 6605 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6606 goto failret; 6607 } 6608 *arg = skipwhite(*arg + 1); 6609 } 6610 6611 if (**arg != '}') 6612 { 6613 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6614 failret: 6615 if (evaluate) 6616 dict_free(d); 6617 return FAIL; 6618 } 6619 6620 *arg = skipwhite(*arg + 1); 6621 if (evaluate) 6622 { 6623 rettv->v_type = VAR_DICT; 6624 rettv->vval.v_dict = d; 6625 ++d->dv_refcount; 6626 } 6627 6628 return OK; 6629 } 6630 6631 /* 6632 * Return a string with the string representation of a variable. 6633 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6634 * "numbuf" is used for a number. 6635 * Does not put quotes around strings, as ":echo" displays values. 6636 * When "copyID" is not NULL replace recursive lists and dicts with "...". 6637 * May return NULL; 6638 */ 6639 static char_u * 6640 echo_string(tv, tofree, numbuf, copyID) 6641 typval_T *tv; 6642 char_u **tofree; 6643 char_u *numbuf; 6644 int copyID; 6645 { 6646 static int recurse = 0; 6647 char_u *r = NULL; 6648 6649 if (recurse >= DICT_MAXNEST) 6650 { 6651 EMSG(_("E724: variable nested too deep for displaying")); 6652 *tofree = NULL; 6653 return NULL; 6654 } 6655 ++recurse; 6656 6657 switch (tv->v_type) 6658 { 6659 case VAR_FUNC: 6660 *tofree = NULL; 6661 r = tv->vval.v_string; 6662 break; 6663 6664 case VAR_LIST: 6665 if (tv->vval.v_list == NULL) 6666 { 6667 *tofree = NULL; 6668 r = NULL; 6669 } 6670 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 6671 { 6672 *tofree = NULL; 6673 r = (char_u *)"[...]"; 6674 } 6675 else 6676 { 6677 tv->vval.v_list->lv_copyID = copyID; 6678 *tofree = list2string(tv, copyID); 6679 r = *tofree; 6680 } 6681 break; 6682 6683 case VAR_DICT: 6684 if (tv->vval.v_dict == NULL) 6685 { 6686 *tofree = NULL; 6687 r = NULL; 6688 } 6689 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 6690 { 6691 *tofree = NULL; 6692 r = (char_u *)"{...}"; 6693 } 6694 else 6695 { 6696 tv->vval.v_dict->dv_copyID = copyID; 6697 *tofree = dict2string(tv, copyID); 6698 r = *tofree; 6699 } 6700 break; 6701 6702 case VAR_STRING: 6703 case VAR_NUMBER: 6704 *tofree = NULL; 6705 r = get_tv_string_buf(tv, numbuf); 6706 break; 6707 6708 default: 6709 EMSG2(_(e_intern2), "echo_string()"); 6710 *tofree = NULL; 6711 } 6712 6713 --recurse; 6714 return r; 6715 } 6716 6717 /* 6718 * Return a string with the string representation of a variable. 6719 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6720 * "numbuf" is used for a number. 6721 * Puts quotes around strings, so that they can be parsed back by eval(). 6722 * May return NULL; 6723 */ 6724 static char_u * 6725 tv2string(tv, tofree, numbuf, copyID) 6726 typval_T *tv; 6727 char_u **tofree; 6728 char_u *numbuf; 6729 int copyID; 6730 { 6731 switch (tv->v_type) 6732 { 6733 case VAR_FUNC: 6734 *tofree = string_quote(tv->vval.v_string, TRUE); 6735 return *tofree; 6736 case VAR_STRING: 6737 *tofree = string_quote(tv->vval.v_string, FALSE); 6738 return *tofree; 6739 case VAR_NUMBER: 6740 case VAR_LIST: 6741 case VAR_DICT: 6742 break; 6743 default: 6744 EMSG2(_(e_intern2), "tv2string()"); 6745 } 6746 return echo_string(tv, tofree, numbuf, copyID); 6747 } 6748 6749 /* 6750 * Return string "str" in ' quotes, doubling ' characters. 6751 * If "str" is NULL an empty string is assumed. 6752 * If "function" is TRUE make it function('string'). 6753 */ 6754 static char_u * 6755 string_quote(str, function) 6756 char_u *str; 6757 int function; 6758 { 6759 unsigned len; 6760 char_u *p, *r, *s; 6761 6762 len = (function ? 13 : 3); 6763 if (str != NULL) 6764 { 6765 len += STRLEN(str); 6766 for (p = str; *p != NUL; mb_ptr_adv(p)) 6767 if (*p == '\'') 6768 ++len; 6769 } 6770 s = r = alloc(len); 6771 if (r != NULL) 6772 { 6773 if (function) 6774 { 6775 STRCPY(r, "function('"); 6776 r += 10; 6777 } 6778 else 6779 *r++ = '\''; 6780 if (str != NULL) 6781 for (p = str; *p != NUL; ) 6782 { 6783 if (*p == '\'') 6784 *r++ = '\''; 6785 MB_COPY_CHAR(p, r); 6786 } 6787 *r++ = '\''; 6788 if (function) 6789 *r++ = ')'; 6790 *r++ = NUL; 6791 } 6792 return s; 6793 } 6794 6795 /* 6796 * Get the value of an environment variable. 6797 * "arg" is pointing to the '$'. It is advanced to after the name. 6798 * If the environment variable was not set, silently assume it is empty. 6799 * Always return OK. 6800 */ 6801 static int 6802 get_env_tv(arg, rettv, evaluate) 6803 char_u **arg; 6804 typval_T *rettv; 6805 int evaluate; 6806 { 6807 char_u *string = NULL; 6808 int len; 6809 int cc; 6810 char_u *name; 6811 int mustfree = FALSE; 6812 6813 ++*arg; 6814 name = *arg; 6815 len = get_env_len(arg); 6816 if (evaluate) 6817 { 6818 if (len != 0) 6819 { 6820 cc = name[len]; 6821 name[len] = NUL; 6822 /* first try vim_getenv(), fast for normal environment vars */ 6823 string = vim_getenv(name, &mustfree); 6824 if (string != NULL && *string != NUL) 6825 { 6826 if (!mustfree) 6827 string = vim_strsave(string); 6828 } 6829 else 6830 { 6831 if (mustfree) 6832 vim_free(string); 6833 6834 /* next try expanding things like $VIM and ${HOME} */ 6835 string = expand_env_save(name - 1); 6836 if (string != NULL && *string == '$') 6837 { 6838 vim_free(string); 6839 string = NULL; 6840 } 6841 } 6842 name[len] = cc; 6843 } 6844 rettv->v_type = VAR_STRING; 6845 rettv->vval.v_string = string; 6846 } 6847 6848 return OK; 6849 } 6850 6851 /* 6852 * Array with names and number of arguments of all internal functions 6853 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6854 */ 6855 static struct fst 6856 { 6857 char *f_name; /* function name */ 6858 char f_min_argc; /* minimal number of arguments */ 6859 char f_max_argc; /* maximal number of arguments */ 6860 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6861 /* implemenation of function */ 6862 } functions[] = 6863 { 6864 {"add", 2, 2, f_add}, 6865 {"append", 2, 2, f_append}, 6866 {"argc", 0, 0, f_argc}, 6867 {"argidx", 0, 0, f_argidx}, 6868 {"argv", 1, 1, f_argv}, 6869 {"browse", 4, 4, f_browse}, 6870 {"browsedir", 2, 2, f_browsedir}, 6871 {"bufexists", 1, 1, f_bufexists}, 6872 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6873 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6874 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6875 {"buflisted", 1, 1, f_buflisted}, 6876 {"bufloaded", 1, 1, f_bufloaded}, 6877 {"bufname", 1, 1, f_bufname}, 6878 {"bufnr", 1, 2, f_bufnr}, 6879 {"bufwinnr", 1, 1, f_bufwinnr}, 6880 {"byte2line", 1, 1, f_byte2line}, 6881 {"byteidx", 2, 2, f_byteidx}, 6882 {"call", 2, 3, f_call}, 6883 {"char2nr", 1, 1, f_char2nr}, 6884 {"cindent", 1, 1, f_cindent}, 6885 {"col", 1, 1, f_col}, 6886 #if defined(FEAT_INS_EXPAND) 6887 {"complete_add", 1, 1, f_complete_add}, 6888 {"complete_check", 0, 0, f_complete_check}, 6889 #endif 6890 {"confirm", 1, 4, f_confirm}, 6891 {"copy", 1, 1, f_copy}, 6892 {"count", 2, 4, f_count}, 6893 {"cscope_connection",0,3, f_cscope_connection}, 6894 {"cursor", 1, 3, f_cursor}, 6895 {"deepcopy", 1, 2, f_deepcopy}, 6896 {"delete", 1, 1, f_delete}, 6897 {"did_filetype", 0, 0, f_did_filetype}, 6898 {"diff_filler", 1, 1, f_diff_filler}, 6899 {"diff_hlID", 2, 2, f_diff_hlID}, 6900 {"empty", 1, 1, f_empty}, 6901 {"escape", 2, 2, f_escape}, 6902 {"eval", 1, 1, f_eval}, 6903 {"eventhandler", 0, 0, f_eventhandler}, 6904 {"executable", 1, 1, f_executable}, 6905 {"exists", 1, 1, f_exists}, 6906 {"expand", 1, 2, f_expand}, 6907 {"extend", 2, 3, f_extend}, 6908 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6909 {"filereadable", 1, 1, f_filereadable}, 6910 {"filewritable", 1, 1, f_filewritable}, 6911 {"filter", 2, 2, f_filter}, 6912 {"finddir", 1, 3, f_finddir}, 6913 {"findfile", 1, 3, f_findfile}, 6914 {"fnamemodify", 2, 2, f_fnamemodify}, 6915 {"foldclosed", 1, 1, f_foldclosed}, 6916 {"foldclosedend", 1, 1, f_foldclosedend}, 6917 {"foldlevel", 1, 1, f_foldlevel}, 6918 {"foldtext", 0, 0, f_foldtext}, 6919 {"foldtextresult", 1, 1, f_foldtextresult}, 6920 {"foreground", 0, 0, f_foreground}, 6921 {"function", 1, 1, f_function}, 6922 {"garbagecollect", 0, 0, f_garbagecollect}, 6923 {"get", 2, 3, f_get}, 6924 {"getbufline", 2, 3, f_getbufline}, 6925 {"getbufvar", 2, 2, f_getbufvar}, 6926 {"getchar", 0, 1, f_getchar}, 6927 {"getcharmod", 0, 0, f_getcharmod}, 6928 {"getcmdline", 0, 0, f_getcmdline}, 6929 {"getcmdpos", 0, 0, f_getcmdpos}, 6930 {"getcmdtype", 0, 0, f_getcmdtype}, 6931 {"getcwd", 0, 0, f_getcwd}, 6932 {"getfontname", 0, 1, f_getfontname}, 6933 {"getfperm", 1, 1, f_getfperm}, 6934 {"getfsize", 1, 1, f_getfsize}, 6935 {"getftime", 1, 1, f_getftime}, 6936 {"getftype", 1, 1, f_getftype}, 6937 {"getline", 1, 2, f_getline}, 6938 {"getloclist", 1, 1, f_getqflist}, 6939 {"getpos", 1, 1, f_getpos}, 6940 {"getqflist", 0, 0, f_getqflist}, 6941 {"getreg", 0, 2, f_getreg}, 6942 {"getregtype", 0, 1, f_getregtype}, 6943 {"getwinposx", 0, 0, f_getwinposx}, 6944 {"getwinposy", 0, 0, f_getwinposy}, 6945 {"getwinvar", 2, 2, f_getwinvar}, 6946 {"glob", 1, 1, f_glob}, 6947 {"globpath", 2, 2, f_globpath}, 6948 {"has", 1, 1, f_has}, 6949 {"has_key", 2, 2, f_has_key}, 6950 {"hasmapto", 1, 2, f_hasmapto}, 6951 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6952 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6953 {"histadd", 2, 2, f_histadd}, 6954 {"histdel", 1, 2, f_histdel}, 6955 {"histget", 1, 2, f_histget}, 6956 {"histnr", 1, 1, f_histnr}, 6957 {"hlID", 1, 1, f_hlID}, 6958 {"hlexists", 1, 1, f_hlexists}, 6959 {"hostname", 0, 0, f_hostname}, 6960 {"iconv", 3, 3, f_iconv}, 6961 {"indent", 1, 1, f_indent}, 6962 {"index", 2, 4, f_index}, 6963 {"input", 1, 3, f_input}, 6964 {"inputdialog", 1, 3, f_inputdialog}, 6965 {"inputlist", 1, 1, f_inputlist}, 6966 {"inputrestore", 0, 0, f_inputrestore}, 6967 {"inputsave", 0, 0, f_inputsave}, 6968 {"inputsecret", 1, 2, f_inputsecret}, 6969 {"insert", 2, 3, f_insert}, 6970 {"isdirectory", 1, 1, f_isdirectory}, 6971 {"islocked", 1, 1, f_islocked}, 6972 {"items", 1, 1, f_items}, 6973 {"join", 1, 2, f_join}, 6974 {"keys", 1, 1, f_keys}, 6975 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6976 {"len", 1, 1, f_len}, 6977 {"libcall", 3, 3, f_libcall}, 6978 {"libcallnr", 3, 3, f_libcallnr}, 6979 {"line", 1, 1, f_line}, 6980 {"line2byte", 1, 1, f_line2byte}, 6981 {"lispindent", 1, 1, f_lispindent}, 6982 {"localtime", 0, 0, f_localtime}, 6983 {"map", 2, 2, f_map}, 6984 {"maparg", 1, 2, f_maparg}, 6985 {"mapcheck", 1, 2, f_mapcheck}, 6986 {"match", 2, 4, f_match}, 6987 {"matchend", 2, 4, f_matchend}, 6988 {"matchlist", 2, 4, f_matchlist}, 6989 {"matchstr", 2, 4, f_matchstr}, 6990 {"max", 1, 1, f_max}, 6991 {"min", 1, 1, f_min}, 6992 #ifdef vim_mkdir 6993 {"mkdir", 1, 3, f_mkdir}, 6994 #endif 6995 {"mode", 0, 0, f_mode}, 6996 {"nextnonblank", 1, 1, f_nextnonblank}, 6997 {"nr2char", 1, 1, f_nr2char}, 6998 {"prevnonblank", 1, 1, f_prevnonblank}, 6999 {"printf", 2, 19, f_printf}, 7000 {"pumvisible", 0, 0, f_pumvisible}, 7001 {"range", 1, 3, f_range}, 7002 {"readfile", 1, 3, f_readfile}, 7003 {"remote_expr", 2, 3, f_remote_expr}, 7004 {"remote_foreground", 1, 1, f_remote_foreground}, 7005 {"remote_peek", 1, 2, f_remote_peek}, 7006 {"remote_read", 1, 1, f_remote_read}, 7007 {"remote_send", 2, 3, f_remote_send}, 7008 {"remove", 2, 3, f_remove}, 7009 {"rename", 2, 2, f_rename}, 7010 {"repeat", 2, 2, f_repeat}, 7011 {"resolve", 1, 1, f_resolve}, 7012 {"reverse", 1, 1, f_reverse}, 7013 {"search", 1, 3, f_search}, 7014 {"searchdecl", 1, 3, f_searchdecl}, 7015 {"searchpair", 3, 6, f_searchpair}, 7016 {"searchpairpos", 3, 6, f_searchpairpos}, 7017 {"searchpos", 1, 3, f_searchpos}, 7018 {"server2client", 2, 2, f_server2client}, 7019 {"serverlist", 0, 0, f_serverlist}, 7020 {"setbufvar", 3, 3, f_setbufvar}, 7021 {"setcmdpos", 1, 1, f_setcmdpos}, 7022 {"setline", 2, 2, f_setline}, 7023 {"setloclist", 2, 3, f_setloclist}, 7024 {"setpos", 2, 2, f_setpos}, 7025 {"setqflist", 1, 2, f_setqflist}, 7026 {"setreg", 2, 3, f_setreg}, 7027 {"setwinvar", 3, 3, f_setwinvar}, 7028 {"simplify", 1, 1, f_simplify}, 7029 {"sort", 1, 2, f_sort}, 7030 {"soundfold", 1, 1, f_soundfold}, 7031 {"spellbadword", 0, 1, f_spellbadword}, 7032 {"spellsuggest", 1, 3, f_spellsuggest}, 7033 {"split", 1, 3, f_split}, 7034 #ifdef HAVE_STRFTIME 7035 {"strftime", 1, 2, f_strftime}, 7036 #endif 7037 {"stridx", 2, 3, f_stridx}, 7038 {"string", 1, 1, f_string}, 7039 {"strlen", 1, 1, f_strlen}, 7040 {"strpart", 2, 3, f_strpart}, 7041 {"strridx", 2, 3, f_strridx}, 7042 {"strtrans", 1, 1, f_strtrans}, 7043 {"submatch", 1, 1, f_submatch}, 7044 {"substitute", 4, 4, f_substitute}, 7045 {"synID", 3, 3, f_synID}, 7046 {"synIDattr", 2, 3, f_synIDattr}, 7047 {"synIDtrans", 1, 1, f_synIDtrans}, 7048 {"system", 1, 2, f_system}, 7049 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 7050 {"tabpagenr", 0, 1, f_tabpagenr}, 7051 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 7052 {"tagfiles", 0, 0, f_tagfiles}, 7053 {"taglist", 1, 1, f_taglist}, 7054 {"tempname", 0, 0, f_tempname}, 7055 {"test", 1, 1, f_test}, 7056 {"tolower", 1, 1, f_tolower}, 7057 {"toupper", 1, 1, f_toupper}, 7058 {"tr", 3, 3, f_tr}, 7059 {"type", 1, 1, f_type}, 7060 {"values", 1, 1, f_values}, 7061 {"virtcol", 1, 1, f_virtcol}, 7062 {"visualmode", 0, 1, f_visualmode}, 7063 {"winbufnr", 1, 1, f_winbufnr}, 7064 {"wincol", 0, 0, f_wincol}, 7065 {"winheight", 1, 1, f_winheight}, 7066 {"winline", 0, 0, f_winline}, 7067 {"winnr", 0, 1, f_winnr}, 7068 {"winrestcmd", 0, 0, f_winrestcmd}, 7069 {"winrestview", 1, 1, f_winrestview}, 7070 {"winsaveview", 0, 0, f_winsaveview}, 7071 {"winwidth", 1, 1, f_winwidth}, 7072 {"writefile", 2, 3, f_writefile}, 7073 }; 7074 7075 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 7076 7077 /* 7078 * Function given to ExpandGeneric() to obtain the list of internal 7079 * or user defined function names. 7080 */ 7081 char_u * 7082 get_function_name(xp, idx) 7083 expand_T *xp; 7084 int idx; 7085 { 7086 static int intidx = -1; 7087 char_u *name; 7088 7089 if (idx == 0) 7090 intidx = -1; 7091 if (intidx < 0) 7092 { 7093 name = get_user_func_name(xp, idx); 7094 if (name != NULL) 7095 return name; 7096 } 7097 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 7098 { 7099 STRCPY(IObuff, functions[intidx].f_name); 7100 STRCAT(IObuff, "("); 7101 if (functions[intidx].f_max_argc == 0) 7102 STRCAT(IObuff, ")"); 7103 return IObuff; 7104 } 7105 7106 return NULL; 7107 } 7108 7109 /* 7110 * Function given to ExpandGeneric() to obtain the list of internal or 7111 * user defined variable or function names. 7112 */ 7113 /*ARGSUSED*/ 7114 char_u * 7115 get_expr_name(xp, idx) 7116 expand_T *xp; 7117 int idx; 7118 { 7119 static int intidx = -1; 7120 char_u *name; 7121 7122 if (idx == 0) 7123 intidx = -1; 7124 if (intidx < 0) 7125 { 7126 name = get_function_name(xp, idx); 7127 if (name != NULL) 7128 return name; 7129 } 7130 return get_user_var_name(xp, ++intidx); 7131 } 7132 7133 #endif /* FEAT_CMDL_COMPL */ 7134 7135 /* 7136 * Find internal function in table above. 7137 * Return index, or -1 if not found 7138 */ 7139 static int 7140 find_internal_func(name) 7141 char_u *name; /* name of the function */ 7142 { 7143 int first = 0; 7144 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 7145 int cmp; 7146 int x; 7147 7148 /* 7149 * Find the function name in the table. Binary search. 7150 */ 7151 while (first <= last) 7152 { 7153 x = first + ((unsigned)(last - first) >> 1); 7154 cmp = STRCMP(name, functions[x].f_name); 7155 if (cmp < 0) 7156 last = x - 1; 7157 else if (cmp > 0) 7158 first = x + 1; 7159 else 7160 return x; 7161 } 7162 return -1; 7163 } 7164 7165 /* 7166 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7167 * name it contains, otherwise return "name". 7168 */ 7169 static char_u * 7170 deref_func_name(name, lenp) 7171 char_u *name; 7172 int *lenp; 7173 { 7174 dictitem_T *v; 7175 int cc; 7176 7177 cc = name[*lenp]; 7178 name[*lenp] = NUL; 7179 v = find_var(name, NULL); 7180 name[*lenp] = cc; 7181 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7182 { 7183 if (v->di_tv.vval.v_string == NULL) 7184 { 7185 *lenp = 0; 7186 return (char_u *)""; /* just in case */ 7187 } 7188 *lenp = STRLEN(v->di_tv.vval.v_string); 7189 return v->di_tv.vval.v_string; 7190 } 7191 7192 return name; 7193 } 7194 7195 /* 7196 * Allocate a variable for the result of a function. 7197 * Return OK or FAIL. 7198 */ 7199 static int 7200 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7201 evaluate, selfdict) 7202 char_u *name; /* name of the function */ 7203 int len; /* length of "name" */ 7204 typval_T *rettv; 7205 char_u **arg; /* argument, pointing to the '(' */ 7206 linenr_T firstline; /* first line of range */ 7207 linenr_T lastline; /* last line of range */ 7208 int *doesrange; /* return: function handled range */ 7209 int evaluate; 7210 dict_T *selfdict; /* Dictionary for "self" */ 7211 { 7212 char_u *argp; 7213 int ret = OK; 7214 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7215 int argcount = 0; /* number of arguments found */ 7216 7217 /* 7218 * Get the arguments. 7219 */ 7220 argp = *arg; 7221 while (argcount < MAX_FUNC_ARGS) 7222 { 7223 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7224 if (*argp == ')' || *argp == ',' || *argp == NUL) 7225 break; 7226 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7227 { 7228 ret = FAIL; 7229 break; 7230 } 7231 ++argcount; 7232 if (*argp != ',') 7233 break; 7234 } 7235 if (*argp == ')') 7236 ++argp; 7237 else 7238 ret = FAIL; 7239 7240 if (ret == OK) 7241 ret = call_func(name, len, rettv, argcount, argvars, 7242 firstline, lastline, doesrange, evaluate, selfdict); 7243 else if (!aborting()) 7244 { 7245 if (argcount == MAX_FUNC_ARGS) 7246 emsg_funcname("E740: Too many arguments for function %s", name); 7247 else 7248 emsg_funcname("E116: Invalid arguments for function %s", name); 7249 } 7250 7251 while (--argcount >= 0) 7252 clear_tv(&argvars[argcount]); 7253 7254 *arg = skipwhite(argp); 7255 return ret; 7256 } 7257 7258 7259 /* 7260 * Call a function with its resolved parameters 7261 * Return OK when the function can't be called, FAIL otherwise. 7262 * Also returns OK when an error was encountered while executing the function. 7263 */ 7264 static int 7265 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7266 doesrange, evaluate, selfdict) 7267 char_u *name; /* name of the function */ 7268 int len; /* length of "name" */ 7269 typval_T *rettv; /* return value goes here */ 7270 int argcount; /* number of "argvars" */ 7271 typval_T *argvars; /* vars for arguments */ 7272 linenr_T firstline; /* first line of range */ 7273 linenr_T lastline; /* last line of range */ 7274 int *doesrange; /* return: function handled range */ 7275 int evaluate; 7276 dict_T *selfdict; /* Dictionary for "self" */ 7277 { 7278 int ret = FAIL; 7279 #define ERROR_UNKNOWN 0 7280 #define ERROR_TOOMANY 1 7281 #define ERROR_TOOFEW 2 7282 #define ERROR_SCRIPT 3 7283 #define ERROR_DICT 4 7284 #define ERROR_NONE 5 7285 #define ERROR_OTHER 6 7286 int error = ERROR_NONE; 7287 int i; 7288 int llen; 7289 ufunc_T *fp; 7290 int cc; 7291 #define FLEN_FIXED 40 7292 char_u fname_buf[FLEN_FIXED + 1]; 7293 char_u *fname; 7294 7295 /* 7296 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7297 * Change <SNR>123_name() to K_SNR 123_name(). 7298 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7299 */ 7300 cc = name[len]; 7301 name[len] = NUL; 7302 llen = eval_fname_script(name); 7303 if (llen > 0) 7304 { 7305 fname_buf[0] = K_SPECIAL; 7306 fname_buf[1] = KS_EXTRA; 7307 fname_buf[2] = (int)KE_SNR; 7308 i = 3; 7309 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7310 { 7311 if (current_SID <= 0) 7312 error = ERROR_SCRIPT; 7313 else 7314 { 7315 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7316 i = (int)STRLEN(fname_buf); 7317 } 7318 } 7319 if (i + STRLEN(name + llen) < FLEN_FIXED) 7320 { 7321 STRCPY(fname_buf + i, name + llen); 7322 fname = fname_buf; 7323 } 7324 else 7325 { 7326 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7327 if (fname == NULL) 7328 error = ERROR_OTHER; 7329 else 7330 { 7331 mch_memmove(fname, fname_buf, (size_t)i); 7332 STRCPY(fname + i, name + llen); 7333 } 7334 } 7335 } 7336 else 7337 fname = name; 7338 7339 *doesrange = FALSE; 7340 7341 7342 /* execute the function if no errors detected and executing */ 7343 if (evaluate && error == ERROR_NONE) 7344 { 7345 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7346 error = ERROR_UNKNOWN; 7347 7348 if (!builtin_function(fname)) 7349 { 7350 /* 7351 * User defined function. 7352 */ 7353 fp = find_func(fname); 7354 7355 #ifdef FEAT_AUTOCMD 7356 /* Trigger FuncUndefined event, may load the function. */ 7357 if (fp == NULL 7358 && apply_autocmds(EVENT_FUNCUNDEFINED, 7359 fname, fname, TRUE, NULL) 7360 && !aborting()) 7361 { 7362 /* executed an autocommand, search for the function again */ 7363 fp = find_func(fname); 7364 } 7365 #endif 7366 /* Try loading a package. */ 7367 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7368 { 7369 /* loaded a package, search for the function again */ 7370 fp = find_func(fname); 7371 } 7372 7373 if (fp != NULL) 7374 { 7375 if (fp->uf_flags & FC_RANGE) 7376 *doesrange = TRUE; 7377 if (argcount < fp->uf_args.ga_len) 7378 error = ERROR_TOOFEW; 7379 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7380 error = ERROR_TOOMANY; 7381 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7382 error = ERROR_DICT; 7383 else 7384 { 7385 /* 7386 * Call the user function. 7387 * Save and restore search patterns, script variables and 7388 * redo buffer. 7389 */ 7390 save_search_patterns(); 7391 saveRedobuff(); 7392 ++fp->uf_calls; 7393 call_user_func(fp, argcount, argvars, rettv, 7394 firstline, lastline, 7395 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7396 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7397 && fp->uf_refcount <= 0) 7398 /* Function was unreferenced while being used, free it 7399 * now. */ 7400 func_free(fp); 7401 restoreRedobuff(); 7402 restore_search_patterns(); 7403 error = ERROR_NONE; 7404 } 7405 } 7406 } 7407 else 7408 { 7409 /* 7410 * Find the function name in the table, call its implementation. 7411 */ 7412 i = find_internal_func(fname); 7413 if (i >= 0) 7414 { 7415 if (argcount < functions[i].f_min_argc) 7416 error = ERROR_TOOFEW; 7417 else if (argcount > functions[i].f_max_argc) 7418 error = ERROR_TOOMANY; 7419 else 7420 { 7421 argvars[argcount].v_type = VAR_UNKNOWN; 7422 functions[i].f_func(argvars, rettv); 7423 error = ERROR_NONE; 7424 } 7425 } 7426 } 7427 /* 7428 * The function call (or "FuncUndefined" autocommand sequence) might 7429 * have been aborted by an error, an interrupt, or an explicitly thrown 7430 * exception that has not been caught so far. This situation can be 7431 * tested for by calling aborting(). For an error in an internal 7432 * function or for the "E132" error in call_user_func(), however, the 7433 * throw point at which the "force_abort" flag (temporarily reset by 7434 * emsg()) is normally updated has not been reached yet. We need to 7435 * update that flag first to make aborting() reliable. 7436 */ 7437 update_force_abort(); 7438 } 7439 if (error == ERROR_NONE) 7440 ret = OK; 7441 7442 /* 7443 * Report an error unless the argument evaluation or function call has been 7444 * cancelled due to an aborting error, an interrupt, or an exception. 7445 */ 7446 if (!aborting()) 7447 { 7448 switch (error) 7449 { 7450 case ERROR_UNKNOWN: 7451 emsg_funcname("E117: Unknown function: %s", name); 7452 break; 7453 case ERROR_TOOMANY: 7454 emsg_funcname(e_toomanyarg, name); 7455 break; 7456 case ERROR_TOOFEW: 7457 emsg_funcname("E119: Not enough arguments for function: %s", 7458 name); 7459 break; 7460 case ERROR_SCRIPT: 7461 emsg_funcname("E120: Using <SID> not in a script context: %s", 7462 name); 7463 break; 7464 case ERROR_DICT: 7465 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7466 name); 7467 break; 7468 } 7469 } 7470 7471 name[len] = cc; 7472 if (fname != name && fname != fname_buf) 7473 vim_free(fname); 7474 7475 return ret; 7476 } 7477 7478 /* 7479 * Give an error message with a function name. Handle <SNR> things. 7480 */ 7481 static void 7482 emsg_funcname(msg, name) 7483 char *msg; 7484 char_u *name; 7485 { 7486 char_u *p; 7487 7488 if (*name == K_SPECIAL) 7489 p = concat_str((char_u *)"<SNR>", name + 3); 7490 else 7491 p = name; 7492 EMSG2(_(msg), p); 7493 if (p != name) 7494 vim_free(p); 7495 } 7496 7497 /********************************************* 7498 * Implementation of the built-in functions 7499 */ 7500 7501 /* 7502 * "add(list, item)" function 7503 */ 7504 static void 7505 f_add(argvars, rettv) 7506 typval_T *argvars; 7507 typval_T *rettv; 7508 { 7509 list_T *l; 7510 7511 rettv->vval.v_number = 1; /* Default: Failed */ 7512 if (argvars[0].v_type == VAR_LIST) 7513 { 7514 if ((l = argvars[0].vval.v_list) != NULL 7515 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7516 && list_append_tv(l, &argvars[1]) == OK) 7517 copy_tv(&argvars[0], rettv); 7518 } 7519 else 7520 EMSG(_(e_listreq)); 7521 } 7522 7523 /* 7524 * "append(lnum, string/list)" function 7525 */ 7526 static void 7527 f_append(argvars, rettv) 7528 typval_T *argvars; 7529 typval_T *rettv; 7530 { 7531 long lnum; 7532 char_u *line; 7533 list_T *l = NULL; 7534 listitem_T *li = NULL; 7535 typval_T *tv; 7536 long added = 0; 7537 7538 lnum = get_tv_lnum(argvars); 7539 if (lnum >= 0 7540 && lnum <= curbuf->b_ml.ml_line_count 7541 && u_save(lnum, lnum + 1) == OK) 7542 { 7543 if (argvars[1].v_type == VAR_LIST) 7544 { 7545 l = argvars[1].vval.v_list; 7546 if (l == NULL) 7547 return; 7548 li = l->lv_first; 7549 } 7550 rettv->vval.v_number = 0; /* Default: Success */ 7551 for (;;) 7552 { 7553 if (l == NULL) 7554 tv = &argvars[1]; /* append a string */ 7555 else if (li == NULL) 7556 break; /* end of list */ 7557 else 7558 tv = &li->li_tv; /* append item from list */ 7559 line = get_tv_string_chk(tv); 7560 if (line == NULL) /* type error */ 7561 { 7562 rettv->vval.v_number = 1; /* Failed */ 7563 break; 7564 } 7565 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7566 ++added; 7567 if (l == NULL) 7568 break; 7569 li = li->li_next; 7570 } 7571 7572 appended_lines_mark(lnum, added); 7573 if (curwin->w_cursor.lnum > lnum) 7574 curwin->w_cursor.lnum += added; 7575 } 7576 else 7577 rettv->vval.v_number = 1; /* Failed */ 7578 } 7579 7580 /* 7581 * "argc()" function 7582 */ 7583 /* ARGSUSED */ 7584 static void 7585 f_argc(argvars, rettv) 7586 typval_T *argvars; 7587 typval_T *rettv; 7588 { 7589 rettv->vval.v_number = ARGCOUNT; 7590 } 7591 7592 /* 7593 * "argidx()" function 7594 */ 7595 /* ARGSUSED */ 7596 static void 7597 f_argidx(argvars, rettv) 7598 typval_T *argvars; 7599 typval_T *rettv; 7600 { 7601 rettv->vval.v_number = curwin->w_arg_idx; 7602 } 7603 7604 /* 7605 * "argv(nr)" function 7606 */ 7607 static void 7608 f_argv(argvars, rettv) 7609 typval_T *argvars; 7610 typval_T *rettv; 7611 { 7612 int idx; 7613 7614 idx = get_tv_number_chk(&argvars[0], NULL); 7615 if (idx >= 0 && idx < ARGCOUNT) 7616 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7617 else 7618 rettv->vval.v_string = NULL; 7619 rettv->v_type = VAR_STRING; 7620 } 7621 7622 /* 7623 * "browse(save, title, initdir, default)" function 7624 */ 7625 /* ARGSUSED */ 7626 static void 7627 f_browse(argvars, rettv) 7628 typval_T *argvars; 7629 typval_T *rettv; 7630 { 7631 #ifdef FEAT_BROWSE 7632 int save; 7633 char_u *title; 7634 char_u *initdir; 7635 char_u *defname; 7636 char_u buf[NUMBUFLEN]; 7637 char_u buf2[NUMBUFLEN]; 7638 int error = FALSE; 7639 7640 save = get_tv_number_chk(&argvars[0], &error); 7641 title = get_tv_string_chk(&argvars[1]); 7642 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7643 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7644 7645 if (error || title == NULL || initdir == NULL || defname == NULL) 7646 rettv->vval.v_string = NULL; 7647 else 7648 rettv->vval.v_string = 7649 do_browse(save ? BROWSE_SAVE : 0, 7650 title, defname, NULL, initdir, NULL, curbuf); 7651 #else 7652 rettv->vval.v_string = NULL; 7653 #endif 7654 rettv->v_type = VAR_STRING; 7655 } 7656 7657 /* 7658 * "browsedir(title, initdir)" function 7659 */ 7660 /* ARGSUSED */ 7661 static void 7662 f_browsedir(argvars, rettv) 7663 typval_T *argvars; 7664 typval_T *rettv; 7665 { 7666 #ifdef FEAT_BROWSE 7667 char_u *title; 7668 char_u *initdir; 7669 char_u buf[NUMBUFLEN]; 7670 7671 title = get_tv_string_chk(&argvars[0]); 7672 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7673 7674 if (title == NULL || initdir == NULL) 7675 rettv->vval.v_string = NULL; 7676 else 7677 rettv->vval.v_string = do_browse(BROWSE_DIR, 7678 title, NULL, NULL, initdir, NULL, curbuf); 7679 #else 7680 rettv->vval.v_string = NULL; 7681 #endif 7682 rettv->v_type = VAR_STRING; 7683 } 7684 7685 static buf_T *find_buffer __ARGS((typval_T *avar)); 7686 7687 /* 7688 * Find a buffer by number or exact name. 7689 */ 7690 static buf_T * 7691 find_buffer(avar) 7692 typval_T *avar; 7693 { 7694 buf_T *buf = NULL; 7695 7696 if (avar->v_type == VAR_NUMBER) 7697 buf = buflist_findnr((int)avar->vval.v_number); 7698 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7699 { 7700 buf = buflist_findname_exp(avar->vval.v_string); 7701 if (buf == NULL) 7702 { 7703 /* No full path name match, try a match with a URL or a "nofile" 7704 * buffer, these don't use the full path. */ 7705 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7706 if (buf->b_fname != NULL 7707 && (path_with_url(buf->b_fname) 7708 #ifdef FEAT_QUICKFIX 7709 || bt_nofile(buf) 7710 #endif 7711 ) 7712 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7713 break; 7714 } 7715 } 7716 return buf; 7717 } 7718 7719 /* 7720 * "bufexists(expr)" function 7721 */ 7722 static void 7723 f_bufexists(argvars, rettv) 7724 typval_T *argvars; 7725 typval_T *rettv; 7726 { 7727 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7728 } 7729 7730 /* 7731 * "buflisted(expr)" function 7732 */ 7733 static void 7734 f_buflisted(argvars, rettv) 7735 typval_T *argvars; 7736 typval_T *rettv; 7737 { 7738 buf_T *buf; 7739 7740 buf = find_buffer(&argvars[0]); 7741 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7742 } 7743 7744 /* 7745 * "bufloaded(expr)" function 7746 */ 7747 static void 7748 f_bufloaded(argvars, rettv) 7749 typval_T *argvars; 7750 typval_T *rettv; 7751 { 7752 buf_T *buf; 7753 7754 buf = find_buffer(&argvars[0]); 7755 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7756 } 7757 7758 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7759 7760 /* 7761 * Get buffer by number or pattern. 7762 */ 7763 static buf_T * 7764 get_buf_tv(tv) 7765 typval_T *tv; 7766 { 7767 char_u *name = tv->vval.v_string; 7768 int save_magic; 7769 char_u *save_cpo; 7770 buf_T *buf; 7771 7772 if (tv->v_type == VAR_NUMBER) 7773 return buflist_findnr((int)tv->vval.v_number); 7774 if (tv->v_type != VAR_STRING) 7775 return NULL; 7776 if (name == NULL || *name == NUL) 7777 return curbuf; 7778 if (name[0] == '$' && name[1] == NUL) 7779 return lastbuf; 7780 7781 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7782 save_magic = p_magic; 7783 p_magic = TRUE; 7784 save_cpo = p_cpo; 7785 p_cpo = (char_u *)""; 7786 7787 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7788 TRUE, FALSE)); 7789 7790 p_magic = save_magic; 7791 p_cpo = save_cpo; 7792 7793 /* If not found, try expanding the name, like done for bufexists(). */ 7794 if (buf == NULL) 7795 buf = find_buffer(tv); 7796 7797 return buf; 7798 } 7799 7800 /* 7801 * "bufname(expr)" function 7802 */ 7803 static void 7804 f_bufname(argvars, rettv) 7805 typval_T *argvars; 7806 typval_T *rettv; 7807 { 7808 buf_T *buf; 7809 7810 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7811 ++emsg_off; 7812 buf = get_buf_tv(&argvars[0]); 7813 rettv->v_type = VAR_STRING; 7814 if (buf != NULL && buf->b_fname != NULL) 7815 rettv->vval.v_string = vim_strsave(buf->b_fname); 7816 else 7817 rettv->vval.v_string = NULL; 7818 --emsg_off; 7819 } 7820 7821 /* 7822 * "bufnr(expr)" function 7823 */ 7824 static void 7825 f_bufnr(argvars, rettv) 7826 typval_T *argvars; 7827 typval_T *rettv; 7828 { 7829 buf_T *buf; 7830 int error = FALSE; 7831 char_u *name; 7832 7833 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7834 ++emsg_off; 7835 buf = get_buf_tv(&argvars[0]); 7836 --emsg_off; 7837 7838 /* If the buffer isn't found and the second argument is not zero create a 7839 * new buffer. */ 7840 if (buf == NULL 7841 && argvars[1].v_type != VAR_UNKNOWN 7842 && get_tv_number_chk(&argvars[1], &error) != 0 7843 && !error 7844 && (name = get_tv_string_chk(&argvars[0])) != NULL 7845 && !error) 7846 buf = buflist_new(name, NULL, (linenr_T)1, 0); 7847 7848 if (buf != NULL) 7849 rettv->vval.v_number = buf->b_fnum; 7850 else 7851 rettv->vval.v_number = -1; 7852 } 7853 7854 /* 7855 * "bufwinnr(nr)" function 7856 */ 7857 static void 7858 f_bufwinnr(argvars, rettv) 7859 typval_T *argvars; 7860 typval_T *rettv; 7861 { 7862 #ifdef FEAT_WINDOWS 7863 win_T *wp; 7864 int winnr = 0; 7865 #endif 7866 buf_T *buf; 7867 7868 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7869 ++emsg_off; 7870 buf = get_buf_tv(&argvars[0]); 7871 #ifdef FEAT_WINDOWS 7872 for (wp = firstwin; wp; wp = wp->w_next) 7873 { 7874 ++winnr; 7875 if (wp->w_buffer == buf) 7876 break; 7877 } 7878 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7879 #else 7880 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7881 #endif 7882 --emsg_off; 7883 } 7884 7885 /* 7886 * "byte2line(byte)" function 7887 */ 7888 /*ARGSUSED*/ 7889 static void 7890 f_byte2line(argvars, rettv) 7891 typval_T *argvars; 7892 typval_T *rettv; 7893 { 7894 #ifndef FEAT_BYTEOFF 7895 rettv->vval.v_number = -1; 7896 #else 7897 long boff = 0; 7898 7899 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7900 if (boff < 0) 7901 rettv->vval.v_number = -1; 7902 else 7903 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7904 (linenr_T)0, &boff); 7905 #endif 7906 } 7907 7908 /* 7909 * "byteidx()" function 7910 */ 7911 /*ARGSUSED*/ 7912 static void 7913 f_byteidx(argvars, rettv) 7914 typval_T *argvars; 7915 typval_T *rettv; 7916 { 7917 #ifdef FEAT_MBYTE 7918 char_u *t; 7919 #endif 7920 char_u *str; 7921 long idx; 7922 7923 str = get_tv_string_chk(&argvars[0]); 7924 idx = get_tv_number_chk(&argvars[1], NULL); 7925 rettv->vval.v_number = -1; 7926 if (str == NULL || idx < 0) 7927 return; 7928 7929 #ifdef FEAT_MBYTE 7930 t = str; 7931 for ( ; idx > 0; idx--) 7932 { 7933 if (*t == NUL) /* EOL reached */ 7934 return; 7935 t += (*mb_ptr2len)(t); 7936 } 7937 rettv->vval.v_number = t - str; 7938 #else 7939 if (idx <= STRLEN(str)) 7940 rettv->vval.v_number = idx; 7941 #endif 7942 } 7943 7944 /* 7945 * "call(func, arglist)" function 7946 */ 7947 static void 7948 f_call(argvars, rettv) 7949 typval_T *argvars; 7950 typval_T *rettv; 7951 { 7952 char_u *func; 7953 typval_T argv[MAX_FUNC_ARGS]; 7954 int argc = 0; 7955 listitem_T *item; 7956 int dummy; 7957 dict_T *selfdict = NULL; 7958 7959 rettv->vval.v_number = 0; 7960 if (argvars[1].v_type != VAR_LIST) 7961 { 7962 EMSG(_(e_listreq)); 7963 return; 7964 } 7965 if (argvars[1].vval.v_list == NULL) 7966 return; 7967 7968 if (argvars[0].v_type == VAR_FUNC) 7969 func = argvars[0].vval.v_string; 7970 else 7971 func = get_tv_string(&argvars[0]); 7972 if (*func == NUL) 7973 return; /* type error or empty name */ 7974 7975 if (argvars[2].v_type != VAR_UNKNOWN) 7976 { 7977 if (argvars[2].v_type != VAR_DICT) 7978 { 7979 EMSG(_(e_dictreq)); 7980 return; 7981 } 7982 selfdict = argvars[2].vval.v_dict; 7983 } 7984 7985 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7986 item = item->li_next) 7987 { 7988 if (argc == MAX_FUNC_ARGS) 7989 { 7990 EMSG(_("E699: Too many arguments")); 7991 break; 7992 } 7993 /* Make a copy of each argument. This is needed to be able to set 7994 * v_lock to VAR_FIXED in the copy without changing the original list. 7995 */ 7996 copy_tv(&item->li_tv, &argv[argc++]); 7997 } 7998 7999 if (item == NULL) 8000 (void)call_func(func, STRLEN(func), rettv, argc, argv, 8001 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 8002 &dummy, TRUE, selfdict); 8003 8004 /* Free the arguments. */ 8005 while (argc > 0) 8006 clear_tv(&argv[--argc]); 8007 } 8008 8009 /* 8010 * "char2nr(string)" function 8011 */ 8012 static void 8013 f_char2nr(argvars, rettv) 8014 typval_T *argvars; 8015 typval_T *rettv; 8016 { 8017 #ifdef FEAT_MBYTE 8018 if (has_mbyte) 8019 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 8020 else 8021 #endif 8022 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 8023 } 8024 8025 /* 8026 * "cindent(lnum)" function 8027 */ 8028 static void 8029 f_cindent(argvars, rettv) 8030 typval_T *argvars; 8031 typval_T *rettv; 8032 { 8033 #ifdef FEAT_CINDENT 8034 pos_T pos; 8035 linenr_T lnum; 8036 8037 pos = curwin->w_cursor; 8038 lnum = get_tv_lnum(argvars); 8039 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8040 { 8041 curwin->w_cursor.lnum = lnum; 8042 rettv->vval.v_number = get_c_indent(); 8043 curwin->w_cursor = pos; 8044 } 8045 else 8046 #endif 8047 rettv->vval.v_number = -1; 8048 } 8049 8050 /* 8051 * "col(string)" function 8052 */ 8053 static void 8054 f_col(argvars, rettv) 8055 typval_T *argvars; 8056 typval_T *rettv; 8057 { 8058 colnr_T col = 0; 8059 pos_T *fp; 8060 int fnum = curbuf->b_fnum; 8061 8062 fp = var2fpos(&argvars[0], FALSE, &fnum); 8063 if (fp != NULL && fnum == curbuf->b_fnum) 8064 { 8065 if (fp->col == MAXCOL) 8066 { 8067 /* '> can be MAXCOL, get the length of the line then */ 8068 if (fp->lnum <= curbuf->b_ml.ml_line_count) 8069 col = STRLEN(ml_get(fp->lnum)) + 1; 8070 else 8071 col = MAXCOL; 8072 } 8073 else 8074 { 8075 col = fp->col + 1; 8076 #ifdef FEAT_VIRTUALEDIT 8077 /* col(".") when the cursor is on the NUL at the end of the line 8078 * because of "coladd" can be seen as an extra column. */ 8079 if (virtual_active() && fp == &curwin->w_cursor) 8080 { 8081 char_u *p = ml_get_cursor(); 8082 8083 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 8084 curwin->w_virtcol - curwin->w_cursor.coladd)) 8085 { 8086 # ifdef FEAT_MBYTE 8087 int l; 8088 8089 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 8090 col += l; 8091 # else 8092 if (*p != NUL && p[1] == NUL) 8093 ++col; 8094 # endif 8095 } 8096 } 8097 #endif 8098 } 8099 } 8100 rettv->vval.v_number = col; 8101 } 8102 8103 #if defined(FEAT_INS_EXPAND) 8104 /* 8105 * "complete_add()" function 8106 */ 8107 /*ARGSUSED*/ 8108 static void 8109 f_complete_add(argvars, rettv) 8110 typval_T *argvars; 8111 typval_T *rettv; 8112 { 8113 char_u *word; 8114 char_u *extra = NULL; 8115 int icase = FALSE; 8116 8117 if (argvars[0].v_type == VAR_DICT && argvars[0].vval.v_dict != NULL) 8118 { 8119 word = get_dict_string(argvars[0].vval.v_dict, 8120 (char_u *)"word", FALSE); 8121 extra = get_dict_string(argvars[0].vval.v_dict, 8122 (char_u *)"menu", FALSE); 8123 icase = get_dict_number(argvars[0].vval.v_dict, (char_u *)"icase"); 8124 } 8125 else 8126 word = get_tv_string_chk(&argvars[0]); 8127 if (word != NULL) 8128 rettv->vval.v_number = ins_compl_add(word, -1, icase, 8129 NULL, extra, 0, 0); 8130 } 8131 8132 /* 8133 * "complete_check()" function 8134 */ 8135 /*ARGSUSED*/ 8136 static void 8137 f_complete_check(argvars, rettv) 8138 typval_T *argvars; 8139 typval_T *rettv; 8140 { 8141 int saved = RedrawingDisabled; 8142 8143 RedrawingDisabled = 0; 8144 ins_compl_check_keys(0); 8145 rettv->vval.v_number = compl_interrupted; 8146 RedrawingDisabled = saved; 8147 } 8148 #endif 8149 8150 /* 8151 * "confirm(message, buttons[, default [, type]])" function 8152 */ 8153 /*ARGSUSED*/ 8154 static void 8155 f_confirm(argvars, rettv) 8156 typval_T *argvars; 8157 typval_T *rettv; 8158 { 8159 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 8160 char_u *message; 8161 char_u *buttons = NULL; 8162 char_u buf[NUMBUFLEN]; 8163 char_u buf2[NUMBUFLEN]; 8164 int def = 1; 8165 int type = VIM_GENERIC; 8166 char_u *typestr; 8167 int error = FALSE; 8168 8169 message = get_tv_string_chk(&argvars[0]); 8170 if (message == NULL) 8171 error = TRUE; 8172 if (argvars[1].v_type != VAR_UNKNOWN) 8173 { 8174 buttons = get_tv_string_buf_chk(&argvars[1], buf); 8175 if (buttons == NULL) 8176 error = TRUE; 8177 if (argvars[2].v_type != VAR_UNKNOWN) 8178 { 8179 def = get_tv_number_chk(&argvars[2], &error); 8180 if (argvars[3].v_type != VAR_UNKNOWN) 8181 { 8182 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 8183 if (typestr == NULL) 8184 error = TRUE; 8185 else 8186 { 8187 switch (TOUPPER_ASC(*typestr)) 8188 { 8189 case 'E': type = VIM_ERROR; break; 8190 case 'Q': type = VIM_QUESTION; break; 8191 case 'I': type = VIM_INFO; break; 8192 case 'W': type = VIM_WARNING; break; 8193 case 'G': type = VIM_GENERIC; break; 8194 } 8195 } 8196 } 8197 } 8198 } 8199 8200 if (buttons == NULL || *buttons == NUL) 8201 buttons = (char_u *)_("&Ok"); 8202 8203 if (error) 8204 rettv->vval.v_number = 0; 8205 else 8206 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8207 def, NULL); 8208 #else 8209 rettv->vval.v_number = 0; 8210 #endif 8211 } 8212 8213 /* 8214 * "copy()" function 8215 */ 8216 static void 8217 f_copy(argvars, rettv) 8218 typval_T *argvars; 8219 typval_T *rettv; 8220 { 8221 item_copy(&argvars[0], rettv, FALSE, 0); 8222 } 8223 8224 /* 8225 * "count()" function 8226 */ 8227 static void 8228 f_count(argvars, rettv) 8229 typval_T *argvars; 8230 typval_T *rettv; 8231 { 8232 long n = 0; 8233 int ic = FALSE; 8234 8235 if (argvars[0].v_type == VAR_LIST) 8236 { 8237 listitem_T *li; 8238 list_T *l; 8239 long idx; 8240 8241 if ((l = argvars[0].vval.v_list) != NULL) 8242 { 8243 li = l->lv_first; 8244 if (argvars[2].v_type != VAR_UNKNOWN) 8245 { 8246 int error = FALSE; 8247 8248 ic = get_tv_number_chk(&argvars[2], &error); 8249 if (argvars[3].v_type != VAR_UNKNOWN) 8250 { 8251 idx = get_tv_number_chk(&argvars[3], &error); 8252 if (!error) 8253 { 8254 li = list_find(l, idx); 8255 if (li == NULL) 8256 EMSGN(_(e_listidx), idx); 8257 } 8258 } 8259 if (error) 8260 li = NULL; 8261 } 8262 8263 for ( ; li != NULL; li = li->li_next) 8264 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8265 ++n; 8266 } 8267 } 8268 else if (argvars[0].v_type == VAR_DICT) 8269 { 8270 int todo; 8271 dict_T *d; 8272 hashitem_T *hi; 8273 8274 if ((d = argvars[0].vval.v_dict) != NULL) 8275 { 8276 int error = FALSE; 8277 8278 if (argvars[2].v_type != VAR_UNKNOWN) 8279 { 8280 ic = get_tv_number_chk(&argvars[2], &error); 8281 if (argvars[3].v_type != VAR_UNKNOWN) 8282 EMSG(_(e_invarg)); 8283 } 8284 8285 todo = error ? 0 : d->dv_hashtab.ht_used; 8286 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8287 { 8288 if (!HASHITEM_EMPTY(hi)) 8289 { 8290 --todo; 8291 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8292 ++n; 8293 } 8294 } 8295 } 8296 } 8297 else 8298 EMSG2(_(e_listdictarg), "count()"); 8299 rettv->vval.v_number = n; 8300 } 8301 8302 /* 8303 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8304 * 8305 * Checks the existence of a cscope connection. 8306 */ 8307 /*ARGSUSED*/ 8308 static void 8309 f_cscope_connection(argvars, rettv) 8310 typval_T *argvars; 8311 typval_T *rettv; 8312 { 8313 #ifdef FEAT_CSCOPE 8314 int num = 0; 8315 char_u *dbpath = NULL; 8316 char_u *prepend = NULL; 8317 char_u buf[NUMBUFLEN]; 8318 8319 if (argvars[0].v_type != VAR_UNKNOWN 8320 && argvars[1].v_type != VAR_UNKNOWN) 8321 { 8322 num = (int)get_tv_number(&argvars[0]); 8323 dbpath = get_tv_string(&argvars[1]); 8324 if (argvars[2].v_type != VAR_UNKNOWN) 8325 prepend = get_tv_string_buf(&argvars[2], buf); 8326 } 8327 8328 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8329 #else 8330 rettv->vval.v_number = 0; 8331 #endif 8332 } 8333 8334 /* 8335 * "cursor(lnum, col)" function 8336 * 8337 * Moves the cursor to the specified line and column 8338 */ 8339 /*ARGSUSED*/ 8340 static void 8341 f_cursor(argvars, rettv) 8342 typval_T *argvars; 8343 typval_T *rettv; 8344 { 8345 long line, col; 8346 #ifdef FEAT_VIRTUALEDIT 8347 long coladd = 0; 8348 #endif 8349 8350 if (argvars[1].v_type == VAR_UNKNOWN) 8351 { 8352 pos_T pos; 8353 8354 if (list2fpos(argvars, &pos, NULL) == FAIL) 8355 return; 8356 line = pos.lnum; 8357 col = pos.col; 8358 #ifdef FEAT_VIRTUALEDIT 8359 coladd = pos.coladd; 8360 #endif 8361 } 8362 else 8363 { 8364 line = get_tv_lnum(argvars); 8365 col = get_tv_number_chk(&argvars[1], NULL); 8366 #ifdef FEAT_VIRTUALEDIT 8367 if (argvars[2].v_type != VAR_UNKNOWN) 8368 coladd = get_tv_number_chk(&argvars[2], NULL); 8369 #endif 8370 } 8371 if (line < 0 || col < 0 8372 #ifdef FEAT_VIRTUALEDIT 8373 || coladd < 0 8374 #endif 8375 ) 8376 return; /* type error; errmsg already given */ 8377 if (line > 0) 8378 curwin->w_cursor.lnum = line; 8379 if (col > 0) 8380 curwin->w_cursor.col = col - 1; 8381 #ifdef FEAT_VIRTUALEDIT 8382 curwin->w_cursor.coladd = coladd; 8383 #endif 8384 8385 /* Make sure the cursor is in a valid position. */ 8386 check_cursor(); 8387 #ifdef FEAT_MBYTE 8388 /* Correct cursor for multi-byte character. */ 8389 if (has_mbyte) 8390 mb_adjust_cursor(); 8391 #endif 8392 8393 curwin->w_set_curswant = TRUE; 8394 } 8395 8396 /* 8397 * "deepcopy()" function 8398 */ 8399 static void 8400 f_deepcopy(argvars, rettv) 8401 typval_T *argvars; 8402 typval_T *rettv; 8403 { 8404 int noref = 0; 8405 8406 if (argvars[1].v_type != VAR_UNKNOWN) 8407 noref = get_tv_number_chk(&argvars[1], NULL); 8408 if (noref < 0 || noref > 1) 8409 EMSG(_(e_invarg)); 8410 else 8411 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8412 } 8413 8414 /* 8415 * "delete()" function 8416 */ 8417 static void 8418 f_delete(argvars, rettv) 8419 typval_T *argvars; 8420 typval_T *rettv; 8421 { 8422 if (check_restricted() || check_secure()) 8423 rettv->vval.v_number = -1; 8424 else 8425 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8426 } 8427 8428 /* 8429 * "did_filetype()" function 8430 */ 8431 /*ARGSUSED*/ 8432 static void 8433 f_did_filetype(argvars, rettv) 8434 typval_T *argvars; 8435 typval_T *rettv; 8436 { 8437 #ifdef FEAT_AUTOCMD 8438 rettv->vval.v_number = did_filetype; 8439 #else 8440 rettv->vval.v_number = 0; 8441 #endif 8442 } 8443 8444 /* 8445 * "diff_filler()" function 8446 */ 8447 /*ARGSUSED*/ 8448 static void 8449 f_diff_filler(argvars, rettv) 8450 typval_T *argvars; 8451 typval_T *rettv; 8452 { 8453 #ifdef FEAT_DIFF 8454 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8455 #endif 8456 } 8457 8458 /* 8459 * "diff_hlID()" function 8460 */ 8461 /*ARGSUSED*/ 8462 static void 8463 f_diff_hlID(argvars, rettv) 8464 typval_T *argvars; 8465 typval_T *rettv; 8466 { 8467 #ifdef FEAT_DIFF 8468 linenr_T lnum = get_tv_lnum(argvars); 8469 static linenr_T prev_lnum = 0; 8470 static int changedtick = 0; 8471 static int fnum = 0; 8472 static int change_start = 0; 8473 static int change_end = 0; 8474 static hlf_T hlID = 0; 8475 int filler_lines; 8476 int col; 8477 8478 if (lnum < 0) /* ignore type error in {lnum} arg */ 8479 lnum = 0; 8480 if (lnum != prev_lnum 8481 || changedtick != curbuf->b_changedtick 8482 || fnum != curbuf->b_fnum) 8483 { 8484 /* New line, buffer, change: need to get the values. */ 8485 filler_lines = diff_check(curwin, lnum); 8486 if (filler_lines < 0) 8487 { 8488 if (filler_lines == -1) 8489 { 8490 change_start = MAXCOL; 8491 change_end = -1; 8492 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8493 hlID = HLF_ADD; /* added line */ 8494 else 8495 hlID = HLF_CHD; /* changed line */ 8496 } 8497 else 8498 hlID = HLF_ADD; /* added line */ 8499 } 8500 else 8501 hlID = (hlf_T)0; 8502 prev_lnum = lnum; 8503 changedtick = curbuf->b_changedtick; 8504 fnum = curbuf->b_fnum; 8505 } 8506 8507 if (hlID == HLF_CHD || hlID == HLF_TXD) 8508 { 8509 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8510 if (col >= change_start && col <= change_end) 8511 hlID = HLF_TXD; /* changed text */ 8512 else 8513 hlID = HLF_CHD; /* changed line */ 8514 } 8515 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 8516 #endif 8517 } 8518 8519 /* 8520 * "empty({expr})" function 8521 */ 8522 static void 8523 f_empty(argvars, rettv) 8524 typval_T *argvars; 8525 typval_T *rettv; 8526 { 8527 int n; 8528 8529 switch (argvars[0].v_type) 8530 { 8531 case VAR_STRING: 8532 case VAR_FUNC: 8533 n = argvars[0].vval.v_string == NULL 8534 || *argvars[0].vval.v_string == NUL; 8535 break; 8536 case VAR_NUMBER: 8537 n = argvars[0].vval.v_number == 0; 8538 break; 8539 case VAR_LIST: 8540 n = argvars[0].vval.v_list == NULL 8541 || argvars[0].vval.v_list->lv_first == NULL; 8542 break; 8543 case VAR_DICT: 8544 n = argvars[0].vval.v_dict == NULL 8545 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8546 break; 8547 default: 8548 EMSG2(_(e_intern2), "f_empty()"); 8549 n = 0; 8550 } 8551 8552 rettv->vval.v_number = n; 8553 } 8554 8555 /* 8556 * "escape({string}, {chars})" function 8557 */ 8558 static void 8559 f_escape(argvars, rettv) 8560 typval_T *argvars; 8561 typval_T *rettv; 8562 { 8563 char_u buf[NUMBUFLEN]; 8564 8565 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8566 get_tv_string_buf(&argvars[1], buf)); 8567 rettv->v_type = VAR_STRING; 8568 } 8569 8570 /* 8571 * "eval()" function 8572 */ 8573 /*ARGSUSED*/ 8574 static void 8575 f_eval(argvars, rettv) 8576 typval_T *argvars; 8577 typval_T *rettv; 8578 { 8579 char_u *s; 8580 8581 s = get_tv_string_chk(&argvars[0]); 8582 if (s != NULL) 8583 s = skipwhite(s); 8584 8585 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8586 { 8587 rettv->v_type = VAR_NUMBER; 8588 rettv->vval.v_number = 0; 8589 } 8590 else if (*s != NUL) 8591 EMSG(_(e_trailing)); 8592 } 8593 8594 /* 8595 * "eventhandler()" function 8596 */ 8597 /*ARGSUSED*/ 8598 static void 8599 f_eventhandler(argvars, rettv) 8600 typval_T *argvars; 8601 typval_T *rettv; 8602 { 8603 rettv->vval.v_number = vgetc_busy; 8604 } 8605 8606 /* 8607 * "executable()" function 8608 */ 8609 static void 8610 f_executable(argvars, rettv) 8611 typval_T *argvars; 8612 typval_T *rettv; 8613 { 8614 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8615 } 8616 8617 /* 8618 * "exists()" function 8619 */ 8620 static void 8621 f_exists(argvars, rettv) 8622 typval_T *argvars; 8623 typval_T *rettv; 8624 { 8625 char_u *p; 8626 char_u *name; 8627 int n = FALSE; 8628 int len = 0; 8629 8630 p = get_tv_string(&argvars[0]); 8631 if (*p == '$') /* environment variable */ 8632 { 8633 /* first try "normal" environment variables (fast) */ 8634 if (mch_getenv(p + 1) != NULL) 8635 n = TRUE; 8636 else 8637 { 8638 /* try expanding things like $VIM and ${HOME} */ 8639 p = expand_env_save(p); 8640 if (p != NULL && *p != '$') 8641 n = TRUE; 8642 vim_free(p); 8643 } 8644 } 8645 else if (*p == '&' || *p == '+') /* option */ 8646 n = (get_option_tv(&p, NULL, TRUE) == OK); 8647 else if (*p == '*') /* internal or user defined function */ 8648 { 8649 n = function_exists(p + 1); 8650 } 8651 else if (*p == ':') 8652 { 8653 n = cmd_exists(p + 1); 8654 } 8655 else if (*p == '#') 8656 { 8657 #ifdef FEAT_AUTOCMD 8658 if (p[1] == '#') 8659 n = autocmd_supported(p + 2); 8660 else 8661 n = au_exists(p + 1); 8662 #endif 8663 } 8664 else /* internal variable */ 8665 { 8666 char_u *tofree; 8667 typval_T tv; 8668 8669 /* get_name_len() takes care of expanding curly braces */ 8670 name = p; 8671 len = get_name_len(&p, &tofree, TRUE, FALSE); 8672 if (len > 0) 8673 { 8674 if (tofree != NULL) 8675 name = tofree; 8676 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8677 if (n) 8678 { 8679 /* handle d.key, l[idx], f(expr) */ 8680 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8681 if (n) 8682 clear_tv(&tv); 8683 } 8684 } 8685 8686 vim_free(tofree); 8687 } 8688 8689 rettv->vval.v_number = n; 8690 } 8691 8692 /* 8693 * "expand()" function 8694 */ 8695 static void 8696 f_expand(argvars, rettv) 8697 typval_T *argvars; 8698 typval_T *rettv; 8699 { 8700 char_u *s; 8701 int len; 8702 char_u *errormsg; 8703 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8704 expand_T xpc; 8705 int error = FALSE; 8706 8707 rettv->v_type = VAR_STRING; 8708 s = get_tv_string(&argvars[0]); 8709 if (*s == '%' || *s == '#' || *s == '<') 8710 { 8711 ++emsg_off; 8712 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8713 --emsg_off; 8714 } 8715 else 8716 { 8717 /* When the optional second argument is non-zero, don't remove matches 8718 * for 'suffixes' and 'wildignore' */ 8719 if (argvars[1].v_type != VAR_UNKNOWN 8720 && get_tv_number_chk(&argvars[1], &error)) 8721 flags |= WILD_KEEP_ALL; 8722 if (!error) 8723 { 8724 ExpandInit(&xpc); 8725 xpc.xp_context = EXPAND_FILES; 8726 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8727 ExpandCleanup(&xpc); 8728 } 8729 else 8730 rettv->vval.v_string = NULL; 8731 } 8732 } 8733 8734 /* 8735 * "extend(list, list [, idx])" function 8736 * "extend(dict, dict [, action])" function 8737 */ 8738 static void 8739 f_extend(argvars, rettv) 8740 typval_T *argvars; 8741 typval_T *rettv; 8742 { 8743 rettv->vval.v_number = 0; 8744 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8745 { 8746 list_T *l1, *l2; 8747 listitem_T *item; 8748 long before; 8749 int error = FALSE; 8750 8751 l1 = argvars[0].vval.v_list; 8752 l2 = argvars[1].vval.v_list; 8753 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8754 && l2 != NULL) 8755 { 8756 if (argvars[2].v_type != VAR_UNKNOWN) 8757 { 8758 before = get_tv_number_chk(&argvars[2], &error); 8759 if (error) 8760 return; /* type error; errmsg already given */ 8761 8762 if (before == l1->lv_len) 8763 item = NULL; 8764 else 8765 { 8766 item = list_find(l1, before); 8767 if (item == NULL) 8768 { 8769 EMSGN(_(e_listidx), before); 8770 return; 8771 } 8772 } 8773 } 8774 else 8775 item = NULL; 8776 list_extend(l1, l2, item); 8777 8778 copy_tv(&argvars[0], rettv); 8779 } 8780 } 8781 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8782 { 8783 dict_T *d1, *d2; 8784 dictitem_T *di1; 8785 char_u *action; 8786 int i; 8787 hashitem_T *hi2; 8788 int todo; 8789 8790 d1 = argvars[0].vval.v_dict; 8791 d2 = argvars[1].vval.v_dict; 8792 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8793 && d2 != NULL) 8794 { 8795 /* Check the third argument. */ 8796 if (argvars[2].v_type != VAR_UNKNOWN) 8797 { 8798 static char *(av[]) = {"keep", "force", "error"}; 8799 8800 action = get_tv_string_chk(&argvars[2]); 8801 if (action == NULL) 8802 return; /* type error; errmsg already given */ 8803 for (i = 0; i < 3; ++i) 8804 if (STRCMP(action, av[i]) == 0) 8805 break; 8806 if (i == 3) 8807 { 8808 EMSGN(_(e_invarg2), action); 8809 return; 8810 } 8811 } 8812 else 8813 action = (char_u *)"force"; 8814 8815 /* Go over all entries in the second dict and add them to the 8816 * first dict. */ 8817 todo = d2->dv_hashtab.ht_used; 8818 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8819 { 8820 if (!HASHITEM_EMPTY(hi2)) 8821 { 8822 --todo; 8823 di1 = dict_find(d1, hi2->hi_key, -1); 8824 if (di1 == NULL) 8825 { 8826 di1 = dictitem_copy(HI2DI(hi2)); 8827 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8828 dictitem_free(di1); 8829 } 8830 else if (*action == 'e') 8831 { 8832 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8833 break; 8834 } 8835 else if (*action == 'f') 8836 { 8837 clear_tv(&di1->di_tv); 8838 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8839 } 8840 } 8841 } 8842 8843 copy_tv(&argvars[0], rettv); 8844 } 8845 } 8846 else 8847 EMSG2(_(e_listdictarg), "extend()"); 8848 } 8849 8850 /* 8851 * "filereadable()" function 8852 */ 8853 static void 8854 f_filereadable(argvars, rettv) 8855 typval_T *argvars; 8856 typval_T *rettv; 8857 { 8858 FILE *fd; 8859 char_u *p; 8860 int n; 8861 8862 p = get_tv_string(&argvars[0]); 8863 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8864 { 8865 n = TRUE; 8866 fclose(fd); 8867 } 8868 else 8869 n = FALSE; 8870 8871 rettv->vval.v_number = n; 8872 } 8873 8874 /* 8875 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8876 * rights to write into. 8877 */ 8878 static void 8879 f_filewritable(argvars, rettv) 8880 typval_T *argvars; 8881 typval_T *rettv; 8882 { 8883 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8884 } 8885 8886 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8887 8888 static void 8889 findfilendir(argvars, rettv, dir) 8890 typval_T *argvars; 8891 typval_T *rettv; 8892 int dir; 8893 { 8894 #ifdef FEAT_SEARCHPATH 8895 char_u *fname; 8896 char_u *fresult = NULL; 8897 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8898 char_u *p; 8899 char_u pathbuf[NUMBUFLEN]; 8900 int count = 1; 8901 int first = TRUE; 8902 8903 fname = get_tv_string(&argvars[0]); 8904 8905 if (argvars[1].v_type != VAR_UNKNOWN) 8906 { 8907 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8908 if (p == NULL) 8909 count = -1; /* error */ 8910 else 8911 { 8912 if (*p != NUL) 8913 path = p; 8914 8915 if (argvars[2].v_type != VAR_UNKNOWN) 8916 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8917 } 8918 } 8919 8920 if (*fname != NUL && count >= 0) 8921 { 8922 do 8923 { 8924 vim_free(fresult); 8925 fresult = find_file_in_path_option(first ? fname : NULL, 8926 first ? (int)STRLEN(fname) : 0, 8927 0, first, path, dir, NULL); 8928 first = FALSE; 8929 } while (--count > 0 && fresult != NULL); 8930 } 8931 8932 rettv->vval.v_string = fresult; 8933 #else 8934 rettv->vval.v_string = NULL; 8935 #endif 8936 rettv->v_type = VAR_STRING; 8937 } 8938 8939 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8940 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8941 8942 /* 8943 * Implementation of map() and filter(). 8944 */ 8945 static void 8946 filter_map(argvars, rettv, map) 8947 typval_T *argvars; 8948 typval_T *rettv; 8949 int map; 8950 { 8951 char_u buf[NUMBUFLEN]; 8952 char_u *expr; 8953 listitem_T *li, *nli; 8954 list_T *l = NULL; 8955 dictitem_T *di; 8956 hashtab_T *ht; 8957 hashitem_T *hi; 8958 dict_T *d = NULL; 8959 typval_T save_val; 8960 typval_T save_key; 8961 int rem; 8962 int todo; 8963 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8964 int save_did_emsg; 8965 8966 rettv->vval.v_number = 0; 8967 if (argvars[0].v_type == VAR_LIST) 8968 { 8969 if ((l = argvars[0].vval.v_list) == NULL 8970 || (map && tv_check_lock(l->lv_lock, msg))) 8971 return; 8972 } 8973 else if (argvars[0].v_type == VAR_DICT) 8974 { 8975 if ((d = argvars[0].vval.v_dict) == NULL 8976 || (map && tv_check_lock(d->dv_lock, msg))) 8977 return; 8978 } 8979 else 8980 { 8981 EMSG2(_(e_listdictarg), msg); 8982 return; 8983 } 8984 8985 expr = get_tv_string_buf_chk(&argvars[1], buf); 8986 /* On type errors, the preceding call has already displayed an error 8987 * message. Avoid a misleading error message for an empty string that 8988 * was not passed as argument. */ 8989 if (expr != NULL) 8990 { 8991 prepare_vimvar(VV_VAL, &save_val); 8992 expr = skipwhite(expr); 8993 8994 /* We reset "did_emsg" to be able to detect whether an error 8995 * occurred during evaluation of the expression. */ 8996 save_did_emsg = did_emsg; 8997 did_emsg = FALSE; 8998 8999 if (argvars[0].v_type == VAR_DICT) 9000 { 9001 prepare_vimvar(VV_KEY, &save_key); 9002 vimvars[VV_KEY].vv_type = VAR_STRING; 9003 9004 ht = &d->dv_hashtab; 9005 hash_lock(ht); 9006 todo = ht->ht_used; 9007 for (hi = ht->ht_array; todo > 0; ++hi) 9008 { 9009 if (!HASHITEM_EMPTY(hi)) 9010 { 9011 --todo; 9012 di = HI2DI(hi); 9013 if (tv_check_lock(di->di_tv.v_lock, msg)) 9014 break; 9015 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 9016 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL 9017 || did_emsg) 9018 break; 9019 if (!map && rem) 9020 dictitem_remove(d, di); 9021 clear_tv(&vimvars[VV_KEY].vv_tv); 9022 } 9023 } 9024 hash_unlock(ht); 9025 9026 restore_vimvar(VV_KEY, &save_key); 9027 } 9028 else 9029 { 9030 for (li = l->lv_first; li != NULL; li = nli) 9031 { 9032 if (tv_check_lock(li->li_tv.v_lock, msg)) 9033 break; 9034 nli = li->li_next; 9035 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 9036 || did_emsg) 9037 break; 9038 if (!map && rem) 9039 listitem_remove(l, li); 9040 } 9041 } 9042 9043 restore_vimvar(VV_VAL, &save_val); 9044 9045 did_emsg |= save_did_emsg; 9046 } 9047 9048 copy_tv(&argvars[0], rettv); 9049 } 9050 9051 static int 9052 filter_map_one(tv, expr, map, remp) 9053 typval_T *tv; 9054 char_u *expr; 9055 int map; 9056 int *remp; 9057 { 9058 typval_T rettv; 9059 char_u *s; 9060 9061 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 9062 s = expr; 9063 if (eval1(&s, &rettv, TRUE) == FAIL) 9064 return FAIL; 9065 if (*s != NUL) /* check for trailing chars after expr */ 9066 { 9067 EMSG2(_(e_invexpr2), s); 9068 return FAIL; 9069 } 9070 if (map) 9071 { 9072 /* map(): replace the list item value */ 9073 clear_tv(tv); 9074 rettv.v_lock = 0; 9075 *tv = rettv; 9076 } 9077 else 9078 { 9079 int error = FALSE; 9080 9081 /* filter(): when expr is zero remove the item */ 9082 *remp = (get_tv_number_chk(&rettv, &error) == 0); 9083 clear_tv(&rettv); 9084 /* On type error, nothing has been removed; return FAIL to stop the 9085 * loop. The error message was given by get_tv_number_chk(). */ 9086 if (error) 9087 return FAIL; 9088 } 9089 clear_tv(&vimvars[VV_VAL].vv_tv); 9090 return OK; 9091 } 9092 9093 /* 9094 * "filter()" function 9095 */ 9096 static void 9097 f_filter(argvars, rettv) 9098 typval_T *argvars; 9099 typval_T *rettv; 9100 { 9101 filter_map(argvars, rettv, FALSE); 9102 } 9103 9104 /* 9105 * "finddir({fname}[, {path}[, {count}]])" function 9106 */ 9107 static void 9108 f_finddir(argvars, rettv) 9109 typval_T *argvars; 9110 typval_T *rettv; 9111 { 9112 findfilendir(argvars, rettv, TRUE); 9113 } 9114 9115 /* 9116 * "findfile({fname}[, {path}[, {count}]])" function 9117 */ 9118 static void 9119 f_findfile(argvars, rettv) 9120 typval_T *argvars; 9121 typval_T *rettv; 9122 { 9123 findfilendir(argvars, rettv, FALSE); 9124 } 9125 9126 /* 9127 * "fnamemodify({fname}, {mods})" function 9128 */ 9129 static void 9130 f_fnamemodify(argvars, rettv) 9131 typval_T *argvars; 9132 typval_T *rettv; 9133 { 9134 char_u *fname; 9135 char_u *mods; 9136 int usedlen = 0; 9137 int len; 9138 char_u *fbuf = NULL; 9139 char_u buf[NUMBUFLEN]; 9140 9141 fname = get_tv_string_chk(&argvars[0]); 9142 mods = get_tv_string_buf_chk(&argvars[1], buf); 9143 if (fname == NULL || mods == NULL) 9144 fname = NULL; 9145 else 9146 { 9147 len = (int)STRLEN(fname); 9148 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 9149 } 9150 9151 rettv->v_type = VAR_STRING; 9152 if (fname == NULL) 9153 rettv->vval.v_string = NULL; 9154 else 9155 rettv->vval.v_string = vim_strnsave(fname, len); 9156 vim_free(fbuf); 9157 } 9158 9159 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 9160 9161 /* 9162 * "foldclosed()" function 9163 */ 9164 static void 9165 foldclosed_both(argvars, rettv, end) 9166 typval_T *argvars; 9167 typval_T *rettv; 9168 int end; 9169 { 9170 #ifdef FEAT_FOLDING 9171 linenr_T lnum; 9172 linenr_T first, last; 9173 9174 lnum = get_tv_lnum(argvars); 9175 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9176 { 9177 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 9178 { 9179 if (end) 9180 rettv->vval.v_number = (varnumber_T)last; 9181 else 9182 rettv->vval.v_number = (varnumber_T)first; 9183 return; 9184 } 9185 } 9186 #endif 9187 rettv->vval.v_number = -1; 9188 } 9189 9190 /* 9191 * "foldclosed()" function 9192 */ 9193 static void 9194 f_foldclosed(argvars, rettv) 9195 typval_T *argvars; 9196 typval_T *rettv; 9197 { 9198 foldclosed_both(argvars, rettv, FALSE); 9199 } 9200 9201 /* 9202 * "foldclosedend()" function 9203 */ 9204 static void 9205 f_foldclosedend(argvars, rettv) 9206 typval_T *argvars; 9207 typval_T *rettv; 9208 { 9209 foldclosed_both(argvars, rettv, TRUE); 9210 } 9211 9212 /* 9213 * "foldlevel()" function 9214 */ 9215 static void 9216 f_foldlevel(argvars, rettv) 9217 typval_T *argvars; 9218 typval_T *rettv; 9219 { 9220 #ifdef FEAT_FOLDING 9221 linenr_T lnum; 9222 9223 lnum = get_tv_lnum(argvars); 9224 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9225 rettv->vval.v_number = foldLevel(lnum); 9226 else 9227 #endif 9228 rettv->vval.v_number = 0; 9229 } 9230 9231 /* 9232 * "foldtext()" function 9233 */ 9234 /*ARGSUSED*/ 9235 static void 9236 f_foldtext(argvars, rettv) 9237 typval_T *argvars; 9238 typval_T *rettv; 9239 { 9240 #ifdef FEAT_FOLDING 9241 linenr_T lnum; 9242 char_u *s; 9243 char_u *r; 9244 int len; 9245 char *txt; 9246 #endif 9247 9248 rettv->v_type = VAR_STRING; 9249 rettv->vval.v_string = NULL; 9250 #ifdef FEAT_FOLDING 9251 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9252 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9253 <= curbuf->b_ml.ml_line_count 9254 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9255 { 9256 /* Find first non-empty line in the fold. */ 9257 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9258 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9259 { 9260 if (!linewhite(lnum)) 9261 break; 9262 ++lnum; 9263 } 9264 9265 /* Find interesting text in this line. */ 9266 s = skipwhite(ml_get(lnum)); 9267 /* skip C comment-start */ 9268 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9269 { 9270 s = skipwhite(s + 2); 9271 if (*skipwhite(s) == NUL 9272 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9273 { 9274 s = skipwhite(ml_get(lnum + 1)); 9275 if (*s == '*') 9276 s = skipwhite(s + 1); 9277 } 9278 } 9279 txt = _("+-%s%3ld lines: "); 9280 r = alloc((unsigned)(STRLEN(txt) 9281 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9282 + 20 /* for %3ld */ 9283 + STRLEN(s))); /* concatenated */ 9284 if (r != NULL) 9285 { 9286 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9287 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9288 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9289 len = (int)STRLEN(r); 9290 STRCAT(r, s); 9291 /* remove 'foldmarker' and 'commentstring' */ 9292 foldtext_cleanup(r + len); 9293 rettv->vval.v_string = r; 9294 } 9295 } 9296 #endif 9297 } 9298 9299 /* 9300 * "foldtextresult(lnum)" function 9301 */ 9302 /*ARGSUSED*/ 9303 static void 9304 f_foldtextresult(argvars, rettv) 9305 typval_T *argvars; 9306 typval_T *rettv; 9307 { 9308 #ifdef FEAT_FOLDING 9309 linenr_T lnum; 9310 char_u *text; 9311 char_u buf[51]; 9312 foldinfo_T foldinfo; 9313 int fold_count; 9314 #endif 9315 9316 rettv->v_type = VAR_STRING; 9317 rettv->vval.v_string = NULL; 9318 #ifdef FEAT_FOLDING 9319 lnum = get_tv_lnum(argvars); 9320 /* treat illegal types and illegal string values for {lnum} the same */ 9321 if (lnum < 0) 9322 lnum = 0; 9323 fold_count = foldedCount(curwin, lnum, &foldinfo); 9324 if (fold_count > 0) 9325 { 9326 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9327 &foldinfo, buf); 9328 if (text == buf) 9329 text = vim_strsave(text); 9330 rettv->vval.v_string = text; 9331 } 9332 #endif 9333 } 9334 9335 /* 9336 * "foreground()" function 9337 */ 9338 /*ARGSUSED*/ 9339 static void 9340 f_foreground(argvars, rettv) 9341 typval_T *argvars; 9342 typval_T *rettv; 9343 { 9344 rettv->vval.v_number = 0; 9345 #ifdef FEAT_GUI 9346 if (gui.in_use) 9347 gui_mch_set_foreground(); 9348 #else 9349 # ifdef WIN32 9350 win32_set_foreground(); 9351 # endif 9352 #endif 9353 } 9354 9355 /* 9356 * "function()" function 9357 */ 9358 /*ARGSUSED*/ 9359 static void 9360 f_function(argvars, rettv) 9361 typval_T *argvars; 9362 typval_T *rettv; 9363 { 9364 char_u *s; 9365 9366 rettv->vval.v_number = 0; 9367 s = get_tv_string(&argvars[0]); 9368 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9369 EMSG2(_(e_invarg2), s); 9370 else if (!function_exists(s)) 9371 EMSG2(_("E700: Unknown function: %s"), s); 9372 else 9373 { 9374 rettv->vval.v_string = vim_strsave(s); 9375 rettv->v_type = VAR_FUNC; 9376 } 9377 } 9378 9379 /* 9380 * "garbagecollect()" function 9381 */ 9382 /*ARGSUSED*/ 9383 static void 9384 f_garbagecollect(argvars, rettv) 9385 typval_T *argvars; 9386 typval_T *rettv; 9387 { 9388 garbage_collect(); 9389 } 9390 9391 /* 9392 * "get()" function 9393 */ 9394 static void 9395 f_get(argvars, rettv) 9396 typval_T *argvars; 9397 typval_T *rettv; 9398 { 9399 listitem_T *li; 9400 list_T *l; 9401 dictitem_T *di; 9402 dict_T *d; 9403 typval_T *tv = NULL; 9404 9405 if (argvars[0].v_type == VAR_LIST) 9406 { 9407 if ((l = argvars[0].vval.v_list) != NULL) 9408 { 9409 int error = FALSE; 9410 9411 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9412 if (!error && li != NULL) 9413 tv = &li->li_tv; 9414 } 9415 } 9416 else if (argvars[0].v_type == VAR_DICT) 9417 { 9418 if ((d = argvars[0].vval.v_dict) != NULL) 9419 { 9420 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9421 if (di != NULL) 9422 tv = &di->di_tv; 9423 } 9424 } 9425 else 9426 EMSG2(_(e_listdictarg), "get()"); 9427 9428 if (tv == NULL) 9429 { 9430 if (argvars[2].v_type == VAR_UNKNOWN) 9431 rettv->vval.v_number = 0; 9432 else 9433 copy_tv(&argvars[2], rettv); 9434 } 9435 else 9436 copy_tv(tv, rettv); 9437 } 9438 9439 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9440 9441 /* 9442 * Get line or list of lines from buffer "buf" into "rettv". 9443 * Return a range (from start to end) of lines in rettv from the specified 9444 * buffer. 9445 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9446 */ 9447 static void 9448 get_buffer_lines(buf, start, end, retlist, rettv) 9449 buf_T *buf; 9450 linenr_T start; 9451 linenr_T end; 9452 int retlist; 9453 typval_T *rettv; 9454 { 9455 char_u *p; 9456 9457 if (retlist) 9458 { 9459 if (rettv_list_alloc(rettv) == FAIL) 9460 return; 9461 } 9462 else 9463 rettv->vval.v_number = 0; 9464 9465 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9466 return; 9467 9468 if (!retlist) 9469 { 9470 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9471 p = ml_get_buf(buf, start, FALSE); 9472 else 9473 p = (char_u *)""; 9474 9475 rettv->v_type = VAR_STRING; 9476 rettv->vval.v_string = vim_strsave(p); 9477 } 9478 else 9479 { 9480 if (end < start) 9481 return; 9482 9483 if (start < 1) 9484 start = 1; 9485 if (end > buf->b_ml.ml_line_count) 9486 end = buf->b_ml.ml_line_count; 9487 while (start <= end) 9488 if (list_append_string(rettv->vval.v_list, 9489 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 9490 break; 9491 } 9492 } 9493 9494 /* 9495 * "getbufline()" function 9496 */ 9497 static void 9498 f_getbufline(argvars, rettv) 9499 typval_T *argvars; 9500 typval_T *rettv; 9501 { 9502 linenr_T lnum; 9503 linenr_T end; 9504 buf_T *buf; 9505 9506 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9507 ++emsg_off; 9508 buf = get_buf_tv(&argvars[0]); 9509 --emsg_off; 9510 9511 lnum = get_tv_lnum_buf(&argvars[1], buf); 9512 if (argvars[2].v_type == VAR_UNKNOWN) 9513 end = lnum; 9514 else 9515 end = get_tv_lnum_buf(&argvars[2], buf); 9516 9517 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9518 } 9519 9520 /* 9521 * "getbufvar()" function 9522 */ 9523 static void 9524 f_getbufvar(argvars, rettv) 9525 typval_T *argvars; 9526 typval_T *rettv; 9527 { 9528 buf_T *buf; 9529 buf_T *save_curbuf; 9530 char_u *varname; 9531 dictitem_T *v; 9532 9533 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9534 varname = get_tv_string_chk(&argvars[1]); 9535 ++emsg_off; 9536 buf = get_buf_tv(&argvars[0]); 9537 9538 rettv->v_type = VAR_STRING; 9539 rettv->vval.v_string = NULL; 9540 9541 if (buf != NULL && varname != NULL) 9542 { 9543 if (*varname == '&') /* buffer-local-option */ 9544 { 9545 /* set curbuf to be our buf, temporarily */ 9546 save_curbuf = curbuf; 9547 curbuf = buf; 9548 9549 get_option_tv(&varname, rettv, TRUE); 9550 9551 /* restore previous notion of curbuf */ 9552 curbuf = save_curbuf; 9553 } 9554 else 9555 { 9556 if (*varname == NUL) 9557 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9558 * scope prefix before the NUL byte is required by 9559 * find_var_in_ht(). */ 9560 varname = (char_u *)"b:" + 2; 9561 /* look up the variable */ 9562 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9563 if (v != NULL) 9564 copy_tv(&v->di_tv, rettv); 9565 } 9566 } 9567 9568 --emsg_off; 9569 } 9570 9571 /* 9572 * "getchar()" function 9573 */ 9574 static void 9575 f_getchar(argvars, rettv) 9576 typval_T *argvars; 9577 typval_T *rettv; 9578 { 9579 varnumber_T n; 9580 int error = FALSE; 9581 9582 ++no_mapping; 9583 ++allow_keys; 9584 if (argvars[0].v_type == VAR_UNKNOWN) 9585 /* getchar(): blocking wait. */ 9586 n = safe_vgetc(); 9587 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9588 /* getchar(1): only check if char avail */ 9589 n = vpeekc(); 9590 else if (error || vpeekc() == NUL) 9591 /* illegal argument or getchar(0) and no char avail: return zero */ 9592 n = 0; 9593 else 9594 /* getchar(0) and char avail: return char */ 9595 n = safe_vgetc(); 9596 --no_mapping; 9597 --allow_keys; 9598 9599 rettv->vval.v_number = n; 9600 if (IS_SPECIAL(n) || mod_mask != 0) 9601 { 9602 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9603 int i = 0; 9604 9605 /* Turn a special key into three bytes, plus modifier. */ 9606 if (mod_mask != 0) 9607 { 9608 temp[i++] = K_SPECIAL; 9609 temp[i++] = KS_MODIFIER; 9610 temp[i++] = mod_mask; 9611 } 9612 if (IS_SPECIAL(n)) 9613 { 9614 temp[i++] = K_SPECIAL; 9615 temp[i++] = K_SECOND(n); 9616 temp[i++] = K_THIRD(n); 9617 } 9618 #ifdef FEAT_MBYTE 9619 else if (has_mbyte) 9620 i += (*mb_char2bytes)(n, temp + i); 9621 #endif 9622 else 9623 temp[i++] = n; 9624 temp[i++] = NUL; 9625 rettv->v_type = VAR_STRING; 9626 rettv->vval.v_string = vim_strsave(temp); 9627 } 9628 } 9629 9630 /* 9631 * "getcharmod()" function 9632 */ 9633 /*ARGSUSED*/ 9634 static void 9635 f_getcharmod(argvars, rettv) 9636 typval_T *argvars; 9637 typval_T *rettv; 9638 { 9639 rettv->vval.v_number = mod_mask; 9640 } 9641 9642 /* 9643 * "getcmdline()" function 9644 */ 9645 /*ARGSUSED*/ 9646 static void 9647 f_getcmdline(argvars, rettv) 9648 typval_T *argvars; 9649 typval_T *rettv; 9650 { 9651 rettv->v_type = VAR_STRING; 9652 rettv->vval.v_string = get_cmdline_str(); 9653 } 9654 9655 /* 9656 * "getcmdpos()" function 9657 */ 9658 /*ARGSUSED*/ 9659 static void 9660 f_getcmdpos(argvars, rettv) 9661 typval_T *argvars; 9662 typval_T *rettv; 9663 { 9664 rettv->vval.v_number = get_cmdline_pos() + 1; 9665 } 9666 9667 /* 9668 * "getcmdtype()" function 9669 */ 9670 /*ARGSUSED*/ 9671 static void 9672 f_getcmdtype(argvars, rettv) 9673 typval_T *argvars; 9674 typval_T *rettv; 9675 { 9676 rettv->v_type = VAR_STRING; 9677 rettv->vval.v_string = alloc(2); 9678 if (rettv->vval.v_string != NULL) 9679 { 9680 rettv->vval.v_string[0] = get_cmdline_type(); 9681 rettv->vval.v_string[1] = NUL; 9682 } 9683 } 9684 9685 /* 9686 * "getcwd()" function 9687 */ 9688 /*ARGSUSED*/ 9689 static void 9690 f_getcwd(argvars, rettv) 9691 typval_T *argvars; 9692 typval_T *rettv; 9693 { 9694 char_u cwd[MAXPATHL]; 9695 9696 rettv->v_type = VAR_STRING; 9697 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9698 rettv->vval.v_string = NULL; 9699 else 9700 { 9701 rettv->vval.v_string = vim_strsave(cwd); 9702 #ifdef BACKSLASH_IN_FILENAME 9703 if (rettv->vval.v_string != NULL) 9704 slash_adjust(rettv->vval.v_string); 9705 #endif 9706 } 9707 } 9708 9709 /* 9710 * "getfontname()" function 9711 */ 9712 /*ARGSUSED*/ 9713 static void 9714 f_getfontname(argvars, rettv) 9715 typval_T *argvars; 9716 typval_T *rettv; 9717 { 9718 rettv->v_type = VAR_STRING; 9719 rettv->vval.v_string = NULL; 9720 #ifdef FEAT_GUI 9721 if (gui.in_use) 9722 { 9723 GuiFont font; 9724 char_u *name = NULL; 9725 9726 if (argvars[0].v_type == VAR_UNKNOWN) 9727 { 9728 /* Get the "Normal" font. Either the name saved by 9729 * hl_set_font_name() or from the font ID. */ 9730 font = gui.norm_font; 9731 name = hl_get_font_name(); 9732 } 9733 else 9734 { 9735 name = get_tv_string(&argvars[0]); 9736 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9737 return; 9738 font = gui_mch_get_font(name, FALSE); 9739 if (font == NOFONT) 9740 return; /* Invalid font name, return empty string. */ 9741 } 9742 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9743 if (argvars[0].v_type != VAR_UNKNOWN) 9744 gui_mch_free_font(font); 9745 } 9746 #endif 9747 } 9748 9749 /* 9750 * "getfperm({fname})" function 9751 */ 9752 static void 9753 f_getfperm(argvars, rettv) 9754 typval_T *argvars; 9755 typval_T *rettv; 9756 { 9757 char_u *fname; 9758 struct stat st; 9759 char_u *perm = NULL; 9760 char_u flags[] = "rwx"; 9761 int i; 9762 9763 fname = get_tv_string(&argvars[0]); 9764 9765 rettv->v_type = VAR_STRING; 9766 if (mch_stat((char *)fname, &st) >= 0) 9767 { 9768 perm = vim_strsave((char_u *)"---------"); 9769 if (perm != NULL) 9770 { 9771 for (i = 0; i < 9; i++) 9772 { 9773 if (st.st_mode & (1 << (8 - i))) 9774 perm[i] = flags[i % 3]; 9775 } 9776 } 9777 } 9778 rettv->vval.v_string = perm; 9779 } 9780 9781 /* 9782 * "getfsize({fname})" function 9783 */ 9784 static void 9785 f_getfsize(argvars, rettv) 9786 typval_T *argvars; 9787 typval_T *rettv; 9788 { 9789 char_u *fname; 9790 struct stat st; 9791 9792 fname = get_tv_string(&argvars[0]); 9793 9794 rettv->v_type = VAR_NUMBER; 9795 9796 if (mch_stat((char *)fname, &st) >= 0) 9797 { 9798 if (mch_isdir(fname)) 9799 rettv->vval.v_number = 0; 9800 else 9801 rettv->vval.v_number = (varnumber_T)st.st_size; 9802 } 9803 else 9804 rettv->vval.v_number = -1; 9805 } 9806 9807 /* 9808 * "getftime({fname})" function 9809 */ 9810 static void 9811 f_getftime(argvars, rettv) 9812 typval_T *argvars; 9813 typval_T *rettv; 9814 { 9815 char_u *fname; 9816 struct stat st; 9817 9818 fname = get_tv_string(&argvars[0]); 9819 9820 if (mch_stat((char *)fname, &st) >= 0) 9821 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9822 else 9823 rettv->vval.v_number = -1; 9824 } 9825 9826 /* 9827 * "getftype({fname})" function 9828 */ 9829 static void 9830 f_getftype(argvars, rettv) 9831 typval_T *argvars; 9832 typval_T *rettv; 9833 { 9834 char_u *fname; 9835 struct stat st; 9836 char_u *type = NULL; 9837 char *t; 9838 9839 fname = get_tv_string(&argvars[0]); 9840 9841 rettv->v_type = VAR_STRING; 9842 if (mch_lstat((char *)fname, &st) >= 0) 9843 { 9844 #ifdef S_ISREG 9845 if (S_ISREG(st.st_mode)) 9846 t = "file"; 9847 else if (S_ISDIR(st.st_mode)) 9848 t = "dir"; 9849 # ifdef S_ISLNK 9850 else if (S_ISLNK(st.st_mode)) 9851 t = "link"; 9852 # endif 9853 # ifdef S_ISBLK 9854 else if (S_ISBLK(st.st_mode)) 9855 t = "bdev"; 9856 # endif 9857 # ifdef S_ISCHR 9858 else if (S_ISCHR(st.st_mode)) 9859 t = "cdev"; 9860 # endif 9861 # ifdef S_ISFIFO 9862 else if (S_ISFIFO(st.st_mode)) 9863 t = "fifo"; 9864 # endif 9865 # ifdef S_ISSOCK 9866 else if (S_ISSOCK(st.st_mode)) 9867 t = "fifo"; 9868 # endif 9869 else 9870 t = "other"; 9871 #else 9872 # ifdef S_IFMT 9873 switch (st.st_mode & S_IFMT) 9874 { 9875 case S_IFREG: t = "file"; break; 9876 case S_IFDIR: t = "dir"; break; 9877 # ifdef S_IFLNK 9878 case S_IFLNK: t = "link"; break; 9879 # endif 9880 # ifdef S_IFBLK 9881 case S_IFBLK: t = "bdev"; break; 9882 # endif 9883 # ifdef S_IFCHR 9884 case S_IFCHR: t = "cdev"; break; 9885 # endif 9886 # ifdef S_IFIFO 9887 case S_IFIFO: t = "fifo"; break; 9888 # endif 9889 # ifdef S_IFSOCK 9890 case S_IFSOCK: t = "socket"; break; 9891 # endif 9892 default: t = "other"; 9893 } 9894 # else 9895 if (mch_isdir(fname)) 9896 t = "dir"; 9897 else 9898 t = "file"; 9899 # endif 9900 #endif 9901 type = vim_strsave((char_u *)t); 9902 } 9903 rettv->vval.v_string = type; 9904 } 9905 9906 /* 9907 * "getline(lnum, [end])" function 9908 */ 9909 static void 9910 f_getline(argvars, rettv) 9911 typval_T *argvars; 9912 typval_T *rettv; 9913 { 9914 linenr_T lnum; 9915 linenr_T end; 9916 int retlist; 9917 9918 lnum = get_tv_lnum(argvars); 9919 if (argvars[1].v_type == VAR_UNKNOWN) 9920 { 9921 end = 0; 9922 retlist = FALSE; 9923 } 9924 else 9925 { 9926 end = get_tv_lnum(&argvars[1]); 9927 retlist = TRUE; 9928 } 9929 9930 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9931 } 9932 9933 /* 9934 * "getpos(string)" function 9935 */ 9936 static void 9937 f_getpos(argvars, rettv) 9938 typval_T *argvars; 9939 typval_T *rettv; 9940 { 9941 pos_T *fp; 9942 list_T *l; 9943 int fnum = -1; 9944 9945 if (rettv_list_alloc(rettv) == OK) 9946 { 9947 l = rettv->vval.v_list; 9948 fp = var2fpos(&argvars[0], TRUE, &fnum); 9949 if (fnum != -1) 9950 list_append_number(l, (varnumber_T)fnum); 9951 else 9952 list_append_number(l, (varnumber_T)0); 9953 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 9954 : (varnumber_T)0); 9955 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->col + 1 9956 : (varnumber_T)0); 9957 list_append_number(l, 9958 #ifdef FEAT_VIRTUALEDIT 9959 (fp != NULL) ? (varnumber_T)fp->coladd : 9960 #endif 9961 (varnumber_T)0); 9962 } 9963 else 9964 rettv->vval.v_number = FALSE; 9965 } 9966 9967 /* 9968 * "getqflist()" and "getloclist()" functions 9969 */ 9970 /*ARGSUSED*/ 9971 static void 9972 f_getqflist(argvars, rettv) 9973 typval_T *argvars; 9974 typval_T *rettv; 9975 { 9976 #ifdef FEAT_QUICKFIX 9977 win_T *wp; 9978 #endif 9979 9980 rettv->vval.v_number = FALSE; 9981 #ifdef FEAT_QUICKFIX 9982 if (rettv_list_alloc(rettv) == OK) 9983 { 9984 wp = NULL; 9985 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 9986 { 9987 wp = find_win_by_nr(&argvars[0]); 9988 if (wp == NULL) 9989 return; 9990 } 9991 9992 (void)get_errorlist(wp, rettv->vval.v_list); 9993 } 9994 #endif 9995 } 9996 9997 /* 9998 * "getreg()" function 9999 */ 10000 static void 10001 f_getreg(argvars, rettv) 10002 typval_T *argvars; 10003 typval_T *rettv; 10004 { 10005 char_u *strregname; 10006 int regname; 10007 int arg2 = FALSE; 10008 int error = FALSE; 10009 10010 if (argvars[0].v_type != VAR_UNKNOWN) 10011 { 10012 strregname = get_tv_string_chk(&argvars[0]); 10013 error = strregname == NULL; 10014 if (argvars[1].v_type != VAR_UNKNOWN) 10015 arg2 = get_tv_number_chk(&argvars[1], &error); 10016 } 10017 else 10018 strregname = vimvars[VV_REG].vv_str; 10019 regname = (strregname == NULL ? '"' : *strregname); 10020 if (regname == 0) 10021 regname = '"'; 10022 10023 rettv->v_type = VAR_STRING; 10024 rettv->vval.v_string = error ? NULL : 10025 get_reg_contents(regname, TRUE, arg2); 10026 } 10027 10028 /* 10029 * "getregtype()" function 10030 */ 10031 static void 10032 f_getregtype(argvars, rettv) 10033 typval_T *argvars; 10034 typval_T *rettv; 10035 { 10036 char_u *strregname; 10037 int regname; 10038 char_u buf[NUMBUFLEN + 2]; 10039 long reglen = 0; 10040 10041 if (argvars[0].v_type != VAR_UNKNOWN) 10042 { 10043 strregname = get_tv_string_chk(&argvars[0]); 10044 if (strregname == NULL) /* type error; errmsg already given */ 10045 { 10046 rettv->v_type = VAR_STRING; 10047 rettv->vval.v_string = NULL; 10048 return; 10049 } 10050 } 10051 else 10052 /* Default to v:register */ 10053 strregname = vimvars[VV_REG].vv_str; 10054 10055 regname = (strregname == NULL ? '"' : *strregname); 10056 if (regname == 0) 10057 regname = '"'; 10058 10059 buf[0] = NUL; 10060 buf[1] = NUL; 10061 switch (get_reg_type(regname, ®len)) 10062 { 10063 case MLINE: buf[0] = 'V'; break; 10064 case MCHAR: buf[0] = 'v'; break; 10065 #ifdef FEAT_VISUAL 10066 case MBLOCK: 10067 buf[0] = Ctrl_V; 10068 sprintf((char *)buf + 1, "%ld", reglen + 1); 10069 break; 10070 #endif 10071 } 10072 rettv->v_type = VAR_STRING; 10073 rettv->vval.v_string = vim_strsave(buf); 10074 } 10075 10076 /* 10077 * "getwinposx()" function 10078 */ 10079 /*ARGSUSED*/ 10080 static void 10081 f_getwinposx(argvars, rettv) 10082 typval_T *argvars; 10083 typval_T *rettv; 10084 { 10085 rettv->vval.v_number = -1; 10086 #ifdef FEAT_GUI 10087 if (gui.in_use) 10088 { 10089 int x, y; 10090 10091 if (gui_mch_get_winpos(&x, &y) == OK) 10092 rettv->vval.v_number = x; 10093 } 10094 #endif 10095 } 10096 10097 /* 10098 * "getwinposy()" function 10099 */ 10100 /*ARGSUSED*/ 10101 static void 10102 f_getwinposy(argvars, rettv) 10103 typval_T *argvars; 10104 typval_T *rettv; 10105 { 10106 rettv->vval.v_number = -1; 10107 #ifdef FEAT_GUI 10108 if (gui.in_use) 10109 { 10110 int x, y; 10111 10112 if (gui_mch_get_winpos(&x, &y) == OK) 10113 rettv->vval.v_number = y; 10114 } 10115 #endif 10116 } 10117 10118 static win_T * 10119 find_win_by_nr(vp) 10120 typval_T *vp; 10121 { 10122 #ifdef FEAT_WINDOWS 10123 win_T *wp; 10124 #endif 10125 int nr; 10126 10127 nr = get_tv_number_chk(vp, NULL); 10128 10129 #ifdef FEAT_WINDOWS 10130 if (nr < 0) 10131 return NULL; 10132 if (nr == 0) 10133 return curwin; 10134 10135 for (wp = firstwin; wp != NULL; wp = wp->w_next) 10136 if (--nr <= 0) 10137 break; 10138 return wp; 10139 #else 10140 if (nr == 0 || nr == 1) 10141 return curwin; 10142 return NULL; 10143 #endif 10144 } 10145 10146 /* 10147 * "getwinvar()" function 10148 */ 10149 static void 10150 f_getwinvar(argvars, rettv) 10151 typval_T *argvars; 10152 typval_T *rettv; 10153 { 10154 win_T *win, *oldcurwin; 10155 char_u *varname; 10156 dictitem_T *v; 10157 10158 win = find_win_by_nr(&argvars[0]); 10159 varname = get_tv_string_chk(&argvars[1]); 10160 ++emsg_off; 10161 10162 rettv->v_type = VAR_STRING; 10163 rettv->vval.v_string = NULL; 10164 10165 if (win != NULL && varname != NULL) 10166 { 10167 if (*varname == '&') /* window-local-option */ 10168 { 10169 /* Set curwin to be our win, temporarily. Also set curbuf, so 10170 * that we can get buffer-local options. */ 10171 oldcurwin = curwin; 10172 curwin = win; 10173 curbuf = win->w_buffer; 10174 10175 get_option_tv(&varname, rettv, 1); 10176 10177 /* restore previous notion of curwin */ 10178 curwin = oldcurwin; 10179 curbuf = curwin->w_buffer; 10180 } 10181 else 10182 { 10183 if (*varname == NUL) 10184 /* let getwinvar({nr}, "") return the "w:" dictionary. The 10185 * scope prefix before the NUL byte is required by 10186 * find_var_in_ht(). */ 10187 varname = (char_u *)"w:" + 2; 10188 /* look up the variable */ 10189 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 10190 if (v != NULL) 10191 copy_tv(&v->di_tv, rettv); 10192 } 10193 } 10194 10195 --emsg_off; 10196 } 10197 10198 /* 10199 * "glob()" function 10200 */ 10201 static void 10202 f_glob(argvars, rettv) 10203 typval_T *argvars; 10204 typval_T *rettv; 10205 { 10206 expand_T xpc; 10207 10208 ExpandInit(&xpc); 10209 xpc.xp_context = EXPAND_FILES; 10210 rettv->v_type = VAR_STRING; 10211 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 10212 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 10213 ExpandCleanup(&xpc); 10214 } 10215 10216 /* 10217 * "globpath()" function 10218 */ 10219 static void 10220 f_globpath(argvars, rettv) 10221 typval_T *argvars; 10222 typval_T *rettv; 10223 { 10224 char_u buf1[NUMBUFLEN]; 10225 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 10226 10227 rettv->v_type = VAR_STRING; 10228 if (file == NULL) 10229 rettv->vval.v_string = NULL; 10230 else 10231 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 10232 } 10233 10234 /* 10235 * "has()" function 10236 */ 10237 static void 10238 f_has(argvars, rettv) 10239 typval_T *argvars; 10240 typval_T *rettv; 10241 { 10242 int i; 10243 char_u *name; 10244 int n = FALSE; 10245 static char *(has_list[]) = 10246 { 10247 #ifdef AMIGA 10248 "amiga", 10249 # ifdef FEAT_ARP 10250 "arp", 10251 # endif 10252 #endif 10253 #ifdef __BEOS__ 10254 "beos", 10255 #endif 10256 #ifdef MSDOS 10257 # ifdef DJGPP 10258 "dos32", 10259 # else 10260 "dos16", 10261 # endif 10262 #endif 10263 #ifdef MACOS 10264 "mac", 10265 #endif 10266 #if defined(MACOS_X_UNIX) 10267 "macunix", 10268 #endif 10269 #ifdef OS2 10270 "os2", 10271 #endif 10272 #ifdef __QNX__ 10273 "qnx", 10274 #endif 10275 #ifdef RISCOS 10276 "riscos", 10277 #endif 10278 #ifdef UNIX 10279 "unix", 10280 #endif 10281 #ifdef VMS 10282 "vms", 10283 #endif 10284 #ifdef WIN16 10285 "win16", 10286 #endif 10287 #ifdef WIN32 10288 "win32", 10289 #endif 10290 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10291 "win32unix", 10292 #endif 10293 #ifdef WIN64 10294 "win64", 10295 #endif 10296 #ifdef EBCDIC 10297 "ebcdic", 10298 #endif 10299 #ifndef CASE_INSENSITIVE_FILENAME 10300 "fname_case", 10301 #endif 10302 #ifdef FEAT_ARABIC 10303 "arabic", 10304 #endif 10305 #ifdef FEAT_AUTOCMD 10306 "autocmd", 10307 #endif 10308 #ifdef FEAT_BEVAL 10309 "balloon_eval", 10310 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10311 "balloon_multiline", 10312 # endif 10313 #endif 10314 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10315 "builtin_terms", 10316 # ifdef ALL_BUILTIN_TCAPS 10317 "all_builtin_terms", 10318 # endif 10319 #endif 10320 #ifdef FEAT_BYTEOFF 10321 "byte_offset", 10322 #endif 10323 #ifdef FEAT_CINDENT 10324 "cindent", 10325 #endif 10326 #ifdef FEAT_CLIENTSERVER 10327 "clientserver", 10328 #endif 10329 #ifdef FEAT_CLIPBOARD 10330 "clipboard", 10331 #endif 10332 #ifdef FEAT_CMDL_COMPL 10333 "cmdline_compl", 10334 #endif 10335 #ifdef FEAT_CMDHIST 10336 "cmdline_hist", 10337 #endif 10338 #ifdef FEAT_COMMENTS 10339 "comments", 10340 #endif 10341 #ifdef FEAT_CRYPT 10342 "cryptv", 10343 #endif 10344 #ifdef FEAT_CSCOPE 10345 "cscope", 10346 #endif 10347 #ifdef CURSOR_SHAPE 10348 "cursorshape", 10349 #endif 10350 #ifdef DEBUG 10351 "debug", 10352 #endif 10353 #ifdef FEAT_CON_DIALOG 10354 "dialog_con", 10355 #endif 10356 #ifdef FEAT_GUI_DIALOG 10357 "dialog_gui", 10358 #endif 10359 #ifdef FEAT_DIFF 10360 "diff", 10361 #endif 10362 #ifdef FEAT_DIGRAPHS 10363 "digraphs", 10364 #endif 10365 #ifdef FEAT_DND 10366 "dnd", 10367 #endif 10368 #ifdef FEAT_EMACS_TAGS 10369 "emacs_tags", 10370 #endif 10371 "eval", /* always present, of course! */ 10372 #ifdef FEAT_EX_EXTRA 10373 "ex_extra", 10374 #endif 10375 #ifdef FEAT_SEARCH_EXTRA 10376 "extra_search", 10377 #endif 10378 #ifdef FEAT_FKMAP 10379 "farsi", 10380 #endif 10381 #ifdef FEAT_SEARCHPATH 10382 "file_in_path", 10383 #endif 10384 #if defined(UNIX) && !defined(USE_SYSTEM) 10385 "filterpipe", 10386 #endif 10387 #ifdef FEAT_FIND_ID 10388 "find_in_path", 10389 #endif 10390 #ifdef FEAT_FOLDING 10391 "folding", 10392 #endif 10393 #ifdef FEAT_FOOTER 10394 "footer", 10395 #endif 10396 #if !defined(USE_SYSTEM) && defined(UNIX) 10397 "fork", 10398 #endif 10399 #ifdef FEAT_GETTEXT 10400 "gettext", 10401 #endif 10402 #ifdef FEAT_GUI 10403 "gui", 10404 #endif 10405 #ifdef FEAT_GUI_ATHENA 10406 # ifdef FEAT_GUI_NEXTAW 10407 "gui_neXtaw", 10408 # else 10409 "gui_athena", 10410 # endif 10411 #endif 10412 #ifdef FEAT_GUI_GTK 10413 "gui_gtk", 10414 # ifdef HAVE_GTK2 10415 "gui_gtk2", 10416 # endif 10417 #endif 10418 #ifdef FEAT_GUI_MAC 10419 "gui_mac", 10420 #endif 10421 #ifdef FEAT_GUI_MOTIF 10422 "gui_motif", 10423 #endif 10424 #ifdef FEAT_GUI_PHOTON 10425 "gui_photon", 10426 #endif 10427 #ifdef FEAT_GUI_W16 10428 "gui_win16", 10429 #endif 10430 #ifdef FEAT_GUI_W32 10431 "gui_win32", 10432 #endif 10433 #ifdef FEAT_HANGULIN 10434 "hangul_input", 10435 #endif 10436 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10437 "iconv", 10438 #endif 10439 #ifdef FEAT_INS_EXPAND 10440 "insert_expand", 10441 #endif 10442 #ifdef FEAT_JUMPLIST 10443 "jumplist", 10444 #endif 10445 #ifdef FEAT_KEYMAP 10446 "keymap", 10447 #endif 10448 #ifdef FEAT_LANGMAP 10449 "langmap", 10450 #endif 10451 #ifdef FEAT_LIBCALL 10452 "libcall", 10453 #endif 10454 #ifdef FEAT_LINEBREAK 10455 "linebreak", 10456 #endif 10457 #ifdef FEAT_LISP 10458 "lispindent", 10459 #endif 10460 #ifdef FEAT_LISTCMDS 10461 "listcmds", 10462 #endif 10463 #ifdef FEAT_LOCALMAP 10464 "localmap", 10465 #endif 10466 #ifdef FEAT_MENU 10467 "menu", 10468 #endif 10469 #ifdef FEAT_SESSION 10470 "mksession", 10471 #endif 10472 #ifdef FEAT_MODIFY_FNAME 10473 "modify_fname", 10474 #endif 10475 #ifdef FEAT_MOUSE 10476 "mouse", 10477 #endif 10478 #ifdef FEAT_MOUSESHAPE 10479 "mouseshape", 10480 #endif 10481 #if defined(UNIX) || defined(VMS) 10482 # ifdef FEAT_MOUSE_DEC 10483 "mouse_dec", 10484 # endif 10485 # ifdef FEAT_MOUSE_GPM 10486 "mouse_gpm", 10487 # endif 10488 # ifdef FEAT_MOUSE_JSB 10489 "mouse_jsbterm", 10490 # endif 10491 # ifdef FEAT_MOUSE_NET 10492 "mouse_netterm", 10493 # endif 10494 # ifdef FEAT_MOUSE_PTERM 10495 "mouse_pterm", 10496 # endif 10497 # ifdef FEAT_MOUSE_XTERM 10498 "mouse_xterm", 10499 # endif 10500 #endif 10501 #ifdef FEAT_MBYTE 10502 "multi_byte", 10503 #endif 10504 #ifdef FEAT_MBYTE_IME 10505 "multi_byte_ime", 10506 #endif 10507 #ifdef FEAT_MULTI_LANG 10508 "multi_lang", 10509 #endif 10510 #ifdef FEAT_MZSCHEME 10511 #ifndef DYNAMIC_MZSCHEME 10512 "mzscheme", 10513 #endif 10514 #endif 10515 #ifdef FEAT_OLE 10516 "ole", 10517 #endif 10518 #ifdef FEAT_OSFILETYPE 10519 "osfiletype", 10520 #endif 10521 #ifdef FEAT_PATH_EXTRA 10522 "path_extra", 10523 #endif 10524 #ifdef FEAT_PERL 10525 #ifndef DYNAMIC_PERL 10526 "perl", 10527 #endif 10528 #endif 10529 #ifdef FEAT_PYTHON 10530 #ifndef DYNAMIC_PYTHON 10531 "python", 10532 #endif 10533 #endif 10534 #ifdef FEAT_POSTSCRIPT 10535 "postscript", 10536 #endif 10537 #ifdef FEAT_PRINTER 10538 "printer", 10539 #endif 10540 #ifdef FEAT_PROFILE 10541 "profile", 10542 #endif 10543 #ifdef FEAT_QUICKFIX 10544 "quickfix", 10545 #endif 10546 #ifdef FEAT_RIGHTLEFT 10547 "rightleft", 10548 #endif 10549 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10550 "ruby", 10551 #endif 10552 #ifdef FEAT_SCROLLBIND 10553 "scrollbind", 10554 #endif 10555 #ifdef FEAT_CMDL_INFO 10556 "showcmd", 10557 "cmdline_info", 10558 #endif 10559 #ifdef FEAT_SIGNS 10560 "signs", 10561 #endif 10562 #ifdef FEAT_SMARTINDENT 10563 "smartindent", 10564 #endif 10565 #ifdef FEAT_SNIFF 10566 "sniff", 10567 #endif 10568 #ifdef FEAT_STL_OPT 10569 "statusline", 10570 #endif 10571 #ifdef FEAT_SUN_WORKSHOP 10572 "sun_workshop", 10573 #endif 10574 #ifdef FEAT_NETBEANS_INTG 10575 "netbeans_intg", 10576 #endif 10577 #ifdef FEAT_SYN_HL 10578 "spell", 10579 #endif 10580 #ifdef FEAT_SYN_HL 10581 "syntax", 10582 #endif 10583 #if defined(USE_SYSTEM) || !defined(UNIX) 10584 "system", 10585 #endif 10586 #ifdef FEAT_TAG_BINS 10587 "tag_binary", 10588 #endif 10589 #ifdef FEAT_TAG_OLDSTATIC 10590 "tag_old_static", 10591 #endif 10592 #ifdef FEAT_TAG_ANYWHITE 10593 "tag_any_white", 10594 #endif 10595 #ifdef FEAT_TCL 10596 # ifndef DYNAMIC_TCL 10597 "tcl", 10598 # endif 10599 #endif 10600 #ifdef TERMINFO 10601 "terminfo", 10602 #endif 10603 #ifdef FEAT_TERMRESPONSE 10604 "termresponse", 10605 #endif 10606 #ifdef FEAT_TEXTOBJ 10607 "textobjects", 10608 #endif 10609 #ifdef HAVE_TGETENT 10610 "tgetent", 10611 #endif 10612 #ifdef FEAT_TITLE 10613 "title", 10614 #endif 10615 #ifdef FEAT_TOOLBAR 10616 "toolbar", 10617 #endif 10618 #ifdef FEAT_USR_CMDS 10619 "user-commands", /* was accidentally included in 5.4 */ 10620 "user_commands", 10621 #endif 10622 #ifdef FEAT_VIMINFO 10623 "viminfo", 10624 #endif 10625 #ifdef FEAT_VERTSPLIT 10626 "vertsplit", 10627 #endif 10628 #ifdef FEAT_VIRTUALEDIT 10629 "virtualedit", 10630 #endif 10631 #ifdef FEAT_VISUAL 10632 "visual", 10633 #endif 10634 #ifdef FEAT_VISUALEXTRA 10635 "visualextra", 10636 #endif 10637 #ifdef FEAT_VREPLACE 10638 "vreplace", 10639 #endif 10640 #ifdef FEAT_WILDIGN 10641 "wildignore", 10642 #endif 10643 #ifdef FEAT_WILDMENU 10644 "wildmenu", 10645 #endif 10646 #ifdef FEAT_WINDOWS 10647 "windows", 10648 #endif 10649 #ifdef FEAT_WAK 10650 "winaltkeys", 10651 #endif 10652 #ifdef FEAT_WRITEBACKUP 10653 "writebackup", 10654 #endif 10655 #ifdef FEAT_XIM 10656 "xim", 10657 #endif 10658 #ifdef FEAT_XFONTSET 10659 "xfontset", 10660 #endif 10661 #ifdef USE_XSMP 10662 "xsmp", 10663 #endif 10664 #ifdef USE_XSMP_INTERACT 10665 "xsmp_interact", 10666 #endif 10667 #ifdef FEAT_XCLIPBOARD 10668 "xterm_clipboard", 10669 #endif 10670 #ifdef FEAT_XTERM_SAVE 10671 "xterm_save", 10672 #endif 10673 #if defined(UNIX) && defined(FEAT_X11) 10674 "X11", 10675 #endif 10676 NULL 10677 }; 10678 10679 name = get_tv_string(&argvars[0]); 10680 for (i = 0; has_list[i] != NULL; ++i) 10681 if (STRICMP(name, has_list[i]) == 0) 10682 { 10683 n = TRUE; 10684 break; 10685 } 10686 10687 if (n == FALSE) 10688 { 10689 if (STRNICMP(name, "patch", 5) == 0) 10690 n = has_patch(atoi((char *)name + 5)); 10691 else if (STRICMP(name, "vim_starting") == 0) 10692 n = (starting != 0); 10693 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10694 else if (STRICMP(name, "balloon_multiline") == 0) 10695 n = multiline_balloon_available(); 10696 #endif 10697 #ifdef DYNAMIC_TCL 10698 else if (STRICMP(name, "tcl") == 0) 10699 n = tcl_enabled(FALSE); 10700 #endif 10701 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10702 else if (STRICMP(name, "iconv") == 0) 10703 n = iconv_enabled(FALSE); 10704 #endif 10705 #ifdef DYNAMIC_MZSCHEME 10706 else if (STRICMP(name, "mzscheme") == 0) 10707 n = mzscheme_enabled(FALSE); 10708 #endif 10709 #ifdef DYNAMIC_RUBY 10710 else if (STRICMP(name, "ruby") == 0) 10711 n = ruby_enabled(FALSE); 10712 #endif 10713 #ifdef DYNAMIC_PYTHON 10714 else if (STRICMP(name, "python") == 0) 10715 n = python_enabled(FALSE); 10716 #endif 10717 #ifdef DYNAMIC_PERL 10718 else if (STRICMP(name, "perl") == 0) 10719 n = perl_enabled(FALSE); 10720 #endif 10721 #ifdef FEAT_GUI 10722 else if (STRICMP(name, "gui_running") == 0) 10723 n = (gui.in_use || gui.starting); 10724 # ifdef FEAT_GUI_W32 10725 else if (STRICMP(name, "gui_win32s") == 0) 10726 n = gui_is_win32s(); 10727 # endif 10728 # ifdef FEAT_BROWSE 10729 else if (STRICMP(name, "browse") == 0) 10730 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10731 # endif 10732 #endif 10733 #ifdef FEAT_SYN_HL 10734 else if (STRICMP(name, "syntax_items") == 0) 10735 n = syntax_present(curbuf); 10736 #endif 10737 #if defined(WIN3264) 10738 else if (STRICMP(name, "win95") == 0) 10739 n = mch_windows95(); 10740 #endif 10741 #ifdef FEAT_NETBEANS_INTG 10742 else if (STRICMP(name, "netbeans_enabled") == 0) 10743 n = usingNetbeans; 10744 #endif 10745 } 10746 10747 rettv->vval.v_number = n; 10748 } 10749 10750 /* 10751 * "has_key()" function 10752 */ 10753 static void 10754 f_has_key(argvars, rettv) 10755 typval_T *argvars; 10756 typval_T *rettv; 10757 { 10758 rettv->vval.v_number = 0; 10759 if (argvars[0].v_type != VAR_DICT) 10760 { 10761 EMSG(_(e_dictreq)); 10762 return; 10763 } 10764 if (argvars[0].vval.v_dict == NULL) 10765 return; 10766 10767 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10768 get_tv_string(&argvars[1]), -1) != NULL; 10769 } 10770 10771 /* 10772 * "hasmapto()" function 10773 */ 10774 static void 10775 f_hasmapto(argvars, rettv) 10776 typval_T *argvars; 10777 typval_T *rettv; 10778 { 10779 char_u *name; 10780 char_u *mode; 10781 char_u buf[NUMBUFLEN]; 10782 10783 name = get_tv_string(&argvars[0]); 10784 if (argvars[1].v_type == VAR_UNKNOWN) 10785 mode = (char_u *)"nvo"; 10786 else 10787 mode = get_tv_string_buf(&argvars[1], buf); 10788 10789 if (map_to_exists(name, mode)) 10790 rettv->vval.v_number = TRUE; 10791 else 10792 rettv->vval.v_number = FALSE; 10793 } 10794 10795 /* 10796 * "histadd()" function 10797 */ 10798 /*ARGSUSED*/ 10799 static void 10800 f_histadd(argvars, rettv) 10801 typval_T *argvars; 10802 typval_T *rettv; 10803 { 10804 #ifdef FEAT_CMDHIST 10805 int histype; 10806 char_u *str; 10807 char_u buf[NUMBUFLEN]; 10808 #endif 10809 10810 rettv->vval.v_number = FALSE; 10811 if (check_restricted() || check_secure()) 10812 return; 10813 #ifdef FEAT_CMDHIST 10814 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10815 histype = str != NULL ? get_histtype(str) : -1; 10816 if (histype >= 0) 10817 { 10818 str = get_tv_string_buf(&argvars[1], buf); 10819 if (*str != NUL) 10820 { 10821 add_to_history(histype, str, FALSE, NUL); 10822 rettv->vval.v_number = TRUE; 10823 return; 10824 } 10825 } 10826 #endif 10827 } 10828 10829 /* 10830 * "histdel()" function 10831 */ 10832 /*ARGSUSED*/ 10833 static void 10834 f_histdel(argvars, rettv) 10835 typval_T *argvars; 10836 typval_T *rettv; 10837 { 10838 #ifdef FEAT_CMDHIST 10839 int n; 10840 char_u buf[NUMBUFLEN]; 10841 char_u *str; 10842 10843 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10844 if (str == NULL) 10845 n = 0; 10846 else if (argvars[1].v_type == VAR_UNKNOWN) 10847 /* only one argument: clear entire history */ 10848 n = clr_history(get_histtype(str)); 10849 else if (argvars[1].v_type == VAR_NUMBER) 10850 /* index given: remove that entry */ 10851 n = del_history_idx(get_histtype(str), 10852 (int)get_tv_number(&argvars[1])); 10853 else 10854 /* string given: remove all matching entries */ 10855 n = del_history_entry(get_histtype(str), 10856 get_tv_string_buf(&argvars[1], buf)); 10857 rettv->vval.v_number = n; 10858 #else 10859 rettv->vval.v_number = 0; 10860 #endif 10861 } 10862 10863 /* 10864 * "histget()" function 10865 */ 10866 /*ARGSUSED*/ 10867 static void 10868 f_histget(argvars, rettv) 10869 typval_T *argvars; 10870 typval_T *rettv; 10871 { 10872 #ifdef FEAT_CMDHIST 10873 int type; 10874 int idx; 10875 char_u *str; 10876 10877 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10878 if (str == NULL) 10879 rettv->vval.v_string = NULL; 10880 else 10881 { 10882 type = get_histtype(str); 10883 if (argvars[1].v_type == VAR_UNKNOWN) 10884 idx = get_history_idx(type); 10885 else 10886 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10887 /* -1 on type error */ 10888 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10889 } 10890 #else 10891 rettv->vval.v_string = NULL; 10892 #endif 10893 rettv->v_type = VAR_STRING; 10894 } 10895 10896 /* 10897 * "histnr()" function 10898 */ 10899 /*ARGSUSED*/ 10900 static void 10901 f_histnr(argvars, rettv) 10902 typval_T *argvars; 10903 typval_T *rettv; 10904 { 10905 int i; 10906 10907 #ifdef FEAT_CMDHIST 10908 char_u *history = get_tv_string_chk(&argvars[0]); 10909 10910 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10911 if (i >= HIST_CMD && i < HIST_COUNT) 10912 i = get_history_idx(i); 10913 else 10914 #endif 10915 i = -1; 10916 rettv->vval.v_number = i; 10917 } 10918 10919 /* 10920 * "highlightID(name)" function 10921 */ 10922 static void 10923 f_hlID(argvars, rettv) 10924 typval_T *argvars; 10925 typval_T *rettv; 10926 { 10927 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10928 } 10929 10930 /* 10931 * "highlight_exists()" function 10932 */ 10933 static void 10934 f_hlexists(argvars, rettv) 10935 typval_T *argvars; 10936 typval_T *rettv; 10937 { 10938 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10939 } 10940 10941 /* 10942 * "hostname()" function 10943 */ 10944 /*ARGSUSED*/ 10945 static void 10946 f_hostname(argvars, rettv) 10947 typval_T *argvars; 10948 typval_T *rettv; 10949 { 10950 char_u hostname[256]; 10951 10952 mch_get_host_name(hostname, 256); 10953 rettv->v_type = VAR_STRING; 10954 rettv->vval.v_string = vim_strsave(hostname); 10955 } 10956 10957 /* 10958 * iconv() function 10959 */ 10960 /*ARGSUSED*/ 10961 static void 10962 f_iconv(argvars, rettv) 10963 typval_T *argvars; 10964 typval_T *rettv; 10965 { 10966 #ifdef FEAT_MBYTE 10967 char_u buf1[NUMBUFLEN]; 10968 char_u buf2[NUMBUFLEN]; 10969 char_u *from, *to, *str; 10970 vimconv_T vimconv; 10971 #endif 10972 10973 rettv->v_type = VAR_STRING; 10974 rettv->vval.v_string = NULL; 10975 10976 #ifdef FEAT_MBYTE 10977 str = get_tv_string(&argvars[0]); 10978 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10979 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10980 vimconv.vc_type = CONV_NONE; 10981 convert_setup(&vimconv, from, to); 10982 10983 /* If the encodings are equal, no conversion needed. */ 10984 if (vimconv.vc_type == CONV_NONE) 10985 rettv->vval.v_string = vim_strsave(str); 10986 else 10987 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10988 10989 convert_setup(&vimconv, NULL, NULL); 10990 vim_free(from); 10991 vim_free(to); 10992 #endif 10993 } 10994 10995 /* 10996 * "indent()" function 10997 */ 10998 static void 10999 f_indent(argvars, rettv) 11000 typval_T *argvars; 11001 typval_T *rettv; 11002 { 11003 linenr_T lnum; 11004 11005 lnum = get_tv_lnum(argvars); 11006 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11007 rettv->vval.v_number = get_indent_lnum(lnum); 11008 else 11009 rettv->vval.v_number = -1; 11010 } 11011 11012 /* 11013 * "index()" function 11014 */ 11015 static void 11016 f_index(argvars, rettv) 11017 typval_T *argvars; 11018 typval_T *rettv; 11019 { 11020 list_T *l; 11021 listitem_T *item; 11022 long idx = 0; 11023 int ic = FALSE; 11024 11025 rettv->vval.v_number = -1; 11026 if (argvars[0].v_type != VAR_LIST) 11027 { 11028 EMSG(_(e_listreq)); 11029 return; 11030 } 11031 l = argvars[0].vval.v_list; 11032 if (l != NULL) 11033 { 11034 item = l->lv_first; 11035 if (argvars[2].v_type != VAR_UNKNOWN) 11036 { 11037 int error = FALSE; 11038 11039 /* Start at specified item. Use the cached index that list_find() 11040 * sets, so that a negative number also works. */ 11041 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 11042 idx = l->lv_idx; 11043 if (argvars[3].v_type != VAR_UNKNOWN) 11044 ic = get_tv_number_chk(&argvars[3], &error); 11045 if (error) 11046 item = NULL; 11047 } 11048 11049 for ( ; item != NULL; item = item->li_next, ++idx) 11050 if (tv_equal(&item->li_tv, &argvars[1], ic)) 11051 { 11052 rettv->vval.v_number = idx; 11053 break; 11054 } 11055 } 11056 } 11057 11058 static int inputsecret_flag = 0; 11059 11060 /* 11061 * "input()" function 11062 * Also handles inputsecret() when inputsecret is set. 11063 */ 11064 static void 11065 f_input(argvars, rettv) 11066 typval_T *argvars; 11067 typval_T *rettv; 11068 { 11069 char_u *prompt = get_tv_string_chk(&argvars[0]); 11070 char_u *p = NULL; 11071 int c; 11072 char_u buf[NUMBUFLEN]; 11073 int cmd_silent_save = cmd_silent; 11074 char_u *defstr = (char_u *)""; 11075 int xp_type = EXPAND_NOTHING; 11076 char_u *xp_arg = NULL; 11077 11078 rettv->v_type = VAR_STRING; 11079 11080 #ifdef NO_CONSOLE_INPUT 11081 /* While starting up, there is no place to enter text. */ 11082 if (no_console_input()) 11083 { 11084 rettv->vval.v_string = NULL; 11085 return; 11086 } 11087 #endif 11088 11089 cmd_silent = FALSE; /* Want to see the prompt. */ 11090 if (prompt != NULL) 11091 { 11092 /* Only the part of the message after the last NL is considered as 11093 * prompt for the command line */ 11094 p = vim_strrchr(prompt, '\n'); 11095 if (p == NULL) 11096 p = prompt; 11097 else 11098 { 11099 ++p; 11100 c = *p; 11101 *p = NUL; 11102 msg_start(); 11103 msg_clr_eos(); 11104 msg_puts_attr(prompt, echo_attr); 11105 msg_didout = FALSE; 11106 msg_starthere(); 11107 *p = c; 11108 } 11109 cmdline_row = msg_row; 11110 11111 if (argvars[1].v_type != VAR_UNKNOWN) 11112 { 11113 defstr = get_tv_string_buf_chk(&argvars[1], buf); 11114 if (defstr != NULL) 11115 stuffReadbuffSpec(defstr); 11116 11117 if (argvars[2].v_type != VAR_UNKNOWN) 11118 { 11119 char_u *xp_name; 11120 int xp_namelen; 11121 long argt; 11122 11123 rettv->vval.v_string = NULL; 11124 11125 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 11126 if (xp_name == NULL) 11127 return; 11128 11129 xp_namelen = STRLEN(xp_name); 11130 11131 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 11132 &xp_arg) == FAIL) 11133 return; 11134 } 11135 } 11136 11137 if (defstr != NULL) 11138 rettv->vval.v_string = 11139 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 11140 xp_type, xp_arg); 11141 11142 vim_free(xp_arg); 11143 11144 /* since the user typed this, no need to wait for return */ 11145 need_wait_return = FALSE; 11146 msg_didout = FALSE; 11147 } 11148 cmd_silent = cmd_silent_save; 11149 } 11150 11151 /* 11152 * "inputdialog()" function 11153 */ 11154 static void 11155 f_inputdialog(argvars, rettv) 11156 typval_T *argvars; 11157 typval_T *rettv; 11158 { 11159 #if defined(FEAT_GUI_TEXTDIALOG) 11160 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 11161 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 11162 { 11163 char_u *message; 11164 char_u buf[NUMBUFLEN]; 11165 char_u *defstr = (char_u *)""; 11166 11167 message = get_tv_string_chk(&argvars[0]); 11168 if (argvars[1].v_type != VAR_UNKNOWN 11169 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 11170 vim_strncpy(IObuff, defstr, IOSIZE - 1); 11171 else 11172 IObuff[0] = NUL; 11173 if (message != NULL && defstr != NULL 11174 && do_dialog(VIM_QUESTION, NULL, message, 11175 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 11176 rettv->vval.v_string = vim_strsave(IObuff); 11177 else 11178 { 11179 if (message != NULL && defstr != NULL 11180 && argvars[1].v_type != VAR_UNKNOWN 11181 && argvars[2].v_type != VAR_UNKNOWN) 11182 rettv->vval.v_string = vim_strsave( 11183 get_tv_string_buf(&argvars[2], buf)); 11184 else 11185 rettv->vval.v_string = NULL; 11186 } 11187 rettv->v_type = VAR_STRING; 11188 } 11189 else 11190 #endif 11191 f_input(argvars, rettv); 11192 } 11193 11194 /* 11195 * "inputlist()" function 11196 */ 11197 static void 11198 f_inputlist(argvars, rettv) 11199 typval_T *argvars; 11200 typval_T *rettv; 11201 { 11202 listitem_T *li; 11203 int selected; 11204 int mouse_used; 11205 11206 rettv->vval.v_number = 0; 11207 #ifdef NO_CONSOLE_INPUT 11208 /* While starting up, there is no place to enter text. */ 11209 if (no_console_input()) 11210 return; 11211 #endif 11212 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 11213 { 11214 EMSG2(_(e_listarg), "inputlist()"); 11215 return; 11216 } 11217 11218 msg_start(); 11219 lines_left = Rows; /* avoid more prompt */ 11220 msg_scroll = TRUE; 11221 msg_clr_eos(); 11222 11223 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 11224 { 11225 msg_puts(get_tv_string(&li->li_tv)); 11226 msg_putchar('\n'); 11227 } 11228 11229 /* Ask for choice. */ 11230 selected = prompt_for_number(&mouse_used); 11231 if (mouse_used) 11232 selected -= lines_left; 11233 11234 rettv->vval.v_number = selected; 11235 } 11236 11237 11238 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 11239 11240 /* 11241 * "inputrestore()" function 11242 */ 11243 /*ARGSUSED*/ 11244 static void 11245 f_inputrestore(argvars, rettv) 11246 typval_T *argvars; 11247 typval_T *rettv; 11248 { 11249 if (ga_userinput.ga_len > 0) 11250 { 11251 --ga_userinput.ga_len; 11252 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 11253 + ga_userinput.ga_len); 11254 rettv->vval.v_number = 0; /* OK */ 11255 } 11256 else if (p_verbose > 1) 11257 { 11258 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11259 rettv->vval.v_number = 1; /* Failed */ 11260 } 11261 } 11262 11263 /* 11264 * "inputsave()" function 11265 */ 11266 /*ARGSUSED*/ 11267 static void 11268 f_inputsave(argvars, rettv) 11269 typval_T *argvars; 11270 typval_T *rettv; 11271 { 11272 /* Add an entry to the stack of typehead storage. */ 11273 if (ga_grow(&ga_userinput, 1) == OK) 11274 { 11275 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11276 + ga_userinput.ga_len); 11277 ++ga_userinput.ga_len; 11278 rettv->vval.v_number = 0; /* OK */ 11279 } 11280 else 11281 rettv->vval.v_number = 1; /* Failed */ 11282 } 11283 11284 /* 11285 * "inputsecret()" function 11286 */ 11287 static void 11288 f_inputsecret(argvars, rettv) 11289 typval_T *argvars; 11290 typval_T *rettv; 11291 { 11292 ++cmdline_star; 11293 ++inputsecret_flag; 11294 f_input(argvars, rettv); 11295 --cmdline_star; 11296 --inputsecret_flag; 11297 } 11298 11299 /* 11300 * "insert()" function 11301 */ 11302 static void 11303 f_insert(argvars, rettv) 11304 typval_T *argvars; 11305 typval_T *rettv; 11306 { 11307 long before = 0; 11308 listitem_T *item; 11309 list_T *l; 11310 int error = FALSE; 11311 11312 rettv->vval.v_number = 0; 11313 if (argvars[0].v_type != VAR_LIST) 11314 EMSG2(_(e_listarg), "insert()"); 11315 else if ((l = argvars[0].vval.v_list) != NULL 11316 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11317 { 11318 if (argvars[2].v_type != VAR_UNKNOWN) 11319 before = get_tv_number_chk(&argvars[2], &error); 11320 if (error) 11321 return; /* type error; errmsg already given */ 11322 11323 if (before == l->lv_len) 11324 item = NULL; 11325 else 11326 { 11327 item = list_find(l, before); 11328 if (item == NULL) 11329 { 11330 EMSGN(_(e_listidx), before); 11331 l = NULL; 11332 } 11333 } 11334 if (l != NULL) 11335 { 11336 list_insert_tv(l, &argvars[1], item); 11337 copy_tv(&argvars[0], rettv); 11338 } 11339 } 11340 } 11341 11342 /* 11343 * "isdirectory()" function 11344 */ 11345 static void 11346 f_isdirectory(argvars, rettv) 11347 typval_T *argvars; 11348 typval_T *rettv; 11349 { 11350 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11351 } 11352 11353 /* 11354 * "islocked()" function 11355 */ 11356 static void 11357 f_islocked(argvars, rettv) 11358 typval_T *argvars; 11359 typval_T *rettv; 11360 { 11361 lval_T lv; 11362 char_u *end; 11363 dictitem_T *di; 11364 11365 rettv->vval.v_number = -1; 11366 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11367 FNE_CHECK_START); 11368 if (end != NULL && lv.ll_name != NULL) 11369 { 11370 if (*end != NUL) 11371 EMSG(_(e_trailing)); 11372 else 11373 { 11374 if (lv.ll_tv == NULL) 11375 { 11376 if (check_changedtick(lv.ll_name)) 11377 rettv->vval.v_number = 1; /* always locked */ 11378 else 11379 { 11380 di = find_var(lv.ll_name, NULL); 11381 if (di != NULL) 11382 { 11383 /* Consider a variable locked when: 11384 * 1. the variable itself is locked 11385 * 2. the value of the variable is locked. 11386 * 3. the List or Dict value is locked. 11387 */ 11388 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11389 || tv_islocked(&di->di_tv)); 11390 } 11391 } 11392 } 11393 else if (lv.ll_range) 11394 EMSG(_("E745: Range not allowed")); 11395 else if (lv.ll_newkey != NULL) 11396 EMSG2(_(e_dictkey), lv.ll_newkey); 11397 else if (lv.ll_list != NULL) 11398 /* List item. */ 11399 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11400 else 11401 /* Dictionary item. */ 11402 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11403 } 11404 } 11405 11406 clear_lval(&lv); 11407 } 11408 11409 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11410 11411 /* 11412 * Turn a dict into a list: 11413 * "what" == 0: list of keys 11414 * "what" == 1: list of values 11415 * "what" == 2: list of items 11416 */ 11417 static void 11418 dict_list(argvars, rettv, what) 11419 typval_T *argvars; 11420 typval_T *rettv; 11421 int what; 11422 { 11423 list_T *l2; 11424 dictitem_T *di; 11425 hashitem_T *hi; 11426 listitem_T *li; 11427 listitem_T *li2; 11428 dict_T *d; 11429 int todo; 11430 11431 rettv->vval.v_number = 0; 11432 if (argvars[0].v_type != VAR_DICT) 11433 { 11434 EMSG(_(e_dictreq)); 11435 return; 11436 } 11437 if ((d = argvars[0].vval.v_dict) == NULL) 11438 return; 11439 11440 if (rettv_list_alloc(rettv) == FAIL) 11441 return; 11442 11443 todo = d->dv_hashtab.ht_used; 11444 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11445 { 11446 if (!HASHITEM_EMPTY(hi)) 11447 { 11448 --todo; 11449 di = HI2DI(hi); 11450 11451 li = listitem_alloc(); 11452 if (li == NULL) 11453 break; 11454 list_append(rettv->vval.v_list, li); 11455 11456 if (what == 0) 11457 { 11458 /* keys() */ 11459 li->li_tv.v_type = VAR_STRING; 11460 li->li_tv.v_lock = 0; 11461 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11462 } 11463 else if (what == 1) 11464 { 11465 /* values() */ 11466 copy_tv(&di->di_tv, &li->li_tv); 11467 } 11468 else 11469 { 11470 /* items() */ 11471 l2 = list_alloc(); 11472 li->li_tv.v_type = VAR_LIST; 11473 li->li_tv.v_lock = 0; 11474 li->li_tv.vval.v_list = l2; 11475 if (l2 == NULL) 11476 break; 11477 ++l2->lv_refcount; 11478 11479 li2 = listitem_alloc(); 11480 if (li2 == NULL) 11481 break; 11482 list_append(l2, li2); 11483 li2->li_tv.v_type = VAR_STRING; 11484 li2->li_tv.v_lock = 0; 11485 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11486 11487 li2 = listitem_alloc(); 11488 if (li2 == NULL) 11489 break; 11490 list_append(l2, li2); 11491 copy_tv(&di->di_tv, &li2->li_tv); 11492 } 11493 } 11494 } 11495 } 11496 11497 /* 11498 * "items(dict)" function 11499 */ 11500 static void 11501 f_items(argvars, rettv) 11502 typval_T *argvars; 11503 typval_T *rettv; 11504 { 11505 dict_list(argvars, rettv, 2); 11506 } 11507 11508 /* 11509 * "join()" function 11510 */ 11511 static void 11512 f_join(argvars, rettv) 11513 typval_T *argvars; 11514 typval_T *rettv; 11515 { 11516 garray_T ga; 11517 char_u *sep; 11518 11519 rettv->vval.v_number = 0; 11520 if (argvars[0].v_type != VAR_LIST) 11521 { 11522 EMSG(_(e_listreq)); 11523 return; 11524 } 11525 if (argvars[0].vval.v_list == NULL) 11526 return; 11527 if (argvars[1].v_type == VAR_UNKNOWN) 11528 sep = (char_u *)" "; 11529 else 11530 sep = get_tv_string_chk(&argvars[1]); 11531 11532 rettv->v_type = VAR_STRING; 11533 11534 if (sep != NULL) 11535 { 11536 ga_init2(&ga, (int)sizeof(char), 80); 11537 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 11538 ga_append(&ga, NUL); 11539 rettv->vval.v_string = (char_u *)ga.ga_data; 11540 } 11541 else 11542 rettv->vval.v_string = NULL; 11543 } 11544 11545 /* 11546 * "keys()" function 11547 */ 11548 static void 11549 f_keys(argvars, rettv) 11550 typval_T *argvars; 11551 typval_T *rettv; 11552 { 11553 dict_list(argvars, rettv, 0); 11554 } 11555 11556 /* 11557 * "last_buffer_nr()" function. 11558 */ 11559 /*ARGSUSED*/ 11560 static void 11561 f_last_buffer_nr(argvars, rettv) 11562 typval_T *argvars; 11563 typval_T *rettv; 11564 { 11565 int n = 0; 11566 buf_T *buf; 11567 11568 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11569 if (n < buf->b_fnum) 11570 n = buf->b_fnum; 11571 11572 rettv->vval.v_number = n; 11573 } 11574 11575 /* 11576 * "len()" function 11577 */ 11578 static void 11579 f_len(argvars, rettv) 11580 typval_T *argvars; 11581 typval_T *rettv; 11582 { 11583 switch (argvars[0].v_type) 11584 { 11585 case VAR_STRING: 11586 case VAR_NUMBER: 11587 rettv->vval.v_number = (varnumber_T)STRLEN( 11588 get_tv_string(&argvars[0])); 11589 break; 11590 case VAR_LIST: 11591 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11592 break; 11593 case VAR_DICT: 11594 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11595 break; 11596 default: 11597 EMSG(_("E701: Invalid type for len()")); 11598 break; 11599 } 11600 } 11601 11602 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11603 11604 static void 11605 libcall_common(argvars, rettv, type) 11606 typval_T *argvars; 11607 typval_T *rettv; 11608 int type; 11609 { 11610 #ifdef FEAT_LIBCALL 11611 char_u *string_in; 11612 char_u **string_result; 11613 int nr_result; 11614 #endif 11615 11616 rettv->v_type = type; 11617 if (type == VAR_NUMBER) 11618 rettv->vval.v_number = 0; 11619 else 11620 rettv->vval.v_string = NULL; 11621 11622 if (check_restricted() || check_secure()) 11623 return; 11624 11625 #ifdef FEAT_LIBCALL 11626 /* The first two args must be strings, otherwise its meaningless */ 11627 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11628 { 11629 string_in = NULL; 11630 if (argvars[2].v_type == VAR_STRING) 11631 string_in = argvars[2].vval.v_string; 11632 if (type == VAR_NUMBER) 11633 string_result = NULL; 11634 else 11635 string_result = &rettv->vval.v_string; 11636 if (mch_libcall(argvars[0].vval.v_string, 11637 argvars[1].vval.v_string, 11638 string_in, 11639 argvars[2].vval.v_number, 11640 string_result, 11641 &nr_result) == OK 11642 && type == VAR_NUMBER) 11643 rettv->vval.v_number = nr_result; 11644 } 11645 #endif 11646 } 11647 11648 /* 11649 * "libcall()" function 11650 */ 11651 static void 11652 f_libcall(argvars, rettv) 11653 typval_T *argvars; 11654 typval_T *rettv; 11655 { 11656 libcall_common(argvars, rettv, VAR_STRING); 11657 } 11658 11659 /* 11660 * "libcallnr()" function 11661 */ 11662 static void 11663 f_libcallnr(argvars, rettv) 11664 typval_T *argvars; 11665 typval_T *rettv; 11666 { 11667 libcall_common(argvars, rettv, VAR_NUMBER); 11668 } 11669 11670 /* 11671 * "line(string)" function 11672 */ 11673 static void 11674 f_line(argvars, rettv) 11675 typval_T *argvars; 11676 typval_T *rettv; 11677 { 11678 linenr_T lnum = 0; 11679 pos_T *fp; 11680 int fnum; 11681 11682 fp = var2fpos(&argvars[0], TRUE, &fnum); 11683 if (fp != NULL) 11684 lnum = fp->lnum; 11685 rettv->vval.v_number = lnum; 11686 } 11687 11688 /* 11689 * "line2byte(lnum)" function 11690 */ 11691 /*ARGSUSED*/ 11692 static void 11693 f_line2byte(argvars, rettv) 11694 typval_T *argvars; 11695 typval_T *rettv; 11696 { 11697 #ifndef FEAT_BYTEOFF 11698 rettv->vval.v_number = -1; 11699 #else 11700 linenr_T lnum; 11701 11702 lnum = get_tv_lnum(argvars); 11703 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11704 rettv->vval.v_number = -1; 11705 else 11706 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11707 if (rettv->vval.v_number >= 0) 11708 ++rettv->vval.v_number; 11709 #endif 11710 } 11711 11712 /* 11713 * "lispindent(lnum)" function 11714 */ 11715 static void 11716 f_lispindent(argvars, rettv) 11717 typval_T *argvars; 11718 typval_T *rettv; 11719 { 11720 #ifdef FEAT_LISP 11721 pos_T pos; 11722 linenr_T lnum; 11723 11724 pos = curwin->w_cursor; 11725 lnum = get_tv_lnum(argvars); 11726 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11727 { 11728 curwin->w_cursor.lnum = lnum; 11729 rettv->vval.v_number = get_lisp_indent(); 11730 curwin->w_cursor = pos; 11731 } 11732 else 11733 #endif 11734 rettv->vval.v_number = -1; 11735 } 11736 11737 /* 11738 * "localtime()" function 11739 */ 11740 /*ARGSUSED*/ 11741 static void 11742 f_localtime(argvars, rettv) 11743 typval_T *argvars; 11744 typval_T *rettv; 11745 { 11746 rettv->vval.v_number = (varnumber_T)time(NULL); 11747 } 11748 11749 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11750 11751 static void 11752 get_maparg(argvars, rettv, exact) 11753 typval_T *argvars; 11754 typval_T *rettv; 11755 int exact; 11756 { 11757 char_u *keys; 11758 char_u *which; 11759 char_u buf[NUMBUFLEN]; 11760 char_u *keys_buf = NULL; 11761 char_u *rhs; 11762 int mode; 11763 garray_T ga; 11764 11765 /* return empty string for failure */ 11766 rettv->v_type = VAR_STRING; 11767 rettv->vval.v_string = NULL; 11768 11769 keys = get_tv_string(&argvars[0]); 11770 if (*keys == NUL) 11771 return; 11772 11773 if (argvars[1].v_type != VAR_UNKNOWN) 11774 which = get_tv_string_buf_chk(&argvars[1], buf); 11775 else 11776 which = (char_u *)""; 11777 if (which == NULL) 11778 return; 11779 11780 mode = get_map_mode(&which, 0); 11781 11782 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11783 rhs = check_map(keys, mode, exact, FALSE); 11784 vim_free(keys_buf); 11785 if (rhs != NULL) 11786 { 11787 ga_init(&ga); 11788 ga.ga_itemsize = 1; 11789 ga.ga_growsize = 40; 11790 11791 while (*rhs != NUL) 11792 ga_concat(&ga, str2special(&rhs, FALSE)); 11793 11794 ga_append(&ga, NUL); 11795 rettv->vval.v_string = (char_u *)ga.ga_data; 11796 } 11797 } 11798 11799 /* 11800 * "map()" function 11801 */ 11802 static void 11803 f_map(argvars, rettv) 11804 typval_T *argvars; 11805 typval_T *rettv; 11806 { 11807 filter_map(argvars, rettv, TRUE); 11808 } 11809 11810 /* 11811 * "maparg()" function 11812 */ 11813 static void 11814 f_maparg(argvars, rettv) 11815 typval_T *argvars; 11816 typval_T *rettv; 11817 { 11818 get_maparg(argvars, rettv, TRUE); 11819 } 11820 11821 /* 11822 * "mapcheck()" function 11823 */ 11824 static void 11825 f_mapcheck(argvars, rettv) 11826 typval_T *argvars; 11827 typval_T *rettv; 11828 { 11829 get_maparg(argvars, rettv, FALSE); 11830 } 11831 11832 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11833 11834 static void 11835 find_some_match(argvars, rettv, type) 11836 typval_T *argvars; 11837 typval_T *rettv; 11838 int type; 11839 { 11840 char_u *str = NULL; 11841 char_u *expr = NULL; 11842 char_u *pat; 11843 regmatch_T regmatch; 11844 char_u patbuf[NUMBUFLEN]; 11845 char_u strbuf[NUMBUFLEN]; 11846 char_u *save_cpo; 11847 long start = 0; 11848 long nth = 1; 11849 colnr_T startcol = 0; 11850 int match = 0; 11851 list_T *l = NULL; 11852 listitem_T *li = NULL; 11853 long idx = 0; 11854 char_u *tofree = NULL; 11855 11856 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11857 save_cpo = p_cpo; 11858 p_cpo = (char_u *)""; 11859 11860 rettv->vval.v_number = -1; 11861 if (type == 3) 11862 { 11863 /* return empty list when there are no matches */ 11864 if (rettv_list_alloc(rettv) == FAIL) 11865 goto theend; 11866 } 11867 else if (type == 2) 11868 { 11869 rettv->v_type = VAR_STRING; 11870 rettv->vval.v_string = NULL; 11871 } 11872 11873 if (argvars[0].v_type == VAR_LIST) 11874 { 11875 if ((l = argvars[0].vval.v_list) == NULL) 11876 goto theend; 11877 li = l->lv_first; 11878 } 11879 else 11880 expr = str = get_tv_string(&argvars[0]); 11881 11882 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11883 if (pat == NULL) 11884 goto theend; 11885 11886 if (argvars[2].v_type != VAR_UNKNOWN) 11887 { 11888 int error = FALSE; 11889 11890 start = get_tv_number_chk(&argvars[2], &error); 11891 if (error) 11892 goto theend; 11893 if (l != NULL) 11894 { 11895 li = list_find(l, start); 11896 if (li == NULL) 11897 goto theend; 11898 idx = l->lv_idx; /* use the cached index */ 11899 } 11900 else 11901 { 11902 if (start < 0) 11903 start = 0; 11904 if (start > (long)STRLEN(str)) 11905 goto theend; 11906 /* When "count" argument is there ignore matches before "start", 11907 * otherwise skip part of the string. Differs when pattern is "^" 11908 * or "\<". */ 11909 if (argvars[3].v_type != VAR_UNKNOWN) 11910 startcol = start; 11911 else 11912 str += start; 11913 } 11914 11915 if (argvars[3].v_type != VAR_UNKNOWN) 11916 nth = get_tv_number_chk(&argvars[3], &error); 11917 if (error) 11918 goto theend; 11919 } 11920 11921 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11922 if (regmatch.regprog != NULL) 11923 { 11924 regmatch.rm_ic = p_ic; 11925 11926 for (;;) 11927 { 11928 if (l != NULL) 11929 { 11930 if (li == NULL) 11931 { 11932 match = FALSE; 11933 break; 11934 } 11935 vim_free(tofree); 11936 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 11937 if (str == NULL) 11938 break; 11939 } 11940 11941 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 11942 11943 if (match && --nth <= 0) 11944 break; 11945 if (l == NULL && !match) 11946 break; 11947 11948 /* Advance to just after the match. */ 11949 if (l != NULL) 11950 { 11951 li = li->li_next; 11952 ++idx; 11953 } 11954 else 11955 { 11956 #ifdef FEAT_MBYTE 11957 startcol = regmatch.startp[0] 11958 + (*mb_ptr2len)(regmatch.startp[0]) - str; 11959 #else 11960 startcol = regmatch.startp[0] + 1 - str; 11961 #endif 11962 } 11963 } 11964 11965 if (match) 11966 { 11967 if (type == 3) 11968 { 11969 int i; 11970 11971 /* return list with matched string and submatches */ 11972 for (i = 0; i < NSUBEXP; ++i) 11973 { 11974 if (regmatch.endp[i] == NULL) 11975 break; 11976 if (list_append_string(rettv->vval.v_list, 11977 regmatch.startp[i], 11978 (int)(regmatch.endp[i] - regmatch.startp[i])) 11979 == FAIL) 11980 break; 11981 } 11982 } 11983 else if (type == 2) 11984 { 11985 /* return matched string */ 11986 if (l != NULL) 11987 copy_tv(&li->li_tv, rettv); 11988 else 11989 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11990 (int)(regmatch.endp[0] - regmatch.startp[0])); 11991 } 11992 else if (l != NULL) 11993 rettv->vval.v_number = idx; 11994 else 11995 { 11996 if (type != 0) 11997 rettv->vval.v_number = 11998 (varnumber_T)(regmatch.startp[0] - str); 11999 else 12000 rettv->vval.v_number = 12001 (varnumber_T)(regmatch.endp[0] - str); 12002 rettv->vval.v_number += str - expr; 12003 } 12004 } 12005 vim_free(regmatch.regprog); 12006 } 12007 12008 theend: 12009 vim_free(tofree); 12010 p_cpo = save_cpo; 12011 } 12012 12013 /* 12014 * "match()" function 12015 */ 12016 static void 12017 f_match(argvars, rettv) 12018 typval_T *argvars; 12019 typval_T *rettv; 12020 { 12021 find_some_match(argvars, rettv, 1); 12022 } 12023 12024 /* 12025 * "matchend()" function 12026 */ 12027 static void 12028 f_matchend(argvars, rettv) 12029 typval_T *argvars; 12030 typval_T *rettv; 12031 { 12032 find_some_match(argvars, rettv, 0); 12033 } 12034 12035 /* 12036 * "matchlist()" function 12037 */ 12038 static void 12039 f_matchlist(argvars, rettv) 12040 typval_T *argvars; 12041 typval_T *rettv; 12042 { 12043 find_some_match(argvars, rettv, 3); 12044 } 12045 12046 /* 12047 * "matchstr()" function 12048 */ 12049 static void 12050 f_matchstr(argvars, rettv) 12051 typval_T *argvars; 12052 typval_T *rettv; 12053 { 12054 find_some_match(argvars, rettv, 2); 12055 } 12056 12057 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 12058 12059 static void 12060 max_min(argvars, rettv, domax) 12061 typval_T *argvars; 12062 typval_T *rettv; 12063 int domax; 12064 { 12065 long n = 0; 12066 long i; 12067 int error = FALSE; 12068 12069 if (argvars[0].v_type == VAR_LIST) 12070 { 12071 list_T *l; 12072 listitem_T *li; 12073 12074 l = argvars[0].vval.v_list; 12075 if (l != NULL) 12076 { 12077 li = l->lv_first; 12078 if (li != NULL) 12079 { 12080 n = get_tv_number_chk(&li->li_tv, &error); 12081 for (;;) 12082 { 12083 li = li->li_next; 12084 if (li == NULL) 12085 break; 12086 i = get_tv_number_chk(&li->li_tv, &error); 12087 if (domax ? i > n : i < n) 12088 n = i; 12089 } 12090 } 12091 } 12092 } 12093 else if (argvars[0].v_type == VAR_DICT) 12094 { 12095 dict_T *d; 12096 int first = TRUE; 12097 hashitem_T *hi; 12098 int todo; 12099 12100 d = argvars[0].vval.v_dict; 12101 if (d != NULL) 12102 { 12103 todo = d->dv_hashtab.ht_used; 12104 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 12105 { 12106 if (!HASHITEM_EMPTY(hi)) 12107 { 12108 --todo; 12109 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 12110 if (first) 12111 { 12112 n = i; 12113 first = FALSE; 12114 } 12115 else if (domax ? i > n : i < n) 12116 n = i; 12117 } 12118 } 12119 } 12120 } 12121 else 12122 EMSG(_(e_listdictarg)); 12123 rettv->vval.v_number = error ? 0 : n; 12124 } 12125 12126 /* 12127 * "max()" function 12128 */ 12129 static void 12130 f_max(argvars, rettv) 12131 typval_T *argvars; 12132 typval_T *rettv; 12133 { 12134 max_min(argvars, rettv, TRUE); 12135 } 12136 12137 /* 12138 * "min()" function 12139 */ 12140 static void 12141 f_min(argvars, rettv) 12142 typval_T *argvars; 12143 typval_T *rettv; 12144 { 12145 max_min(argvars, rettv, FALSE); 12146 } 12147 12148 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 12149 12150 /* 12151 * Create the directory in which "dir" is located, and higher levels when 12152 * needed. 12153 */ 12154 static int 12155 mkdir_recurse(dir, prot) 12156 char_u *dir; 12157 int prot; 12158 { 12159 char_u *p; 12160 char_u *updir; 12161 int r = FAIL; 12162 12163 /* Get end of directory name in "dir". 12164 * We're done when it's "/" or "c:/". */ 12165 p = gettail_sep(dir); 12166 if (p <= get_past_head(dir)) 12167 return OK; 12168 12169 /* If the directory exists we're done. Otherwise: create it.*/ 12170 updir = vim_strnsave(dir, (int)(p - dir)); 12171 if (updir == NULL) 12172 return FAIL; 12173 if (mch_isdir(updir)) 12174 r = OK; 12175 else if (mkdir_recurse(updir, prot) == OK) 12176 r = vim_mkdir_emsg(updir, prot); 12177 vim_free(updir); 12178 return r; 12179 } 12180 12181 #ifdef vim_mkdir 12182 /* 12183 * "mkdir()" function 12184 */ 12185 static void 12186 f_mkdir(argvars, rettv) 12187 typval_T *argvars; 12188 typval_T *rettv; 12189 { 12190 char_u *dir; 12191 char_u buf[NUMBUFLEN]; 12192 int prot = 0755; 12193 12194 rettv->vval.v_number = FAIL; 12195 if (check_restricted() || check_secure()) 12196 return; 12197 12198 dir = get_tv_string_buf(&argvars[0], buf); 12199 if (argvars[1].v_type != VAR_UNKNOWN) 12200 { 12201 if (argvars[2].v_type != VAR_UNKNOWN) 12202 prot = get_tv_number_chk(&argvars[2], NULL); 12203 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 12204 mkdir_recurse(dir, prot); 12205 } 12206 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 12207 } 12208 #endif 12209 12210 /* 12211 * "mode()" function 12212 */ 12213 /*ARGSUSED*/ 12214 static void 12215 f_mode(argvars, rettv) 12216 typval_T *argvars; 12217 typval_T *rettv; 12218 { 12219 char_u buf[2]; 12220 12221 #ifdef FEAT_VISUAL 12222 if (VIsual_active) 12223 { 12224 if (VIsual_select) 12225 buf[0] = VIsual_mode + 's' - 'v'; 12226 else 12227 buf[0] = VIsual_mode; 12228 } 12229 else 12230 #endif 12231 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 12232 buf[0] = 'r'; 12233 else if (State & INSERT) 12234 { 12235 if (State & REPLACE_FLAG) 12236 buf[0] = 'R'; 12237 else 12238 buf[0] = 'i'; 12239 } 12240 else if (State & CMDLINE) 12241 buf[0] = 'c'; 12242 else 12243 buf[0] = 'n'; 12244 12245 buf[1] = NUL; 12246 rettv->vval.v_string = vim_strsave(buf); 12247 rettv->v_type = VAR_STRING; 12248 } 12249 12250 /* 12251 * "nextnonblank()" function 12252 */ 12253 static void 12254 f_nextnonblank(argvars, rettv) 12255 typval_T *argvars; 12256 typval_T *rettv; 12257 { 12258 linenr_T lnum; 12259 12260 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12261 { 12262 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12263 { 12264 lnum = 0; 12265 break; 12266 } 12267 if (*skipwhite(ml_get(lnum)) != NUL) 12268 break; 12269 } 12270 rettv->vval.v_number = lnum; 12271 } 12272 12273 /* 12274 * "nr2char()" function 12275 */ 12276 static void 12277 f_nr2char(argvars, rettv) 12278 typval_T *argvars; 12279 typval_T *rettv; 12280 { 12281 char_u buf[NUMBUFLEN]; 12282 12283 #ifdef FEAT_MBYTE 12284 if (has_mbyte) 12285 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12286 else 12287 #endif 12288 { 12289 buf[0] = (char_u)get_tv_number(&argvars[0]); 12290 buf[1] = NUL; 12291 } 12292 rettv->v_type = VAR_STRING; 12293 rettv->vval.v_string = vim_strsave(buf); 12294 } 12295 12296 /* 12297 * "prevnonblank()" function 12298 */ 12299 static void 12300 f_prevnonblank(argvars, rettv) 12301 typval_T *argvars; 12302 typval_T *rettv; 12303 { 12304 linenr_T lnum; 12305 12306 lnum = get_tv_lnum(argvars); 12307 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12308 lnum = 0; 12309 else 12310 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12311 --lnum; 12312 rettv->vval.v_number = lnum; 12313 } 12314 12315 #ifdef HAVE_STDARG_H 12316 /* This dummy va_list is here because: 12317 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12318 * - locally in the function results in a "used before set" warning 12319 * - using va_start() to initialize it gives "function with fixed args" error */ 12320 static va_list ap; 12321 #endif 12322 12323 /* 12324 * "printf()" function 12325 */ 12326 static void 12327 f_printf(argvars, rettv) 12328 typval_T *argvars; 12329 typval_T *rettv; 12330 { 12331 rettv->v_type = VAR_STRING; 12332 rettv->vval.v_string = NULL; 12333 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12334 { 12335 char_u buf[NUMBUFLEN]; 12336 int len; 12337 char_u *s; 12338 int saved_did_emsg = did_emsg; 12339 char *fmt; 12340 12341 /* Get the required length, allocate the buffer and do it for real. */ 12342 did_emsg = FALSE; 12343 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12344 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12345 if (!did_emsg) 12346 { 12347 s = alloc(len + 1); 12348 if (s != NULL) 12349 { 12350 rettv->vval.v_string = s; 12351 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12352 } 12353 } 12354 did_emsg |= saved_did_emsg; 12355 } 12356 #endif 12357 } 12358 12359 /* 12360 * "pumvisible()" function 12361 */ 12362 /*ARGSUSED*/ 12363 static void 12364 f_pumvisible(argvars, rettv) 12365 typval_T *argvars; 12366 typval_T *rettv; 12367 { 12368 rettv->vval.v_number = 0; 12369 #ifdef FEAT_INS_EXPAND 12370 if (pum_visible()) 12371 rettv->vval.v_number = 1; 12372 #endif 12373 } 12374 12375 /* 12376 * "range()" function 12377 */ 12378 static void 12379 f_range(argvars, rettv) 12380 typval_T *argvars; 12381 typval_T *rettv; 12382 { 12383 long start; 12384 long end; 12385 long stride = 1; 12386 long i; 12387 int error = FALSE; 12388 12389 start = get_tv_number_chk(&argvars[0], &error); 12390 if (argvars[1].v_type == VAR_UNKNOWN) 12391 { 12392 end = start - 1; 12393 start = 0; 12394 } 12395 else 12396 { 12397 end = get_tv_number_chk(&argvars[1], &error); 12398 if (argvars[2].v_type != VAR_UNKNOWN) 12399 stride = get_tv_number_chk(&argvars[2], &error); 12400 } 12401 12402 rettv->vval.v_number = 0; 12403 if (error) 12404 return; /* type error; errmsg already given */ 12405 if (stride == 0) 12406 EMSG(_("E726: Stride is zero")); 12407 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12408 EMSG(_("E727: Start past end")); 12409 else 12410 { 12411 if (rettv_list_alloc(rettv) == OK) 12412 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12413 if (list_append_number(rettv->vval.v_list, 12414 (varnumber_T)i) == FAIL) 12415 break; 12416 } 12417 } 12418 12419 /* 12420 * "readfile()" function 12421 */ 12422 static void 12423 f_readfile(argvars, rettv) 12424 typval_T *argvars; 12425 typval_T *rettv; 12426 { 12427 int binary = FALSE; 12428 char_u *fname; 12429 FILE *fd; 12430 listitem_T *li; 12431 #define FREAD_SIZE 200 /* optimized for text lines */ 12432 char_u buf[FREAD_SIZE]; 12433 int readlen; /* size of last fread() */ 12434 int buflen; /* nr of valid chars in buf[] */ 12435 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12436 int tolist; /* first byte in buf[] still to be put in list */ 12437 int chop; /* how many CR to chop off */ 12438 char_u *prev = NULL; /* previously read bytes, if any */ 12439 int prevlen = 0; /* length of "prev" if not NULL */ 12440 char_u *s; 12441 int len; 12442 long maxline = MAXLNUM; 12443 long cnt = 0; 12444 12445 if (argvars[1].v_type != VAR_UNKNOWN) 12446 { 12447 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12448 binary = TRUE; 12449 if (argvars[2].v_type != VAR_UNKNOWN) 12450 maxline = get_tv_number(&argvars[2]); 12451 } 12452 12453 if (rettv_list_alloc(rettv) == FAIL) 12454 return; 12455 12456 /* Always open the file in binary mode, library functions have a mind of 12457 * their own about CR-LF conversion. */ 12458 fname = get_tv_string(&argvars[0]); 12459 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12460 { 12461 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12462 return; 12463 } 12464 12465 filtd = 0; 12466 while (cnt < maxline || maxline < 0) 12467 { 12468 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12469 buflen = filtd + readlen; 12470 tolist = 0; 12471 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12472 { 12473 if (buf[filtd] == '\n' || readlen <= 0) 12474 { 12475 /* Only when in binary mode add an empty list item when the 12476 * last line ends in a '\n'. */ 12477 if (!binary && readlen == 0 && filtd == 0) 12478 break; 12479 12480 /* Found end-of-line or end-of-file: add a text line to the 12481 * list. */ 12482 chop = 0; 12483 if (!binary) 12484 while (filtd - chop - 1 >= tolist 12485 && buf[filtd - chop - 1] == '\r') 12486 ++chop; 12487 len = filtd - tolist - chop; 12488 if (prev == NULL) 12489 s = vim_strnsave(buf + tolist, len); 12490 else 12491 { 12492 s = alloc((unsigned)(prevlen + len + 1)); 12493 if (s != NULL) 12494 { 12495 mch_memmove(s, prev, prevlen); 12496 vim_free(prev); 12497 prev = NULL; 12498 mch_memmove(s + prevlen, buf + tolist, len); 12499 s[prevlen + len] = NUL; 12500 } 12501 } 12502 tolist = filtd + 1; 12503 12504 li = listitem_alloc(); 12505 if (li == NULL) 12506 { 12507 vim_free(s); 12508 break; 12509 } 12510 li->li_tv.v_type = VAR_STRING; 12511 li->li_tv.v_lock = 0; 12512 li->li_tv.vval.v_string = s; 12513 list_append(rettv->vval.v_list, li); 12514 12515 if (++cnt >= maxline && maxline >= 0) 12516 break; 12517 if (readlen <= 0) 12518 break; 12519 } 12520 else if (buf[filtd] == NUL) 12521 buf[filtd] = '\n'; 12522 } 12523 if (readlen <= 0) 12524 break; 12525 12526 if (tolist == 0) 12527 { 12528 /* "buf" is full, need to move text to an allocated buffer */ 12529 if (prev == NULL) 12530 { 12531 prev = vim_strnsave(buf, buflen); 12532 prevlen = buflen; 12533 } 12534 else 12535 { 12536 s = alloc((unsigned)(prevlen + buflen)); 12537 if (s != NULL) 12538 { 12539 mch_memmove(s, prev, prevlen); 12540 mch_memmove(s + prevlen, buf, buflen); 12541 vim_free(prev); 12542 prev = s; 12543 prevlen += buflen; 12544 } 12545 } 12546 filtd = 0; 12547 } 12548 else 12549 { 12550 mch_memmove(buf, buf + tolist, buflen - tolist); 12551 filtd -= tolist; 12552 } 12553 } 12554 12555 /* 12556 * For a negative line count use only the lines at the end of the file, 12557 * free the rest. 12558 */ 12559 if (maxline < 0) 12560 while (cnt > -maxline) 12561 { 12562 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 12563 --cnt; 12564 } 12565 12566 vim_free(prev); 12567 fclose(fd); 12568 } 12569 12570 12571 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12572 static void make_connection __ARGS((void)); 12573 static int check_connection __ARGS((void)); 12574 12575 static void 12576 make_connection() 12577 { 12578 if (X_DISPLAY == NULL 12579 # ifdef FEAT_GUI 12580 && !gui.in_use 12581 # endif 12582 ) 12583 { 12584 x_force_connect = TRUE; 12585 setup_term_clip(); 12586 x_force_connect = FALSE; 12587 } 12588 } 12589 12590 static int 12591 check_connection() 12592 { 12593 make_connection(); 12594 if (X_DISPLAY == NULL) 12595 { 12596 EMSG(_("E240: No connection to Vim server")); 12597 return FAIL; 12598 } 12599 return OK; 12600 } 12601 #endif 12602 12603 #ifdef FEAT_CLIENTSERVER 12604 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12605 12606 static void 12607 remote_common(argvars, rettv, expr) 12608 typval_T *argvars; 12609 typval_T *rettv; 12610 int expr; 12611 { 12612 char_u *server_name; 12613 char_u *keys; 12614 char_u *r = NULL; 12615 char_u buf[NUMBUFLEN]; 12616 # ifdef WIN32 12617 HWND w; 12618 # else 12619 Window w; 12620 # endif 12621 12622 if (check_restricted() || check_secure()) 12623 return; 12624 12625 # ifdef FEAT_X11 12626 if (check_connection() == FAIL) 12627 return; 12628 # endif 12629 12630 server_name = get_tv_string_chk(&argvars[0]); 12631 if (server_name == NULL) 12632 return; /* type error; errmsg already given */ 12633 keys = get_tv_string_buf(&argvars[1], buf); 12634 # ifdef WIN32 12635 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12636 # else 12637 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12638 < 0) 12639 # endif 12640 { 12641 if (r != NULL) 12642 EMSG(r); /* sending worked but evaluation failed */ 12643 else 12644 EMSG2(_("E241: Unable to send to %s"), server_name); 12645 return; 12646 } 12647 12648 rettv->vval.v_string = r; 12649 12650 if (argvars[2].v_type != VAR_UNKNOWN) 12651 { 12652 dictitem_T v; 12653 char_u str[30]; 12654 char_u *idvar; 12655 12656 sprintf((char *)str, "0x%x", (unsigned int)w); 12657 v.di_tv.v_type = VAR_STRING; 12658 v.di_tv.vval.v_string = vim_strsave(str); 12659 idvar = get_tv_string_chk(&argvars[2]); 12660 if (idvar != NULL) 12661 set_var(idvar, &v.di_tv, FALSE); 12662 vim_free(v.di_tv.vval.v_string); 12663 } 12664 } 12665 #endif 12666 12667 /* 12668 * "remote_expr()" function 12669 */ 12670 /*ARGSUSED*/ 12671 static void 12672 f_remote_expr(argvars, rettv) 12673 typval_T *argvars; 12674 typval_T *rettv; 12675 { 12676 rettv->v_type = VAR_STRING; 12677 rettv->vval.v_string = NULL; 12678 #ifdef FEAT_CLIENTSERVER 12679 remote_common(argvars, rettv, TRUE); 12680 #endif 12681 } 12682 12683 /* 12684 * "remote_foreground()" function 12685 */ 12686 /*ARGSUSED*/ 12687 static void 12688 f_remote_foreground(argvars, rettv) 12689 typval_T *argvars; 12690 typval_T *rettv; 12691 { 12692 rettv->vval.v_number = 0; 12693 #ifdef FEAT_CLIENTSERVER 12694 # ifdef WIN32 12695 /* On Win32 it's done in this application. */ 12696 { 12697 char_u *server_name = get_tv_string_chk(&argvars[0]); 12698 12699 if (server_name != NULL) 12700 serverForeground(server_name); 12701 } 12702 # else 12703 /* Send a foreground() expression to the server. */ 12704 argvars[1].v_type = VAR_STRING; 12705 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12706 argvars[2].v_type = VAR_UNKNOWN; 12707 remote_common(argvars, rettv, TRUE); 12708 vim_free(argvars[1].vval.v_string); 12709 # endif 12710 #endif 12711 } 12712 12713 /*ARGSUSED*/ 12714 static void 12715 f_remote_peek(argvars, rettv) 12716 typval_T *argvars; 12717 typval_T *rettv; 12718 { 12719 #ifdef FEAT_CLIENTSERVER 12720 dictitem_T v; 12721 char_u *s = NULL; 12722 # ifdef WIN32 12723 int n = 0; 12724 # endif 12725 char_u *serverid; 12726 12727 if (check_restricted() || check_secure()) 12728 { 12729 rettv->vval.v_number = -1; 12730 return; 12731 } 12732 serverid = get_tv_string_chk(&argvars[0]); 12733 if (serverid == NULL) 12734 { 12735 rettv->vval.v_number = -1; 12736 return; /* type error; errmsg already given */ 12737 } 12738 # ifdef WIN32 12739 sscanf(serverid, "%x", &n); 12740 if (n == 0) 12741 rettv->vval.v_number = -1; 12742 else 12743 { 12744 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12745 rettv->vval.v_number = (s != NULL); 12746 } 12747 # else 12748 rettv->vval.v_number = 0; 12749 if (check_connection() == FAIL) 12750 return; 12751 12752 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12753 serverStrToWin(serverid), &s); 12754 # endif 12755 12756 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12757 { 12758 char_u *retvar; 12759 12760 v.di_tv.v_type = VAR_STRING; 12761 v.di_tv.vval.v_string = vim_strsave(s); 12762 retvar = get_tv_string_chk(&argvars[1]); 12763 if (retvar != NULL) 12764 set_var(retvar, &v.di_tv, FALSE); 12765 vim_free(v.di_tv.vval.v_string); 12766 } 12767 #else 12768 rettv->vval.v_number = -1; 12769 #endif 12770 } 12771 12772 /*ARGSUSED*/ 12773 static void 12774 f_remote_read(argvars, rettv) 12775 typval_T *argvars; 12776 typval_T *rettv; 12777 { 12778 char_u *r = NULL; 12779 12780 #ifdef FEAT_CLIENTSERVER 12781 char_u *serverid = get_tv_string_chk(&argvars[0]); 12782 12783 if (serverid != NULL && !check_restricted() && !check_secure()) 12784 { 12785 # ifdef WIN32 12786 /* The server's HWND is encoded in the 'id' parameter */ 12787 int n = 0; 12788 12789 sscanf(serverid, "%x", &n); 12790 if (n != 0) 12791 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12792 if (r == NULL) 12793 # else 12794 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12795 serverStrToWin(serverid), &r, FALSE) < 0) 12796 # endif 12797 EMSG(_("E277: Unable to read a server reply")); 12798 } 12799 #endif 12800 rettv->v_type = VAR_STRING; 12801 rettv->vval.v_string = r; 12802 } 12803 12804 /* 12805 * "remote_send()" function 12806 */ 12807 /*ARGSUSED*/ 12808 static void 12809 f_remote_send(argvars, rettv) 12810 typval_T *argvars; 12811 typval_T *rettv; 12812 { 12813 rettv->v_type = VAR_STRING; 12814 rettv->vval.v_string = NULL; 12815 #ifdef FEAT_CLIENTSERVER 12816 remote_common(argvars, rettv, FALSE); 12817 #endif 12818 } 12819 12820 /* 12821 * "remove()" function 12822 */ 12823 static void 12824 f_remove(argvars, rettv) 12825 typval_T *argvars; 12826 typval_T *rettv; 12827 { 12828 list_T *l; 12829 listitem_T *item, *item2; 12830 listitem_T *li; 12831 long idx; 12832 long end; 12833 char_u *key; 12834 dict_T *d; 12835 dictitem_T *di; 12836 12837 rettv->vval.v_number = 0; 12838 if (argvars[0].v_type == VAR_DICT) 12839 { 12840 if (argvars[2].v_type != VAR_UNKNOWN) 12841 EMSG2(_(e_toomanyarg), "remove()"); 12842 else if ((d = argvars[0].vval.v_dict) != NULL 12843 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12844 { 12845 key = get_tv_string_chk(&argvars[1]); 12846 if (key != NULL) 12847 { 12848 di = dict_find(d, key, -1); 12849 if (di == NULL) 12850 EMSG2(_(e_dictkey), key); 12851 else 12852 { 12853 *rettv = di->di_tv; 12854 init_tv(&di->di_tv); 12855 dictitem_remove(d, di); 12856 } 12857 } 12858 } 12859 } 12860 else if (argvars[0].v_type != VAR_LIST) 12861 EMSG2(_(e_listdictarg), "remove()"); 12862 else if ((l = argvars[0].vval.v_list) != NULL 12863 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12864 { 12865 int error = FALSE; 12866 12867 idx = get_tv_number_chk(&argvars[1], &error); 12868 if (error) 12869 ; /* type error: do nothing, errmsg already given */ 12870 else if ((item = list_find(l, idx)) == NULL) 12871 EMSGN(_(e_listidx), idx); 12872 else 12873 { 12874 if (argvars[2].v_type == VAR_UNKNOWN) 12875 { 12876 /* Remove one item, return its value. */ 12877 list_remove(l, item, item); 12878 *rettv = item->li_tv; 12879 vim_free(item); 12880 } 12881 else 12882 { 12883 /* Remove range of items, return list with values. */ 12884 end = get_tv_number_chk(&argvars[2], &error); 12885 if (error) 12886 ; /* type error: do nothing */ 12887 else if ((item2 = list_find(l, end)) == NULL) 12888 EMSGN(_(e_listidx), end); 12889 else 12890 { 12891 int cnt = 0; 12892 12893 for (li = item; li != NULL; li = li->li_next) 12894 { 12895 ++cnt; 12896 if (li == item2) 12897 break; 12898 } 12899 if (li == NULL) /* didn't find "item2" after "item" */ 12900 EMSG(_(e_invrange)); 12901 else 12902 { 12903 list_remove(l, item, item2); 12904 if (rettv_list_alloc(rettv) == OK) 12905 { 12906 l = rettv->vval.v_list; 12907 l->lv_first = item; 12908 l->lv_last = item2; 12909 item->li_prev = NULL; 12910 item2->li_next = NULL; 12911 l->lv_len = cnt; 12912 } 12913 } 12914 } 12915 } 12916 } 12917 } 12918 } 12919 12920 /* 12921 * "rename({from}, {to})" function 12922 */ 12923 static void 12924 f_rename(argvars, rettv) 12925 typval_T *argvars; 12926 typval_T *rettv; 12927 { 12928 char_u buf[NUMBUFLEN]; 12929 12930 if (check_restricted() || check_secure()) 12931 rettv->vval.v_number = -1; 12932 else 12933 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12934 get_tv_string_buf(&argvars[1], buf)); 12935 } 12936 12937 /* 12938 * "repeat()" function 12939 */ 12940 /*ARGSUSED*/ 12941 static void 12942 f_repeat(argvars, rettv) 12943 typval_T *argvars; 12944 typval_T *rettv; 12945 { 12946 char_u *p; 12947 int n; 12948 int slen; 12949 int len; 12950 char_u *r; 12951 int i; 12952 12953 n = get_tv_number(&argvars[1]); 12954 if (argvars[0].v_type == VAR_LIST) 12955 { 12956 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 12957 while (n-- > 0) 12958 if (list_extend(rettv->vval.v_list, 12959 argvars[0].vval.v_list, NULL) == FAIL) 12960 break; 12961 } 12962 else 12963 { 12964 p = get_tv_string(&argvars[0]); 12965 rettv->v_type = VAR_STRING; 12966 rettv->vval.v_string = NULL; 12967 12968 slen = (int)STRLEN(p); 12969 len = slen * n; 12970 if (len <= 0) 12971 return; 12972 12973 r = alloc(len + 1); 12974 if (r != NULL) 12975 { 12976 for (i = 0; i < n; i++) 12977 mch_memmove(r + i * slen, p, (size_t)slen); 12978 r[len] = NUL; 12979 } 12980 12981 rettv->vval.v_string = r; 12982 } 12983 } 12984 12985 /* 12986 * "resolve()" function 12987 */ 12988 static void 12989 f_resolve(argvars, rettv) 12990 typval_T *argvars; 12991 typval_T *rettv; 12992 { 12993 char_u *p; 12994 12995 p = get_tv_string(&argvars[0]); 12996 #ifdef FEAT_SHORTCUT 12997 { 12998 char_u *v = NULL; 12999 13000 v = mch_resolve_shortcut(p); 13001 if (v != NULL) 13002 rettv->vval.v_string = v; 13003 else 13004 rettv->vval.v_string = vim_strsave(p); 13005 } 13006 #else 13007 # ifdef HAVE_READLINK 13008 { 13009 char_u buf[MAXPATHL + 1]; 13010 char_u *cpy; 13011 int len; 13012 char_u *remain = NULL; 13013 char_u *q; 13014 int is_relative_to_current = FALSE; 13015 int has_trailing_pathsep = FALSE; 13016 int limit = 100; 13017 13018 p = vim_strsave(p); 13019 13020 if (p[0] == '.' && (vim_ispathsep(p[1]) 13021 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 13022 is_relative_to_current = TRUE; 13023 13024 len = STRLEN(p); 13025 if (len > 0 && after_pathsep(p, p + len)) 13026 has_trailing_pathsep = TRUE; 13027 13028 q = getnextcomp(p); 13029 if (*q != NUL) 13030 { 13031 /* Separate the first path component in "p", and keep the 13032 * remainder (beginning with the path separator). */ 13033 remain = vim_strsave(q - 1); 13034 q[-1] = NUL; 13035 } 13036 13037 for (;;) 13038 { 13039 for (;;) 13040 { 13041 len = readlink((char *)p, (char *)buf, MAXPATHL); 13042 if (len <= 0) 13043 break; 13044 buf[len] = NUL; 13045 13046 if (limit-- == 0) 13047 { 13048 vim_free(p); 13049 vim_free(remain); 13050 EMSG(_("E655: Too many symbolic links (cycle?)")); 13051 rettv->vval.v_string = NULL; 13052 goto fail; 13053 } 13054 13055 /* Ensure that the result will have a trailing path separator 13056 * if the argument has one. */ 13057 if (remain == NULL && has_trailing_pathsep) 13058 add_pathsep(buf); 13059 13060 /* Separate the first path component in the link value and 13061 * concatenate the remainders. */ 13062 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 13063 if (*q != NUL) 13064 { 13065 if (remain == NULL) 13066 remain = vim_strsave(q - 1); 13067 else 13068 { 13069 cpy = concat_str(q - 1, remain); 13070 if (cpy != NULL) 13071 { 13072 vim_free(remain); 13073 remain = cpy; 13074 } 13075 } 13076 q[-1] = NUL; 13077 } 13078 13079 q = gettail(p); 13080 if (q > p && *q == NUL) 13081 { 13082 /* Ignore trailing path separator. */ 13083 q[-1] = NUL; 13084 q = gettail(p); 13085 } 13086 if (q > p && !mch_isFullName(buf)) 13087 { 13088 /* symlink is relative to directory of argument */ 13089 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 13090 if (cpy != NULL) 13091 { 13092 STRCPY(cpy, p); 13093 STRCPY(gettail(cpy), buf); 13094 vim_free(p); 13095 p = cpy; 13096 } 13097 } 13098 else 13099 { 13100 vim_free(p); 13101 p = vim_strsave(buf); 13102 } 13103 } 13104 13105 if (remain == NULL) 13106 break; 13107 13108 /* Append the first path component of "remain" to "p". */ 13109 q = getnextcomp(remain + 1); 13110 len = q - remain - (*q != NUL); 13111 cpy = vim_strnsave(p, STRLEN(p) + len); 13112 if (cpy != NULL) 13113 { 13114 STRNCAT(cpy, remain, len); 13115 vim_free(p); 13116 p = cpy; 13117 } 13118 /* Shorten "remain". */ 13119 if (*q != NUL) 13120 STRCPY(remain, q - 1); 13121 else 13122 { 13123 vim_free(remain); 13124 remain = NULL; 13125 } 13126 } 13127 13128 /* If the result is a relative path name, make it explicitly relative to 13129 * the current directory if and only if the argument had this form. */ 13130 if (!vim_ispathsep(*p)) 13131 { 13132 if (is_relative_to_current 13133 && *p != NUL 13134 && !(p[0] == '.' 13135 && (p[1] == NUL 13136 || vim_ispathsep(p[1]) 13137 || (p[1] == '.' 13138 && (p[2] == NUL 13139 || vim_ispathsep(p[2])))))) 13140 { 13141 /* Prepend "./". */ 13142 cpy = concat_str((char_u *)"./", p); 13143 if (cpy != NULL) 13144 { 13145 vim_free(p); 13146 p = cpy; 13147 } 13148 } 13149 else if (!is_relative_to_current) 13150 { 13151 /* Strip leading "./". */ 13152 q = p; 13153 while (q[0] == '.' && vim_ispathsep(q[1])) 13154 q += 2; 13155 if (q > p) 13156 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 13157 } 13158 } 13159 13160 /* Ensure that the result will have no trailing path separator 13161 * if the argument had none. But keep "/" or "//". */ 13162 if (!has_trailing_pathsep) 13163 { 13164 q = p + STRLEN(p); 13165 if (after_pathsep(p, q)) 13166 *gettail_sep(p) = NUL; 13167 } 13168 13169 rettv->vval.v_string = p; 13170 } 13171 # else 13172 rettv->vval.v_string = vim_strsave(p); 13173 # endif 13174 #endif 13175 13176 simplify_filename(rettv->vval.v_string); 13177 13178 #ifdef HAVE_READLINK 13179 fail: 13180 #endif 13181 rettv->v_type = VAR_STRING; 13182 } 13183 13184 /* 13185 * "reverse({list})" function 13186 */ 13187 static void 13188 f_reverse(argvars, rettv) 13189 typval_T *argvars; 13190 typval_T *rettv; 13191 { 13192 list_T *l; 13193 listitem_T *li, *ni; 13194 13195 rettv->vval.v_number = 0; 13196 if (argvars[0].v_type != VAR_LIST) 13197 EMSG2(_(e_listarg), "reverse()"); 13198 else if ((l = argvars[0].vval.v_list) != NULL 13199 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 13200 { 13201 li = l->lv_last; 13202 l->lv_first = l->lv_last = NULL; 13203 l->lv_len = 0; 13204 while (li != NULL) 13205 { 13206 ni = li->li_prev; 13207 list_append(l, li); 13208 li = ni; 13209 } 13210 rettv->vval.v_list = l; 13211 rettv->v_type = VAR_LIST; 13212 ++l->lv_refcount; 13213 } 13214 } 13215 13216 #define SP_NOMOVE 0x01 /* don't move cursor */ 13217 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 13218 #define SP_RETCOUNT 0x04 /* return matchcount */ 13219 #define SP_SETPCMARK 0x08 /* set previous context mark */ 13220 #define SP_START 0x10 /* accept match at start position */ 13221 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 13222 #define SP_END 0x40 /* leave cursor at end of match */ 13223 13224 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 13225 13226 /* 13227 * Get flags for a search function. 13228 * Possibly sets "p_ws". 13229 * Returns BACKWARD, FORWARD or zero (for an error). 13230 */ 13231 static int 13232 get_search_arg(varp, flagsp) 13233 typval_T *varp; 13234 int *flagsp; 13235 { 13236 int dir = FORWARD; 13237 char_u *flags; 13238 char_u nbuf[NUMBUFLEN]; 13239 int mask; 13240 13241 if (varp->v_type != VAR_UNKNOWN) 13242 { 13243 flags = get_tv_string_buf_chk(varp, nbuf); 13244 if (flags == NULL) 13245 return 0; /* type error; errmsg already given */ 13246 while (*flags != NUL) 13247 { 13248 switch (*flags) 13249 { 13250 case 'b': dir = BACKWARD; break; 13251 case 'w': p_ws = TRUE; break; 13252 case 'W': p_ws = FALSE; break; 13253 default: mask = 0; 13254 if (flagsp != NULL) 13255 switch (*flags) 13256 { 13257 case 'c': mask = SP_START; break; 13258 case 'e': mask = SP_END; break; 13259 case 'm': mask = SP_RETCOUNT; break; 13260 case 'n': mask = SP_NOMOVE; break; 13261 case 'p': mask = SP_SUBPAT; break; 13262 case 'r': mask = SP_REPEAT; break; 13263 case 's': mask = SP_SETPCMARK; break; 13264 } 13265 if (mask == 0) 13266 { 13267 EMSG2(_(e_invarg2), flags); 13268 dir = 0; 13269 } 13270 else 13271 *flagsp |= mask; 13272 } 13273 if (dir == 0) 13274 break; 13275 ++flags; 13276 } 13277 } 13278 return dir; 13279 } 13280 13281 /* 13282 * Shared by search() and searchpos() functions 13283 */ 13284 static int 13285 search_cmn(argvars, match_pos, flagsp) 13286 typval_T *argvars; 13287 pos_T *match_pos; 13288 int *flagsp; 13289 { 13290 int flags; 13291 char_u *pat; 13292 pos_T pos; 13293 pos_T save_cursor; 13294 int save_p_ws = p_ws; 13295 int dir; 13296 int retval = 0; /* default: FAIL */ 13297 long lnum_stop = 0; 13298 int options = SEARCH_KEEP; 13299 int subpatnum; 13300 13301 pat = get_tv_string(&argvars[0]); 13302 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 13303 if (dir == 0) 13304 goto theend; 13305 flags = *flagsp; 13306 if (flags & SP_START) 13307 options |= SEARCH_START; 13308 if (flags & SP_END) 13309 options |= SEARCH_END; 13310 13311 /* Optional extra argument: line number to stop searching. */ 13312 if (argvars[1].v_type != VAR_UNKNOWN 13313 && argvars[2].v_type != VAR_UNKNOWN) 13314 { 13315 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 13316 if (lnum_stop < 0) 13317 goto theend; 13318 } 13319 13320 /* 13321 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 13322 * Check to make sure only those flags are set. 13323 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13324 * flags cannot be set. Check for that condition also. 13325 */ 13326 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 13327 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13328 { 13329 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13330 goto theend; 13331 } 13332 13333 pos = save_cursor = curwin->w_cursor; 13334 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13335 options, RE_SEARCH, (linenr_T)lnum_stop); 13336 if (subpatnum != FAIL) 13337 { 13338 if (flags & SP_SUBPAT) 13339 retval = subpatnum; 13340 else 13341 retval = pos.lnum; 13342 if (flags & SP_SETPCMARK) 13343 setpcmark(); 13344 curwin->w_cursor = pos; 13345 if (match_pos != NULL) 13346 { 13347 /* Store the match cursor position */ 13348 match_pos->lnum = pos.lnum; 13349 match_pos->col = pos.col + 1; 13350 } 13351 /* "/$" will put the cursor after the end of the line, may need to 13352 * correct that here */ 13353 check_cursor(); 13354 } 13355 13356 /* If 'n' flag is used: restore cursor position. */ 13357 if (flags & SP_NOMOVE) 13358 curwin->w_cursor = save_cursor; 13359 theend: 13360 p_ws = save_p_ws; 13361 13362 return retval; 13363 } 13364 13365 /* 13366 * "search()" function 13367 */ 13368 static void 13369 f_search(argvars, rettv) 13370 typval_T *argvars; 13371 typval_T *rettv; 13372 { 13373 int flags = 0; 13374 13375 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 13376 } 13377 13378 /* 13379 * "searchdecl()" function 13380 */ 13381 static void 13382 f_searchdecl(argvars, rettv) 13383 typval_T *argvars; 13384 typval_T *rettv; 13385 { 13386 int locally = 1; 13387 int thisblock = 0; 13388 int error = FALSE; 13389 char_u *name; 13390 13391 rettv->vval.v_number = 1; /* default: FAIL */ 13392 13393 name = get_tv_string_chk(&argvars[0]); 13394 if (argvars[1].v_type != VAR_UNKNOWN) 13395 { 13396 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13397 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13398 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13399 } 13400 if (!error && name != NULL) 13401 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13402 locally, thisblock, SEARCH_KEEP) == FAIL; 13403 } 13404 13405 /* 13406 * Used by searchpair() and searchpairpos() 13407 */ 13408 static int 13409 searchpair_cmn(argvars, match_pos) 13410 typval_T *argvars; 13411 pos_T *match_pos; 13412 { 13413 char_u *spat, *mpat, *epat; 13414 char_u *skip; 13415 int save_p_ws = p_ws; 13416 int dir; 13417 int flags = 0; 13418 char_u nbuf1[NUMBUFLEN]; 13419 char_u nbuf2[NUMBUFLEN]; 13420 char_u nbuf3[NUMBUFLEN]; 13421 int retval = 0; /* default: FAIL */ 13422 long lnum_stop = 0; 13423 13424 /* Get the three pattern arguments: start, middle, end. */ 13425 spat = get_tv_string_chk(&argvars[0]); 13426 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13427 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13428 if (spat == NULL || mpat == NULL || epat == NULL) 13429 goto theend; /* type error */ 13430 13431 /* Handle the optional fourth argument: flags */ 13432 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13433 if (dir == 0) 13434 goto theend; 13435 13436 /* Don't accept SP_END or SP_SUBPAT. 13437 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13438 */ 13439 if ((flags & (SP_END | SP_SUBPAT)) != 0 13440 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13441 { 13442 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 13443 goto theend; 13444 } 13445 13446 /* Optional fifth argument: skip expression */ 13447 if (argvars[3].v_type == VAR_UNKNOWN 13448 || argvars[4].v_type == VAR_UNKNOWN) 13449 skip = (char_u *)""; 13450 else 13451 { 13452 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13453 if (argvars[5].v_type != VAR_UNKNOWN) 13454 { 13455 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 13456 if (lnum_stop < 0) 13457 goto theend; 13458 } 13459 } 13460 if (skip == NULL) 13461 goto theend; /* type error */ 13462 13463 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 13464 match_pos, lnum_stop); 13465 13466 theend: 13467 p_ws = save_p_ws; 13468 13469 return retval; 13470 } 13471 13472 /* 13473 * "searchpair()" function 13474 */ 13475 static void 13476 f_searchpair(argvars, rettv) 13477 typval_T *argvars; 13478 typval_T *rettv; 13479 { 13480 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 13481 } 13482 13483 /* 13484 * "searchpairpos()" function 13485 */ 13486 static void 13487 f_searchpairpos(argvars, rettv) 13488 typval_T *argvars; 13489 typval_T *rettv; 13490 { 13491 pos_T match_pos; 13492 int lnum = 0; 13493 int col = 0; 13494 13495 rettv->vval.v_number = 0; 13496 13497 if (rettv_list_alloc(rettv) == FAIL) 13498 return; 13499 13500 if (searchpair_cmn(argvars, &match_pos) > 0) 13501 { 13502 lnum = match_pos.lnum; 13503 col = match_pos.col; 13504 } 13505 13506 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 13507 list_append_number(rettv->vval.v_list, (varnumber_T)col); 13508 } 13509 13510 /* 13511 * Search for a start/middle/end thing. 13512 * Used by searchpair(), see its documentation for the details. 13513 * Returns 0 or -1 for no match, 13514 */ 13515 long 13516 do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, lnum_stop) 13517 char_u *spat; /* start pattern */ 13518 char_u *mpat; /* middle pattern */ 13519 char_u *epat; /* end pattern */ 13520 int dir; /* BACKWARD or FORWARD */ 13521 char_u *skip; /* skip expression */ 13522 int flags; /* SP_SETPCMARK and other SP_ values */ 13523 pos_T *match_pos; 13524 linenr_T lnum_stop; /* stop at this line if not zero */ 13525 { 13526 char_u *save_cpo; 13527 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13528 long retval = 0; 13529 pos_T pos; 13530 pos_T firstpos; 13531 pos_T foundpos; 13532 pos_T save_cursor; 13533 pos_T save_pos; 13534 int n; 13535 int r; 13536 int nest = 1; 13537 int err; 13538 int options = SEARCH_KEEP; 13539 13540 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13541 save_cpo = p_cpo; 13542 p_cpo = (char_u *)""; 13543 13544 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13545 * start/middle/end (pat3, for the top pair). */ 13546 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13547 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13548 if (pat2 == NULL || pat3 == NULL) 13549 goto theend; 13550 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13551 if (*mpat == NUL) 13552 STRCPY(pat3, pat2); 13553 else 13554 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13555 spat, epat, mpat); 13556 if (flags & SP_START) 13557 options |= SEARCH_START; 13558 13559 save_cursor = curwin->w_cursor; 13560 pos = curwin->w_cursor; 13561 clearpos(&firstpos); 13562 clearpos(&foundpos); 13563 pat = pat3; 13564 for (;;) 13565 { 13566 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13567 options, RE_SEARCH, lnum_stop); 13568 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13569 /* didn't find it or found the first match again: FAIL */ 13570 break; 13571 13572 if (firstpos.lnum == 0) 13573 firstpos = pos; 13574 if (equalpos(pos, foundpos)) 13575 { 13576 /* Found the same position again. Can happen with a pattern that 13577 * has "\zs" at the end and searching backwards. Advance one 13578 * character and try again. */ 13579 if (dir == BACKWARD) 13580 decl(&pos); 13581 else 13582 incl(&pos); 13583 } 13584 foundpos = pos; 13585 13586 /* If the skip pattern matches, ignore this match. */ 13587 if (*skip != NUL) 13588 { 13589 save_pos = curwin->w_cursor; 13590 curwin->w_cursor = pos; 13591 r = eval_to_bool(skip, &err, NULL, FALSE); 13592 curwin->w_cursor = save_pos; 13593 if (err) 13594 { 13595 /* Evaluating {skip} caused an error, break here. */ 13596 curwin->w_cursor = save_cursor; 13597 retval = -1; 13598 break; 13599 } 13600 if (r) 13601 continue; 13602 } 13603 13604 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13605 { 13606 /* Found end when searching backwards or start when searching 13607 * forward: nested pair. */ 13608 ++nest; 13609 pat = pat2; /* nested, don't search for middle */ 13610 } 13611 else 13612 { 13613 /* Found end when searching forward or start when searching 13614 * backward: end of (nested) pair; or found middle in outer pair. */ 13615 if (--nest == 1) 13616 pat = pat3; /* outer level, search for middle */ 13617 } 13618 13619 if (nest == 0) 13620 { 13621 /* Found the match: return matchcount or line number. */ 13622 if (flags & SP_RETCOUNT) 13623 ++retval; 13624 else 13625 retval = pos.lnum; 13626 if (flags & SP_SETPCMARK) 13627 setpcmark(); 13628 curwin->w_cursor = pos; 13629 if (!(flags & SP_REPEAT)) 13630 break; 13631 nest = 1; /* search for next unmatched */ 13632 } 13633 } 13634 13635 if (match_pos != NULL) 13636 { 13637 /* Store the match cursor position */ 13638 match_pos->lnum = curwin->w_cursor.lnum; 13639 match_pos->col = curwin->w_cursor.col + 1; 13640 } 13641 13642 /* If 'n' flag is used or search failed: restore cursor position. */ 13643 if ((flags & SP_NOMOVE) || retval == 0) 13644 curwin->w_cursor = save_cursor; 13645 13646 theend: 13647 vim_free(pat2); 13648 vim_free(pat3); 13649 p_cpo = save_cpo; 13650 13651 return retval; 13652 } 13653 13654 /* 13655 * "searchpos()" function 13656 */ 13657 static void 13658 f_searchpos(argvars, rettv) 13659 typval_T *argvars; 13660 typval_T *rettv; 13661 { 13662 pos_T match_pos; 13663 int lnum = 0; 13664 int col = 0; 13665 int n; 13666 int flags = 0; 13667 13668 rettv->vval.v_number = 0; 13669 13670 if (rettv_list_alloc(rettv) == FAIL) 13671 return; 13672 13673 n = search_cmn(argvars, &match_pos, &flags); 13674 if (n > 0) 13675 { 13676 lnum = match_pos.lnum; 13677 col = match_pos.col; 13678 } 13679 13680 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 13681 list_append_number(rettv->vval.v_list, (varnumber_T)col); 13682 if (flags & SP_SUBPAT) 13683 list_append_number(rettv->vval.v_list, (varnumber_T)n); 13684 } 13685 13686 13687 /*ARGSUSED*/ 13688 static void 13689 f_server2client(argvars, rettv) 13690 typval_T *argvars; 13691 typval_T *rettv; 13692 { 13693 #ifdef FEAT_CLIENTSERVER 13694 char_u buf[NUMBUFLEN]; 13695 char_u *server = get_tv_string_chk(&argvars[0]); 13696 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13697 13698 rettv->vval.v_number = -1; 13699 if (server == NULL || reply == NULL) 13700 return; 13701 if (check_restricted() || check_secure()) 13702 return; 13703 # ifdef FEAT_X11 13704 if (check_connection() == FAIL) 13705 return; 13706 # endif 13707 13708 if (serverSendReply(server, reply) < 0) 13709 { 13710 EMSG(_("E258: Unable to send to client")); 13711 return; 13712 } 13713 rettv->vval.v_number = 0; 13714 #else 13715 rettv->vval.v_number = -1; 13716 #endif 13717 } 13718 13719 /*ARGSUSED*/ 13720 static void 13721 f_serverlist(argvars, rettv) 13722 typval_T *argvars; 13723 typval_T *rettv; 13724 { 13725 char_u *r = NULL; 13726 13727 #ifdef FEAT_CLIENTSERVER 13728 # ifdef WIN32 13729 r = serverGetVimNames(); 13730 # else 13731 make_connection(); 13732 if (X_DISPLAY != NULL) 13733 r = serverGetVimNames(X_DISPLAY); 13734 # endif 13735 #endif 13736 rettv->v_type = VAR_STRING; 13737 rettv->vval.v_string = r; 13738 } 13739 13740 /* 13741 * "setbufvar()" function 13742 */ 13743 /*ARGSUSED*/ 13744 static void 13745 f_setbufvar(argvars, rettv) 13746 typval_T *argvars; 13747 typval_T *rettv; 13748 { 13749 buf_T *buf; 13750 #ifdef FEAT_AUTOCMD 13751 aco_save_T aco; 13752 #else 13753 buf_T *save_curbuf; 13754 #endif 13755 char_u *varname, *bufvarname; 13756 typval_T *varp; 13757 char_u nbuf[NUMBUFLEN]; 13758 13759 rettv->vval.v_number = 0; 13760 13761 if (check_restricted() || check_secure()) 13762 return; 13763 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13764 varname = get_tv_string_chk(&argvars[1]); 13765 buf = get_buf_tv(&argvars[0]); 13766 varp = &argvars[2]; 13767 13768 if (buf != NULL && varname != NULL && varp != NULL) 13769 { 13770 /* set curbuf to be our buf, temporarily */ 13771 #ifdef FEAT_AUTOCMD 13772 aucmd_prepbuf(&aco, buf); 13773 #else 13774 save_curbuf = curbuf; 13775 curbuf = buf; 13776 #endif 13777 13778 if (*varname == '&') 13779 { 13780 long numval; 13781 char_u *strval; 13782 int error = FALSE; 13783 13784 ++varname; 13785 numval = get_tv_number_chk(varp, &error); 13786 strval = get_tv_string_buf_chk(varp, nbuf); 13787 if (!error && strval != NULL) 13788 set_option_value(varname, numval, strval, OPT_LOCAL); 13789 } 13790 else 13791 { 13792 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13793 if (bufvarname != NULL) 13794 { 13795 STRCPY(bufvarname, "b:"); 13796 STRCPY(bufvarname + 2, varname); 13797 set_var(bufvarname, varp, TRUE); 13798 vim_free(bufvarname); 13799 } 13800 } 13801 13802 /* reset notion of buffer */ 13803 #ifdef FEAT_AUTOCMD 13804 aucmd_restbuf(&aco); 13805 #else 13806 curbuf = save_curbuf; 13807 #endif 13808 } 13809 } 13810 13811 /* 13812 * "setcmdpos()" function 13813 */ 13814 static void 13815 f_setcmdpos(argvars, rettv) 13816 typval_T *argvars; 13817 typval_T *rettv; 13818 { 13819 int pos = (int)get_tv_number(&argvars[0]) - 1; 13820 13821 if (pos >= 0) 13822 rettv->vval.v_number = set_cmdline_pos(pos); 13823 } 13824 13825 /* 13826 * "setline()" function 13827 */ 13828 static void 13829 f_setline(argvars, rettv) 13830 typval_T *argvars; 13831 typval_T *rettv; 13832 { 13833 linenr_T lnum; 13834 char_u *line = NULL; 13835 list_T *l = NULL; 13836 listitem_T *li = NULL; 13837 long added = 0; 13838 linenr_T lcount = curbuf->b_ml.ml_line_count; 13839 13840 lnum = get_tv_lnum(&argvars[0]); 13841 if (argvars[1].v_type == VAR_LIST) 13842 { 13843 l = argvars[1].vval.v_list; 13844 li = l->lv_first; 13845 } 13846 else 13847 line = get_tv_string_chk(&argvars[1]); 13848 13849 rettv->vval.v_number = 0; /* OK */ 13850 for (;;) 13851 { 13852 if (l != NULL) 13853 { 13854 /* list argument, get next string */ 13855 if (li == NULL) 13856 break; 13857 line = get_tv_string_chk(&li->li_tv); 13858 li = li->li_next; 13859 } 13860 13861 rettv->vval.v_number = 1; /* FAIL */ 13862 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13863 break; 13864 if (lnum <= curbuf->b_ml.ml_line_count) 13865 { 13866 /* existing line, replace it */ 13867 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13868 { 13869 changed_bytes(lnum, 0); 13870 check_cursor_col(); 13871 rettv->vval.v_number = 0; /* OK */ 13872 } 13873 } 13874 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13875 { 13876 /* lnum is one past the last line, append the line */ 13877 ++added; 13878 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13879 rettv->vval.v_number = 0; /* OK */ 13880 } 13881 13882 if (l == NULL) /* only one string argument */ 13883 break; 13884 ++lnum; 13885 } 13886 13887 if (added > 0) 13888 appended_lines_mark(lcount, added); 13889 } 13890 13891 /* 13892 * Used by "setqflist()" and "setloclist()" functions 13893 */ 13894 /*ARGSUSED*/ 13895 static void 13896 set_qf_ll_list(wp, list_arg, action_arg, rettv) 13897 win_T *wp; 13898 typval_T *list_arg; 13899 typval_T *action_arg; 13900 typval_T *rettv; 13901 { 13902 #ifdef FEAT_QUICKFIX 13903 char_u *act; 13904 int action = ' '; 13905 #endif 13906 13907 rettv->vval.v_number = -1; 13908 13909 #ifdef FEAT_QUICKFIX 13910 if (list_arg->v_type != VAR_LIST) 13911 EMSG(_(e_listreq)); 13912 else 13913 { 13914 list_T *l = list_arg->vval.v_list; 13915 13916 if (action_arg->v_type == VAR_STRING) 13917 { 13918 act = get_tv_string_chk(action_arg); 13919 if (act == NULL) 13920 return; /* type error; errmsg already given */ 13921 if (*act == 'a' || *act == 'r') 13922 action = *act; 13923 } 13924 13925 if (l != NULL && set_errorlist(wp, l, action) == OK) 13926 rettv->vval.v_number = 0; 13927 } 13928 #endif 13929 } 13930 13931 /* 13932 * "setloclist()" function 13933 */ 13934 /*ARGSUSED*/ 13935 static void 13936 f_setloclist(argvars, rettv) 13937 typval_T *argvars; 13938 typval_T *rettv; 13939 { 13940 win_T *win; 13941 13942 rettv->vval.v_number = -1; 13943 13944 win = find_win_by_nr(&argvars[0]); 13945 if (win != NULL) 13946 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 13947 } 13948 13949 /* 13950 * "setpos()" function 13951 */ 13952 /*ARGSUSED*/ 13953 static void 13954 f_setpos(argvars, rettv) 13955 typval_T *argvars; 13956 typval_T *rettv; 13957 { 13958 pos_T pos; 13959 int fnum; 13960 char_u *name; 13961 13962 name = get_tv_string_chk(argvars); 13963 if (name != NULL) 13964 { 13965 if (list2fpos(&argvars[1], &pos, &fnum) == OK) 13966 { 13967 --pos.col; 13968 if (name[0] == '.') /* cursor */ 13969 { 13970 if (fnum == curbuf->b_fnum) 13971 { 13972 curwin->w_cursor = pos; 13973 check_cursor(); 13974 } 13975 else 13976 EMSG(_(e_invarg)); 13977 } 13978 else if (name[0] == '\'') /* mark */ 13979 (void)setmark_pos(name[1], &pos, fnum); 13980 else 13981 EMSG(_(e_invarg)); 13982 } 13983 } 13984 } 13985 13986 /* 13987 * "setqflist()" function 13988 */ 13989 /*ARGSUSED*/ 13990 static void 13991 f_setqflist(argvars, rettv) 13992 typval_T *argvars; 13993 typval_T *rettv; 13994 { 13995 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 13996 } 13997 13998 /* 13999 * "setreg()" function 14000 */ 14001 static void 14002 f_setreg(argvars, rettv) 14003 typval_T *argvars; 14004 typval_T *rettv; 14005 { 14006 int regname; 14007 char_u *strregname; 14008 char_u *stropt; 14009 char_u *strval; 14010 int append; 14011 char_u yank_type; 14012 long block_len; 14013 14014 block_len = -1; 14015 yank_type = MAUTO; 14016 append = FALSE; 14017 14018 strregname = get_tv_string_chk(argvars); 14019 rettv->vval.v_number = 1; /* FAIL is default */ 14020 14021 if (strregname == NULL) 14022 return; /* type error; errmsg already given */ 14023 regname = *strregname; 14024 if (regname == 0 || regname == '@') 14025 regname = '"'; 14026 else if (regname == '=') 14027 return; 14028 14029 if (argvars[2].v_type != VAR_UNKNOWN) 14030 { 14031 stropt = get_tv_string_chk(&argvars[2]); 14032 if (stropt == NULL) 14033 return; /* type error */ 14034 for (; *stropt != NUL; ++stropt) 14035 switch (*stropt) 14036 { 14037 case 'a': case 'A': /* append */ 14038 append = TRUE; 14039 break; 14040 case 'v': case 'c': /* character-wise selection */ 14041 yank_type = MCHAR; 14042 break; 14043 case 'V': case 'l': /* line-wise selection */ 14044 yank_type = MLINE; 14045 break; 14046 #ifdef FEAT_VISUAL 14047 case 'b': case Ctrl_V: /* block-wise selection */ 14048 yank_type = MBLOCK; 14049 if (VIM_ISDIGIT(stropt[1])) 14050 { 14051 ++stropt; 14052 block_len = getdigits(&stropt) - 1; 14053 --stropt; 14054 } 14055 break; 14056 #endif 14057 } 14058 } 14059 14060 strval = get_tv_string_chk(&argvars[1]); 14061 if (strval != NULL) 14062 write_reg_contents_ex(regname, strval, -1, 14063 append, yank_type, block_len); 14064 rettv->vval.v_number = 0; 14065 } 14066 14067 14068 /* 14069 * "setwinvar(expr)" function 14070 */ 14071 /*ARGSUSED*/ 14072 static void 14073 f_setwinvar(argvars, rettv) 14074 typval_T *argvars; 14075 typval_T *rettv; 14076 { 14077 win_T *win; 14078 #ifdef FEAT_WINDOWS 14079 win_T *save_curwin; 14080 #endif 14081 char_u *varname, *winvarname; 14082 typval_T *varp; 14083 char_u nbuf[NUMBUFLEN]; 14084 14085 rettv->vval.v_number = 0; 14086 14087 if (check_restricted() || check_secure()) 14088 return; 14089 win = find_win_by_nr(&argvars[0]); 14090 varname = get_tv_string_chk(&argvars[1]); 14091 varp = &argvars[2]; 14092 14093 if (win != NULL && varname != NULL && varp != NULL) 14094 { 14095 #ifdef FEAT_WINDOWS 14096 /* set curwin to be our win, temporarily */ 14097 save_curwin = curwin; 14098 curwin = win; 14099 curbuf = curwin->w_buffer; 14100 #endif 14101 14102 if (*varname == '&') 14103 { 14104 long numval; 14105 char_u *strval; 14106 int error = FALSE; 14107 14108 ++varname; 14109 numval = get_tv_number_chk(varp, &error); 14110 strval = get_tv_string_buf_chk(varp, nbuf); 14111 if (!error && strval != NULL) 14112 set_option_value(varname, numval, strval, OPT_LOCAL); 14113 } 14114 else 14115 { 14116 winvarname = alloc((unsigned)STRLEN(varname) + 3); 14117 if (winvarname != NULL) 14118 { 14119 STRCPY(winvarname, "w:"); 14120 STRCPY(winvarname + 2, varname); 14121 set_var(winvarname, varp, TRUE); 14122 vim_free(winvarname); 14123 } 14124 } 14125 14126 #ifdef FEAT_WINDOWS 14127 /* Restore current window, if it's still valid (autocomands can make 14128 * it invalid). */ 14129 if (win_valid(save_curwin)) 14130 { 14131 curwin = save_curwin; 14132 curbuf = curwin->w_buffer; 14133 } 14134 #endif 14135 } 14136 } 14137 14138 /* 14139 * "simplify()" function 14140 */ 14141 static void 14142 f_simplify(argvars, rettv) 14143 typval_T *argvars; 14144 typval_T *rettv; 14145 { 14146 char_u *p; 14147 14148 p = get_tv_string(&argvars[0]); 14149 rettv->vval.v_string = vim_strsave(p); 14150 simplify_filename(rettv->vval.v_string); /* simplify in place */ 14151 rettv->v_type = VAR_STRING; 14152 } 14153 14154 static int 14155 #ifdef __BORLANDC__ 14156 _RTLENTRYF 14157 #endif 14158 item_compare __ARGS((const void *s1, const void *s2)); 14159 static int 14160 #ifdef __BORLANDC__ 14161 _RTLENTRYF 14162 #endif 14163 item_compare2 __ARGS((const void *s1, const void *s2)); 14164 14165 static int item_compare_ic; 14166 static char_u *item_compare_func; 14167 static int item_compare_func_err; 14168 #define ITEM_COMPARE_FAIL 999 14169 14170 /* 14171 * Compare functions for f_sort() below. 14172 */ 14173 static int 14174 #ifdef __BORLANDC__ 14175 _RTLENTRYF 14176 #endif 14177 item_compare(s1, s2) 14178 const void *s1; 14179 const void *s2; 14180 { 14181 char_u *p1, *p2; 14182 char_u *tofree1, *tofree2; 14183 int res; 14184 char_u numbuf1[NUMBUFLEN]; 14185 char_u numbuf2[NUMBUFLEN]; 14186 14187 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0); 14188 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0); 14189 if (item_compare_ic) 14190 res = STRICMP(p1, p2); 14191 else 14192 res = STRCMP(p1, p2); 14193 vim_free(tofree1); 14194 vim_free(tofree2); 14195 return res; 14196 } 14197 14198 static int 14199 #ifdef __BORLANDC__ 14200 _RTLENTRYF 14201 #endif 14202 item_compare2(s1, s2) 14203 const void *s1; 14204 const void *s2; 14205 { 14206 int res; 14207 typval_T rettv; 14208 typval_T argv[2]; 14209 int dummy; 14210 14211 /* shortcut after failure in previous call; compare all items equal */ 14212 if (item_compare_func_err) 14213 return 0; 14214 14215 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 14216 * in the copy without changing the original list items. */ 14217 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 14218 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 14219 14220 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 14221 res = call_func(item_compare_func, STRLEN(item_compare_func), 14222 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 14223 clear_tv(&argv[0]); 14224 clear_tv(&argv[1]); 14225 14226 if (res == FAIL) 14227 res = ITEM_COMPARE_FAIL; 14228 else 14229 /* return value has wrong type */ 14230 res = get_tv_number_chk(&rettv, &item_compare_func_err); 14231 if (item_compare_func_err) 14232 res = ITEM_COMPARE_FAIL; 14233 clear_tv(&rettv); 14234 return res; 14235 } 14236 14237 /* 14238 * "sort({list})" function 14239 */ 14240 static void 14241 f_sort(argvars, rettv) 14242 typval_T *argvars; 14243 typval_T *rettv; 14244 { 14245 list_T *l; 14246 listitem_T *li; 14247 listitem_T **ptrs; 14248 long len; 14249 long i; 14250 14251 rettv->vval.v_number = 0; 14252 if (argvars[0].v_type != VAR_LIST) 14253 EMSG2(_(e_listarg), "sort()"); 14254 else 14255 { 14256 l = argvars[0].vval.v_list; 14257 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 14258 return; 14259 rettv->vval.v_list = l; 14260 rettv->v_type = VAR_LIST; 14261 ++l->lv_refcount; 14262 14263 len = list_len(l); 14264 if (len <= 1) 14265 return; /* short list sorts pretty quickly */ 14266 14267 item_compare_ic = FALSE; 14268 item_compare_func = NULL; 14269 if (argvars[1].v_type != VAR_UNKNOWN) 14270 { 14271 if (argvars[1].v_type == VAR_FUNC) 14272 item_compare_func = argvars[1].vval.v_string; 14273 else 14274 { 14275 int error = FALSE; 14276 14277 i = get_tv_number_chk(&argvars[1], &error); 14278 if (error) 14279 return; /* type error; errmsg already given */ 14280 if (i == 1) 14281 item_compare_ic = TRUE; 14282 else 14283 item_compare_func = get_tv_string(&argvars[1]); 14284 } 14285 } 14286 14287 /* Make an array with each entry pointing to an item in the List. */ 14288 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 14289 if (ptrs == NULL) 14290 return; 14291 i = 0; 14292 for (li = l->lv_first; li != NULL; li = li->li_next) 14293 ptrs[i++] = li; 14294 14295 item_compare_func_err = FALSE; 14296 /* test the compare function */ 14297 if (item_compare_func != NULL 14298 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 14299 == ITEM_COMPARE_FAIL) 14300 EMSG(_("E702: Sort compare function failed")); 14301 else 14302 { 14303 /* Sort the array with item pointers. */ 14304 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 14305 item_compare_func == NULL ? item_compare : item_compare2); 14306 14307 if (!item_compare_func_err) 14308 { 14309 /* Clear the List and append the items in the sorted order. */ 14310 l->lv_first = l->lv_last = NULL; 14311 l->lv_len = 0; 14312 for (i = 0; i < len; ++i) 14313 list_append(l, ptrs[i]); 14314 } 14315 } 14316 14317 vim_free(ptrs); 14318 } 14319 } 14320 14321 /* 14322 * "soundfold({word})" function 14323 */ 14324 static void 14325 f_soundfold(argvars, rettv) 14326 typval_T *argvars; 14327 typval_T *rettv; 14328 { 14329 char_u *s; 14330 14331 rettv->v_type = VAR_STRING; 14332 s = get_tv_string(&argvars[0]); 14333 #ifdef FEAT_SYN_HL 14334 rettv->vval.v_string = eval_soundfold(s); 14335 #else 14336 rettv->vval.v_string = vim_strsave(s); 14337 #endif 14338 } 14339 14340 /* 14341 * "spellbadword()" function 14342 */ 14343 /* ARGSUSED */ 14344 static void 14345 f_spellbadword(argvars, rettv) 14346 typval_T *argvars; 14347 typval_T *rettv; 14348 { 14349 char_u *word = (char_u *)""; 14350 hlf_T attr = HLF_COUNT; 14351 int len = 0; 14352 14353 if (rettv_list_alloc(rettv) == FAIL) 14354 return; 14355 14356 #ifdef FEAT_SYN_HL 14357 if (argvars[0].v_type == VAR_UNKNOWN) 14358 { 14359 /* Find the start and length of the badly spelled word. */ 14360 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 14361 if (len != 0) 14362 word = ml_get_cursor(); 14363 } 14364 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 14365 { 14366 char_u *str = get_tv_string_chk(&argvars[0]); 14367 int capcol = -1; 14368 14369 if (str != NULL) 14370 { 14371 /* Check the argument for spelling. */ 14372 while (*str != NUL) 14373 { 14374 len = spell_check(curwin, str, &attr, &capcol, FALSE); 14375 if (attr != HLF_COUNT) 14376 { 14377 word = str; 14378 break; 14379 } 14380 str += len; 14381 } 14382 } 14383 } 14384 #endif 14385 14386 list_append_string(rettv->vval.v_list, word, len); 14387 list_append_string(rettv->vval.v_list, (char_u *)( 14388 attr == HLF_SPB ? "bad" : 14389 attr == HLF_SPR ? "rare" : 14390 attr == HLF_SPL ? "local" : 14391 attr == HLF_SPC ? "caps" : 14392 ""), -1); 14393 } 14394 14395 /* 14396 * "spellsuggest()" function 14397 */ 14398 static void 14399 f_spellsuggest(argvars, rettv) 14400 typval_T *argvars; 14401 typval_T *rettv; 14402 { 14403 #ifdef FEAT_SYN_HL 14404 char_u *str; 14405 int typeerr = FALSE; 14406 int maxcount; 14407 garray_T ga; 14408 int i; 14409 listitem_T *li; 14410 int need_capital = FALSE; 14411 #endif 14412 14413 if (rettv_list_alloc(rettv) == FAIL) 14414 return; 14415 14416 #ifdef FEAT_SYN_HL 14417 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 14418 { 14419 str = get_tv_string(&argvars[0]); 14420 if (argvars[1].v_type != VAR_UNKNOWN) 14421 { 14422 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 14423 if (maxcount <= 0) 14424 return; 14425 if (argvars[2].v_type != VAR_UNKNOWN) 14426 { 14427 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 14428 if (typeerr) 14429 return; 14430 } 14431 } 14432 else 14433 maxcount = 25; 14434 14435 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 14436 14437 for (i = 0; i < ga.ga_len; ++i) 14438 { 14439 str = ((char_u **)ga.ga_data)[i]; 14440 14441 li = listitem_alloc(); 14442 if (li == NULL) 14443 vim_free(str); 14444 else 14445 { 14446 li->li_tv.v_type = VAR_STRING; 14447 li->li_tv.v_lock = 0; 14448 li->li_tv.vval.v_string = str; 14449 list_append(rettv->vval.v_list, li); 14450 } 14451 } 14452 ga_clear(&ga); 14453 } 14454 #endif 14455 } 14456 14457 static void 14458 f_split(argvars, rettv) 14459 typval_T *argvars; 14460 typval_T *rettv; 14461 { 14462 char_u *str; 14463 char_u *end; 14464 char_u *pat = NULL; 14465 regmatch_T regmatch; 14466 char_u patbuf[NUMBUFLEN]; 14467 char_u *save_cpo; 14468 int match; 14469 colnr_T col = 0; 14470 int keepempty = FALSE; 14471 int typeerr = FALSE; 14472 14473 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14474 save_cpo = p_cpo; 14475 p_cpo = (char_u *)""; 14476 14477 str = get_tv_string(&argvars[0]); 14478 if (argvars[1].v_type != VAR_UNKNOWN) 14479 { 14480 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14481 if (pat == NULL) 14482 typeerr = TRUE; 14483 if (argvars[2].v_type != VAR_UNKNOWN) 14484 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 14485 } 14486 if (pat == NULL || *pat == NUL) 14487 pat = (char_u *)"[\\x01- ]\\+"; 14488 14489 if (rettv_list_alloc(rettv) == FAIL) 14490 return; 14491 if (typeerr) 14492 return; 14493 14494 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14495 if (regmatch.regprog != NULL) 14496 { 14497 regmatch.rm_ic = FALSE; 14498 while (*str != NUL || keepempty) 14499 { 14500 if (*str == NUL) 14501 match = FALSE; /* empty item at the end */ 14502 else 14503 match = vim_regexec_nl(®match, str, col); 14504 if (match) 14505 end = regmatch.startp[0]; 14506 else 14507 end = str + STRLEN(str); 14508 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 14509 && *str != NUL && match && end < regmatch.endp[0])) 14510 { 14511 if (list_append_string(rettv->vval.v_list, str, 14512 (int)(end - str)) == FAIL) 14513 break; 14514 } 14515 if (!match) 14516 break; 14517 /* Advance to just after the match. */ 14518 if (regmatch.endp[0] > str) 14519 col = 0; 14520 else 14521 { 14522 /* Don't get stuck at the same match. */ 14523 #ifdef FEAT_MBYTE 14524 col = (*mb_ptr2len)(regmatch.endp[0]); 14525 #else 14526 col = 1; 14527 #endif 14528 } 14529 str = regmatch.endp[0]; 14530 } 14531 14532 vim_free(regmatch.regprog); 14533 } 14534 14535 p_cpo = save_cpo; 14536 } 14537 14538 #ifdef HAVE_STRFTIME 14539 /* 14540 * "strftime({format}[, {time}])" function 14541 */ 14542 static void 14543 f_strftime(argvars, rettv) 14544 typval_T *argvars; 14545 typval_T *rettv; 14546 { 14547 char_u result_buf[256]; 14548 struct tm *curtime; 14549 time_t seconds; 14550 char_u *p; 14551 14552 rettv->v_type = VAR_STRING; 14553 14554 p = get_tv_string(&argvars[0]); 14555 if (argvars[1].v_type == VAR_UNKNOWN) 14556 seconds = time(NULL); 14557 else 14558 seconds = (time_t)get_tv_number(&argvars[1]); 14559 curtime = localtime(&seconds); 14560 /* MSVC returns NULL for an invalid value of seconds. */ 14561 if (curtime == NULL) 14562 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 14563 else 14564 { 14565 # ifdef FEAT_MBYTE 14566 vimconv_T conv; 14567 char_u *enc; 14568 14569 conv.vc_type = CONV_NONE; 14570 enc = enc_locale(); 14571 convert_setup(&conv, p_enc, enc); 14572 if (conv.vc_type != CONV_NONE) 14573 p = string_convert(&conv, p, NULL); 14574 # endif 14575 if (p != NULL) 14576 (void)strftime((char *)result_buf, sizeof(result_buf), 14577 (char *)p, curtime); 14578 else 14579 result_buf[0] = NUL; 14580 14581 # ifdef FEAT_MBYTE 14582 if (conv.vc_type != CONV_NONE) 14583 vim_free(p); 14584 convert_setup(&conv, enc, p_enc); 14585 if (conv.vc_type != CONV_NONE) 14586 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 14587 else 14588 # endif 14589 rettv->vval.v_string = vim_strsave(result_buf); 14590 14591 # ifdef FEAT_MBYTE 14592 /* Release conversion descriptors */ 14593 convert_setup(&conv, NULL, NULL); 14594 vim_free(enc); 14595 # endif 14596 } 14597 } 14598 #endif 14599 14600 /* 14601 * "stridx()" function 14602 */ 14603 static void 14604 f_stridx(argvars, rettv) 14605 typval_T *argvars; 14606 typval_T *rettv; 14607 { 14608 char_u buf[NUMBUFLEN]; 14609 char_u *needle; 14610 char_u *haystack; 14611 char_u *save_haystack; 14612 char_u *pos; 14613 int start_idx; 14614 14615 needle = get_tv_string_chk(&argvars[1]); 14616 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 14617 rettv->vval.v_number = -1; 14618 if (needle == NULL || haystack == NULL) 14619 return; /* type error; errmsg already given */ 14620 14621 if (argvars[2].v_type != VAR_UNKNOWN) 14622 { 14623 int error = FALSE; 14624 14625 start_idx = get_tv_number_chk(&argvars[2], &error); 14626 if (error || start_idx >= (int)STRLEN(haystack)) 14627 return; 14628 if (start_idx >= 0) 14629 haystack += start_idx; 14630 } 14631 14632 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14633 if (pos != NULL) 14634 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14635 } 14636 14637 /* 14638 * "string()" function 14639 */ 14640 static void 14641 f_string(argvars, rettv) 14642 typval_T *argvars; 14643 typval_T *rettv; 14644 { 14645 char_u *tofree; 14646 char_u numbuf[NUMBUFLEN]; 14647 14648 rettv->v_type = VAR_STRING; 14649 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 14650 if (tofree == NULL) 14651 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14652 } 14653 14654 /* 14655 * "strlen()" function 14656 */ 14657 static void 14658 f_strlen(argvars, rettv) 14659 typval_T *argvars; 14660 typval_T *rettv; 14661 { 14662 rettv->vval.v_number = (varnumber_T)(STRLEN( 14663 get_tv_string(&argvars[0]))); 14664 } 14665 14666 /* 14667 * "strpart()" function 14668 */ 14669 static void 14670 f_strpart(argvars, rettv) 14671 typval_T *argvars; 14672 typval_T *rettv; 14673 { 14674 char_u *p; 14675 int n; 14676 int len; 14677 int slen; 14678 int error = FALSE; 14679 14680 p = get_tv_string(&argvars[0]); 14681 slen = (int)STRLEN(p); 14682 14683 n = get_tv_number_chk(&argvars[1], &error); 14684 if (error) 14685 len = 0; 14686 else if (argvars[2].v_type != VAR_UNKNOWN) 14687 len = get_tv_number(&argvars[2]); 14688 else 14689 len = slen - n; /* default len: all bytes that are available. */ 14690 14691 /* 14692 * Only return the overlap between the specified part and the actual 14693 * string. 14694 */ 14695 if (n < 0) 14696 { 14697 len += n; 14698 n = 0; 14699 } 14700 else if (n > slen) 14701 n = slen; 14702 if (len < 0) 14703 len = 0; 14704 else if (n + len > slen) 14705 len = slen - n; 14706 14707 rettv->v_type = VAR_STRING; 14708 rettv->vval.v_string = vim_strnsave(p + n, len); 14709 } 14710 14711 /* 14712 * "strridx()" function 14713 */ 14714 static void 14715 f_strridx(argvars, rettv) 14716 typval_T *argvars; 14717 typval_T *rettv; 14718 { 14719 char_u buf[NUMBUFLEN]; 14720 char_u *needle; 14721 char_u *haystack; 14722 char_u *rest; 14723 char_u *lastmatch = NULL; 14724 int haystack_len, end_idx; 14725 14726 needle = get_tv_string_chk(&argvars[1]); 14727 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14728 haystack_len = STRLEN(haystack); 14729 14730 rettv->vval.v_number = -1; 14731 if (needle == NULL || haystack == NULL) 14732 return; /* type error; errmsg already given */ 14733 if (argvars[2].v_type != VAR_UNKNOWN) 14734 { 14735 /* Third argument: upper limit for index */ 14736 end_idx = get_tv_number_chk(&argvars[2], NULL); 14737 if (end_idx < 0) 14738 return; /* can never find a match */ 14739 } 14740 else 14741 end_idx = haystack_len; 14742 14743 if (*needle == NUL) 14744 { 14745 /* Empty string matches past the end. */ 14746 lastmatch = haystack + end_idx; 14747 } 14748 else 14749 { 14750 for (rest = haystack; *rest != '\0'; ++rest) 14751 { 14752 rest = (char_u *)strstr((char *)rest, (char *)needle); 14753 if (rest == NULL || rest > haystack + end_idx) 14754 break; 14755 lastmatch = rest; 14756 } 14757 } 14758 14759 if (lastmatch == NULL) 14760 rettv->vval.v_number = -1; 14761 else 14762 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14763 } 14764 14765 /* 14766 * "strtrans()" function 14767 */ 14768 static void 14769 f_strtrans(argvars, rettv) 14770 typval_T *argvars; 14771 typval_T *rettv; 14772 { 14773 rettv->v_type = VAR_STRING; 14774 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14775 } 14776 14777 /* 14778 * "submatch()" function 14779 */ 14780 static void 14781 f_submatch(argvars, rettv) 14782 typval_T *argvars; 14783 typval_T *rettv; 14784 { 14785 rettv->v_type = VAR_STRING; 14786 rettv->vval.v_string = 14787 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14788 } 14789 14790 /* 14791 * "substitute()" function 14792 */ 14793 static void 14794 f_substitute(argvars, rettv) 14795 typval_T *argvars; 14796 typval_T *rettv; 14797 { 14798 char_u patbuf[NUMBUFLEN]; 14799 char_u subbuf[NUMBUFLEN]; 14800 char_u flagsbuf[NUMBUFLEN]; 14801 14802 char_u *str = get_tv_string_chk(&argvars[0]); 14803 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14804 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14805 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14806 14807 rettv->v_type = VAR_STRING; 14808 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14809 rettv->vval.v_string = NULL; 14810 else 14811 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14812 } 14813 14814 /* 14815 * "synID(lnum, col, trans)" function 14816 */ 14817 /*ARGSUSED*/ 14818 static void 14819 f_synID(argvars, rettv) 14820 typval_T *argvars; 14821 typval_T *rettv; 14822 { 14823 int id = 0; 14824 #ifdef FEAT_SYN_HL 14825 long lnum; 14826 long col; 14827 int trans; 14828 int transerr = FALSE; 14829 14830 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14831 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14832 trans = get_tv_number_chk(&argvars[2], &transerr); 14833 14834 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14835 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14836 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14837 #endif 14838 14839 rettv->vval.v_number = id; 14840 } 14841 14842 /* 14843 * "synIDattr(id, what [, mode])" function 14844 */ 14845 /*ARGSUSED*/ 14846 static void 14847 f_synIDattr(argvars, rettv) 14848 typval_T *argvars; 14849 typval_T *rettv; 14850 { 14851 char_u *p = NULL; 14852 #ifdef FEAT_SYN_HL 14853 int id; 14854 char_u *what; 14855 char_u *mode; 14856 char_u modebuf[NUMBUFLEN]; 14857 int modec; 14858 14859 id = get_tv_number(&argvars[0]); 14860 what = get_tv_string(&argvars[1]); 14861 if (argvars[2].v_type != VAR_UNKNOWN) 14862 { 14863 mode = get_tv_string_buf(&argvars[2], modebuf); 14864 modec = TOLOWER_ASC(mode[0]); 14865 if (modec != 't' && modec != 'c' 14866 #ifdef FEAT_GUI 14867 && modec != 'g' 14868 #endif 14869 ) 14870 modec = 0; /* replace invalid with current */ 14871 } 14872 else 14873 { 14874 #ifdef FEAT_GUI 14875 if (gui.in_use) 14876 modec = 'g'; 14877 else 14878 #endif 14879 if (t_colors > 1) 14880 modec = 'c'; 14881 else 14882 modec = 't'; 14883 } 14884 14885 14886 switch (TOLOWER_ASC(what[0])) 14887 { 14888 case 'b': 14889 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14890 p = highlight_color(id, what, modec); 14891 else /* bold */ 14892 p = highlight_has_attr(id, HL_BOLD, modec); 14893 break; 14894 14895 case 'f': /* fg[#] */ 14896 p = highlight_color(id, what, modec); 14897 break; 14898 14899 case 'i': 14900 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14901 p = highlight_has_attr(id, HL_INVERSE, modec); 14902 else /* italic */ 14903 p = highlight_has_attr(id, HL_ITALIC, modec); 14904 break; 14905 14906 case 'n': /* name */ 14907 p = get_highlight_name(NULL, id - 1); 14908 break; 14909 14910 case 'r': /* reverse */ 14911 p = highlight_has_attr(id, HL_INVERSE, modec); 14912 break; 14913 14914 case 's': /* standout */ 14915 p = highlight_has_attr(id, HL_STANDOUT, modec); 14916 break; 14917 14918 case 'u': 14919 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14920 /* underline */ 14921 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14922 else 14923 /* undercurl */ 14924 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14925 break; 14926 } 14927 14928 if (p != NULL) 14929 p = vim_strsave(p); 14930 #endif 14931 rettv->v_type = VAR_STRING; 14932 rettv->vval.v_string = p; 14933 } 14934 14935 /* 14936 * "synIDtrans(id)" function 14937 */ 14938 /*ARGSUSED*/ 14939 static void 14940 f_synIDtrans(argvars, rettv) 14941 typval_T *argvars; 14942 typval_T *rettv; 14943 { 14944 int id; 14945 14946 #ifdef FEAT_SYN_HL 14947 id = get_tv_number(&argvars[0]); 14948 14949 if (id > 0) 14950 id = syn_get_final_id(id); 14951 else 14952 #endif 14953 id = 0; 14954 14955 rettv->vval.v_number = id; 14956 } 14957 14958 /* 14959 * "system()" function 14960 */ 14961 static void 14962 f_system(argvars, rettv) 14963 typval_T *argvars; 14964 typval_T *rettv; 14965 { 14966 char_u *res = NULL; 14967 char_u *p; 14968 char_u *infile = NULL; 14969 char_u buf[NUMBUFLEN]; 14970 int err = FALSE; 14971 FILE *fd; 14972 14973 if (argvars[1].v_type != VAR_UNKNOWN) 14974 { 14975 /* 14976 * Write the string to a temp file, to be used for input of the shell 14977 * command. 14978 */ 14979 if ((infile = vim_tempname('i')) == NULL) 14980 { 14981 EMSG(_(e_notmp)); 14982 return; 14983 } 14984 14985 fd = mch_fopen((char *)infile, WRITEBIN); 14986 if (fd == NULL) 14987 { 14988 EMSG2(_(e_notopen), infile); 14989 goto done; 14990 } 14991 p = get_tv_string_buf_chk(&argvars[1], buf); 14992 if (p == NULL) 14993 goto done; /* type error; errmsg already given */ 14994 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14995 err = TRUE; 14996 if (fclose(fd) != 0) 14997 err = TRUE; 14998 if (err) 14999 { 15000 EMSG(_("E677: Error writing temp file")); 15001 goto done; 15002 } 15003 } 15004 15005 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 15006 15007 #ifdef USE_CR 15008 /* translate <CR> into <NL> */ 15009 if (res != NULL) 15010 { 15011 char_u *s; 15012 15013 for (s = res; *s; ++s) 15014 { 15015 if (*s == CAR) 15016 *s = NL; 15017 } 15018 } 15019 #else 15020 # ifdef USE_CRNL 15021 /* translate <CR><NL> into <NL> */ 15022 if (res != NULL) 15023 { 15024 char_u *s, *d; 15025 15026 d = res; 15027 for (s = res; *s; ++s) 15028 { 15029 if (s[0] == CAR && s[1] == NL) 15030 ++s; 15031 *d++ = *s; 15032 } 15033 *d = NUL; 15034 } 15035 # endif 15036 #endif 15037 15038 done: 15039 if (infile != NULL) 15040 { 15041 mch_remove(infile); 15042 vim_free(infile); 15043 } 15044 rettv->v_type = VAR_STRING; 15045 rettv->vval.v_string = res; 15046 } 15047 15048 /* 15049 * "tabpagebuflist()" function 15050 */ 15051 /* ARGSUSED */ 15052 static void 15053 f_tabpagebuflist(argvars, rettv) 15054 typval_T *argvars; 15055 typval_T *rettv; 15056 { 15057 #ifndef FEAT_WINDOWS 15058 rettv->vval.v_number = 0; 15059 #else 15060 tabpage_T *tp; 15061 win_T *wp = NULL; 15062 15063 if (argvars[0].v_type == VAR_UNKNOWN) 15064 wp = firstwin; 15065 else 15066 { 15067 tp = find_tabpage((int)get_tv_number(&argvars[0])); 15068 if (tp != NULL) 15069 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 15070 } 15071 if (wp == NULL) 15072 rettv->vval.v_number = 0; 15073 else 15074 { 15075 if (rettv_list_alloc(rettv) == FAIL) 15076 rettv->vval.v_number = 0; 15077 else 15078 { 15079 for (; wp != NULL; wp = wp->w_next) 15080 if (list_append_number(rettv->vval.v_list, 15081 wp->w_buffer->b_fnum) == FAIL) 15082 break; 15083 } 15084 } 15085 #endif 15086 } 15087 15088 15089 /* 15090 * "tabpagenr()" function 15091 */ 15092 /* ARGSUSED */ 15093 static void 15094 f_tabpagenr(argvars, rettv) 15095 typval_T *argvars; 15096 typval_T *rettv; 15097 { 15098 int nr = 1; 15099 #ifdef FEAT_WINDOWS 15100 char_u *arg; 15101 15102 if (argvars[0].v_type != VAR_UNKNOWN) 15103 { 15104 arg = get_tv_string_chk(&argvars[0]); 15105 nr = 0; 15106 if (arg != NULL) 15107 { 15108 if (STRCMP(arg, "$") == 0) 15109 nr = tabpage_index(NULL) - 1; 15110 else 15111 EMSG2(_(e_invexpr2), arg); 15112 } 15113 } 15114 else 15115 nr = tabpage_index(curtab); 15116 #endif 15117 rettv->vval.v_number = nr; 15118 } 15119 15120 15121 #ifdef FEAT_WINDOWS 15122 static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 15123 15124 /* 15125 * Common code for tabpagewinnr() and winnr(). 15126 */ 15127 static int 15128 get_winnr(tp, argvar) 15129 tabpage_T *tp; 15130 typval_T *argvar; 15131 { 15132 win_T *twin; 15133 int nr = 1; 15134 win_T *wp; 15135 char_u *arg; 15136 15137 twin = (tp == curtab) ? curwin : tp->tp_curwin; 15138 if (argvar->v_type != VAR_UNKNOWN) 15139 { 15140 arg = get_tv_string_chk(argvar); 15141 if (arg == NULL) 15142 nr = 0; /* type error; errmsg already given */ 15143 else if (STRCMP(arg, "$") == 0) 15144 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 15145 else if (STRCMP(arg, "#") == 0) 15146 { 15147 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 15148 if (twin == NULL) 15149 nr = 0; 15150 } 15151 else 15152 { 15153 EMSG2(_(e_invexpr2), arg); 15154 nr = 0; 15155 } 15156 } 15157 15158 if (nr > 0) 15159 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 15160 wp != twin; wp = wp->w_next) 15161 ++nr; 15162 return nr; 15163 } 15164 #endif 15165 15166 /* 15167 * "tabpagewinnr()" function 15168 */ 15169 /* ARGSUSED */ 15170 static void 15171 f_tabpagewinnr(argvars, rettv) 15172 typval_T *argvars; 15173 typval_T *rettv; 15174 { 15175 int nr = 1; 15176 #ifdef FEAT_WINDOWS 15177 tabpage_T *tp; 15178 15179 tp = find_tabpage((int)get_tv_number(&argvars[0])); 15180 if (tp == NULL) 15181 nr = 0; 15182 else 15183 nr = get_winnr(tp, &argvars[1]); 15184 #endif 15185 rettv->vval.v_number = nr; 15186 } 15187 15188 15189 /* 15190 * "tagfiles()" function 15191 */ 15192 /*ARGSUSED*/ 15193 static void 15194 f_tagfiles(argvars, rettv) 15195 typval_T *argvars; 15196 typval_T *rettv; 15197 { 15198 char_u fname[MAXPATHL + 1]; 15199 tagname_T tn; 15200 int first; 15201 15202 if (rettv_list_alloc(rettv) == FAIL) 15203 { 15204 rettv->vval.v_number = 0; 15205 return; 15206 } 15207 15208 for (first = TRUE; ; first = FALSE) 15209 if (get_tagfname(&tn, first, fname) == FAIL 15210 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 15211 break; 15212 tagname_free(&tn); 15213 } 15214 15215 /* 15216 * "taglist()" function 15217 */ 15218 static void 15219 f_taglist(argvars, rettv) 15220 typval_T *argvars; 15221 typval_T *rettv; 15222 { 15223 char_u *tag_pattern; 15224 15225 tag_pattern = get_tv_string(&argvars[0]); 15226 15227 rettv->vval.v_number = FALSE; 15228 if (*tag_pattern == NUL) 15229 return; 15230 15231 if (rettv_list_alloc(rettv) == OK) 15232 (void)get_tags(rettv->vval.v_list, tag_pattern); 15233 } 15234 15235 /* 15236 * "tempname()" function 15237 */ 15238 /*ARGSUSED*/ 15239 static void 15240 f_tempname(argvars, rettv) 15241 typval_T *argvars; 15242 typval_T *rettv; 15243 { 15244 static int x = 'A'; 15245 15246 rettv->v_type = VAR_STRING; 15247 rettv->vval.v_string = vim_tempname(x); 15248 15249 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 15250 * names. Skip 'I' and 'O', they are used for shell redirection. */ 15251 do 15252 { 15253 if (x == 'Z') 15254 x = '0'; 15255 else if (x == '9') 15256 x = 'A'; 15257 else 15258 { 15259 #ifdef EBCDIC 15260 if (x == 'I') 15261 x = 'J'; 15262 else if (x == 'R') 15263 x = 'S'; 15264 else 15265 #endif 15266 ++x; 15267 } 15268 } while (x == 'I' || x == 'O'); 15269 } 15270 15271 /* 15272 * "test(list)" function: Just checking the walls... 15273 */ 15274 /*ARGSUSED*/ 15275 static void 15276 f_test(argvars, rettv) 15277 typval_T *argvars; 15278 typval_T *rettv; 15279 { 15280 /* Used for unit testing. Change the code below to your liking. */ 15281 #if 0 15282 listitem_T *li; 15283 list_T *l; 15284 char_u *bad, *good; 15285 15286 if (argvars[0].v_type != VAR_LIST) 15287 return; 15288 l = argvars[0].vval.v_list; 15289 if (l == NULL) 15290 return; 15291 li = l->lv_first; 15292 if (li == NULL) 15293 return; 15294 bad = get_tv_string(&li->li_tv); 15295 li = li->li_next; 15296 if (li == NULL) 15297 return; 15298 good = get_tv_string(&li->li_tv); 15299 rettv->vval.v_number = test_edit_score(bad, good); 15300 #endif 15301 } 15302 15303 /* 15304 * "tolower(string)" function 15305 */ 15306 static void 15307 f_tolower(argvars, rettv) 15308 typval_T *argvars; 15309 typval_T *rettv; 15310 { 15311 char_u *p; 15312 15313 p = vim_strsave(get_tv_string(&argvars[0])); 15314 rettv->v_type = VAR_STRING; 15315 rettv->vval.v_string = p; 15316 15317 if (p != NULL) 15318 while (*p != NUL) 15319 { 15320 #ifdef FEAT_MBYTE 15321 int l; 15322 15323 if (enc_utf8) 15324 { 15325 int c, lc; 15326 15327 c = utf_ptr2char(p); 15328 lc = utf_tolower(c); 15329 l = utf_ptr2len(p); 15330 /* TODO: reallocate string when byte count changes. */ 15331 if (utf_char2len(lc) == l) 15332 utf_char2bytes(lc, p); 15333 p += l; 15334 } 15335 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 15336 p += l; /* skip multi-byte character */ 15337 else 15338 #endif 15339 { 15340 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 15341 ++p; 15342 } 15343 } 15344 } 15345 15346 /* 15347 * "toupper(string)" function 15348 */ 15349 static void 15350 f_toupper(argvars, rettv) 15351 typval_T *argvars; 15352 typval_T *rettv; 15353 { 15354 rettv->v_type = VAR_STRING; 15355 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 15356 } 15357 15358 /* 15359 * "tr(string, fromstr, tostr)" function 15360 */ 15361 static void 15362 f_tr(argvars, rettv) 15363 typval_T *argvars; 15364 typval_T *rettv; 15365 { 15366 char_u *instr; 15367 char_u *fromstr; 15368 char_u *tostr; 15369 char_u *p; 15370 #ifdef FEAT_MBYTE 15371 int inlen; 15372 int fromlen; 15373 int tolen; 15374 int idx; 15375 char_u *cpstr; 15376 int cplen; 15377 int first = TRUE; 15378 #endif 15379 char_u buf[NUMBUFLEN]; 15380 char_u buf2[NUMBUFLEN]; 15381 garray_T ga; 15382 15383 instr = get_tv_string(&argvars[0]); 15384 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 15385 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 15386 15387 /* Default return value: empty string. */ 15388 rettv->v_type = VAR_STRING; 15389 rettv->vval.v_string = NULL; 15390 if (fromstr == NULL || tostr == NULL) 15391 return; /* type error; errmsg already given */ 15392 ga_init2(&ga, (int)sizeof(char), 80); 15393 15394 #ifdef FEAT_MBYTE 15395 if (!has_mbyte) 15396 #endif 15397 /* not multi-byte: fromstr and tostr must be the same length */ 15398 if (STRLEN(fromstr) != STRLEN(tostr)) 15399 { 15400 #ifdef FEAT_MBYTE 15401 error: 15402 #endif 15403 EMSG2(_(e_invarg2), fromstr); 15404 ga_clear(&ga); 15405 return; 15406 } 15407 15408 /* fromstr and tostr have to contain the same number of chars */ 15409 while (*instr != NUL) 15410 { 15411 #ifdef FEAT_MBYTE 15412 if (has_mbyte) 15413 { 15414 inlen = (*mb_ptr2len)(instr); 15415 cpstr = instr; 15416 cplen = inlen; 15417 idx = 0; 15418 for (p = fromstr; *p != NUL; p += fromlen) 15419 { 15420 fromlen = (*mb_ptr2len)(p); 15421 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 15422 { 15423 for (p = tostr; *p != NUL; p += tolen) 15424 { 15425 tolen = (*mb_ptr2len)(p); 15426 if (idx-- == 0) 15427 { 15428 cplen = tolen; 15429 cpstr = p; 15430 break; 15431 } 15432 } 15433 if (*p == NUL) /* tostr is shorter than fromstr */ 15434 goto error; 15435 break; 15436 } 15437 ++idx; 15438 } 15439 15440 if (first && cpstr == instr) 15441 { 15442 /* Check that fromstr and tostr have the same number of 15443 * (multi-byte) characters. Done only once when a character 15444 * of instr doesn't appear in fromstr. */ 15445 first = FALSE; 15446 for (p = tostr; *p != NUL; p += tolen) 15447 { 15448 tolen = (*mb_ptr2len)(p); 15449 --idx; 15450 } 15451 if (idx != 0) 15452 goto error; 15453 } 15454 15455 ga_grow(&ga, cplen); 15456 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 15457 ga.ga_len += cplen; 15458 15459 instr += inlen; 15460 } 15461 else 15462 #endif 15463 { 15464 /* When not using multi-byte chars we can do it faster. */ 15465 p = vim_strchr(fromstr, *instr); 15466 if (p != NULL) 15467 ga_append(&ga, tostr[p - fromstr]); 15468 else 15469 ga_append(&ga, *instr); 15470 ++instr; 15471 } 15472 } 15473 15474 rettv->vval.v_string = ga.ga_data; 15475 } 15476 15477 /* 15478 * "type(expr)" function 15479 */ 15480 static void 15481 f_type(argvars, rettv) 15482 typval_T *argvars; 15483 typval_T *rettv; 15484 { 15485 int n; 15486 15487 switch (argvars[0].v_type) 15488 { 15489 case VAR_NUMBER: n = 0; break; 15490 case VAR_STRING: n = 1; break; 15491 case VAR_FUNC: n = 2; break; 15492 case VAR_LIST: n = 3; break; 15493 case VAR_DICT: n = 4; break; 15494 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 15495 } 15496 rettv->vval.v_number = n; 15497 } 15498 15499 /* 15500 * "values(dict)" function 15501 */ 15502 static void 15503 f_values(argvars, rettv) 15504 typval_T *argvars; 15505 typval_T *rettv; 15506 { 15507 dict_list(argvars, rettv, 1); 15508 } 15509 15510 /* 15511 * "virtcol(string)" function 15512 */ 15513 static void 15514 f_virtcol(argvars, rettv) 15515 typval_T *argvars; 15516 typval_T *rettv; 15517 { 15518 colnr_T vcol = 0; 15519 pos_T *fp; 15520 int fnum = curbuf->b_fnum; 15521 15522 fp = var2fpos(&argvars[0], FALSE, &fnum); 15523 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 15524 && fnum == curbuf->b_fnum) 15525 { 15526 getvvcol(curwin, fp, NULL, NULL, &vcol); 15527 ++vcol; 15528 } 15529 15530 rettv->vval.v_number = vcol; 15531 } 15532 15533 /* 15534 * "visualmode()" function 15535 */ 15536 /*ARGSUSED*/ 15537 static void 15538 f_visualmode(argvars, rettv) 15539 typval_T *argvars; 15540 typval_T *rettv; 15541 { 15542 #ifdef FEAT_VISUAL 15543 char_u str[2]; 15544 15545 rettv->v_type = VAR_STRING; 15546 str[0] = curbuf->b_visual_mode_eval; 15547 str[1] = NUL; 15548 rettv->vval.v_string = vim_strsave(str); 15549 15550 /* A non-zero number or non-empty string argument: reset mode. */ 15551 if ((argvars[0].v_type == VAR_NUMBER 15552 && argvars[0].vval.v_number != 0) 15553 || (argvars[0].v_type == VAR_STRING 15554 && *get_tv_string(&argvars[0]) != NUL)) 15555 curbuf->b_visual_mode_eval = NUL; 15556 #else 15557 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 15558 #endif 15559 } 15560 15561 /* 15562 * "winbufnr(nr)" function 15563 */ 15564 static void 15565 f_winbufnr(argvars, rettv) 15566 typval_T *argvars; 15567 typval_T *rettv; 15568 { 15569 win_T *wp; 15570 15571 wp = find_win_by_nr(&argvars[0]); 15572 if (wp == NULL) 15573 rettv->vval.v_number = -1; 15574 else 15575 rettv->vval.v_number = wp->w_buffer->b_fnum; 15576 } 15577 15578 /* 15579 * "wincol()" function 15580 */ 15581 /*ARGSUSED*/ 15582 static void 15583 f_wincol(argvars, rettv) 15584 typval_T *argvars; 15585 typval_T *rettv; 15586 { 15587 validate_cursor(); 15588 rettv->vval.v_number = curwin->w_wcol + 1; 15589 } 15590 15591 /* 15592 * "winheight(nr)" function 15593 */ 15594 static void 15595 f_winheight(argvars, rettv) 15596 typval_T *argvars; 15597 typval_T *rettv; 15598 { 15599 win_T *wp; 15600 15601 wp = find_win_by_nr(&argvars[0]); 15602 if (wp == NULL) 15603 rettv->vval.v_number = -1; 15604 else 15605 rettv->vval.v_number = wp->w_height; 15606 } 15607 15608 /* 15609 * "winline()" function 15610 */ 15611 /*ARGSUSED*/ 15612 static void 15613 f_winline(argvars, rettv) 15614 typval_T *argvars; 15615 typval_T *rettv; 15616 { 15617 validate_cursor(); 15618 rettv->vval.v_number = curwin->w_wrow + 1; 15619 } 15620 15621 /* 15622 * "winnr()" function 15623 */ 15624 /* ARGSUSED */ 15625 static void 15626 f_winnr(argvars, rettv) 15627 typval_T *argvars; 15628 typval_T *rettv; 15629 { 15630 int nr = 1; 15631 15632 #ifdef FEAT_WINDOWS 15633 nr = get_winnr(curtab, &argvars[0]); 15634 #endif 15635 rettv->vval.v_number = nr; 15636 } 15637 15638 /* 15639 * "winrestcmd()" function 15640 */ 15641 /* ARGSUSED */ 15642 static void 15643 f_winrestcmd(argvars, rettv) 15644 typval_T *argvars; 15645 typval_T *rettv; 15646 { 15647 #ifdef FEAT_WINDOWS 15648 win_T *wp; 15649 int winnr = 1; 15650 garray_T ga; 15651 char_u buf[50]; 15652 15653 ga_init2(&ga, (int)sizeof(char), 70); 15654 for (wp = firstwin; wp != NULL; wp = wp->w_next) 15655 { 15656 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 15657 ga_concat(&ga, buf); 15658 # ifdef FEAT_VERTSPLIT 15659 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 15660 ga_concat(&ga, buf); 15661 # endif 15662 ++winnr; 15663 } 15664 ga_append(&ga, NUL); 15665 15666 rettv->vval.v_string = ga.ga_data; 15667 #else 15668 rettv->vval.v_string = NULL; 15669 #endif 15670 rettv->v_type = VAR_STRING; 15671 } 15672 15673 /* 15674 * "winrestview()" function 15675 */ 15676 /* ARGSUSED */ 15677 static void 15678 f_winrestview(argvars, rettv) 15679 typval_T *argvars; 15680 typval_T *rettv; 15681 { 15682 dict_T *dict; 15683 15684 if (argvars[0].v_type != VAR_DICT 15685 || (dict = argvars[0].vval.v_dict) == NULL) 15686 EMSG(_(e_invarg)); 15687 else 15688 { 15689 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 15690 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 15691 #ifdef FEAT_VIRTUALEDIT 15692 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 15693 #endif 15694 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 15695 curwin->w_set_curswant = FALSE; 15696 15697 curwin->w_topline = get_dict_number(dict, (char_u *)"topline"); 15698 #ifdef FEAT_DIFF 15699 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 15700 #endif 15701 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 15702 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 15703 15704 check_cursor(); 15705 changed_cline_bef_curs(); 15706 invalidate_botline(); 15707 redraw_later(VALID); 15708 15709 if (curwin->w_topline == 0) 15710 curwin->w_topline = 1; 15711 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 15712 curwin->w_topline = curbuf->b_ml.ml_line_count; 15713 #ifdef FEAT_DIFF 15714 check_topfill(curwin, TRUE); 15715 #endif 15716 } 15717 } 15718 15719 /* 15720 * "winsaveview()" function 15721 */ 15722 /* ARGSUSED */ 15723 static void 15724 f_winsaveview(argvars, rettv) 15725 typval_T *argvars; 15726 typval_T *rettv; 15727 { 15728 dict_T *dict; 15729 15730 dict = dict_alloc(); 15731 if (dict == NULL) 15732 return; 15733 rettv->v_type = VAR_DICT; 15734 rettv->vval.v_dict = dict; 15735 ++dict->dv_refcount; 15736 15737 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 15738 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 15739 #ifdef FEAT_VIRTUALEDIT 15740 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 15741 #endif 15742 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 15743 15744 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 15745 #ifdef FEAT_DIFF 15746 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 15747 #endif 15748 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 15749 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 15750 } 15751 15752 /* 15753 * "winwidth(nr)" function 15754 */ 15755 static void 15756 f_winwidth(argvars, rettv) 15757 typval_T *argvars; 15758 typval_T *rettv; 15759 { 15760 win_T *wp; 15761 15762 wp = find_win_by_nr(&argvars[0]); 15763 if (wp == NULL) 15764 rettv->vval.v_number = -1; 15765 else 15766 #ifdef FEAT_VERTSPLIT 15767 rettv->vval.v_number = wp->w_width; 15768 #else 15769 rettv->vval.v_number = Columns; 15770 #endif 15771 } 15772 15773 /* 15774 * "writefile()" function 15775 */ 15776 static void 15777 f_writefile(argvars, rettv) 15778 typval_T *argvars; 15779 typval_T *rettv; 15780 { 15781 int binary = FALSE; 15782 char_u *fname; 15783 FILE *fd; 15784 listitem_T *li; 15785 char_u *s; 15786 int ret = 0; 15787 int c; 15788 15789 if (argvars[0].v_type != VAR_LIST) 15790 { 15791 EMSG2(_(e_listarg), "writefile()"); 15792 return; 15793 } 15794 if (argvars[0].vval.v_list == NULL) 15795 return; 15796 15797 if (argvars[2].v_type != VAR_UNKNOWN 15798 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 15799 binary = TRUE; 15800 15801 /* Always open the file in binary mode, library functions have a mind of 15802 * their own about CR-LF conversion. */ 15803 fname = get_tv_string(&argvars[1]); 15804 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 15805 { 15806 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 15807 ret = -1; 15808 } 15809 else 15810 { 15811 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 15812 li = li->li_next) 15813 { 15814 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 15815 { 15816 if (*s == '\n') 15817 c = putc(NUL, fd); 15818 else 15819 c = putc(*s, fd); 15820 if (c == EOF) 15821 { 15822 ret = -1; 15823 break; 15824 } 15825 } 15826 if (!binary || li->li_next != NULL) 15827 if (putc('\n', fd) == EOF) 15828 { 15829 ret = -1; 15830 break; 15831 } 15832 if (ret < 0) 15833 { 15834 EMSG(_(e_write)); 15835 break; 15836 } 15837 } 15838 fclose(fd); 15839 } 15840 15841 rettv->vval.v_number = ret; 15842 } 15843 15844 /* 15845 * Translate a String variable into a position. 15846 * Returns NULL when there is an error. 15847 */ 15848 static pos_T * 15849 var2fpos(varp, lnum, fnum) 15850 typval_T *varp; 15851 int lnum; /* TRUE when $ is last line */ 15852 int *fnum; /* set to fnum for '0, 'A, etc. */ 15853 { 15854 char_u *name; 15855 static pos_T pos; 15856 pos_T *pp; 15857 15858 /* Argument can be [lnum, col, coladd]. */ 15859 if (varp->v_type == VAR_LIST) 15860 { 15861 list_T *l; 15862 int len; 15863 int error = FALSE; 15864 15865 l = varp->vval.v_list; 15866 if (l == NULL) 15867 return NULL; 15868 15869 /* Get the line number */ 15870 pos.lnum = list_find_nr(l, 0L, &error); 15871 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 15872 return NULL; /* invalid line number */ 15873 15874 /* Get the column number */ 15875 pos.col = list_find_nr(l, 1L, &error); 15876 if (error) 15877 return NULL; 15878 len = (long)STRLEN(ml_get(pos.lnum)); 15879 /* Accept a position up to the NUL after the line. */ 15880 if (pos.col <= 0 || (int)pos.col > len + 1) 15881 return NULL; /* invalid column number */ 15882 --pos.col; 15883 15884 #ifdef FEAT_VIRTUALEDIT 15885 /* Get the virtual offset. Defaults to zero. */ 15886 pos.coladd = list_find_nr(l, 2L, &error); 15887 if (error) 15888 pos.coladd = 0; 15889 #endif 15890 15891 return &pos; 15892 } 15893 15894 name = get_tv_string_chk(varp); 15895 if (name == NULL) 15896 return NULL; 15897 if (name[0] == '.') /* cursor */ 15898 return &curwin->w_cursor; 15899 if (name[0] == '\'') /* mark */ 15900 { 15901 pp = getmark_fnum(name[1], FALSE, fnum); 15902 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15903 return NULL; 15904 return pp; 15905 } 15906 15907 #ifdef FEAT_VIRTUALEDIT 15908 pos.coladd = 0; 15909 #endif 15910 15911 if (name[0] == 'w' && lnum) 15912 { 15913 pos.col = 0; 15914 if (name[1] == '0') /* "w0": first visible line */ 15915 { 15916 update_topline(); 15917 pos.lnum = curwin->w_topline; 15918 return &pos; 15919 } 15920 else if (name[1] == '$') /* "w$": last visible line */ 15921 { 15922 validate_botline(); 15923 pos.lnum = curwin->w_botline - 1; 15924 return &pos; 15925 } 15926 } 15927 else if (name[0] == '$') /* last column or line */ 15928 { 15929 if (lnum) 15930 { 15931 pos.lnum = curbuf->b_ml.ml_line_count; 15932 pos.col = 0; 15933 } 15934 else 15935 { 15936 pos.lnum = curwin->w_cursor.lnum; 15937 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15938 } 15939 return &pos; 15940 } 15941 return NULL; 15942 } 15943 15944 /* 15945 * Convert list in "arg" into a position and optional file number. 15946 * When "fnump" is NULL there is no file number, only 3 items. 15947 * Note that the column is passed on as-is, the caller may want to decrement 15948 * it to use 1 for the first column. 15949 * Return FAIL when conversion is not possible, doesn't check the position for 15950 * validity. 15951 */ 15952 static int 15953 list2fpos(arg, posp, fnump) 15954 typval_T *arg; 15955 pos_T *posp; 15956 int *fnump; 15957 { 15958 list_T *l = arg->vval.v_list; 15959 long i = 0; 15960 long n; 15961 15962 /* List must be: [fnum, lnum, col, coladd] */ 15963 if (arg->v_type != VAR_LIST || l == NULL 15964 || l->lv_len != (fnump == NULL ? 3 : 4)) 15965 return FAIL; 15966 15967 if (fnump != NULL) 15968 { 15969 n = list_find_nr(l, i++, NULL); /* fnum */ 15970 if (n < 0) 15971 return FAIL; 15972 if (n == 0) 15973 n = curbuf->b_fnum; /* current buffer */ 15974 *fnump = n; 15975 } 15976 15977 n = list_find_nr(l, i++, NULL); /* lnum */ 15978 if (n < 0) 15979 return FAIL; 15980 posp->lnum = n; 15981 15982 n = list_find_nr(l, i++, NULL); /* col */ 15983 if (n < 0) 15984 return FAIL; 15985 posp->col = n; 15986 15987 #ifdef FEAT_VIRTUALEDIT 15988 n = list_find_nr(l, i, NULL); 15989 if (n < 0) 15990 return FAIL; 15991 posp->coladd = n; 15992 #endif 15993 15994 return OK; 15995 } 15996 15997 /* 15998 * Get the length of an environment variable name. 15999 * Advance "arg" to the first character after the name. 16000 * Return 0 for error. 16001 */ 16002 static int 16003 get_env_len(arg) 16004 char_u **arg; 16005 { 16006 char_u *p; 16007 int len; 16008 16009 for (p = *arg; vim_isIDc(*p); ++p) 16010 ; 16011 if (p == *arg) /* no name found */ 16012 return 0; 16013 16014 len = (int)(p - *arg); 16015 *arg = p; 16016 return len; 16017 } 16018 16019 /* 16020 * Get the length of the name of a function or internal variable. 16021 * "arg" is advanced to the first non-white character after the name. 16022 * Return 0 if something is wrong. 16023 */ 16024 static int 16025 get_id_len(arg) 16026 char_u **arg; 16027 { 16028 char_u *p; 16029 int len; 16030 16031 /* Find the end of the name. */ 16032 for (p = *arg; eval_isnamec(*p); ++p) 16033 ; 16034 if (p == *arg) /* no name found */ 16035 return 0; 16036 16037 len = (int)(p - *arg); 16038 *arg = skipwhite(p); 16039 16040 return len; 16041 } 16042 16043 /* 16044 * Get the length of the name of a variable or function. 16045 * Only the name is recognized, does not handle ".key" or "[idx]". 16046 * "arg" is advanced to the first non-white character after the name. 16047 * Return -1 if curly braces expansion failed. 16048 * Return 0 if something else is wrong. 16049 * If the name contains 'magic' {}'s, expand them and return the 16050 * expanded name in an allocated string via 'alias' - caller must free. 16051 */ 16052 static int 16053 get_name_len(arg, alias, evaluate, verbose) 16054 char_u **arg; 16055 char_u **alias; 16056 int evaluate; 16057 int verbose; 16058 { 16059 int len; 16060 char_u *p; 16061 char_u *expr_start; 16062 char_u *expr_end; 16063 16064 *alias = NULL; /* default to no alias */ 16065 16066 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 16067 && (*arg)[2] == (int)KE_SNR) 16068 { 16069 /* hard coded <SNR>, already translated */ 16070 *arg += 3; 16071 return get_id_len(arg) + 3; 16072 } 16073 len = eval_fname_script(*arg); 16074 if (len > 0) 16075 { 16076 /* literal "<SID>", "s:" or "<SNR>" */ 16077 *arg += len; 16078 } 16079 16080 /* 16081 * Find the end of the name; check for {} construction. 16082 */ 16083 p = find_name_end(*arg, &expr_start, &expr_end, 16084 len > 0 ? 0 : FNE_CHECK_START); 16085 if (expr_start != NULL) 16086 { 16087 char_u *temp_string; 16088 16089 if (!evaluate) 16090 { 16091 len += (int)(p - *arg); 16092 *arg = skipwhite(p); 16093 return len; 16094 } 16095 16096 /* 16097 * Include any <SID> etc in the expanded string: 16098 * Thus the -len here. 16099 */ 16100 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 16101 if (temp_string == NULL) 16102 return -1; 16103 *alias = temp_string; 16104 *arg = skipwhite(p); 16105 return (int)STRLEN(temp_string); 16106 } 16107 16108 len += get_id_len(arg); 16109 if (len == 0 && verbose) 16110 EMSG2(_(e_invexpr2), *arg); 16111 16112 return len; 16113 } 16114 16115 /* 16116 * Find the end of a variable or function name, taking care of magic braces. 16117 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 16118 * start and end of the first magic braces item. 16119 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 16120 * Return a pointer to just after the name. Equal to "arg" if there is no 16121 * valid name. 16122 */ 16123 static char_u * 16124 find_name_end(arg, expr_start, expr_end, flags) 16125 char_u *arg; 16126 char_u **expr_start; 16127 char_u **expr_end; 16128 int flags; 16129 { 16130 int mb_nest = 0; 16131 int br_nest = 0; 16132 char_u *p; 16133 16134 if (expr_start != NULL) 16135 { 16136 *expr_start = NULL; 16137 *expr_end = NULL; 16138 } 16139 16140 /* Quick check for valid starting character. */ 16141 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 16142 return arg; 16143 16144 for (p = arg; *p != NUL 16145 && (eval_isnamec(*p) 16146 || *p == '{' 16147 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 16148 || mb_nest != 0 16149 || br_nest != 0); mb_ptr_adv(p)) 16150 { 16151 if (*p == '\'') 16152 { 16153 /* skip over 'string' to avoid counting [ and ] inside it. */ 16154 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 16155 ; 16156 if (*p == NUL) 16157 break; 16158 } 16159 else if (*p == '"') 16160 { 16161 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 16162 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 16163 if (*p == '\\' && p[1] != NUL) 16164 ++p; 16165 if (*p == NUL) 16166 break; 16167 } 16168 16169 if (mb_nest == 0) 16170 { 16171 if (*p == '[') 16172 ++br_nest; 16173 else if (*p == ']') 16174 --br_nest; 16175 } 16176 16177 if (br_nest == 0) 16178 { 16179 if (*p == '{') 16180 { 16181 mb_nest++; 16182 if (expr_start != NULL && *expr_start == NULL) 16183 *expr_start = p; 16184 } 16185 else if (*p == '}') 16186 { 16187 mb_nest--; 16188 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 16189 *expr_end = p; 16190 } 16191 } 16192 } 16193 16194 return p; 16195 } 16196 16197 /* 16198 * Expands out the 'magic' {}'s in a variable/function name. 16199 * Note that this can call itself recursively, to deal with 16200 * constructs like foo{bar}{baz}{bam} 16201 * The four pointer arguments point to "foo{expre}ss{ion}bar" 16202 * "in_start" ^ 16203 * "expr_start" ^ 16204 * "expr_end" ^ 16205 * "in_end" ^ 16206 * 16207 * Returns a new allocated string, which the caller must free. 16208 * Returns NULL for failure. 16209 */ 16210 static char_u * 16211 make_expanded_name(in_start, expr_start, expr_end, in_end) 16212 char_u *in_start; 16213 char_u *expr_start; 16214 char_u *expr_end; 16215 char_u *in_end; 16216 { 16217 char_u c1; 16218 char_u *retval = NULL; 16219 char_u *temp_result; 16220 char_u *nextcmd = NULL; 16221 16222 if (expr_end == NULL || in_end == NULL) 16223 return NULL; 16224 *expr_start = NUL; 16225 *expr_end = NUL; 16226 c1 = *in_end; 16227 *in_end = NUL; 16228 16229 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 16230 if (temp_result != NULL && nextcmd == NULL) 16231 { 16232 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 16233 + (in_end - expr_end) + 1)); 16234 if (retval != NULL) 16235 { 16236 STRCPY(retval, in_start); 16237 STRCAT(retval, temp_result); 16238 STRCAT(retval, expr_end + 1); 16239 } 16240 } 16241 vim_free(temp_result); 16242 16243 *in_end = c1; /* put char back for error messages */ 16244 *expr_start = '{'; 16245 *expr_end = '}'; 16246 16247 if (retval != NULL) 16248 { 16249 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 16250 if (expr_start != NULL) 16251 { 16252 /* Further expansion! */ 16253 temp_result = make_expanded_name(retval, expr_start, 16254 expr_end, temp_result); 16255 vim_free(retval); 16256 retval = temp_result; 16257 } 16258 } 16259 16260 return retval; 16261 } 16262 16263 /* 16264 * Return TRUE if character "c" can be used in a variable or function name. 16265 * Does not include '{' or '}' for magic braces. 16266 */ 16267 static int 16268 eval_isnamec(c) 16269 int c; 16270 { 16271 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 16272 } 16273 16274 /* 16275 * Return TRUE if character "c" can be used as the first character in a 16276 * variable or function name (excluding '{' and '}'). 16277 */ 16278 static int 16279 eval_isnamec1(c) 16280 int c; 16281 { 16282 return (ASCII_ISALPHA(c) || c == '_'); 16283 } 16284 16285 /* 16286 * Set number v: variable to "val". 16287 */ 16288 void 16289 set_vim_var_nr(idx, val) 16290 int idx; 16291 long val; 16292 { 16293 vimvars[idx].vv_nr = val; 16294 } 16295 16296 /* 16297 * Get number v: variable value. 16298 */ 16299 long 16300 get_vim_var_nr(idx) 16301 int idx; 16302 { 16303 return vimvars[idx].vv_nr; 16304 } 16305 16306 #if defined(FEAT_AUTOCMD) || defined(PROTO) 16307 /* 16308 * Get string v: variable value. Uses a static buffer, can only be used once. 16309 */ 16310 char_u * 16311 get_vim_var_str(idx) 16312 int idx; 16313 { 16314 return get_tv_string(&vimvars[idx].vv_tv); 16315 } 16316 #endif 16317 16318 /* 16319 * Set v:count, v:count1 and v:prevcount. 16320 */ 16321 void 16322 set_vcount(count, count1) 16323 long count; 16324 long count1; 16325 { 16326 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 16327 vimvars[VV_COUNT].vv_nr = count; 16328 vimvars[VV_COUNT1].vv_nr = count1; 16329 } 16330 16331 /* 16332 * Set string v: variable to a copy of "val". 16333 */ 16334 void 16335 set_vim_var_string(idx, val, len) 16336 int idx; 16337 char_u *val; 16338 int len; /* length of "val" to use or -1 (whole string) */ 16339 { 16340 /* Need to do this (at least) once, since we can't initialize a union. 16341 * Will always be invoked when "v:progname" is set. */ 16342 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 16343 16344 vim_free(vimvars[idx].vv_str); 16345 if (val == NULL) 16346 vimvars[idx].vv_str = NULL; 16347 else if (len == -1) 16348 vimvars[idx].vv_str = vim_strsave(val); 16349 else 16350 vimvars[idx].vv_str = vim_strnsave(val, len); 16351 } 16352 16353 /* 16354 * Set v:register if needed. 16355 */ 16356 void 16357 set_reg_var(c) 16358 int c; 16359 { 16360 char_u regname; 16361 16362 if (c == 0 || c == ' ') 16363 regname = '"'; 16364 else 16365 regname = c; 16366 /* Avoid free/alloc when the value is already right. */ 16367 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 16368 set_vim_var_string(VV_REG, ®name, 1); 16369 } 16370 16371 /* 16372 * Get or set v:exception. If "oldval" == NULL, return the current value. 16373 * Otherwise, restore the value to "oldval" and return NULL. 16374 * Must always be called in pairs to save and restore v:exception! Does not 16375 * take care of memory allocations. 16376 */ 16377 char_u * 16378 v_exception(oldval) 16379 char_u *oldval; 16380 { 16381 if (oldval == NULL) 16382 return vimvars[VV_EXCEPTION].vv_str; 16383 16384 vimvars[VV_EXCEPTION].vv_str = oldval; 16385 return NULL; 16386 } 16387 16388 /* 16389 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 16390 * Otherwise, restore the value to "oldval" and return NULL. 16391 * Must always be called in pairs to save and restore v:throwpoint! Does not 16392 * take care of memory allocations. 16393 */ 16394 char_u * 16395 v_throwpoint(oldval) 16396 char_u *oldval; 16397 { 16398 if (oldval == NULL) 16399 return vimvars[VV_THROWPOINT].vv_str; 16400 16401 vimvars[VV_THROWPOINT].vv_str = oldval; 16402 return NULL; 16403 } 16404 16405 #if defined(FEAT_AUTOCMD) || defined(PROTO) 16406 /* 16407 * Set v:cmdarg. 16408 * If "eap" != NULL, use "eap" to generate the value and return the old value. 16409 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 16410 * Must always be called in pairs! 16411 */ 16412 char_u * 16413 set_cmdarg(eap, oldarg) 16414 exarg_T *eap; 16415 char_u *oldarg; 16416 { 16417 char_u *oldval; 16418 char_u *newval; 16419 unsigned len; 16420 16421 oldval = vimvars[VV_CMDARG].vv_str; 16422 if (eap == NULL) 16423 { 16424 vim_free(oldval); 16425 vimvars[VV_CMDARG].vv_str = oldarg; 16426 return NULL; 16427 } 16428 16429 if (eap->force_bin == FORCE_BIN) 16430 len = 6; 16431 else if (eap->force_bin == FORCE_NOBIN) 16432 len = 8; 16433 else 16434 len = 0; 16435 if (eap->force_ff != 0) 16436 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 16437 # ifdef FEAT_MBYTE 16438 if (eap->force_enc != 0) 16439 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 16440 if (eap->bad_char != 0) 16441 len += (unsigned)STRLEN(eap->cmd + eap->bad_char) + 7; 16442 # endif 16443 16444 newval = alloc(len + 1); 16445 if (newval == NULL) 16446 return NULL; 16447 16448 if (eap->force_bin == FORCE_BIN) 16449 sprintf((char *)newval, " ++bin"); 16450 else if (eap->force_bin == FORCE_NOBIN) 16451 sprintf((char *)newval, " ++nobin"); 16452 else 16453 *newval = NUL; 16454 if (eap->force_ff != 0) 16455 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 16456 eap->cmd + eap->force_ff); 16457 # ifdef FEAT_MBYTE 16458 if (eap->force_enc != 0) 16459 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 16460 eap->cmd + eap->force_enc); 16461 if (eap->bad_char != 0) 16462 sprintf((char *)newval + STRLEN(newval), " ++bad=%s", 16463 eap->cmd + eap->bad_char); 16464 # endif 16465 vimvars[VV_CMDARG].vv_str = newval; 16466 return oldval; 16467 } 16468 #endif 16469 16470 /* 16471 * Get the value of internal variable "name". 16472 * Return OK or FAIL. 16473 */ 16474 static int 16475 get_var_tv(name, len, rettv, verbose) 16476 char_u *name; 16477 int len; /* length of "name" */ 16478 typval_T *rettv; /* NULL when only checking existence */ 16479 int verbose; /* may give error message */ 16480 { 16481 int ret = OK; 16482 typval_T *tv = NULL; 16483 typval_T atv; 16484 dictitem_T *v; 16485 int cc; 16486 16487 /* truncate the name, so that we can use strcmp() */ 16488 cc = name[len]; 16489 name[len] = NUL; 16490 16491 /* 16492 * Check for "b:changedtick". 16493 */ 16494 if (STRCMP(name, "b:changedtick") == 0) 16495 { 16496 atv.v_type = VAR_NUMBER; 16497 atv.vval.v_number = curbuf->b_changedtick; 16498 tv = &atv; 16499 } 16500 16501 /* 16502 * Check for user-defined variables. 16503 */ 16504 else 16505 { 16506 v = find_var(name, NULL); 16507 if (v != NULL) 16508 tv = &v->di_tv; 16509 } 16510 16511 if (tv == NULL) 16512 { 16513 if (rettv != NULL && verbose) 16514 EMSG2(_(e_undefvar), name); 16515 ret = FAIL; 16516 } 16517 else if (rettv != NULL) 16518 copy_tv(tv, rettv); 16519 16520 name[len] = cc; 16521 16522 return ret; 16523 } 16524 16525 /* 16526 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 16527 * Also handle function call with Funcref variable: func(expr) 16528 * Can all be combined: dict.func(expr)[idx]['func'](expr) 16529 */ 16530 static int 16531 handle_subscript(arg, rettv, evaluate, verbose) 16532 char_u **arg; 16533 typval_T *rettv; 16534 int evaluate; /* do more than finding the end */ 16535 int verbose; /* give error messages */ 16536 { 16537 int ret = OK; 16538 dict_T *selfdict = NULL; 16539 char_u *s; 16540 int len; 16541 typval_T functv; 16542 16543 while (ret == OK 16544 && (**arg == '[' 16545 || (**arg == '.' && rettv->v_type == VAR_DICT) 16546 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 16547 && !vim_iswhite(*(*arg - 1))) 16548 { 16549 if (**arg == '(') 16550 { 16551 /* need to copy the funcref so that we can clear rettv */ 16552 functv = *rettv; 16553 rettv->v_type = VAR_UNKNOWN; 16554 16555 /* Invoke the function. Recursive! */ 16556 s = functv.vval.v_string; 16557 ret = get_func_tv(s, STRLEN(s), rettv, arg, 16558 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 16559 &len, evaluate, selfdict); 16560 16561 /* Clear the funcref afterwards, so that deleting it while 16562 * evaluating the arguments is possible (see test55). */ 16563 clear_tv(&functv); 16564 16565 /* Stop the expression evaluation when immediately aborting on 16566 * error, or when an interrupt occurred or an exception was thrown 16567 * but not caught. */ 16568 if (aborting()) 16569 { 16570 if (ret == OK) 16571 clear_tv(rettv); 16572 ret = FAIL; 16573 } 16574 dict_unref(selfdict); 16575 selfdict = NULL; 16576 } 16577 else /* **arg == '[' || **arg == '.' */ 16578 { 16579 dict_unref(selfdict); 16580 if (rettv->v_type == VAR_DICT) 16581 { 16582 selfdict = rettv->vval.v_dict; 16583 if (selfdict != NULL) 16584 ++selfdict->dv_refcount; 16585 } 16586 else 16587 selfdict = NULL; 16588 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 16589 { 16590 clear_tv(rettv); 16591 ret = FAIL; 16592 } 16593 } 16594 } 16595 dict_unref(selfdict); 16596 return ret; 16597 } 16598 16599 /* 16600 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 16601 * value). 16602 */ 16603 static typval_T * 16604 alloc_tv() 16605 { 16606 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 16607 } 16608 16609 /* 16610 * Allocate memory for a variable type-value, and assign a string to it. 16611 * The string "s" must have been allocated, it is consumed. 16612 * Return NULL for out of memory, the variable otherwise. 16613 */ 16614 static typval_T * 16615 alloc_string_tv(s) 16616 char_u *s; 16617 { 16618 typval_T *rettv; 16619 16620 rettv = alloc_tv(); 16621 if (rettv != NULL) 16622 { 16623 rettv->v_type = VAR_STRING; 16624 rettv->vval.v_string = s; 16625 } 16626 else 16627 vim_free(s); 16628 return rettv; 16629 } 16630 16631 /* 16632 * Free the memory for a variable type-value. 16633 */ 16634 void 16635 free_tv(varp) 16636 typval_T *varp; 16637 { 16638 if (varp != NULL) 16639 { 16640 switch (varp->v_type) 16641 { 16642 case VAR_FUNC: 16643 func_unref(varp->vval.v_string); 16644 /*FALLTHROUGH*/ 16645 case VAR_STRING: 16646 vim_free(varp->vval.v_string); 16647 break; 16648 case VAR_LIST: 16649 list_unref(varp->vval.v_list); 16650 break; 16651 case VAR_DICT: 16652 dict_unref(varp->vval.v_dict); 16653 break; 16654 case VAR_NUMBER: 16655 case VAR_UNKNOWN: 16656 break; 16657 default: 16658 EMSG2(_(e_intern2), "free_tv()"); 16659 break; 16660 } 16661 vim_free(varp); 16662 } 16663 } 16664 16665 /* 16666 * Free the memory for a variable value and set the value to NULL or 0. 16667 */ 16668 void 16669 clear_tv(varp) 16670 typval_T *varp; 16671 { 16672 if (varp != NULL) 16673 { 16674 switch (varp->v_type) 16675 { 16676 case VAR_FUNC: 16677 func_unref(varp->vval.v_string); 16678 /*FALLTHROUGH*/ 16679 case VAR_STRING: 16680 vim_free(varp->vval.v_string); 16681 varp->vval.v_string = NULL; 16682 break; 16683 case VAR_LIST: 16684 list_unref(varp->vval.v_list); 16685 varp->vval.v_list = NULL; 16686 break; 16687 case VAR_DICT: 16688 dict_unref(varp->vval.v_dict); 16689 varp->vval.v_dict = NULL; 16690 break; 16691 case VAR_NUMBER: 16692 varp->vval.v_number = 0; 16693 break; 16694 case VAR_UNKNOWN: 16695 break; 16696 default: 16697 EMSG2(_(e_intern2), "clear_tv()"); 16698 } 16699 varp->v_lock = 0; 16700 } 16701 } 16702 16703 /* 16704 * Set the value of a variable to NULL without freeing items. 16705 */ 16706 static void 16707 init_tv(varp) 16708 typval_T *varp; 16709 { 16710 if (varp != NULL) 16711 vim_memset(varp, 0, sizeof(typval_T)); 16712 } 16713 16714 /* 16715 * Get the number value of a variable. 16716 * If it is a String variable, uses vim_str2nr(). 16717 * For incompatible types, return 0. 16718 * get_tv_number_chk() is similar to get_tv_number(), but informs the 16719 * caller of incompatible types: it sets *denote to TRUE if "denote" 16720 * is not NULL or returns -1 otherwise. 16721 */ 16722 static long 16723 get_tv_number(varp) 16724 typval_T *varp; 16725 { 16726 int error = FALSE; 16727 16728 return get_tv_number_chk(varp, &error); /* return 0L on error */ 16729 } 16730 16731 long 16732 get_tv_number_chk(varp, denote) 16733 typval_T *varp; 16734 int *denote; 16735 { 16736 long n = 0L; 16737 16738 switch (varp->v_type) 16739 { 16740 case VAR_NUMBER: 16741 return (long)(varp->vval.v_number); 16742 case VAR_FUNC: 16743 EMSG(_("E703: Using a Funcref as a number")); 16744 break; 16745 case VAR_STRING: 16746 if (varp->vval.v_string != NULL) 16747 vim_str2nr(varp->vval.v_string, NULL, NULL, 16748 TRUE, TRUE, &n, NULL); 16749 return n; 16750 case VAR_LIST: 16751 EMSG(_("E745: Using a List as a number")); 16752 break; 16753 case VAR_DICT: 16754 EMSG(_("E728: Using a Dictionary as a number")); 16755 break; 16756 default: 16757 EMSG2(_(e_intern2), "get_tv_number()"); 16758 break; 16759 } 16760 if (denote == NULL) /* useful for values that must be unsigned */ 16761 n = -1; 16762 else 16763 *denote = TRUE; 16764 return n; 16765 } 16766 16767 /* 16768 * Get the lnum from the first argument. 16769 * Also accepts ".", "$", etc., but that only works for the current buffer. 16770 * Returns -1 on error. 16771 */ 16772 static linenr_T 16773 get_tv_lnum(argvars) 16774 typval_T *argvars; 16775 { 16776 typval_T rettv; 16777 linenr_T lnum; 16778 16779 lnum = get_tv_number_chk(&argvars[0], NULL); 16780 if (lnum == 0) /* no valid number, try using line() */ 16781 { 16782 rettv.v_type = VAR_NUMBER; 16783 f_line(argvars, &rettv); 16784 lnum = rettv.vval.v_number; 16785 clear_tv(&rettv); 16786 } 16787 return lnum; 16788 } 16789 16790 /* 16791 * Get the lnum from the first argument. 16792 * Also accepts "$", then "buf" is used. 16793 * Returns 0 on error. 16794 */ 16795 static linenr_T 16796 get_tv_lnum_buf(argvars, buf) 16797 typval_T *argvars; 16798 buf_T *buf; 16799 { 16800 if (argvars[0].v_type == VAR_STRING 16801 && argvars[0].vval.v_string != NULL 16802 && argvars[0].vval.v_string[0] == '$' 16803 && buf != NULL) 16804 return buf->b_ml.ml_line_count; 16805 return get_tv_number_chk(&argvars[0], NULL); 16806 } 16807 16808 /* 16809 * Get the string value of a variable. 16810 * If it is a Number variable, the number is converted into a string. 16811 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 16812 * get_tv_string_buf() uses a given buffer. 16813 * If the String variable has never been set, return an empty string. 16814 * Never returns NULL; 16815 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 16816 * NULL on error. 16817 */ 16818 static char_u * 16819 get_tv_string(varp) 16820 typval_T *varp; 16821 { 16822 static char_u mybuf[NUMBUFLEN]; 16823 16824 return get_tv_string_buf(varp, mybuf); 16825 } 16826 16827 static char_u * 16828 get_tv_string_buf(varp, buf) 16829 typval_T *varp; 16830 char_u *buf; 16831 { 16832 char_u *res = get_tv_string_buf_chk(varp, buf); 16833 16834 return res != NULL ? res : (char_u *)""; 16835 } 16836 16837 char_u * 16838 get_tv_string_chk(varp) 16839 typval_T *varp; 16840 { 16841 static char_u mybuf[NUMBUFLEN]; 16842 16843 return get_tv_string_buf_chk(varp, mybuf); 16844 } 16845 16846 static char_u * 16847 get_tv_string_buf_chk(varp, buf) 16848 typval_T *varp; 16849 char_u *buf; 16850 { 16851 switch (varp->v_type) 16852 { 16853 case VAR_NUMBER: 16854 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 16855 return buf; 16856 case VAR_FUNC: 16857 EMSG(_("E729: using Funcref as a String")); 16858 break; 16859 case VAR_LIST: 16860 EMSG(_("E730: using List as a String")); 16861 break; 16862 case VAR_DICT: 16863 EMSG(_("E731: using Dictionary as a String")); 16864 break; 16865 case VAR_STRING: 16866 if (varp->vval.v_string != NULL) 16867 return varp->vval.v_string; 16868 return (char_u *)""; 16869 default: 16870 EMSG2(_(e_intern2), "get_tv_string_buf()"); 16871 break; 16872 } 16873 return NULL; 16874 } 16875 16876 /* 16877 * Find variable "name" in the list of variables. 16878 * Return a pointer to it if found, NULL if not found. 16879 * Careful: "a:0" variables don't have a name. 16880 * When "htp" is not NULL we are writing to the variable, set "htp" to the 16881 * hashtab_T used. 16882 */ 16883 static dictitem_T * 16884 find_var(name, htp) 16885 char_u *name; 16886 hashtab_T **htp; 16887 { 16888 char_u *varname; 16889 hashtab_T *ht; 16890 16891 ht = find_var_ht(name, &varname); 16892 if (htp != NULL) 16893 *htp = ht; 16894 if (ht == NULL) 16895 return NULL; 16896 return find_var_in_ht(ht, varname, htp != NULL); 16897 } 16898 16899 /* 16900 * Find variable "varname" in hashtab "ht". 16901 * Returns NULL if not found. 16902 */ 16903 static dictitem_T * 16904 find_var_in_ht(ht, varname, writing) 16905 hashtab_T *ht; 16906 char_u *varname; 16907 int writing; 16908 { 16909 hashitem_T *hi; 16910 16911 if (*varname == NUL) 16912 { 16913 /* Must be something like "s:", otherwise "ht" would be NULL. */ 16914 switch (varname[-2]) 16915 { 16916 case 's': return &SCRIPT_SV(current_SID).sv_var; 16917 case 'g': return &globvars_var; 16918 case 'v': return &vimvars_var; 16919 case 'b': return &curbuf->b_bufvar; 16920 case 'w': return &curwin->w_winvar; 16921 case 'l': return current_funccal == NULL 16922 ? NULL : ¤t_funccal->l_vars_var; 16923 case 'a': return current_funccal == NULL 16924 ? NULL : ¤t_funccal->l_avars_var; 16925 } 16926 return NULL; 16927 } 16928 16929 hi = hash_find(ht, varname); 16930 if (HASHITEM_EMPTY(hi)) 16931 { 16932 /* For global variables we may try auto-loading the script. If it 16933 * worked find the variable again. Don't auto-load a script if it was 16934 * loaded already, otherwise it would be loaded every time when 16935 * checking if a function name is a Funcref variable. */ 16936 if (ht == &globvarht && !writing 16937 && script_autoload(varname, FALSE) && !aborting()) 16938 hi = hash_find(ht, varname); 16939 if (HASHITEM_EMPTY(hi)) 16940 return NULL; 16941 } 16942 return HI2DI(hi); 16943 } 16944 16945 /* 16946 * Find the hashtab used for a variable name. 16947 * Set "varname" to the start of name without ':'. 16948 */ 16949 static hashtab_T * 16950 find_var_ht(name, varname) 16951 char_u *name; 16952 char_u **varname; 16953 { 16954 hashitem_T *hi; 16955 16956 if (name[1] != ':') 16957 { 16958 /* The name must not start with a colon or #. */ 16959 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16960 return NULL; 16961 *varname = name; 16962 16963 /* "version" is "v:version" in all scopes */ 16964 hi = hash_find(&compat_hashtab, name); 16965 if (!HASHITEM_EMPTY(hi)) 16966 return &compat_hashtab; 16967 16968 if (current_funccal == NULL) 16969 return &globvarht; /* global variable */ 16970 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16971 } 16972 *varname = name + 2; 16973 if (*name == 'g') /* global variable */ 16974 return &globvarht; 16975 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16976 */ 16977 if (vim_strchr(name + 2, ':') != NULL 16978 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16979 return NULL; 16980 if (*name == 'b') /* buffer variable */ 16981 return &curbuf->b_vars.dv_hashtab; 16982 if (*name == 'w') /* window variable */ 16983 return &curwin->w_vars.dv_hashtab; 16984 if (*name == 'v') /* v: variable */ 16985 return &vimvarht; 16986 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16987 return ¤t_funccal->l_avars.dv_hashtab; 16988 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16989 return ¤t_funccal->l_vars.dv_hashtab; 16990 if (*name == 's' /* script variable */ 16991 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16992 return &SCRIPT_VARS(current_SID); 16993 return NULL; 16994 } 16995 16996 /* 16997 * Get the string value of a (global/local) variable. 16998 * Returns NULL when it doesn't exist. 16999 */ 17000 char_u * 17001 get_var_value(name) 17002 char_u *name; 17003 { 17004 dictitem_T *v; 17005 17006 v = find_var(name, NULL); 17007 if (v == NULL) 17008 return NULL; 17009 return get_tv_string(&v->di_tv); 17010 } 17011 17012 /* 17013 * Allocate a new hashtab for a sourced script. It will be used while 17014 * sourcing this script and when executing functions defined in the script. 17015 */ 17016 void 17017 new_script_vars(id) 17018 scid_T id; 17019 { 17020 int i; 17021 hashtab_T *ht; 17022 scriptvar_T *sv; 17023 17024 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 17025 { 17026 /* Re-allocating ga_data means that an ht_array pointing to 17027 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 17028 * at its init value. Also reset "v_dict", it's always the same. */ 17029 for (i = 1; i <= ga_scripts.ga_len; ++i) 17030 { 17031 ht = &SCRIPT_VARS(i); 17032 if (ht->ht_mask == HT_INIT_SIZE - 1) 17033 ht->ht_array = ht->ht_smallarray; 17034 sv = &SCRIPT_SV(i); 17035 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 17036 } 17037 17038 while (ga_scripts.ga_len < id) 17039 { 17040 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 17041 init_var_dict(&sv->sv_dict, &sv->sv_var); 17042 ++ga_scripts.ga_len; 17043 } 17044 } 17045 } 17046 17047 /* 17048 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 17049 * point to it. 17050 */ 17051 void 17052 init_var_dict(dict, dict_var) 17053 dict_T *dict; 17054 dictitem_T *dict_var; 17055 { 17056 hash_init(&dict->dv_hashtab); 17057 dict->dv_refcount = 99999; 17058 dict_var->di_tv.vval.v_dict = dict; 17059 dict_var->di_tv.v_type = VAR_DICT; 17060 dict_var->di_tv.v_lock = VAR_FIXED; 17061 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 17062 dict_var->di_key[0] = NUL; 17063 } 17064 17065 /* 17066 * Clean up a list of internal variables. 17067 * Frees all allocated variables and the value they contain. 17068 * Clears hashtab "ht", does not free it. 17069 */ 17070 void 17071 vars_clear(ht) 17072 hashtab_T *ht; 17073 { 17074 vars_clear_ext(ht, TRUE); 17075 } 17076 17077 /* 17078 * Like vars_clear(), but only free the value if "free_val" is TRUE. 17079 */ 17080 static void 17081 vars_clear_ext(ht, free_val) 17082 hashtab_T *ht; 17083 int free_val; 17084 { 17085 int todo; 17086 hashitem_T *hi; 17087 dictitem_T *v; 17088 17089 hash_lock(ht); 17090 todo = ht->ht_used; 17091 for (hi = ht->ht_array; todo > 0; ++hi) 17092 { 17093 if (!HASHITEM_EMPTY(hi)) 17094 { 17095 --todo; 17096 17097 /* Free the variable. Don't remove it from the hashtab, 17098 * ht_array might change then. hash_clear() takes care of it 17099 * later. */ 17100 v = HI2DI(hi); 17101 if (free_val) 17102 clear_tv(&v->di_tv); 17103 if ((v->di_flags & DI_FLAGS_FIX) == 0) 17104 vim_free(v); 17105 } 17106 } 17107 hash_clear(ht); 17108 ht->ht_used = 0; 17109 } 17110 17111 /* 17112 * Delete a variable from hashtab "ht" at item "hi". 17113 * Clear the variable value and free the dictitem. 17114 */ 17115 static void 17116 delete_var(ht, hi) 17117 hashtab_T *ht; 17118 hashitem_T *hi; 17119 { 17120 dictitem_T *di = HI2DI(hi); 17121 17122 hash_remove(ht, hi); 17123 clear_tv(&di->di_tv); 17124 vim_free(di); 17125 } 17126 17127 /* 17128 * List the value of one internal variable. 17129 */ 17130 static void 17131 list_one_var(v, prefix) 17132 dictitem_T *v; 17133 char_u *prefix; 17134 { 17135 char_u *tofree; 17136 char_u *s; 17137 char_u numbuf[NUMBUFLEN]; 17138 17139 s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID); 17140 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 17141 s == NULL ? (char_u *)"" : s); 17142 vim_free(tofree); 17143 } 17144 17145 static void 17146 list_one_var_a(prefix, name, type, string) 17147 char_u *prefix; 17148 char_u *name; 17149 int type; 17150 char_u *string; 17151 { 17152 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 17153 if (name != NULL) /* "a:" vars don't have a name stored */ 17154 msg_puts(name); 17155 msg_putchar(' '); 17156 msg_advance(22); 17157 if (type == VAR_NUMBER) 17158 msg_putchar('#'); 17159 else if (type == VAR_FUNC) 17160 msg_putchar('*'); 17161 else if (type == VAR_LIST) 17162 { 17163 msg_putchar('['); 17164 if (*string == '[') 17165 ++string; 17166 } 17167 else if (type == VAR_DICT) 17168 { 17169 msg_putchar('{'); 17170 if (*string == '{') 17171 ++string; 17172 } 17173 else 17174 msg_putchar(' '); 17175 17176 msg_outtrans(string); 17177 17178 if (type == VAR_FUNC) 17179 msg_puts((char_u *)"()"); 17180 } 17181 17182 /* 17183 * Set variable "name" to value in "tv". 17184 * If the variable already exists, the value is updated. 17185 * Otherwise the variable is created. 17186 */ 17187 static void 17188 set_var(name, tv, copy) 17189 char_u *name; 17190 typval_T *tv; 17191 int copy; /* make copy of value in "tv" */ 17192 { 17193 dictitem_T *v; 17194 char_u *varname; 17195 hashtab_T *ht; 17196 char_u *p; 17197 17198 if (tv->v_type == VAR_FUNC) 17199 { 17200 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 17201 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 17202 ? name[2] : name[0])) 17203 { 17204 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 17205 return; 17206 } 17207 if (function_exists(name)) 17208 { 17209 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 17210 name); 17211 return; 17212 } 17213 } 17214 17215 ht = find_var_ht(name, &varname); 17216 if (ht == NULL || *varname == NUL) 17217 { 17218 EMSG2(_(e_illvar), name); 17219 return; 17220 } 17221 17222 v = find_var_in_ht(ht, varname, TRUE); 17223 if (v != NULL) 17224 { 17225 /* existing variable, need to clear the value */ 17226 if (var_check_ro(v->di_flags, name) 17227 || tv_check_lock(v->di_tv.v_lock, name)) 17228 return; 17229 if (v->di_tv.v_type != tv->v_type 17230 && !((v->di_tv.v_type == VAR_STRING 17231 || v->di_tv.v_type == VAR_NUMBER) 17232 && (tv->v_type == VAR_STRING 17233 || tv->v_type == VAR_NUMBER))) 17234 { 17235 EMSG2(_("E706: Variable type mismatch for: %s"), name); 17236 return; 17237 } 17238 17239 /* 17240 * Handle setting internal v: variables separately: we don't change 17241 * the type. 17242 */ 17243 if (ht == &vimvarht) 17244 { 17245 if (v->di_tv.v_type == VAR_STRING) 17246 { 17247 vim_free(v->di_tv.vval.v_string); 17248 if (copy || tv->v_type != VAR_STRING) 17249 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 17250 else 17251 { 17252 /* Take over the string to avoid an extra alloc/free. */ 17253 v->di_tv.vval.v_string = tv->vval.v_string; 17254 tv->vval.v_string = NULL; 17255 } 17256 } 17257 else if (v->di_tv.v_type != VAR_NUMBER) 17258 EMSG2(_(e_intern2), "set_var()"); 17259 else 17260 v->di_tv.vval.v_number = get_tv_number(tv); 17261 return; 17262 } 17263 17264 clear_tv(&v->di_tv); 17265 } 17266 else /* add a new variable */ 17267 { 17268 /* Make sure the variable name is valid. */ 17269 for (p = varname; *p != NUL; ++p) 17270 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 17271 && *p != AUTOLOAD_CHAR) 17272 { 17273 EMSG2(_(e_illvar), varname); 17274 return; 17275 } 17276 17277 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 17278 + STRLEN(varname))); 17279 if (v == NULL) 17280 return; 17281 STRCPY(v->di_key, varname); 17282 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 17283 { 17284 vim_free(v); 17285 return; 17286 } 17287 v->di_flags = 0; 17288 } 17289 17290 if (copy || tv->v_type == VAR_NUMBER) 17291 copy_tv(tv, &v->di_tv); 17292 else 17293 { 17294 v->di_tv = *tv; 17295 v->di_tv.v_lock = 0; 17296 init_tv(tv); 17297 } 17298 } 17299 17300 /* 17301 * Return TRUE if di_flags "flags" indicate read-only variable "name". 17302 * Also give an error message. 17303 */ 17304 static int 17305 var_check_ro(flags, name) 17306 int flags; 17307 char_u *name; 17308 { 17309 if (flags & DI_FLAGS_RO) 17310 { 17311 EMSG2(_(e_readonlyvar), name); 17312 return TRUE; 17313 } 17314 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 17315 { 17316 EMSG2(_(e_readonlysbx), name); 17317 return TRUE; 17318 } 17319 return FALSE; 17320 } 17321 17322 /* 17323 * Return TRUE if typeval "tv" is set to be locked (immutable). 17324 * Also give an error message, using "name". 17325 */ 17326 static int 17327 tv_check_lock(lock, name) 17328 int lock; 17329 char_u *name; 17330 { 17331 if (lock & VAR_LOCKED) 17332 { 17333 EMSG2(_("E741: Value is locked: %s"), 17334 name == NULL ? (char_u *)_("Unknown") : name); 17335 return TRUE; 17336 } 17337 if (lock & VAR_FIXED) 17338 { 17339 EMSG2(_("E742: Cannot change value of %s"), 17340 name == NULL ? (char_u *)_("Unknown") : name); 17341 return TRUE; 17342 } 17343 return FALSE; 17344 } 17345 17346 /* 17347 * Copy the values from typval_T "from" to typval_T "to". 17348 * When needed allocates string or increases reference count. 17349 * Does not make a copy of a list or dict but copies the reference! 17350 */ 17351 static void 17352 copy_tv(from, to) 17353 typval_T *from; 17354 typval_T *to; 17355 { 17356 to->v_type = from->v_type; 17357 to->v_lock = 0; 17358 switch (from->v_type) 17359 { 17360 case VAR_NUMBER: 17361 to->vval.v_number = from->vval.v_number; 17362 break; 17363 case VAR_STRING: 17364 case VAR_FUNC: 17365 if (from->vval.v_string == NULL) 17366 to->vval.v_string = NULL; 17367 else 17368 { 17369 to->vval.v_string = vim_strsave(from->vval.v_string); 17370 if (from->v_type == VAR_FUNC) 17371 func_ref(to->vval.v_string); 17372 } 17373 break; 17374 case VAR_LIST: 17375 if (from->vval.v_list == NULL) 17376 to->vval.v_list = NULL; 17377 else 17378 { 17379 to->vval.v_list = from->vval.v_list; 17380 ++to->vval.v_list->lv_refcount; 17381 } 17382 break; 17383 case VAR_DICT: 17384 if (from->vval.v_dict == NULL) 17385 to->vval.v_dict = NULL; 17386 else 17387 { 17388 to->vval.v_dict = from->vval.v_dict; 17389 ++to->vval.v_dict->dv_refcount; 17390 } 17391 break; 17392 default: 17393 EMSG2(_(e_intern2), "copy_tv()"); 17394 break; 17395 } 17396 } 17397 17398 /* 17399 * Make a copy of an item. 17400 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 17401 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 17402 * reference to an already copied list/dict can be used. 17403 * Returns FAIL or OK. 17404 */ 17405 static int 17406 item_copy(from, to, deep, copyID) 17407 typval_T *from; 17408 typval_T *to; 17409 int deep; 17410 int copyID; 17411 { 17412 static int recurse = 0; 17413 int ret = OK; 17414 17415 if (recurse >= DICT_MAXNEST) 17416 { 17417 EMSG(_("E698: variable nested too deep for making a copy")); 17418 return FAIL; 17419 } 17420 ++recurse; 17421 17422 switch (from->v_type) 17423 { 17424 case VAR_NUMBER: 17425 case VAR_STRING: 17426 case VAR_FUNC: 17427 copy_tv(from, to); 17428 break; 17429 case VAR_LIST: 17430 to->v_type = VAR_LIST; 17431 to->v_lock = 0; 17432 if (from->vval.v_list == NULL) 17433 to->vval.v_list = NULL; 17434 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 17435 { 17436 /* use the copy made earlier */ 17437 to->vval.v_list = from->vval.v_list->lv_copylist; 17438 ++to->vval.v_list->lv_refcount; 17439 } 17440 else 17441 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 17442 if (to->vval.v_list == NULL) 17443 ret = FAIL; 17444 break; 17445 case VAR_DICT: 17446 to->v_type = VAR_DICT; 17447 to->v_lock = 0; 17448 if (from->vval.v_dict == NULL) 17449 to->vval.v_dict = NULL; 17450 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 17451 { 17452 /* use the copy made earlier */ 17453 to->vval.v_dict = from->vval.v_dict->dv_copydict; 17454 ++to->vval.v_dict->dv_refcount; 17455 } 17456 else 17457 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 17458 if (to->vval.v_dict == NULL) 17459 ret = FAIL; 17460 break; 17461 default: 17462 EMSG2(_(e_intern2), "item_copy()"); 17463 ret = FAIL; 17464 } 17465 --recurse; 17466 return ret; 17467 } 17468 17469 /* 17470 * ":echo expr1 ..." print each argument separated with a space, add a 17471 * newline at the end. 17472 * ":echon expr1 ..." print each argument plain. 17473 */ 17474 void 17475 ex_echo(eap) 17476 exarg_T *eap; 17477 { 17478 char_u *arg = eap->arg; 17479 typval_T rettv; 17480 char_u *tofree; 17481 char_u *p; 17482 int needclr = TRUE; 17483 int atstart = TRUE; 17484 char_u numbuf[NUMBUFLEN]; 17485 17486 if (eap->skip) 17487 ++emsg_skip; 17488 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 17489 { 17490 p = arg; 17491 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 17492 { 17493 /* 17494 * Report the invalid expression unless the expression evaluation 17495 * has been cancelled due to an aborting error, an interrupt, or an 17496 * exception. 17497 */ 17498 if (!aborting()) 17499 EMSG2(_(e_invexpr2), p); 17500 break; 17501 } 17502 if (!eap->skip) 17503 { 17504 if (atstart) 17505 { 17506 atstart = FALSE; 17507 /* Call msg_start() after eval1(), evaluating the expression 17508 * may cause a message to appear. */ 17509 if (eap->cmdidx == CMD_echo) 17510 msg_start(); 17511 } 17512 else if (eap->cmdidx == CMD_echo) 17513 msg_puts_attr((char_u *)" ", echo_attr); 17514 p = echo_string(&rettv, &tofree, numbuf, ++current_copyID); 17515 if (p != NULL) 17516 for ( ; *p != NUL && !got_int; ++p) 17517 { 17518 if (*p == '\n' || *p == '\r' || *p == TAB) 17519 { 17520 if (*p != TAB && needclr) 17521 { 17522 /* remove any text still there from the command */ 17523 msg_clr_eos(); 17524 needclr = FALSE; 17525 } 17526 msg_putchar_attr(*p, echo_attr); 17527 } 17528 else 17529 { 17530 #ifdef FEAT_MBYTE 17531 if (has_mbyte) 17532 { 17533 int i = (*mb_ptr2len)(p); 17534 17535 (void)msg_outtrans_len_attr(p, i, echo_attr); 17536 p += i - 1; 17537 } 17538 else 17539 #endif 17540 (void)msg_outtrans_len_attr(p, 1, echo_attr); 17541 } 17542 } 17543 vim_free(tofree); 17544 } 17545 clear_tv(&rettv); 17546 arg = skipwhite(arg); 17547 } 17548 eap->nextcmd = check_nextcmd(arg); 17549 17550 if (eap->skip) 17551 --emsg_skip; 17552 else 17553 { 17554 /* remove text that may still be there from the command */ 17555 if (needclr) 17556 msg_clr_eos(); 17557 if (eap->cmdidx == CMD_echo) 17558 msg_end(); 17559 } 17560 } 17561 17562 /* 17563 * ":echohl {name}". 17564 */ 17565 void 17566 ex_echohl(eap) 17567 exarg_T *eap; 17568 { 17569 int id; 17570 17571 id = syn_name2id(eap->arg); 17572 if (id == 0) 17573 echo_attr = 0; 17574 else 17575 echo_attr = syn_id2attr(id); 17576 } 17577 17578 /* 17579 * ":execute expr1 ..." execute the result of an expression. 17580 * ":echomsg expr1 ..." Print a message 17581 * ":echoerr expr1 ..." Print an error 17582 * Each gets spaces around each argument and a newline at the end for 17583 * echo commands 17584 */ 17585 void 17586 ex_execute(eap) 17587 exarg_T *eap; 17588 { 17589 char_u *arg = eap->arg; 17590 typval_T rettv; 17591 int ret = OK; 17592 char_u *p; 17593 garray_T ga; 17594 int len; 17595 int save_did_emsg; 17596 17597 ga_init2(&ga, 1, 80); 17598 17599 if (eap->skip) 17600 ++emsg_skip; 17601 while (*arg != NUL && *arg != '|' && *arg != '\n') 17602 { 17603 p = arg; 17604 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 17605 { 17606 /* 17607 * Report the invalid expression unless the expression evaluation 17608 * has been cancelled due to an aborting error, an interrupt, or an 17609 * exception. 17610 */ 17611 if (!aborting()) 17612 EMSG2(_(e_invexpr2), p); 17613 ret = FAIL; 17614 break; 17615 } 17616 17617 if (!eap->skip) 17618 { 17619 p = get_tv_string(&rettv); 17620 len = (int)STRLEN(p); 17621 if (ga_grow(&ga, len + 2) == FAIL) 17622 { 17623 clear_tv(&rettv); 17624 ret = FAIL; 17625 break; 17626 } 17627 if (ga.ga_len) 17628 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 17629 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 17630 ga.ga_len += len; 17631 } 17632 17633 clear_tv(&rettv); 17634 arg = skipwhite(arg); 17635 } 17636 17637 if (ret != FAIL && ga.ga_data != NULL) 17638 { 17639 if (eap->cmdidx == CMD_echomsg) 17640 { 17641 MSG_ATTR(ga.ga_data, echo_attr); 17642 out_flush(); 17643 } 17644 else if (eap->cmdidx == CMD_echoerr) 17645 { 17646 /* We don't want to abort following commands, restore did_emsg. */ 17647 save_did_emsg = did_emsg; 17648 EMSG((char_u *)ga.ga_data); 17649 if (!force_abort) 17650 did_emsg = save_did_emsg; 17651 } 17652 else if (eap->cmdidx == CMD_execute) 17653 do_cmdline((char_u *)ga.ga_data, 17654 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 17655 } 17656 17657 ga_clear(&ga); 17658 17659 if (eap->skip) 17660 --emsg_skip; 17661 17662 eap->nextcmd = check_nextcmd(arg); 17663 } 17664 17665 /* 17666 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 17667 * "arg" points to the "&" or '+' when called, to "option" when returning. 17668 * Returns NULL when no option name found. Otherwise pointer to the char 17669 * after the option name. 17670 */ 17671 static char_u * 17672 find_option_end(arg, opt_flags) 17673 char_u **arg; 17674 int *opt_flags; 17675 { 17676 char_u *p = *arg; 17677 17678 ++p; 17679 if (*p == 'g' && p[1] == ':') 17680 { 17681 *opt_flags = OPT_GLOBAL; 17682 p += 2; 17683 } 17684 else if (*p == 'l' && p[1] == ':') 17685 { 17686 *opt_flags = OPT_LOCAL; 17687 p += 2; 17688 } 17689 else 17690 *opt_flags = 0; 17691 17692 if (!ASCII_ISALPHA(*p)) 17693 return NULL; 17694 *arg = p; 17695 17696 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 17697 p += 4; /* termcap option */ 17698 else 17699 while (ASCII_ISALPHA(*p)) 17700 ++p; 17701 return p; 17702 } 17703 17704 /* 17705 * ":function" 17706 */ 17707 void 17708 ex_function(eap) 17709 exarg_T *eap; 17710 { 17711 char_u *theline; 17712 int j; 17713 int c; 17714 int saved_did_emsg; 17715 char_u *name = NULL; 17716 char_u *p; 17717 char_u *arg; 17718 char_u *line_arg = NULL; 17719 garray_T newargs; 17720 garray_T newlines; 17721 int varargs = FALSE; 17722 int mustend = FALSE; 17723 int flags = 0; 17724 ufunc_T *fp; 17725 int indent; 17726 int nesting; 17727 char_u *skip_until = NULL; 17728 dictitem_T *v; 17729 funcdict_T fudi; 17730 static int func_nr = 0; /* number for nameless function */ 17731 int paren; 17732 hashtab_T *ht; 17733 int todo; 17734 hashitem_T *hi; 17735 int sourcing_lnum_off; 17736 17737 /* 17738 * ":function" without argument: list functions. 17739 */ 17740 if (ends_excmd(*eap->arg)) 17741 { 17742 if (!eap->skip) 17743 { 17744 todo = func_hashtab.ht_used; 17745 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17746 { 17747 if (!HASHITEM_EMPTY(hi)) 17748 { 17749 --todo; 17750 fp = HI2UF(hi); 17751 if (!isdigit(*fp->uf_name)) 17752 list_func_head(fp, FALSE); 17753 } 17754 } 17755 } 17756 eap->nextcmd = check_nextcmd(eap->arg); 17757 return; 17758 } 17759 17760 /* 17761 * ":function /pat": list functions matching pattern. 17762 */ 17763 if (*eap->arg == '/') 17764 { 17765 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 17766 if (!eap->skip) 17767 { 17768 regmatch_T regmatch; 17769 17770 c = *p; 17771 *p = NUL; 17772 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 17773 *p = c; 17774 if (regmatch.regprog != NULL) 17775 { 17776 regmatch.rm_ic = p_ic; 17777 17778 todo = func_hashtab.ht_used; 17779 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17780 { 17781 if (!HASHITEM_EMPTY(hi)) 17782 { 17783 --todo; 17784 fp = HI2UF(hi); 17785 if (!isdigit(*fp->uf_name) 17786 && vim_regexec(®match, fp->uf_name, 0)) 17787 list_func_head(fp, FALSE); 17788 } 17789 } 17790 } 17791 } 17792 if (*p == '/') 17793 ++p; 17794 eap->nextcmd = check_nextcmd(p); 17795 return; 17796 } 17797 17798 /* 17799 * Get the function name. There are these situations: 17800 * func normal function name 17801 * "name" == func, "fudi.fd_dict" == NULL 17802 * dict.func new dictionary entry 17803 * "name" == NULL, "fudi.fd_dict" set, 17804 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 17805 * dict.func existing dict entry with a Funcref 17806 * "name" == func, "fudi.fd_dict" set, 17807 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17808 * dict.func existing dict entry that's not a Funcref 17809 * "name" == NULL, "fudi.fd_dict" set, 17810 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17811 */ 17812 p = eap->arg; 17813 name = trans_function_name(&p, eap->skip, 0, &fudi); 17814 paren = (vim_strchr(p, '(') != NULL); 17815 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 17816 { 17817 /* 17818 * Return on an invalid expression in braces, unless the expression 17819 * evaluation has been cancelled due to an aborting error, an 17820 * interrupt, or an exception. 17821 */ 17822 if (!aborting()) 17823 { 17824 if (!eap->skip && fudi.fd_newkey != NULL) 17825 EMSG2(_(e_dictkey), fudi.fd_newkey); 17826 vim_free(fudi.fd_newkey); 17827 return; 17828 } 17829 else 17830 eap->skip = TRUE; 17831 } 17832 17833 /* An error in a function call during evaluation of an expression in magic 17834 * braces should not cause the function not to be defined. */ 17835 saved_did_emsg = did_emsg; 17836 did_emsg = FALSE; 17837 17838 /* 17839 * ":function func" with only function name: list function. 17840 */ 17841 if (!paren) 17842 { 17843 if (!ends_excmd(*skipwhite(p))) 17844 { 17845 EMSG(_(e_trailing)); 17846 goto ret_free; 17847 } 17848 eap->nextcmd = check_nextcmd(p); 17849 if (eap->nextcmd != NULL) 17850 *p = NUL; 17851 if (!eap->skip && !got_int) 17852 { 17853 fp = find_func(name); 17854 if (fp != NULL) 17855 { 17856 list_func_head(fp, TRUE); 17857 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 17858 { 17859 if (FUNCLINE(fp, j) == NULL) 17860 continue; 17861 msg_putchar('\n'); 17862 msg_outnum((long)(j + 1)); 17863 if (j < 9) 17864 msg_putchar(' '); 17865 if (j < 99) 17866 msg_putchar(' '); 17867 msg_prt_line(FUNCLINE(fp, j), FALSE); 17868 out_flush(); /* show a line at a time */ 17869 ui_breakcheck(); 17870 } 17871 if (!got_int) 17872 { 17873 msg_putchar('\n'); 17874 msg_puts((char_u *)" endfunction"); 17875 } 17876 } 17877 else 17878 emsg_funcname("E123: Undefined function: %s", name); 17879 } 17880 goto ret_free; 17881 } 17882 17883 /* 17884 * ":function name(arg1, arg2)" Define function. 17885 */ 17886 p = skipwhite(p); 17887 if (*p != '(') 17888 { 17889 if (!eap->skip) 17890 { 17891 EMSG2(_("E124: Missing '(': %s"), eap->arg); 17892 goto ret_free; 17893 } 17894 /* attempt to continue by skipping some text */ 17895 if (vim_strchr(p, '(') != NULL) 17896 p = vim_strchr(p, '('); 17897 } 17898 p = skipwhite(p + 1); 17899 17900 ga_init2(&newargs, (int)sizeof(char_u *), 3); 17901 ga_init2(&newlines, (int)sizeof(char_u *), 3); 17902 17903 if (!eap->skip) 17904 { 17905 /* Check the name of the function. */ 17906 if (name != NULL) 17907 arg = name; 17908 else 17909 arg = fudi.fd_newkey; 17910 if (arg != NULL) 17911 { 17912 if (*arg == K_SPECIAL) 17913 j = 3; 17914 else 17915 j = 0; 17916 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 17917 : eval_isnamec(arg[j]))) 17918 ++j; 17919 if (arg[j] != NUL) 17920 emsg_funcname(_(e_invarg2), arg); 17921 } 17922 } 17923 17924 /* 17925 * Isolate the arguments: "arg1, arg2, ...)" 17926 */ 17927 while (*p != ')') 17928 { 17929 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 17930 { 17931 varargs = TRUE; 17932 p += 3; 17933 mustend = TRUE; 17934 } 17935 else 17936 { 17937 arg = p; 17938 while (ASCII_ISALNUM(*p) || *p == '_') 17939 ++p; 17940 if (arg == p || isdigit(*arg) 17941 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 17942 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 17943 { 17944 if (!eap->skip) 17945 EMSG2(_("E125: Illegal argument: %s"), arg); 17946 break; 17947 } 17948 if (ga_grow(&newargs, 1) == FAIL) 17949 goto erret; 17950 c = *p; 17951 *p = NUL; 17952 arg = vim_strsave(arg); 17953 if (arg == NULL) 17954 goto erret; 17955 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 17956 *p = c; 17957 newargs.ga_len++; 17958 if (*p == ',') 17959 ++p; 17960 else 17961 mustend = TRUE; 17962 } 17963 p = skipwhite(p); 17964 if (mustend && *p != ')') 17965 { 17966 if (!eap->skip) 17967 EMSG2(_(e_invarg2), eap->arg); 17968 break; 17969 } 17970 } 17971 ++p; /* skip the ')' */ 17972 17973 /* find extra arguments "range", "dict" and "abort" */ 17974 for (;;) 17975 { 17976 p = skipwhite(p); 17977 if (STRNCMP(p, "range", 5) == 0) 17978 { 17979 flags |= FC_RANGE; 17980 p += 5; 17981 } 17982 else if (STRNCMP(p, "dict", 4) == 0) 17983 { 17984 flags |= FC_DICT; 17985 p += 4; 17986 } 17987 else if (STRNCMP(p, "abort", 5) == 0) 17988 { 17989 flags |= FC_ABORT; 17990 p += 5; 17991 } 17992 else 17993 break; 17994 } 17995 17996 /* When there is a line break use what follows for the function body. 17997 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 17998 if (*p == '\n') 17999 line_arg = p + 1; 18000 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 18001 EMSG(_(e_trailing)); 18002 18003 /* 18004 * Read the body of the function, until ":endfunction" is found. 18005 */ 18006 if (KeyTyped) 18007 { 18008 /* Check if the function already exists, don't let the user type the 18009 * whole function before telling him it doesn't work! For a script we 18010 * need to skip the body to be able to find what follows. */ 18011 if (!eap->skip && !eap->forceit) 18012 { 18013 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 18014 EMSG(_(e_funcdict)); 18015 else if (name != NULL && find_func(name) != NULL) 18016 emsg_funcname(e_funcexts, name); 18017 } 18018 18019 if (!eap->skip && did_emsg) 18020 goto erret; 18021 18022 msg_putchar('\n'); /* don't overwrite the function name */ 18023 cmdline_row = msg_row; 18024 } 18025 18026 indent = 2; 18027 nesting = 0; 18028 for (;;) 18029 { 18030 msg_scroll = TRUE; 18031 need_wait_return = FALSE; 18032 sourcing_lnum_off = sourcing_lnum; 18033 18034 if (line_arg != NULL) 18035 { 18036 /* Use eap->arg, split up in parts by line breaks. */ 18037 theline = line_arg; 18038 p = vim_strchr(theline, '\n'); 18039 if (p == NULL) 18040 line_arg += STRLEN(line_arg); 18041 else 18042 { 18043 *p = NUL; 18044 line_arg = p + 1; 18045 } 18046 } 18047 else if (eap->getline == NULL) 18048 theline = getcmdline(':', 0L, indent); 18049 else 18050 theline = eap->getline(':', eap->cookie, indent); 18051 if (KeyTyped) 18052 lines_left = Rows - 1; 18053 if (theline == NULL) 18054 { 18055 EMSG(_("E126: Missing :endfunction")); 18056 goto erret; 18057 } 18058 18059 /* Detect line continuation: sourcing_lnum increased more than one. */ 18060 if (sourcing_lnum > sourcing_lnum_off + 1) 18061 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 18062 else 18063 sourcing_lnum_off = 0; 18064 18065 if (skip_until != NULL) 18066 { 18067 /* between ":append" and "." and between ":python <<EOF" and "EOF" 18068 * don't check for ":endfunc". */ 18069 if (STRCMP(theline, skip_until) == 0) 18070 { 18071 vim_free(skip_until); 18072 skip_until = NULL; 18073 } 18074 } 18075 else 18076 { 18077 /* skip ':' and blanks*/ 18078 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 18079 ; 18080 18081 /* Check for "endfunction". */ 18082 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 18083 { 18084 if (line_arg == NULL) 18085 vim_free(theline); 18086 break; 18087 } 18088 18089 /* Increase indent inside "if", "while", "for" and "try", decrease 18090 * at "end". */ 18091 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 18092 indent -= 2; 18093 else if (STRNCMP(p, "if", 2) == 0 18094 || STRNCMP(p, "wh", 2) == 0 18095 || STRNCMP(p, "for", 3) == 0 18096 || STRNCMP(p, "try", 3) == 0) 18097 indent += 2; 18098 18099 /* Check for defining a function inside this function. */ 18100 if (checkforcmd(&p, "function", 2)) 18101 { 18102 if (*p == '!') 18103 p = skipwhite(p + 1); 18104 p += eval_fname_script(p); 18105 if (ASCII_ISALPHA(*p)) 18106 { 18107 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 18108 if (*skipwhite(p) == '(') 18109 { 18110 ++nesting; 18111 indent += 2; 18112 } 18113 } 18114 } 18115 18116 /* Check for ":append" or ":insert". */ 18117 p = skip_range(p, NULL); 18118 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 18119 || (p[0] == 'i' 18120 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 18121 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 18122 skip_until = vim_strsave((char_u *)"."); 18123 18124 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 18125 arg = skipwhite(skiptowhite(p)); 18126 if (arg[0] == '<' && arg[1] =='<' 18127 && ((p[0] == 'p' && p[1] == 'y' 18128 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 18129 || (p[0] == 'p' && p[1] == 'e' 18130 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 18131 || (p[0] == 't' && p[1] == 'c' 18132 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 18133 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 18134 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 18135 || (p[0] == 'm' && p[1] == 'z' 18136 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 18137 )) 18138 { 18139 /* ":python <<" continues until a dot, like ":append" */ 18140 p = skipwhite(arg + 2); 18141 if (*p == NUL) 18142 skip_until = vim_strsave((char_u *)"."); 18143 else 18144 skip_until = vim_strsave(p); 18145 } 18146 } 18147 18148 /* Add the line to the function. */ 18149 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 18150 { 18151 if (line_arg == NULL) 18152 vim_free(theline); 18153 goto erret; 18154 } 18155 18156 /* Copy the line to newly allocated memory. get_one_sourceline() 18157 * allocates 250 bytes per line, this saves 80% on average. The cost 18158 * is an extra alloc/free. */ 18159 p = vim_strsave(theline); 18160 if (p != NULL) 18161 { 18162 if (line_arg == NULL) 18163 vim_free(theline); 18164 theline = p; 18165 } 18166 18167 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 18168 18169 /* Add NULL lines for continuation lines, so that the line count is 18170 * equal to the index in the growarray. */ 18171 while (sourcing_lnum_off-- > 0) 18172 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 18173 18174 /* Check for end of eap->arg. */ 18175 if (line_arg != NULL && *line_arg == NUL) 18176 line_arg = NULL; 18177 } 18178 18179 /* Don't define the function when skipping commands or when an error was 18180 * detected. */ 18181 if (eap->skip || did_emsg) 18182 goto erret; 18183 18184 /* 18185 * If there are no errors, add the function 18186 */ 18187 if (fudi.fd_dict == NULL) 18188 { 18189 v = find_var(name, &ht); 18190 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 18191 { 18192 emsg_funcname("E707: Function name conflicts with variable: %s", 18193 name); 18194 goto erret; 18195 } 18196 18197 fp = find_func(name); 18198 if (fp != NULL) 18199 { 18200 if (!eap->forceit) 18201 { 18202 emsg_funcname(e_funcexts, name); 18203 goto erret; 18204 } 18205 if (fp->uf_calls > 0) 18206 { 18207 emsg_funcname("E127: Cannot redefine function %s: It is in use", 18208 name); 18209 goto erret; 18210 } 18211 /* redefine existing function */ 18212 ga_clear_strings(&(fp->uf_args)); 18213 ga_clear_strings(&(fp->uf_lines)); 18214 vim_free(name); 18215 name = NULL; 18216 } 18217 } 18218 else 18219 { 18220 char numbuf[20]; 18221 18222 fp = NULL; 18223 if (fudi.fd_newkey == NULL && !eap->forceit) 18224 { 18225 EMSG(_(e_funcdict)); 18226 goto erret; 18227 } 18228 if (fudi.fd_di == NULL) 18229 { 18230 /* Can't add a function to a locked dictionary */ 18231 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 18232 goto erret; 18233 } 18234 /* Can't change an existing function if it is locked */ 18235 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 18236 goto erret; 18237 18238 /* Give the function a sequential number. Can only be used with a 18239 * Funcref! */ 18240 vim_free(name); 18241 sprintf(numbuf, "%d", ++func_nr); 18242 name = vim_strsave((char_u *)numbuf); 18243 if (name == NULL) 18244 goto erret; 18245 } 18246 18247 if (fp == NULL) 18248 { 18249 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 18250 { 18251 int slen, plen; 18252 char_u *scriptname; 18253 18254 /* Check that the autoload name matches the script name. */ 18255 j = FAIL; 18256 if (sourcing_name != NULL) 18257 { 18258 scriptname = autoload_name(name); 18259 if (scriptname != NULL) 18260 { 18261 p = vim_strchr(scriptname, '/'); 18262 plen = STRLEN(p); 18263 slen = STRLEN(sourcing_name); 18264 if (slen > plen && fnamecmp(p, 18265 sourcing_name + slen - plen) == 0) 18266 j = OK; 18267 vim_free(scriptname); 18268 } 18269 } 18270 if (j == FAIL) 18271 { 18272 EMSG2(_("E746: Function name does not match script file name: %s"), name); 18273 goto erret; 18274 } 18275 } 18276 18277 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 18278 if (fp == NULL) 18279 goto erret; 18280 18281 if (fudi.fd_dict != NULL) 18282 { 18283 if (fudi.fd_di == NULL) 18284 { 18285 /* add new dict entry */ 18286 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 18287 if (fudi.fd_di == NULL) 18288 { 18289 vim_free(fp); 18290 goto erret; 18291 } 18292 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 18293 { 18294 vim_free(fudi.fd_di); 18295 goto erret; 18296 } 18297 } 18298 else 18299 /* overwrite existing dict entry */ 18300 clear_tv(&fudi.fd_di->di_tv); 18301 fudi.fd_di->di_tv.v_type = VAR_FUNC; 18302 fudi.fd_di->di_tv.v_lock = 0; 18303 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 18304 fp->uf_refcount = 1; 18305 } 18306 18307 /* insert the new function in the function list */ 18308 STRCPY(fp->uf_name, name); 18309 hash_add(&func_hashtab, UF2HIKEY(fp)); 18310 } 18311 fp->uf_args = newargs; 18312 fp->uf_lines = newlines; 18313 #ifdef FEAT_PROFILE 18314 fp->uf_tml_count = NULL; 18315 fp->uf_tml_total = NULL; 18316 fp->uf_tml_self = NULL; 18317 fp->uf_profiling = FALSE; 18318 if (prof_def_func()) 18319 func_do_profile(fp); 18320 #endif 18321 fp->uf_varargs = varargs; 18322 fp->uf_flags = flags; 18323 fp->uf_calls = 0; 18324 fp->uf_script_ID = current_SID; 18325 goto ret_free; 18326 18327 erret: 18328 ga_clear_strings(&newargs); 18329 ga_clear_strings(&newlines); 18330 ret_free: 18331 vim_free(skip_until); 18332 vim_free(fudi.fd_newkey); 18333 vim_free(name); 18334 did_emsg |= saved_did_emsg; 18335 } 18336 18337 /* 18338 * Get a function name, translating "<SID>" and "<SNR>". 18339 * Also handles a Funcref in a List or Dictionary. 18340 * Returns the function name in allocated memory, or NULL for failure. 18341 * flags: 18342 * TFN_INT: internal function name OK 18343 * TFN_QUIET: be quiet 18344 * Advances "pp" to just after the function name (if no error). 18345 */ 18346 static char_u * 18347 trans_function_name(pp, skip, flags, fdp) 18348 char_u **pp; 18349 int skip; /* only find the end, don't evaluate */ 18350 int flags; 18351 funcdict_T *fdp; /* return: info about dictionary used */ 18352 { 18353 char_u *name = NULL; 18354 char_u *start; 18355 char_u *end; 18356 int lead; 18357 char_u sid_buf[20]; 18358 int len; 18359 lval_T lv; 18360 18361 if (fdp != NULL) 18362 vim_memset(fdp, 0, sizeof(funcdict_T)); 18363 start = *pp; 18364 18365 /* Check for hard coded <SNR>: already translated function ID (from a user 18366 * command). */ 18367 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 18368 && (*pp)[2] == (int)KE_SNR) 18369 { 18370 *pp += 3; 18371 len = get_id_len(pp) + 3; 18372 return vim_strnsave(start, len); 18373 } 18374 18375 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 18376 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 18377 lead = eval_fname_script(start); 18378 if (lead > 2) 18379 start += lead; 18380 18381 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 18382 lead > 2 ? 0 : FNE_CHECK_START); 18383 if (end == start) 18384 { 18385 if (!skip) 18386 EMSG(_("E129: Function name required")); 18387 goto theend; 18388 } 18389 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 18390 { 18391 /* 18392 * Report an invalid expression in braces, unless the expression 18393 * evaluation has been cancelled due to an aborting error, an 18394 * interrupt, or an exception. 18395 */ 18396 if (!aborting()) 18397 { 18398 if (end != NULL) 18399 EMSG2(_(e_invarg2), start); 18400 } 18401 else 18402 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 18403 goto theend; 18404 } 18405 18406 if (lv.ll_tv != NULL) 18407 { 18408 if (fdp != NULL) 18409 { 18410 fdp->fd_dict = lv.ll_dict; 18411 fdp->fd_newkey = lv.ll_newkey; 18412 lv.ll_newkey = NULL; 18413 fdp->fd_di = lv.ll_di; 18414 } 18415 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 18416 { 18417 name = vim_strsave(lv.ll_tv->vval.v_string); 18418 *pp = end; 18419 } 18420 else 18421 { 18422 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 18423 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 18424 EMSG(_(e_funcref)); 18425 else 18426 *pp = end; 18427 name = NULL; 18428 } 18429 goto theend; 18430 } 18431 18432 if (lv.ll_name == NULL) 18433 { 18434 /* Error found, but continue after the function name. */ 18435 *pp = end; 18436 goto theend; 18437 } 18438 18439 if (lv.ll_exp_name != NULL) 18440 { 18441 len = STRLEN(lv.ll_exp_name); 18442 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 18443 && STRNCMP(lv.ll_name, "s:", 2) == 0) 18444 { 18445 /* When there was "s:" already or the name expanded to get a 18446 * leading "s:" then remove it. */ 18447 lv.ll_name += 2; 18448 len -= 2; 18449 lead = 2; 18450 } 18451 } 18452 else 18453 { 18454 if (lead == 2) /* skip over "s:" */ 18455 lv.ll_name += 2; 18456 len = (int)(end - lv.ll_name); 18457 } 18458 18459 /* 18460 * Copy the function name to allocated memory. 18461 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 18462 * Accept <SNR>123_name() outside a script. 18463 */ 18464 if (skip) 18465 lead = 0; /* do nothing */ 18466 else if (lead > 0) 18467 { 18468 lead = 3; 18469 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 18470 { 18471 if (current_SID <= 0) 18472 { 18473 EMSG(_(e_usingsid)); 18474 goto theend; 18475 } 18476 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 18477 lead += (int)STRLEN(sid_buf); 18478 } 18479 } 18480 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 18481 { 18482 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 18483 goto theend; 18484 } 18485 name = alloc((unsigned)(len + lead + 1)); 18486 if (name != NULL) 18487 { 18488 if (lead > 0) 18489 { 18490 name[0] = K_SPECIAL; 18491 name[1] = KS_EXTRA; 18492 name[2] = (int)KE_SNR; 18493 if (lead > 3) /* If it's "<SID>" */ 18494 STRCPY(name + 3, sid_buf); 18495 } 18496 mch_memmove(name + lead, lv.ll_name, (size_t)len); 18497 name[len + lead] = NUL; 18498 } 18499 *pp = end; 18500 18501 theend: 18502 clear_lval(&lv); 18503 return name; 18504 } 18505 18506 /* 18507 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 18508 * Return 2 if "p" starts with "s:". 18509 * Return 0 otherwise. 18510 */ 18511 static int 18512 eval_fname_script(p) 18513 char_u *p; 18514 { 18515 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 18516 || STRNICMP(p + 1, "SNR>", 4) == 0)) 18517 return 5; 18518 if (p[0] == 's' && p[1] == ':') 18519 return 2; 18520 return 0; 18521 } 18522 18523 /* 18524 * Return TRUE if "p" starts with "<SID>" or "s:". 18525 * Only works if eval_fname_script() returned non-zero for "p"! 18526 */ 18527 static int 18528 eval_fname_sid(p) 18529 char_u *p; 18530 { 18531 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 18532 } 18533 18534 /* 18535 * List the head of the function: "name(arg1, arg2)". 18536 */ 18537 static void 18538 list_func_head(fp, indent) 18539 ufunc_T *fp; 18540 int indent; 18541 { 18542 int j; 18543 18544 msg_start(); 18545 if (indent) 18546 MSG_PUTS(" "); 18547 MSG_PUTS("function "); 18548 if (fp->uf_name[0] == K_SPECIAL) 18549 { 18550 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 18551 msg_puts(fp->uf_name + 3); 18552 } 18553 else 18554 msg_puts(fp->uf_name); 18555 msg_putchar('('); 18556 for (j = 0; j < fp->uf_args.ga_len; ++j) 18557 { 18558 if (j) 18559 MSG_PUTS(", "); 18560 msg_puts(FUNCARG(fp, j)); 18561 } 18562 if (fp->uf_varargs) 18563 { 18564 if (j) 18565 MSG_PUTS(", "); 18566 MSG_PUTS("..."); 18567 } 18568 msg_putchar(')'); 18569 msg_clr_eos(); 18570 if (p_verbose > 0) 18571 last_set_msg(fp->uf_script_ID); 18572 } 18573 18574 /* 18575 * Find a function by name, return pointer to it in ufuncs. 18576 * Return NULL for unknown function. 18577 */ 18578 static ufunc_T * 18579 find_func(name) 18580 char_u *name; 18581 { 18582 hashitem_T *hi; 18583 18584 hi = hash_find(&func_hashtab, name); 18585 if (!HASHITEM_EMPTY(hi)) 18586 return HI2UF(hi); 18587 return NULL; 18588 } 18589 18590 #if defined(EXITFREE) || defined(PROTO) 18591 void 18592 free_all_functions() 18593 { 18594 hashitem_T *hi; 18595 18596 /* Need to start all over every time, because func_free() may change the 18597 * hash table. */ 18598 while (func_hashtab.ht_used > 0) 18599 for (hi = func_hashtab.ht_array; ; ++hi) 18600 if (!HASHITEM_EMPTY(hi)) 18601 { 18602 func_free(HI2UF(hi)); 18603 break; 18604 } 18605 } 18606 #endif 18607 18608 /* 18609 * Return TRUE if a function "name" exists. 18610 */ 18611 static int 18612 function_exists(name) 18613 char_u *name; 18614 { 18615 char_u *p = name; 18616 int n = FALSE; 18617 18618 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 18619 if (p != NULL) 18620 { 18621 if (builtin_function(p)) 18622 n = (find_internal_func(p) >= 0); 18623 else 18624 n = (find_func(p) != NULL); 18625 vim_free(p); 18626 } 18627 return n; 18628 } 18629 18630 /* 18631 * Return TRUE if "name" looks like a builtin function name: starts with a 18632 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 18633 */ 18634 static int 18635 builtin_function(name) 18636 char_u *name; 18637 { 18638 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 18639 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 18640 } 18641 18642 #if defined(FEAT_PROFILE) || defined(PROTO) 18643 /* 18644 * Start profiling function "fp". 18645 */ 18646 static void 18647 func_do_profile(fp) 18648 ufunc_T *fp; 18649 { 18650 fp->uf_tm_count = 0; 18651 profile_zero(&fp->uf_tm_self); 18652 profile_zero(&fp->uf_tm_total); 18653 if (fp->uf_tml_count == NULL) 18654 fp->uf_tml_count = (int *)alloc_clear((unsigned) 18655 (sizeof(int) * fp->uf_lines.ga_len)); 18656 if (fp->uf_tml_total == NULL) 18657 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 18658 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 18659 if (fp->uf_tml_self == NULL) 18660 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 18661 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 18662 fp->uf_tml_idx = -1; 18663 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 18664 || fp->uf_tml_self == NULL) 18665 return; /* out of memory */ 18666 18667 fp->uf_profiling = TRUE; 18668 } 18669 18670 /* 18671 * Dump the profiling results for all functions in file "fd". 18672 */ 18673 void 18674 func_dump_profile(fd) 18675 FILE *fd; 18676 { 18677 hashitem_T *hi; 18678 int todo; 18679 ufunc_T *fp; 18680 int i; 18681 ufunc_T **sorttab; 18682 int st_len = 0; 18683 18684 todo = func_hashtab.ht_used; 18685 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 18686 18687 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 18688 { 18689 if (!HASHITEM_EMPTY(hi)) 18690 { 18691 --todo; 18692 fp = HI2UF(hi); 18693 if (fp->uf_profiling) 18694 { 18695 if (sorttab != NULL) 18696 sorttab[st_len++] = fp; 18697 18698 if (fp->uf_name[0] == K_SPECIAL) 18699 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 18700 else 18701 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 18702 if (fp->uf_tm_count == 1) 18703 fprintf(fd, "Called 1 time\n"); 18704 else 18705 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 18706 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 18707 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 18708 fprintf(fd, "\n"); 18709 fprintf(fd, "count total (s) self (s)\n"); 18710 18711 for (i = 0; i < fp->uf_lines.ga_len; ++i) 18712 { 18713 if (FUNCLINE(fp, i) == NULL) 18714 continue; 18715 prof_func_line(fd, fp->uf_tml_count[i], 18716 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 18717 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 18718 } 18719 fprintf(fd, "\n"); 18720 } 18721 } 18722 } 18723 18724 if (sorttab != NULL && st_len > 0) 18725 { 18726 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 18727 prof_total_cmp); 18728 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 18729 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 18730 prof_self_cmp); 18731 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 18732 } 18733 } 18734 18735 static void 18736 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 18737 FILE *fd; 18738 ufunc_T **sorttab; 18739 int st_len; 18740 char *title; 18741 int prefer_self; /* when equal print only self time */ 18742 { 18743 int i; 18744 ufunc_T *fp; 18745 18746 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 18747 fprintf(fd, "count total (s) self (s) function\n"); 18748 for (i = 0; i < 20 && i < st_len; ++i) 18749 { 18750 fp = sorttab[i]; 18751 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 18752 prefer_self); 18753 if (fp->uf_name[0] == K_SPECIAL) 18754 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 18755 else 18756 fprintf(fd, " %s()\n", fp->uf_name); 18757 } 18758 fprintf(fd, "\n"); 18759 } 18760 18761 /* 18762 * Print the count and times for one function or function line. 18763 */ 18764 static void 18765 prof_func_line(fd, count, total, self, prefer_self) 18766 FILE *fd; 18767 int count; 18768 proftime_T *total; 18769 proftime_T *self; 18770 int prefer_self; /* when equal print only self time */ 18771 { 18772 if (count > 0) 18773 { 18774 fprintf(fd, "%5d ", count); 18775 if (prefer_self && profile_equal(total, self)) 18776 fprintf(fd, " "); 18777 else 18778 fprintf(fd, "%s ", profile_msg(total)); 18779 if (!prefer_self && profile_equal(total, self)) 18780 fprintf(fd, " "); 18781 else 18782 fprintf(fd, "%s ", profile_msg(self)); 18783 } 18784 else 18785 fprintf(fd, " "); 18786 } 18787 18788 /* 18789 * Compare function for total time sorting. 18790 */ 18791 static int 18792 #ifdef __BORLANDC__ 18793 _RTLENTRYF 18794 #endif 18795 prof_total_cmp(s1, s2) 18796 const void *s1; 18797 const void *s2; 18798 { 18799 ufunc_T *p1, *p2; 18800 18801 p1 = *(ufunc_T **)s1; 18802 p2 = *(ufunc_T **)s2; 18803 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 18804 } 18805 18806 /* 18807 * Compare function for self time sorting. 18808 */ 18809 static int 18810 #ifdef __BORLANDC__ 18811 _RTLENTRYF 18812 #endif 18813 prof_self_cmp(s1, s2) 18814 const void *s1; 18815 const void *s2; 18816 { 18817 ufunc_T *p1, *p2; 18818 18819 p1 = *(ufunc_T **)s1; 18820 p2 = *(ufunc_T **)s2; 18821 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 18822 } 18823 18824 #endif 18825 18826 /* The names of packages that once were loaded is remembered. */ 18827 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 18828 18829 /* 18830 * If "name" has a package name try autoloading the script for it. 18831 * Return TRUE if a package was loaded. 18832 */ 18833 static int 18834 script_autoload(name, reload) 18835 char_u *name; 18836 int reload; /* load script again when already loaded */ 18837 { 18838 char_u *p; 18839 char_u *scriptname, *tofree; 18840 int ret = FALSE; 18841 int i; 18842 18843 /* If there is no '#' after name[0] there is no package name. */ 18844 p = vim_strchr(name, AUTOLOAD_CHAR); 18845 if (p == NULL || p == name) 18846 return FALSE; 18847 18848 tofree = scriptname = autoload_name(name); 18849 18850 /* Find the name in the list of previously loaded package names. Skip 18851 * "autoload/", it's always the same. */ 18852 for (i = 0; i < ga_loaded.ga_len; ++i) 18853 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 18854 break; 18855 if (!reload && i < ga_loaded.ga_len) 18856 ret = FALSE; /* was loaded already */ 18857 else 18858 { 18859 /* Remember the name if it wasn't loaded already. */ 18860 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 18861 { 18862 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 18863 tofree = NULL; 18864 } 18865 18866 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 18867 if (source_runtime(scriptname, FALSE) == OK) 18868 ret = TRUE; 18869 } 18870 18871 vim_free(tofree); 18872 return ret; 18873 } 18874 18875 /* 18876 * Return the autoload script name for a function or variable name. 18877 * Returns NULL when out of memory. 18878 */ 18879 static char_u * 18880 autoload_name(name) 18881 char_u *name; 18882 { 18883 char_u *p; 18884 char_u *scriptname; 18885 18886 /* Get the script file name: replace '#' with '/', append ".vim". */ 18887 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 18888 if (scriptname == NULL) 18889 return FALSE; 18890 STRCPY(scriptname, "autoload/"); 18891 STRCAT(scriptname, name); 18892 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 18893 STRCAT(scriptname, ".vim"); 18894 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 18895 *p = '/'; 18896 return scriptname; 18897 } 18898 18899 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 18900 18901 /* 18902 * Function given to ExpandGeneric() to obtain the list of user defined 18903 * function names. 18904 */ 18905 char_u * 18906 get_user_func_name(xp, idx) 18907 expand_T *xp; 18908 int idx; 18909 { 18910 static long_u done; 18911 static hashitem_T *hi; 18912 ufunc_T *fp; 18913 18914 if (idx == 0) 18915 { 18916 done = 0; 18917 hi = func_hashtab.ht_array; 18918 } 18919 if (done < func_hashtab.ht_used) 18920 { 18921 if (done++ > 0) 18922 ++hi; 18923 while (HASHITEM_EMPTY(hi)) 18924 ++hi; 18925 fp = HI2UF(hi); 18926 18927 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 18928 return fp->uf_name; /* prevents overflow */ 18929 18930 cat_func_name(IObuff, fp); 18931 if (xp->xp_context != EXPAND_USER_FUNC) 18932 { 18933 STRCAT(IObuff, "("); 18934 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 18935 STRCAT(IObuff, ")"); 18936 } 18937 return IObuff; 18938 } 18939 return NULL; 18940 } 18941 18942 #endif /* FEAT_CMDL_COMPL */ 18943 18944 /* 18945 * Copy the function name of "fp" to buffer "buf". 18946 * "buf" must be able to hold the function name plus three bytes. 18947 * Takes care of script-local function names. 18948 */ 18949 static void 18950 cat_func_name(buf, fp) 18951 char_u *buf; 18952 ufunc_T *fp; 18953 { 18954 if (fp->uf_name[0] == K_SPECIAL) 18955 { 18956 STRCPY(buf, "<SNR>"); 18957 STRCAT(buf, fp->uf_name + 3); 18958 } 18959 else 18960 STRCPY(buf, fp->uf_name); 18961 } 18962 18963 /* 18964 * ":delfunction {name}" 18965 */ 18966 void 18967 ex_delfunction(eap) 18968 exarg_T *eap; 18969 { 18970 ufunc_T *fp = NULL; 18971 char_u *p; 18972 char_u *name; 18973 funcdict_T fudi; 18974 18975 p = eap->arg; 18976 name = trans_function_name(&p, eap->skip, 0, &fudi); 18977 vim_free(fudi.fd_newkey); 18978 if (name == NULL) 18979 { 18980 if (fudi.fd_dict != NULL && !eap->skip) 18981 EMSG(_(e_funcref)); 18982 return; 18983 } 18984 if (!ends_excmd(*skipwhite(p))) 18985 { 18986 vim_free(name); 18987 EMSG(_(e_trailing)); 18988 return; 18989 } 18990 eap->nextcmd = check_nextcmd(p); 18991 if (eap->nextcmd != NULL) 18992 *p = NUL; 18993 18994 if (!eap->skip) 18995 fp = find_func(name); 18996 vim_free(name); 18997 18998 if (!eap->skip) 18999 { 19000 if (fp == NULL) 19001 { 19002 EMSG2(_(e_nofunc), eap->arg); 19003 return; 19004 } 19005 if (fp->uf_calls > 0) 19006 { 19007 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 19008 return; 19009 } 19010 19011 if (fudi.fd_dict != NULL) 19012 { 19013 /* Delete the dict item that refers to the function, it will 19014 * invoke func_unref() and possibly delete the function. */ 19015 dictitem_remove(fudi.fd_dict, fudi.fd_di); 19016 } 19017 else 19018 func_free(fp); 19019 } 19020 } 19021 19022 /* 19023 * Free a function and remove it from the list of functions. 19024 */ 19025 static void 19026 func_free(fp) 19027 ufunc_T *fp; 19028 { 19029 hashitem_T *hi; 19030 19031 /* clear this function */ 19032 ga_clear_strings(&(fp->uf_args)); 19033 ga_clear_strings(&(fp->uf_lines)); 19034 #ifdef FEAT_PROFILE 19035 vim_free(fp->uf_tml_count); 19036 vim_free(fp->uf_tml_total); 19037 vim_free(fp->uf_tml_self); 19038 #endif 19039 19040 /* remove the function from the function hashtable */ 19041 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 19042 if (HASHITEM_EMPTY(hi)) 19043 EMSG2(_(e_intern2), "func_free()"); 19044 else 19045 hash_remove(&func_hashtab, hi); 19046 19047 vim_free(fp); 19048 } 19049 19050 /* 19051 * Unreference a Function: decrement the reference count and free it when it 19052 * becomes zero. Only for numbered functions. 19053 */ 19054 static void 19055 func_unref(name) 19056 char_u *name; 19057 { 19058 ufunc_T *fp; 19059 19060 if (name != NULL && isdigit(*name)) 19061 { 19062 fp = find_func(name); 19063 if (fp == NULL) 19064 EMSG2(_(e_intern2), "func_unref()"); 19065 else if (--fp->uf_refcount <= 0) 19066 { 19067 /* Only delete it when it's not being used. Otherwise it's done 19068 * when "uf_calls" becomes zero. */ 19069 if (fp->uf_calls == 0) 19070 func_free(fp); 19071 } 19072 } 19073 } 19074 19075 /* 19076 * Count a reference to a Function. 19077 */ 19078 static void 19079 func_ref(name) 19080 char_u *name; 19081 { 19082 ufunc_T *fp; 19083 19084 if (name != NULL && isdigit(*name)) 19085 { 19086 fp = find_func(name); 19087 if (fp == NULL) 19088 EMSG2(_(e_intern2), "func_ref()"); 19089 else 19090 ++fp->uf_refcount; 19091 } 19092 } 19093 19094 /* 19095 * Call a user function. 19096 */ 19097 static void 19098 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 19099 ufunc_T *fp; /* pointer to function */ 19100 int argcount; /* nr of args */ 19101 typval_T *argvars; /* arguments */ 19102 typval_T *rettv; /* return value */ 19103 linenr_T firstline; /* first line of range */ 19104 linenr_T lastline; /* last line of range */ 19105 dict_T *selfdict; /* Dictionary for "self" */ 19106 { 19107 char_u *save_sourcing_name; 19108 linenr_T save_sourcing_lnum; 19109 scid_T save_current_SID; 19110 funccall_T fc; 19111 int save_did_emsg; 19112 static int depth = 0; 19113 dictitem_T *v; 19114 int fixvar_idx = 0; /* index in fixvar[] */ 19115 int i; 19116 int ai; 19117 char_u numbuf[NUMBUFLEN]; 19118 char_u *name; 19119 #ifdef FEAT_PROFILE 19120 proftime_T wait_start; 19121 #endif 19122 19123 /* If depth of calling is getting too high, don't execute the function */ 19124 if (depth >= p_mfd) 19125 { 19126 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 19127 rettv->v_type = VAR_NUMBER; 19128 rettv->vval.v_number = -1; 19129 return; 19130 } 19131 ++depth; 19132 19133 line_breakcheck(); /* check for CTRL-C hit */ 19134 19135 fc.caller = current_funccal; 19136 current_funccal = &fc; 19137 fc.func = fp; 19138 fc.rettv = rettv; 19139 rettv->vval.v_number = 0; 19140 fc.linenr = 0; 19141 fc.returned = FALSE; 19142 fc.level = ex_nesting_level; 19143 /* Check if this function has a breakpoint. */ 19144 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 19145 fc.dbg_tick = debug_tick; 19146 19147 /* 19148 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 19149 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 19150 * each argument variable and saves a lot of time. 19151 */ 19152 /* 19153 * Init l: variables. 19154 */ 19155 init_var_dict(&fc.l_vars, &fc.l_vars_var); 19156 if (selfdict != NULL) 19157 { 19158 /* Set l:self to "selfdict". */ 19159 v = &fc.fixvar[fixvar_idx++].var; 19160 STRCPY(v->di_key, "self"); 19161 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 19162 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 19163 v->di_tv.v_type = VAR_DICT; 19164 v->di_tv.v_lock = 0; 19165 v->di_tv.vval.v_dict = selfdict; 19166 ++selfdict->dv_refcount; 19167 } 19168 19169 /* 19170 * Init a: variables. 19171 * Set a:0 to "argcount". 19172 * Set a:000 to a list with room for the "..." arguments. 19173 */ 19174 init_var_dict(&fc.l_avars, &fc.l_avars_var); 19175 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 19176 (varnumber_T)(argcount - fp->uf_args.ga_len)); 19177 v = &fc.fixvar[fixvar_idx++].var; 19178 STRCPY(v->di_key, "000"); 19179 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19180 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 19181 v->di_tv.v_type = VAR_LIST; 19182 v->di_tv.v_lock = VAR_FIXED; 19183 v->di_tv.vval.v_list = &fc.l_varlist; 19184 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 19185 fc.l_varlist.lv_refcount = 99999; 19186 19187 /* 19188 * Set a:firstline to "firstline" and a:lastline to "lastline". 19189 * Set a:name to named arguments. 19190 * Set a:N to the "..." arguments. 19191 */ 19192 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 19193 (varnumber_T)firstline); 19194 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 19195 (varnumber_T)lastline); 19196 for (i = 0; i < argcount; ++i) 19197 { 19198 ai = i - fp->uf_args.ga_len; 19199 if (ai < 0) 19200 /* named argument a:name */ 19201 name = FUNCARG(fp, i); 19202 else 19203 { 19204 /* "..." argument a:1, a:2, etc. */ 19205 sprintf((char *)numbuf, "%d", ai + 1); 19206 name = numbuf; 19207 } 19208 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 19209 { 19210 v = &fc.fixvar[fixvar_idx++].var; 19211 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19212 } 19213 else 19214 { 19215 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19216 + STRLEN(name))); 19217 if (v == NULL) 19218 break; 19219 v->di_flags = DI_FLAGS_RO; 19220 } 19221 STRCPY(v->di_key, name); 19222 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 19223 19224 /* Note: the values are copied directly to avoid alloc/free. 19225 * "argvars" must have VAR_FIXED for v_lock. */ 19226 v->di_tv = argvars[i]; 19227 v->di_tv.v_lock = VAR_FIXED; 19228 19229 if (ai >= 0 && ai < MAX_FUNC_ARGS) 19230 { 19231 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 19232 fc.l_listitems[ai].li_tv = argvars[i]; 19233 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 19234 } 19235 } 19236 19237 /* Don't redraw while executing the function. */ 19238 ++RedrawingDisabled; 19239 save_sourcing_name = sourcing_name; 19240 save_sourcing_lnum = sourcing_lnum; 19241 sourcing_lnum = 1; 19242 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 19243 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 19244 if (sourcing_name != NULL) 19245 { 19246 if (save_sourcing_name != NULL 19247 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 19248 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 19249 else 19250 STRCPY(sourcing_name, "function "); 19251 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 19252 19253 if (p_verbose >= 12) 19254 { 19255 ++no_wait_return; 19256 verbose_enter_scroll(); 19257 19258 smsg((char_u *)_("calling %s"), sourcing_name); 19259 if (p_verbose >= 14) 19260 { 19261 char_u buf[MSG_BUF_LEN]; 19262 char_u numbuf[NUMBUFLEN]; 19263 char_u *tofree; 19264 19265 msg_puts((char_u *)"("); 19266 for (i = 0; i < argcount; ++i) 19267 { 19268 if (i > 0) 19269 msg_puts((char_u *)", "); 19270 if (argvars[i].v_type == VAR_NUMBER) 19271 msg_outnum((long)argvars[i].vval.v_number); 19272 else 19273 { 19274 trunc_string(tv2string(&argvars[i], &tofree, numbuf, 0), 19275 buf, MSG_BUF_CLEN); 19276 msg_puts(buf); 19277 vim_free(tofree); 19278 } 19279 } 19280 msg_puts((char_u *)")"); 19281 } 19282 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19283 19284 verbose_leave_scroll(); 19285 --no_wait_return; 19286 } 19287 } 19288 #ifdef FEAT_PROFILE 19289 if (do_profiling) 19290 { 19291 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 19292 func_do_profile(fp); 19293 if (fp->uf_profiling 19294 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 19295 { 19296 ++fp->uf_tm_count; 19297 profile_start(&fp->uf_tm_start); 19298 profile_zero(&fp->uf_tm_children); 19299 } 19300 script_prof_save(&wait_start); 19301 } 19302 #endif 19303 19304 save_current_SID = current_SID; 19305 current_SID = fp->uf_script_ID; 19306 save_did_emsg = did_emsg; 19307 did_emsg = FALSE; 19308 19309 /* call do_cmdline() to execute the lines */ 19310 do_cmdline(NULL, get_func_line, (void *)&fc, 19311 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 19312 19313 --RedrawingDisabled; 19314 19315 /* when the function was aborted because of an error, return -1 */ 19316 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 19317 { 19318 clear_tv(rettv); 19319 rettv->v_type = VAR_NUMBER; 19320 rettv->vval.v_number = -1; 19321 } 19322 19323 #ifdef FEAT_PROFILE 19324 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 19325 { 19326 profile_end(&fp->uf_tm_start); 19327 profile_sub_wait(&wait_start, &fp->uf_tm_start); 19328 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 19329 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 19330 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 19331 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 19332 { 19333 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 19334 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 19335 } 19336 } 19337 #endif 19338 19339 /* when being verbose, mention the return value */ 19340 if (p_verbose >= 12) 19341 { 19342 ++no_wait_return; 19343 verbose_enter_scroll(); 19344 19345 if (aborting()) 19346 smsg((char_u *)_("%s aborted"), sourcing_name); 19347 else if (fc.rettv->v_type == VAR_NUMBER) 19348 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 19349 (long)fc.rettv->vval.v_number); 19350 else 19351 { 19352 char_u buf[MSG_BUF_LEN]; 19353 char_u numbuf[NUMBUFLEN]; 19354 char_u *tofree; 19355 19356 /* The value may be very long. Skip the middle part, so that we 19357 * have some idea how it starts and ends. smsg() would always 19358 * truncate it at the end. */ 19359 trunc_string(tv2string(fc.rettv, &tofree, numbuf, 0), 19360 buf, MSG_BUF_CLEN); 19361 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 19362 vim_free(tofree); 19363 } 19364 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19365 19366 verbose_leave_scroll(); 19367 --no_wait_return; 19368 } 19369 19370 vim_free(sourcing_name); 19371 sourcing_name = save_sourcing_name; 19372 sourcing_lnum = save_sourcing_lnum; 19373 current_SID = save_current_SID; 19374 #ifdef FEAT_PROFILE 19375 if (do_profiling) 19376 script_prof_restore(&wait_start); 19377 #endif 19378 19379 if (p_verbose >= 12 && sourcing_name != NULL) 19380 { 19381 ++no_wait_return; 19382 verbose_enter_scroll(); 19383 19384 smsg((char_u *)_("continuing in %s"), sourcing_name); 19385 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19386 19387 verbose_leave_scroll(); 19388 --no_wait_return; 19389 } 19390 19391 did_emsg |= save_did_emsg; 19392 current_funccal = fc.caller; 19393 19394 /* The a: variables typevals were not alloced, only free the allocated 19395 * variables. */ 19396 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 19397 19398 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 19399 --depth; 19400 } 19401 19402 /* 19403 * Add a number variable "name" to dict "dp" with value "nr". 19404 */ 19405 static void 19406 add_nr_var(dp, v, name, nr) 19407 dict_T *dp; 19408 dictitem_T *v; 19409 char *name; 19410 varnumber_T nr; 19411 { 19412 STRCPY(v->di_key, name); 19413 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19414 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 19415 v->di_tv.v_type = VAR_NUMBER; 19416 v->di_tv.v_lock = VAR_FIXED; 19417 v->di_tv.vval.v_number = nr; 19418 } 19419 19420 /* 19421 * ":return [expr]" 19422 */ 19423 void 19424 ex_return(eap) 19425 exarg_T *eap; 19426 { 19427 char_u *arg = eap->arg; 19428 typval_T rettv; 19429 int returning = FALSE; 19430 19431 if (current_funccal == NULL) 19432 { 19433 EMSG(_("E133: :return not inside a function")); 19434 return; 19435 } 19436 19437 if (eap->skip) 19438 ++emsg_skip; 19439 19440 eap->nextcmd = NULL; 19441 if ((*arg != NUL && *arg != '|' && *arg != '\n') 19442 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 19443 { 19444 if (!eap->skip) 19445 returning = do_return(eap, FALSE, TRUE, &rettv); 19446 else 19447 clear_tv(&rettv); 19448 } 19449 /* It's safer to return also on error. */ 19450 else if (!eap->skip) 19451 { 19452 /* 19453 * Return unless the expression evaluation has been cancelled due to an 19454 * aborting error, an interrupt, or an exception. 19455 */ 19456 if (!aborting()) 19457 returning = do_return(eap, FALSE, TRUE, NULL); 19458 } 19459 19460 /* When skipping or the return gets pending, advance to the next command 19461 * in this line (!returning). Otherwise, ignore the rest of the line. 19462 * Following lines will be ignored by get_func_line(). */ 19463 if (returning) 19464 eap->nextcmd = NULL; 19465 else if (eap->nextcmd == NULL) /* no argument */ 19466 eap->nextcmd = check_nextcmd(arg); 19467 19468 if (eap->skip) 19469 --emsg_skip; 19470 } 19471 19472 /* 19473 * Return from a function. Possibly makes the return pending. Also called 19474 * for a pending return at the ":endtry" or after returning from an extra 19475 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 19476 * when called due to a ":return" command. "rettv" may point to a typval_T 19477 * with the return rettv. Returns TRUE when the return can be carried out, 19478 * FALSE when the return gets pending. 19479 */ 19480 int 19481 do_return(eap, reanimate, is_cmd, rettv) 19482 exarg_T *eap; 19483 int reanimate; 19484 int is_cmd; 19485 void *rettv; 19486 { 19487 int idx; 19488 struct condstack *cstack = eap->cstack; 19489 19490 if (reanimate) 19491 /* Undo the return. */ 19492 current_funccal->returned = FALSE; 19493 19494 /* 19495 * Cleanup (and inactivate) conditionals, but stop when a try conditional 19496 * not in its finally clause (which then is to be executed next) is found. 19497 * In this case, make the ":return" pending for execution at the ":endtry". 19498 * Otherwise, return normally. 19499 */ 19500 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 19501 if (idx >= 0) 19502 { 19503 cstack->cs_pending[idx] = CSTP_RETURN; 19504 19505 if (!is_cmd && !reanimate) 19506 /* A pending return again gets pending. "rettv" points to an 19507 * allocated variable with the rettv of the original ":return"'s 19508 * argument if present or is NULL else. */ 19509 cstack->cs_rettv[idx] = rettv; 19510 else 19511 { 19512 /* When undoing a return in order to make it pending, get the stored 19513 * return rettv. */ 19514 if (reanimate) 19515 rettv = current_funccal->rettv; 19516 19517 if (rettv != NULL) 19518 { 19519 /* Store the value of the pending return. */ 19520 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 19521 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 19522 else 19523 EMSG(_(e_outofmem)); 19524 } 19525 else 19526 cstack->cs_rettv[idx] = NULL; 19527 19528 if (reanimate) 19529 { 19530 /* The pending return value could be overwritten by a ":return" 19531 * without argument in a finally clause; reset the default 19532 * return value. */ 19533 current_funccal->rettv->v_type = VAR_NUMBER; 19534 current_funccal->rettv->vval.v_number = 0; 19535 } 19536 } 19537 report_make_pending(CSTP_RETURN, rettv); 19538 } 19539 else 19540 { 19541 current_funccal->returned = TRUE; 19542 19543 /* If the return is carried out now, store the return value. For 19544 * a return immediately after reanimation, the value is already 19545 * there. */ 19546 if (!reanimate && rettv != NULL) 19547 { 19548 clear_tv(current_funccal->rettv); 19549 *current_funccal->rettv = *(typval_T *)rettv; 19550 if (!is_cmd) 19551 vim_free(rettv); 19552 } 19553 } 19554 19555 return idx < 0; 19556 } 19557 19558 /* 19559 * Free the variable with a pending return value. 19560 */ 19561 void 19562 discard_pending_return(rettv) 19563 void *rettv; 19564 { 19565 free_tv((typval_T *)rettv); 19566 } 19567 19568 /* 19569 * Generate a return command for producing the value of "rettv". The result 19570 * is an allocated string. Used by report_pending() for verbose messages. 19571 */ 19572 char_u * 19573 get_return_cmd(rettv) 19574 void *rettv; 19575 { 19576 char_u *s = NULL; 19577 char_u *tofree = NULL; 19578 char_u numbuf[NUMBUFLEN]; 19579 19580 if (rettv != NULL) 19581 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 19582 if (s == NULL) 19583 s = (char_u *)""; 19584 19585 STRCPY(IObuff, ":return "); 19586 STRNCPY(IObuff + 8, s, IOSIZE - 8); 19587 if (STRLEN(s) + 8 >= IOSIZE) 19588 STRCPY(IObuff + IOSIZE - 4, "..."); 19589 vim_free(tofree); 19590 return vim_strsave(IObuff); 19591 } 19592 19593 /* 19594 * Get next function line. 19595 * Called by do_cmdline() to get the next line. 19596 * Returns allocated string, or NULL for end of function. 19597 */ 19598 /* ARGSUSED */ 19599 char_u * 19600 get_func_line(c, cookie, indent) 19601 int c; /* not used */ 19602 void *cookie; 19603 int indent; /* not used */ 19604 { 19605 funccall_T *fcp = (funccall_T *)cookie; 19606 ufunc_T *fp = fcp->func; 19607 char_u *retval; 19608 garray_T *gap; /* growarray with function lines */ 19609 19610 /* If breakpoints have been added/deleted need to check for it. */ 19611 if (fcp->dbg_tick != debug_tick) 19612 { 19613 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 19614 sourcing_lnum); 19615 fcp->dbg_tick = debug_tick; 19616 } 19617 #ifdef FEAT_PROFILE 19618 if (do_profiling) 19619 func_line_end(cookie); 19620 #endif 19621 19622 gap = &fp->uf_lines; 19623 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 19624 || fcp->returned) 19625 retval = NULL; 19626 else 19627 { 19628 /* Skip NULL lines (continuation lines). */ 19629 while (fcp->linenr < gap->ga_len 19630 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 19631 ++fcp->linenr; 19632 if (fcp->linenr >= gap->ga_len) 19633 retval = NULL; 19634 else 19635 { 19636 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 19637 sourcing_lnum = fcp->linenr; 19638 #ifdef FEAT_PROFILE 19639 if (do_profiling) 19640 func_line_start(cookie); 19641 #endif 19642 } 19643 } 19644 19645 /* Did we encounter a breakpoint? */ 19646 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 19647 { 19648 dbg_breakpoint(fp->uf_name, sourcing_lnum); 19649 /* Find next breakpoint. */ 19650 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 19651 sourcing_lnum); 19652 fcp->dbg_tick = debug_tick; 19653 } 19654 19655 return retval; 19656 } 19657 19658 #if defined(FEAT_PROFILE) || defined(PROTO) 19659 /* 19660 * Called when starting to read a function line. 19661 * "sourcing_lnum" must be correct! 19662 * When skipping lines it may not actually be executed, but we won't find out 19663 * until later and we need to store the time now. 19664 */ 19665 void 19666 func_line_start(cookie) 19667 void *cookie; 19668 { 19669 funccall_T *fcp = (funccall_T *)cookie; 19670 ufunc_T *fp = fcp->func; 19671 19672 if (fp->uf_profiling && sourcing_lnum >= 1 19673 && sourcing_lnum <= fp->uf_lines.ga_len) 19674 { 19675 fp->uf_tml_idx = sourcing_lnum - 1; 19676 /* Skip continuation lines. */ 19677 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 19678 --fp->uf_tml_idx; 19679 fp->uf_tml_execed = FALSE; 19680 profile_start(&fp->uf_tml_start); 19681 profile_zero(&fp->uf_tml_children); 19682 profile_get_wait(&fp->uf_tml_wait); 19683 } 19684 } 19685 19686 /* 19687 * Called when actually executing a function line. 19688 */ 19689 void 19690 func_line_exec(cookie) 19691 void *cookie; 19692 { 19693 funccall_T *fcp = (funccall_T *)cookie; 19694 ufunc_T *fp = fcp->func; 19695 19696 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 19697 fp->uf_tml_execed = TRUE; 19698 } 19699 19700 /* 19701 * Called when done with a function line. 19702 */ 19703 void 19704 func_line_end(cookie) 19705 void *cookie; 19706 { 19707 funccall_T *fcp = (funccall_T *)cookie; 19708 ufunc_T *fp = fcp->func; 19709 19710 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 19711 { 19712 if (fp->uf_tml_execed) 19713 { 19714 ++fp->uf_tml_count[fp->uf_tml_idx]; 19715 profile_end(&fp->uf_tml_start); 19716 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 19717 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 19718 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 19719 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 19720 } 19721 fp->uf_tml_idx = -1; 19722 } 19723 } 19724 #endif 19725 19726 /* 19727 * Return TRUE if the currently active function should be ended, because a 19728 * return was encountered or an error occured. Used inside a ":while". 19729 */ 19730 int 19731 func_has_ended(cookie) 19732 void *cookie; 19733 { 19734 funccall_T *fcp = (funccall_T *)cookie; 19735 19736 /* Ignore the "abort" flag if the abortion behavior has been changed due to 19737 * an error inside a try conditional. */ 19738 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 19739 || fcp->returned); 19740 } 19741 19742 /* 19743 * return TRUE if cookie indicates a function which "abort"s on errors. 19744 */ 19745 int 19746 func_has_abort(cookie) 19747 void *cookie; 19748 { 19749 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 19750 } 19751 19752 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 19753 typedef enum 19754 { 19755 VAR_FLAVOUR_DEFAULT, 19756 VAR_FLAVOUR_SESSION, 19757 VAR_FLAVOUR_VIMINFO 19758 } var_flavour_T; 19759 19760 static var_flavour_T var_flavour __ARGS((char_u *varname)); 19761 19762 static var_flavour_T 19763 var_flavour(varname) 19764 char_u *varname; 19765 { 19766 char_u *p = varname; 19767 19768 if (ASCII_ISUPPER(*p)) 19769 { 19770 while (*(++p)) 19771 if (ASCII_ISLOWER(*p)) 19772 return VAR_FLAVOUR_SESSION; 19773 return VAR_FLAVOUR_VIMINFO; 19774 } 19775 else 19776 return VAR_FLAVOUR_DEFAULT; 19777 } 19778 #endif 19779 19780 #if defined(FEAT_VIMINFO) || defined(PROTO) 19781 /* 19782 * Restore global vars that start with a capital from the viminfo file 19783 */ 19784 int 19785 read_viminfo_varlist(virp, writing) 19786 vir_T *virp; 19787 int writing; 19788 { 19789 char_u *tab; 19790 int is_string = FALSE; 19791 typval_T tv; 19792 19793 if (!writing && (find_viminfo_parameter('!') != NULL)) 19794 { 19795 tab = vim_strchr(virp->vir_line + 1, '\t'); 19796 if (tab != NULL) 19797 { 19798 *tab++ = '\0'; /* isolate the variable name */ 19799 if (*tab == 'S') /* string var */ 19800 is_string = TRUE; 19801 19802 tab = vim_strchr(tab, '\t'); 19803 if (tab != NULL) 19804 { 19805 if (is_string) 19806 { 19807 tv.v_type = VAR_STRING; 19808 tv.vval.v_string = viminfo_readstring(virp, 19809 (int)(tab - virp->vir_line + 1), TRUE); 19810 } 19811 else 19812 { 19813 tv.v_type = VAR_NUMBER; 19814 tv.vval.v_number = atol((char *)tab + 1); 19815 } 19816 set_var(virp->vir_line + 1, &tv, FALSE); 19817 if (is_string) 19818 vim_free(tv.vval.v_string); 19819 } 19820 } 19821 } 19822 19823 return viminfo_readline(virp); 19824 } 19825 19826 /* 19827 * Write global vars that start with a capital to the viminfo file 19828 */ 19829 void 19830 write_viminfo_varlist(fp) 19831 FILE *fp; 19832 { 19833 hashitem_T *hi; 19834 dictitem_T *this_var; 19835 int todo; 19836 char *s; 19837 char_u *p; 19838 char_u *tofree; 19839 char_u numbuf[NUMBUFLEN]; 19840 19841 if (find_viminfo_parameter('!') == NULL) 19842 return; 19843 19844 fprintf(fp, _("\n# global variables:\n")); 19845 19846 todo = globvarht.ht_used; 19847 for (hi = globvarht.ht_array; todo > 0; ++hi) 19848 { 19849 if (!HASHITEM_EMPTY(hi)) 19850 { 19851 --todo; 19852 this_var = HI2DI(hi); 19853 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 19854 { 19855 switch (this_var->di_tv.v_type) 19856 { 19857 case VAR_STRING: s = "STR"; break; 19858 case VAR_NUMBER: s = "NUM"; break; 19859 default: continue; 19860 } 19861 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 19862 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 19863 if (p != NULL) 19864 viminfo_writestring(fp, p); 19865 vim_free(tofree); 19866 } 19867 } 19868 } 19869 } 19870 #endif 19871 19872 #if defined(FEAT_SESSION) || defined(PROTO) 19873 int 19874 store_session_globals(fd) 19875 FILE *fd; 19876 { 19877 hashitem_T *hi; 19878 dictitem_T *this_var; 19879 int todo; 19880 char_u *p, *t; 19881 19882 todo = globvarht.ht_used; 19883 for (hi = globvarht.ht_array; todo > 0; ++hi) 19884 { 19885 if (!HASHITEM_EMPTY(hi)) 19886 { 19887 --todo; 19888 this_var = HI2DI(hi); 19889 if ((this_var->di_tv.v_type == VAR_NUMBER 19890 || this_var->di_tv.v_type == VAR_STRING) 19891 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 19892 { 19893 /* Escape special characters with a backslash. Turn a LF and 19894 * CR into \n and \r. */ 19895 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 19896 (char_u *)"\\\"\n\r"); 19897 if (p == NULL) /* out of memory */ 19898 break; 19899 for (t = p; *t != NUL; ++t) 19900 if (*t == '\n') 19901 *t = 'n'; 19902 else if (*t == '\r') 19903 *t = 'r'; 19904 if ((fprintf(fd, "let %s = %c%s%c", 19905 this_var->di_key, 19906 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19907 : ' ', 19908 p, 19909 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19910 : ' ') < 0) 19911 || put_eol(fd) == FAIL) 19912 { 19913 vim_free(p); 19914 return FAIL; 19915 } 19916 vim_free(p); 19917 } 19918 } 19919 } 19920 return OK; 19921 } 19922 #endif 19923 19924 /* 19925 * Display script name where an item was last set. 19926 * Should only be invoked when 'verbose' is non-zero. 19927 */ 19928 void 19929 last_set_msg(scriptID) 19930 scid_T scriptID; 19931 { 19932 char_u *p; 19933 19934 if (scriptID != 0) 19935 { 19936 p = home_replace_save(NULL, get_scriptname(scriptID)); 19937 if (p != NULL) 19938 { 19939 verbose_enter(); 19940 MSG_PUTS(_("\n\tLast set from ")); 19941 MSG_PUTS(p); 19942 vim_free(p); 19943 verbose_leave(); 19944 } 19945 } 19946 } 19947 19948 #endif /* FEAT_EVAL */ 19949 19950 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 19951 19952 19953 #ifdef WIN3264 19954 /* 19955 * Functions for ":8" filename modifier: get 8.3 version of a filename. 19956 */ 19957 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19958 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 19959 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19960 19961 /* 19962 * Get the short pathname of a file. 19963 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 19964 */ 19965 static int 19966 get_short_pathname(fnamep, bufp, fnamelen) 19967 char_u **fnamep; 19968 char_u **bufp; 19969 int *fnamelen; 19970 { 19971 int l,len; 19972 char_u *newbuf; 19973 19974 len = *fnamelen; 19975 19976 l = GetShortPathName(*fnamep, *fnamep, len); 19977 if (l > len - 1) 19978 { 19979 /* If that doesn't work (not enough space), then save the string 19980 * and try again with a new buffer big enough 19981 */ 19982 newbuf = vim_strnsave(*fnamep, l); 19983 if (newbuf == NULL) 19984 return 0; 19985 19986 vim_free(*bufp); 19987 *fnamep = *bufp = newbuf; 19988 19989 l = GetShortPathName(*fnamep,*fnamep,l+1); 19990 19991 /* Really should always succeed, as the buffer is big enough */ 19992 } 19993 19994 *fnamelen = l; 19995 return 1; 19996 } 19997 19998 /* 19999 * Create a short path name. Returns the length of the buffer it needs. 20000 * Doesn't copy over the end of the buffer passed in. 20001 */ 20002 static int 20003 shortpath_for_invalid_fname(fname, bufp, fnamelen) 20004 char_u **fname; 20005 char_u **bufp; 20006 int *fnamelen; 20007 { 20008 char_u *s, *p, *pbuf2, *pbuf3; 20009 char_u ch; 20010 int len, len2, plen, slen; 20011 20012 /* Make a copy */ 20013 len2 = *fnamelen; 20014 pbuf2 = vim_strnsave(*fname, len2); 20015 pbuf3 = NULL; 20016 20017 s = pbuf2 + len2 - 1; /* Find the end */ 20018 slen = 1; 20019 plen = len2; 20020 20021 if (after_pathsep(pbuf2, s + 1)) 20022 { 20023 --s; 20024 ++slen; 20025 --plen; 20026 } 20027 20028 do 20029 { 20030 /* Go back one path-seperator */ 20031 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 20032 { 20033 --s; 20034 ++slen; 20035 --plen; 20036 } 20037 if (s <= pbuf2) 20038 break; 20039 20040 /* Remeber the character that is about to be blatted */ 20041 ch = *s; 20042 *s = 0; /* get_short_pathname requires a null-terminated string */ 20043 20044 /* Try it in situ */ 20045 p = pbuf2; 20046 if (!get_short_pathname(&p, &pbuf3, &plen)) 20047 { 20048 vim_free(pbuf2); 20049 return -1; 20050 } 20051 *s = ch; /* Preserve the string */ 20052 } while (plen == 0); 20053 20054 if (plen > 0) 20055 { 20056 /* Remeber the length of the new string. */ 20057 *fnamelen = len = plen + slen; 20058 vim_free(*bufp); 20059 if (len > len2) 20060 { 20061 /* If there's not enough space in the currently allocated string, 20062 * then copy it to a buffer big enough. 20063 */ 20064 *fname= *bufp = vim_strnsave(p, len); 20065 if (*fname == NULL) 20066 return -1; 20067 } 20068 else 20069 { 20070 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 20071 *fname = *bufp = pbuf2; 20072 if (p != pbuf2) 20073 strncpy(*fname, p, plen); 20074 pbuf2 = NULL; 20075 } 20076 /* Concat the next bit */ 20077 strncpy(*fname + plen, s, slen); 20078 (*fname)[len] = '\0'; 20079 } 20080 vim_free(pbuf3); 20081 vim_free(pbuf2); 20082 return 0; 20083 } 20084 20085 /* 20086 * Get a pathname for a partial path. 20087 */ 20088 static int 20089 shortpath_for_partial(fnamep, bufp, fnamelen) 20090 char_u **fnamep; 20091 char_u **bufp; 20092 int *fnamelen; 20093 { 20094 int sepcount, len, tflen; 20095 char_u *p; 20096 char_u *pbuf, *tfname; 20097 int hasTilde; 20098 20099 /* Count up the path seperators from the RHS.. so we know which part 20100 * of the path to return. 20101 */ 20102 sepcount = 0; 20103 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 20104 if (vim_ispathsep(*p)) 20105 ++sepcount; 20106 20107 /* Need full path first (use expand_env() to remove a "~/") */ 20108 hasTilde = (**fnamep == '~'); 20109 if (hasTilde) 20110 pbuf = tfname = expand_env_save(*fnamep); 20111 else 20112 pbuf = tfname = FullName_save(*fnamep, FALSE); 20113 20114 len = tflen = STRLEN(tfname); 20115 20116 if (!get_short_pathname(&tfname, &pbuf, &len)) 20117 return -1; 20118 20119 if (len == 0) 20120 { 20121 /* Don't have a valid filename, so shorten the rest of the 20122 * path if we can. This CAN give us invalid 8.3 filenames, but 20123 * there's not a lot of point in guessing what it might be. 20124 */ 20125 len = tflen; 20126 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 20127 return -1; 20128 } 20129 20130 /* Count the paths backward to find the beginning of the desired string. */ 20131 for (p = tfname + len - 1; p >= tfname; --p) 20132 { 20133 #ifdef FEAT_MBYTE 20134 if (has_mbyte) 20135 p -= mb_head_off(tfname, p); 20136 #endif 20137 if (vim_ispathsep(*p)) 20138 { 20139 if (sepcount == 0 || (hasTilde && sepcount == 1)) 20140 break; 20141 else 20142 sepcount --; 20143 } 20144 } 20145 if (hasTilde) 20146 { 20147 --p; 20148 if (p >= tfname) 20149 *p = '~'; 20150 else 20151 return -1; 20152 } 20153 else 20154 ++p; 20155 20156 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 20157 vim_free(*bufp); 20158 *fnamelen = (int)STRLEN(p); 20159 *bufp = pbuf; 20160 *fnamep = p; 20161 20162 return 0; 20163 } 20164 #endif /* WIN3264 */ 20165 20166 /* 20167 * Adjust a filename, according to a string of modifiers. 20168 * *fnamep must be NUL terminated when called. When returning, the length is 20169 * determined by *fnamelen. 20170 * Returns valid flags. 20171 * When there is an error, *fnamep is set to NULL. 20172 */ 20173 int 20174 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 20175 char_u *src; /* string with modifiers */ 20176 int *usedlen; /* characters after src that are used */ 20177 char_u **fnamep; /* file name so far */ 20178 char_u **bufp; /* buffer for allocated file name or NULL */ 20179 int *fnamelen; /* length of fnamep */ 20180 { 20181 int valid = 0; 20182 char_u *tail; 20183 char_u *s, *p, *pbuf; 20184 char_u dirname[MAXPATHL]; 20185 int c; 20186 int has_fullname = 0; 20187 #ifdef WIN3264 20188 int has_shortname = 0; 20189 #endif 20190 20191 repeat: 20192 /* ":p" - full path/file_name */ 20193 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 20194 { 20195 has_fullname = 1; 20196 20197 valid |= VALID_PATH; 20198 *usedlen += 2; 20199 20200 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 20201 if ((*fnamep)[0] == '~' 20202 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 20203 && ((*fnamep)[1] == '/' 20204 # ifdef BACKSLASH_IN_FILENAME 20205 || (*fnamep)[1] == '\\' 20206 # endif 20207 || (*fnamep)[1] == NUL) 20208 20209 #endif 20210 ) 20211 { 20212 *fnamep = expand_env_save(*fnamep); 20213 vim_free(*bufp); /* free any allocated file name */ 20214 *bufp = *fnamep; 20215 if (*fnamep == NULL) 20216 return -1; 20217 } 20218 20219 /* When "/." or "/.." is used: force expansion to get rid of it. */ 20220 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 20221 { 20222 if (vim_ispathsep(*p) 20223 && p[1] == '.' 20224 && (p[2] == NUL 20225 || vim_ispathsep(p[2]) 20226 || (p[2] == '.' 20227 && (p[3] == NUL || vim_ispathsep(p[3]))))) 20228 break; 20229 } 20230 20231 /* FullName_save() is slow, don't use it when not needed. */ 20232 if (*p != NUL || !vim_isAbsName(*fnamep)) 20233 { 20234 *fnamep = FullName_save(*fnamep, *p != NUL); 20235 vim_free(*bufp); /* free any allocated file name */ 20236 *bufp = *fnamep; 20237 if (*fnamep == NULL) 20238 return -1; 20239 } 20240 20241 /* Append a path separator to a directory. */ 20242 if (mch_isdir(*fnamep)) 20243 { 20244 /* Make room for one or two extra characters. */ 20245 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 20246 vim_free(*bufp); /* free any allocated file name */ 20247 *bufp = *fnamep; 20248 if (*fnamep == NULL) 20249 return -1; 20250 add_pathsep(*fnamep); 20251 } 20252 } 20253 20254 /* ":." - path relative to the current directory */ 20255 /* ":~" - path relative to the home directory */ 20256 /* ":8" - shortname path - postponed till after */ 20257 while (src[*usedlen] == ':' 20258 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 20259 { 20260 *usedlen += 2; 20261 if (c == '8') 20262 { 20263 #ifdef WIN3264 20264 has_shortname = 1; /* Postpone this. */ 20265 #endif 20266 continue; 20267 } 20268 pbuf = NULL; 20269 /* Need full path first (use expand_env() to remove a "~/") */ 20270 if (!has_fullname) 20271 { 20272 if (c == '.' && **fnamep == '~') 20273 p = pbuf = expand_env_save(*fnamep); 20274 else 20275 p = pbuf = FullName_save(*fnamep, FALSE); 20276 } 20277 else 20278 p = *fnamep; 20279 20280 has_fullname = 0; 20281 20282 if (p != NULL) 20283 { 20284 if (c == '.') 20285 { 20286 mch_dirname(dirname, MAXPATHL); 20287 s = shorten_fname(p, dirname); 20288 if (s != NULL) 20289 { 20290 *fnamep = s; 20291 if (pbuf != NULL) 20292 { 20293 vim_free(*bufp); /* free any allocated file name */ 20294 *bufp = pbuf; 20295 pbuf = NULL; 20296 } 20297 } 20298 } 20299 else 20300 { 20301 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 20302 /* Only replace it when it starts with '~' */ 20303 if (*dirname == '~') 20304 { 20305 s = vim_strsave(dirname); 20306 if (s != NULL) 20307 { 20308 *fnamep = s; 20309 vim_free(*bufp); 20310 *bufp = s; 20311 } 20312 } 20313 } 20314 vim_free(pbuf); 20315 } 20316 } 20317 20318 tail = gettail(*fnamep); 20319 *fnamelen = (int)STRLEN(*fnamep); 20320 20321 /* ":h" - head, remove "/file_name", can be repeated */ 20322 /* Don't remove the first "/" or "c:\" */ 20323 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 20324 { 20325 valid |= VALID_HEAD; 20326 *usedlen += 2; 20327 s = get_past_head(*fnamep); 20328 while (tail > s && after_pathsep(s, tail)) 20329 --tail; 20330 *fnamelen = (int)(tail - *fnamep); 20331 #ifdef VMS 20332 if (*fnamelen > 0) 20333 *fnamelen += 1; /* the path separator is part of the path */ 20334 #endif 20335 while (tail > s && !after_pathsep(s, tail)) 20336 mb_ptr_back(*fnamep, tail); 20337 } 20338 20339 /* ":8" - shortname */ 20340 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 20341 { 20342 *usedlen += 2; 20343 #ifdef WIN3264 20344 has_shortname = 1; 20345 #endif 20346 } 20347 20348 #ifdef WIN3264 20349 /* Check shortname after we have done 'heads' and before we do 'tails' 20350 */ 20351 if (has_shortname) 20352 { 20353 pbuf = NULL; 20354 /* Copy the string if it is shortened by :h */ 20355 if (*fnamelen < (int)STRLEN(*fnamep)) 20356 { 20357 p = vim_strnsave(*fnamep, *fnamelen); 20358 if (p == 0) 20359 return -1; 20360 vim_free(*bufp); 20361 *bufp = *fnamep = p; 20362 } 20363 20364 /* Split into two implementations - makes it easier. First is where 20365 * there isn't a full name already, second is where there is. 20366 */ 20367 if (!has_fullname && !vim_isAbsName(*fnamep)) 20368 { 20369 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 20370 return -1; 20371 } 20372 else 20373 { 20374 int l; 20375 20376 /* Simple case, already have the full-name 20377 * Nearly always shorter, so try first time. */ 20378 l = *fnamelen; 20379 if (!get_short_pathname(fnamep, bufp, &l)) 20380 return -1; 20381 20382 if (l == 0) 20383 { 20384 /* Couldn't find the filename.. search the paths. 20385 */ 20386 l = *fnamelen; 20387 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 20388 return -1; 20389 } 20390 *fnamelen = l; 20391 } 20392 } 20393 #endif /* WIN3264 */ 20394 20395 /* ":t" - tail, just the basename */ 20396 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 20397 { 20398 *usedlen += 2; 20399 *fnamelen -= (int)(tail - *fnamep); 20400 *fnamep = tail; 20401 } 20402 20403 /* ":e" - extension, can be repeated */ 20404 /* ":r" - root, without extension, can be repeated */ 20405 while (src[*usedlen] == ':' 20406 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 20407 { 20408 /* find a '.' in the tail: 20409 * - for second :e: before the current fname 20410 * - otherwise: The last '.' 20411 */ 20412 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 20413 s = *fnamep - 2; 20414 else 20415 s = *fnamep + *fnamelen - 1; 20416 for ( ; s > tail; --s) 20417 if (s[0] == '.') 20418 break; 20419 if (src[*usedlen + 1] == 'e') /* :e */ 20420 { 20421 if (s > tail) 20422 { 20423 *fnamelen += (int)(*fnamep - (s + 1)); 20424 *fnamep = s + 1; 20425 #ifdef VMS 20426 /* cut version from the extension */ 20427 s = *fnamep + *fnamelen - 1; 20428 for ( ; s > *fnamep; --s) 20429 if (s[0] == ';') 20430 break; 20431 if (s > *fnamep) 20432 *fnamelen = s - *fnamep; 20433 #endif 20434 } 20435 else if (*fnamep <= tail) 20436 *fnamelen = 0; 20437 } 20438 else /* :r */ 20439 { 20440 if (s > tail) /* remove one extension */ 20441 *fnamelen = (int)(s - *fnamep); 20442 } 20443 *usedlen += 2; 20444 } 20445 20446 /* ":s?pat?foo?" - substitute */ 20447 /* ":gs?pat?foo?" - global substitute */ 20448 if (src[*usedlen] == ':' 20449 && (src[*usedlen + 1] == 's' 20450 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 20451 { 20452 char_u *str; 20453 char_u *pat; 20454 char_u *sub; 20455 int sep; 20456 char_u *flags; 20457 int didit = FALSE; 20458 20459 flags = (char_u *)""; 20460 s = src + *usedlen + 2; 20461 if (src[*usedlen + 1] == 'g') 20462 { 20463 flags = (char_u *)"g"; 20464 ++s; 20465 } 20466 20467 sep = *s++; 20468 if (sep) 20469 { 20470 /* find end of pattern */ 20471 p = vim_strchr(s, sep); 20472 if (p != NULL) 20473 { 20474 pat = vim_strnsave(s, (int)(p - s)); 20475 if (pat != NULL) 20476 { 20477 s = p + 1; 20478 /* find end of substitution */ 20479 p = vim_strchr(s, sep); 20480 if (p != NULL) 20481 { 20482 sub = vim_strnsave(s, (int)(p - s)); 20483 str = vim_strnsave(*fnamep, *fnamelen); 20484 if (sub != NULL && str != NULL) 20485 { 20486 *usedlen = (int)(p + 1 - src); 20487 s = do_string_sub(str, pat, sub, flags); 20488 if (s != NULL) 20489 { 20490 *fnamep = s; 20491 *fnamelen = (int)STRLEN(s); 20492 vim_free(*bufp); 20493 *bufp = s; 20494 didit = TRUE; 20495 } 20496 } 20497 vim_free(sub); 20498 vim_free(str); 20499 } 20500 vim_free(pat); 20501 } 20502 } 20503 /* after using ":s", repeat all the modifiers */ 20504 if (didit) 20505 goto repeat; 20506 } 20507 } 20508 20509 return valid; 20510 } 20511 20512 /* 20513 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 20514 * "flags" can be "g" to do a global substitute. 20515 * Returns an allocated string, NULL for error. 20516 */ 20517 char_u * 20518 do_string_sub(str, pat, sub, flags) 20519 char_u *str; 20520 char_u *pat; 20521 char_u *sub; 20522 char_u *flags; 20523 { 20524 int sublen; 20525 regmatch_T regmatch; 20526 int i; 20527 int do_all; 20528 char_u *tail; 20529 garray_T ga; 20530 char_u *ret; 20531 char_u *save_cpo; 20532 20533 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 20534 save_cpo = p_cpo; 20535 p_cpo = (char_u *)""; 20536 20537 ga_init2(&ga, 1, 200); 20538 20539 do_all = (flags[0] == 'g'); 20540 20541 regmatch.rm_ic = p_ic; 20542 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 20543 if (regmatch.regprog != NULL) 20544 { 20545 tail = str; 20546 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 20547 { 20548 /* 20549 * Get some space for a temporary buffer to do the substitution 20550 * into. It will contain: 20551 * - The text up to where the match is. 20552 * - The substituted text. 20553 * - The text after the match. 20554 */ 20555 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 20556 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 20557 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 20558 { 20559 ga_clear(&ga); 20560 break; 20561 } 20562 20563 /* copy the text up to where the match is */ 20564 i = (int)(regmatch.startp[0] - tail); 20565 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 20566 /* add the substituted text */ 20567 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 20568 + ga.ga_len + i, TRUE, TRUE, FALSE); 20569 ga.ga_len += i + sublen - 1; 20570 /* avoid getting stuck on a match with an empty string */ 20571 if (tail == regmatch.endp[0]) 20572 { 20573 if (*tail == NUL) 20574 break; 20575 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 20576 ++ga.ga_len; 20577 } 20578 else 20579 { 20580 tail = regmatch.endp[0]; 20581 if (*tail == NUL) 20582 break; 20583 } 20584 if (!do_all) 20585 break; 20586 } 20587 20588 if (ga.ga_data != NULL) 20589 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 20590 20591 vim_free(regmatch.regprog); 20592 } 20593 20594 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 20595 ga_clear(&ga); 20596 p_cpo = save_cpo; 20597 20598 return ret; 20599 } 20600 20601 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 20602