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 <io.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 }; 342 343 /* shorthand */ 344 #define vv_type vv_di.di_tv.v_type 345 #define vv_nr vv_di.di_tv.vval.v_number 346 #define vv_str vv_di.di_tv.vval.v_string 347 #define vv_tv vv_di.di_tv 348 349 /* 350 * The v: variables are stored in dictionary "vimvardict". 351 * "vimvars_var" is the variable that is used for the "l:" scope. 352 */ 353 static dict_T vimvardict; 354 static dictitem_T vimvars_var; 355 #define vimvarht vimvardict.dv_hashtab 356 357 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 358 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 359 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 360 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 361 #endif 362 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 363 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 364 static char_u *skip_var_one __ARGS((char_u *arg)); 365 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 366 static void list_glob_vars __ARGS((void)); 367 static void list_buf_vars __ARGS((void)); 368 static void list_win_vars __ARGS((void)); 369 static void list_vim_vars __ARGS((void)); 370 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 371 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 372 static int check_changedtick __ARGS((char_u *arg)); 373 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 374 static void clear_lval __ARGS((lval_T *lp)); 375 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 376 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 377 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 378 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 379 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 380 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 381 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 382 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 383 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 384 static int tv_islocked __ARGS((typval_T *tv)); 385 386 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 387 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 388 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 389 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 390 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 391 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 392 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 393 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 394 395 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 396 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 397 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 398 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 399 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 400 static list_T *list_alloc __ARGS((void)); 401 static void list_free __ARGS((list_T *l)); 402 static listitem_T *listitem_alloc __ARGS((void)); 403 static void listitem_free __ARGS((listitem_T *item)); 404 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 405 static long list_len __ARGS((list_T *l)); 406 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 407 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 408 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 409 static listitem_T *list_find __ARGS((list_T *l, long n)); 410 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 411 static void list_append __ARGS((list_T *l, listitem_T *item)); 412 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 413 static int list_append_string __ARGS((list_T *l, char_u *str, int len)); 414 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 415 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 416 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 417 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 418 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 419 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 420 static char_u *list2string __ARGS((typval_T *tv)); 421 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); 422 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 423 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 424 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 425 static void dict_unref __ARGS((dict_T *d)); 426 static void dict_free __ARGS((dict_T *d)); 427 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 428 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 429 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 430 static void dictitem_free __ARGS((dictitem_T *item)); 431 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 432 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 433 static long dict_len __ARGS((dict_T *d)); 434 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 435 static char_u *dict2string __ARGS((typval_T *tv)); 436 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 437 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 438 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 439 static char_u *string_quote __ARGS((char_u *str, int function)); 440 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 441 static int find_internal_func __ARGS((char_u *name)); 442 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 443 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)); 444 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)); 445 static void emsg_funcname __ARGS((char *msg, char_u *name)); 446 447 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 448 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 449 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 450 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 466 #if defined(FEAT_INS_EXPAND) 467 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 468 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 469 #endif 470 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 475 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 567 #ifdef vim_mkdir 568 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 569 #endif 570 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 604 #ifdef HAVE_STRFTIME 605 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 606 #endif 607 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 636 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 637 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 638 639 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 640 static int get_env_len __ARGS((char_u **arg)); 641 static int get_id_len __ARGS((char_u **arg)); 642 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 643 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 644 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 645 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 646 valid character */ 647 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 648 static int eval_isnamec __ARGS((int c)); 649 static int eval_isnamec1 __ARGS((int c)); 650 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 651 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 652 static typval_T *alloc_tv __ARGS((void)); 653 static typval_T *alloc_string_tv __ARGS((char_u *string)); 654 static void free_tv __ARGS((typval_T *varp)); 655 static void init_tv __ARGS((typval_T *varp)); 656 static long get_tv_number __ARGS((typval_T *varp)); 657 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 658 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 659 static char_u *get_tv_string __ARGS((typval_T *varp)); 660 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 661 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 662 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 663 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 664 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 665 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 666 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 667 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 668 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 669 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 670 static int var_check_ro __ARGS((int flags, char_u *name)); 671 static int tv_check_lock __ARGS((int lock, char_u *name)); 672 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 673 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 674 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 675 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 676 static int eval_fname_script __ARGS((char_u *p)); 677 static int eval_fname_sid __ARGS((char_u *p)); 678 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 679 static ufunc_T *find_func __ARGS((char_u *name)); 680 static int function_exists __ARGS((char_u *name)); 681 static int builtin_function __ARGS((char_u *name)); 682 #ifdef FEAT_PROFILE 683 static void func_do_profile __ARGS((ufunc_T *fp)); 684 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 685 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 686 static int 687 # ifdef __BORLANDC__ 688 _RTLENTRYF 689 # endif 690 prof_total_cmp __ARGS((const void *s1, const void *s2)); 691 static int 692 # ifdef __BORLANDC__ 693 _RTLENTRYF 694 # endif 695 prof_self_cmp __ARGS((const void *s1, const void *s2)); 696 #endif 697 static int script_autoload __ARGS((char_u *name, int reload)); 698 static char_u *autoload_name __ARGS((char_u *name)); 699 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 700 static void func_free __ARGS((ufunc_T *fp)); 701 static void func_unref __ARGS((char_u *name)); 702 static void func_ref __ARGS((char_u *name)); 703 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)); 704 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 705 706 /* Character used as separated in autoload function/variable names. */ 707 #define AUTOLOAD_CHAR '#' 708 709 /* 710 * Initialize the global and v: variables. 711 */ 712 void 713 eval_init() 714 { 715 int i; 716 struct vimvar *p; 717 718 init_var_dict(&globvardict, &globvars_var); 719 init_var_dict(&vimvardict, &vimvars_var); 720 hash_init(&compat_hashtab); 721 hash_init(&func_hashtab); 722 723 for (i = 0; i < VV_LEN; ++i) 724 { 725 p = &vimvars[i]; 726 STRCPY(p->vv_di.di_key, p->vv_name); 727 if (p->vv_flags & VV_RO) 728 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 729 else if (p->vv_flags & VV_RO_SBX) 730 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 731 else 732 p->vv_di.di_flags = DI_FLAGS_FIX; 733 734 /* add to v: scope dict, unless the value is not always available */ 735 if (p->vv_type != VAR_UNKNOWN) 736 hash_add(&vimvarht, p->vv_di.di_key); 737 if (p->vv_flags & VV_COMPAT) 738 /* add to compat scope dict */ 739 hash_add(&compat_hashtab, p->vv_di.di_key); 740 } 741 } 742 743 #if defined(EXITFREE) || defined(PROTO) 744 void 745 eval_clear() 746 { 747 int i; 748 struct vimvar *p; 749 750 for (i = 0; i < VV_LEN; ++i) 751 { 752 p = &vimvars[i]; 753 if (p->vv_di.di_tv.v_type == VAR_STRING) 754 { 755 vim_free(p->vv_di.di_tv.vval.v_string); 756 p->vv_di.di_tv.vval.v_string = NULL; 757 } 758 } 759 hash_clear(&vimvarht); 760 hash_clear(&compat_hashtab); 761 762 /* script-local variables */ 763 for (i = 1; i <= ga_scripts.ga_len; ++i) 764 vars_clear(&SCRIPT_VARS(i)); 765 ga_clear(&ga_scripts); 766 free_scriptnames(); 767 768 /* global variables */ 769 vars_clear(&globvarht); 770 771 /* functions */ 772 free_all_functions(); 773 hash_clear(&func_hashtab); 774 775 /* unreferenced lists and dicts */ 776 (void)garbage_collect(); 777 } 778 #endif 779 780 /* 781 * Return the name of the executed function. 782 */ 783 char_u * 784 func_name(cookie) 785 void *cookie; 786 { 787 return ((funccall_T *)cookie)->func->uf_name; 788 } 789 790 /* 791 * Return the address holding the next breakpoint line for a funccall cookie. 792 */ 793 linenr_T * 794 func_breakpoint(cookie) 795 void *cookie; 796 { 797 return &((funccall_T *)cookie)->breakpoint; 798 } 799 800 /* 801 * Return the address holding the debug tick for a funccall cookie. 802 */ 803 int * 804 func_dbg_tick(cookie) 805 void *cookie; 806 { 807 return &((funccall_T *)cookie)->dbg_tick; 808 } 809 810 /* 811 * Return the nesting level for a funccall cookie. 812 */ 813 int 814 func_level(cookie) 815 void *cookie; 816 { 817 return ((funccall_T *)cookie)->level; 818 } 819 820 /* pointer to funccal for currently active function */ 821 funccall_T *current_funccal = NULL; 822 823 /* 824 * Return TRUE when a function was ended by a ":return" command. 825 */ 826 int 827 current_func_returned() 828 { 829 return current_funccal->returned; 830 } 831 832 833 /* 834 * Set an internal variable to a string value. Creates the variable if it does 835 * not already exist. 836 */ 837 void 838 set_internal_string_var(name, value) 839 char_u *name; 840 char_u *value; 841 { 842 char_u *val; 843 typval_T *tvp; 844 845 val = vim_strsave(value); 846 if (val != NULL) 847 { 848 tvp = alloc_string_tv(val); 849 if (tvp != NULL) 850 { 851 set_var(name, tvp, FALSE); 852 free_tv(tvp); 853 } 854 } 855 } 856 857 static lval_T *redir_lval = NULL; 858 static char_u *redir_endp = NULL; 859 static char_u *redir_varname = NULL; 860 861 /* 862 * Start recording command output to a variable 863 * Returns OK if successfully completed the setup. FAIL otherwise. 864 */ 865 int 866 var_redir_start(name, append) 867 char_u *name; 868 int append; /* append to an existing variable */ 869 { 870 int save_emsg; 871 int err; 872 typval_T tv; 873 874 /* Make sure a valid variable name is specified */ 875 if (!eval_isnamec1(*name)) 876 { 877 EMSG(_(e_invarg)); 878 return FAIL; 879 } 880 881 redir_varname = vim_strsave(name); 882 if (redir_varname == NULL) 883 return FAIL; 884 885 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 886 if (redir_lval == NULL) 887 { 888 var_redir_stop(); 889 return FAIL; 890 } 891 892 /* Parse the variable name (can be a dict or list entry). */ 893 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 894 FNE_CHECK_START); 895 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 896 { 897 if (redir_endp != NULL && *redir_endp != NUL) 898 /* Trailing characters are present after the variable name */ 899 EMSG(_(e_trailing)); 900 else 901 EMSG(_(e_invarg)); 902 var_redir_stop(); 903 return FAIL; 904 } 905 906 /* check if we can write to the variable: set it to or append an empty 907 * string */ 908 save_emsg = did_emsg; 909 did_emsg = FALSE; 910 tv.v_type = VAR_STRING; 911 tv.vval.v_string = (char_u *)""; 912 if (append) 913 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 914 else 915 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 916 err = did_emsg; 917 did_emsg += save_emsg; 918 if (err) 919 { 920 var_redir_stop(); 921 return FAIL; 922 } 923 if (redir_lval->ll_newkey != NULL) 924 { 925 /* Dictionary item was created, don't do it again. */ 926 vim_free(redir_lval->ll_newkey); 927 redir_lval->ll_newkey = NULL; 928 } 929 930 return OK; 931 } 932 933 /* 934 * Append "value[len]" to the variable set by var_redir_start(). 935 */ 936 void 937 var_redir_str(value, len) 938 char_u *value; 939 int len; 940 { 941 char_u *val; 942 typval_T tv; 943 int save_emsg; 944 int err; 945 946 if (redir_lval == NULL) 947 return; 948 949 if (len == -1) 950 /* Append the entire string */ 951 val = vim_strsave(value); 952 else 953 /* Append only the specified number of characters */ 954 val = vim_strnsave(value, len); 955 if (val == NULL) 956 return; 957 958 tv.v_type = VAR_STRING; 959 tv.vval.v_string = val; 960 961 save_emsg = did_emsg; 962 did_emsg = FALSE; 963 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 964 err = did_emsg; 965 did_emsg += save_emsg; 966 if (err) 967 var_redir_stop(); 968 969 vim_free(tv.vval.v_string); 970 } 971 972 /* 973 * Stop redirecting command output to a variable. 974 */ 975 void 976 var_redir_stop() 977 { 978 if (redir_lval != NULL) 979 { 980 clear_lval(redir_lval); 981 vim_free(redir_lval); 982 redir_lval = NULL; 983 } 984 vim_free(redir_varname); 985 redir_varname = NULL; 986 } 987 988 # if defined(FEAT_MBYTE) || defined(PROTO) 989 int 990 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 991 char_u *enc_from; 992 char_u *enc_to; 993 char_u *fname_from; 994 char_u *fname_to; 995 { 996 int err = FALSE; 997 998 set_vim_var_string(VV_CC_FROM, enc_from, -1); 999 set_vim_var_string(VV_CC_TO, enc_to, -1); 1000 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1001 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1002 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1003 err = TRUE; 1004 set_vim_var_string(VV_CC_FROM, NULL, -1); 1005 set_vim_var_string(VV_CC_TO, NULL, -1); 1006 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1007 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1008 1009 if (err) 1010 return FAIL; 1011 return OK; 1012 } 1013 # endif 1014 1015 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1016 int 1017 eval_printexpr(fname, args) 1018 char_u *fname; 1019 char_u *args; 1020 { 1021 int err = FALSE; 1022 1023 set_vim_var_string(VV_FNAME_IN, fname, -1); 1024 set_vim_var_string(VV_CMDARG, args, -1); 1025 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1026 err = TRUE; 1027 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1028 set_vim_var_string(VV_CMDARG, NULL, -1); 1029 1030 if (err) 1031 { 1032 mch_remove(fname); 1033 return FAIL; 1034 } 1035 return OK; 1036 } 1037 # endif 1038 1039 # if defined(FEAT_DIFF) || defined(PROTO) 1040 void 1041 eval_diff(origfile, newfile, outfile) 1042 char_u *origfile; 1043 char_u *newfile; 1044 char_u *outfile; 1045 { 1046 int err = FALSE; 1047 1048 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1049 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1050 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1051 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1052 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1053 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1054 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1055 } 1056 1057 void 1058 eval_patch(origfile, difffile, outfile) 1059 char_u *origfile; 1060 char_u *difffile; 1061 char_u *outfile; 1062 { 1063 int err; 1064 1065 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1066 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1067 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1068 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1069 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1070 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1071 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1072 } 1073 # endif 1074 1075 /* 1076 * Top level evaluation function, returning a boolean. 1077 * Sets "error" to TRUE if there was an error. 1078 * Return TRUE or FALSE. 1079 */ 1080 int 1081 eval_to_bool(arg, error, nextcmd, skip) 1082 char_u *arg; 1083 int *error; 1084 char_u **nextcmd; 1085 int skip; /* only parse, don't execute */ 1086 { 1087 typval_T tv; 1088 int retval = FALSE; 1089 1090 if (skip) 1091 ++emsg_skip; 1092 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1093 *error = TRUE; 1094 else 1095 { 1096 *error = FALSE; 1097 if (!skip) 1098 { 1099 retval = (get_tv_number_chk(&tv, error) != 0); 1100 clear_tv(&tv); 1101 } 1102 } 1103 if (skip) 1104 --emsg_skip; 1105 1106 return retval; 1107 } 1108 1109 /* 1110 * Top level evaluation function, returning a string. If "skip" is TRUE, 1111 * only parsing to "nextcmd" is done, without reporting errors. Return 1112 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1113 */ 1114 char_u * 1115 eval_to_string_skip(arg, nextcmd, skip) 1116 char_u *arg; 1117 char_u **nextcmd; 1118 int skip; /* only parse, don't execute */ 1119 { 1120 typval_T tv; 1121 char_u *retval; 1122 1123 if (skip) 1124 ++emsg_skip; 1125 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1126 retval = NULL; 1127 else 1128 { 1129 retval = vim_strsave(get_tv_string(&tv)); 1130 clear_tv(&tv); 1131 } 1132 if (skip) 1133 --emsg_skip; 1134 1135 return retval; 1136 } 1137 1138 /* 1139 * Skip over an expression at "*pp". 1140 * Return FAIL for an error, OK otherwise. 1141 */ 1142 int 1143 skip_expr(pp) 1144 char_u **pp; 1145 { 1146 typval_T rettv; 1147 1148 *pp = skipwhite(*pp); 1149 return eval1(pp, &rettv, FALSE); 1150 } 1151 1152 /* 1153 * Top level evaluation function, returning a string. 1154 * Return pointer to allocated memory, or NULL for failure. 1155 */ 1156 char_u * 1157 eval_to_string(arg, nextcmd) 1158 char_u *arg; 1159 char_u **nextcmd; 1160 { 1161 typval_T tv; 1162 char_u *retval; 1163 1164 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1165 retval = NULL; 1166 else 1167 { 1168 retval = vim_strsave(get_tv_string(&tv)); 1169 clear_tv(&tv); 1170 } 1171 1172 return retval; 1173 } 1174 1175 /* 1176 * Call eval_to_string() with "sandbox" set and not using local variables. 1177 */ 1178 char_u * 1179 eval_to_string_safe(arg, nextcmd) 1180 char_u *arg; 1181 char_u **nextcmd; 1182 { 1183 char_u *retval; 1184 void *save_funccalp; 1185 1186 save_funccalp = save_funccal(); 1187 ++sandbox; 1188 retval = eval_to_string(arg, nextcmd); 1189 --sandbox; 1190 restore_funccal(save_funccalp); 1191 return retval; 1192 } 1193 1194 /* 1195 * Top level evaluation function, returning a number. 1196 * Evaluates "expr" silently. 1197 * Returns -1 for an error. 1198 */ 1199 int 1200 eval_to_number(expr) 1201 char_u *expr; 1202 { 1203 typval_T rettv; 1204 int retval; 1205 char_u *p = skipwhite(expr); 1206 1207 ++emsg_off; 1208 1209 if (eval1(&p, &rettv, TRUE) == FAIL) 1210 retval = -1; 1211 else 1212 { 1213 retval = get_tv_number_chk(&rettv, NULL); 1214 clear_tv(&rettv); 1215 } 1216 --emsg_off; 1217 1218 return retval; 1219 } 1220 1221 /* 1222 * Prepare v: variable "idx" to be used. 1223 * Save the current typeval in "save_tv". 1224 * When not used yet add the variable to the v: hashtable. 1225 */ 1226 static void 1227 prepare_vimvar(idx, save_tv) 1228 int idx; 1229 typval_T *save_tv; 1230 { 1231 *save_tv = vimvars[idx].vv_tv; 1232 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1233 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1234 } 1235 1236 /* 1237 * Restore v: variable "idx" to typeval "save_tv". 1238 * When no longer defined, remove the variable from the v: hashtable. 1239 */ 1240 static void 1241 restore_vimvar(idx, save_tv) 1242 int idx; 1243 typval_T *save_tv; 1244 { 1245 hashitem_T *hi; 1246 1247 clear_tv(&vimvars[idx].vv_tv); 1248 vimvars[idx].vv_tv = *save_tv; 1249 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1250 { 1251 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1252 if (HASHITEM_EMPTY(hi)) 1253 EMSG2(_(e_intern2), "restore_vimvar()"); 1254 else 1255 hash_remove(&vimvarht, hi); 1256 } 1257 } 1258 1259 #if defined(FEAT_SYN_HL) || defined(PROTO) 1260 /* 1261 * Evaluate an expression to a list with suggestions. 1262 * For the "expr:" part of 'spellsuggest'. 1263 */ 1264 list_T * 1265 eval_spell_expr(badword, expr) 1266 char_u *badword; 1267 char_u *expr; 1268 { 1269 typval_T save_val; 1270 typval_T rettv; 1271 list_T *list = NULL; 1272 char_u *p = skipwhite(expr); 1273 1274 /* Set "v:val" to the bad word. */ 1275 prepare_vimvar(VV_VAL, &save_val); 1276 vimvars[VV_VAL].vv_type = VAR_STRING; 1277 vimvars[VV_VAL].vv_str = badword; 1278 if (p_verbose == 0) 1279 ++emsg_off; 1280 1281 if (eval1(&p, &rettv, TRUE) == OK) 1282 { 1283 if (rettv.v_type != VAR_LIST) 1284 clear_tv(&rettv); 1285 else 1286 list = rettv.vval.v_list; 1287 } 1288 1289 if (p_verbose == 0) 1290 --emsg_off; 1291 vimvars[VV_VAL].vv_str = NULL; 1292 restore_vimvar(VV_VAL, &save_val); 1293 1294 return list; 1295 } 1296 1297 /* 1298 * "list" is supposed to contain two items: a word and a number. Return the 1299 * word in "pp" and the number as the return value. 1300 * Return -1 if anything isn't right. 1301 * Used to get the good word and score from the eval_spell_expr() result. 1302 */ 1303 int 1304 get_spellword(list, pp) 1305 list_T *list; 1306 char_u **pp; 1307 { 1308 listitem_T *li; 1309 1310 li = list->lv_first; 1311 if (li == NULL) 1312 return -1; 1313 *pp = get_tv_string(&li->li_tv); 1314 1315 li = li->li_next; 1316 if (li == NULL) 1317 return -1; 1318 return get_tv_number(&li->li_tv); 1319 } 1320 #endif 1321 1322 /* 1323 * Top level evaluation function, 1324 */ 1325 typval_T * 1326 eval_expr(arg, nextcmd) 1327 char_u *arg; 1328 char_u **nextcmd; 1329 { 1330 typval_T *tv; 1331 1332 tv = (typval_T *)alloc(sizeof(typval_T)); 1333 if (!tv) 1334 return NULL; 1335 1336 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1337 { 1338 vim_free(tv); 1339 return NULL; 1340 } 1341 1342 return tv; 1343 } 1344 1345 1346 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1347 /* 1348 * Call some vimL function and return the result in "*rettv". 1349 * Uses argv[argc] for the function arguments. 1350 * Returns OK or FAIL. 1351 */ 1352 static int 1353 call_vim_function(func, argc, argv, safe, rettv) 1354 char_u *func; 1355 int argc; 1356 char_u **argv; 1357 int safe; /* use the sandbox */ 1358 typval_T *rettv; 1359 { 1360 typval_T *argvars; 1361 long n; 1362 int len; 1363 int i; 1364 int doesrange; 1365 void *save_funccalp = NULL; 1366 int ret; 1367 1368 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1369 if (argvars == NULL) 1370 return FAIL; 1371 1372 for (i = 0; i < argc; i++) 1373 { 1374 /* Pass a NULL or empty argument as an empty string */ 1375 if (argv[i] == NULL || *argv[i] == NUL) 1376 { 1377 argvars[i].v_type = VAR_STRING; 1378 argvars[i].vval.v_string = (char_u *)""; 1379 continue; 1380 } 1381 1382 /* Recognize a number argument, the others must be strings. */ 1383 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1384 if (len != 0 && len == (int)STRLEN(argv[i])) 1385 { 1386 argvars[i].v_type = VAR_NUMBER; 1387 argvars[i].vval.v_number = n; 1388 } 1389 else 1390 { 1391 argvars[i].v_type = VAR_STRING; 1392 argvars[i].vval.v_string = argv[i]; 1393 } 1394 } 1395 1396 if (safe) 1397 { 1398 save_funccalp = save_funccal(); 1399 ++sandbox; 1400 } 1401 1402 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1403 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1404 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1405 &doesrange, TRUE, NULL); 1406 if (safe) 1407 { 1408 --sandbox; 1409 restore_funccal(save_funccalp); 1410 } 1411 vim_free(argvars); 1412 1413 if (ret == FAIL) 1414 clear_tv(rettv); 1415 1416 return ret; 1417 } 1418 1419 /* 1420 * Call vimL function "func" and return the result as a string. 1421 * Returns NULL when calling the function fails. 1422 * Uses argv[argc] for the function arguments. 1423 */ 1424 void * 1425 call_func_retstr(func, argc, argv, safe) 1426 char_u *func; 1427 int argc; 1428 char_u **argv; 1429 int safe; /* use the sandbox */ 1430 { 1431 typval_T rettv; 1432 char_u *retval; 1433 1434 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1435 return NULL; 1436 1437 retval = vim_strsave(get_tv_string(&rettv)); 1438 clear_tv(&rettv); 1439 return retval; 1440 } 1441 1442 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1443 /* 1444 * Call vimL function "func" and return the result as a number. 1445 * Returns -1 when calling the function fails. 1446 * Uses argv[argc] for the function arguments. 1447 */ 1448 long 1449 call_func_retnr(func, argc, argv, safe) 1450 char_u *func; 1451 int argc; 1452 char_u **argv; 1453 int safe; /* use the sandbox */ 1454 { 1455 typval_T rettv; 1456 long retval; 1457 1458 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1459 return -1; 1460 1461 retval = get_tv_number_chk(&rettv, NULL); 1462 clear_tv(&rettv); 1463 return retval; 1464 } 1465 #endif 1466 1467 /* 1468 * Call vimL function "func" and return the result as a list 1469 * Uses argv[argc] for the function arguments. 1470 */ 1471 void * 1472 call_func_retlist(func, argc, argv, safe) 1473 char_u *func; 1474 int argc; 1475 char_u **argv; 1476 int safe; /* use the sandbox */ 1477 { 1478 typval_T rettv; 1479 1480 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1481 return NULL; 1482 1483 if (rettv.v_type != VAR_LIST) 1484 { 1485 clear_tv(&rettv); 1486 return NULL; 1487 } 1488 1489 return rettv.vval.v_list; 1490 } 1491 1492 #endif 1493 1494 /* 1495 * Save the current function call pointer, and set it to NULL. 1496 * Used when executing autocommands and for ":source". 1497 */ 1498 void * 1499 save_funccal() 1500 { 1501 funccall_T *fc = current_funccal; 1502 1503 current_funccal = NULL; 1504 return (void *)fc; 1505 } 1506 1507 void 1508 restore_funccal(vfc) 1509 void *vfc; 1510 { 1511 funccall_T *fc = (funccall_T *)vfc; 1512 1513 current_funccal = fc; 1514 } 1515 1516 #if defined(FEAT_PROFILE) || defined(PROTO) 1517 /* 1518 * Prepare profiling for entering a child or something else that is not 1519 * counted for the script/function itself. 1520 * Should always be called in pair with prof_child_exit(). 1521 */ 1522 void 1523 prof_child_enter(tm) 1524 proftime_T *tm; /* place to store waittime */ 1525 { 1526 funccall_T *fc = current_funccal; 1527 1528 if (fc != NULL && fc->func->uf_profiling) 1529 profile_start(&fc->prof_child); 1530 script_prof_save(tm); 1531 } 1532 1533 /* 1534 * Take care of time spent in a child. 1535 * Should always be called after prof_child_enter(). 1536 */ 1537 void 1538 prof_child_exit(tm) 1539 proftime_T *tm; /* where waittime was stored */ 1540 { 1541 funccall_T *fc = current_funccal; 1542 1543 if (fc != NULL && fc->func->uf_profiling) 1544 { 1545 profile_end(&fc->prof_child); 1546 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1547 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1548 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1549 } 1550 script_prof_restore(tm); 1551 } 1552 #endif 1553 1554 1555 #ifdef FEAT_FOLDING 1556 /* 1557 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1558 * it in "*cp". Doesn't give error messages. 1559 */ 1560 int 1561 eval_foldexpr(arg, cp) 1562 char_u *arg; 1563 int *cp; 1564 { 1565 typval_T tv; 1566 int retval; 1567 char_u *s; 1568 1569 ++emsg_off; 1570 ++sandbox; 1571 *cp = NUL; 1572 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1573 retval = 0; 1574 else 1575 { 1576 /* If the result is a number, just return the number. */ 1577 if (tv.v_type == VAR_NUMBER) 1578 retval = tv.vval.v_number; 1579 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1580 retval = 0; 1581 else 1582 { 1583 /* If the result is a string, check if there is a non-digit before 1584 * the number. */ 1585 s = tv.vval.v_string; 1586 if (!VIM_ISDIGIT(*s) && *s != '-') 1587 *cp = *s++; 1588 retval = atol((char *)s); 1589 } 1590 clear_tv(&tv); 1591 } 1592 --emsg_off; 1593 --sandbox; 1594 1595 return retval; 1596 } 1597 #endif 1598 1599 /* 1600 * ":let" list all variable values 1601 * ":let var1 var2" list variable values 1602 * ":let var = expr" assignment command. 1603 * ":let var += expr" assignment command. 1604 * ":let var -= expr" assignment command. 1605 * ":let var .= expr" assignment command. 1606 * ":let [var1, var2] = expr" unpack list. 1607 */ 1608 void 1609 ex_let(eap) 1610 exarg_T *eap; 1611 { 1612 char_u *arg = eap->arg; 1613 char_u *expr = NULL; 1614 typval_T rettv; 1615 int i; 1616 int var_count = 0; 1617 int semicolon = 0; 1618 char_u op[2]; 1619 1620 expr = skip_var_list(arg, &var_count, &semicolon); 1621 if (expr == NULL) 1622 return; 1623 expr = vim_strchr(expr, '='); 1624 if (expr == NULL) 1625 { 1626 /* 1627 * ":let" without "=": list variables 1628 */ 1629 if (*arg == '[') 1630 EMSG(_(e_invarg)); 1631 else if (!ends_excmd(*arg)) 1632 /* ":let var1 var2" */ 1633 arg = list_arg_vars(eap, arg); 1634 else if (!eap->skip) 1635 { 1636 /* ":let" */ 1637 list_glob_vars(); 1638 list_buf_vars(); 1639 list_win_vars(); 1640 list_vim_vars(); 1641 } 1642 eap->nextcmd = check_nextcmd(arg); 1643 } 1644 else 1645 { 1646 op[0] = '='; 1647 op[1] = NUL; 1648 if (expr > arg) 1649 { 1650 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1651 op[0] = expr[-1]; /* +=, -= or .= */ 1652 } 1653 expr = skipwhite(expr + 1); 1654 1655 if (eap->skip) 1656 ++emsg_skip; 1657 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1658 if (eap->skip) 1659 { 1660 if (i != FAIL) 1661 clear_tv(&rettv); 1662 --emsg_skip; 1663 } 1664 else if (i != FAIL) 1665 { 1666 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1667 op); 1668 clear_tv(&rettv); 1669 } 1670 } 1671 } 1672 1673 /* 1674 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1675 * Handles both "var" with any type and "[var, var; var]" with a list type. 1676 * When "nextchars" is not NULL it points to a string with characters that 1677 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1678 * or concatenate. 1679 * Returns OK or FAIL; 1680 */ 1681 static int 1682 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1683 char_u *arg_start; 1684 typval_T *tv; 1685 int copy; /* copy values from "tv", don't move */ 1686 int semicolon; /* from skip_var_list() */ 1687 int var_count; /* from skip_var_list() */ 1688 char_u *nextchars; 1689 { 1690 char_u *arg = arg_start; 1691 list_T *l; 1692 int i; 1693 listitem_T *item; 1694 typval_T ltv; 1695 1696 if (*arg != '[') 1697 { 1698 /* 1699 * ":let var = expr" or ":for var in list" 1700 */ 1701 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1702 return FAIL; 1703 return OK; 1704 } 1705 1706 /* 1707 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1708 */ 1709 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1710 { 1711 EMSG(_(e_listreq)); 1712 return FAIL; 1713 } 1714 1715 i = list_len(l); 1716 if (semicolon == 0 && var_count < i) 1717 { 1718 EMSG(_("E687: Less targets than List items")); 1719 return FAIL; 1720 } 1721 if (var_count - semicolon > i) 1722 { 1723 EMSG(_("E688: More targets than List items")); 1724 return FAIL; 1725 } 1726 1727 item = l->lv_first; 1728 while (*arg != ']') 1729 { 1730 arg = skipwhite(arg + 1); 1731 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1732 item = item->li_next; 1733 if (arg == NULL) 1734 return FAIL; 1735 1736 arg = skipwhite(arg); 1737 if (*arg == ';') 1738 { 1739 /* Put the rest of the list (may be empty) in the var after ';'. 1740 * Create a new list for this. */ 1741 l = list_alloc(); 1742 if (l == NULL) 1743 return FAIL; 1744 while (item != NULL) 1745 { 1746 list_append_tv(l, &item->li_tv); 1747 item = item->li_next; 1748 } 1749 1750 ltv.v_type = VAR_LIST; 1751 ltv.v_lock = 0; 1752 ltv.vval.v_list = l; 1753 l->lv_refcount = 1; 1754 1755 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1756 (char_u *)"]", nextchars); 1757 clear_tv(<v); 1758 if (arg == NULL) 1759 return FAIL; 1760 break; 1761 } 1762 else if (*arg != ',' && *arg != ']') 1763 { 1764 EMSG2(_(e_intern2), "ex_let_vars()"); 1765 return FAIL; 1766 } 1767 } 1768 1769 return OK; 1770 } 1771 1772 /* 1773 * Skip over assignable variable "var" or list of variables "[var, var]". 1774 * Used for ":let varvar = expr" and ":for varvar in expr". 1775 * For "[var, var]" increment "*var_count" for each variable. 1776 * for "[var, var; var]" set "semicolon". 1777 * Return NULL for an error. 1778 */ 1779 static char_u * 1780 skip_var_list(arg, var_count, semicolon) 1781 char_u *arg; 1782 int *var_count; 1783 int *semicolon; 1784 { 1785 char_u *p, *s; 1786 1787 if (*arg == '[') 1788 { 1789 /* "[var, var]": find the matching ']'. */ 1790 p = arg; 1791 for (;;) 1792 { 1793 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1794 s = skip_var_one(p); 1795 if (s == p) 1796 { 1797 EMSG2(_(e_invarg2), p); 1798 return NULL; 1799 } 1800 ++*var_count; 1801 1802 p = skipwhite(s); 1803 if (*p == ']') 1804 break; 1805 else if (*p == ';') 1806 { 1807 if (*semicolon == 1) 1808 { 1809 EMSG(_("Double ; in list of variables")); 1810 return NULL; 1811 } 1812 *semicolon = 1; 1813 } 1814 else if (*p != ',') 1815 { 1816 EMSG2(_(e_invarg2), p); 1817 return NULL; 1818 } 1819 } 1820 return p + 1; 1821 } 1822 else 1823 return skip_var_one(arg); 1824 } 1825 1826 /* 1827 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1828 * l[idx]. 1829 */ 1830 static char_u * 1831 skip_var_one(arg) 1832 char_u *arg; 1833 { 1834 if (*arg == '@' && arg[1] != NUL) 1835 return arg + 2; 1836 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1837 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1838 } 1839 1840 /* 1841 * List variables for hashtab "ht" with prefix "prefix". 1842 * If "empty" is TRUE also list NULL strings as empty strings. 1843 */ 1844 static void 1845 list_hashtable_vars(ht, prefix, empty) 1846 hashtab_T *ht; 1847 char_u *prefix; 1848 int empty; 1849 { 1850 hashitem_T *hi; 1851 dictitem_T *di; 1852 int todo; 1853 1854 todo = ht->ht_used; 1855 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1856 { 1857 if (!HASHITEM_EMPTY(hi)) 1858 { 1859 --todo; 1860 di = HI2DI(hi); 1861 if (empty || di->di_tv.v_type != VAR_STRING 1862 || di->di_tv.vval.v_string != NULL) 1863 list_one_var(di, prefix); 1864 } 1865 } 1866 } 1867 1868 /* 1869 * List global variables. 1870 */ 1871 static void 1872 list_glob_vars() 1873 { 1874 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1875 } 1876 1877 /* 1878 * List buffer variables. 1879 */ 1880 static void 1881 list_buf_vars() 1882 { 1883 char_u numbuf[NUMBUFLEN]; 1884 1885 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1886 1887 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1888 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1889 } 1890 1891 /* 1892 * List window variables. 1893 */ 1894 static void 1895 list_win_vars() 1896 { 1897 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1898 } 1899 1900 /* 1901 * List Vim variables. 1902 */ 1903 static void 1904 list_vim_vars() 1905 { 1906 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1907 } 1908 1909 /* 1910 * List variables in "arg". 1911 */ 1912 static char_u * 1913 list_arg_vars(eap, arg) 1914 exarg_T *eap; 1915 char_u *arg; 1916 { 1917 int error = FALSE; 1918 int len; 1919 char_u *name; 1920 char_u *name_start; 1921 char_u *arg_subsc; 1922 char_u *tofree; 1923 typval_T tv; 1924 1925 while (!ends_excmd(*arg) && !got_int) 1926 { 1927 if (error || eap->skip) 1928 { 1929 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1930 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1931 { 1932 emsg_severe = TRUE; 1933 EMSG(_(e_trailing)); 1934 break; 1935 } 1936 } 1937 else 1938 { 1939 /* get_name_len() takes care of expanding curly braces */ 1940 name_start = name = arg; 1941 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1942 if (len <= 0) 1943 { 1944 /* This is mainly to keep test 49 working: when expanding 1945 * curly braces fails overrule the exception error message. */ 1946 if (len < 0 && !aborting()) 1947 { 1948 emsg_severe = TRUE; 1949 EMSG2(_(e_invarg2), arg); 1950 break; 1951 } 1952 error = TRUE; 1953 } 1954 else 1955 { 1956 if (tofree != NULL) 1957 name = tofree; 1958 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1959 error = TRUE; 1960 else 1961 { 1962 /* handle d.key, l[idx], f(expr) */ 1963 arg_subsc = arg; 1964 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1965 error = TRUE; 1966 else 1967 { 1968 if (arg == arg_subsc && len == 2 && name[1] == ':') 1969 { 1970 switch (*name) 1971 { 1972 case 'g': list_glob_vars(); break; 1973 case 'b': list_buf_vars(); break; 1974 case 'w': list_win_vars(); break; 1975 case 'v': list_vim_vars(); break; 1976 default: 1977 EMSG2(_("E738: Can't list variables for %s"), name); 1978 } 1979 } 1980 else 1981 { 1982 char_u numbuf[NUMBUFLEN]; 1983 char_u *tf; 1984 int c; 1985 char_u *s; 1986 1987 s = echo_string(&tv, &tf, numbuf); 1988 c = *arg; 1989 *arg = NUL; 1990 list_one_var_a((char_u *)"", 1991 arg == arg_subsc ? name : name_start, 1992 tv.v_type, s == NULL ? (char_u *)"" : s); 1993 *arg = c; 1994 vim_free(tf); 1995 } 1996 clear_tv(&tv); 1997 } 1998 } 1999 } 2000 2001 vim_free(tofree); 2002 } 2003 2004 arg = skipwhite(arg); 2005 } 2006 2007 return arg; 2008 } 2009 2010 /* 2011 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2012 * Returns a pointer to the char just after the var name. 2013 * Returns NULL if there is an error. 2014 */ 2015 static char_u * 2016 ex_let_one(arg, tv, copy, endchars, op) 2017 char_u *arg; /* points to variable name */ 2018 typval_T *tv; /* value to assign to variable */ 2019 int copy; /* copy value from "tv" */ 2020 char_u *endchars; /* valid chars after variable name or NULL */ 2021 char_u *op; /* "+", "-", "." or NULL*/ 2022 { 2023 int c1; 2024 char_u *name; 2025 char_u *p; 2026 char_u *arg_end = NULL; 2027 int len; 2028 int opt_flags; 2029 char_u *tofree = NULL; 2030 2031 /* 2032 * ":let $VAR = expr": Set environment variable. 2033 */ 2034 if (*arg == '$') 2035 { 2036 /* Find the end of the name. */ 2037 ++arg; 2038 name = arg; 2039 len = get_env_len(&arg); 2040 if (len == 0) 2041 EMSG2(_(e_invarg2), name - 1); 2042 else 2043 { 2044 if (op != NULL && (*op == '+' || *op == '-')) 2045 EMSG2(_(e_letwrong), op); 2046 else if (endchars != NULL 2047 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2048 EMSG(_(e_letunexp)); 2049 else 2050 { 2051 c1 = name[len]; 2052 name[len] = NUL; 2053 p = get_tv_string_chk(tv); 2054 if (p != NULL && op != NULL && *op == '.') 2055 { 2056 int mustfree = FALSE; 2057 char_u *s = vim_getenv(name, &mustfree); 2058 2059 if (s != NULL) 2060 { 2061 p = tofree = concat_str(s, p); 2062 if (mustfree) 2063 vim_free(s); 2064 } 2065 } 2066 if (p != NULL) 2067 { 2068 vim_setenv(name, p); 2069 if (STRICMP(name, "HOME") == 0) 2070 init_homedir(); 2071 else if (didset_vim && STRICMP(name, "VIM") == 0) 2072 didset_vim = FALSE; 2073 else if (didset_vimruntime 2074 && STRICMP(name, "VIMRUNTIME") == 0) 2075 didset_vimruntime = FALSE; 2076 arg_end = arg; 2077 } 2078 name[len] = c1; 2079 vim_free(tofree); 2080 } 2081 } 2082 } 2083 2084 /* 2085 * ":let &option = expr": Set option value. 2086 * ":let &l:option = expr": Set local option value. 2087 * ":let &g:option = expr": Set global option value. 2088 */ 2089 else if (*arg == '&') 2090 { 2091 /* Find the end of the name. */ 2092 p = find_option_end(&arg, &opt_flags); 2093 if (p == NULL || (endchars != NULL 2094 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2095 EMSG(_(e_letunexp)); 2096 else 2097 { 2098 long n; 2099 int opt_type; 2100 long numval; 2101 char_u *stringval = NULL; 2102 char_u *s; 2103 2104 c1 = *p; 2105 *p = NUL; 2106 2107 n = get_tv_number(tv); 2108 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2109 if (s != NULL && op != NULL && *op != '=') 2110 { 2111 opt_type = get_option_value(arg, &numval, 2112 &stringval, opt_flags); 2113 if ((opt_type == 1 && *op == '.') 2114 || (opt_type == 0 && *op != '.')) 2115 EMSG2(_(e_letwrong), op); 2116 else 2117 { 2118 if (opt_type == 1) /* number */ 2119 { 2120 if (*op == '+') 2121 n = numval + n; 2122 else 2123 n = numval - n; 2124 } 2125 else if (opt_type == 0 && stringval != NULL) /* string */ 2126 { 2127 s = concat_str(stringval, s); 2128 vim_free(stringval); 2129 stringval = s; 2130 } 2131 } 2132 } 2133 if (s != NULL) 2134 { 2135 set_option_value(arg, n, s, opt_flags); 2136 arg_end = p; 2137 } 2138 *p = c1; 2139 vim_free(stringval); 2140 } 2141 } 2142 2143 /* 2144 * ":let @r = expr": Set register contents. 2145 */ 2146 else if (*arg == '@') 2147 { 2148 ++arg; 2149 if (op != NULL && (*op == '+' || *op == '-')) 2150 EMSG2(_(e_letwrong), op); 2151 else if (endchars != NULL 2152 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2153 EMSG(_(e_letunexp)); 2154 else 2155 { 2156 char_u *tofree = NULL; 2157 char_u *s; 2158 2159 p = get_tv_string_chk(tv); 2160 if (p != NULL && op != NULL && *op == '.') 2161 { 2162 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2163 if (s != NULL) 2164 { 2165 p = tofree = concat_str(s, p); 2166 vim_free(s); 2167 } 2168 } 2169 if (p != NULL) 2170 { 2171 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2172 arg_end = arg + 1; 2173 } 2174 vim_free(tofree); 2175 } 2176 } 2177 2178 /* 2179 * ":let var = expr": Set internal variable. 2180 * ":let {expr} = expr": Idem, name made with curly braces 2181 */ 2182 else if (eval_isnamec1(*arg) || *arg == '{') 2183 { 2184 lval_T lv; 2185 2186 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2187 if (p != NULL && lv.ll_name != NULL) 2188 { 2189 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2190 EMSG(_(e_letunexp)); 2191 else 2192 { 2193 set_var_lval(&lv, p, tv, copy, op); 2194 arg_end = p; 2195 } 2196 } 2197 clear_lval(&lv); 2198 } 2199 2200 else 2201 EMSG2(_(e_invarg2), arg); 2202 2203 return arg_end; 2204 } 2205 2206 /* 2207 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2208 */ 2209 static int 2210 check_changedtick(arg) 2211 char_u *arg; 2212 { 2213 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2214 { 2215 EMSG2(_(e_readonlyvar), arg); 2216 return TRUE; 2217 } 2218 return FALSE; 2219 } 2220 2221 /* 2222 * Get an lval: variable, Dict item or List item that can be assigned a value 2223 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2224 * "name.key", "name.key[expr]" etc. 2225 * Indexing only works if "name" is an existing List or Dictionary. 2226 * "name" points to the start of the name. 2227 * If "rettv" is not NULL it points to the value to be assigned. 2228 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2229 * wrong; must end in space or cmd separator. 2230 * 2231 * Returns a pointer to just after the name, including indexes. 2232 * When an evaluation error occurs "lp->ll_name" is NULL; 2233 * Returns NULL for a parsing error. Still need to free items in "lp"! 2234 */ 2235 static char_u * 2236 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2237 char_u *name; 2238 typval_T *rettv; 2239 lval_T *lp; 2240 int unlet; 2241 int skip; 2242 int quiet; /* don't give error messages */ 2243 int fne_flags; /* flags for find_name_end() */ 2244 { 2245 char_u *p; 2246 char_u *expr_start, *expr_end; 2247 int cc; 2248 dictitem_T *v; 2249 typval_T var1; 2250 typval_T var2; 2251 int empty1 = FALSE; 2252 listitem_T *ni; 2253 char_u *key = NULL; 2254 int len; 2255 hashtab_T *ht; 2256 2257 /* Clear everything in "lp". */ 2258 vim_memset(lp, 0, sizeof(lval_T)); 2259 2260 if (skip) 2261 { 2262 /* When skipping just find the end of the name. */ 2263 lp->ll_name = name; 2264 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2265 } 2266 2267 /* Find the end of the name. */ 2268 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2269 if (expr_start != NULL) 2270 { 2271 /* Don't expand the name when we already know there is an error. */ 2272 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2273 && *p != '[' && *p != '.') 2274 { 2275 EMSG(_(e_trailing)); 2276 return NULL; 2277 } 2278 2279 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2280 if (lp->ll_exp_name == NULL) 2281 { 2282 /* Report an invalid expression in braces, unless the 2283 * expression evaluation has been cancelled due to an 2284 * aborting error, an interrupt, or an exception. */ 2285 if (!aborting() && !quiet) 2286 { 2287 emsg_severe = TRUE; 2288 EMSG2(_(e_invarg2), name); 2289 return NULL; 2290 } 2291 } 2292 lp->ll_name = lp->ll_exp_name; 2293 } 2294 else 2295 lp->ll_name = name; 2296 2297 /* Without [idx] or .key we are done. */ 2298 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2299 return p; 2300 2301 cc = *p; 2302 *p = NUL; 2303 v = find_var(lp->ll_name, &ht); 2304 if (v == NULL && !quiet) 2305 EMSG2(_(e_undefvar), lp->ll_name); 2306 *p = cc; 2307 if (v == NULL) 2308 return NULL; 2309 2310 /* 2311 * Loop until no more [idx] or .key is following. 2312 */ 2313 lp->ll_tv = &v->di_tv; 2314 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2315 { 2316 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2317 && !(lp->ll_tv->v_type == VAR_DICT 2318 && lp->ll_tv->vval.v_dict != NULL)) 2319 { 2320 if (!quiet) 2321 EMSG(_("E689: Can only index a List or Dictionary")); 2322 return NULL; 2323 } 2324 if (lp->ll_range) 2325 { 2326 if (!quiet) 2327 EMSG(_("E708: [:] must come last")); 2328 return NULL; 2329 } 2330 2331 len = -1; 2332 if (*p == '.') 2333 { 2334 key = p + 1; 2335 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2336 ; 2337 if (len == 0) 2338 { 2339 if (!quiet) 2340 EMSG(_(e_emptykey)); 2341 return NULL; 2342 } 2343 p = key + len; 2344 } 2345 else 2346 { 2347 /* Get the index [expr] or the first index [expr: ]. */ 2348 p = skipwhite(p + 1); 2349 if (*p == ':') 2350 empty1 = TRUE; 2351 else 2352 { 2353 empty1 = FALSE; 2354 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2355 return NULL; 2356 if (get_tv_string_chk(&var1) == NULL) 2357 { 2358 /* not a number or string */ 2359 clear_tv(&var1); 2360 return NULL; 2361 } 2362 } 2363 2364 /* Optionally get the second index [ :expr]. */ 2365 if (*p == ':') 2366 { 2367 if (lp->ll_tv->v_type == VAR_DICT) 2368 { 2369 if (!quiet) 2370 EMSG(_(e_dictrange)); 2371 if (!empty1) 2372 clear_tv(&var1); 2373 return NULL; 2374 } 2375 if (rettv != NULL && (rettv->v_type != VAR_LIST 2376 || rettv->vval.v_list == NULL)) 2377 { 2378 if (!quiet) 2379 EMSG(_("E709: [:] requires a List value")); 2380 if (!empty1) 2381 clear_tv(&var1); 2382 return NULL; 2383 } 2384 p = skipwhite(p + 1); 2385 if (*p == ']') 2386 lp->ll_empty2 = TRUE; 2387 else 2388 { 2389 lp->ll_empty2 = FALSE; 2390 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2391 { 2392 if (!empty1) 2393 clear_tv(&var1); 2394 return NULL; 2395 } 2396 if (get_tv_string_chk(&var2) == NULL) 2397 { 2398 /* not a number or string */ 2399 if (!empty1) 2400 clear_tv(&var1); 2401 clear_tv(&var2); 2402 return NULL; 2403 } 2404 } 2405 lp->ll_range = TRUE; 2406 } 2407 else 2408 lp->ll_range = FALSE; 2409 2410 if (*p != ']') 2411 { 2412 if (!quiet) 2413 EMSG(_(e_missbrac)); 2414 if (!empty1) 2415 clear_tv(&var1); 2416 if (lp->ll_range && !lp->ll_empty2) 2417 clear_tv(&var2); 2418 return NULL; 2419 } 2420 2421 /* Skip to past ']'. */ 2422 ++p; 2423 } 2424 2425 if (lp->ll_tv->v_type == VAR_DICT) 2426 { 2427 if (len == -1) 2428 { 2429 /* "[key]": get key from "var1" */ 2430 key = get_tv_string(&var1); /* is number or string */ 2431 if (*key == NUL) 2432 { 2433 if (!quiet) 2434 EMSG(_(e_emptykey)); 2435 clear_tv(&var1); 2436 return NULL; 2437 } 2438 } 2439 lp->ll_list = NULL; 2440 lp->ll_dict = lp->ll_tv->vval.v_dict; 2441 lp->ll_di = dict_find(lp->ll_dict, key, len); 2442 if (lp->ll_di == NULL) 2443 { 2444 /* Key does not exist in dict: may need to add it. */ 2445 if (*p == '[' || *p == '.' || unlet) 2446 { 2447 if (!quiet) 2448 EMSG2(_(e_dictkey), key); 2449 if (len == -1) 2450 clear_tv(&var1); 2451 return NULL; 2452 } 2453 if (len == -1) 2454 lp->ll_newkey = vim_strsave(key); 2455 else 2456 lp->ll_newkey = vim_strnsave(key, len); 2457 if (len == -1) 2458 clear_tv(&var1); 2459 if (lp->ll_newkey == NULL) 2460 p = NULL; 2461 break; 2462 } 2463 if (len == -1) 2464 clear_tv(&var1); 2465 lp->ll_tv = &lp->ll_di->di_tv; 2466 } 2467 else 2468 { 2469 /* 2470 * Get the number and item for the only or first index of the List. 2471 */ 2472 if (empty1) 2473 lp->ll_n1 = 0; 2474 else 2475 { 2476 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2477 clear_tv(&var1); 2478 } 2479 lp->ll_dict = NULL; 2480 lp->ll_list = lp->ll_tv->vval.v_list; 2481 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2482 if (lp->ll_li == NULL) 2483 { 2484 if (!quiet) 2485 EMSGN(_(e_listidx), lp->ll_n1); 2486 if (lp->ll_range && !lp->ll_empty2) 2487 clear_tv(&var2); 2488 return NULL; 2489 } 2490 2491 /* 2492 * May need to find the item or absolute index for the second 2493 * index of a range. 2494 * When no index given: "lp->ll_empty2" is TRUE. 2495 * Otherwise "lp->ll_n2" is set to the second index. 2496 */ 2497 if (lp->ll_range && !lp->ll_empty2) 2498 { 2499 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2500 clear_tv(&var2); 2501 if (lp->ll_n2 < 0) 2502 { 2503 ni = list_find(lp->ll_list, lp->ll_n2); 2504 if (ni == NULL) 2505 { 2506 if (!quiet) 2507 EMSGN(_(e_listidx), lp->ll_n2); 2508 return NULL; 2509 } 2510 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2511 } 2512 2513 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2514 if (lp->ll_n1 < 0) 2515 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2516 if (lp->ll_n2 < lp->ll_n1) 2517 { 2518 if (!quiet) 2519 EMSGN(_(e_listidx), lp->ll_n2); 2520 return NULL; 2521 } 2522 } 2523 2524 lp->ll_tv = &lp->ll_li->li_tv; 2525 } 2526 } 2527 2528 return p; 2529 } 2530 2531 /* 2532 * Clear lval "lp" that was filled by get_lval(). 2533 */ 2534 static void 2535 clear_lval(lp) 2536 lval_T *lp; 2537 { 2538 vim_free(lp->ll_exp_name); 2539 vim_free(lp->ll_newkey); 2540 } 2541 2542 /* 2543 * Set a variable that was parsed by get_lval() to "rettv". 2544 * "endp" points to just after the parsed name. 2545 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2546 */ 2547 static void 2548 set_var_lval(lp, endp, rettv, copy, op) 2549 lval_T *lp; 2550 char_u *endp; 2551 typval_T *rettv; 2552 int copy; 2553 char_u *op; 2554 { 2555 int cc; 2556 listitem_T *ri; 2557 dictitem_T *di; 2558 2559 if (lp->ll_tv == NULL) 2560 { 2561 if (!check_changedtick(lp->ll_name)) 2562 { 2563 cc = *endp; 2564 *endp = NUL; 2565 if (op != NULL && *op != '=') 2566 { 2567 typval_T tv; 2568 2569 /* handle +=, -= and .= */ 2570 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2571 &tv, TRUE) == OK) 2572 { 2573 if (tv_op(&tv, rettv, op) == OK) 2574 set_var(lp->ll_name, &tv, FALSE); 2575 clear_tv(&tv); 2576 } 2577 } 2578 else 2579 set_var(lp->ll_name, rettv, copy); 2580 *endp = cc; 2581 } 2582 } 2583 else if (tv_check_lock(lp->ll_newkey == NULL 2584 ? lp->ll_tv->v_lock 2585 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2586 ; 2587 else if (lp->ll_range) 2588 { 2589 /* 2590 * Assign the List values to the list items. 2591 */ 2592 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2593 { 2594 if (op != NULL && *op != '=') 2595 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2596 else 2597 { 2598 clear_tv(&lp->ll_li->li_tv); 2599 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2600 } 2601 ri = ri->li_next; 2602 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2603 break; 2604 if (lp->ll_li->li_next == NULL) 2605 { 2606 /* Need to add an empty item. */ 2607 if (list_append_number(lp->ll_list, 0) == FAIL) 2608 { 2609 ri = NULL; 2610 break; 2611 } 2612 } 2613 lp->ll_li = lp->ll_li->li_next; 2614 ++lp->ll_n1; 2615 } 2616 if (ri != NULL) 2617 EMSG(_("E710: List value has more items than target")); 2618 else if (lp->ll_empty2 2619 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2620 : lp->ll_n1 != lp->ll_n2) 2621 EMSG(_("E711: List value has not enough items")); 2622 } 2623 else 2624 { 2625 /* 2626 * Assign to a List or Dictionary item. 2627 */ 2628 if (lp->ll_newkey != NULL) 2629 { 2630 if (op != NULL && *op != '=') 2631 { 2632 EMSG2(_(e_letwrong), op); 2633 return; 2634 } 2635 2636 /* Need to add an item to the Dictionary. */ 2637 di = dictitem_alloc(lp->ll_newkey); 2638 if (di == NULL) 2639 return; 2640 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2641 { 2642 vim_free(di); 2643 return; 2644 } 2645 lp->ll_tv = &di->di_tv; 2646 } 2647 else if (op != NULL && *op != '=') 2648 { 2649 tv_op(lp->ll_tv, rettv, op); 2650 return; 2651 } 2652 else 2653 clear_tv(lp->ll_tv); 2654 2655 /* 2656 * Assign the value to the variable or list item. 2657 */ 2658 if (copy) 2659 copy_tv(rettv, lp->ll_tv); 2660 else 2661 { 2662 *lp->ll_tv = *rettv; 2663 lp->ll_tv->v_lock = 0; 2664 init_tv(rettv); 2665 } 2666 } 2667 } 2668 2669 /* 2670 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2671 * Returns OK or FAIL. 2672 */ 2673 static int 2674 tv_op(tv1, tv2, op) 2675 typval_T *tv1; 2676 typval_T *tv2; 2677 char_u *op; 2678 { 2679 long n; 2680 char_u numbuf[NUMBUFLEN]; 2681 char_u *s; 2682 2683 /* Can't do anything with a Funcref or a Dict on the right. */ 2684 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2685 { 2686 switch (tv1->v_type) 2687 { 2688 case VAR_DICT: 2689 case VAR_FUNC: 2690 break; 2691 2692 case VAR_LIST: 2693 if (*op != '+' || tv2->v_type != VAR_LIST) 2694 break; 2695 /* List += List */ 2696 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2697 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2698 return OK; 2699 2700 case VAR_NUMBER: 2701 case VAR_STRING: 2702 if (tv2->v_type == VAR_LIST) 2703 break; 2704 if (*op == '+' || *op == '-') 2705 { 2706 /* nr += nr or nr -= nr*/ 2707 n = get_tv_number(tv1); 2708 if (*op == '+') 2709 n += get_tv_number(tv2); 2710 else 2711 n -= get_tv_number(tv2); 2712 clear_tv(tv1); 2713 tv1->v_type = VAR_NUMBER; 2714 tv1->vval.v_number = n; 2715 } 2716 else 2717 { 2718 /* str .= str */ 2719 s = get_tv_string(tv1); 2720 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2721 clear_tv(tv1); 2722 tv1->v_type = VAR_STRING; 2723 tv1->vval.v_string = s; 2724 } 2725 return OK; 2726 } 2727 } 2728 2729 EMSG2(_(e_letwrong), op); 2730 return FAIL; 2731 } 2732 2733 /* 2734 * Add a watcher to a list. 2735 */ 2736 static void 2737 list_add_watch(l, lw) 2738 list_T *l; 2739 listwatch_T *lw; 2740 { 2741 lw->lw_next = l->lv_watch; 2742 l->lv_watch = lw; 2743 } 2744 2745 /* 2746 * Remove a watcher from a list. 2747 * No warning when it isn't found... 2748 */ 2749 static void 2750 list_rem_watch(l, lwrem) 2751 list_T *l; 2752 listwatch_T *lwrem; 2753 { 2754 listwatch_T *lw, **lwp; 2755 2756 lwp = &l->lv_watch; 2757 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2758 { 2759 if (lw == lwrem) 2760 { 2761 *lwp = lw->lw_next; 2762 break; 2763 } 2764 lwp = &lw->lw_next; 2765 } 2766 } 2767 2768 /* 2769 * Just before removing an item from a list: advance watchers to the next 2770 * item. 2771 */ 2772 static void 2773 list_fix_watch(l, item) 2774 list_T *l; 2775 listitem_T *item; 2776 { 2777 listwatch_T *lw; 2778 2779 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2780 if (lw->lw_item == item) 2781 lw->lw_item = item->li_next; 2782 } 2783 2784 /* 2785 * Evaluate the expression used in a ":for var in expr" command. 2786 * "arg" points to "var". 2787 * Set "*errp" to TRUE for an error, FALSE otherwise; 2788 * Return a pointer that holds the info. Null when there is an error. 2789 */ 2790 void * 2791 eval_for_line(arg, errp, nextcmdp, skip) 2792 char_u *arg; 2793 int *errp; 2794 char_u **nextcmdp; 2795 int skip; 2796 { 2797 forinfo_T *fi; 2798 char_u *expr; 2799 typval_T tv; 2800 list_T *l; 2801 2802 *errp = TRUE; /* default: there is an error */ 2803 2804 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2805 if (fi == NULL) 2806 return NULL; 2807 2808 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2809 if (expr == NULL) 2810 return fi; 2811 2812 expr = skipwhite(expr); 2813 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2814 { 2815 EMSG(_("E690: Missing \"in\" after :for")); 2816 return fi; 2817 } 2818 2819 if (skip) 2820 ++emsg_skip; 2821 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2822 { 2823 *errp = FALSE; 2824 if (!skip) 2825 { 2826 l = tv.vval.v_list; 2827 if (tv.v_type != VAR_LIST || l == NULL) 2828 { 2829 EMSG(_(e_listreq)); 2830 clear_tv(&tv); 2831 } 2832 else 2833 { 2834 /* No need to increment the refcount, it's already set for the 2835 * list being used in "tv". */ 2836 fi->fi_list = l; 2837 list_add_watch(l, &fi->fi_lw); 2838 fi->fi_lw.lw_item = l->lv_first; 2839 } 2840 } 2841 } 2842 if (skip) 2843 --emsg_skip; 2844 2845 return fi; 2846 } 2847 2848 /* 2849 * Use the first item in a ":for" list. Advance to the next. 2850 * Assign the values to the variable (list). "arg" points to the first one. 2851 * Return TRUE when a valid item was found, FALSE when at end of list or 2852 * something wrong. 2853 */ 2854 int 2855 next_for_item(fi_void, arg) 2856 void *fi_void; 2857 char_u *arg; 2858 { 2859 forinfo_T *fi = (forinfo_T *)fi_void; 2860 int result; 2861 listitem_T *item; 2862 2863 item = fi->fi_lw.lw_item; 2864 if (item == NULL) 2865 result = FALSE; 2866 else 2867 { 2868 fi->fi_lw.lw_item = item->li_next; 2869 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2870 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2871 } 2872 return result; 2873 } 2874 2875 /* 2876 * Free the structure used to store info used by ":for". 2877 */ 2878 void 2879 free_for_info(fi_void) 2880 void *fi_void; 2881 { 2882 forinfo_T *fi = (forinfo_T *)fi_void; 2883 2884 if (fi != NULL && fi->fi_list != NULL) 2885 { 2886 list_rem_watch(fi->fi_list, &fi->fi_lw); 2887 list_unref(fi->fi_list); 2888 } 2889 vim_free(fi); 2890 } 2891 2892 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2893 2894 void 2895 set_context_for_expression(xp, arg, cmdidx) 2896 expand_T *xp; 2897 char_u *arg; 2898 cmdidx_T cmdidx; 2899 { 2900 int got_eq = FALSE; 2901 int c; 2902 char_u *p; 2903 2904 if (cmdidx == CMD_let) 2905 { 2906 xp->xp_context = EXPAND_USER_VARS; 2907 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2908 { 2909 /* ":let var1 var2 ...": find last space. */ 2910 for (p = arg + STRLEN(arg); p >= arg; ) 2911 { 2912 xp->xp_pattern = p; 2913 mb_ptr_back(arg, p); 2914 if (vim_iswhite(*p)) 2915 break; 2916 } 2917 return; 2918 } 2919 } 2920 else 2921 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2922 : EXPAND_EXPRESSION; 2923 while ((xp->xp_pattern = vim_strpbrk(arg, 2924 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2925 { 2926 c = *xp->xp_pattern; 2927 if (c == '&') 2928 { 2929 c = xp->xp_pattern[1]; 2930 if (c == '&') 2931 { 2932 ++xp->xp_pattern; 2933 xp->xp_context = cmdidx != CMD_let || got_eq 2934 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2935 } 2936 else if (c != ' ') 2937 { 2938 xp->xp_context = EXPAND_SETTINGS; 2939 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2940 xp->xp_pattern += 2; 2941 2942 } 2943 } 2944 else if (c == '$') 2945 { 2946 /* environment variable */ 2947 xp->xp_context = EXPAND_ENV_VARS; 2948 } 2949 else if (c == '=') 2950 { 2951 got_eq = TRUE; 2952 xp->xp_context = EXPAND_EXPRESSION; 2953 } 2954 else if (c == '<' 2955 && xp->xp_context == EXPAND_FUNCTIONS 2956 && vim_strchr(xp->xp_pattern, '(') == NULL) 2957 { 2958 /* Function name can start with "<SNR>" */ 2959 break; 2960 } 2961 else if (cmdidx != CMD_let || got_eq) 2962 { 2963 if (c == '"') /* string */ 2964 { 2965 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2966 if (c == '\\' && xp->xp_pattern[1] != NUL) 2967 ++xp->xp_pattern; 2968 xp->xp_context = EXPAND_NOTHING; 2969 } 2970 else if (c == '\'') /* literal string */ 2971 { 2972 /* Trick: '' is like stopping and starting a literal string. */ 2973 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2974 /* skip */ ; 2975 xp->xp_context = EXPAND_NOTHING; 2976 } 2977 else if (c == '|') 2978 { 2979 if (xp->xp_pattern[1] == '|') 2980 { 2981 ++xp->xp_pattern; 2982 xp->xp_context = EXPAND_EXPRESSION; 2983 } 2984 else 2985 xp->xp_context = EXPAND_COMMANDS; 2986 } 2987 else 2988 xp->xp_context = EXPAND_EXPRESSION; 2989 } 2990 else 2991 /* Doesn't look like something valid, expand as an expression 2992 * anyway. */ 2993 xp->xp_context = EXPAND_EXPRESSION; 2994 arg = xp->xp_pattern; 2995 if (*arg != NUL) 2996 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 2997 /* skip */ ; 2998 } 2999 xp->xp_pattern = arg; 3000 } 3001 3002 #endif /* FEAT_CMDL_COMPL */ 3003 3004 /* 3005 * ":1,25call func(arg1, arg2)" function call. 3006 */ 3007 void 3008 ex_call(eap) 3009 exarg_T *eap; 3010 { 3011 char_u *arg = eap->arg; 3012 char_u *startarg; 3013 char_u *name; 3014 char_u *tofree; 3015 int len; 3016 typval_T rettv; 3017 linenr_T lnum; 3018 int doesrange; 3019 int failed = FALSE; 3020 funcdict_T fudi; 3021 3022 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3023 vim_free(fudi.fd_newkey); 3024 if (tofree == NULL) 3025 return; 3026 3027 /* Increase refcount on dictionary, it could get deleted when evaluating 3028 * the arguments. */ 3029 if (fudi.fd_dict != NULL) 3030 ++fudi.fd_dict->dv_refcount; 3031 3032 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3033 len = STRLEN(tofree); 3034 name = deref_func_name(tofree, &len); 3035 3036 /* Skip white space to allow ":call func ()". Not good, but required for 3037 * backward compatibility. */ 3038 startarg = skipwhite(arg); 3039 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3040 3041 if (*startarg != '(') 3042 { 3043 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3044 goto end; 3045 } 3046 3047 /* 3048 * When skipping, evaluate the function once, to find the end of the 3049 * arguments. 3050 * When the function takes a range, this is discovered after the first 3051 * call, and the loop is broken. 3052 */ 3053 if (eap->skip) 3054 { 3055 ++emsg_skip; 3056 lnum = eap->line2; /* do it once, also with an invalid range */ 3057 } 3058 else 3059 lnum = eap->line1; 3060 for ( ; lnum <= eap->line2; ++lnum) 3061 { 3062 if (!eap->skip && eap->addr_count > 0) 3063 { 3064 curwin->w_cursor.lnum = lnum; 3065 curwin->w_cursor.col = 0; 3066 } 3067 arg = startarg; 3068 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3069 eap->line1, eap->line2, &doesrange, 3070 !eap->skip, fudi.fd_dict) == FAIL) 3071 { 3072 failed = TRUE; 3073 break; 3074 } 3075 clear_tv(&rettv); 3076 if (doesrange || eap->skip) 3077 break; 3078 /* Stop when immediately aborting on error, or when an interrupt 3079 * occurred or an exception was thrown but not caught. 3080 * get_func_tv() returned OK, so that the check for trailing 3081 * characters below is executed. */ 3082 if (aborting()) 3083 break; 3084 } 3085 if (eap->skip) 3086 --emsg_skip; 3087 3088 if (!failed) 3089 { 3090 /* Check for trailing illegal characters and a following command. */ 3091 if (!ends_excmd(*arg)) 3092 { 3093 emsg_severe = TRUE; 3094 EMSG(_(e_trailing)); 3095 } 3096 else 3097 eap->nextcmd = check_nextcmd(arg); 3098 } 3099 3100 end: 3101 dict_unref(fudi.fd_dict); 3102 vim_free(tofree); 3103 } 3104 3105 /* 3106 * ":unlet[!] var1 ... " command. 3107 */ 3108 void 3109 ex_unlet(eap) 3110 exarg_T *eap; 3111 { 3112 ex_unletlock(eap, eap->arg, 0); 3113 } 3114 3115 /* 3116 * ":lockvar" and ":unlockvar" commands 3117 */ 3118 void 3119 ex_lockvar(eap) 3120 exarg_T *eap; 3121 { 3122 char_u *arg = eap->arg; 3123 int deep = 2; 3124 3125 if (eap->forceit) 3126 deep = -1; 3127 else if (vim_isdigit(*arg)) 3128 { 3129 deep = getdigits(&arg); 3130 arg = skipwhite(arg); 3131 } 3132 3133 ex_unletlock(eap, arg, deep); 3134 } 3135 3136 /* 3137 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3138 */ 3139 static void 3140 ex_unletlock(eap, argstart, deep) 3141 exarg_T *eap; 3142 char_u *argstart; 3143 int deep; 3144 { 3145 char_u *arg = argstart; 3146 char_u *name_end; 3147 int error = FALSE; 3148 lval_T lv; 3149 3150 do 3151 { 3152 /* Parse the name and find the end. */ 3153 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3154 FNE_CHECK_START); 3155 if (lv.ll_name == NULL) 3156 error = TRUE; /* error but continue parsing */ 3157 if (name_end == NULL || (!vim_iswhite(*name_end) 3158 && !ends_excmd(*name_end))) 3159 { 3160 if (name_end != NULL) 3161 { 3162 emsg_severe = TRUE; 3163 EMSG(_(e_trailing)); 3164 } 3165 if (!(eap->skip || error)) 3166 clear_lval(&lv); 3167 break; 3168 } 3169 3170 if (!error && !eap->skip) 3171 { 3172 if (eap->cmdidx == CMD_unlet) 3173 { 3174 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3175 error = TRUE; 3176 } 3177 else 3178 { 3179 if (do_lock_var(&lv, name_end, deep, 3180 eap->cmdidx == CMD_lockvar) == FAIL) 3181 error = TRUE; 3182 } 3183 } 3184 3185 if (!eap->skip) 3186 clear_lval(&lv); 3187 3188 arg = skipwhite(name_end); 3189 } while (!ends_excmd(*arg)); 3190 3191 eap->nextcmd = check_nextcmd(arg); 3192 } 3193 3194 static int 3195 do_unlet_var(lp, name_end, forceit) 3196 lval_T *lp; 3197 char_u *name_end; 3198 int forceit; 3199 { 3200 int ret = OK; 3201 int cc; 3202 3203 if (lp->ll_tv == NULL) 3204 { 3205 cc = *name_end; 3206 *name_end = NUL; 3207 3208 /* Normal name or expanded name. */ 3209 if (check_changedtick(lp->ll_name)) 3210 ret = FAIL; 3211 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3212 ret = FAIL; 3213 *name_end = cc; 3214 } 3215 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3216 return FAIL; 3217 else if (lp->ll_range) 3218 { 3219 listitem_T *li; 3220 3221 /* Delete a range of List items. */ 3222 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3223 { 3224 li = lp->ll_li->li_next; 3225 listitem_remove(lp->ll_list, lp->ll_li); 3226 lp->ll_li = li; 3227 ++lp->ll_n1; 3228 } 3229 } 3230 else 3231 { 3232 if (lp->ll_list != NULL) 3233 /* unlet a List item. */ 3234 listitem_remove(lp->ll_list, lp->ll_li); 3235 else 3236 /* unlet a Dictionary item. */ 3237 dictitem_remove(lp->ll_dict, lp->ll_di); 3238 } 3239 3240 return ret; 3241 } 3242 3243 /* 3244 * "unlet" a variable. Return OK if it existed, FAIL if not. 3245 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3246 */ 3247 int 3248 do_unlet(name, forceit) 3249 char_u *name; 3250 int forceit; 3251 { 3252 hashtab_T *ht; 3253 hashitem_T *hi; 3254 char_u *varname; 3255 3256 ht = find_var_ht(name, &varname); 3257 if (ht != NULL && *varname != NUL) 3258 { 3259 hi = hash_find(ht, varname); 3260 if (!HASHITEM_EMPTY(hi)) 3261 { 3262 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3263 return FAIL; 3264 delete_var(ht, hi); 3265 return OK; 3266 } 3267 } 3268 if (forceit) 3269 return OK; 3270 EMSG2(_("E108: No such variable: \"%s\""), name); 3271 return FAIL; 3272 } 3273 3274 /* 3275 * Lock or unlock variable indicated by "lp". 3276 * "deep" is the levels to go (-1 for unlimited); 3277 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3278 */ 3279 static int 3280 do_lock_var(lp, name_end, deep, lock) 3281 lval_T *lp; 3282 char_u *name_end; 3283 int deep; 3284 int lock; 3285 { 3286 int ret = OK; 3287 int cc; 3288 dictitem_T *di; 3289 3290 if (deep == 0) /* nothing to do */ 3291 return OK; 3292 3293 if (lp->ll_tv == NULL) 3294 { 3295 cc = *name_end; 3296 *name_end = NUL; 3297 3298 /* Normal name or expanded name. */ 3299 if (check_changedtick(lp->ll_name)) 3300 ret = FAIL; 3301 else 3302 { 3303 di = find_var(lp->ll_name, NULL); 3304 if (di == NULL) 3305 ret = FAIL; 3306 else 3307 { 3308 if (lock) 3309 di->di_flags |= DI_FLAGS_LOCK; 3310 else 3311 di->di_flags &= ~DI_FLAGS_LOCK; 3312 item_lock(&di->di_tv, deep, lock); 3313 } 3314 } 3315 *name_end = cc; 3316 } 3317 else if (lp->ll_range) 3318 { 3319 listitem_T *li = lp->ll_li; 3320 3321 /* (un)lock a range of List items. */ 3322 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3323 { 3324 item_lock(&li->li_tv, deep, lock); 3325 li = li->li_next; 3326 ++lp->ll_n1; 3327 } 3328 } 3329 else if (lp->ll_list != NULL) 3330 /* (un)lock a List item. */ 3331 item_lock(&lp->ll_li->li_tv, deep, lock); 3332 else 3333 /* un(lock) a Dictionary item. */ 3334 item_lock(&lp->ll_di->di_tv, deep, lock); 3335 3336 return ret; 3337 } 3338 3339 /* 3340 * Lock or unlock an item. "deep" is nr of levels to go. 3341 */ 3342 static void 3343 item_lock(tv, deep, lock) 3344 typval_T *tv; 3345 int deep; 3346 int lock; 3347 { 3348 static int recurse = 0; 3349 list_T *l; 3350 listitem_T *li; 3351 dict_T *d; 3352 hashitem_T *hi; 3353 int todo; 3354 3355 if (recurse >= DICT_MAXNEST) 3356 { 3357 EMSG(_("E743: variable nested too deep for (un)lock")); 3358 return; 3359 } 3360 if (deep == 0) 3361 return; 3362 ++recurse; 3363 3364 /* lock/unlock the item itself */ 3365 if (lock) 3366 tv->v_lock |= VAR_LOCKED; 3367 else 3368 tv->v_lock &= ~VAR_LOCKED; 3369 3370 switch (tv->v_type) 3371 { 3372 case VAR_LIST: 3373 if ((l = tv->vval.v_list) != NULL) 3374 { 3375 if (lock) 3376 l->lv_lock |= VAR_LOCKED; 3377 else 3378 l->lv_lock &= ~VAR_LOCKED; 3379 if (deep < 0 || deep > 1) 3380 /* recursive: lock/unlock the items the List contains */ 3381 for (li = l->lv_first; li != NULL; li = li->li_next) 3382 item_lock(&li->li_tv, deep - 1, lock); 3383 } 3384 break; 3385 case VAR_DICT: 3386 if ((d = tv->vval.v_dict) != NULL) 3387 { 3388 if (lock) 3389 d->dv_lock |= VAR_LOCKED; 3390 else 3391 d->dv_lock &= ~VAR_LOCKED; 3392 if (deep < 0 || deep > 1) 3393 { 3394 /* recursive: lock/unlock the items the List contains */ 3395 todo = d->dv_hashtab.ht_used; 3396 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3397 { 3398 if (!HASHITEM_EMPTY(hi)) 3399 { 3400 --todo; 3401 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3402 } 3403 } 3404 } 3405 } 3406 } 3407 --recurse; 3408 } 3409 3410 /* 3411 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3412 * it refers to a List or Dictionary that is locked. 3413 */ 3414 static int 3415 tv_islocked(tv) 3416 typval_T *tv; 3417 { 3418 return (tv->v_lock & VAR_LOCKED) 3419 || (tv->v_type == VAR_LIST 3420 && tv->vval.v_list != NULL 3421 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3422 || (tv->v_type == VAR_DICT 3423 && tv->vval.v_dict != NULL 3424 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3425 } 3426 3427 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3428 /* 3429 * Delete all "menutrans_" variables. 3430 */ 3431 void 3432 del_menutrans_vars() 3433 { 3434 hashitem_T *hi; 3435 int todo; 3436 3437 hash_lock(&globvarht); 3438 todo = globvarht.ht_used; 3439 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3440 { 3441 if (!HASHITEM_EMPTY(hi)) 3442 { 3443 --todo; 3444 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3445 delete_var(&globvarht, hi); 3446 } 3447 } 3448 hash_unlock(&globvarht); 3449 } 3450 #endif 3451 3452 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3453 3454 /* 3455 * Local string buffer for the next two functions to store a variable name 3456 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3457 * get_user_var_name(). 3458 */ 3459 3460 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3461 3462 static char_u *varnamebuf = NULL; 3463 static int varnamebuflen = 0; 3464 3465 /* 3466 * Function to concatenate a prefix and a variable name. 3467 */ 3468 static char_u * 3469 cat_prefix_varname(prefix, name) 3470 int prefix; 3471 char_u *name; 3472 { 3473 int len; 3474 3475 len = (int)STRLEN(name) + 3; 3476 if (len > varnamebuflen) 3477 { 3478 vim_free(varnamebuf); 3479 len += 10; /* some additional space */ 3480 varnamebuf = alloc(len); 3481 if (varnamebuf == NULL) 3482 { 3483 varnamebuflen = 0; 3484 return NULL; 3485 } 3486 varnamebuflen = len; 3487 } 3488 *varnamebuf = prefix; 3489 varnamebuf[1] = ':'; 3490 STRCPY(varnamebuf + 2, name); 3491 return varnamebuf; 3492 } 3493 3494 /* 3495 * Function given to ExpandGeneric() to obtain the list of user defined 3496 * (global/buffer/window/built-in) variable names. 3497 */ 3498 /*ARGSUSED*/ 3499 char_u * 3500 get_user_var_name(xp, idx) 3501 expand_T *xp; 3502 int idx; 3503 { 3504 static long_u gdone; 3505 static long_u bdone; 3506 static long_u wdone; 3507 static int vidx; 3508 static hashitem_T *hi; 3509 hashtab_T *ht; 3510 3511 if (idx == 0) 3512 gdone = bdone = wdone = vidx = 0; 3513 3514 /* Global variables */ 3515 if (gdone < globvarht.ht_used) 3516 { 3517 if (gdone++ == 0) 3518 hi = globvarht.ht_array; 3519 else 3520 ++hi; 3521 while (HASHITEM_EMPTY(hi)) 3522 ++hi; 3523 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3524 return cat_prefix_varname('g', hi->hi_key); 3525 return hi->hi_key; 3526 } 3527 3528 /* b: variables */ 3529 ht = &curbuf->b_vars.dv_hashtab; 3530 if (bdone < ht->ht_used) 3531 { 3532 if (bdone++ == 0) 3533 hi = ht->ht_array; 3534 else 3535 ++hi; 3536 while (HASHITEM_EMPTY(hi)) 3537 ++hi; 3538 return cat_prefix_varname('b', hi->hi_key); 3539 } 3540 if (bdone == ht->ht_used) 3541 { 3542 ++bdone; 3543 return (char_u *)"b:changedtick"; 3544 } 3545 3546 /* w: variables */ 3547 ht = &curwin->w_vars.dv_hashtab; 3548 if (wdone < ht->ht_used) 3549 { 3550 if (wdone++ == 0) 3551 hi = ht->ht_array; 3552 else 3553 ++hi; 3554 while (HASHITEM_EMPTY(hi)) 3555 ++hi; 3556 return cat_prefix_varname('w', hi->hi_key); 3557 } 3558 3559 /* v: variables */ 3560 if (vidx < VV_LEN) 3561 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3562 3563 vim_free(varnamebuf); 3564 varnamebuf = NULL; 3565 varnamebuflen = 0; 3566 return NULL; 3567 } 3568 3569 #endif /* FEAT_CMDL_COMPL */ 3570 3571 /* 3572 * types for expressions. 3573 */ 3574 typedef enum 3575 { 3576 TYPE_UNKNOWN = 0 3577 , TYPE_EQUAL /* == */ 3578 , TYPE_NEQUAL /* != */ 3579 , TYPE_GREATER /* > */ 3580 , TYPE_GEQUAL /* >= */ 3581 , TYPE_SMALLER /* < */ 3582 , TYPE_SEQUAL /* <= */ 3583 , TYPE_MATCH /* =~ */ 3584 , TYPE_NOMATCH /* !~ */ 3585 } exptype_T; 3586 3587 /* 3588 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3589 * executed. The function may return OK, but the rettv will be of type 3590 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3591 */ 3592 3593 /* 3594 * Handle zero level expression. 3595 * This calls eval1() and handles error message and nextcmd. 3596 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3597 * Note: "rettv.v_lock" is not set. 3598 * Return OK or FAIL. 3599 */ 3600 static int 3601 eval0(arg, rettv, nextcmd, evaluate) 3602 char_u *arg; 3603 typval_T *rettv; 3604 char_u **nextcmd; 3605 int evaluate; 3606 { 3607 int ret; 3608 char_u *p; 3609 3610 p = skipwhite(arg); 3611 ret = eval1(&p, rettv, evaluate); 3612 if (ret == FAIL || !ends_excmd(*p)) 3613 { 3614 if (ret != FAIL) 3615 clear_tv(rettv); 3616 /* 3617 * Report the invalid expression unless the expression evaluation has 3618 * been cancelled due to an aborting error, an interrupt, or an 3619 * exception. 3620 */ 3621 if (!aborting()) 3622 EMSG2(_(e_invexpr2), arg); 3623 ret = FAIL; 3624 } 3625 if (nextcmd != NULL) 3626 *nextcmd = check_nextcmd(p); 3627 3628 return ret; 3629 } 3630 3631 /* 3632 * Handle top level expression: 3633 * expr1 ? expr0 : expr0 3634 * 3635 * "arg" must point to the first non-white of the expression. 3636 * "arg" is advanced to the next non-white after the recognized expression. 3637 * 3638 * Note: "rettv.v_lock" is not set. 3639 * 3640 * Return OK or FAIL. 3641 */ 3642 static int 3643 eval1(arg, rettv, evaluate) 3644 char_u **arg; 3645 typval_T *rettv; 3646 int evaluate; 3647 { 3648 int result; 3649 typval_T var2; 3650 3651 /* 3652 * Get the first variable. 3653 */ 3654 if (eval2(arg, rettv, evaluate) == FAIL) 3655 return FAIL; 3656 3657 if ((*arg)[0] == '?') 3658 { 3659 result = FALSE; 3660 if (evaluate) 3661 { 3662 int error = FALSE; 3663 3664 if (get_tv_number_chk(rettv, &error) != 0) 3665 result = TRUE; 3666 clear_tv(rettv); 3667 if (error) 3668 return FAIL; 3669 } 3670 3671 /* 3672 * Get the second variable. 3673 */ 3674 *arg = skipwhite(*arg + 1); 3675 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3676 return FAIL; 3677 3678 /* 3679 * Check for the ":". 3680 */ 3681 if ((*arg)[0] != ':') 3682 { 3683 EMSG(_("E109: Missing ':' after '?'")); 3684 if (evaluate && result) 3685 clear_tv(rettv); 3686 return FAIL; 3687 } 3688 3689 /* 3690 * Get the third variable. 3691 */ 3692 *arg = skipwhite(*arg + 1); 3693 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3694 { 3695 if (evaluate && result) 3696 clear_tv(rettv); 3697 return FAIL; 3698 } 3699 if (evaluate && !result) 3700 *rettv = var2; 3701 } 3702 3703 return OK; 3704 } 3705 3706 /* 3707 * Handle first level expression: 3708 * expr2 || expr2 || expr2 logical OR 3709 * 3710 * "arg" must point to the first non-white of the expression. 3711 * "arg" is advanced to the next non-white after the recognized expression. 3712 * 3713 * Return OK or FAIL. 3714 */ 3715 static int 3716 eval2(arg, rettv, evaluate) 3717 char_u **arg; 3718 typval_T *rettv; 3719 int evaluate; 3720 { 3721 typval_T var2; 3722 long result; 3723 int first; 3724 int error = FALSE; 3725 3726 /* 3727 * Get the first variable. 3728 */ 3729 if (eval3(arg, rettv, evaluate) == FAIL) 3730 return FAIL; 3731 3732 /* 3733 * Repeat until there is no following "||". 3734 */ 3735 first = TRUE; 3736 result = FALSE; 3737 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3738 { 3739 if (evaluate && first) 3740 { 3741 if (get_tv_number_chk(rettv, &error) != 0) 3742 result = TRUE; 3743 clear_tv(rettv); 3744 if (error) 3745 return FAIL; 3746 first = FALSE; 3747 } 3748 3749 /* 3750 * Get the second variable. 3751 */ 3752 *arg = skipwhite(*arg + 2); 3753 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3754 return FAIL; 3755 3756 /* 3757 * Compute the result. 3758 */ 3759 if (evaluate && !result) 3760 { 3761 if (get_tv_number_chk(&var2, &error) != 0) 3762 result = TRUE; 3763 clear_tv(&var2); 3764 if (error) 3765 return FAIL; 3766 } 3767 if (evaluate) 3768 { 3769 rettv->v_type = VAR_NUMBER; 3770 rettv->vval.v_number = result; 3771 } 3772 } 3773 3774 return OK; 3775 } 3776 3777 /* 3778 * Handle second level expression: 3779 * expr3 && expr3 && expr3 logical AND 3780 * 3781 * "arg" must point to the first non-white of the expression. 3782 * "arg" is advanced to the next non-white after the recognized expression. 3783 * 3784 * Return OK or FAIL. 3785 */ 3786 static int 3787 eval3(arg, rettv, evaluate) 3788 char_u **arg; 3789 typval_T *rettv; 3790 int evaluate; 3791 { 3792 typval_T var2; 3793 long result; 3794 int first; 3795 int error = FALSE; 3796 3797 /* 3798 * Get the first variable. 3799 */ 3800 if (eval4(arg, rettv, evaluate) == FAIL) 3801 return FAIL; 3802 3803 /* 3804 * Repeat until there is no following "&&". 3805 */ 3806 first = TRUE; 3807 result = TRUE; 3808 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3809 { 3810 if (evaluate && first) 3811 { 3812 if (get_tv_number_chk(rettv, &error) == 0) 3813 result = FALSE; 3814 clear_tv(rettv); 3815 if (error) 3816 return FAIL; 3817 first = FALSE; 3818 } 3819 3820 /* 3821 * Get the second variable. 3822 */ 3823 *arg = skipwhite(*arg + 2); 3824 if (eval4(arg, &var2, evaluate && result) == FAIL) 3825 return FAIL; 3826 3827 /* 3828 * Compute the result. 3829 */ 3830 if (evaluate && result) 3831 { 3832 if (get_tv_number_chk(&var2, &error) == 0) 3833 result = FALSE; 3834 clear_tv(&var2); 3835 if (error) 3836 return FAIL; 3837 } 3838 if (evaluate) 3839 { 3840 rettv->v_type = VAR_NUMBER; 3841 rettv->vval.v_number = result; 3842 } 3843 } 3844 3845 return OK; 3846 } 3847 3848 /* 3849 * Handle third level expression: 3850 * var1 == var2 3851 * var1 =~ var2 3852 * var1 != var2 3853 * var1 !~ var2 3854 * var1 > var2 3855 * var1 >= var2 3856 * var1 < var2 3857 * var1 <= var2 3858 * var1 is var2 3859 * var1 isnot var2 3860 * 3861 * "arg" must point to the first non-white of the expression. 3862 * "arg" is advanced to the next non-white after the recognized expression. 3863 * 3864 * Return OK or FAIL. 3865 */ 3866 static int 3867 eval4(arg, rettv, evaluate) 3868 char_u **arg; 3869 typval_T *rettv; 3870 int evaluate; 3871 { 3872 typval_T var2; 3873 char_u *p; 3874 int i; 3875 exptype_T type = TYPE_UNKNOWN; 3876 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3877 int len = 2; 3878 long n1, n2; 3879 char_u *s1, *s2; 3880 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3881 regmatch_T regmatch; 3882 int ic; 3883 char_u *save_cpo; 3884 3885 /* 3886 * Get the first variable. 3887 */ 3888 if (eval5(arg, rettv, evaluate) == FAIL) 3889 return FAIL; 3890 3891 p = *arg; 3892 switch (p[0]) 3893 { 3894 case '=': if (p[1] == '=') 3895 type = TYPE_EQUAL; 3896 else if (p[1] == '~') 3897 type = TYPE_MATCH; 3898 break; 3899 case '!': if (p[1] == '=') 3900 type = TYPE_NEQUAL; 3901 else if (p[1] == '~') 3902 type = TYPE_NOMATCH; 3903 break; 3904 case '>': if (p[1] != '=') 3905 { 3906 type = TYPE_GREATER; 3907 len = 1; 3908 } 3909 else 3910 type = TYPE_GEQUAL; 3911 break; 3912 case '<': if (p[1] != '=') 3913 { 3914 type = TYPE_SMALLER; 3915 len = 1; 3916 } 3917 else 3918 type = TYPE_SEQUAL; 3919 break; 3920 case 'i': if (p[1] == 's') 3921 { 3922 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3923 len = 5; 3924 if (!vim_isIDc(p[len])) 3925 { 3926 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3927 type_is = TRUE; 3928 } 3929 } 3930 break; 3931 } 3932 3933 /* 3934 * If there is a comparitive operator, use it. 3935 */ 3936 if (type != TYPE_UNKNOWN) 3937 { 3938 /* extra question mark appended: ignore case */ 3939 if (p[len] == '?') 3940 { 3941 ic = TRUE; 3942 ++len; 3943 } 3944 /* extra '#' appended: match case */ 3945 else if (p[len] == '#') 3946 { 3947 ic = FALSE; 3948 ++len; 3949 } 3950 /* nothing appened: use 'ignorecase' */ 3951 else 3952 ic = p_ic; 3953 3954 /* 3955 * Get the second variable. 3956 */ 3957 *arg = skipwhite(p + len); 3958 if (eval5(arg, &var2, evaluate) == FAIL) 3959 { 3960 clear_tv(rettv); 3961 return FAIL; 3962 } 3963 3964 if (evaluate) 3965 { 3966 if (type_is && rettv->v_type != var2.v_type) 3967 { 3968 /* For "is" a different type always means FALSE, for "notis" 3969 * it means TRUE. */ 3970 n1 = (type == TYPE_NEQUAL); 3971 } 3972 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3973 { 3974 if (type_is) 3975 { 3976 n1 = (rettv->v_type == var2.v_type 3977 && rettv->vval.v_list == var2.vval.v_list); 3978 if (type == TYPE_NEQUAL) 3979 n1 = !n1; 3980 } 3981 else if (rettv->v_type != var2.v_type 3982 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3983 { 3984 if (rettv->v_type != var2.v_type) 3985 EMSG(_("E691: Can only compare List with List")); 3986 else 3987 EMSG(_("E692: Invalid operation for Lists")); 3988 clear_tv(rettv); 3989 clear_tv(&var2); 3990 return FAIL; 3991 } 3992 else 3993 { 3994 /* Compare two Lists for being equal or unequal. */ 3995 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3996 if (type == TYPE_NEQUAL) 3997 n1 = !n1; 3998 } 3999 } 4000 4001 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4002 { 4003 if (type_is) 4004 { 4005 n1 = (rettv->v_type == var2.v_type 4006 && rettv->vval.v_dict == var2.vval.v_dict); 4007 if (type == TYPE_NEQUAL) 4008 n1 = !n1; 4009 } 4010 else if (rettv->v_type != var2.v_type 4011 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4012 { 4013 if (rettv->v_type != var2.v_type) 4014 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4015 else 4016 EMSG(_("E736: Invalid operation for Dictionary")); 4017 clear_tv(rettv); 4018 clear_tv(&var2); 4019 return FAIL; 4020 } 4021 else 4022 { 4023 /* Compare two Dictionaries for being equal or unequal. */ 4024 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4025 if (type == TYPE_NEQUAL) 4026 n1 = !n1; 4027 } 4028 } 4029 4030 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4031 { 4032 if (rettv->v_type != var2.v_type 4033 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4034 { 4035 if (rettv->v_type != var2.v_type) 4036 EMSG(_("E693: Can only compare Funcref with Funcref")); 4037 else 4038 EMSG(_("E694: Invalid operation for Funcrefs")); 4039 clear_tv(rettv); 4040 clear_tv(&var2); 4041 return FAIL; 4042 } 4043 else 4044 { 4045 /* Compare two Funcrefs for being equal or unequal. */ 4046 if (rettv->vval.v_string == NULL 4047 || var2.vval.v_string == NULL) 4048 n1 = FALSE; 4049 else 4050 n1 = STRCMP(rettv->vval.v_string, 4051 var2.vval.v_string) == 0; 4052 if (type == TYPE_NEQUAL) 4053 n1 = !n1; 4054 } 4055 } 4056 4057 /* 4058 * If one of the two variables is a number, compare as a number. 4059 * When using "=~" or "!~", always compare as string. 4060 */ 4061 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4062 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4063 { 4064 n1 = get_tv_number(rettv); 4065 n2 = get_tv_number(&var2); 4066 switch (type) 4067 { 4068 case TYPE_EQUAL: n1 = (n1 == n2); break; 4069 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4070 case TYPE_GREATER: n1 = (n1 > n2); break; 4071 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4072 case TYPE_SMALLER: n1 = (n1 < n2); break; 4073 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4074 case TYPE_UNKNOWN: 4075 case TYPE_MATCH: 4076 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4077 } 4078 } 4079 else 4080 { 4081 s1 = get_tv_string_buf(rettv, buf1); 4082 s2 = get_tv_string_buf(&var2, buf2); 4083 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4084 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4085 else 4086 i = 0; 4087 n1 = FALSE; 4088 switch (type) 4089 { 4090 case TYPE_EQUAL: n1 = (i == 0); break; 4091 case TYPE_NEQUAL: n1 = (i != 0); break; 4092 case TYPE_GREATER: n1 = (i > 0); break; 4093 case TYPE_GEQUAL: n1 = (i >= 0); break; 4094 case TYPE_SMALLER: n1 = (i < 0); break; 4095 case TYPE_SEQUAL: n1 = (i <= 0); break; 4096 4097 case TYPE_MATCH: 4098 case TYPE_NOMATCH: 4099 /* avoid 'l' flag in 'cpoptions' */ 4100 save_cpo = p_cpo; 4101 p_cpo = (char_u *)""; 4102 regmatch.regprog = vim_regcomp(s2, 4103 RE_MAGIC + RE_STRING); 4104 regmatch.rm_ic = ic; 4105 if (regmatch.regprog != NULL) 4106 { 4107 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4108 vim_free(regmatch.regprog); 4109 if (type == TYPE_NOMATCH) 4110 n1 = !n1; 4111 } 4112 p_cpo = save_cpo; 4113 break; 4114 4115 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4116 } 4117 } 4118 clear_tv(rettv); 4119 clear_tv(&var2); 4120 rettv->v_type = VAR_NUMBER; 4121 rettv->vval.v_number = n1; 4122 } 4123 } 4124 4125 return OK; 4126 } 4127 4128 /* 4129 * Handle fourth level expression: 4130 * + number addition 4131 * - number subtraction 4132 * . string concatenation 4133 * 4134 * "arg" must point to the first non-white of the expression. 4135 * "arg" is advanced to the next non-white after the recognized expression. 4136 * 4137 * Return OK or FAIL. 4138 */ 4139 static int 4140 eval5(arg, rettv, evaluate) 4141 char_u **arg; 4142 typval_T *rettv; 4143 int evaluate; 4144 { 4145 typval_T var2; 4146 typval_T var3; 4147 int op; 4148 long n1, n2; 4149 char_u *s1, *s2; 4150 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4151 char_u *p; 4152 4153 /* 4154 * Get the first variable. 4155 */ 4156 if (eval6(arg, rettv, evaluate) == FAIL) 4157 return FAIL; 4158 4159 /* 4160 * Repeat computing, until no '+', '-' or '.' is following. 4161 */ 4162 for (;;) 4163 { 4164 op = **arg; 4165 if (op != '+' && op != '-' && op != '.') 4166 break; 4167 4168 if (op != '+' || rettv->v_type != VAR_LIST) 4169 { 4170 /* For "list + ...", an illegal use of the first operand as 4171 * a number cannot be determined before evaluating the 2nd 4172 * operand: if this is also a list, all is ok. 4173 * For "something . ...", "something - ..." or "non-list + ...", 4174 * we know that the first operand needs to be a string or number 4175 * without evaluating the 2nd operand. So check before to avoid 4176 * side effects after an error. */ 4177 if (evaluate && get_tv_string_chk(rettv) == NULL) 4178 { 4179 clear_tv(rettv); 4180 return FAIL; 4181 } 4182 } 4183 4184 /* 4185 * Get the second variable. 4186 */ 4187 *arg = skipwhite(*arg + 1); 4188 if (eval6(arg, &var2, evaluate) == FAIL) 4189 { 4190 clear_tv(rettv); 4191 return FAIL; 4192 } 4193 4194 if (evaluate) 4195 { 4196 /* 4197 * Compute the result. 4198 */ 4199 if (op == '.') 4200 { 4201 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4202 s2 = get_tv_string_buf_chk(&var2, buf2); 4203 if (s2 == NULL) /* type error ? */ 4204 { 4205 clear_tv(rettv); 4206 clear_tv(&var2); 4207 return FAIL; 4208 } 4209 p = concat_str(s1, s2); 4210 clear_tv(rettv); 4211 rettv->v_type = VAR_STRING; 4212 rettv->vval.v_string = p; 4213 } 4214 else if (op == '+' && rettv->v_type == VAR_LIST 4215 && var2.v_type == VAR_LIST) 4216 { 4217 /* concatenate Lists */ 4218 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4219 &var3) == FAIL) 4220 { 4221 clear_tv(rettv); 4222 clear_tv(&var2); 4223 return FAIL; 4224 } 4225 clear_tv(rettv); 4226 *rettv = var3; 4227 } 4228 else 4229 { 4230 int error = FALSE; 4231 4232 n1 = get_tv_number_chk(rettv, &error); 4233 if (error) 4234 { 4235 /* This can only happen for "list + non-list". 4236 * For "non-list + ..." or "something - ...", we returned 4237 * before evaluating the 2nd operand. */ 4238 clear_tv(rettv); 4239 return FAIL; 4240 } 4241 n2 = get_tv_number_chk(&var2, &error); 4242 if (error) 4243 { 4244 clear_tv(rettv); 4245 clear_tv(&var2); 4246 return FAIL; 4247 } 4248 clear_tv(rettv); 4249 if (op == '+') 4250 n1 = n1 + n2; 4251 else 4252 n1 = n1 - n2; 4253 rettv->v_type = VAR_NUMBER; 4254 rettv->vval.v_number = n1; 4255 } 4256 clear_tv(&var2); 4257 } 4258 } 4259 return OK; 4260 } 4261 4262 /* 4263 * Handle fifth level expression: 4264 * * number multiplication 4265 * / number division 4266 * % number modulo 4267 * 4268 * "arg" must point to the first non-white of the expression. 4269 * "arg" is advanced to the next non-white after the recognized expression. 4270 * 4271 * Return OK or FAIL. 4272 */ 4273 static int 4274 eval6(arg, rettv, evaluate) 4275 char_u **arg; 4276 typval_T *rettv; 4277 int evaluate; 4278 { 4279 typval_T var2; 4280 int op; 4281 long n1, n2; 4282 int error = FALSE; 4283 4284 /* 4285 * Get the first variable. 4286 */ 4287 if (eval7(arg, rettv, evaluate) == FAIL) 4288 return FAIL; 4289 4290 /* 4291 * Repeat computing, until no '*', '/' or '%' is following. 4292 */ 4293 for (;;) 4294 { 4295 op = **arg; 4296 if (op != '*' && op != '/' && op != '%') 4297 break; 4298 4299 if (evaluate) 4300 { 4301 n1 = get_tv_number_chk(rettv, &error); 4302 clear_tv(rettv); 4303 if (error) 4304 return FAIL; 4305 } 4306 else 4307 n1 = 0; 4308 4309 /* 4310 * Get the second variable. 4311 */ 4312 *arg = skipwhite(*arg + 1); 4313 if (eval7(arg, &var2, evaluate) == FAIL) 4314 return FAIL; 4315 4316 if (evaluate) 4317 { 4318 n2 = get_tv_number_chk(&var2, &error); 4319 clear_tv(&var2); 4320 if (error) 4321 return FAIL; 4322 4323 /* 4324 * Compute the result. 4325 */ 4326 if (op == '*') 4327 n1 = n1 * n2; 4328 else if (op == '/') 4329 { 4330 if (n2 == 0) /* give an error message? */ 4331 n1 = 0x7fffffffL; 4332 else 4333 n1 = n1 / n2; 4334 } 4335 else 4336 { 4337 if (n2 == 0) /* give an error message? */ 4338 n1 = 0; 4339 else 4340 n1 = n1 % n2; 4341 } 4342 rettv->v_type = VAR_NUMBER; 4343 rettv->vval.v_number = n1; 4344 } 4345 } 4346 4347 return OK; 4348 } 4349 4350 /* 4351 * Handle sixth level expression: 4352 * number number constant 4353 * "string" string contstant 4354 * 'string' literal string contstant 4355 * &option-name option value 4356 * @r register contents 4357 * identifier variable value 4358 * function() function call 4359 * $VAR environment variable 4360 * (expression) nested expression 4361 * [expr, expr] List 4362 * {key: val, key: val} Dictionary 4363 * 4364 * Also handle: 4365 * ! in front logical NOT 4366 * - in front unary minus 4367 * + in front unary plus (ignored) 4368 * trailing [] subscript in String or List 4369 * trailing .name entry in Dictionary 4370 * 4371 * "arg" must point to the first non-white of the expression. 4372 * "arg" is advanced to the next non-white after the recognized expression. 4373 * 4374 * Return OK or FAIL. 4375 */ 4376 static int 4377 eval7(arg, rettv, evaluate) 4378 char_u **arg; 4379 typval_T *rettv; 4380 int evaluate; 4381 { 4382 long n; 4383 int len; 4384 char_u *s; 4385 int val; 4386 char_u *start_leader, *end_leader; 4387 int ret = OK; 4388 char_u *alias; 4389 4390 /* 4391 * Initialise variable so that clear_tv() can't mistake this for a 4392 * string and free a string that isn't there. 4393 */ 4394 rettv->v_type = VAR_UNKNOWN; 4395 4396 /* 4397 * Skip '!' and '-' characters. They are handled later. 4398 */ 4399 start_leader = *arg; 4400 while (**arg == '!' || **arg == '-' || **arg == '+') 4401 *arg = skipwhite(*arg + 1); 4402 end_leader = *arg; 4403 4404 switch (**arg) 4405 { 4406 /* 4407 * Number constant. 4408 */ 4409 case '0': 4410 case '1': 4411 case '2': 4412 case '3': 4413 case '4': 4414 case '5': 4415 case '6': 4416 case '7': 4417 case '8': 4418 case '9': 4419 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4420 *arg += len; 4421 if (evaluate) 4422 { 4423 rettv->v_type = VAR_NUMBER; 4424 rettv->vval.v_number = n; 4425 } 4426 break; 4427 4428 /* 4429 * String constant: "string". 4430 */ 4431 case '"': ret = get_string_tv(arg, rettv, evaluate); 4432 break; 4433 4434 /* 4435 * Literal string constant: 'str''ing'. 4436 */ 4437 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4438 break; 4439 4440 /* 4441 * List: [expr, expr] 4442 */ 4443 case '[': ret = get_list_tv(arg, rettv, evaluate); 4444 break; 4445 4446 /* 4447 * Dictionary: {key: val, key: val} 4448 */ 4449 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4450 break; 4451 4452 /* 4453 * Option value: &name 4454 */ 4455 case '&': ret = get_option_tv(arg, rettv, evaluate); 4456 break; 4457 4458 /* 4459 * Environment variable: $VAR. 4460 */ 4461 case '$': ret = get_env_tv(arg, rettv, evaluate); 4462 break; 4463 4464 /* 4465 * Register contents: @r. 4466 */ 4467 case '@': ++*arg; 4468 if (evaluate) 4469 { 4470 rettv->v_type = VAR_STRING; 4471 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4472 } 4473 if (**arg != NUL) 4474 ++*arg; 4475 break; 4476 4477 /* 4478 * nested expression: (expression). 4479 */ 4480 case '(': *arg = skipwhite(*arg + 1); 4481 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4482 if (**arg == ')') 4483 ++*arg; 4484 else if (ret == OK) 4485 { 4486 EMSG(_("E110: Missing ')'")); 4487 clear_tv(rettv); 4488 ret = FAIL; 4489 } 4490 break; 4491 4492 default: ret = NOTDONE; 4493 break; 4494 } 4495 4496 if (ret == NOTDONE) 4497 { 4498 /* 4499 * Must be a variable or function name. 4500 * Can also be a curly-braces kind of name: {expr}. 4501 */ 4502 s = *arg; 4503 len = get_name_len(arg, &alias, evaluate, TRUE); 4504 if (alias != NULL) 4505 s = alias; 4506 4507 if (len <= 0) 4508 ret = FAIL; 4509 else 4510 { 4511 if (**arg == '(') /* recursive! */ 4512 { 4513 /* If "s" is the name of a variable of type VAR_FUNC 4514 * use its contents. */ 4515 s = deref_func_name(s, &len); 4516 4517 /* Invoke the function. */ 4518 ret = get_func_tv(s, len, rettv, arg, 4519 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4520 &len, evaluate, NULL); 4521 /* Stop the expression evaluation when immediately 4522 * aborting on error, or when an interrupt occurred or 4523 * an exception was thrown but not caught. */ 4524 if (aborting()) 4525 { 4526 if (ret == OK) 4527 clear_tv(rettv); 4528 ret = FAIL; 4529 } 4530 } 4531 else if (evaluate) 4532 ret = get_var_tv(s, len, rettv, TRUE); 4533 else 4534 ret = OK; 4535 } 4536 4537 if (alias != NULL) 4538 vim_free(alias); 4539 } 4540 4541 *arg = skipwhite(*arg); 4542 4543 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4544 * expr(expr). */ 4545 if (ret == OK) 4546 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4547 4548 /* 4549 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4550 */ 4551 if (ret == OK && evaluate && end_leader > start_leader) 4552 { 4553 int error = FALSE; 4554 4555 val = get_tv_number_chk(rettv, &error); 4556 if (error) 4557 { 4558 clear_tv(rettv); 4559 ret = FAIL; 4560 } 4561 else 4562 { 4563 while (end_leader > start_leader) 4564 { 4565 --end_leader; 4566 if (*end_leader == '!') 4567 val = !val; 4568 else if (*end_leader == '-') 4569 val = -val; 4570 } 4571 clear_tv(rettv); 4572 rettv->v_type = VAR_NUMBER; 4573 rettv->vval.v_number = val; 4574 } 4575 } 4576 4577 return ret; 4578 } 4579 4580 /* 4581 * Evaluate an "[expr]" or "[expr:expr]" index. 4582 * "*arg" points to the '['. 4583 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4584 */ 4585 static int 4586 eval_index(arg, rettv, evaluate, verbose) 4587 char_u **arg; 4588 typval_T *rettv; 4589 int evaluate; 4590 int verbose; /* give error messages */ 4591 { 4592 int empty1 = FALSE, empty2 = FALSE; 4593 typval_T var1, var2; 4594 long n1, n2 = 0; 4595 long len = -1; 4596 int range = FALSE; 4597 char_u *s; 4598 char_u *key = NULL; 4599 4600 if (rettv->v_type == VAR_FUNC) 4601 { 4602 if (verbose) 4603 EMSG(_("E695: Cannot index a Funcref")); 4604 return FAIL; 4605 } 4606 4607 if (**arg == '.') 4608 { 4609 /* 4610 * dict.name 4611 */ 4612 key = *arg + 1; 4613 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4614 ; 4615 if (len == 0) 4616 return FAIL; 4617 *arg = skipwhite(key + len); 4618 } 4619 else 4620 { 4621 /* 4622 * something[idx] 4623 * 4624 * Get the (first) variable from inside the []. 4625 */ 4626 *arg = skipwhite(*arg + 1); 4627 if (**arg == ':') 4628 empty1 = TRUE; 4629 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4630 return FAIL; 4631 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4632 { 4633 /* not a number or string */ 4634 clear_tv(&var1); 4635 return FAIL; 4636 } 4637 4638 /* 4639 * Get the second variable from inside the [:]. 4640 */ 4641 if (**arg == ':') 4642 { 4643 range = TRUE; 4644 *arg = skipwhite(*arg + 1); 4645 if (**arg == ']') 4646 empty2 = TRUE; 4647 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4648 { 4649 if (!empty1) 4650 clear_tv(&var1); 4651 return FAIL; 4652 } 4653 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4654 { 4655 /* not a number or string */ 4656 if (!empty1) 4657 clear_tv(&var1); 4658 clear_tv(&var2); 4659 return FAIL; 4660 } 4661 } 4662 4663 /* Check for the ']'. */ 4664 if (**arg != ']') 4665 { 4666 if (verbose) 4667 EMSG(_(e_missbrac)); 4668 clear_tv(&var1); 4669 if (range) 4670 clear_tv(&var2); 4671 return FAIL; 4672 } 4673 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4674 } 4675 4676 if (evaluate) 4677 { 4678 n1 = 0; 4679 if (!empty1 && rettv->v_type != VAR_DICT) 4680 { 4681 n1 = get_tv_number(&var1); 4682 clear_tv(&var1); 4683 } 4684 if (range) 4685 { 4686 if (empty2) 4687 n2 = -1; 4688 else 4689 { 4690 n2 = get_tv_number(&var2); 4691 clear_tv(&var2); 4692 } 4693 } 4694 4695 switch (rettv->v_type) 4696 { 4697 case VAR_NUMBER: 4698 case VAR_STRING: 4699 s = get_tv_string(rettv); 4700 len = (long)STRLEN(s); 4701 if (range) 4702 { 4703 /* The resulting variable is a substring. If the indexes 4704 * are out of range the result is empty. */ 4705 if (n1 < 0) 4706 { 4707 n1 = len + n1; 4708 if (n1 < 0) 4709 n1 = 0; 4710 } 4711 if (n2 < 0) 4712 n2 = len + n2; 4713 else if (n2 >= len) 4714 n2 = len; 4715 if (n1 >= len || n2 < 0 || n1 > n2) 4716 s = NULL; 4717 else 4718 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4719 } 4720 else 4721 { 4722 /* The resulting variable is a string of a single 4723 * character. If the index is too big or negative the 4724 * result is empty. */ 4725 if (n1 >= len || n1 < 0) 4726 s = NULL; 4727 else 4728 s = vim_strnsave(s + n1, 1); 4729 } 4730 clear_tv(rettv); 4731 rettv->v_type = VAR_STRING; 4732 rettv->vval.v_string = s; 4733 break; 4734 4735 case VAR_LIST: 4736 len = list_len(rettv->vval.v_list); 4737 if (n1 < 0) 4738 n1 = len + n1; 4739 if (!empty1 && (n1 < 0 || n1 >= len)) 4740 { 4741 if (verbose) 4742 EMSGN(_(e_listidx), n1); 4743 return FAIL; 4744 } 4745 if (range) 4746 { 4747 list_T *l; 4748 listitem_T *item; 4749 4750 if (n2 < 0) 4751 n2 = len + n2; 4752 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4753 { 4754 if (verbose) 4755 EMSGN(_(e_listidx), n2); 4756 return FAIL; 4757 } 4758 l = list_alloc(); 4759 if (l == NULL) 4760 return FAIL; 4761 for (item = list_find(rettv->vval.v_list, n1); 4762 n1 <= n2; ++n1) 4763 { 4764 if (list_append_tv(l, &item->li_tv) == FAIL) 4765 { 4766 list_free(l); 4767 return FAIL; 4768 } 4769 item = item->li_next; 4770 } 4771 clear_tv(rettv); 4772 rettv->v_type = VAR_LIST; 4773 rettv->vval.v_list = l; 4774 ++l->lv_refcount; 4775 } 4776 else 4777 { 4778 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4779 &var1); 4780 clear_tv(rettv); 4781 *rettv = var1; 4782 } 4783 break; 4784 4785 case VAR_DICT: 4786 if (range) 4787 { 4788 if (verbose) 4789 EMSG(_(e_dictrange)); 4790 if (len == -1) 4791 clear_tv(&var1); 4792 return FAIL; 4793 } 4794 { 4795 dictitem_T *item; 4796 4797 if (len == -1) 4798 { 4799 key = get_tv_string(&var1); 4800 if (*key == NUL) 4801 { 4802 if (verbose) 4803 EMSG(_(e_emptykey)); 4804 clear_tv(&var1); 4805 return FAIL; 4806 } 4807 } 4808 4809 item = dict_find(rettv->vval.v_dict, key, (int)len); 4810 4811 if (item == NULL && verbose) 4812 EMSG2(_(e_dictkey), key); 4813 if (len == -1) 4814 clear_tv(&var1); 4815 if (item == NULL) 4816 return FAIL; 4817 4818 copy_tv(&item->di_tv, &var1); 4819 clear_tv(rettv); 4820 *rettv = var1; 4821 } 4822 break; 4823 } 4824 } 4825 4826 return OK; 4827 } 4828 4829 /* 4830 * Get an option value. 4831 * "arg" points to the '&' or '+' before the option name. 4832 * "arg" is advanced to character after the option name. 4833 * Return OK or FAIL. 4834 */ 4835 static int 4836 get_option_tv(arg, rettv, evaluate) 4837 char_u **arg; 4838 typval_T *rettv; /* when NULL, only check if option exists */ 4839 int evaluate; 4840 { 4841 char_u *option_end; 4842 long numval; 4843 char_u *stringval; 4844 int opt_type; 4845 int c; 4846 int working = (**arg == '+'); /* has("+option") */ 4847 int ret = OK; 4848 int opt_flags; 4849 4850 /* 4851 * Isolate the option name and find its value. 4852 */ 4853 option_end = find_option_end(arg, &opt_flags); 4854 if (option_end == NULL) 4855 { 4856 if (rettv != NULL) 4857 EMSG2(_("E112: Option name missing: %s"), *arg); 4858 return FAIL; 4859 } 4860 4861 if (!evaluate) 4862 { 4863 *arg = option_end; 4864 return OK; 4865 } 4866 4867 c = *option_end; 4868 *option_end = NUL; 4869 opt_type = get_option_value(*arg, &numval, 4870 rettv == NULL ? NULL : &stringval, opt_flags); 4871 4872 if (opt_type == -3) /* invalid name */ 4873 { 4874 if (rettv != NULL) 4875 EMSG2(_("E113: Unknown option: %s"), *arg); 4876 ret = FAIL; 4877 } 4878 else if (rettv != NULL) 4879 { 4880 if (opt_type == -2) /* hidden string option */ 4881 { 4882 rettv->v_type = VAR_STRING; 4883 rettv->vval.v_string = NULL; 4884 } 4885 else if (opt_type == -1) /* hidden number option */ 4886 { 4887 rettv->v_type = VAR_NUMBER; 4888 rettv->vval.v_number = 0; 4889 } 4890 else if (opt_type == 1) /* number option */ 4891 { 4892 rettv->v_type = VAR_NUMBER; 4893 rettv->vval.v_number = numval; 4894 } 4895 else /* string option */ 4896 { 4897 rettv->v_type = VAR_STRING; 4898 rettv->vval.v_string = stringval; 4899 } 4900 } 4901 else if (working && (opt_type == -2 || opt_type == -1)) 4902 ret = FAIL; 4903 4904 *option_end = c; /* put back for error messages */ 4905 *arg = option_end; 4906 4907 return ret; 4908 } 4909 4910 /* 4911 * Allocate a variable for a string constant. 4912 * Return OK or FAIL. 4913 */ 4914 static int 4915 get_string_tv(arg, rettv, evaluate) 4916 char_u **arg; 4917 typval_T *rettv; 4918 int evaluate; 4919 { 4920 char_u *p; 4921 char_u *name; 4922 int extra = 0; 4923 4924 /* 4925 * Find the end of the string, skipping backslashed characters. 4926 */ 4927 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4928 { 4929 if (*p == '\\' && p[1] != NUL) 4930 { 4931 ++p; 4932 /* A "\<x>" form occupies at least 4 characters, and produces up 4933 * to 6 characters: reserve space for 2 extra */ 4934 if (*p == '<') 4935 extra += 2; 4936 } 4937 } 4938 4939 if (*p != '"') 4940 { 4941 EMSG2(_("E114: Missing quote: %s"), *arg); 4942 return FAIL; 4943 } 4944 4945 /* If only parsing, set *arg and return here */ 4946 if (!evaluate) 4947 { 4948 *arg = p + 1; 4949 return OK; 4950 } 4951 4952 /* 4953 * Copy the string into allocated memory, handling backslashed 4954 * characters. 4955 */ 4956 name = alloc((unsigned)(p - *arg + extra)); 4957 if (name == NULL) 4958 return FAIL; 4959 rettv->v_type = VAR_STRING; 4960 rettv->vval.v_string = name; 4961 4962 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4963 { 4964 if (*p == '\\') 4965 { 4966 switch (*++p) 4967 { 4968 case 'b': *name++ = BS; ++p; break; 4969 case 'e': *name++ = ESC; ++p; break; 4970 case 'f': *name++ = FF; ++p; break; 4971 case 'n': *name++ = NL; ++p; break; 4972 case 'r': *name++ = CAR; ++p; break; 4973 case 't': *name++ = TAB; ++p; break; 4974 4975 case 'X': /* hex: "\x1", "\x12" */ 4976 case 'x': 4977 case 'u': /* Unicode: "\u0023" */ 4978 case 'U': 4979 if (vim_isxdigit(p[1])) 4980 { 4981 int n, nr; 4982 int c = toupper(*p); 4983 4984 if (c == 'X') 4985 n = 2; 4986 else 4987 n = 4; 4988 nr = 0; 4989 while (--n >= 0 && vim_isxdigit(p[1])) 4990 { 4991 ++p; 4992 nr = (nr << 4) + hex2nr(*p); 4993 } 4994 ++p; 4995 #ifdef FEAT_MBYTE 4996 /* For "\u" store the number according to 4997 * 'encoding'. */ 4998 if (c != 'X') 4999 name += (*mb_char2bytes)(nr, name); 5000 else 5001 #endif 5002 *name++ = nr; 5003 } 5004 break; 5005 5006 /* octal: "\1", "\12", "\123" */ 5007 case '0': 5008 case '1': 5009 case '2': 5010 case '3': 5011 case '4': 5012 case '5': 5013 case '6': 5014 case '7': *name = *p++ - '0'; 5015 if (*p >= '0' && *p <= '7') 5016 { 5017 *name = (*name << 3) + *p++ - '0'; 5018 if (*p >= '0' && *p <= '7') 5019 *name = (*name << 3) + *p++ - '0'; 5020 } 5021 ++name; 5022 break; 5023 5024 /* Special key, e.g.: "\<C-W>" */ 5025 case '<': extra = trans_special(&p, name, TRUE); 5026 if (extra != 0) 5027 { 5028 name += extra; 5029 break; 5030 } 5031 /* FALLTHROUGH */ 5032 5033 default: MB_COPY_CHAR(p, name); 5034 break; 5035 } 5036 } 5037 else 5038 MB_COPY_CHAR(p, name); 5039 5040 } 5041 *name = NUL; 5042 *arg = p + 1; 5043 5044 return OK; 5045 } 5046 5047 /* 5048 * Allocate a variable for a 'str''ing' constant. 5049 * Return OK or FAIL. 5050 */ 5051 static int 5052 get_lit_string_tv(arg, rettv, evaluate) 5053 char_u **arg; 5054 typval_T *rettv; 5055 int evaluate; 5056 { 5057 char_u *p; 5058 char_u *str; 5059 int reduce = 0; 5060 5061 /* 5062 * Find the end of the string, skipping ''. 5063 */ 5064 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5065 { 5066 if (*p == '\'') 5067 { 5068 if (p[1] != '\'') 5069 break; 5070 ++reduce; 5071 ++p; 5072 } 5073 } 5074 5075 if (*p != '\'') 5076 { 5077 EMSG2(_("E115: Missing quote: %s"), *arg); 5078 return FAIL; 5079 } 5080 5081 /* If only parsing return after setting "*arg" */ 5082 if (!evaluate) 5083 { 5084 *arg = p + 1; 5085 return OK; 5086 } 5087 5088 /* 5089 * Copy the string into allocated memory, handling '' to ' reduction. 5090 */ 5091 str = alloc((unsigned)((p - *arg) - reduce)); 5092 if (str == NULL) 5093 return FAIL; 5094 rettv->v_type = VAR_STRING; 5095 rettv->vval.v_string = str; 5096 5097 for (p = *arg + 1; *p != NUL; ) 5098 { 5099 if (*p == '\'') 5100 { 5101 if (p[1] != '\'') 5102 break; 5103 ++p; 5104 } 5105 MB_COPY_CHAR(p, str); 5106 } 5107 *str = NUL; 5108 *arg = p + 1; 5109 5110 return OK; 5111 } 5112 5113 /* 5114 * Allocate a variable for a List and fill it from "*arg". 5115 * Return OK or FAIL. 5116 */ 5117 static int 5118 get_list_tv(arg, rettv, evaluate) 5119 char_u **arg; 5120 typval_T *rettv; 5121 int evaluate; 5122 { 5123 list_T *l = NULL; 5124 typval_T tv; 5125 listitem_T *item; 5126 5127 if (evaluate) 5128 { 5129 l = list_alloc(); 5130 if (l == NULL) 5131 return FAIL; 5132 } 5133 5134 *arg = skipwhite(*arg + 1); 5135 while (**arg != ']' && **arg != NUL) 5136 { 5137 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5138 goto failret; 5139 if (evaluate) 5140 { 5141 item = listitem_alloc(); 5142 if (item != NULL) 5143 { 5144 item->li_tv = tv; 5145 item->li_tv.v_lock = 0; 5146 list_append(l, item); 5147 } 5148 else 5149 clear_tv(&tv); 5150 } 5151 5152 if (**arg == ']') 5153 break; 5154 if (**arg != ',') 5155 { 5156 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5157 goto failret; 5158 } 5159 *arg = skipwhite(*arg + 1); 5160 } 5161 5162 if (**arg != ']') 5163 { 5164 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5165 failret: 5166 if (evaluate) 5167 list_free(l); 5168 return FAIL; 5169 } 5170 5171 *arg = skipwhite(*arg + 1); 5172 if (evaluate) 5173 { 5174 rettv->v_type = VAR_LIST; 5175 rettv->vval.v_list = l; 5176 ++l->lv_refcount; 5177 } 5178 5179 return OK; 5180 } 5181 5182 /* 5183 * Allocate an empty header for a list. 5184 * Caller should take care of the reference count. 5185 */ 5186 static list_T * 5187 list_alloc() 5188 { 5189 list_T *l; 5190 5191 l = (list_T *)alloc_clear(sizeof(list_T)); 5192 if (l != NULL) 5193 { 5194 /* Prepend the list to the list of lists for garbage collection. */ 5195 if (first_list != NULL) 5196 first_list->lv_used_prev = l; 5197 l->lv_used_prev = NULL; 5198 l->lv_used_next = first_list; 5199 first_list = l; 5200 } 5201 return l; 5202 } 5203 5204 /* 5205 * Unreference a list: decrement the reference count and free it when it 5206 * becomes zero. 5207 */ 5208 void 5209 list_unref(l) 5210 list_T *l; 5211 { 5212 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5213 list_free(l); 5214 } 5215 5216 /* 5217 * Free a list, including all items it points to. 5218 * Ignores the reference count. 5219 */ 5220 static void 5221 list_free(l) 5222 list_T *l; 5223 { 5224 listitem_T *item; 5225 5226 /* Avoid that recursive reference to the list frees us again. */ 5227 l->lv_refcount = DEL_REFCOUNT; 5228 5229 /* Remove the list from the list of lists for garbage collection. */ 5230 if (l->lv_used_prev == NULL) 5231 first_list = l->lv_used_next; 5232 else 5233 l->lv_used_prev->lv_used_next = l->lv_used_next; 5234 if (l->lv_used_next != NULL) 5235 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5236 5237 for (item = l->lv_first; item != NULL; item = l->lv_first) 5238 { 5239 /* Remove the item before deleting it. */ 5240 l->lv_first = item->li_next; 5241 listitem_free(item); 5242 } 5243 vim_free(l); 5244 } 5245 5246 /* 5247 * Allocate a list item. 5248 */ 5249 static listitem_T * 5250 listitem_alloc() 5251 { 5252 return (listitem_T *)alloc(sizeof(listitem_T)); 5253 } 5254 5255 /* 5256 * Free a list item. Also clears the value. Does not notify watchers. 5257 */ 5258 static void 5259 listitem_free(item) 5260 listitem_T *item; 5261 { 5262 clear_tv(&item->li_tv); 5263 vim_free(item); 5264 } 5265 5266 /* 5267 * Remove a list item from a List and free it. Also clears the value. 5268 */ 5269 static void 5270 listitem_remove(l, item) 5271 list_T *l; 5272 listitem_T *item; 5273 { 5274 list_remove(l, item, item); 5275 listitem_free(item); 5276 } 5277 5278 /* 5279 * Get the number of items in a list. 5280 */ 5281 static long 5282 list_len(l) 5283 list_T *l; 5284 { 5285 if (l == NULL) 5286 return 0L; 5287 return l->lv_len; 5288 } 5289 5290 /* 5291 * Return TRUE when two lists have exactly the same values. 5292 */ 5293 static int 5294 list_equal(l1, l2, ic) 5295 list_T *l1; 5296 list_T *l2; 5297 int ic; /* ignore case for strings */ 5298 { 5299 listitem_T *item1, *item2; 5300 5301 if (list_len(l1) != list_len(l2)) 5302 return FALSE; 5303 5304 for (item1 = l1->lv_first, item2 = l2->lv_first; 5305 item1 != NULL && item2 != NULL; 5306 item1 = item1->li_next, item2 = item2->li_next) 5307 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5308 return FALSE; 5309 return item1 == NULL && item2 == NULL; 5310 } 5311 5312 /* 5313 * Return TRUE when two dictionaries have exactly the same key/values. 5314 */ 5315 static int 5316 dict_equal(d1, d2, ic) 5317 dict_T *d1; 5318 dict_T *d2; 5319 int ic; /* ignore case for strings */ 5320 { 5321 hashitem_T *hi; 5322 dictitem_T *item2; 5323 int todo; 5324 5325 if (dict_len(d1) != dict_len(d2)) 5326 return FALSE; 5327 5328 todo = d1->dv_hashtab.ht_used; 5329 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5330 { 5331 if (!HASHITEM_EMPTY(hi)) 5332 { 5333 item2 = dict_find(d2, hi->hi_key, -1); 5334 if (item2 == NULL) 5335 return FALSE; 5336 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5337 return FALSE; 5338 --todo; 5339 } 5340 } 5341 return TRUE; 5342 } 5343 5344 /* 5345 * Return TRUE if "tv1" and "tv2" have the same value. 5346 * Compares the items just like "==" would compare them, but strings and 5347 * numbers are different. 5348 */ 5349 static int 5350 tv_equal(tv1, tv2, ic) 5351 typval_T *tv1; 5352 typval_T *tv2; 5353 int ic; /* ignore case */ 5354 { 5355 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5356 char_u *s1, *s2; 5357 5358 if (tv1->v_type != tv2->v_type) 5359 return FALSE; 5360 5361 switch (tv1->v_type) 5362 { 5363 case VAR_LIST: 5364 /* recursive! */ 5365 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5366 5367 case VAR_DICT: 5368 /* recursive! */ 5369 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5370 5371 case VAR_FUNC: 5372 return (tv1->vval.v_string != NULL 5373 && tv2->vval.v_string != NULL 5374 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5375 5376 case VAR_NUMBER: 5377 return tv1->vval.v_number == tv2->vval.v_number; 5378 5379 case VAR_STRING: 5380 s1 = get_tv_string_buf(tv1, buf1); 5381 s2 = get_tv_string_buf(tv2, buf2); 5382 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5383 } 5384 5385 EMSG2(_(e_intern2), "tv_equal()"); 5386 return TRUE; 5387 } 5388 5389 /* 5390 * Locate item with index "n" in list "l" and return it. 5391 * A negative index is counted from the end; -1 is the last item. 5392 * Returns NULL when "n" is out of range. 5393 */ 5394 static listitem_T * 5395 list_find(l, n) 5396 list_T *l; 5397 long n; 5398 { 5399 listitem_T *item; 5400 long idx; 5401 5402 if (l == NULL) 5403 return NULL; 5404 5405 /* Negative index is relative to the end. */ 5406 if (n < 0) 5407 n = l->lv_len + n; 5408 5409 /* Check for index out of range. */ 5410 if (n < 0 || n >= l->lv_len) 5411 return NULL; 5412 5413 /* When there is a cached index may start search from there. */ 5414 if (l->lv_idx_item != NULL) 5415 { 5416 if (n < l->lv_idx / 2) 5417 { 5418 /* closest to the start of the list */ 5419 item = l->lv_first; 5420 idx = 0; 5421 } 5422 else if (n > (l->lv_idx + l->lv_len) / 2) 5423 { 5424 /* closest to the end of the list */ 5425 item = l->lv_last; 5426 idx = l->lv_len - 1; 5427 } 5428 else 5429 { 5430 /* closest to the cached index */ 5431 item = l->lv_idx_item; 5432 idx = l->lv_idx; 5433 } 5434 } 5435 else 5436 { 5437 if (n < l->lv_len / 2) 5438 { 5439 /* closest to the start of the list */ 5440 item = l->lv_first; 5441 idx = 0; 5442 } 5443 else 5444 { 5445 /* closest to the end of the list */ 5446 item = l->lv_last; 5447 idx = l->lv_len - 1; 5448 } 5449 } 5450 5451 while (n > idx) 5452 { 5453 /* search forward */ 5454 item = item->li_next; 5455 ++idx; 5456 } 5457 while (n < idx) 5458 { 5459 /* search backward */ 5460 item = item->li_prev; 5461 --idx; 5462 } 5463 5464 /* cache the used index */ 5465 l->lv_idx = idx; 5466 l->lv_idx_item = item; 5467 5468 return item; 5469 } 5470 5471 /* 5472 * Locate "item" list "l" and return its index. 5473 * Returns -1 when "item" is not in the list. 5474 */ 5475 static long 5476 list_idx_of_item(l, item) 5477 list_T *l; 5478 listitem_T *item; 5479 { 5480 long idx = 0; 5481 listitem_T *li; 5482 5483 if (l == NULL) 5484 return -1; 5485 idx = 0; 5486 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5487 ++idx; 5488 if (li == NULL) 5489 return -1; 5490 return idx; 5491 } 5492 5493 /* 5494 * Append item "item" to the end of list "l". 5495 */ 5496 static void 5497 list_append(l, item) 5498 list_T *l; 5499 listitem_T *item; 5500 { 5501 if (l->lv_last == NULL) 5502 { 5503 /* empty list */ 5504 l->lv_first = item; 5505 l->lv_last = item; 5506 item->li_prev = NULL; 5507 } 5508 else 5509 { 5510 l->lv_last->li_next = item; 5511 item->li_prev = l->lv_last; 5512 l->lv_last = item; 5513 } 5514 ++l->lv_len; 5515 item->li_next = NULL; 5516 } 5517 5518 /* 5519 * Append typval_T "tv" to the end of list "l". 5520 * Return FAIL when out of memory. 5521 */ 5522 static int 5523 list_append_tv(l, tv) 5524 list_T *l; 5525 typval_T *tv; 5526 { 5527 listitem_T *li = listitem_alloc(); 5528 5529 if (li == NULL) 5530 return FAIL; 5531 copy_tv(tv, &li->li_tv); 5532 list_append(l, li); 5533 return OK; 5534 } 5535 5536 /* 5537 * Add a dictionary to a list. Used by getqflist(). 5538 * Return FAIL when out of memory. 5539 */ 5540 int 5541 list_append_dict(list, dict) 5542 list_T *list; 5543 dict_T *dict; 5544 { 5545 listitem_T *li = listitem_alloc(); 5546 5547 if (li == NULL) 5548 return FAIL; 5549 li->li_tv.v_type = VAR_DICT; 5550 li->li_tv.v_lock = 0; 5551 li->li_tv.vval.v_dict = dict; 5552 list_append(list, li); 5553 ++dict->dv_refcount; 5554 return OK; 5555 } 5556 5557 /* 5558 * Make a copy of "str" and append it as an item to list "l". 5559 * When "len" >= 0 use "str[len]". 5560 * Returns FAIL when out of memory. 5561 */ 5562 static int 5563 list_append_string(l, str, len) 5564 list_T *l; 5565 char_u *str; 5566 int len; 5567 { 5568 listitem_T *li = listitem_alloc(); 5569 5570 if (li == NULL) 5571 return FAIL; 5572 list_append(l, li); 5573 li->li_tv.v_type = VAR_STRING; 5574 li->li_tv.v_lock = 0; 5575 if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 5576 : vim_strsave(str))) == NULL) 5577 return FAIL; 5578 return OK; 5579 } 5580 5581 /* 5582 * Append "n" to list "l". 5583 * Returns FAIL when out of memory. 5584 */ 5585 static int 5586 list_append_number(l, n) 5587 list_T *l; 5588 varnumber_T n; 5589 { 5590 listitem_T *li; 5591 5592 li = listitem_alloc(); 5593 if (li == NULL) 5594 return FAIL; 5595 li->li_tv.v_type = VAR_NUMBER; 5596 li->li_tv.v_lock = 0; 5597 li->li_tv.vval.v_number = n; 5598 list_append(l, li); 5599 return OK; 5600 } 5601 5602 /* 5603 * Insert typval_T "tv" in list "l" before "item". 5604 * If "item" is NULL append at the end. 5605 * Return FAIL when out of memory. 5606 */ 5607 static int 5608 list_insert_tv(l, tv, item) 5609 list_T *l; 5610 typval_T *tv; 5611 listitem_T *item; 5612 { 5613 listitem_T *ni = listitem_alloc(); 5614 5615 if (ni == NULL) 5616 return FAIL; 5617 copy_tv(tv, &ni->li_tv); 5618 if (item == NULL) 5619 /* Append new item at end of list. */ 5620 list_append(l, ni); 5621 else 5622 { 5623 /* Insert new item before existing item. */ 5624 ni->li_prev = item->li_prev; 5625 ni->li_next = item; 5626 if (item->li_prev == NULL) 5627 { 5628 l->lv_first = ni; 5629 ++l->lv_idx; 5630 } 5631 else 5632 { 5633 item->li_prev->li_next = ni; 5634 l->lv_idx_item = NULL; 5635 } 5636 item->li_prev = ni; 5637 ++l->lv_len; 5638 } 5639 return OK; 5640 } 5641 5642 /* 5643 * Extend "l1" with "l2". 5644 * If "bef" is NULL append at the end, otherwise insert before this item. 5645 * Returns FAIL when out of memory. 5646 */ 5647 static int 5648 list_extend(l1, l2, bef) 5649 list_T *l1; 5650 list_T *l2; 5651 listitem_T *bef; 5652 { 5653 listitem_T *item; 5654 5655 for (item = l2->lv_first; item != NULL; item = item->li_next) 5656 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5657 return FAIL; 5658 return OK; 5659 } 5660 5661 /* 5662 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5663 * Return FAIL when out of memory. 5664 */ 5665 static int 5666 list_concat(l1, l2, tv) 5667 list_T *l1; 5668 list_T *l2; 5669 typval_T *tv; 5670 { 5671 list_T *l; 5672 5673 /* make a copy of the first list. */ 5674 l = list_copy(l1, FALSE, 0); 5675 if (l == NULL) 5676 return FAIL; 5677 tv->v_type = VAR_LIST; 5678 tv->vval.v_list = l; 5679 5680 /* append all items from the second list */ 5681 return list_extend(l, l2, NULL); 5682 } 5683 5684 /* 5685 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5686 * The refcount of the new list is set to 1. 5687 * See item_copy() for "copyID". 5688 * Returns NULL when out of memory. 5689 */ 5690 static list_T * 5691 list_copy(orig, deep, copyID) 5692 list_T *orig; 5693 int deep; 5694 int copyID; 5695 { 5696 list_T *copy; 5697 listitem_T *item; 5698 listitem_T *ni; 5699 5700 if (orig == NULL) 5701 return NULL; 5702 5703 copy = list_alloc(); 5704 if (copy != NULL) 5705 { 5706 if (copyID != 0) 5707 { 5708 /* Do this before adding the items, because one of the items may 5709 * refer back to this list. */ 5710 orig->lv_copyID = copyID; 5711 orig->lv_copylist = copy; 5712 } 5713 for (item = orig->lv_first; item != NULL && !got_int; 5714 item = item->li_next) 5715 { 5716 ni = listitem_alloc(); 5717 if (ni == NULL) 5718 break; 5719 if (deep) 5720 { 5721 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5722 { 5723 vim_free(ni); 5724 break; 5725 } 5726 } 5727 else 5728 copy_tv(&item->li_tv, &ni->li_tv); 5729 list_append(copy, ni); 5730 } 5731 ++copy->lv_refcount; 5732 if (item != NULL) 5733 { 5734 list_unref(copy); 5735 copy = NULL; 5736 } 5737 } 5738 5739 return copy; 5740 } 5741 5742 /* 5743 * Remove items "item" to "item2" from list "l". 5744 * Does not free the listitem or the value! 5745 */ 5746 static void 5747 list_remove(l, item, item2) 5748 list_T *l; 5749 listitem_T *item; 5750 listitem_T *item2; 5751 { 5752 listitem_T *ip; 5753 5754 /* notify watchers */ 5755 for (ip = item; ip != NULL; ip = ip->li_next) 5756 { 5757 --l->lv_len; 5758 list_fix_watch(l, ip); 5759 if (ip == item2) 5760 break; 5761 } 5762 5763 if (item2->li_next == NULL) 5764 l->lv_last = item->li_prev; 5765 else 5766 item2->li_next->li_prev = item->li_prev; 5767 if (item->li_prev == NULL) 5768 l->lv_first = item2->li_next; 5769 else 5770 item->li_prev->li_next = item2->li_next; 5771 l->lv_idx_item = NULL; 5772 } 5773 5774 /* 5775 * Return an allocated string with the string representation of a list. 5776 * May return NULL. 5777 */ 5778 static char_u * 5779 list2string(tv) 5780 typval_T *tv; 5781 { 5782 garray_T ga; 5783 5784 if (tv->vval.v_list == NULL) 5785 return NULL; 5786 ga_init2(&ga, (int)sizeof(char), 80); 5787 ga_append(&ga, '['); 5788 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5789 { 5790 vim_free(ga.ga_data); 5791 return NULL; 5792 } 5793 ga_append(&ga, ']'); 5794 ga_append(&ga, NUL); 5795 return (char_u *)ga.ga_data; 5796 } 5797 5798 /* 5799 * Join list "l" into a string in "*gap", using separator "sep". 5800 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5801 * Return FAIL or OK. 5802 */ 5803 static int 5804 list_join(gap, l, sep, echo) 5805 garray_T *gap; 5806 list_T *l; 5807 char_u *sep; 5808 int echo; 5809 { 5810 int first = TRUE; 5811 char_u *tofree; 5812 char_u numbuf[NUMBUFLEN]; 5813 listitem_T *item; 5814 char_u *s; 5815 5816 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5817 { 5818 if (first) 5819 first = FALSE; 5820 else 5821 ga_concat(gap, sep); 5822 5823 if (echo) 5824 s = echo_string(&item->li_tv, &tofree, numbuf); 5825 else 5826 s = tv2string(&item->li_tv, &tofree, numbuf); 5827 if (s != NULL) 5828 ga_concat(gap, s); 5829 vim_free(tofree); 5830 if (s == NULL) 5831 return FAIL; 5832 } 5833 return OK; 5834 } 5835 5836 /* 5837 * Garbage collection for lists and dictionaries. 5838 * 5839 * We use reference counts to be able to free most items right away when they 5840 * are no longer used. But for composite items it's possible that it becomes 5841 * unused while the reference count is > 0: When there is a recursive 5842 * reference. Example: 5843 * :let l = [1, 2, 3] 5844 * :let d = {9: l} 5845 * :let l[1] = d 5846 * 5847 * Since this is quite unusual we handle this with garbage collection: every 5848 * once in a while find out which lists and dicts are not referenced from any 5849 * variable. 5850 * 5851 * Here is a good reference text about garbage collection (refers to Python 5852 * but it applies to all reference-counting mechanisms): 5853 * http://python.ca/nas/python/gc/ 5854 */ 5855 5856 /* 5857 * Do garbage collection for lists and dicts. 5858 * Return TRUE if some memory was freed. 5859 */ 5860 int 5861 garbage_collect() 5862 { 5863 dict_T *dd; 5864 list_T *ll; 5865 int copyID = ++current_copyID; 5866 buf_T *buf; 5867 win_T *wp; 5868 int i; 5869 funccall_T *fc; 5870 int did_free = FALSE; 5871 5872 /* 5873 * 1. Go through all accessible variables and mark all lists and dicts 5874 * with copyID. 5875 */ 5876 /* script-local variables */ 5877 for (i = 1; i <= ga_scripts.ga_len; ++i) 5878 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5879 5880 /* buffer-local variables */ 5881 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5882 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5883 5884 /* window-local variables */ 5885 FOR_ALL_WINDOWS(wp) 5886 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5887 5888 /* global variables */ 5889 set_ref_in_ht(&globvarht, copyID); 5890 5891 /* function-local variables */ 5892 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5893 { 5894 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5895 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5896 } 5897 5898 /* 5899 * 2. Go through the list of dicts and free items without the copyID. 5900 */ 5901 for (dd = first_dict; dd != NULL; ) 5902 if (dd->dv_copyID != copyID) 5903 { 5904 dict_free(dd); 5905 did_free = TRUE; 5906 5907 /* restart, next dict may also have been freed */ 5908 dd = first_dict; 5909 } 5910 else 5911 dd = dd->dv_used_next; 5912 5913 /* 5914 * 3. Go through the list of lists and free items without the copyID. 5915 * But don't free a list that has a watcher (used in a for loop), these 5916 * are not referenced anywhere. 5917 */ 5918 for (ll = first_list; ll != NULL; ) 5919 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 5920 { 5921 list_free(ll); 5922 did_free = TRUE; 5923 5924 /* restart, next list may also have been freed */ 5925 ll = first_list; 5926 } 5927 else 5928 ll = ll->lv_used_next; 5929 5930 return did_free; 5931 } 5932 5933 /* 5934 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5935 */ 5936 static void 5937 set_ref_in_ht(ht, copyID) 5938 hashtab_T *ht; 5939 int copyID; 5940 { 5941 int todo; 5942 hashitem_T *hi; 5943 5944 todo = ht->ht_used; 5945 for (hi = ht->ht_array; todo > 0; ++hi) 5946 if (!HASHITEM_EMPTY(hi)) 5947 { 5948 --todo; 5949 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5950 } 5951 } 5952 5953 /* 5954 * Mark all lists and dicts referenced through list "l" with "copyID". 5955 */ 5956 static void 5957 set_ref_in_list(l, copyID) 5958 list_T *l; 5959 int copyID; 5960 { 5961 listitem_T *li; 5962 5963 for (li = l->lv_first; li != NULL; li = li->li_next) 5964 set_ref_in_item(&li->li_tv, copyID); 5965 } 5966 5967 /* 5968 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5969 */ 5970 static void 5971 set_ref_in_item(tv, copyID) 5972 typval_T *tv; 5973 int copyID; 5974 { 5975 dict_T *dd; 5976 list_T *ll; 5977 5978 switch (tv->v_type) 5979 { 5980 case VAR_DICT: 5981 dd = tv->vval.v_dict; 5982 if (dd->dv_copyID != copyID) 5983 { 5984 /* Didn't see this dict yet. */ 5985 dd->dv_copyID = copyID; 5986 set_ref_in_ht(&dd->dv_hashtab, copyID); 5987 } 5988 break; 5989 5990 case VAR_LIST: 5991 ll = tv->vval.v_list; 5992 if (ll->lv_copyID != copyID) 5993 { 5994 /* Didn't see this list yet. */ 5995 ll->lv_copyID = copyID; 5996 set_ref_in_list(ll, copyID); 5997 } 5998 break; 5999 } 6000 return; 6001 } 6002 6003 /* 6004 * Allocate an empty header for a dictionary. 6005 */ 6006 dict_T * 6007 dict_alloc() 6008 { 6009 dict_T *d; 6010 6011 d = (dict_T *)alloc(sizeof(dict_T)); 6012 if (d != NULL) 6013 { 6014 /* Add the list to the hashtable for garbage collection. */ 6015 if (first_dict != NULL) 6016 first_dict->dv_used_prev = d; 6017 d->dv_used_next = first_dict; 6018 d->dv_used_prev = NULL; 6019 6020 hash_init(&d->dv_hashtab); 6021 d->dv_lock = 0; 6022 d->dv_refcount = 0; 6023 d->dv_copyID = 0; 6024 } 6025 return d; 6026 } 6027 6028 /* 6029 * Unreference a Dictionary: decrement the reference count and free it when it 6030 * becomes zero. 6031 */ 6032 static void 6033 dict_unref(d) 6034 dict_T *d; 6035 { 6036 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6037 dict_free(d); 6038 } 6039 6040 /* 6041 * Free a Dictionary, including all items it contains. 6042 * Ignores the reference count. 6043 */ 6044 static void 6045 dict_free(d) 6046 dict_T *d; 6047 { 6048 int todo; 6049 hashitem_T *hi; 6050 dictitem_T *di; 6051 6052 /* Avoid that recursive reference to the dict frees us again. */ 6053 d->dv_refcount = DEL_REFCOUNT; 6054 6055 /* Remove the dict from the list of dicts for garbage collection. */ 6056 if (d->dv_used_prev == NULL) 6057 first_dict = d->dv_used_next; 6058 else 6059 d->dv_used_prev->dv_used_next = d->dv_used_next; 6060 if (d->dv_used_next != NULL) 6061 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6062 6063 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6064 hash_lock(&d->dv_hashtab); 6065 todo = d->dv_hashtab.ht_used; 6066 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6067 { 6068 if (!HASHITEM_EMPTY(hi)) 6069 { 6070 /* Remove the item before deleting it, just in case there is 6071 * something recursive causing trouble. */ 6072 di = HI2DI(hi); 6073 hash_remove(&d->dv_hashtab, hi); 6074 dictitem_free(di); 6075 --todo; 6076 } 6077 } 6078 hash_clear(&d->dv_hashtab); 6079 vim_free(d); 6080 } 6081 6082 /* 6083 * Allocate a Dictionary item. 6084 * The "key" is copied to the new item. 6085 * Note that the value of the item "di_tv" still needs to be initialized! 6086 * Returns NULL when out of memory. 6087 */ 6088 static dictitem_T * 6089 dictitem_alloc(key) 6090 char_u *key; 6091 { 6092 dictitem_T *di; 6093 6094 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6095 if (di != NULL) 6096 { 6097 STRCPY(di->di_key, key); 6098 di->di_flags = 0; 6099 } 6100 return di; 6101 } 6102 6103 /* 6104 * Make a copy of a Dictionary item. 6105 */ 6106 static dictitem_T * 6107 dictitem_copy(org) 6108 dictitem_T *org; 6109 { 6110 dictitem_T *di; 6111 6112 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6113 if (di != NULL) 6114 { 6115 STRCPY(di->di_key, org->di_key); 6116 di->di_flags = 0; 6117 copy_tv(&org->di_tv, &di->di_tv); 6118 } 6119 return di; 6120 } 6121 6122 /* 6123 * Remove item "item" from Dictionary "dict" and free it. 6124 */ 6125 static void 6126 dictitem_remove(dict, item) 6127 dict_T *dict; 6128 dictitem_T *item; 6129 { 6130 hashitem_T *hi; 6131 6132 hi = hash_find(&dict->dv_hashtab, item->di_key); 6133 if (HASHITEM_EMPTY(hi)) 6134 EMSG2(_(e_intern2), "dictitem_remove()"); 6135 else 6136 hash_remove(&dict->dv_hashtab, hi); 6137 dictitem_free(item); 6138 } 6139 6140 /* 6141 * Free a dict item. Also clears the value. 6142 */ 6143 static void 6144 dictitem_free(item) 6145 dictitem_T *item; 6146 { 6147 clear_tv(&item->di_tv); 6148 vim_free(item); 6149 } 6150 6151 /* 6152 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6153 * The refcount of the new dict is set to 1. 6154 * See item_copy() for "copyID". 6155 * Returns NULL when out of memory. 6156 */ 6157 static dict_T * 6158 dict_copy(orig, deep, copyID) 6159 dict_T *orig; 6160 int deep; 6161 int copyID; 6162 { 6163 dict_T *copy; 6164 dictitem_T *di; 6165 int todo; 6166 hashitem_T *hi; 6167 6168 if (orig == NULL) 6169 return NULL; 6170 6171 copy = dict_alloc(); 6172 if (copy != NULL) 6173 { 6174 if (copyID != 0) 6175 { 6176 orig->dv_copyID = copyID; 6177 orig->dv_copydict = copy; 6178 } 6179 todo = orig->dv_hashtab.ht_used; 6180 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6181 { 6182 if (!HASHITEM_EMPTY(hi)) 6183 { 6184 --todo; 6185 6186 di = dictitem_alloc(hi->hi_key); 6187 if (di == NULL) 6188 break; 6189 if (deep) 6190 { 6191 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6192 copyID) == FAIL) 6193 { 6194 vim_free(di); 6195 break; 6196 } 6197 } 6198 else 6199 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6200 if (dict_add(copy, di) == FAIL) 6201 { 6202 dictitem_free(di); 6203 break; 6204 } 6205 } 6206 } 6207 6208 ++copy->dv_refcount; 6209 if (todo > 0) 6210 { 6211 dict_unref(copy); 6212 copy = NULL; 6213 } 6214 } 6215 6216 return copy; 6217 } 6218 6219 /* 6220 * Add item "item" to Dictionary "d". 6221 * Returns FAIL when out of memory and when key already existed. 6222 */ 6223 static int 6224 dict_add(d, item) 6225 dict_T *d; 6226 dictitem_T *item; 6227 { 6228 return hash_add(&d->dv_hashtab, item->di_key); 6229 } 6230 6231 /* 6232 * Add a number or string entry to dictionary "d". 6233 * When "str" is NULL use number "nr", otherwise use "str". 6234 * Returns FAIL when out of memory and when key already exists. 6235 */ 6236 int 6237 dict_add_nr_str(d, key, nr, str) 6238 dict_T *d; 6239 char *key; 6240 long nr; 6241 char_u *str; 6242 { 6243 dictitem_T *item; 6244 6245 item = dictitem_alloc((char_u *)key); 6246 if (item == NULL) 6247 return FAIL; 6248 item->di_tv.v_lock = 0; 6249 if (str == NULL) 6250 { 6251 item->di_tv.v_type = VAR_NUMBER; 6252 item->di_tv.vval.v_number = nr; 6253 } 6254 else 6255 { 6256 item->di_tv.v_type = VAR_STRING; 6257 item->di_tv.vval.v_string = vim_strsave(str); 6258 } 6259 if (dict_add(d, item) == FAIL) 6260 { 6261 dictitem_free(item); 6262 return FAIL; 6263 } 6264 return OK; 6265 } 6266 6267 /* 6268 * Get the number of items in a Dictionary. 6269 */ 6270 static long 6271 dict_len(d) 6272 dict_T *d; 6273 { 6274 if (d == NULL) 6275 return 0L; 6276 return d->dv_hashtab.ht_used; 6277 } 6278 6279 /* 6280 * Find item "key[len]" in Dictionary "d". 6281 * If "len" is negative use strlen(key). 6282 * Returns NULL when not found. 6283 */ 6284 static dictitem_T * 6285 dict_find(d, key, len) 6286 dict_T *d; 6287 char_u *key; 6288 int len; 6289 { 6290 #define AKEYLEN 200 6291 char_u buf[AKEYLEN]; 6292 char_u *akey; 6293 char_u *tofree = NULL; 6294 hashitem_T *hi; 6295 6296 if (len < 0) 6297 akey = key; 6298 else if (len >= AKEYLEN) 6299 { 6300 tofree = akey = vim_strnsave(key, len); 6301 if (akey == NULL) 6302 return NULL; 6303 } 6304 else 6305 { 6306 /* Avoid a malloc/free by using buf[]. */ 6307 vim_strncpy(buf, key, len); 6308 akey = buf; 6309 } 6310 6311 hi = hash_find(&d->dv_hashtab, akey); 6312 vim_free(tofree); 6313 if (HASHITEM_EMPTY(hi)) 6314 return NULL; 6315 return HI2DI(hi); 6316 } 6317 6318 /* 6319 * Get a string item from a dictionary in allocated memory. 6320 * Returns NULL if the entry doesn't exist or out of memory. 6321 */ 6322 char_u * 6323 get_dict_string(d, key) 6324 dict_T *d; 6325 char_u *key; 6326 { 6327 dictitem_T *di; 6328 6329 di = dict_find(d, key, -1); 6330 if (di == NULL) 6331 return NULL; 6332 return vim_strsave(get_tv_string(&di->di_tv)); 6333 } 6334 6335 /* 6336 * Get a number item from a dictionary. 6337 * Returns 0 if the entry doesn't exist or out of memory. 6338 */ 6339 long 6340 get_dict_number(d, key) 6341 dict_T *d; 6342 char_u *key; 6343 { 6344 dictitem_T *di; 6345 6346 di = dict_find(d, key, -1); 6347 if (di == NULL) 6348 return 0; 6349 return get_tv_number(&di->di_tv); 6350 } 6351 6352 /* 6353 * Return an allocated string with the string representation of a Dictionary. 6354 * May return NULL. 6355 */ 6356 static char_u * 6357 dict2string(tv) 6358 typval_T *tv; 6359 { 6360 garray_T ga; 6361 int first = TRUE; 6362 char_u *tofree; 6363 char_u numbuf[NUMBUFLEN]; 6364 hashitem_T *hi; 6365 char_u *s; 6366 dict_T *d; 6367 int todo; 6368 6369 if ((d = tv->vval.v_dict) == NULL) 6370 return NULL; 6371 ga_init2(&ga, (int)sizeof(char), 80); 6372 ga_append(&ga, '{'); 6373 6374 todo = d->dv_hashtab.ht_used; 6375 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6376 { 6377 if (!HASHITEM_EMPTY(hi)) 6378 { 6379 --todo; 6380 6381 if (first) 6382 first = FALSE; 6383 else 6384 ga_concat(&ga, (char_u *)", "); 6385 6386 tofree = string_quote(hi->hi_key, FALSE); 6387 if (tofree != NULL) 6388 { 6389 ga_concat(&ga, tofree); 6390 vim_free(tofree); 6391 } 6392 ga_concat(&ga, (char_u *)": "); 6393 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6394 if (s != NULL) 6395 ga_concat(&ga, s); 6396 vim_free(tofree); 6397 if (s == NULL) 6398 break; 6399 } 6400 } 6401 if (todo > 0) 6402 { 6403 vim_free(ga.ga_data); 6404 return NULL; 6405 } 6406 6407 ga_append(&ga, '}'); 6408 ga_append(&ga, NUL); 6409 return (char_u *)ga.ga_data; 6410 } 6411 6412 /* 6413 * Allocate a variable for a Dictionary and fill it from "*arg". 6414 * Return OK or FAIL. Returns NOTDONE for {expr}. 6415 */ 6416 static int 6417 get_dict_tv(arg, rettv, evaluate) 6418 char_u **arg; 6419 typval_T *rettv; 6420 int evaluate; 6421 { 6422 dict_T *d = NULL; 6423 typval_T tvkey; 6424 typval_T tv; 6425 char_u *key; 6426 dictitem_T *item; 6427 char_u *start = skipwhite(*arg + 1); 6428 char_u buf[NUMBUFLEN]; 6429 6430 /* 6431 * First check if it's not a curly-braces thing: {expr}. 6432 * Must do this without evaluating, otherwise a function may be called 6433 * twice. Unfortunately this means we need to call eval1() twice for the 6434 * first item. 6435 * But {} is an empty Dictionary. 6436 */ 6437 if (*start != '}') 6438 { 6439 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6440 return FAIL; 6441 if (*start == '}') 6442 return NOTDONE; 6443 } 6444 6445 if (evaluate) 6446 { 6447 d = dict_alloc(); 6448 if (d == NULL) 6449 return FAIL; 6450 } 6451 tvkey.v_type = VAR_UNKNOWN; 6452 tv.v_type = VAR_UNKNOWN; 6453 6454 *arg = skipwhite(*arg + 1); 6455 while (**arg != '}' && **arg != NUL) 6456 { 6457 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6458 goto failret; 6459 if (**arg != ':') 6460 { 6461 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6462 clear_tv(&tvkey); 6463 goto failret; 6464 } 6465 key = get_tv_string_buf_chk(&tvkey, buf); 6466 if (key == NULL || *key == NUL) 6467 { 6468 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6469 if (key != NULL) 6470 EMSG(_(e_emptykey)); 6471 clear_tv(&tvkey); 6472 goto failret; 6473 } 6474 6475 *arg = skipwhite(*arg + 1); 6476 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6477 { 6478 clear_tv(&tvkey); 6479 goto failret; 6480 } 6481 if (evaluate) 6482 { 6483 item = dict_find(d, key, -1); 6484 if (item != NULL) 6485 { 6486 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6487 clear_tv(&tvkey); 6488 clear_tv(&tv); 6489 goto failret; 6490 } 6491 item = dictitem_alloc(key); 6492 clear_tv(&tvkey); 6493 if (item != NULL) 6494 { 6495 item->di_tv = tv; 6496 item->di_tv.v_lock = 0; 6497 if (dict_add(d, item) == FAIL) 6498 dictitem_free(item); 6499 } 6500 } 6501 6502 if (**arg == '}') 6503 break; 6504 if (**arg != ',') 6505 { 6506 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6507 goto failret; 6508 } 6509 *arg = skipwhite(*arg + 1); 6510 } 6511 6512 if (**arg != '}') 6513 { 6514 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6515 failret: 6516 if (evaluate) 6517 dict_free(d); 6518 return FAIL; 6519 } 6520 6521 *arg = skipwhite(*arg + 1); 6522 if (evaluate) 6523 { 6524 rettv->v_type = VAR_DICT; 6525 rettv->vval.v_dict = d; 6526 ++d->dv_refcount; 6527 } 6528 6529 return OK; 6530 } 6531 6532 /* 6533 * Return a string with the string representation of a variable. 6534 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6535 * "numbuf" is used for a number. 6536 * Does not put quotes around strings, as ":echo" displays values. 6537 * May return NULL; 6538 */ 6539 static char_u * 6540 echo_string(tv, tofree, numbuf) 6541 typval_T *tv; 6542 char_u **tofree; 6543 char_u *numbuf; 6544 { 6545 static int recurse = 0; 6546 char_u *r = NULL; 6547 6548 if (recurse >= DICT_MAXNEST) 6549 { 6550 EMSG(_("E724: variable nested too deep for displaying")); 6551 *tofree = NULL; 6552 return NULL; 6553 } 6554 ++recurse; 6555 6556 switch (tv->v_type) 6557 { 6558 case VAR_FUNC: 6559 *tofree = NULL; 6560 r = tv->vval.v_string; 6561 break; 6562 case VAR_LIST: 6563 *tofree = list2string(tv); 6564 r = *tofree; 6565 break; 6566 case VAR_DICT: 6567 *tofree = dict2string(tv); 6568 r = *tofree; 6569 break; 6570 case VAR_STRING: 6571 case VAR_NUMBER: 6572 *tofree = NULL; 6573 r = get_tv_string_buf(tv, numbuf); 6574 break; 6575 default: 6576 EMSG2(_(e_intern2), "echo_string()"); 6577 *tofree = NULL; 6578 } 6579 6580 --recurse; 6581 return r; 6582 } 6583 6584 /* 6585 * Return a string with the string representation of a variable. 6586 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6587 * "numbuf" is used for a number. 6588 * Puts quotes around strings, so that they can be parsed back by eval(). 6589 * May return NULL; 6590 */ 6591 static char_u * 6592 tv2string(tv, tofree, numbuf) 6593 typval_T *tv; 6594 char_u **tofree; 6595 char_u *numbuf; 6596 { 6597 switch (tv->v_type) 6598 { 6599 case VAR_FUNC: 6600 *tofree = string_quote(tv->vval.v_string, TRUE); 6601 return *tofree; 6602 case VAR_STRING: 6603 *tofree = string_quote(tv->vval.v_string, FALSE); 6604 return *tofree; 6605 case VAR_NUMBER: 6606 case VAR_LIST: 6607 case VAR_DICT: 6608 break; 6609 default: 6610 EMSG2(_(e_intern2), "tv2string()"); 6611 } 6612 return echo_string(tv, tofree, numbuf); 6613 } 6614 6615 /* 6616 * Return string "str" in ' quotes, doubling ' characters. 6617 * If "str" is NULL an empty string is assumed. 6618 * If "function" is TRUE make it function('string'). 6619 */ 6620 static char_u * 6621 string_quote(str, function) 6622 char_u *str; 6623 int function; 6624 { 6625 unsigned len; 6626 char_u *p, *r, *s; 6627 6628 len = (function ? 13 : 3); 6629 if (str != NULL) 6630 { 6631 len += STRLEN(str); 6632 for (p = str; *p != NUL; mb_ptr_adv(p)) 6633 if (*p == '\'') 6634 ++len; 6635 } 6636 s = r = alloc(len); 6637 if (r != NULL) 6638 { 6639 if (function) 6640 { 6641 STRCPY(r, "function('"); 6642 r += 10; 6643 } 6644 else 6645 *r++ = '\''; 6646 if (str != NULL) 6647 for (p = str; *p != NUL; ) 6648 { 6649 if (*p == '\'') 6650 *r++ = '\''; 6651 MB_COPY_CHAR(p, r); 6652 } 6653 *r++ = '\''; 6654 if (function) 6655 *r++ = ')'; 6656 *r++ = NUL; 6657 } 6658 return s; 6659 } 6660 6661 /* 6662 * Get the value of an environment variable. 6663 * "arg" is pointing to the '$'. It is advanced to after the name. 6664 * If the environment variable was not set, silently assume it is empty. 6665 * Always return OK. 6666 */ 6667 static int 6668 get_env_tv(arg, rettv, evaluate) 6669 char_u **arg; 6670 typval_T *rettv; 6671 int evaluate; 6672 { 6673 char_u *string = NULL; 6674 int len; 6675 int cc; 6676 char_u *name; 6677 int mustfree = FALSE; 6678 6679 ++*arg; 6680 name = *arg; 6681 len = get_env_len(arg); 6682 if (evaluate) 6683 { 6684 if (len != 0) 6685 { 6686 cc = name[len]; 6687 name[len] = NUL; 6688 /* first try vim_getenv(), fast for normal environment vars */ 6689 string = vim_getenv(name, &mustfree); 6690 if (string != NULL && *string != NUL) 6691 { 6692 if (!mustfree) 6693 string = vim_strsave(string); 6694 } 6695 else 6696 { 6697 if (mustfree) 6698 vim_free(string); 6699 6700 /* next try expanding things like $VIM and ${HOME} */ 6701 string = expand_env_save(name - 1); 6702 if (string != NULL && *string == '$') 6703 { 6704 vim_free(string); 6705 string = NULL; 6706 } 6707 } 6708 name[len] = cc; 6709 } 6710 rettv->v_type = VAR_STRING; 6711 rettv->vval.v_string = string; 6712 } 6713 6714 return OK; 6715 } 6716 6717 /* 6718 * Array with names and number of arguments of all internal functions 6719 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6720 */ 6721 static struct fst 6722 { 6723 char *f_name; /* function name */ 6724 char f_min_argc; /* minimal number of arguments */ 6725 char f_max_argc; /* maximal number of arguments */ 6726 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6727 /* implemenation of function */ 6728 } functions[] = 6729 { 6730 {"add", 2, 2, f_add}, 6731 {"append", 2, 2, f_append}, 6732 {"argc", 0, 0, f_argc}, 6733 {"argidx", 0, 0, f_argidx}, 6734 {"argv", 1, 1, f_argv}, 6735 {"browse", 4, 4, f_browse}, 6736 {"browsedir", 2, 2, f_browsedir}, 6737 {"bufexists", 1, 1, f_bufexists}, 6738 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6739 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6740 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6741 {"buflisted", 1, 1, f_buflisted}, 6742 {"bufloaded", 1, 1, f_bufloaded}, 6743 {"bufname", 1, 1, f_bufname}, 6744 {"bufnr", 1, 1, f_bufnr}, 6745 {"bufwinnr", 1, 1, f_bufwinnr}, 6746 {"byte2line", 1, 1, f_byte2line}, 6747 {"byteidx", 2, 2, f_byteidx}, 6748 {"call", 2, 3, f_call}, 6749 {"char2nr", 1, 1, f_char2nr}, 6750 {"cindent", 1, 1, f_cindent}, 6751 {"col", 1, 1, f_col}, 6752 #if defined(FEAT_INS_EXPAND) 6753 {"complete_add", 1, 1, f_complete_add}, 6754 {"complete_check", 0, 0, f_complete_check}, 6755 #endif 6756 {"confirm", 1, 4, f_confirm}, 6757 {"copy", 1, 1, f_copy}, 6758 {"count", 2, 4, f_count}, 6759 {"cscope_connection",0,3, f_cscope_connection}, 6760 {"cursor", 2, 2, f_cursor}, 6761 {"deepcopy", 1, 2, f_deepcopy}, 6762 {"delete", 1, 1, f_delete}, 6763 {"did_filetype", 0, 0, f_did_filetype}, 6764 {"diff_filler", 1, 1, f_diff_filler}, 6765 {"diff_hlID", 2, 2, f_diff_hlID}, 6766 {"empty", 1, 1, f_empty}, 6767 {"escape", 2, 2, f_escape}, 6768 {"eval", 1, 1, f_eval}, 6769 {"eventhandler", 0, 0, f_eventhandler}, 6770 {"executable", 1, 1, f_executable}, 6771 {"exists", 1, 1, f_exists}, 6772 {"expand", 1, 2, f_expand}, 6773 {"extend", 2, 3, f_extend}, 6774 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6775 {"filereadable", 1, 1, f_filereadable}, 6776 {"filewritable", 1, 1, f_filewritable}, 6777 {"filter", 2, 2, f_filter}, 6778 {"finddir", 1, 3, f_finddir}, 6779 {"findfile", 1, 3, f_findfile}, 6780 {"fnamemodify", 2, 2, f_fnamemodify}, 6781 {"foldclosed", 1, 1, f_foldclosed}, 6782 {"foldclosedend", 1, 1, f_foldclosedend}, 6783 {"foldlevel", 1, 1, f_foldlevel}, 6784 {"foldtext", 0, 0, f_foldtext}, 6785 {"foldtextresult", 1, 1, f_foldtextresult}, 6786 {"foreground", 0, 0, f_foreground}, 6787 {"function", 1, 1, f_function}, 6788 {"garbagecollect", 0, 0, f_garbagecollect}, 6789 {"get", 2, 3, f_get}, 6790 {"getbufline", 2, 3, f_getbufline}, 6791 {"getbufvar", 2, 2, f_getbufvar}, 6792 {"getchar", 0, 1, f_getchar}, 6793 {"getcharmod", 0, 0, f_getcharmod}, 6794 {"getcmdline", 0, 0, f_getcmdline}, 6795 {"getcmdpos", 0, 0, f_getcmdpos}, 6796 {"getcmdtype", 0, 0, f_getcmdtype}, 6797 {"getcwd", 0, 0, f_getcwd}, 6798 {"getfontname", 0, 1, f_getfontname}, 6799 {"getfperm", 1, 1, f_getfperm}, 6800 {"getfsize", 1, 1, f_getfsize}, 6801 {"getftime", 1, 1, f_getftime}, 6802 {"getftype", 1, 1, f_getftype}, 6803 {"getline", 1, 2, f_getline}, 6804 {"getqflist", 0, 0, f_getqflist}, 6805 {"getreg", 0, 2, f_getreg}, 6806 {"getregtype", 0, 1, f_getregtype}, 6807 {"getwinposx", 0, 0, f_getwinposx}, 6808 {"getwinposy", 0, 0, f_getwinposy}, 6809 {"getwinvar", 2, 2, f_getwinvar}, 6810 {"glob", 1, 1, f_glob}, 6811 {"globpath", 2, 2, f_globpath}, 6812 {"has", 1, 1, f_has}, 6813 {"has_key", 2, 2, f_has_key}, 6814 {"hasmapto", 1, 2, f_hasmapto}, 6815 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6816 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6817 {"histadd", 2, 2, f_histadd}, 6818 {"histdel", 1, 2, f_histdel}, 6819 {"histget", 1, 2, f_histget}, 6820 {"histnr", 1, 1, f_histnr}, 6821 {"hlID", 1, 1, f_hlID}, 6822 {"hlexists", 1, 1, f_hlexists}, 6823 {"hostname", 0, 0, f_hostname}, 6824 {"iconv", 3, 3, f_iconv}, 6825 {"indent", 1, 1, f_indent}, 6826 {"index", 2, 4, f_index}, 6827 {"input", 1, 3, f_input}, 6828 {"inputdialog", 1, 3, f_inputdialog}, 6829 {"inputlist", 1, 1, f_inputlist}, 6830 {"inputrestore", 0, 0, f_inputrestore}, 6831 {"inputsave", 0, 0, f_inputsave}, 6832 {"inputsecret", 1, 2, f_inputsecret}, 6833 {"insert", 2, 3, f_insert}, 6834 {"isdirectory", 1, 1, f_isdirectory}, 6835 {"islocked", 1, 1, f_islocked}, 6836 {"items", 1, 1, f_items}, 6837 {"join", 1, 2, f_join}, 6838 {"keys", 1, 1, f_keys}, 6839 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6840 {"len", 1, 1, f_len}, 6841 {"libcall", 3, 3, f_libcall}, 6842 {"libcallnr", 3, 3, f_libcallnr}, 6843 {"line", 1, 1, f_line}, 6844 {"line2byte", 1, 1, f_line2byte}, 6845 {"lispindent", 1, 1, f_lispindent}, 6846 {"localtime", 0, 0, f_localtime}, 6847 {"map", 2, 2, f_map}, 6848 {"maparg", 1, 2, f_maparg}, 6849 {"mapcheck", 1, 2, f_mapcheck}, 6850 {"match", 2, 4, f_match}, 6851 {"matchend", 2, 4, f_matchend}, 6852 {"matchlist", 2, 4, f_matchlist}, 6853 {"matchstr", 2, 4, f_matchstr}, 6854 {"max", 1, 1, f_max}, 6855 {"min", 1, 1, f_min}, 6856 #ifdef vim_mkdir 6857 {"mkdir", 1, 3, f_mkdir}, 6858 #endif 6859 {"mode", 0, 0, f_mode}, 6860 {"nextnonblank", 1, 1, f_nextnonblank}, 6861 {"nr2char", 1, 1, f_nr2char}, 6862 {"prevnonblank", 1, 1, f_prevnonblank}, 6863 {"printf", 2, 19, f_printf}, 6864 {"range", 1, 3, f_range}, 6865 {"readfile", 1, 3, f_readfile}, 6866 {"remote_expr", 2, 3, f_remote_expr}, 6867 {"remote_foreground", 1, 1, f_remote_foreground}, 6868 {"remote_peek", 1, 2, f_remote_peek}, 6869 {"remote_read", 1, 1, f_remote_read}, 6870 {"remote_send", 2, 3, f_remote_send}, 6871 {"remove", 2, 3, f_remove}, 6872 {"rename", 2, 2, f_rename}, 6873 {"repeat", 2, 2, f_repeat}, 6874 {"resolve", 1, 1, f_resolve}, 6875 {"reverse", 1, 1, f_reverse}, 6876 {"search", 1, 2, f_search}, 6877 {"searchdecl", 1, 3, f_searchdecl}, 6878 {"searchpair", 3, 5, f_searchpair}, 6879 {"server2client", 2, 2, f_server2client}, 6880 {"serverlist", 0, 0, f_serverlist}, 6881 {"setbufvar", 3, 3, f_setbufvar}, 6882 {"setcmdpos", 1, 1, f_setcmdpos}, 6883 {"setline", 2, 2, f_setline}, 6884 {"setqflist", 1, 2, f_setqflist}, 6885 {"setreg", 2, 3, f_setreg}, 6886 {"setwinvar", 3, 3, f_setwinvar}, 6887 {"simplify", 1, 1, f_simplify}, 6888 {"sort", 1, 2, f_sort}, 6889 {"soundfold", 1, 1, f_soundfold}, 6890 {"spellbadword", 0, 1, f_spellbadword}, 6891 {"spellsuggest", 1, 3, f_spellsuggest}, 6892 {"split", 1, 3, f_split}, 6893 #ifdef HAVE_STRFTIME 6894 {"strftime", 1, 2, f_strftime}, 6895 #endif 6896 {"stridx", 2, 3, f_stridx}, 6897 {"string", 1, 1, f_string}, 6898 {"strlen", 1, 1, f_strlen}, 6899 {"strpart", 2, 3, f_strpart}, 6900 {"strridx", 2, 3, f_strridx}, 6901 {"strtrans", 1, 1, f_strtrans}, 6902 {"submatch", 1, 1, f_submatch}, 6903 {"substitute", 4, 4, f_substitute}, 6904 {"synID", 3, 3, f_synID}, 6905 {"synIDattr", 2, 3, f_synIDattr}, 6906 {"synIDtrans", 1, 1, f_synIDtrans}, 6907 {"system", 1, 2, f_system}, 6908 {"tagfiles", 0, 0, f_tagfiles}, 6909 {"taglist", 1, 1, f_taglist}, 6910 {"tempname", 0, 0, f_tempname}, 6911 {"test", 1, 1, f_test}, 6912 {"tolower", 1, 1, f_tolower}, 6913 {"toupper", 1, 1, f_toupper}, 6914 {"tr", 3, 3, f_tr}, 6915 {"type", 1, 1, f_type}, 6916 {"values", 1, 1, f_values}, 6917 {"virtcol", 1, 1, f_virtcol}, 6918 {"visualmode", 0, 1, f_visualmode}, 6919 {"winbufnr", 1, 1, f_winbufnr}, 6920 {"wincol", 0, 0, f_wincol}, 6921 {"winheight", 1, 1, f_winheight}, 6922 {"winline", 0, 0, f_winline}, 6923 {"winnr", 0, 1, f_winnr}, 6924 {"winrestcmd", 0, 0, f_winrestcmd}, 6925 {"winwidth", 1, 1, f_winwidth}, 6926 {"writefile", 2, 3, f_writefile}, 6927 }; 6928 6929 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6930 6931 /* 6932 * Function given to ExpandGeneric() to obtain the list of internal 6933 * or user defined function names. 6934 */ 6935 char_u * 6936 get_function_name(xp, idx) 6937 expand_T *xp; 6938 int idx; 6939 { 6940 static int intidx = -1; 6941 char_u *name; 6942 6943 if (idx == 0) 6944 intidx = -1; 6945 if (intidx < 0) 6946 { 6947 name = get_user_func_name(xp, idx); 6948 if (name != NULL) 6949 return name; 6950 } 6951 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6952 { 6953 STRCPY(IObuff, functions[intidx].f_name); 6954 STRCAT(IObuff, "("); 6955 if (functions[intidx].f_max_argc == 0) 6956 STRCAT(IObuff, ")"); 6957 return IObuff; 6958 } 6959 6960 return NULL; 6961 } 6962 6963 /* 6964 * Function given to ExpandGeneric() to obtain the list of internal or 6965 * user defined variable or function names. 6966 */ 6967 /*ARGSUSED*/ 6968 char_u * 6969 get_expr_name(xp, idx) 6970 expand_T *xp; 6971 int idx; 6972 { 6973 static int intidx = -1; 6974 char_u *name; 6975 6976 if (idx == 0) 6977 intidx = -1; 6978 if (intidx < 0) 6979 { 6980 name = get_function_name(xp, idx); 6981 if (name != NULL) 6982 return name; 6983 } 6984 return get_user_var_name(xp, ++intidx); 6985 } 6986 6987 #endif /* FEAT_CMDL_COMPL */ 6988 6989 /* 6990 * Find internal function in table above. 6991 * Return index, or -1 if not found 6992 */ 6993 static int 6994 find_internal_func(name) 6995 char_u *name; /* name of the function */ 6996 { 6997 int first = 0; 6998 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 6999 int cmp; 7000 int x; 7001 7002 /* 7003 * Find the function name in the table. Binary search. 7004 */ 7005 while (first <= last) 7006 { 7007 x = first + ((unsigned)(last - first) >> 1); 7008 cmp = STRCMP(name, functions[x].f_name); 7009 if (cmp < 0) 7010 last = x - 1; 7011 else if (cmp > 0) 7012 first = x + 1; 7013 else 7014 return x; 7015 } 7016 return -1; 7017 } 7018 7019 /* 7020 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7021 * name it contains, otherwise return "name". 7022 */ 7023 static char_u * 7024 deref_func_name(name, lenp) 7025 char_u *name; 7026 int *lenp; 7027 { 7028 dictitem_T *v; 7029 int cc; 7030 7031 cc = name[*lenp]; 7032 name[*lenp] = NUL; 7033 v = find_var(name, NULL); 7034 name[*lenp] = cc; 7035 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7036 { 7037 if (v->di_tv.vval.v_string == NULL) 7038 { 7039 *lenp = 0; 7040 return (char_u *)""; /* just in case */ 7041 } 7042 *lenp = STRLEN(v->di_tv.vval.v_string); 7043 return v->di_tv.vval.v_string; 7044 } 7045 7046 return name; 7047 } 7048 7049 /* 7050 * Allocate a variable for the result of a function. 7051 * Return OK or FAIL. 7052 */ 7053 static int 7054 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7055 evaluate, selfdict) 7056 char_u *name; /* name of the function */ 7057 int len; /* length of "name" */ 7058 typval_T *rettv; 7059 char_u **arg; /* argument, pointing to the '(' */ 7060 linenr_T firstline; /* first line of range */ 7061 linenr_T lastline; /* last line of range */ 7062 int *doesrange; /* return: function handled range */ 7063 int evaluate; 7064 dict_T *selfdict; /* Dictionary for "self" */ 7065 { 7066 char_u *argp; 7067 int ret = OK; 7068 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7069 int argcount = 0; /* number of arguments found */ 7070 7071 /* 7072 * Get the arguments. 7073 */ 7074 argp = *arg; 7075 while (argcount < MAX_FUNC_ARGS) 7076 { 7077 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7078 if (*argp == ')' || *argp == ',' || *argp == NUL) 7079 break; 7080 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7081 { 7082 ret = FAIL; 7083 break; 7084 } 7085 ++argcount; 7086 if (*argp != ',') 7087 break; 7088 } 7089 if (*argp == ')') 7090 ++argp; 7091 else 7092 ret = FAIL; 7093 7094 if (ret == OK) 7095 ret = call_func(name, len, rettv, argcount, argvars, 7096 firstline, lastline, doesrange, evaluate, selfdict); 7097 else if (!aborting()) 7098 { 7099 if (argcount == MAX_FUNC_ARGS) 7100 emsg_funcname("E740: Too many arguments for function %s", name); 7101 else 7102 emsg_funcname("E116: Invalid arguments for function %s", name); 7103 } 7104 7105 while (--argcount >= 0) 7106 clear_tv(&argvars[argcount]); 7107 7108 *arg = skipwhite(argp); 7109 return ret; 7110 } 7111 7112 7113 /* 7114 * Call a function with its resolved parameters 7115 * Return OK or FAIL. 7116 */ 7117 static int 7118 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7119 doesrange, evaluate, selfdict) 7120 char_u *name; /* name of the function */ 7121 int len; /* length of "name" */ 7122 typval_T *rettv; /* return value goes here */ 7123 int argcount; /* number of "argvars" */ 7124 typval_T *argvars; /* vars for arguments */ 7125 linenr_T firstline; /* first line of range */ 7126 linenr_T lastline; /* last line of range */ 7127 int *doesrange; /* return: function handled range */ 7128 int evaluate; 7129 dict_T *selfdict; /* Dictionary for "self" */ 7130 { 7131 int ret = FAIL; 7132 #define ERROR_UNKNOWN 0 7133 #define ERROR_TOOMANY 1 7134 #define ERROR_TOOFEW 2 7135 #define ERROR_SCRIPT 3 7136 #define ERROR_DICT 4 7137 #define ERROR_NONE 5 7138 #define ERROR_OTHER 6 7139 int error = ERROR_NONE; 7140 int i; 7141 int llen; 7142 ufunc_T *fp; 7143 int cc; 7144 #define FLEN_FIXED 40 7145 char_u fname_buf[FLEN_FIXED + 1]; 7146 char_u *fname; 7147 7148 /* 7149 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7150 * Change <SNR>123_name() to K_SNR 123_name(). 7151 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7152 */ 7153 cc = name[len]; 7154 name[len] = NUL; 7155 llen = eval_fname_script(name); 7156 if (llen > 0) 7157 { 7158 fname_buf[0] = K_SPECIAL; 7159 fname_buf[1] = KS_EXTRA; 7160 fname_buf[2] = (int)KE_SNR; 7161 i = 3; 7162 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7163 { 7164 if (current_SID <= 0) 7165 error = ERROR_SCRIPT; 7166 else 7167 { 7168 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7169 i = (int)STRLEN(fname_buf); 7170 } 7171 } 7172 if (i + STRLEN(name + llen) < FLEN_FIXED) 7173 { 7174 STRCPY(fname_buf + i, name + llen); 7175 fname = fname_buf; 7176 } 7177 else 7178 { 7179 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7180 if (fname == NULL) 7181 error = ERROR_OTHER; 7182 else 7183 { 7184 mch_memmove(fname, fname_buf, (size_t)i); 7185 STRCPY(fname + i, name + llen); 7186 } 7187 } 7188 } 7189 else 7190 fname = name; 7191 7192 *doesrange = FALSE; 7193 7194 7195 /* execute the function if no errors detected and executing */ 7196 if (evaluate && error == ERROR_NONE) 7197 { 7198 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7199 error = ERROR_UNKNOWN; 7200 7201 if (!builtin_function(fname)) 7202 { 7203 /* 7204 * User defined function. 7205 */ 7206 fp = find_func(fname); 7207 7208 #ifdef FEAT_AUTOCMD 7209 /* Trigger FuncUndefined event, may load the function. */ 7210 if (fp == NULL 7211 && apply_autocmds(EVENT_FUNCUNDEFINED, 7212 fname, fname, TRUE, NULL) 7213 && !aborting()) 7214 { 7215 /* executed an autocommand, search for the function again */ 7216 fp = find_func(fname); 7217 } 7218 #endif 7219 /* Try loading a package. */ 7220 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7221 { 7222 /* loaded a package, search for the function again */ 7223 fp = find_func(fname); 7224 } 7225 7226 if (fp != NULL) 7227 { 7228 if (fp->uf_flags & FC_RANGE) 7229 *doesrange = TRUE; 7230 if (argcount < fp->uf_args.ga_len) 7231 error = ERROR_TOOFEW; 7232 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7233 error = ERROR_TOOMANY; 7234 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7235 error = ERROR_DICT; 7236 else 7237 { 7238 /* 7239 * Call the user function. 7240 * Save and restore search patterns, script variables and 7241 * redo buffer. 7242 */ 7243 save_search_patterns(); 7244 saveRedobuff(); 7245 ++fp->uf_calls; 7246 call_user_func(fp, argcount, argvars, rettv, 7247 firstline, lastline, 7248 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7249 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7250 && fp->uf_refcount <= 0) 7251 /* Function was unreferenced while being used, free it 7252 * now. */ 7253 func_free(fp); 7254 restoreRedobuff(); 7255 restore_search_patterns(); 7256 error = ERROR_NONE; 7257 } 7258 } 7259 } 7260 else 7261 { 7262 /* 7263 * Find the function name in the table, call its implementation. 7264 */ 7265 i = find_internal_func(fname); 7266 if (i >= 0) 7267 { 7268 if (argcount < functions[i].f_min_argc) 7269 error = ERROR_TOOFEW; 7270 else if (argcount > functions[i].f_max_argc) 7271 error = ERROR_TOOMANY; 7272 else 7273 { 7274 argvars[argcount].v_type = VAR_UNKNOWN; 7275 functions[i].f_func(argvars, rettv); 7276 error = ERROR_NONE; 7277 } 7278 } 7279 } 7280 /* 7281 * The function call (or "FuncUndefined" autocommand sequence) might 7282 * have been aborted by an error, an interrupt, or an explicitly thrown 7283 * exception that has not been caught so far. This situation can be 7284 * tested for by calling aborting(). For an error in an internal 7285 * function or for the "E132" error in call_user_func(), however, the 7286 * throw point at which the "force_abort" flag (temporarily reset by 7287 * emsg()) is normally updated has not been reached yet. We need to 7288 * update that flag first to make aborting() reliable. 7289 */ 7290 update_force_abort(); 7291 } 7292 if (error == ERROR_NONE) 7293 ret = OK; 7294 7295 /* 7296 * Report an error unless the argument evaluation or function call has been 7297 * cancelled due to an aborting error, an interrupt, or an exception. 7298 */ 7299 if (!aborting()) 7300 { 7301 switch (error) 7302 { 7303 case ERROR_UNKNOWN: 7304 emsg_funcname("E117: Unknown function: %s", name); 7305 break; 7306 case ERROR_TOOMANY: 7307 emsg_funcname(e_toomanyarg, name); 7308 break; 7309 case ERROR_TOOFEW: 7310 emsg_funcname("E119: Not enough arguments for function: %s", 7311 name); 7312 break; 7313 case ERROR_SCRIPT: 7314 emsg_funcname("E120: Using <SID> not in a script context: %s", 7315 name); 7316 break; 7317 case ERROR_DICT: 7318 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7319 name); 7320 break; 7321 } 7322 } 7323 7324 name[len] = cc; 7325 if (fname != name && fname != fname_buf) 7326 vim_free(fname); 7327 7328 return ret; 7329 } 7330 7331 /* 7332 * Give an error message with a function name. Handle <SNR> things. 7333 */ 7334 static void 7335 emsg_funcname(msg, name) 7336 char *msg; 7337 char_u *name; 7338 { 7339 char_u *p; 7340 7341 if (*name == K_SPECIAL) 7342 p = concat_str((char_u *)"<SNR>", name + 3); 7343 else 7344 p = name; 7345 EMSG2(_(msg), p); 7346 if (p != name) 7347 vim_free(p); 7348 } 7349 7350 /********************************************* 7351 * Implementation of the built-in functions 7352 */ 7353 7354 /* 7355 * "add(list, item)" function 7356 */ 7357 static void 7358 f_add(argvars, rettv) 7359 typval_T *argvars; 7360 typval_T *rettv; 7361 { 7362 list_T *l; 7363 7364 rettv->vval.v_number = 1; /* Default: Failed */ 7365 if (argvars[0].v_type == VAR_LIST) 7366 { 7367 if ((l = argvars[0].vval.v_list) != NULL 7368 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7369 && list_append_tv(l, &argvars[1]) == OK) 7370 copy_tv(&argvars[0], rettv); 7371 } 7372 else 7373 EMSG(_(e_listreq)); 7374 } 7375 7376 /* 7377 * "append(lnum, string/list)" function 7378 */ 7379 static void 7380 f_append(argvars, rettv) 7381 typval_T *argvars; 7382 typval_T *rettv; 7383 { 7384 long lnum; 7385 char_u *line; 7386 list_T *l = NULL; 7387 listitem_T *li = NULL; 7388 typval_T *tv; 7389 long added = 0; 7390 7391 lnum = get_tv_lnum(argvars); 7392 if (lnum >= 0 7393 && lnum <= curbuf->b_ml.ml_line_count 7394 && u_save(lnum, lnum + 1) == OK) 7395 { 7396 if (argvars[1].v_type == VAR_LIST) 7397 { 7398 l = argvars[1].vval.v_list; 7399 if (l == NULL) 7400 return; 7401 li = l->lv_first; 7402 } 7403 rettv->vval.v_number = 0; /* Default: Success */ 7404 for (;;) 7405 { 7406 if (l == NULL) 7407 tv = &argvars[1]; /* append a string */ 7408 else if (li == NULL) 7409 break; /* end of list */ 7410 else 7411 tv = &li->li_tv; /* append item from list */ 7412 line = get_tv_string_chk(tv); 7413 if (line == NULL) /* type error */ 7414 { 7415 rettv->vval.v_number = 1; /* Failed */ 7416 break; 7417 } 7418 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7419 ++added; 7420 if (l == NULL) 7421 break; 7422 li = li->li_next; 7423 } 7424 7425 appended_lines_mark(lnum, added); 7426 if (curwin->w_cursor.lnum > lnum) 7427 curwin->w_cursor.lnum += added; 7428 } 7429 else 7430 rettv->vval.v_number = 1; /* Failed */ 7431 } 7432 7433 /* 7434 * "argc()" function 7435 */ 7436 /* ARGSUSED */ 7437 static void 7438 f_argc(argvars, rettv) 7439 typval_T *argvars; 7440 typval_T *rettv; 7441 { 7442 rettv->vval.v_number = ARGCOUNT; 7443 } 7444 7445 /* 7446 * "argidx()" function 7447 */ 7448 /* ARGSUSED */ 7449 static void 7450 f_argidx(argvars, rettv) 7451 typval_T *argvars; 7452 typval_T *rettv; 7453 { 7454 rettv->vval.v_number = curwin->w_arg_idx; 7455 } 7456 7457 /* 7458 * "argv(nr)" function 7459 */ 7460 static void 7461 f_argv(argvars, rettv) 7462 typval_T *argvars; 7463 typval_T *rettv; 7464 { 7465 int idx; 7466 7467 idx = get_tv_number_chk(&argvars[0], NULL); 7468 if (idx >= 0 && idx < ARGCOUNT) 7469 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7470 else 7471 rettv->vval.v_string = NULL; 7472 rettv->v_type = VAR_STRING; 7473 } 7474 7475 /* 7476 * "browse(save, title, initdir, default)" function 7477 */ 7478 /* ARGSUSED */ 7479 static void 7480 f_browse(argvars, rettv) 7481 typval_T *argvars; 7482 typval_T *rettv; 7483 { 7484 #ifdef FEAT_BROWSE 7485 int save; 7486 char_u *title; 7487 char_u *initdir; 7488 char_u *defname; 7489 char_u buf[NUMBUFLEN]; 7490 char_u buf2[NUMBUFLEN]; 7491 int error = FALSE; 7492 7493 save = get_tv_number_chk(&argvars[0], &error); 7494 title = get_tv_string_chk(&argvars[1]); 7495 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7496 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7497 7498 if (error || title == NULL || initdir == NULL || defname == NULL) 7499 rettv->vval.v_string = NULL; 7500 else 7501 rettv->vval.v_string = 7502 do_browse(save ? BROWSE_SAVE : 0, 7503 title, defname, NULL, initdir, NULL, curbuf); 7504 #else 7505 rettv->vval.v_string = NULL; 7506 #endif 7507 rettv->v_type = VAR_STRING; 7508 } 7509 7510 /* 7511 * "browsedir(title, initdir)" function 7512 */ 7513 /* ARGSUSED */ 7514 static void 7515 f_browsedir(argvars, rettv) 7516 typval_T *argvars; 7517 typval_T *rettv; 7518 { 7519 #ifdef FEAT_BROWSE 7520 char_u *title; 7521 char_u *initdir; 7522 char_u buf[NUMBUFLEN]; 7523 7524 title = get_tv_string_chk(&argvars[0]); 7525 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7526 7527 if (title == NULL || initdir == NULL) 7528 rettv->vval.v_string = NULL; 7529 else 7530 rettv->vval.v_string = do_browse(BROWSE_DIR, 7531 title, NULL, NULL, initdir, NULL, curbuf); 7532 #else 7533 rettv->vval.v_string = NULL; 7534 #endif 7535 rettv->v_type = VAR_STRING; 7536 } 7537 7538 static buf_T *find_buffer __ARGS((typval_T *avar)); 7539 7540 /* 7541 * Find a buffer by number or exact name. 7542 */ 7543 static buf_T * 7544 find_buffer(avar) 7545 typval_T *avar; 7546 { 7547 buf_T *buf = NULL; 7548 7549 if (avar->v_type == VAR_NUMBER) 7550 buf = buflist_findnr((int)avar->vval.v_number); 7551 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7552 { 7553 buf = buflist_findname_exp(avar->vval.v_string); 7554 if (buf == NULL) 7555 { 7556 /* No full path name match, try a match with a URL or a "nofile" 7557 * buffer, these don't use the full path. */ 7558 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7559 if (buf->b_fname != NULL 7560 && (path_with_url(buf->b_fname) 7561 #ifdef FEAT_QUICKFIX 7562 || bt_nofile(buf) 7563 #endif 7564 ) 7565 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7566 break; 7567 } 7568 } 7569 return buf; 7570 } 7571 7572 /* 7573 * "bufexists(expr)" function 7574 */ 7575 static void 7576 f_bufexists(argvars, rettv) 7577 typval_T *argvars; 7578 typval_T *rettv; 7579 { 7580 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7581 } 7582 7583 /* 7584 * "buflisted(expr)" function 7585 */ 7586 static void 7587 f_buflisted(argvars, rettv) 7588 typval_T *argvars; 7589 typval_T *rettv; 7590 { 7591 buf_T *buf; 7592 7593 buf = find_buffer(&argvars[0]); 7594 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7595 } 7596 7597 /* 7598 * "bufloaded(expr)" function 7599 */ 7600 static void 7601 f_bufloaded(argvars, rettv) 7602 typval_T *argvars; 7603 typval_T *rettv; 7604 { 7605 buf_T *buf; 7606 7607 buf = find_buffer(&argvars[0]); 7608 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7609 } 7610 7611 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7612 7613 /* 7614 * Get buffer by number or pattern. 7615 */ 7616 static buf_T * 7617 get_buf_tv(tv) 7618 typval_T *tv; 7619 { 7620 char_u *name = tv->vval.v_string; 7621 int save_magic; 7622 char_u *save_cpo; 7623 buf_T *buf; 7624 7625 if (tv->v_type == VAR_NUMBER) 7626 return buflist_findnr((int)tv->vval.v_number); 7627 if (tv->v_type != VAR_STRING) 7628 return NULL; 7629 if (name == NULL || *name == NUL) 7630 return curbuf; 7631 if (name[0] == '$' && name[1] == NUL) 7632 return lastbuf; 7633 7634 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7635 save_magic = p_magic; 7636 p_magic = TRUE; 7637 save_cpo = p_cpo; 7638 p_cpo = (char_u *)""; 7639 7640 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7641 TRUE, FALSE)); 7642 7643 p_magic = save_magic; 7644 p_cpo = save_cpo; 7645 7646 /* If not found, try expanding the name, like done for bufexists(). */ 7647 if (buf == NULL) 7648 buf = find_buffer(tv); 7649 7650 return buf; 7651 } 7652 7653 /* 7654 * "bufname(expr)" function 7655 */ 7656 static void 7657 f_bufname(argvars, rettv) 7658 typval_T *argvars; 7659 typval_T *rettv; 7660 { 7661 buf_T *buf; 7662 7663 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7664 ++emsg_off; 7665 buf = get_buf_tv(&argvars[0]); 7666 rettv->v_type = VAR_STRING; 7667 if (buf != NULL && buf->b_fname != NULL) 7668 rettv->vval.v_string = vim_strsave(buf->b_fname); 7669 else 7670 rettv->vval.v_string = NULL; 7671 --emsg_off; 7672 } 7673 7674 /* 7675 * "bufnr(expr)" function 7676 */ 7677 static void 7678 f_bufnr(argvars, rettv) 7679 typval_T *argvars; 7680 typval_T *rettv; 7681 { 7682 buf_T *buf; 7683 7684 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7685 ++emsg_off; 7686 buf = get_buf_tv(&argvars[0]); 7687 if (buf != NULL) 7688 rettv->vval.v_number = buf->b_fnum; 7689 else 7690 rettv->vval.v_number = -1; 7691 --emsg_off; 7692 } 7693 7694 /* 7695 * "bufwinnr(nr)" function 7696 */ 7697 static void 7698 f_bufwinnr(argvars, rettv) 7699 typval_T *argvars; 7700 typval_T *rettv; 7701 { 7702 #ifdef FEAT_WINDOWS 7703 win_T *wp; 7704 int winnr = 0; 7705 #endif 7706 buf_T *buf; 7707 7708 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7709 ++emsg_off; 7710 buf = get_buf_tv(&argvars[0]); 7711 #ifdef FEAT_WINDOWS 7712 for (wp = firstwin; wp; wp = wp->w_next) 7713 { 7714 ++winnr; 7715 if (wp->w_buffer == buf) 7716 break; 7717 } 7718 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7719 #else 7720 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7721 #endif 7722 --emsg_off; 7723 } 7724 7725 /* 7726 * "byte2line(byte)" function 7727 */ 7728 /*ARGSUSED*/ 7729 static void 7730 f_byte2line(argvars, rettv) 7731 typval_T *argvars; 7732 typval_T *rettv; 7733 { 7734 #ifndef FEAT_BYTEOFF 7735 rettv->vval.v_number = -1; 7736 #else 7737 long boff = 0; 7738 7739 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7740 if (boff < 0) 7741 rettv->vval.v_number = -1; 7742 else 7743 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7744 (linenr_T)0, &boff); 7745 #endif 7746 } 7747 7748 /* 7749 * "byteidx()" function 7750 */ 7751 /*ARGSUSED*/ 7752 static void 7753 f_byteidx(argvars, rettv) 7754 typval_T *argvars; 7755 typval_T *rettv; 7756 { 7757 #ifdef FEAT_MBYTE 7758 char_u *t; 7759 #endif 7760 char_u *str; 7761 long idx; 7762 7763 str = get_tv_string_chk(&argvars[0]); 7764 idx = get_tv_number_chk(&argvars[1], NULL); 7765 rettv->vval.v_number = -1; 7766 if (str == NULL || idx < 0) 7767 return; 7768 7769 #ifdef FEAT_MBYTE 7770 t = str; 7771 for ( ; idx > 0; idx--) 7772 { 7773 if (*t == NUL) /* EOL reached */ 7774 return; 7775 t += (*mb_ptr2len)(t); 7776 } 7777 rettv->vval.v_number = t - str; 7778 #else 7779 if (idx <= STRLEN(str)) 7780 rettv->vval.v_number = idx; 7781 #endif 7782 } 7783 7784 /* 7785 * "call(func, arglist)" function 7786 */ 7787 static void 7788 f_call(argvars, rettv) 7789 typval_T *argvars; 7790 typval_T *rettv; 7791 { 7792 char_u *func; 7793 typval_T argv[MAX_FUNC_ARGS]; 7794 int argc = 0; 7795 listitem_T *item; 7796 int dummy; 7797 dict_T *selfdict = NULL; 7798 7799 rettv->vval.v_number = 0; 7800 if (argvars[1].v_type != VAR_LIST) 7801 { 7802 EMSG(_(e_listreq)); 7803 return; 7804 } 7805 if (argvars[1].vval.v_list == NULL) 7806 return; 7807 7808 if (argvars[0].v_type == VAR_FUNC) 7809 func = argvars[0].vval.v_string; 7810 else 7811 func = get_tv_string(&argvars[0]); 7812 if (*func == NUL) 7813 return; /* type error or empty name */ 7814 7815 if (argvars[2].v_type != VAR_UNKNOWN) 7816 { 7817 if (argvars[2].v_type != VAR_DICT) 7818 { 7819 EMSG(_(e_dictreq)); 7820 return; 7821 } 7822 selfdict = argvars[2].vval.v_dict; 7823 } 7824 7825 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7826 item = item->li_next) 7827 { 7828 if (argc == MAX_FUNC_ARGS) 7829 { 7830 EMSG(_("E699: Too many arguments")); 7831 break; 7832 } 7833 /* Make a copy of each argument. This is needed to be able to set 7834 * v_lock to VAR_FIXED in the copy without changing the original list. 7835 */ 7836 copy_tv(&item->li_tv, &argv[argc++]); 7837 } 7838 7839 if (item == NULL) 7840 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7841 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7842 &dummy, TRUE, selfdict); 7843 7844 /* Free the arguments. */ 7845 while (argc > 0) 7846 clear_tv(&argv[--argc]); 7847 } 7848 7849 /* 7850 * "char2nr(string)" function 7851 */ 7852 static void 7853 f_char2nr(argvars, rettv) 7854 typval_T *argvars; 7855 typval_T *rettv; 7856 { 7857 #ifdef FEAT_MBYTE 7858 if (has_mbyte) 7859 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7860 else 7861 #endif 7862 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7863 } 7864 7865 /* 7866 * "cindent(lnum)" function 7867 */ 7868 static void 7869 f_cindent(argvars, rettv) 7870 typval_T *argvars; 7871 typval_T *rettv; 7872 { 7873 #ifdef FEAT_CINDENT 7874 pos_T pos; 7875 linenr_T lnum; 7876 7877 pos = curwin->w_cursor; 7878 lnum = get_tv_lnum(argvars); 7879 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7880 { 7881 curwin->w_cursor.lnum = lnum; 7882 rettv->vval.v_number = get_c_indent(); 7883 curwin->w_cursor = pos; 7884 } 7885 else 7886 #endif 7887 rettv->vval.v_number = -1; 7888 } 7889 7890 /* 7891 * "col(string)" function 7892 */ 7893 static void 7894 f_col(argvars, rettv) 7895 typval_T *argvars; 7896 typval_T *rettv; 7897 { 7898 colnr_T col = 0; 7899 pos_T *fp; 7900 7901 fp = var2fpos(&argvars[0], FALSE); 7902 if (fp != NULL) 7903 { 7904 if (fp->col == MAXCOL) 7905 { 7906 /* '> can be MAXCOL, get the length of the line then */ 7907 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7908 col = STRLEN(ml_get(fp->lnum)) + 1; 7909 else 7910 col = MAXCOL; 7911 } 7912 else 7913 { 7914 col = fp->col + 1; 7915 #ifdef FEAT_VIRTUALEDIT 7916 /* col(".") when the cursor is on the NUL at the end of the line 7917 * because of "coladd" can be seen as an extra column. */ 7918 if (virtual_active() && fp == &curwin->w_cursor) 7919 { 7920 char_u *p = ml_get_cursor(); 7921 7922 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7923 curwin->w_virtcol - curwin->w_cursor.coladd)) 7924 { 7925 # ifdef FEAT_MBYTE 7926 int l; 7927 7928 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 7929 col += l; 7930 # else 7931 if (*p != NUL && p[1] == NUL) 7932 ++col; 7933 # endif 7934 } 7935 } 7936 #endif 7937 } 7938 } 7939 rettv->vval.v_number = col; 7940 } 7941 7942 #if defined(FEAT_INS_EXPAND) 7943 /* 7944 * "complete_add()" function 7945 */ 7946 /*ARGSUSED*/ 7947 static void 7948 f_complete_add(argvars, rettv) 7949 typval_T *argvars; 7950 typval_T *rettv; 7951 { 7952 char_u *s; 7953 7954 s = get_tv_string_chk(&argvars[0]); 7955 if (s != NULL) 7956 rettv->vval.v_number = ins_compl_add(s, -1, NULL, FORWARD, 0); 7957 } 7958 7959 /* 7960 * "complete_check()" function 7961 */ 7962 /*ARGSUSED*/ 7963 static void 7964 f_complete_check(argvars, rettv) 7965 typval_T *argvars; 7966 typval_T *rettv; 7967 { 7968 int saved = RedrawingDisabled; 7969 7970 RedrawingDisabled = 0; 7971 ins_compl_check_keys(0); 7972 rettv->vval.v_number = compl_interrupted; 7973 RedrawingDisabled = saved; 7974 } 7975 #endif 7976 7977 /* 7978 * "confirm(message, buttons[, default [, type]])" function 7979 */ 7980 /*ARGSUSED*/ 7981 static void 7982 f_confirm(argvars, rettv) 7983 typval_T *argvars; 7984 typval_T *rettv; 7985 { 7986 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7987 char_u *message; 7988 char_u *buttons = NULL; 7989 char_u buf[NUMBUFLEN]; 7990 char_u buf2[NUMBUFLEN]; 7991 int def = 1; 7992 int type = VIM_GENERIC; 7993 char_u *typestr; 7994 int error = FALSE; 7995 7996 message = get_tv_string_chk(&argvars[0]); 7997 if (message == NULL) 7998 error = TRUE; 7999 if (argvars[1].v_type != VAR_UNKNOWN) 8000 { 8001 buttons = get_tv_string_buf_chk(&argvars[1], buf); 8002 if (buttons == NULL) 8003 error = TRUE; 8004 if (argvars[2].v_type != VAR_UNKNOWN) 8005 { 8006 def = get_tv_number_chk(&argvars[2], &error); 8007 if (argvars[3].v_type != VAR_UNKNOWN) 8008 { 8009 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 8010 if (typestr == NULL) 8011 error = TRUE; 8012 else 8013 { 8014 switch (TOUPPER_ASC(*typestr)) 8015 { 8016 case 'E': type = VIM_ERROR; break; 8017 case 'Q': type = VIM_QUESTION; break; 8018 case 'I': type = VIM_INFO; break; 8019 case 'W': type = VIM_WARNING; break; 8020 case 'G': type = VIM_GENERIC; break; 8021 } 8022 } 8023 } 8024 } 8025 } 8026 8027 if (buttons == NULL || *buttons == NUL) 8028 buttons = (char_u *)_("&Ok"); 8029 8030 if (error) 8031 rettv->vval.v_number = 0; 8032 else 8033 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8034 def, NULL); 8035 #else 8036 rettv->vval.v_number = 0; 8037 #endif 8038 } 8039 8040 /* 8041 * "copy()" function 8042 */ 8043 static void 8044 f_copy(argvars, rettv) 8045 typval_T *argvars; 8046 typval_T *rettv; 8047 { 8048 item_copy(&argvars[0], rettv, FALSE, 0); 8049 } 8050 8051 /* 8052 * "count()" function 8053 */ 8054 static void 8055 f_count(argvars, rettv) 8056 typval_T *argvars; 8057 typval_T *rettv; 8058 { 8059 long n = 0; 8060 int ic = FALSE; 8061 8062 if (argvars[0].v_type == VAR_LIST) 8063 { 8064 listitem_T *li; 8065 list_T *l; 8066 long idx; 8067 8068 if ((l = argvars[0].vval.v_list) != NULL) 8069 { 8070 li = l->lv_first; 8071 if (argvars[2].v_type != VAR_UNKNOWN) 8072 { 8073 int error = FALSE; 8074 8075 ic = get_tv_number_chk(&argvars[2], &error); 8076 if (argvars[3].v_type != VAR_UNKNOWN) 8077 { 8078 idx = get_tv_number_chk(&argvars[3], &error); 8079 if (!error) 8080 { 8081 li = list_find(l, idx); 8082 if (li == NULL) 8083 EMSGN(_(e_listidx), idx); 8084 } 8085 } 8086 if (error) 8087 li = NULL; 8088 } 8089 8090 for ( ; li != NULL; li = li->li_next) 8091 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8092 ++n; 8093 } 8094 } 8095 else if (argvars[0].v_type == VAR_DICT) 8096 { 8097 int todo; 8098 dict_T *d; 8099 hashitem_T *hi; 8100 8101 if ((d = argvars[0].vval.v_dict) != NULL) 8102 { 8103 int error = FALSE; 8104 8105 if (argvars[2].v_type != VAR_UNKNOWN) 8106 { 8107 ic = get_tv_number_chk(&argvars[2], &error); 8108 if (argvars[3].v_type != VAR_UNKNOWN) 8109 EMSG(_(e_invarg)); 8110 } 8111 8112 todo = error ? 0 : d->dv_hashtab.ht_used; 8113 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8114 { 8115 if (!HASHITEM_EMPTY(hi)) 8116 { 8117 --todo; 8118 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8119 ++n; 8120 } 8121 } 8122 } 8123 } 8124 else 8125 EMSG2(_(e_listdictarg), "count()"); 8126 rettv->vval.v_number = n; 8127 } 8128 8129 /* 8130 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8131 * 8132 * Checks the existence of a cscope connection. 8133 */ 8134 /*ARGSUSED*/ 8135 static void 8136 f_cscope_connection(argvars, rettv) 8137 typval_T *argvars; 8138 typval_T *rettv; 8139 { 8140 #ifdef FEAT_CSCOPE 8141 int num = 0; 8142 char_u *dbpath = NULL; 8143 char_u *prepend = NULL; 8144 char_u buf[NUMBUFLEN]; 8145 8146 if (argvars[0].v_type != VAR_UNKNOWN 8147 && argvars[1].v_type != VAR_UNKNOWN) 8148 { 8149 num = (int)get_tv_number(&argvars[0]); 8150 dbpath = get_tv_string(&argvars[1]); 8151 if (argvars[2].v_type != VAR_UNKNOWN) 8152 prepend = get_tv_string_buf(&argvars[2], buf); 8153 } 8154 8155 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8156 #else 8157 rettv->vval.v_number = 0; 8158 #endif 8159 } 8160 8161 /* 8162 * "cursor(lnum, col)" function 8163 * 8164 * Moves the cursor to the specified line and column 8165 */ 8166 /*ARGSUSED*/ 8167 static void 8168 f_cursor(argvars, rettv) 8169 typval_T *argvars; 8170 typval_T *rettv; 8171 { 8172 long line, col; 8173 8174 line = get_tv_lnum(argvars); 8175 col = get_tv_number_chk(&argvars[1], NULL); 8176 if (line < 0 || col < 0) 8177 return; /* type error; errmsg already given */ 8178 if (line > 0) 8179 curwin->w_cursor.lnum = line; 8180 if (col > 0) 8181 curwin->w_cursor.col = col - 1; 8182 #ifdef FEAT_VIRTUALEDIT 8183 curwin->w_cursor.coladd = 0; 8184 #endif 8185 8186 /* Make sure the cursor is in a valid position. */ 8187 check_cursor(); 8188 #ifdef FEAT_MBYTE 8189 /* Correct cursor for multi-byte character. */ 8190 if (has_mbyte) 8191 mb_adjust_cursor(); 8192 #endif 8193 8194 curwin->w_set_curswant = TRUE; 8195 } 8196 8197 /* 8198 * "deepcopy()" function 8199 */ 8200 static void 8201 f_deepcopy(argvars, rettv) 8202 typval_T *argvars; 8203 typval_T *rettv; 8204 { 8205 int noref = 0; 8206 8207 if (argvars[1].v_type != VAR_UNKNOWN) 8208 noref = get_tv_number_chk(&argvars[1], NULL); 8209 if (noref < 0 || noref > 1) 8210 EMSG(_(e_invarg)); 8211 else 8212 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8213 } 8214 8215 /* 8216 * "delete()" function 8217 */ 8218 static void 8219 f_delete(argvars, rettv) 8220 typval_T *argvars; 8221 typval_T *rettv; 8222 { 8223 if (check_restricted() || check_secure()) 8224 rettv->vval.v_number = -1; 8225 else 8226 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8227 } 8228 8229 /* 8230 * "did_filetype()" function 8231 */ 8232 /*ARGSUSED*/ 8233 static void 8234 f_did_filetype(argvars, rettv) 8235 typval_T *argvars; 8236 typval_T *rettv; 8237 { 8238 #ifdef FEAT_AUTOCMD 8239 rettv->vval.v_number = did_filetype; 8240 #else 8241 rettv->vval.v_number = 0; 8242 #endif 8243 } 8244 8245 /* 8246 * "diff_filler()" function 8247 */ 8248 /*ARGSUSED*/ 8249 static void 8250 f_diff_filler(argvars, rettv) 8251 typval_T *argvars; 8252 typval_T *rettv; 8253 { 8254 #ifdef FEAT_DIFF 8255 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8256 #endif 8257 } 8258 8259 /* 8260 * "diff_hlID()" function 8261 */ 8262 /*ARGSUSED*/ 8263 static void 8264 f_diff_hlID(argvars, rettv) 8265 typval_T *argvars; 8266 typval_T *rettv; 8267 { 8268 #ifdef FEAT_DIFF 8269 linenr_T lnum = get_tv_lnum(argvars); 8270 static linenr_T prev_lnum = 0; 8271 static int changedtick = 0; 8272 static int fnum = 0; 8273 static int change_start = 0; 8274 static int change_end = 0; 8275 static hlf_T hlID = 0; 8276 int filler_lines; 8277 int col; 8278 8279 if (lnum < 0) /* ignore type error in {lnum} arg */ 8280 lnum = 0; 8281 if (lnum != prev_lnum 8282 || changedtick != curbuf->b_changedtick 8283 || fnum != curbuf->b_fnum) 8284 { 8285 /* New line, buffer, change: need to get the values. */ 8286 filler_lines = diff_check(curwin, lnum); 8287 if (filler_lines < 0) 8288 { 8289 if (filler_lines == -1) 8290 { 8291 change_start = MAXCOL; 8292 change_end = -1; 8293 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8294 hlID = HLF_ADD; /* added line */ 8295 else 8296 hlID = HLF_CHD; /* changed line */ 8297 } 8298 else 8299 hlID = HLF_ADD; /* added line */ 8300 } 8301 else 8302 hlID = (hlf_T)0; 8303 prev_lnum = lnum; 8304 changedtick = curbuf->b_changedtick; 8305 fnum = curbuf->b_fnum; 8306 } 8307 8308 if (hlID == HLF_CHD || hlID == HLF_TXD) 8309 { 8310 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8311 if (col >= change_start && col <= change_end) 8312 hlID = HLF_TXD; /* changed text */ 8313 else 8314 hlID = HLF_CHD; /* changed line */ 8315 } 8316 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 8317 #endif 8318 } 8319 8320 /* 8321 * "empty({expr})" function 8322 */ 8323 static void 8324 f_empty(argvars, rettv) 8325 typval_T *argvars; 8326 typval_T *rettv; 8327 { 8328 int n; 8329 8330 switch (argvars[0].v_type) 8331 { 8332 case VAR_STRING: 8333 case VAR_FUNC: 8334 n = argvars[0].vval.v_string == NULL 8335 || *argvars[0].vval.v_string == NUL; 8336 break; 8337 case VAR_NUMBER: 8338 n = argvars[0].vval.v_number == 0; 8339 break; 8340 case VAR_LIST: 8341 n = argvars[0].vval.v_list == NULL 8342 || argvars[0].vval.v_list->lv_first == NULL; 8343 break; 8344 case VAR_DICT: 8345 n = argvars[0].vval.v_dict == NULL 8346 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8347 break; 8348 default: 8349 EMSG2(_(e_intern2), "f_empty()"); 8350 n = 0; 8351 } 8352 8353 rettv->vval.v_number = n; 8354 } 8355 8356 /* 8357 * "escape({string}, {chars})" function 8358 */ 8359 static void 8360 f_escape(argvars, rettv) 8361 typval_T *argvars; 8362 typval_T *rettv; 8363 { 8364 char_u buf[NUMBUFLEN]; 8365 8366 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8367 get_tv_string_buf(&argvars[1], buf)); 8368 rettv->v_type = VAR_STRING; 8369 } 8370 8371 /* 8372 * "eval()" function 8373 */ 8374 /*ARGSUSED*/ 8375 static void 8376 f_eval(argvars, rettv) 8377 typval_T *argvars; 8378 typval_T *rettv; 8379 { 8380 char_u *s; 8381 8382 s = get_tv_string_chk(&argvars[0]); 8383 if (s != NULL) 8384 s = skipwhite(s); 8385 8386 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8387 { 8388 rettv->v_type = VAR_NUMBER; 8389 rettv->vval.v_number = 0; 8390 } 8391 else if (*s != NUL) 8392 EMSG(_(e_trailing)); 8393 } 8394 8395 /* 8396 * "eventhandler()" function 8397 */ 8398 /*ARGSUSED*/ 8399 static void 8400 f_eventhandler(argvars, rettv) 8401 typval_T *argvars; 8402 typval_T *rettv; 8403 { 8404 rettv->vval.v_number = vgetc_busy; 8405 } 8406 8407 /* 8408 * "executable()" function 8409 */ 8410 static void 8411 f_executable(argvars, rettv) 8412 typval_T *argvars; 8413 typval_T *rettv; 8414 { 8415 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8416 } 8417 8418 /* 8419 * "exists()" function 8420 */ 8421 static void 8422 f_exists(argvars, rettv) 8423 typval_T *argvars; 8424 typval_T *rettv; 8425 { 8426 char_u *p; 8427 char_u *name; 8428 int n = FALSE; 8429 int len = 0; 8430 8431 p = get_tv_string(&argvars[0]); 8432 if (*p == '$') /* environment variable */ 8433 { 8434 /* first try "normal" environment variables (fast) */ 8435 if (mch_getenv(p + 1) != NULL) 8436 n = TRUE; 8437 else 8438 { 8439 /* try expanding things like $VIM and ${HOME} */ 8440 p = expand_env_save(p); 8441 if (p != NULL && *p != '$') 8442 n = TRUE; 8443 vim_free(p); 8444 } 8445 } 8446 else if (*p == '&' || *p == '+') /* option */ 8447 n = (get_option_tv(&p, NULL, TRUE) == OK); 8448 else if (*p == '*') /* internal or user defined function */ 8449 { 8450 n = function_exists(p + 1); 8451 } 8452 else if (*p == ':') 8453 { 8454 n = cmd_exists(p + 1); 8455 } 8456 else if (*p == '#') 8457 { 8458 #ifdef FEAT_AUTOCMD 8459 name = p + 1; 8460 p = vim_strchr(name, '#'); 8461 if (p != NULL) 8462 n = au_exists(name, p, p + 1); 8463 else 8464 n = au_exists(name, name + STRLEN(name), NULL); 8465 #endif 8466 } 8467 else /* internal variable */ 8468 { 8469 char_u *tofree; 8470 typval_T tv; 8471 8472 /* get_name_len() takes care of expanding curly braces */ 8473 name = p; 8474 len = get_name_len(&p, &tofree, TRUE, FALSE); 8475 if (len > 0) 8476 { 8477 if (tofree != NULL) 8478 name = tofree; 8479 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8480 if (n) 8481 { 8482 /* handle d.key, l[idx], f(expr) */ 8483 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8484 if (n) 8485 clear_tv(&tv); 8486 } 8487 } 8488 8489 vim_free(tofree); 8490 } 8491 8492 rettv->vval.v_number = n; 8493 } 8494 8495 /* 8496 * "expand()" function 8497 */ 8498 static void 8499 f_expand(argvars, rettv) 8500 typval_T *argvars; 8501 typval_T *rettv; 8502 { 8503 char_u *s; 8504 int len; 8505 char_u *errormsg; 8506 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8507 expand_T xpc; 8508 int error = FALSE; 8509 8510 rettv->v_type = VAR_STRING; 8511 s = get_tv_string(&argvars[0]); 8512 if (*s == '%' || *s == '#' || *s == '<') 8513 { 8514 ++emsg_off; 8515 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8516 --emsg_off; 8517 } 8518 else 8519 { 8520 /* When the optional second argument is non-zero, don't remove matches 8521 * for 'suffixes' and 'wildignore' */ 8522 if (argvars[1].v_type != VAR_UNKNOWN 8523 && get_tv_number_chk(&argvars[1], &error)) 8524 flags |= WILD_KEEP_ALL; 8525 if (!error) 8526 { 8527 ExpandInit(&xpc); 8528 xpc.xp_context = EXPAND_FILES; 8529 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8530 ExpandCleanup(&xpc); 8531 } 8532 else 8533 rettv->vval.v_string = NULL; 8534 } 8535 } 8536 8537 /* 8538 * "extend(list, list [, idx])" function 8539 * "extend(dict, dict [, action])" function 8540 */ 8541 static void 8542 f_extend(argvars, rettv) 8543 typval_T *argvars; 8544 typval_T *rettv; 8545 { 8546 rettv->vval.v_number = 0; 8547 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8548 { 8549 list_T *l1, *l2; 8550 listitem_T *item; 8551 long before; 8552 int error = FALSE; 8553 8554 l1 = argvars[0].vval.v_list; 8555 l2 = argvars[1].vval.v_list; 8556 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8557 && l2 != NULL) 8558 { 8559 if (argvars[2].v_type != VAR_UNKNOWN) 8560 { 8561 before = get_tv_number_chk(&argvars[2], &error); 8562 if (error) 8563 return; /* type error; errmsg already given */ 8564 8565 if (before == l1->lv_len) 8566 item = NULL; 8567 else 8568 { 8569 item = list_find(l1, before); 8570 if (item == NULL) 8571 { 8572 EMSGN(_(e_listidx), before); 8573 return; 8574 } 8575 } 8576 } 8577 else 8578 item = NULL; 8579 list_extend(l1, l2, item); 8580 8581 copy_tv(&argvars[0], rettv); 8582 } 8583 } 8584 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8585 { 8586 dict_T *d1, *d2; 8587 dictitem_T *di1; 8588 char_u *action; 8589 int i; 8590 hashitem_T *hi2; 8591 int todo; 8592 8593 d1 = argvars[0].vval.v_dict; 8594 d2 = argvars[1].vval.v_dict; 8595 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8596 && d2 != NULL) 8597 { 8598 /* Check the third argument. */ 8599 if (argvars[2].v_type != VAR_UNKNOWN) 8600 { 8601 static char *(av[]) = {"keep", "force", "error"}; 8602 8603 action = get_tv_string_chk(&argvars[2]); 8604 if (action == NULL) 8605 return; /* type error; errmsg already given */ 8606 for (i = 0; i < 3; ++i) 8607 if (STRCMP(action, av[i]) == 0) 8608 break; 8609 if (i == 3) 8610 { 8611 EMSGN(_(e_invarg2), action); 8612 return; 8613 } 8614 } 8615 else 8616 action = (char_u *)"force"; 8617 8618 /* Go over all entries in the second dict and add them to the 8619 * first dict. */ 8620 todo = d2->dv_hashtab.ht_used; 8621 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8622 { 8623 if (!HASHITEM_EMPTY(hi2)) 8624 { 8625 --todo; 8626 di1 = dict_find(d1, hi2->hi_key, -1); 8627 if (di1 == NULL) 8628 { 8629 di1 = dictitem_copy(HI2DI(hi2)); 8630 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8631 dictitem_free(di1); 8632 } 8633 else if (*action == 'e') 8634 { 8635 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8636 break; 8637 } 8638 else if (*action == 'f') 8639 { 8640 clear_tv(&di1->di_tv); 8641 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8642 } 8643 } 8644 } 8645 8646 copy_tv(&argvars[0], rettv); 8647 } 8648 } 8649 else 8650 EMSG2(_(e_listdictarg), "extend()"); 8651 } 8652 8653 /* 8654 * "filereadable()" function 8655 */ 8656 static void 8657 f_filereadable(argvars, rettv) 8658 typval_T *argvars; 8659 typval_T *rettv; 8660 { 8661 FILE *fd; 8662 char_u *p; 8663 int n; 8664 8665 p = get_tv_string(&argvars[0]); 8666 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8667 { 8668 n = TRUE; 8669 fclose(fd); 8670 } 8671 else 8672 n = FALSE; 8673 8674 rettv->vval.v_number = n; 8675 } 8676 8677 /* 8678 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8679 * rights to write into. 8680 */ 8681 static void 8682 f_filewritable(argvars, rettv) 8683 typval_T *argvars; 8684 typval_T *rettv; 8685 { 8686 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8687 } 8688 8689 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8690 8691 static void 8692 findfilendir(argvars, rettv, dir) 8693 typval_T *argvars; 8694 typval_T *rettv; 8695 int dir; 8696 { 8697 #ifdef FEAT_SEARCHPATH 8698 char_u *fname; 8699 char_u *fresult = NULL; 8700 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8701 char_u *p; 8702 char_u pathbuf[NUMBUFLEN]; 8703 int count = 1; 8704 int first = TRUE; 8705 8706 fname = get_tv_string(&argvars[0]); 8707 8708 if (argvars[1].v_type != VAR_UNKNOWN) 8709 { 8710 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8711 if (p == NULL) 8712 count = -1; /* error */ 8713 else 8714 { 8715 if (*p != NUL) 8716 path = p; 8717 8718 if (argvars[2].v_type != VAR_UNKNOWN) 8719 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8720 } 8721 } 8722 8723 if (*fname != NUL && count >= 0) 8724 { 8725 do 8726 { 8727 vim_free(fresult); 8728 fresult = find_file_in_path_option(first ? fname : NULL, 8729 first ? (int)STRLEN(fname) : 0, 8730 0, first, path, dir, NULL); 8731 first = FALSE; 8732 } while (--count > 0 && fresult != NULL); 8733 } 8734 8735 rettv->vval.v_string = fresult; 8736 #else 8737 rettv->vval.v_string = NULL; 8738 #endif 8739 rettv->v_type = VAR_STRING; 8740 } 8741 8742 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8743 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8744 8745 /* 8746 * Implementation of map() and filter(). 8747 */ 8748 static void 8749 filter_map(argvars, rettv, map) 8750 typval_T *argvars; 8751 typval_T *rettv; 8752 int map; 8753 { 8754 char_u buf[NUMBUFLEN]; 8755 char_u *expr; 8756 listitem_T *li, *nli; 8757 list_T *l = NULL; 8758 dictitem_T *di; 8759 hashtab_T *ht; 8760 hashitem_T *hi; 8761 dict_T *d = NULL; 8762 typval_T save_val; 8763 typval_T save_key; 8764 int rem; 8765 int todo; 8766 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8767 8768 8769 rettv->vval.v_number = 0; 8770 if (argvars[0].v_type == VAR_LIST) 8771 { 8772 if ((l = argvars[0].vval.v_list) == NULL 8773 || (map && tv_check_lock(l->lv_lock, msg))) 8774 return; 8775 } 8776 else if (argvars[0].v_type == VAR_DICT) 8777 { 8778 if ((d = argvars[0].vval.v_dict) == NULL 8779 || (map && tv_check_lock(d->dv_lock, msg))) 8780 return; 8781 } 8782 else 8783 { 8784 EMSG2(_(e_listdictarg), msg); 8785 return; 8786 } 8787 8788 expr = get_tv_string_buf_chk(&argvars[1], buf); 8789 /* On type errors, the preceding call has already displayed an error 8790 * message. Avoid a misleading error message for an empty string that 8791 * was not passed as argument. */ 8792 if (expr != NULL) 8793 { 8794 prepare_vimvar(VV_VAL, &save_val); 8795 expr = skipwhite(expr); 8796 8797 if (argvars[0].v_type == VAR_DICT) 8798 { 8799 prepare_vimvar(VV_KEY, &save_key); 8800 vimvars[VV_KEY].vv_type = VAR_STRING; 8801 8802 ht = &d->dv_hashtab; 8803 hash_lock(ht); 8804 todo = ht->ht_used; 8805 for (hi = ht->ht_array; todo > 0; ++hi) 8806 { 8807 if (!HASHITEM_EMPTY(hi)) 8808 { 8809 --todo; 8810 di = HI2DI(hi); 8811 if (tv_check_lock(di->di_tv.v_lock, msg)) 8812 break; 8813 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8814 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8815 break; 8816 if (!map && rem) 8817 dictitem_remove(d, di); 8818 clear_tv(&vimvars[VV_KEY].vv_tv); 8819 } 8820 } 8821 hash_unlock(ht); 8822 8823 restore_vimvar(VV_KEY, &save_key); 8824 } 8825 else 8826 { 8827 for (li = l->lv_first; li != NULL; li = nli) 8828 { 8829 if (tv_check_lock(li->li_tv.v_lock, msg)) 8830 break; 8831 nli = li->li_next; 8832 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8833 break; 8834 if (!map && rem) 8835 listitem_remove(l, li); 8836 } 8837 } 8838 8839 restore_vimvar(VV_VAL, &save_val); 8840 } 8841 8842 copy_tv(&argvars[0], rettv); 8843 } 8844 8845 static int 8846 filter_map_one(tv, expr, map, remp) 8847 typval_T *tv; 8848 char_u *expr; 8849 int map; 8850 int *remp; 8851 { 8852 typval_T rettv; 8853 char_u *s; 8854 8855 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8856 s = expr; 8857 if (eval1(&s, &rettv, TRUE) == FAIL) 8858 return FAIL; 8859 if (*s != NUL) /* check for trailing chars after expr */ 8860 { 8861 EMSG2(_(e_invexpr2), s); 8862 return FAIL; 8863 } 8864 if (map) 8865 { 8866 /* map(): replace the list item value */ 8867 clear_tv(tv); 8868 rettv.v_lock = 0; 8869 *tv = rettv; 8870 } 8871 else 8872 { 8873 int error = FALSE; 8874 8875 /* filter(): when expr is zero remove the item */ 8876 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8877 clear_tv(&rettv); 8878 /* On type error, nothing has been removed; return FAIL to stop the 8879 * loop. The error message was given by get_tv_number_chk(). */ 8880 if (error) 8881 return FAIL; 8882 } 8883 clear_tv(&vimvars[VV_VAL].vv_tv); 8884 return OK; 8885 } 8886 8887 /* 8888 * "filter()" function 8889 */ 8890 static void 8891 f_filter(argvars, rettv) 8892 typval_T *argvars; 8893 typval_T *rettv; 8894 { 8895 filter_map(argvars, rettv, FALSE); 8896 } 8897 8898 /* 8899 * "finddir({fname}[, {path}[, {count}]])" function 8900 */ 8901 static void 8902 f_finddir(argvars, rettv) 8903 typval_T *argvars; 8904 typval_T *rettv; 8905 { 8906 findfilendir(argvars, rettv, TRUE); 8907 } 8908 8909 /* 8910 * "findfile({fname}[, {path}[, {count}]])" function 8911 */ 8912 static void 8913 f_findfile(argvars, rettv) 8914 typval_T *argvars; 8915 typval_T *rettv; 8916 { 8917 findfilendir(argvars, rettv, FALSE); 8918 } 8919 8920 /* 8921 * "fnamemodify({fname}, {mods})" function 8922 */ 8923 static void 8924 f_fnamemodify(argvars, rettv) 8925 typval_T *argvars; 8926 typval_T *rettv; 8927 { 8928 char_u *fname; 8929 char_u *mods; 8930 int usedlen = 0; 8931 int len; 8932 char_u *fbuf = NULL; 8933 char_u buf[NUMBUFLEN]; 8934 8935 fname = get_tv_string_chk(&argvars[0]); 8936 mods = get_tv_string_buf_chk(&argvars[1], buf); 8937 if (fname == NULL || mods == NULL) 8938 fname = NULL; 8939 else 8940 { 8941 len = (int)STRLEN(fname); 8942 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8943 } 8944 8945 rettv->v_type = VAR_STRING; 8946 if (fname == NULL) 8947 rettv->vval.v_string = NULL; 8948 else 8949 rettv->vval.v_string = vim_strnsave(fname, len); 8950 vim_free(fbuf); 8951 } 8952 8953 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8954 8955 /* 8956 * "foldclosed()" function 8957 */ 8958 static void 8959 foldclosed_both(argvars, rettv, end) 8960 typval_T *argvars; 8961 typval_T *rettv; 8962 int end; 8963 { 8964 #ifdef FEAT_FOLDING 8965 linenr_T lnum; 8966 linenr_T first, last; 8967 8968 lnum = get_tv_lnum(argvars); 8969 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8970 { 8971 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8972 { 8973 if (end) 8974 rettv->vval.v_number = (varnumber_T)last; 8975 else 8976 rettv->vval.v_number = (varnumber_T)first; 8977 return; 8978 } 8979 } 8980 #endif 8981 rettv->vval.v_number = -1; 8982 } 8983 8984 /* 8985 * "foldclosed()" function 8986 */ 8987 static void 8988 f_foldclosed(argvars, rettv) 8989 typval_T *argvars; 8990 typval_T *rettv; 8991 { 8992 foldclosed_both(argvars, rettv, FALSE); 8993 } 8994 8995 /* 8996 * "foldclosedend()" function 8997 */ 8998 static void 8999 f_foldclosedend(argvars, rettv) 9000 typval_T *argvars; 9001 typval_T *rettv; 9002 { 9003 foldclosed_both(argvars, rettv, TRUE); 9004 } 9005 9006 /* 9007 * "foldlevel()" function 9008 */ 9009 static void 9010 f_foldlevel(argvars, rettv) 9011 typval_T *argvars; 9012 typval_T *rettv; 9013 { 9014 #ifdef FEAT_FOLDING 9015 linenr_T lnum; 9016 9017 lnum = get_tv_lnum(argvars); 9018 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9019 rettv->vval.v_number = foldLevel(lnum); 9020 else 9021 #endif 9022 rettv->vval.v_number = 0; 9023 } 9024 9025 /* 9026 * "foldtext()" function 9027 */ 9028 /*ARGSUSED*/ 9029 static void 9030 f_foldtext(argvars, rettv) 9031 typval_T *argvars; 9032 typval_T *rettv; 9033 { 9034 #ifdef FEAT_FOLDING 9035 linenr_T lnum; 9036 char_u *s; 9037 char_u *r; 9038 int len; 9039 char *txt; 9040 #endif 9041 9042 rettv->v_type = VAR_STRING; 9043 rettv->vval.v_string = NULL; 9044 #ifdef FEAT_FOLDING 9045 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9046 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9047 <= curbuf->b_ml.ml_line_count 9048 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9049 { 9050 /* Find first non-empty line in the fold. */ 9051 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9052 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9053 { 9054 if (!linewhite(lnum)) 9055 break; 9056 ++lnum; 9057 } 9058 9059 /* Find interesting text in this line. */ 9060 s = skipwhite(ml_get(lnum)); 9061 /* skip C comment-start */ 9062 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9063 { 9064 s = skipwhite(s + 2); 9065 if (*skipwhite(s) == NUL 9066 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9067 { 9068 s = skipwhite(ml_get(lnum + 1)); 9069 if (*s == '*') 9070 s = skipwhite(s + 1); 9071 } 9072 } 9073 txt = _("+-%s%3ld lines: "); 9074 r = alloc((unsigned)(STRLEN(txt) 9075 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9076 + 20 /* for %3ld */ 9077 + STRLEN(s))); /* concatenated */ 9078 if (r != NULL) 9079 { 9080 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9081 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9082 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9083 len = (int)STRLEN(r); 9084 STRCAT(r, s); 9085 /* remove 'foldmarker' and 'commentstring' */ 9086 foldtext_cleanup(r + len); 9087 rettv->vval.v_string = r; 9088 } 9089 } 9090 #endif 9091 } 9092 9093 /* 9094 * "foldtextresult(lnum)" function 9095 */ 9096 /*ARGSUSED*/ 9097 static void 9098 f_foldtextresult(argvars, rettv) 9099 typval_T *argvars; 9100 typval_T *rettv; 9101 { 9102 #ifdef FEAT_FOLDING 9103 linenr_T lnum; 9104 char_u *text; 9105 char_u buf[51]; 9106 foldinfo_T foldinfo; 9107 int fold_count; 9108 #endif 9109 9110 rettv->v_type = VAR_STRING; 9111 rettv->vval.v_string = NULL; 9112 #ifdef FEAT_FOLDING 9113 lnum = get_tv_lnum(argvars); 9114 /* treat illegal types and illegal string values for {lnum} the same */ 9115 if (lnum < 0) 9116 lnum = 0; 9117 fold_count = foldedCount(curwin, lnum, &foldinfo); 9118 if (fold_count > 0) 9119 { 9120 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9121 &foldinfo, buf); 9122 if (text == buf) 9123 text = vim_strsave(text); 9124 rettv->vval.v_string = text; 9125 } 9126 #endif 9127 } 9128 9129 /* 9130 * "foreground()" function 9131 */ 9132 /*ARGSUSED*/ 9133 static void 9134 f_foreground(argvars, rettv) 9135 typval_T *argvars; 9136 typval_T *rettv; 9137 { 9138 rettv->vval.v_number = 0; 9139 #ifdef FEAT_GUI 9140 if (gui.in_use) 9141 gui_mch_set_foreground(); 9142 #else 9143 # ifdef WIN32 9144 win32_set_foreground(); 9145 # endif 9146 #endif 9147 } 9148 9149 /* 9150 * "function()" function 9151 */ 9152 /*ARGSUSED*/ 9153 static void 9154 f_function(argvars, rettv) 9155 typval_T *argvars; 9156 typval_T *rettv; 9157 { 9158 char_u *s; 9159 9160 rettv->vval.v_number = 0; 9161 s = get_tv_string(&argvars[0]); 9162 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9163 EMSG2(_(e_invarg2), s); 9164 else if (!function_exists(s)) 9165 EMSG2(_("E700: Unknown function: %s"), s); 9166 else 9167 { 9168 rettv->vval.v_string = vim_strsave(s); 9169 rettv->v_type = VAR_FUNC; 9170 } 9171 } 9172 9173 /* 9174 * "garbagecollect()" function 9175 */ 9176 /*ARGSUSED*/ 9177 static void 9178 f_garbagecollect(argvars, rettv) 9179 typval_T *argvars; 9180 typval_T *rettv; 9181 { 9182 garbage_collect(); 9183 } 9184 9185 /* 9186 * "get()" function 9187 */ 9188 static void 9189 f_get(argvars, rettv) 9190 typval_T *argvars; 9191 typval_T *rettv; 9192 { 9193 listitem_T *li; 9194 list_T *l; 9195 dictitem_T *di; 9196 dict_T *d; 9197 typval_T *tv = NULL; 9198 9199 if (argvars[0].v_type == VAR_LIST) 9200 { 9201 if ((l = argvars[0].vval.v_list) != NULL) 9202 { 9203 int error = FALSE; 9204 9205 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9206 if (!error && li != NULL) 9207 tv = &li->li_tv; 9208 } 9209 } 9210 else if (argvars[0].v_type == VAR_DICT) 9211 { 9212 if ((d = argvars[0].vval.v_dict) != NULL) 9213 { 9214 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9215 if (di != NULL) 9216 tv = &di->di_tv; 9217 } 9218 } 9219 else 9220 EMSG2(_(e_listdictarg), "get()"); 9221 9222 if (tv == NULL) 9223 { 9224 if (argvars[2].v_type == VAR_UNKNOWN) 9225 rettv->vval.v_number = 0; 9226 else 9227 copy_tv(&argvars[2], rettv); 9228 } 9229 else 9230 copy_tv(tv, rettv); 9231 } 9232 9233 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9234 9235 /* 9236 * Get line or list of lines from buffer "buf" into "rettv". 9237 * Return a range (from start to end) of lines in rettv from the specified 9238 * buffer. 9239 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9240 */ 9241 static void 9242 get_buffer_lines(buf, start, end, retlist, rettv) 9243 buf_T *buf; 9244 linenr_T start; 9245 linenr_T end; 9246 int retlist; 9247 typval_T *rettv; 9248 { 9249 char_u *p; 9250 list_T *l = NULL; 9251 9252 if (retlist) 9253 { 9254 l = list_alloc(); 9255 if (l == NULL) 9256 return; 9257 9258 rettv->vval.v_list = l; 9259 rettv->v_type = VAR_LIST; 9260 ++l->lv_refcount; 9261 } 9262 else 9263 rettv->vval.v_number = 0; 9264 9265 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9266 return; 9267 9268 if (!retlist) 9269 { 9270 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9271 p = ml_get_buf(buf, start, FALSE); 9272 else 9273 p = (char_u *)""; 9274 9275 rettv->v_type = VAR_STRING; 9276 rettv->vval.v_string = vim_strsave(p); 9277 } 9278 else 9279 { 9280 if (end < start) 9281 return; 9282 9283 if (start < 1) 9284 start = 1; 9285 if (end > buf->b_ml.ml_line_count) 9286 end = buf->b_ml.ml_line_count; 9287 while (start <= end) 9288 if (list_append_string(l, ml_get_buf(buf, start++, FALSE), -1) 9289 == FAIL) 9290 break; 9291 } 9292 } 9293 9294 /* 9295 * "getbufline()" function 9296 */ 9297 static void 9298 f_getbufline(argvars, rettv) 9299 typval_T *argvars; 9300 typval_T *rettv; 9301 { 9302 linenr_T lnum; 9303 linenr_T end; 9304 buf_T *buf; 9305 9306 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9307 ++emsg_off; 9308 buf = get_buf_tv(&argvars[0]); 9309 --emsg_off; 9310 9311 lnum = get_tv_lnum_buf(&argvars[1], buf); 9312 if (argvars[2].v_type == VAR_UNKNOWN) 9313 end = lnum; 9314 else 9315 end = get_tv_lnum_buf(&argvars[2], buf); 9316 9317 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9318 } 9319 9320 /* 9321 * "getbufvar()" function 9322 */ 9323 static void 9324 f_getbufvar(argvars, rettv) 9325 typval_T *argvars; 9326 typval_T *rettv; 9327 { 9328 buf_T *buf; 9329 buf_T *save_curbuf; 9330 char_u *varname; 9331 dictitem_T *v; 9332 9333 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9334 varname = get_tv_string_chk(&argvars[1]); 9335 ++emsg_off; 9336 buf = get_buf_tv(&argvars[0]); 9337 9338 rettv->v_type = VAR_STRING; 9339 rettv->vval.v_string = NULL; 9340 9341 if (buf != NULL && varname != NULL) 9342 { 9343 if (*varname == '&') /* buffer-local-option */ 9344 { 9345 /* set curbuf to be our buf, temporarily */ 9346 save_curbuf = curbuf; 9347 curbuf = buf; 9348 9349 get_option_tv(&varname, rettv, TRUE); 9350 9351 /* restore previous notion of curbuf */ 9352 curbuf = save_curbuf; 9353 } 9354 else 9355 { 9356 if (*varname == NUL) 9357 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9358 * scope prefix before the NUL byte is required by 9359 * find_var_in_ht(). */ 9360 varname = (char_u *)"b:" + 2; 9361 /* look up the variable */ 9362 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9363 if (v != NULL) 9364 copy_tv(&v->di_tv, rettv); 9365 } 9366 } 9367 9368 --emsg_off; 9369 } 9370 9371 /* 9372 * "getchar()" function 9373 */ 9374 static void 9375 f_getchar(argvars, rettv) 9376 typval_T *argvars; 9377 typval_T *rettv; 9378 { 9379 varnumber_T n; 9380 int error = FALSE; 9381 9382 ++no_mapping; 9383 ++allow_keys; 9384 if (argvars[0].v_type == VAR_UNKNOWN) 9385 /* getchar(): blocking wait. */ 9386 n = safe_vgetc(); 9387 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9388 /* getchar(1): only check if char avail */ 9389 n = vpeekc(); 9390 else if (error || vpeekc() == NUL) 9391 /* illegal argument or getchar(0) and no char avail: return zero */ 9392 n = 0; 9393 else 9394 /* getchar(0) and char avail: return char */ 9395 n = safe_vgetc(); 9396 --no_mapping; 9397 --allow_keys; 9398 9399 rettv->vval.v_number = n; 9400 if (IS_SPECIAL(n) || mod_mask != 0) 9401 { 9402 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9403 int i = 0; 9404 9405 /* Turn a special key into three bytes, plus modifier. */ 9406 if (mod_mask != 0) 9407 { 9408 temp[i++] = K_SPECIAL; 9409 temp[i++] = KS_MODIFIER; 9410 temp[i++] = mod_mask; 9411 } 9412 if (IS_SPECIAL(n)) 9413 { 9414 temp[i++] = K_SPECIAL; 9415 temp[i++] = K_SECOND(n); 9416 temp[i++] = K_THIRD(n); 9417 } 9418 #ifdef FEAT_MBYTE 9419 else if (has_mbyte) 9420 i += (*mb_char2bytes)(n, temp + i); 9421 #endif 9422 else 9423 temp[i++] = n; 9424 temp[i++] = NUL; 9425 rettv->v_type = VAR_STRING; 9426 rettv->vval.v_string = vim_strsave(temp); 9427 } 9428 } 9429 9430 /* 9431 * "getcharmod()" function 9432 */ 9433 /*ARGSUSED*/ 9434 static void 9435 f_getcharmod(argvars, rettv) 9436 typval_T *argvars; 9437 typval_T *rettv; 9438 { 9439 rettv->vval.v_number = mod_mask; 9440 } 9441 9442 /* 9443 * "getcmdline()" function 9444 */ 9445 /*ARGSUSED*/ 9446 static void 9447 f_getcmdline(argvars, rettv) 9448 typval_T *argvars; 9449 typval_T *rettv; 9450 { 9451 rettv->v_type = VAR_STRING; 9452 rettv->vval.v_string = get_cmdline_str(); 9453 } 9454 9455 /* 9456 * "getcmdpos()" function 9457 */ 9458 /*ARGSUSED*/ 9459 static void 9460 f_getcmdpos(argvars, rettv) 9461 typval_T *argvars; 9462 typval_T *rettv; 9463 { 9464 rettv->vval.v_number = get_cmdline_pos() + 1; 9465 } 9466 9467 /* 9468 * "getcmdtype()" function 9469 */ 9470 /*ARGSUSED*/ 9471 static void 9472 f_getcmdtype(argvars, rettv) 9473 typval_T *argvars; 9474 typval_T *rettv; 9475 { 9476 rettv->v_type = VAR_STRING; 9477 rettv->vval.v_string = alloc(2); 9478 if (rettv->vval.v_string != NULL) 9479 { 9480 rettv->vval.v_string[0] = get_cmdline_type(); 9481 rettv->vval.v_string[1] = NUL; 9482 } 9483 } 9484 9485 /* 9486 * "getcwd()" function 9487 */ 9488 /*ARGSUSED*/ 9489 static void 9490 f_getcwd(argvars, rettv) 9491 typval_T *argvars; 9492 typval_T *rettv; 9493 { 9494 char_u cwd[MAXPATHL]; 9495 9496 rettv->v_type = VAR_STRING; 9497 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9498 rettv->vval.v_string = NULL; 9499 else 9500 { 9501 rettv->vval.v_string = vim_strsave(cwd); 9502 #ifdef BACKSLASH_IN_FILENAME 9503 if (rettv->vval.v_string != NULL) 9504 slash_adjust(rettv->vval.v_string); 9505 #endif 9506 } 9507 } 9508 9509 /* 9510 * "getfontname()" function 9511 */ 9512 /*ARGSUSED*/ 9513 static void 9514 f_getfontname(argvars, rettv) 9515 typval_T *argvars; 9516 typval_T *rettv; 9517 { 9518 rettv->v_type = VAR_STRING; 9519 rettv->vval.v_string = NULL; 9520 #ifdef FEAT_GUI 9521 if (gui.in_use) 9522 { 9523 GuiFont font; 9524 char_u *name = NULL; 9525 9526 if (argvars[0].v_type == VAR_UNKNOWN) 9527 { 9528 /* Get the "Normal" font. Either the name saved by 9529 * hl_set_font_name() or from the font ID. */ 9530 font = gui.norm_font; 9531 name = hl_get_font_name(); 9532 } 9533 else 9534 { 9535 name = get_tv_string(&argvars[0]); 9536 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9537 return; 9538 font = gui_mch_get_font(name, FALSE); 9539 if (font == NOFONT) 9540 return; /* Invalid font name, return empty string. */ 9541 } 9542 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9543 if (argvars[0].v_type != VAR_UNKNOWN) 9544 gui_mch_free_font(font); 9545 } 9546 #endif 9547 } 9548 9549 /* 9550 * "getfperm({fname})" function 9551 */ 9552 static void 9553 f_getfperm(argvars, rettv) 9554 typval_T *argvars; 9555 typval_T *rettv; 9556 { 9557 char_u *fname; 9558 struct stat st; 9559 char_u *perm = NULL; 9560 char_u flags[] = "rwx"; 9561 int i; 9562 9563 fname = get_tv_string(&argvars[0]); 9564 9565 rettv->v_type = VAR_STRING; 9566 if (mch_stat((char *)fname, &st) >= 0) 9567 { 9568 perm = vim_strsave((char_u *)"---------"); 9569 if (perm != NULL) 9570 { 9571 for (i = 0; i < 9; i++) 9572 { 9573 if (st.st_mode & (1 << (8 - i))) 9574 perm[i] = flags[i % 3]; 9575 } 9576 } 9577 } 9578 rettv->vval.v_string = perm; 9579 } 9580 9581 /* 9582 * "getfsize({fname})" function 9583 */ 9584 static void 9585 f_getfsize(argvars, rettv) 9586 typval_T *argvars; 9587 typval_T *rettv; 9588 { 9589 char_u *fname; 9590 struct stat st; 9591 9592 fname = get_tv_string(&argvars[0]); 9593 9594 rettv->v_type = VAR_NUMBER; 9595 9596 if (mch_stat((char *)fname, &st) >= 0) 9597 { 9598 if (mch_isdir(fname)) 9599 rettv->vval.v_number = 0; 9600 else 9601 rettv->vval.v_number = (varnumber_T)st.st_size; 9602 } 9603 else 9604 rettv->vval.v_number = -1; 9605 } 9606 9607 /* 9608 * "getftime({fname})" function 9609 */ 9610 static void 9611 f_getftime(argvars, rettv) 9612 typval_T *argvars; 9613 typval_T *rettv; 9614 { 9615 char_u *fname; 9616 struct stat st; 9617 9618 fname = get_tv_string(&argvars[0]); 9619 9620 if (mch_stat((char *)fname, &st) >= 0) 9621 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9622 else 9623 rettv->vval.v_number = -1; 9624 } 9625 9626 /* 9627 * "getftype({fname})" function 9628 */ 9629 static void 9630 f_getftype(argvars, rettv) 9631 typval_T *argvars; 9632 typval_T *rettv; 9633 { 9634 char_u *fname; 9635 struct stat st; 9636 char_u *type = NULL; 9637 char *t; 9638 9639 fname = get_tv_string(&argvars[0]); 9640 9641 rettv->v_type = VAR_STRING; 9642 if (mch_lstat((char *)fname, &st) >= 0) 9643 { 9644 #ifdef S_ISREG 9645 if (S_ISREG(st.st_mode)) 9646 t = "file"; 9647 else if (S_ISDIR(st.st_mode)) 9648 t = "dir"; 9649 # ifdef S_ISLNK 9650 else if (S_ISLNK(st.st_mode)) 9651 t = "link"; 9652 # endif 9653 # ifdef S_ISBLK 9654 else if (S_ISBLK(st.st_mode)) 9655 t = "bdev"; 9656 # endif 9657 # ifdef S_ISCHR 9658 else if (S_ISCHR(st.st_mode)) 9659 t = "cdev"; 9660 # endif 9661 # ifdef S_ISFIFO 9662 else if (S_ISFIFO(st.st_mode)) 9663 t = "fifo"; 9664 # endif 9665 # ifdef S_ISSOCK 9666 else if (S_ISSOCK(st.st_mode)) 9667 t = "fifo"; 9668 # endif 9669 else 9670 t = "other"; 9671 #else 9672 # ifdef S_IFMT 9673 switch (st.st_mode & S_IFMT) 9674 { 9675 case S_IFREG: t = "file"; break; 9676 case S_IFDIR: t = "dir"; break; 9677 # ifdef S_IFLNK 9678 case S_IFLNK: t = "link"; break; 9679 # endif 9680 # ifdef S_IFBLK 9681 case S_IFBLK: t = "bdev"; break; 9682 # endif 9683 # ifdef S_IFCHR 9684 case S_IFCHR: t = "cdev"; break; 9685 # endif 9686 # ifdef S_IFIFO 9687 case S_IFIFO: t = "fifo"; break; 9688 # endif 9689 # ifdef S_IFSOCK 9690 case S_IFSOCK: t = "socket"; break; 9691 # endif 9692 default: t = "other"; 9693 } 9694 # else 9695 if (mch_isdir(fname)) 9696 t = "dir"; 9697 else 9698 t = "file"; 9699 # endif 9700 #endif 9701 type = vim_strsave((char_u *)t); 9702 } 9703 rettv->vval.v_string = type; 9704 } 9705 9706 /* 9707 * "getline(lnum, [end])" function 9708 */ 9709 static void 9710 f_getline(argvars, rettv) 9711 typval_T *argvars; 9712 typval_T *rettv; 9713 { 9714 linenr_T lnum; 9715 linenr_T end; 9716 int retlist; 9717 9718 lnum = get_tv_lnum(argvars); 9719 if (argvars[1].v_type == VAR_UNKNOWN) 9720 { 9721 end = 0; 9722 retlist = FALSE; 9723 } 9724 else 9725 { 9726 end = get_tv_lnum(&argvars[1]); 9727 retlist = TRUE; 9728 } 9729 9730 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9731 } 9732 9733 /* 9734 * "getqflist()" function 9735 */ 9736 /*ARGSUSED*/ 9737 static void 9738 f_getqflist(argvars, rettv) 9739 typval_T *argvars; 9740 typval_T *rettv; 9741 { 9742 #ifdef FEAT_QUICKFIX 9743 list_T *l; 9744 #endif 9745 9746 rettv->vval.v_number = FALSE; 9747 #ifdef FEAT_QUICKFIX 9748 l = list_alloc(); 9749 if (l != NULL) 9750 { 9751 rettv->vval.v_list = l; 9752 rettv->v_type = VAR_LIST; 9753 ++l->lv_refcount; 9754 (void)get_errorlist(l); 9755 } 9756 #endif 9757 } 9758 9759 /* 9760 * "getreg()" function 9761 */ 9762 static void 9763 f_getreg(argvars, rettv) 9764 typval_T *argvars; 9765 typval_T *rettv; 9766 { 9767 char_u *strregname; 9768 int regname; 9769 int arg2 = FALSE; 9770 int error = FALSE; 9771 9772 if (argvars[0].v_type != VAR_UNKNOWN) 9773 { 9774 strregname = get_tv_string_chk(&argvars[0]); 9775 error = strregname == NULL; 9776 if (argvars[1].v_type != VAR_UNKNOWN) 9777 arg2 = get_tv_number_chk(&argvars[1], &error); 9778 } 9779 else 9780 strregname = vimvars[VV_REG].vv_str; 9781 regname = (strregname == NULL ? '"' : *strregname); 9782 if (regname == 0) 9783 regname = '"'; 9784 9785 rettv->v_type = VAR_STRING; 9786 rettv->vval.v_string = error ? NULL : 9787 get_reg_contents(regname, TRUE, arg2); 9788 } 9789 9790 /* 9791 * "getregtype()" function 9792 */ 9793 static void 9794 f_getregtype(argvars, rettv) 9795 typval_T *argvars; 9796 typval_T *rettv; 9797 { 9798 char_u *strregname; 9799 int regname; 9800 char_u buf[NUMBUFLEN + 2]; 9801 long reglen = 0; 9802 9803 if (argvars[0].v_type != VAR_UNKNOWN) 9804 { 9805 strregname = get_tv_string_chk(&argvars[0]); 9806 if (strregname == NULL) /* type error; errmsg already given */ 9807 { 9808 rettv->v_type = VAR_STRING; 9809 rettv->vval.v_string = NULL; 9810 return; 9811 } 9812 } 9813 else 9814 /* Default to v:register */ 9815 strregname = vimvars[VV_REG].vv_str; 9816 9817 regname = (strregname == NULL ? '"' : *strregname); 9818 if (regname == 0) 9819 regname = '"'; 9820 9821 buf[0] = NUL; 9822 buf[1] = NUL; 9823 switch (get_reg_type(regname, ®len)) 9824 { 9825 case MLINE: buf[0] = 'V'; break; 9826 case MCHAR: buf[0] = 'v'; break; 9827 #ifdef FEAT_VISUAL 9828 case MBLOCK: 9829 buf[0] = Ctrl_V; 9830 sprintf((char *)buf + 1, "%ld", reglen + 1); 9831 break; 9832 #endif 9833 } 9834 rettv->v_type = VAR_STRING; 9835 rettv->vval.v_string = vim_strsave(buf); 9836 } 9837 9838 /* 9839 * "getwinposx()" function 9840 */ 9841 /*ARGSUSED*/ 9842 static void 9843 f_getwinposx(argvars, rettv) 9844 typval_T *argvars; 9845 typval_T *rettv; 9846 { 9847 rettv->vval.v_number = -1; 9848 #ifdef FEAT_GUI 9849 if (gui.in_use) 9850 { 9851 int x, y; 9852 9853 if (gui_mch_get_winpos(&x, &y) == OK) 9854 rettv->vval.v_number = x; 9855 } 9856 #endif 9857 } 9858 9859 /* 9860 * "getwinposy()" function 9861 */ 9862 /*ARGSUSED*/ 9863 static void 9864 f_getwinposy(argvars, rettv) 9865 typval_T *argvars; 9866 typval_T *rettv; 9867 { 9868 rettv->vval.v_number = -1; 9869 #ifdef FEAT_GUI 9870 if (gui.in_use) 9871 { 9872 int x, y; 9873 9874 if (gui_mch_get_winpos(&x, &y) == OK) 9875 rettv->vval.v_number = y; 9876 } 9877 #endif 9878 } 9879 9880 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9881 9882 static win_T * 9883 find_win_by_nr(vp) 9884 typval_T *vp; 9885 { 9886 #ifdef FEAT_WINDOWS 9887 win_T *wp; 9888 #endif 9889 int nr; 9890 9891 nr = get_tv_number_chk(vp, NULL); 9892 9893 #ifdef FEAT_WINDOWS 9894 if (nr < 0) 9895 return NULL; 9896 if (nr == 0) 9897 return curwin; 9898 9899 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9900 if (--nr <= 0) 9901 break; 9902 return wp; 9903 #else 9904 if (nr == 0 || nr == 1) 9905 return curwin; 9906 return NULL; 9907 #endif 9908 } 9909 9910 /* 9911 * "getwinvar()" function 9912 */ 9913 static void 9914 f_getwinvar(argvars, rettv) 9915 typval_T *argvars; 9916 typval_T *rettv; 9917 { 9918 win_T *win, *oldcurwin; 9919 char_u *varname; 9920 dictitem_T *v; 9921 9922 win = find_win_by_nr(&argvars[0]); 9923 varname = get_tv_string_chk(&argvars[1]); 9924 ++emsg_off; 9925 9926 rettv->v_type = VAR_STRING; 9927 rettv->vval.v_string = NULL; 9928 9929 if (win != NULL && varname != NULL) 9930 { 9931 if (*varname == '&') /* window-local-option */ 9932 { 9933 /* Set curwin to be our win, temporarily. Also set curbuf, so 9934 * that we can get buffer-local options. */ 9935 oldcurwin = curwin; 9936 curwin = win; 9937 curbuf = win->w_buffer; 9938 9939 get_option_tv(&varname, rettv, 1); 9940 9941 /* restore previous notion of curwin */ 9942 curwin = oldcurwin; 9943 curbuf = curwin->w_buffer; 9944 } 9945 else 9946 { 9947 if (*varname == NUL) 9948 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9949 * scope prefix before the NUL byte is required by 9950 * find_var_in_ht(). */ 9951 varname = (char_u *)"w:" + 2; 9952 /* look up the variable */ 9953 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9954 if (v != NULL) 9955 copy_tv(&v->di_tv, rettv); 9956 } 9957 } 9958 9959 --emsg_off; 9960 } 9961 9962 /* 9963 * "glob()" function 9964 */ 9965 static void 9966 f_glob(argvars, rettv) 9967 typval_T *argvars; 9968 typval_T *rettv; 9969 { 9970 expand_T xpc; 9971 9972 ExpandInit(&xpc); 9973 xpc.xp_context = EXPAND_FILES; 9974 rettv->v_type = VAR_STRING; 9975 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9976 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9977 ExpandCleanup(&xpc); 9978 } 9979 9980 /* 9981 * "globpath()" function 9982 */ 9983 static void 9984 f_globpath(argvars, rettv) 9985 typval_T *argvars; 9986 typval_T *rettv; 9987 { 9988 char_u buf1[NUMBUFLEN]; 9989 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9990 9991 rettv->v_type = VAR_STRING; 9992 if (file == NULL) 9993 rettv->vval.v_string = NULL; 9994 else 9995 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9996 } 9997 9998 /* 9999 * "has()" function 10000 */ 10001 static void 10002 f_has(argvars, rettv) 10003 typval_T *argvars; 10004 typval_T *rettv; 10005 { 10006 int i; 10007 char_u *name; 10008 int n = FALSE; 10009 static char *(has_list[]) = 10010 { 10011 #ifdef AMIGA 10012 "amiga", 10013 # ifdef FEAT_ARP 10014 "arp", 10015 # endif 10016 #endif 10017 #ifdef __BEOS__ 10018 "beos", 10019 #endif 10020 #ifdef MSDOS 10021 # ifdef DJGPP 10022 "dos32", 10023 # else 10024 "dos16", 10025 # endif 10026 #endif 10027 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 10028 "mac", 10029 #endif 10030 #if defined(MACOS_X_UNIX) 10031 "macunix", 10032 #endif 10033 #ifdef OS2 10034 "os2", 10035 #endif 10036 #ifdef __QNX__ 10037 "qnx", 10038 #endif 10039 #ifdef RISCOS 10040 "riscos", 10041 #endif 10042 #ifdef UNIX 10043 "unix", 10044 #endif 10045 #ifdef VMS 10046 "vms", 10047 #endif 10048 #ifdef WIN16 10049 "win16", 10050 #endif 10051 #ifdef WIN32 10052 "win32", 10053 #endif 10054 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10055 "win32unix", 10056 #endif 10057 #ifdef WIN64 10058 "win64", 10059 #endif 10060 #ifdef EBCDIC 10061 "ebcdic", 10062 #endif 10063 #ifndef CASE_INSENSITIVE_FILENAME 10064 "fname_case", 10065 #endif 10066 #ifdef FEAT_ARABIC 10067 "arabic", 10068 #endif 10069 #ifdef FEAT_AUTOCMD 10070 "autocmd", 10071 #endif 10072 #ifdef FEAT_BEVAL 10073 "balloon_eval", 10074 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10075 "balloon_multiline", 10076 # endif 10077 #endif 10078 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10079 "builtin_terms", 10080 # ifdef ALL_BUILTIN_TCAPS 10081 "all_builtin_terms", 10082 # endif 10083 #endif 10084 #ifdef FEAT_BYTEOFF 10085 "byte_offset", 10086 #endif 10087 #ifdef FEAT_CINDENT 10088 "cindent", 10089 #endif 10090 #ifdef FEAT_CLIENTSERVER 10091 "clientserver", 10092 #endif 10093 #ifdef FEAT_CLIPBOARD 10094 "clipboard", 10095 #endif 10096 #ifdef FEAT_CMDL_COMPL 10097 "cmdline_compl", 10098 #endif 10099 #ifdef FEAT_CMDHIST 10100 "cmdline_hist", 10101 #endif 10102 #ifdef FEAT_COMMENTS 10103 "comments", 10104 #endif 10105 #ifdef FEAT_CRYPT 10106 "cryptv", 10107 #endif 10108 #ifdef FEAT_CSCOPE 10109 "cscope", 10110 #endif 10111 #ifdef CURSOR_SHAPE 10112 "cursorshape", 10113 #endif 10114 #ifdef DEBUG 10115 "debug", 10116 #endif 10117 #ifdef FEAT_CON_DIALOG 10118 "dialog_con", 10119 #endif 10120 #ifdef FEAT_GUI_DIALOG 10121 "dialog_gui", 10122 #endif 10123 #ifdef FEAT_DIFF 10124 "diff", 10125 #endif 10126 #ifdef FEAT_DIGRAPHS 10127 "digraphs", 10128 #endif 10129 #ifdef FEAT_DND 10130 "dnd", 10131 #endif 10132 #ifdef FEAT_EMACS_TAGS 10133 "emacs_tags", 10134 #endif 10135 "eval", /* always present, of course! */ 10136 #ifdef FEAT_EX_EXTRA 10137 "ex_extra", 10138 #endif 10139 #ifdef FEAT_SEARCH_EXTRA 10140 "extra_search", 10141 #endif 10142 #ifdef FEAT_FKMAP 10143 "farsi", 10144 #endif 10145 #ifdef FEAT_SEARCHPATH 10146 "file_in_path", 10147 #endif 10148 #if defined(UNIX) && !defined(USE_SYSTEM) 10149 "filterpipe", 10150 #endif 10151 #ifdef FEAT_FIND_ID 10152 "find_in_path", 10153 #endif 10154 #ifdef FEAT_FOLDING 10155 "folding", 10156 #endif 10157 #ifdef FEAT_FOOTER 10158 "footer", 10159 #endif 10160 #if !defined(USE_SYSTEM) && defined(UNIX) 10161 "fork", 10162 #endif 10163 #ifdef FEAT_GETTEXT 10164 "gettext", 10165 #endif 10166 #ifdef FEAT_GUI 10167 "gui", 10168 #endif 10169 #ifdef FEAT_GUI_ATHENA 10170 # ifdef FEAT_GUI_NEXTAW 10171 "gui_neXtaw", 10172 # else 10173 "gui_athena", 10174 # endif 10175 #endif 10176 #ifdef FEAT_GUI_KDE 10177 "gui_kde", 10178 #endif 10179 #ifdef FEAT_GUI_GTK 10180 "gui_gtk", 10181 # ifdef HAVE_GTK2 10182 "gui_gtk2", 10183 # endif 10184 #endif 10185 #ifdef FEAT_GUI_MAC 10186 "gui_mac", 10187 #endif 10188 #ifdef FEAT_GUI_MOTIF 10189 "gui_motif", 10190 #endif 10191 #ifdef FEAT_GUI_PHOTON 10192 "gui_photon", 10193 #endif 10194 #ifdef FEAT_GUI_W16 10195 "gui_win16", 10196 #endif 10197 #ifdef FEAT_GUI_W32 10198 "gui_win32", 10199 #endif 10200 #ifdef FEAT_HANGULIN 10201 "hangul_input", 10202 #endif 10203 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10204 "iconv", 10205 #endif 10206 #ifdef FEAT_INS_EXPAND 10207 "insert_expand", 10208 #endif 10209 #ifdef FEAT_JUMPLIST 10210 "jumplist", 10211 #endif 10212 #ifdef FEAT_KEYMAP 10213 "keymap", 10214 #endif 10215 #ifdef FEAT_LANGMAP 10216 "langmap", 10217 #endif 10218 #ifdef FEAT_LIBCALL 10219 "libcall", 10220 #endif 10221 #ifdef FEAT_LINEBREAK 10222 "linebreak", 10223 #endif 10224 #ifdef FEAT_LISP 10225 "lispindent", 10226 #endif 10227 #ifdef FEAT_LISTCMDS 10228 "listcmds", 10229 #endif 10230 #ifdef FEAT_LOCALMAP 10231 "localmap", 10232 #endif 10233 #ifdef FEAT_MENU 10234 "menu", 10235 #endif 10236 #ifdef FEAT_SESSION 10237 "mksession", 10238 #endif 10239 #ifdef FEAT_MODIFY_FNAME 10240 "modify_fname", 10241 #endif 10242 #ifdef FEAT_MOUSE 10243 "mouse", 10244 #endif 10245 #ifdef FEAT_MOUSESHAPE 10246 "mouseshape", 10247 #endif 10248 #if defined(UNIX) || defined(VMS) 10249 # ifdef FEAT_MOUSE_DEC 10250 "mouse_dec", 10251 # endif 10252 # ifdef FEAT_MOUSE_GPM 10253 "mouse_gpm", 10254 # endif 10255 # ifdef FEAT_MOUSE_JSB 10256 "mouse_jsbterm", 10257 # endif 10258 # ifdef FEAT_MOUSE_NET 10259 "mouse_netterm", 10260 # endif 10261 # ifdef FEAT_MOUSE_PTERM 10262 "mouse_pterm", 10263 # endif 10264 # ifdef FEAT_MOUSE_XTERM 10265 "mouse_xterm", 10266 # endif 10267 #endif 10268 #ifdef FEAT_MBYTE 10269 "multi_byte", 10270 #endif 10271 #ifdef FEAT_MBYTE_IME 10272 "multi_byte_ime", 10273 #endif 10274 #ifdef FEAT_MULTI_LANG 10275 "multi_lang", 10276 #endif 10277 #ifdef FEAT_MZSCHEME 10278 #ifndef DYNAMIC_MZSCHEME 10279 "mzscheme", 10280 #endif 10281 #endif 10282 #ifdef FEAT_OLE 10283 "ole", 10284 #endif 10285 #ifdef FEAT_OSFILETYPE 10286 "osfiletype", 10287 #endif 10288 #ifdef FEAT_PATH_EXTRA 10289 "path_extra", 10290 #endif 10291 #ifdef FEAT_PERL 10292 #ifndef DYNAMIC_PERL 10293 "perl", 10294 #endif 10295 #endif 10296 #ifdef FEAT_PYTHON 10297 #ifndef DYNAMIC_PYTHON 10298 "python", 10299 #endif 10300 #endif 10301 #ifdef FEAT_POSTSCRIPT 10302 "postscript", 10303 #endif 10304 #ifdef FEAT_PRINTER 10305 "printer", 10306 #endif 10307 #ifdef FEAT_PROFILE 10308 "profile", 10309 #endif 10310 #ifdef FEAT_QUICKFIX 10311 "quickfix", 10312 #endif 10313 #ifdef FEAT_RIGHTLEFT 10314 "rightleft", 10315 #endif 10316 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10317 "ruby", 10318 #endif 10319 #ifdef FEAT_SCROLLBIND 10320 "scrollbind", 10321 #endif 10322 #ifdef FEAT_CMDL_INFO 10323 "showcmd", 10324 "cmdline_info", 10325 #endif 10326 #ifdef FEAT_SIGNS 10327 "signs", 10328 #endif 10329 #ifdef FEAT_SMARTINDENT 10330 "smartindent", 10331 #endif 10332 #ifdef FEAT_SNIFF 10333 "sniff", 10334 #endif 10335 #ifdef FEAT_STL_OPT 10336 "statusline", 10337 #endif 10338 #ifdef FEAT_SUN_WORKSHOP 10339 "sun_workshop", 10340 #endif 10341 #ifdef FEAT_NETBEANS_INTG 10342 "netbeans_intg", 10343 #endif 10344 #ifdef FEAT_SYN_HL 10345 "spell", 10346 #endif 10347 #ifdef FEAT_SYN_HL 10348 "syntax", 10349 #endif 10350 #if defined(USE_SYSTEM) || !defined(UNIX) 10351 "system", 10352 #endif 10353 #ifdef FEAT_TAG_BINS 10354 "tag_binary", 10355 #endif 10356 #ifdef FEAT_TAG_OLDSTATIC 10357 "tag_old_static", 10358 #endif 10359 #ifdef FEAT_TAG_ANYWHITE 10360 "tag_any_white", 10361 #endif 10362 #ifdef FEAT_TCL 10363 # ifndef DYNAMIC_TCL 10364 "tcl", 10365 # endif 10366 #endif 10367 #ifdef TERMINFO 10368 "terminfo", 10369 #endif 10370 #ifdef FEAT_TERMRESPONSE 10371 "termresponse", 10372 #endif 10373 #ifdef FEAT_TEXTOBJ 10374 "textobjects", 10375 #endif 10376 #ifdef HAVE_TGETENT 10377 "tgetent", 10378 #endif 10379 #ifdef FEAT_TITLE 10380 "title", 10381 #endif 10382 #ifdef FEAT_TOOLBAR 10383 "toolbar", 10384 #endif 10385 #ifdef FEAT_USR_CMDS 10386 "user-commands", /* was accidentally included in 5.4 */ 10387 "user_commands", 10388 #endif 10389 #ifdef FEAT_VIMINFO 10390 "viminfo", 10391 #endif 10392 #ifdef FEAT_VERTSPLIT 10393 "vertsplit", 10394 #endif 10395 #ifdef FEAT_VIRTUALEDIT 10396 "virtualedit", 10397 #endif 10398 #ifdef FEAT_VISUAL 10399 "visual", 10400 #endif 10401 #ifdef FEAT_VISUALEXTRA 10402 "visualextra", 10403 #endif 10404 #ifdef FEAT_VREPLACE 10405 "vreplace", 10406 #endif 10407 #ifdef FEAT_WILDIGN 10408 "wildignore", 10409 #endif 10410 #ifdef FEAT_WILDMENU 10411 "wildmenu", 10412 #endif 10413 #ifdef FEAT_WINDOWS 10414 "windows", 10415 #endif 10416 #ifdef FEAT_WAK 10417 "winaltkeys", 10418 #endif 10419 #ifdef FEAT_WRITEBACKUP 10420 "writebackup", 10421 #endif 10422 #ifdef FEAT_XIM 10423 "xim", 10424 #endif 10425 #ifdef FEAT_XFONTSET 10426 "xfontset", 10427 #endif 10428 #ifdef USE_XSMP 10429 "xsmp", 10430 #endif 10431 #ifdef USE_XSMP_INTERACT 10432 "xsmp_interact", 10433 #endif 10434 #ifdef FEAT_XCLIPBOARD 10435 "xterm_clipboard", 10436 #endif 10437 #ifdef FEAT_XTERM_SAVE 10438 "xterm_save", 10439 #endif 10440 #if defined(UNIX) && defined(FEAT_X11) 10441 "X11", 10442 #endif 10443 NULL 10444 }; 10445 10446 name = get_tv_string(&argvars[0]); 10447 for (i = 0; has_list[i] != NULL; ++i) 10448 if (STRICMP(name, has_list[i]) == 0) 10449 { 10450 n = TRUE; 10451 break; 10452 } 10453 10454 if (n == FALSE) 10455 { 10456 if (STRNICMP(name, "patch", 5) == 0) 10457 n = has_patch(atoi((char *)name + 5)); 10458 else if (STRICMP(name, "vim_starting") == 0) 10459 n = (starting != 0); 10460 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10461 else if (STRICMP(name, "balloon_multiline") == 0) 10462 n = multiline_balloon_available(); 10463 #endif 10464 #ifdef DYNAMIC_TCL 10465 else if (STRICMP(name, "tcl") == 0) 10466 n = tcl_enabled(FALSE); 10467 #endif 10468 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10469 else if (STRICMP(name, "iconv") == 0) 10470 n = iconv_enabled(FALSE); 10471 #endif 10472 #ifdef DYNAMIC_MZSCHEME 10473 else if (STRICMP(name, "mzscheme") == 0) 10474 n = mzscheme_enabled(FALSE); 10475 #endif 10476 #ifdef DYNAMIC_RUBY 10477 else if (STRICMP(name, "ruby") == 0) 10478 n = ruby_enabled(FALSE); 10479 #endif 10480 #ifdef DYNAMIC_PYTHON 10481 else if (STRICMP(name, "python") == 0) 10482 n = python_enabled(FALSE); 10483 #endif 10484 #ifdef DYNAMIC_PERL 10485 else if (STRICMP(name, "perl") == 0) 10486 n = perl_enabled(FALSE); 10487 #endif 10488 #ifdef FEAT_GUI 10489 else if (STRICMP(name, "gui_running") == 0) 10490 n = (gui.in_use || gui.starting); 10491 # ifdef FEAT_GUI_W32 10492 else if (STRICMP(name, "gui_win32s") == 0) 10493 n = gui_is_win32s(); 10494 # endif 10495 # ifdef FEAT_BROWSE 10496 else if (STRICMP(name, "browse") == 0) 10497 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10498 # endif 10499 #endif 10500 #ifdef FEAT_SYN_HL 10501 else if (STRICMP(name, "syntax_items") == 0) 10502 n = syntax_present(curbuf); 10503 #endif 10504 #if defined(WIN3264) 10505 else if (STRICMP(name, "win95") == 0) 10506 n = mch_windows95(); 10507 #endif 10508 #ifdef FEAT_NETBEANS_INTG 10509 else if (STRICMP(name, "netbeans_enabled") == 0) 10510 n = usingNetbeans; 10511 #endif 10512 } 10513 10514 rettv->vval.v_number = n; 10515 } 10516 10517 /* 10518 * "has_key()" function 10519 */ 10520 static void 10521 f_has_key(argvars, rettv) 10522 typval_T *argvars; 10523 typval_T *rettv; 10524 { 10525 rettv->vval.v_number = 0; 10526 if (argvars[0].v_type != VAR_DICT) 10527 { 10528 EMSG(_(e_dictreq)); 10529 return; 10530 } 10531 if (argvars[0].vval.v_dict == NULL) 10532 return; 10533 10534 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10535 get_tv_string(&argvars[1]), -1) != NULL; 10536 } 10537 10538 /* 10539 * "hasmapto()" function 10540 */ 10541 static void 10542 f_hasmapto(argvars, rettv) 10543 typval_T *argvars; 10544 typval_T *rettv; 10545 { 10546 char_u *name; 10547 char_u *mode; 10548 char_u buf[NUMBUFLEN]; 10549 10550 name = get_tv_string(&argvars[0]); 10551 if (argvars[1].v_type == VAR_UNKNOWN) 10552 mode = (char_u *)"nvo"; 10553 else 10554 mode = get_tv_string_buf(&argvars[1], buf); 10555 10556 if (map_to_exists(name, mode)) 10557 rettv->vval.v_number = TRUE; 10558 else 10559 rettv->vval.v_number = FALSE; 10560 } 10561 10562 /* 10563 * "histadd()" function 10564 */ 10565 /*ARGSUSED*/ 10566 static void 10567 f_histadd(argvars, rettv) 10568 typval_T *argvars; 10569 typval_T *rettv; 10570 { 10571 #ifdef FEAT_CMDHIST 10572 int histype; 10573 char_u *str; 10574 char_u buf[NUMBUFLEN]; 10575 #endif 10576 10577 rettv->vval.v_number = FALSE; 10578 if (check_restricted() || check_secure()) 10579 return; 10580 #ifdef FEAT_CMDHIST 10581 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10582 histype = str != NULL ? get_histtype(str) : -1; 10583 if (histype >= 0) 10584 { 10585 str = get_tv_string_buf(&argvars[1], buf); 10586 if (*str != NUL) 10587 { 10588 add_to_history(histype, str, FALSE, NUL); 10589 rettv->vval.v_number = TRUE; 10590 return; 10591 } 10592 } 10593 #endif 10594 } 10595 10596 /* 10597 * "histdel()" function 10598 */ 10599 /*ARGSUSED*/ 10600 static void 10601 f_histdel(argvars, rettv) 10602 typval_T *argvars; 10603 typval_T *rettv; 10604 { 10605 #ifdef FEAT_CMDHIST 10606 int n; 10607 char_u buf[NUMBUFLEN]; 10608 char_u *str; 10609 10610 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10611 if (str == NULL) 10612 n = 0; 10613 else if (argvars[1].v_type == VAR_UNKNOWN) 10614 /* only one argument: clear entire history */ 10615 n = clr_history(get_histtype(str)); 10616 else if (argvars[1].v_type == VAR_NUMBER) 10617 /* index given: remove that entry */ 10618 n = del_history_idx(get_histtype(str), 10619 (int)get_tv_number(&argvars[1])); 10620 else 10621 /* string given: remove all matching entries */ 10622 n = del_history_entry(get_histtype(str), 10623 get_tv_string_buf(&argvars[1], buf)); 10624 rettv->vval.v_number = n; 10625 #else 10626 rettv->vval.v_number = 0; 10627 #endif 10628 } 10629 10630 /* 10631 * "histget()" function 10632 */ 10633 /*ARGSUSED*/ 10634 static void 10635 f_histget(argvars, rettv) 10636 typval_T *argvars; 10637 typval_T *rettv; 10638 { 10639 #ifdef FEAT_CMDHIST 10640 int type; 10641 int idx; 10642 char_u *str; 10643 10644 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10645 if (str == NULL) 10646 rettv->vval.v_string = NULL; 10647 else 10648 { 10649 type = get_histtype(str); 10650 if (argvars[1].v_type == VAR_UNKNOWN) 10651 idx = get_history_idx(type); 10652 else 10653 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10654 /* -1 on type error */ 10655 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10656 } 10657 #else 10658 rettv->vval.v_string = NULL; 10659 #endif 10660 rettv->v_type = VAR_STRING; 10661 } 10662 10663 /* 10664 * "histnr()" function 10665 */ 10666 /*ARGSUSED*/ 10667 static void 10668 f_histnr(argvars, rettv) 10669 typval_T *argvars; 10670 typval_T *rettv; 10671 { 10672 int i; 10673 10674 #ifdef FEAT_CMDHIST 10675 char_u *history = get_tv_string_chk(&argvars[0]); 10676 10677 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10678 if (i >= HIST_CMD && i < HIST_COUNT) 10679 i = get_history_idx(i); 10680 else 10681 #endif 10682 i = -1; 10683 rettv->vval.v_number = i; 10684 } 10685 10686 /* 10687 * "highlightID(name)" function 10688 */ 10689 static void 10690 f_hlID(argvars, rettv) 10691 typval_T *argvars; 10692 typval_T *rettv; 10693 { 10694 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10695 } 10696 10697 /* 10698 * "highlight_exists()" function 10699 */ 10700 static void 10701 f_hlexists(argvars, rettv) 10702 typval_T *argvars; 10703 typval_T *rettv; 10704 { 10705 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10706 } 10707 10708 /* 10709 * "hostname()" function 10710 */ 10711 /*ARGSUSED*/ 10712 static void 10713 f_hostname(argvars, rettv) 10714 typval_T *argvars; 10715 typval_T *rettv; 10716 { 10717 char_u hostname[256]; 10718 10719 mch_get_host_name(hostname, 256); 10720 rettv->v_type = VAR_STRING; 10721 rettv->vval.v_string = vim_strsave(hostname); 10722 } 10723 10724 /* 10725 * iconv() function 10726 */ 10727 /*ARGSUSED*/ 10728 static void 10729 f_iconv(argvars, rettv) 10730 typval_T *argvars; 10731 typval_T *rettv; 10732 { 10733 #ifdef FEAT_MBYTE 10734 char_u buf1[NUMBUFLEN]; 10735 char_u buf2[NUMBUFLEN]; 10736 char_u *from, *to, *str; 10737 vimconv_T vimconv; 10738 #endif 10739 10740 rettv->v_type = VAR_STRING; 10741 rettv->vval.v_string = NULL; 10742 10743 #ifdef FEAT_MBYTE 10744 str = get_tv_string(&argvars[0]); 10745 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10746 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10747 vimconv.vc_type = CONV_NONE; 10748 convert_setup(&vimconv, from, to); 10749 10750 /* If the encodings are equal, no conversion needed. */ 10751 if (vimconv.vc_type == CONV_NONE) 10752 rettv->vval.v_string = vim_strsave(str); 10753 else 10754 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10755 10756 convert_setup(&vimconv, NULL, NULL); 10757 vim_free(from); 10758 vim_free(to); 10759 #endif 10760 } 10761 10762 /* 10763 * "indent()" function 10764 */ 10765 static void 10766 f_indent(argvars, rettv) 10767 typval_T *argvars; 10768 typval_T *rettv; 10769 { 10770 linenr_T lnum; 10771 10772 lnum = get_tv_lnum(argvars); 10773 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10774 rettv->vval.v_number = get_indent_lnum(lnum); 10775 else 10776 rettv->vval.v_number = -1; 10777 } 10778 10779 /* 10780 * "index()" function 10781 */ 10782 static void 10783 f_index(argvars, rettv) 10784 typval_T *argvars; 10785 typval_T *rettv; 10786 { 10787 list_T *l; 10788 listitem_T *item; 10789 long idx = 0; 10790 int ic = FALSE; 10791 10792 rettv->vval.v_number = -1; 10793 if (argvars[0].v_type != VAR_LIST) 10794 { 10795 EMSG(_(e_listreq)); 10796 return; 10797 } 10798 l = argvars[0].vval.v_list; 10799 if (l != NULL) 10800 { 10801 item = l->lv_first; 10802 if (argvars[2].v_type != VAR_UNKNOWN) 10803 { 10804 int error = FALSE; 10805 10806 /* Start at specified item. Use the cached index that list_find() 10807 * sets, so that a negative number also works. */ 10808 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10809 idx = l->lv_idx; 10810 if (argvars[3].v_type != VAR_UNKNOWN) 10811 ic = get_tv_number_chk(&argvars[3], &error); 10812 if (error) 10813 item = NULL; 10814 } 10815 10816 for ( ; item != NULL; item = item->li_next, ++idx) 10817 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10818 { 10819 rettv->vval.v_number = idx; 10820 break; 10821 } 10822 } 10823 } 10824 10825 static int inputsecret_flag = 0; 10826 10827 /* 10828 * "input()" function 10829 * Also handles inputsecret() when inputsecret is set. 10830 */ 10831 static void 10832 f_input(argvars, rettv) 10833 typval_T *argvars; 10834 typval_T *rettv; 10835 { 10836 char_u *prompt = get_tv_string_chk(&argvars[0]); 10837 char_u *p = NULL; 10838 int c; 10839 char_u buf[NUMBUFLEN]; 10840 int cmd_silent_save = cmd_silent; 10841 char_u *defstr = (char_u *)""; 10842 int xp_type = EXPAND_NOTHING; 10843 char_u *xp_arg = NULL; 10844 10845 rettv->v_type = VAR_STRING; 10846 10847 #ifdef NO_CONSOLE_INPUT 10848 /* While starting up, there is no place to enter text. */ 10849 if (no_console_input()) 10850 { 10851 rettv->vval.v_string = NULL; 10852 return; 10853 } 10854 #endif 10855 10856 cmd_silent = FALSE; /* Want to see the prompt. */ 10857 if (prompt != NULL) 10858 { 10859 /* Only the part of the message after the last NL is considered as 10860 * prompt for the command line */ 10861 p = vim_strrchr(prompt, '\n'); 10862 if (p == NULL) 10863 p = prompt; 10864 else 10865 { 10866 ++p; 10867 c = *p; 10868 *p = NUL; 10869 msg_start(); 10870 msg_clr_eos(); 10871 msg_puts_attr(prompt, echo_attr); 10872 msg_didout = FALSE; 10873 msg_starthere(); 10874 *p = c; 10875 } 10876 cmdline_row = msg_row; 10877 10878 if (argvars[1].v_type != VAR_UNKNOWN) 10879 { 10880 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10881 if (defstr != NULL) 10882 stuffReadbuffSpec(defstr); 10883 10884 if (argvars[2].v_type != VAR_UNKNOWN) 10885 { 10886 char_u *xp_name; 10887 int xp_namelen; 10888 long argt; 10889 10890 rettv->vval.v_string = NULL; 10891 10892 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 10893 if (xp_name == NULL) 10894 return; 10895 10896 xp_namelen = STRLEN(xp_name); 10897 10898 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 10899 &xp_arg) == FAIL) 10900 return; 10901 } 10902 } 10903 10904 if (defstr != NULL) 10905 rettv->vval.v_string = 10906 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 10907 xp_type, xp_arg); 10908 10909 vim_free(xp_arg); 10910 10911 /* since the user typed this, no need to wait for return */ 10912 need_wait_return = FALSE; 10913 msg_didout = FALSE; 10914 } 10915 cmd_silent = cmd_silent_save; 10916 } 10917 10918 /* 10919 * "inputdialog()" function 10920 */ 10921 static void 10922 f_inputdialog(argvars, rettv) 10923 typval_T *argvars; 10924 typval_T *rettv; 10925 { 10926 #if defined(FEAT_GUI_TEXTDIALOG) 10927 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10928 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10929 { 10930 char_u *message; 10931 char_u buf[NUMBUFLEN]; 10932 char_u *defstr = (char_u *)""; 10933 10934 message = get_tv_string_chk(&argvars[0]); 10935 if (argvars[1].v_type != VAR_UNKNOWN 10936 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10937 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10938 else 10939 IObuff[0] = NUL; 10940 if (message != NULL && defstr != NULL 10941 && do_dialog(VIM_QUESTION, NULL, message, 10942 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10943 rettv->vval.v_string = vim_strsave(IObuff); 10944 else 10945 { 10946 if (message != NULL && defstr != NULL 10947 && argvars[1].v_type != VAR_UNKNOWN 10948 && argvars[2].v_type != VAR_UNKNOWN) 10949 rettv->vval.v_string = vim_strsave( 10950 get_tv_string_buf(&argvars[2], buf)); 10951 else 10952 rettv->vval.v_string = NULL; 10953 } 10954 rettv->v_type = VAR_STRING; 10955 } 10956 else 10957 #endif 10958 f_input(argvars, rettv); 10959 } 10960 10961 /* 10962 * "inputlist()" function 10963 */ 10964 static void 10965 f_inputlist(argvars, rettv) 10966 typval_T *argvars; 10967 typval_T *rettv; 10968 { 10969 listitem_T *li; 10970 int selected; 10971 int mouse_used; 10972 10973 rettv->vval.v_number = 0; 10974 #ifdef NO_CONSOLE_INPUT 10975 /* While starting up, there is no place to enter text. */ 10976 if (no_console_input()) 10977 return; 10978 #endif 10979 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 10980 { 10981 EMSG2(_(e_listarg), "inputlist()"); 10982 return; 10983 } 10984 10985 msg_start(); 10986 lines_left = Rows; /* avoid more prompt */ 10987 msg_scroll = TRUE; 10988 msg_clr_eos(); 10989 10990 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 10991 { 10992 msg_puts(get_tv_string(&li->li_tv)); 10993 msg_putchar('\n'); 10994 } 10995 10996 /* Ask for choice. */ 10997 selected = prompt_for_number(&mouse_used); 10998 if (mouse_used) 10999 selected -= lines_left; 11000 11001 rettv->vval.v_number = selected; 11002 } 11003 11004 11005 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 11006 11007 /* 11008 * "inputrestore()" function 11009 */ 11010 /*ARGSUSED*/ 11011 static void 11012 f_inputrestore(argvars, rettv) 11013 typval_T *argvars; 11014 typval_T *rettv; 11015 { 11016 if (ga_userinput.ga_len > 0) 11017 { 11018 --ga_userinput.ga_len; 11019 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 11020 + ga_userinput.ga_len); 11021 rettv->vval.v_number = 0; /* OK */ 11022 } 11023 else if (p_verbose > 1) 11024 { 11025 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11026 rettv->vval.v_number = 1; /* Failed */ 11027 } 11028 } 11029 11030 /* 11031 * "inputsave()" function 11032 */ 11033 /*ARGSUSED*/ 11034 static void 11035 f_inputsave(argvars, rettv) 11036 typval_T *argvars; 11037 typval_T *rettv; 11038 { 11039 /* Add an entry to the stack of typehead storage. */ 11040 if (ga_grow(&ga_userinput, 1) == OK) 11041 { 11042 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11043 + ga_userinput.ga_len); 11044 ++ga_userinput.ga_len; 11045 rettv->vval.v_number = 0; /* OK */ 11046 } 11047 else 11048 rettv->vval.v_number = 1; /* Failed */ 11049 } 11050 11051 /* 11052 * "inputsecret()" function 11053 */ 11054 static void 11055 f_inputsecret(argvars, rettv) 11056 typval_T *argvars; 11057 typval_T *rettv; 11058 { 11059 ++cmdline_star; 11060 ++inputsecret_flag; 11061 f_input(argvars, rettv); 11062 --cmdline_star; 11063 --inputsecret_flag; 11064 } 11065 11066 /* 11067 * "insert()" function 11068 */ 11069 static void 11070 f_insert(argvars, rettv) 11071 typval_T *argvars; 11072 typval_T *rettv; 11073 { 11074 long before = 0; 11075 listitem_T *item; 11076 list_T *l; 11077 int error = FALSE; 11078 11079 rettv->vval.v_number = 0; 11080 if (argvars[0].v_type != VAR_LIST) 11081 EMSG2(_(e_listarg), "insert()"); 11082 else if ((l = argvars[0].vval.v_list) != NULL 11083 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11084 { 11085 if (argvars[2].v_type != VAR_UNKNOWN) 11086 before = get_tv_number_chk(&argvars[2], &error); 11087 if (error) 11088 return; /* type error; errmsg already given */ 11089 11090 if (before == l->lv_len) 11091 item = NULL; 11092 else 11093 { 11094 item = list_find(l, before); 11095 if (item == NULL) 11096 { 11097 EMSGN(_(e_listidx), before); 11098 l = NULL; 11099 } 11100 } 11101 if (l != NULL) 11102 { 11103 list_insert_tv(l, &argvars[1], item); 11104 copy_tv(&argvars[0], rettv); 11105 } 11106 } 11107 } 11108 11109 /* 11110 * "isdirectory()" function 11111 */ 11112 static void 11113 f_isdirectory(argvars, rettv) 11114 typval_T *argvars; 11115 typval_T *rettv; 11116 { 11117 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11118 } 11119 11120 /* 11121 * "islocked()" function 11122 */ 11123 static void 11124 f_islocked(argvars, rettv) 11125 typval_T *argvars; 11126 typval_T *rettv; 11127 { 11128 lval_T lv; 11129 char_u *end; 11130 dictitem_T *di; 11131 11132 rettv->vval.v_number = -1; 11133 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11134 FNE_CHECK_START); 11135 if (end != NULL && lv.ll_name != NULL) 11136 { 11137 if (*end != NUL) 11138 EMSG(_(e_trailing)); 11139 else 11140 { 11141 if (lv.ll_tv == NULL) 11142 { 11143 if (check_changedtick(lv.ll_name)) 11144 rettv->vval.v_number = 1; /* always locked */ 11145 else 11146 { 11147 di = find_var(lv.ll_name, NULL); 11148 if (di != NULL) 11149 { 11150 /* Consider a variable locked when: 11151 * 1. the variable itself is locked 11152 * 2. the value of the variable is locked. 11153 * 3. the List or Dict value is locked. 11154 */ 11155 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11156 || tv_islocked(&di->di_tv)); 11157 } 11158 } 11159 } 11160 else if (lv.ll_range) 11161 EMSG(_("E745: Range not allowed")); 11162 else if (lv.ll_newkey != NULL) 11163 EMSG2(_(e_dictkey), lv.ll_newkey); 11164 else if (lv.ll_list != NULL) 11165 /* List item. */ 11166 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11167 else 11168 /* Dictionary item. */ 11169 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11170 } 11171 } 11172 11173 clear_lval(&lv); 11174 } 11175 11176 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11177 11178 /* 11179 * Turn a dict into a list: 11180 * "what" == 0: list of keys 11181 * "what" == 1: list of values 11182 * "what" == 2: list of items 11183 */ 11184 static void 11185 dict_list(argvars, rettv, what) 11186 typval_T *argvars; 11187 typval_T *rettv; 11188 int what; 11189 { 11190 list_T *l; 11191 list_T *l2; 11192 dictitem_T *di; 11193 hashitem_T *hi; 11194 listitem_T *li; 11195 listitem_T *li2; 11196 dict_T *d; 11197 int todo; 11198 11199 rettv->vval.v_number = 0; 11200 if (argvars[0].v_type != VAR_DICT) 11201 { 11202 EMSG(_(e_dictreq)); 11203 return; 11204 } 11205 if ((d = argvars[0].vval.v_dict) == NULL) 11206 return; 11207 11208 l = list_alloc(); 11209 if (l == NULL) 11210 return; 11211 rettv->v_type = VAR_LIST; 11212 rettv->vval.v_list = l; 11213 ++l->lv_refcount; 11214 11215 todo = d->dv_hashtab.ht_used; 11216 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11217 { 11218 if (!HASHITEM_EMPTY(hi)) 11219 { 11220 --todo; 11221 di = HI2DI(hi); 11222 11223 li = listitem_alloc(); 11224 if (li == NULL) 11225 break; 11226 list_append(l, li); 11227 11228 if (what == 0) 11229 { 11230 /* keys() */ 11231 li->li_tv.v_type = VAR_STRING; 11232 li->li_tv.v_lock = 0; 11233 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11234 } 11235 else if (what == 1) 11236 { 11237 /* values() */ 11238 copy_tv(&di->di_tv, &li->li_tv); 11239 } 11240 else 11241 { 11242 /* items() */ 11243 l2 = list_alloc(); 11244 li->li_tv.v_type = VAR_LIST; 11245 li->li_tv.v_lock = 0; 11246 li->li_tv.vval.v_list = l2; 11247 if (l2 == NULL) 11248 break; 11249 ++l2->lv_refcount; 11250 11251 li2 = listitem_alloc(); 11252 if (li2 == NULL) 11253 break; 11254 list_append(l2, li2); 11255 li2->li_tv.v_type = VAR_STRING; 11256 li2->li_tv.v_lock = 0; 11257 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11258 11259 li2 = listitem_alloc(); 11260 if (li2 == NULL) 11261 break; 11262 list_append(l2, li2); 11263 copy_tv(&di->di_tv, &li2->li_tv); 11264 } 11265 } 11266 } 11267 } 11268 11269 /* 11270 * "items(dict)" function 11271 */ 11272 static void 11273 f_items(argvars, rettv) 11274 typval_T *argvars; 11275 typval_T *rettv; 11276 { 11277 dict_list(argvars, rettv, 2); 11278 } 11279 11280 /* 11281 * "join()" function 11282 */ 11283 static void 11284 f_join(argvars, rettv) 11285 typval_T *argvars; 11286 typval_T *rettv; 11287 { 11288 garray_T ga; 11289 char_u *sep; 11290 11291 rettv->vval.v_number = 0; 11292 if (argvars[0].v_type != VAR_LIST) 11293 { 11294 EMSG(_(e_listreq)); 11295 return; 11296 } 11297 if (argvars[0].vval.v_list == NULL) 11298 return; 11299 if (argvars[1].v_type == VAR_UNKNOWN) 11300 sep = (char_u *)" "; 11301 else 11302 sep = get_tv_string_chk(&argvars[1]); 11303 11304 rettv->v_type = VAR_STRING; 11305 11306 if (sep != NULL) 11307 { 11308 ga_init2(&ga, (int)sizeof(char), 80); 11309 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11310 ga_append(&ga, NUL); 11311 rettv->vval.v_string = (char_u *)ga.ga_data; 11312 } 11313 else 11314 rettv->vval.v_string = NULL; 11315 } 11316 11317 /* 11318 * "keys()" function 11319 */ 11320 static void 11321 f_keys(argvars, rettv) 11322 typval_T *argvars; 11323 typval_T *rettv; 11324 { 11325 dict_list(argvars, rettv, 0); 11326 } 11327 11328 /* 11329 * "last_buffer_nr()" function. 11330 */ 11331 /*ARGSUSED*/ 11332 static void 11333 f_last_buffer_nr(argvars, rettv) 11334 typval_T *argvars; 11335 typval_T *rettv; 11336 { 11337 int n = 0; 11338 buf_T *buf; 11339 11340 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11341 if (n < buf->b_fnum) 11342 n = buf->b_fnum; 11343 11344 rettv->vval.v_number = n; 11345 } 11346 11347 /* 11348 * "len()" function 11349 */ 11350 static void 11351 f_len(argvars, rettv) 11352 typval_T *argvars; 11353 typval_T *rettv; 11354 { 11355 switch (argvars[0].v_type) 11356 { 11357 case VAR_STRING: 11358 case VAR_NUMBER: 11359 rettv->vval.v_number = (varnumber_T)STRLEN( 11360 get_tv_string(&argvars[0])); 11361 break; 11362 case VAR_LIST: 11363 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11364 break; 11365 case VAR_DICT: 11366 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11367 break; 11368 default: 11369 EMSG(_("E701: Invalid type for len()")); 11370 break; 11371 } 11372 } 11373 11374 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11375 11376 static void 11377 libcall_common(argvars, rettv, type) 11378 typval_T *argvars; 11379 typval_T *rettv; 11380 int type; 11381 { 11382 #ifdef FEAT_LIBCALL 11383 char_u *string_in; 11384 char_u **string_result; 11385 int nr_result; 11386 #endif 11387 11388 rettv->v_type = type; 11389 if (type == VAR_NUMBER) 11390 rettv->vval.v_number = 0; 11391 else 11392 rettv->vval.v_string = NULL; 11393 11394 if (check_restricted() || check_secure()) 11395 return; 11396 11397 #ifdef FEAT_LIBCALL 11398 /* The first two args must be strings, otherwise its meaningless */ 11399 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11400 { 11401 string_in = NULL; 11402 if (argvars[2].v_type == VAR_STRING) 11403 string_in = argvars[2].vval.v_string; 11404 if (type == VAR_NUMBER) 11405 string_result = NULL; 11406 else 11407 string_result = &rettv->vval.v_string; 11408 if (mch_libcall(argvars[0].vval.v_string, 11409 argvars[1].vval.v_string, 11410 string_in, 11411 argvars[2].vval.v_number, 11412 string_result, 11413 &nr_result) == OK 11414 && type == VAR_NUMBER) 11415 rettv->vval.v_number = nr_result; 11416 } 11417 #endif 11418 } 11419 11420 /* 11421 * "libcall()" function 11422 */ 11423 static void 11424 f_libcall(argvars, rettv) 11425 typval_T *argvars; 11426 typval_T *rettv; 11427 { 11428 libcall_common(argvars, rettv, VAR_STRING); 11429 } 11430 11431 /* 11432 * "libcallnr()" function 11433 */ 11434 static void 11435 f_libcallnr(argvars, rettv) 11436 typval_T *argvars; 11437 typval_T *rettv; 11438 { 11439 libcall_common(argvars, rettv, VAR_NUMBER); 11440 } 11441 11442 /* 11443 * "line(string)" function 11444 */ 11445 static void 11446 f_line(argvars, rettv) 11447 typval_T *argvars; 11448 typval_T *rettv; 11449 { 11450 linenr_T lnum = 0; 11451 pos_T *fp; 11452 11453 fp = var2fpos(&argvars[0], TRUE); 11454 if (fp != NULL) 11455 lnum = fp->lnum; 11456 rettv->vval.v_number = lnum; 11457 } 11458 11459 /* 11460 * "line2byte(lnum)" function 11461 */ 11462 /*ARGSUSED*/ 11463 static void 11464 f_line2byte(argvars, rettv) 11465 typval_T *argvars; 11466 typval_T *rettv; 11467 { 11468 #ifndef FEAT_BYTEOFF 11469 rettv->vval.v_number = -1; 11470 #else 11471 linenr_T lnum; 11472 11473 lnum = get_tv_lnum(argvars); 11474 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11475 rettv->vval.v_number = -1; 11476 else 11477 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11478 if (rettv->vval.v_number >= 0) 11479 ++rettv->vval.v_number; 11480 #endif 11481 } 11482 11483 /* 11484 * "lispindent(lnum)" function 11485 */ 11486 static void 11487 f_lispindent(argvars, rettv) 11488 typval_T *argvars; 11489 typval_T *rettv; 11490 { 11491 #ifdef FEAT_LISP 11492 pos_T pos; 11493 linenr_T lnum; 11494 11495 pos = curwin->w_cursor; 11496 lnum = get_tv_lnum(argvars); 11497 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11498 { 11499 curwin->w_cursor.lnum = lnum; 11500 rettv->vval.v_number = get_lisp_indent(); 11501 curwin->w_cursor = pos; 11502 } 11503 else 11504 #endif 11505 rettv->vval.v_number = -1; 11506 } 11507 11508 /* 11509 * "localtime()" function 11510 */ 11511 /*ARGSUSED*/ 11512 static void 11513 f_localtime(argvars, rettv) 11514 typval_T *argvars; 11515 typval_T *rettv; 11516 { 11517 rettv->vval.v_number = (varnumber_T)time(NULL); 11518 } 11519 11520 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11521 11522 static void 11523 get_maparg(argvars, rettv, exact) 11524 typval_T *argvars; 11525 typval_T *rettv; 11526 int exact; 11527 { 11528 char_u *keys; 11529 char_u *which; 11530 char_u buf[NUMBUFLEN]; 11531 char_u *keys_buf = NULL; 11532 char_u *rhs; 11533 int mode; 11534 garray_T ga; 11535 11536 /* return empty string for failure */ 11537 rettv->v_type = VAR_STRING; 11538 rettv->vval.v_string = NULL; 11539 11540 keys = get_tv_string(&argvars[0]); 11541 if (*keys == NUL) 11542 return; 11543 11544 if (argvars[1].v_type != VAR_UNKNOWN) 11545 which = get_tv_string_buf_chk(&argvars[1], buf); 11546 else 11547 which = (char_u *)""; 11548 if (which == NULL) 11549 return; 11550 11551 mode = get_map_mode(&which, 0); 11552 11553 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11554 rhs = check_map(keys, mode, exact, FALSE); 11555 vim_free(keys_buf); 11556 if (rhs != NULL) 11557 { 11558 ga_init(&ga); 11559 ga.ga_itemsize = 1; 11560 ga.ga_growsize = 40; 11561 11562 while (*rhs != NUL) 11563 ga_concat(&ga, str2special(&rhs, FALSE)); 11564 11565 ga_append(&ga, NUL); 11566 rettv->vval.v_string = (char_u *)ga.ga_data; 11567 } 11568 } 11569 11570 /* 11571 * "map()" function 11572 */ 11573 static void 11574 f_map(argvars, rettv) 11575 typval_T *argvars; 11576 typval_T *rettv; 11577 { 11578 filter_map(argvars, rettv, TRUE); 11579 } 11580 11581 /* 11582 * "maparg()" function 11583 */ 11584 static void 11585 f_maparg(argvars, rettv) 11586 typval_T *argvars; 11587 typval_T *rettv; 11588 { 11589 get_maparg(argvars, rettv, TRUE); 11590 } 11591 11592 /* 11593 * "mapcheck()" function 11594 */ 11595 static void 11596 f_mapcheck(argvars, rettv) 11597 typval_T *argvars; 11598 typval_T *rettv; 11599 { 11600 get_maparg(argvars, rettv, FALSE); 11601 } 11602 11603 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11604 11605 static void 11606 find_some_match(argvars, rettv, type) 11607 typval_T *argvars; 11608 typval_T *rettv; 11609 int type; 11610 { 11611 char_u *str = NULL; 11612 char_u *expr = NULL; 11613 char_u *pat; 11614 regmatch_T regmatch; 11615 char_u patbuf[NUMBUFLEN]; 11616 char_u strbuf[NUMBUFLEN]; 11617 char_u *save_cpo; 11618 long start = 0; 11619 long nth = 1; 11620 int match = 0; 11621 list_T *l = NULL; 11622 listitem_T *li = NULL; 11623 long idx = 0; 11624 char_u *tofree = NULL; 11625 11626 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11627 save_cpo = p_cpo; 11628 p_cpo = (char_u *)""; 11629 11630 rettv->vval.v_number = -1; 11631 if (type == 3) 11632 { 11633 /* return empty list when there are no matches */ 11634 if ((rettv->vval.v_list = list_alloc()) == NULL) 11635 goto theend; 11636 rettv->v_type = VAR_LIST; 11637 ++rettv->vval.v_list->lv_refcount; 11638 } 11639 else if (type == 2) 11640 { 11641 rettv->v_type = VAR_STRING; 11642 rettv->vval.v_string = NULL; 11643 } 11644 11645 if (argvars[0].v_type == VAR_LIST) 11646 { 11647 if ((l = argvars[0].vval.v_list) == NULL) 11648 goto theend; 11649 li = l->lv_first; 11650 } 11651 else 11652 expr = str = get_tv_string(&argvars[0]); 11653 11654 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11655 if (pat == NULL) 11656 goto theend; 11657 11658 if (argvars[2].v_type != VAR_UNKNOWN) 11659 { 11660 int error = FALSE; 11661 11662 start = get_tv_number_chk(&argvars[2], &error); 11663 if (error) 11664 goto theend; 11665 if (l != NULL) 11666 { 11667 li = list_find(l, start); 11668 if (li == NULL) 11669 goto theend; 11670 idx = l->lv_idx; /* use the cached index */ 11671 } 11672 else 11673 { 11674 if (start < 0) 11675 start = 0; 11676 if (start > (long)STRLEN(str)) 11677 goto theend; 11678 str += start; 11679 } 11680 11681 if (argvars[3].v_type != VAR_UNKNOWN) 11682 nth = get_tv_number_chk(&argvars[3], &error); 11683 if (error) 11684 goto theend; 11685 } 11686 11687 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11688 if (regmatch.regprog != NULL) 11689 { 11690 regmatch.rm_ic = p_ic; 11691 11692 for (;;) 11693 { 11694 if (l != NULL) 11695 { 11696 if (li == NULL) 11697 { 11698 match = FALSE; 11699 break; 11700 } 11701 vim_free(tofree); 11702 str = echo_string(&li->li_tv, &tofree, strbuf); 11703 if (str == NULL) 11704 break; 11705 } 11706 11707 match = vim_regexec_nl(®match, str, (colnr_T)0); 11708 11709 if (match && --nth <= 0) 11710 break; 11711 if (l == NULL && !match) 11712 break; 11713 11714 /* Advance to just after the match. */ 11715 if (l != NULL) 11716 { 11717 li = li->li_next; 11718 ++idx; 11719 } 11720 else 11721 { 11722 #ifdef FEAT_MBYTE 11723 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11724 #else 11725 str = regmatch.startp[0] + 1; 11726 #endif 11727 } 11728 } 11729 11730 if (match) 11731 { 11732 if (type == 3) 11733 { 11734 int i; 11735 11736 /* return list with matched string and submatches */ 11737 for (i = 0; i < NSUBEXP; ++i) 11738 { 11739 if (regmatch.endp[i] == NULL) 11740 break; 11741 if (list_append_string(rettv->vval.v_list, 11742 regmatch.startp[i], 11743 (int)(regmatch.endp[i] - regmatch.startp[i])) 11744 == FAIL) 11745 break; 11746 } 11747 } 11748 else if (type == 2) 11749 { 11750 /* return matched string */ 11751 if (l != NULL) 11752 copy_tv(&li->li_tv, rettv); 11753 else 11754 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11755 (int)(regmatch.endp[0] - regmatch.startp[0])); 11756 } 11757 else if (l != NULL) 11758 rettv->vval.v_number = idx; 11759 else 11760 { 11761 if (type != 0) 11762 rettv->vval.v_number = 11763 (varnumber_T)(regmatch.startp[0] - str); 11764 else 11765 rettv->vval.v_number = 11766 (varnumber_T)(regmatch.endp[0] - str); 11767 rettv->vval.v_number += str - expr; 11768 } 11769 } 11770 vim_free(regmatch.regprog); 11771 } 11772 11773 theend: 11774 vim_free(tofree); 11775 p_cpo = save_cpo; 11776 } 11777 11778 /* 11779 * "match()" function 11780 */ 11781 static void 11782 f_match(argvars, rettv) 11783 typval_T *argvars; 11784 typval_T *rettv; 11785 { 11786 find_some_match(argvars, rettv, 1); 11787 } 11788 11789 /* 11790 * "matchend()" function 11791 */ 11792 static void 11793 f_matchend(argvars, rettv) 11794 typval_T *argvars; 11795 typval_T *rettv; 11796 { 11797 find_some_match(argvars, rettv, 0); 11798 } 11799 11800 /* 11801 * "matchlist()" function 11802 */ 11803 static void 11804 f_matchlist(argvars, rettv) 11805 typval_T *argvars; 11806 typval_T *rettv; 11807 { 11808 find_some_match(argvars, rettv, 3); 11809 } 11810 11811 /* 11812 * "matchstr()" function 11813 */ 11814 static void 11815 f_matchstr(argvars, rettv) 11816 typval_T *argvars; 11817 typval_T *rettv; 11818 { 11819 find_some_match(argvars, rettv, 2); 11820 } 11821 11822 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11823 11824 static void 11825 max_min(argvars, rettv, domax) 11826 typval_T *argvars; 11827 typval_T *rettv; 11828 int domax; 11829 { 11830 long n = 0; 11831 long i; 11832 int error = FALSE; 11833 11834 if (argvars[0].v_type == VAR_LIST) 11835 { 11836 list_T *l; 11837 listitem_T *li; 11838 11839 l = argvars[0].vval.v_list; 11840 if (l != NULL) 11841 { 11842 li = l->lv_first; 11843 if (li != NULL) 11844 { 11845 n = get_tv_number_chk(&li->li_tv, &error); 11846 for (;;) 11847 { 11848 li = li->li_next; 11849 if (li == NULL) 11850 break; 11851 i = get_tv_number_chk(&li->li_tv, &error); 11852 if (domax ? i > n : i < n) 11853 n = i; 11854 } 11855 } 11856 } 11857 } 11858 else if (argvars[0].v_type == VAR_DICT) 11859 { 11860 dict_T *d; 11861 int first = TRUE; 11862 hashitem_T *hi; 11863 int todo; 11864 11865 d = argvars[0].vval.v_dict; 11866 if (d != NULL) 11867 { 11868 todo = d->dv_hashtab.ht_used; 11869 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11870 { 11871 if (!HASHITEM_EMPTY(hi)) 11872 { 11873 --todo; 11874 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11875 if (first) 11876 { 11877 n = i; 11878 first = FALSE; 11879 } 11880 else if (domax ? i > n : i < n) 11881 n = i; 11882 } 11883 } 11884 } 11885 } 11886 else 11887 EMSG(_(e_listdictarg)); 11888 rettv->vval.v_number = error ? 0 : n; 11889 } 11890 11891 /* 11892 * "max()" function 11893 */ 11894 static void 11895 f_max(argvars, rettv) 11896 typval_T *argvars; 11897 typval_T *rettv; 11898 { 11899 max_min(argvars, rettv, TRUE); 11900 } 11901 11902 /* 11903 * "min()" function 11904 */ 11905 static void 11906 f_min(argvars, rettv) 11907 typval_T *argvars; 11908 typval_T *rettv; 11909 { 11910 max_min(argvars, rettv, FALSE); 11911 } 11912 11913 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11914 11915 /* 11916 * Create the directory in which "dir" is located, and higher levels when 11917 * needed. 11918 */ 11919 static int 11920 mkdir_recurse(dir, prot) 11921 char_u *dir; 11922 int prot; 11923 { 11924 char_u *p; 11925 char_u *updir; 11926 int r = FAIL; 11927 11928 /* Get end of directory name in "dir". 11929 * We're done when it's "/" or "c:/". */ 11930 p = gettail_sep(dir); 11931 if (p <= get_past_head(dir)) 11932 return OK; 11933 11934 /* If the directory exists we're done. Otherwise: create it.*/ 11935 updir = vim_strnsave(dir, (int)(p - dir)); 11936 if (updir == NULL) 11937 return FAIL; 11938 if (mch_isdir(updir)) 11939 r = OK; 11940 else if (mkdir_recurse(updir, prot) == OK) 11941 r = vim_mkdir_emsg(updir, prot); 11942 vim_free(updir); 11943 return r; 11944 } 11945 11946 #ifdef vim_mkdir 11947 /* 11948 * "mkdir()" function 11949 */ 11950 static void 11951 f_mkdir(argvars, rettv) 11952 typval_T *argvars; 11953 typval_T *rettv; 11954 { 11955 char_u *dir; 11956 char_u buf[NUMBUFLEN]; 11957 int prot = 0755; 11958 11959 rettv->vval.v_number = FAIL; 11960 if (check_restricted() || check_secure()) 11961 return; 11962 11963 dir = get_tv_string_buf(&argvars[0], buf); 11964 if (argvars[1].v_type != VAR_UNKNOWN) 11965 { 11966 if (argvars[2].v_type != VAR_UNKNOWN) 11967 prot = get_tv_number_chk(&argvars[2], NULL); 11968 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11969 mkdir_recurse(dir, prot); 11970 } 11971 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11972 } 11973 #endif 11974 11975 /* 11976 * "mode()" function 11977 */ 11978 /*ARGSUSED*/ 11979 static void 11980 f_mode(argvars, rettv) 11981 typval_T *argvars; 11982 typval_T *rettv; 11983 { 11984 char_u buf[2]; 11985 11986 #ifdef FEAT_VISUAL 11987 if (VIsual_active) 11988 { 11989 if (VIsual_select) 11990 buf[0] = VIsual_mode + 's' - 'v'; 11991 else 11992 buf[0] = VIsual_mode; 11993 } 11994 else 11995 #endif 11996 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11997 buf[0] = 'r'; 11998 else if (State & INSERT) 11999 { 12000 if (State & REPLACE_FLAG) 12001 buf[0] = 'R'; 12002 else 12003 buf[0] = 'i'; 12004 } 12005 else if (State & CMDLINE) 12006 buf[0] = 'c'; 12007 else 12008 buf[0] = 'n'; 12009 12010 buf[1] = NUL; 12011 rettv->vval.v_string = vim_strsave(buf); 12012 rettv->v_type = VAR_STRING; 12013 } 12014 12015 /* 12016 * "nextnonblank()" function 12017 */ 12018 static void 12019 f_nextnonblank(argvars, rettv) 12020 typval_T *argvars; 12021 typval_T *rettv; 12022 { 12023 linenr_T lnum; 12024 12025 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12026 { 12027 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12028 { 12029 lnum = 0; 12030 break; 12031 } 12032 if (*skipwhite(ml_get(lnum)) != NUL) 12033 break; 12034 } 12035 rettv->vval.v_number = lnum; 12036 } 12037 12038 /* 12039 * "nr2char()" function 12040 */ 12041 static void 12042 f_nr2char(argvars, rettv) 12043 typval_T *argvars; 12044 typval_T *rettv; 12045 { 12046 char_u buf[NUMBUFLEN]; 12047 12048 #ifdef FEAT_MBYTE 12049 if (has_mbyte) 12050 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12051 else 12052 #endif 12053 { 12054 buf[0] = (char_u)get_tv_number(&argvars[0]); 12055 buf[1] = NUL; 12056 } 12057 rettv->v_type = VAR_STRING; 12058 rettv->vval.v_string = vim_strsave(buf); 12059 } 12060 12061 /* 12062 * "prevnonblank()" function 12063 */ 12064 static void 12065 f_prevnonblank(argvars, rettv) 12066 typval_T *argvars; 12067 typval_T *rettv; 12068 { 12069 linenr_T lnum; 12070 12071 lnum = get_tv_lnum(argvars); 12072 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12073 lnum = 0; 12074 else 12075 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12076 --lnum; 12077 rettv->vval.v_number = lnum; 12078 } 12079 12080 #ifdef HAVE_STDARG_H 12081 /* This dummy va_list is here because: 12082 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12083 * - locally in the function results in a "used before set" warning 12084 * - using va_start() to initialize it gives "function with fixed args" error */ 12085 static va_list ap; 12086 #endif 12087 12088 /* 12089 * "printf()" function 12090 */ 12091 static void 12092 f_printf(argvars, rettv) 12093 typval_T *argvars; 12094 typval_T *rettv; 12095 { 12096 rettv->v_type = VAR_STRING; 12097 rettv->vval.v_string = NULL; 12098 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12099 { 12100 char_u buf[NUMBUFLEN]; 12101 int len; 12102 char_u *s; 12103 int saved_did_emsg = did_emsg; 12104 char *fmt; 12105 12106 /* Get the required length, allocate the buffer and do it for real. */ 12107 did_emsg = FALSE; 12108 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12109 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12110 if (!did_emsg) 12111 { 12112 s = alloc(len + 1); 12113 if (s != NULL) 12114 { 12115 rettv->vval.v_string = s; 12116 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12117 } 12118 } 12119 did_emsg |= saved_did_emsg; 12120 } 12121 #endif 12122 } 12123 12124 /* 12125 * "range()" function 12126 */ 12127 static void 12128 f_range(argvars, rettv) 12129 typval_T *argvars; 12130 typval_T *rettv; 12131 { 12132 long start; 12133 long end; 12134 long stride = 1; 12135 long i; 12136 list_T *l; 12137 int error = FALSE; 12138 12139 start = get_tv_number_chk(&argvars[0], &error); 12140 if (argvars[1].v_type == VAR_UNKNOWN) 12141 { 12142 end = start - 1; 12143 start = 0; 12144 } 12145 else 12146 { 12147 end = get_tv_number_chk(&argvars[1], &error); 12148 if (argvars[2].v_type != VAR_UNKNOWN) 12149 stride = get_tv_number_chk(&argvars[2], &error); 12150 } 12151 12152 rettv->vval.v_number = 0; 12153 if (error) 12154 return; /* type error; errmsg already given */ 12155 if (stride == 0) 12156 EMSG(_("E726: Stride is zero")); 12157 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12158 EMSG(_("E727: Start past end")); 12159 else 12160 { 12161 l = list_alloc(); 12162 if (l != NULL) 12163 { 12164 rettv->v_type = VAR_LIST; 12165 rettv->vval.v_list = l; 12166 ++l->lv_refcount; 12167 12168 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12169 if (list_append_number(l, (varnumber_T)i) == FAIL) 12170 break; 12171 } 12172 } 12173 } 12174 12175 /* 12176 * "readfile()" function 12177 */ 12178 static void 12179 f_readfile(argvars, rettv) 12180 typval_T *argvars; 12181 typval_T *rettv; 12182 { 12183 int binary = FALSE; 12184 char_u *fname; 12185 FILE *fd; 12186 list_T *l; 12187 listitem_T *li; 12188 #define FREAD_SIZE 200 /* optimized for text lines */ 12189 char_u buf[FREAD_SIZE]; 12190 int readlen; /* size of last fread() */ 12191 int buflen; /* nr of valid chars in buf[] */ 12192 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12193 int tolist; /* first byte in buf[] still to be put in list */ 12194 int chop; /* how many CR to chop off */ 12195 char_u *prev = NULL; /* previously read bytes, if any */ 12196 int prevlen = 0; /* length of "prev" if not NULL */ 12197 char_u *s; 12198 int len; 12199 long maxline = MAXLNUM; 12200 long cnt = 0; 12201 12202 if (argvars[1].v_type != VAR_UNKNOWN) 12203 { 12204 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12205 binary = TRUE; 12206 if (argvars[2].v_type != VAR_UNKNOWN) 12207 maxline = get_tv_number(&argvars[2]); 12208 } 12209 12210 l = list_alloc(); 12211 if (l == NULL) 12212 return; 12213 rettv->v_type = VAR_LIST; 12214 rettv->vval.v_list = l; 12215 l->lv_refcount = 1; 12216 12217 /* Always open the file in binary mode, library functions have a mind of 12218 * their own about CR-LF conversion. */ 12219 fname = get_tv_string(&argvars[0]); 12220 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12221 { 12222 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12223 return; 12224 } 12225 12226 filtd = 0; 12227 while (cnt < maxline || maxline < 0) 12228 { 12229 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12230 buflen = filtd + readlen; 12231 tolist = 0; 12232 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12233 { 12234 if (buf[filtd] == '\n' || readlen <= 0) 12235 { 12236 /* Only when in binary mode add an empty list item when the 12237 * last line ends in a '\n'. */ 12238 if (!binary && readlen == 0 && filtd == 0) 12239 break; 12240 12241 /* Found end-of-line or end-of-file: add a text line to the 12242 * list. */ 12243 chop = 0; 12244 if (!binary) 12245 while (filtd - chop - 1 >= tolist 12246 && buf[filtd - chop - 1] == '\r') 12247 ++chop; 12248 len = filtd - tolist - chop; 12249 if (prev == NULL) 12250 s = vim_strnsave(buf + tolist, len); 12251 else 12252 { 12253 s = alloc((unsigned)(prevlen + len + 1)); 12254 if (s != NULL) 12255 { 12256 mch_memmove(s, prev, prevlen); 12257 vim_free(prev); 12258 prev = NULL; 12259 mch_memmove(s + prevlen, buf + tolist, len); 12260 s[prevlen + len] = NUL; 12261 } 12262 } 12263 tolist = filtd + 1; 12264 12265 li = listitem_alloc(); 12266 if (li == NULL) 12267 { 12268 vim_free(s); 12269 break; 12270 } 12271 li->li_tv.v_type = VAR_STRING; 12272 li->li_tv.v_lock = 0; 12273 li->li_tv.vval.v_string = s; 12274 list_append(l, li); 12275 12276 if (++cnt >= maxline && maxline >= 0) 12277 break; 12278 if (readlen <= 0) 12279 break; 12280 } 12281 else if (buf[filtd] == NUL) 12282 buf[filtd] = '\n'; 12283 } 12284 if (readlen <= 0) 12285 break; 12286 12287 if (tolist == 0) 12288 { 12289 /* "buf" is full, need to move text to an allocated buffer */ 12290 if (prev == NULL) 12291 { 12292 prev = vim_strnsave(buf, buflen); 12293 prevlen = buflen; 12294 } 12295 else 12296 { 12297 s = alloc((unsigned)(prevlen + buflen)); 12298 if (s != NULL) 12299 { 12300 mch_memmove(s, prev, prevlen); 12301 mch_memmove(s + prevlen, buf, buflen); 12302 vim_free(prev); 12303 prev = s; 12304 prevlen += buflen; 12305 } 12306 } 12307 filtd = 0; 12308 } 12309 else 12310 { 12311 mch_memmove(buf, buf + tolist, buflen - tolist); 12312 filtd -= tolist; 12313 } 12314 } 12315 12316 /* 12317 * For a negative line count use only the lines at the end of the file, 12318 * free the rest. 12319 */ 12320 if (maxline < 0) 12321 while (cnt > -maxline) 12322 { 12323 listitem_remove(l, l->lv_first); 12324 --cnt; 12325 } 12326 12327 vim_free(prev); 12328 fclose(fd); 12329 } 12330 12331 12332 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12333 static void make_connection __ARGS((void)); 12334 static int check_connection __ARGS((void)); 12335 12336 static void 12337 make_connection() 12338 { 12339 if (X_DISPLAY == NULL 12340 # ifdef FEAT_GUI 12341 && !gui.in_use 12342 # endif 12343 ) 12344 { 12345 x_force_connect = TRUE; 12346 setup_term_clip(); 12347 x_force_connect = FALSE; 12348 } 12349 } 12350 12351 static int 12352 check_connection() 12353 { 12354 make_connection(); 12355 if (X_DISPLAY == NULL) 12356 { 12357 EMSG(_("E240: No connection to Vim server")); 12358 return FAIL; 12359 } 12360 return OK; 12361 } 12362 #endif 12363 12364 #ifdef FEAT_CLIENTSERVER 12365 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12366 12367 static void 12368 remote_common(argvars, rettv, expr) 12369 typval_T *argvars; 12370 typval_T *rettv; 12371 int expr; 12372 { 12373 char_u *server_name; 12374 char_u *keys; 12375 char_u *r = NULL; 12376 char_u buf[NUMBUFLEN]; 12377 # ifdef WIN32 12378 HWND w; 12379 # else 12380 Window w; 12381 # endif 12382 12383 if (check_restricted() || check_secure()) 12384 return; 12385 12386 # ifdef FEAT_X11 12387 if (check_connection() == FAIL) 12388 return; 12389 # endif 12390 12391 server_name = get_tv_string_chk(&argvars[0]); 12392 if (server_name == NULL) 12393 return; /* type error; errmsg already given */ 12394 keys = get_tv_string_buf(&argvars[1], buf); 12395 # ifdef WIN32 12396 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12397 # else 12398 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12399 < 0) 12400 # endif 12401 { 12402 if (r != NULL) 12403 EMSG(r); /* sending worked but evaluation failed */ 12404 else 12405 EMSG2(_("E241: Unable to send to %s"), server_name); 12406 return; 12407 } 12408 12409 rettv->vval.v_string = r; 12410 12411 if (argvars[2].v_type != VAR_UNKNOWN) 12412 { 12413 dictitem_T v; 12414 char_u str[30]; 12415 char_u *idvar; 12416 12417 sprintf((char *)str, "0x%x", (unsigned int)w); 12418 v.di_tv.v_type = VAR_STRING; 12419 v.di_tv.vval.v_string = vim_strsave(str); 12420 idvar = get_tv_string_chk(&argvars[2]); 12421 if (idvar != NULL) 12422 set_var(idvar, &v.di_tv, FALSE); 12423 vim_free(v.di_tv.vval.v_string); 12424 } 12425 } 12426 #endif 12427 12428 /* 12429 * "remote_expr()" function 12430 */ 12431 /*ARGSUSED*/ 12432 static void 12433 f_remote_expr(argvars, rettv) 12434 typval_T *argvars; 12435 typval_T *rettv; 12436 { 12437 rettv->v_type = VAR_STRING; 12438 rettv->vval.v_string = NULL; 12439 #ifdef FEAT_CLIENTSERVER 12440 remote_common(argvars, rettv, TRUE); 12441 #endif 12442 } 12443 12444 /* 12445 * "remote_foreground()" function 12446 */ 12447 /*ARGSUSED*/ 12448 static void 12449 f_remote_foreground(argvars, rettv) 12450 typval_T *argvars; 12451 typval_T *rettv; 12452 { 12453 rettv->vval.v_number = 0; 12454 #ifdef FEAT_CLIENTSERVER 12455 # ifdef WIN32 12456 /* On Win32 it's done in this application. */ 12457 { 12458 char_u *server_name = get_tv_string_chk(&argvars[0]); 12459 12460 if (server_name != NULL) 12461 serverForeground(server_name); 12462 } 12463 # else 12464 /* Send a foreground() expression to the server. */ 12465 argvars[1].v_type = VAR_STRING; 12466 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12467 argvars[2].v_type = VAR_UNKNOWN; 12468 remote_common(argvars, rettv, TRUE); 12469 vim_free(argvars[1].vval.v_string); 12470 # endif 12471 #endif 12472 } 12473 12474 /*ARGSUSED*/ 12475 static void 12476 f_remote_peek(argvars, rettv) 12477 typval_T *argvars; 12478 typval_T *rettv; 12479 { 12480 #ifdef FEAT_CLIENTSERVER 12481 dictitem_T v; 12482 char_u *s = NULL; 12483 # ifdef WIN32 12484 int n = 0; 12485 # endif 12486 char_u *serverid; 12487 12488 if (check_restricted() || check_secure()) 12489 { 12490 rettv->vval.v_number = -1; 12491 return; 12492 } 12493 serverid = get_tv_string_chk(&argvars[0]); 12494 if (serverid == NULL) 12495 { 12496 rettv->vval.v_number = -1; 12497 return; /* type error; errmsg already given */ 12498 } 12499 # ifdef WIN32 12500 sscanf(serverid, "%x", &n); 12501 if (n == 0) 12502 rettv->vval.v_number = -1; 12503 else 12504 { 12505 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12506 rettv->vval.v_number = (s != NULL); 12507 } 12508 # else 12509 rettv->vval.v_number = 0; 12510 if (check_connection() == FAIL) 12511 return; 12512 12513 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12514 serverStrToWin(serverid), &s); 12515 # endif 12516 12517 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12518 { 12519 char_u *retvar; 12520 12521 v.di_tv.v_type = VAR_STRING; 12522 v.di_tv.vval.v_string = vim_strsave(s); 12523 retvar = get_tv_string_chk(&argvars[1]); 12524 if (retvar != NULL) 12525 set_var(retvar, &v.di_tv, FALSE); 12526 vim_free(v.di_tv.vval.v_string); 12527 } 12528 #else 12529 rettv->vval.v_number = -1; 12530 #endif 12531 } 12532 12533 /*ARGSUSED*/ 12534 static void 12535 f_remote_read(argvars, rettv) 12536 typval_T *argvars; 12537 typval_T *rettv; 12538 { 12539 char_u *r = NULL; 12540 12541 #ifdef FEAT_CLIENTSERVER 12542 char_u *serverid = get_tv_string_chk(&argvars[0]); 12543 12544 if (serverid != NULL && !check_restricted() && !check_secure()) 12545 { 12546 # ifdef WIN32 12547 /* The server's HWND is encoded in the 'id' parameter */ 12548 int n = 0; 12549 12550 sscanf(serverid, "%x", &n); 12551 if (n != 0) 12552 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12553 if (r == NULL) 12554 # else 12555 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12556 serverStrToWin(serverid), &r, FALSE) < 0) 12557 # endif 12558 EMSG(_("E277: Unable to read a server reply")); 12559 } 12560 #endif 12561 rettv->v_type = VAR_STRING; 12562 rettv->vval.v_string = r; 12563 } 12564 12565 /* 12566 * "remote_send()" function 12567 */ 12568 /*ARGSUSED*/ 12569 static void 12570 f_remote_send(argvars, rettv) 12571 typval_T *argvars; 12572 typval_T *rettv; 12573 { 12574 rettv->v_type = VAR_STRING; 12575 rettv->vval.v_string = NULL; 12576 #ifdef FEAT_CLIENTSERVER 12577 remote_common(argvars, rettv, FALSE); 12578 #endif 12579 } 12580 12581 /* 12582 * "remove()" function 12583 */ 12584 static void 12585 f_remove(argvars, rettv) 12586 typval_T *argvars; 12587 typval_T *rettv; 12588 { 12589 list_T *l; 12590 listitem_T *item, *item2; 12591 listitem_T *li; 12592 long idx; 12593 long end; 12594 char_u *key; 12595 dict_T *d; 12596 dictitem_T *di; 12597 12598 rettv->vval.v_number = 0; 12599 if (argvars[0].v_type == VAR_DICT) 12600 { 12601 if (argvars[2].v_type != VAR_UNKNOWN) 12602 EMSG2(_(e_toomanyarg), "remove()"); 12603 else if ((d = argvars[0].vval.v_dict) != NULL 12604 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12605 { 12606 key = get_tv_string_chk(&argvars[1]); 12607 if (key != NULL) 12608 { 12609 di = dict_find(d, key, -1); 12610 if (di == NULL) 12611 EMSG2(_(e_dictkey), key); 12612 else 12613 { 12614 *rettv = di->di_tv; 12615 init_tv(&di->di_tv); 12616 dictitem_remove(d, di); 12617 } 12618 } 12619 } 12620 } 12621 else if (argvars[0].v_type != VAR_LIST) 12622 EMSG2(_(e_listdictarg), "remove()"); 12623 else if ((l = argvars[0].vval.v_list) != NULL 12624 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12625 { 12626 int error = FALSE; 12627 12628 idx = get_tv_number_chk(&argvars[1], &error); 12629 if (error) 12630 ; /* type error: do nothing, errmsg already given */ 12631 else if ((item = list_find(l, idx)) == NULL) 12632 EMSGN(_(e_listidx), idx); 12633 else 12634 { 12635 if (argvars[2].v_type == VAR_UNKNOWN) 12636 { 12637 /* Remove one item, return its value. */ 12638 list_remove(l, item, item); 12639 *rettv = item->li_tv; 12640 vim_free(item); 12641 } 12642 else 12643 { 12644 /* Remove range of items, return list with values. */ 12645 end = get_tv_number_chk(&argvars[2], &error); 12646 if (error) 12647 ; /* type error: do nothing */ 12648 else if ((item2 = list_find(l, end)) == NULL) 12649 EMSGN(_(e_listidx), end); 12650 else 12651 { 12652 int cnt = 0; 12653 12654 for (li = item; li != NULL; li = li->li_next) 12655 { 12656 ++cnt; 12657 if (li == item2) 12658 break; 12659 } 12660 if (li == NULL) /* didn't find "item2" after "item" */ 12661 EMSG(_(e_invrange)); 12662 else 12663 { 12664 list_remove(l, item, item2); 12665 l = list_alloc(); 12666 if (l != NULL) 12667 { 12668 rettv->v_type = VAR_LIST; 12669 rettv->vval.v_list = l; 12670 l->lv_first = item; 12671 l->lv_last = item2; 12672 l->lv_refcount = 1; 12673 item->li_prev = NULL; 12674 item2->li_next = NULL; 12675 l->lv_len = cnt; 12676 } 12677 } 12678 } 12679 } 12680 } 12681 } 12682 } 12683 12684 /* 12685 * "rename({from}, {to})" function 12686 */ 12687 static void 12688 f_rename(argvars, rettv) 12689 typval_T *argvars; 12690 typval_T *rettv; 12691 { 12692 char_u buf[NUMBUFLEN]; 12693 12694 if (check_restricted() || check_secure()) 12695 rettv->vval.v_number = -1; 12696 else 12697 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12698 get_tv_string_buf(&argvars[1], buf)); 12699 } 12700 12701 /* 12702 * "repeat()" function 12703 */ 12704 /*ARGSUSED*/ 12705 static void 12706 f_repeat(argvars, rettv) 12707 typval_T *argvars; 12708 typval_T *rettv; 12709 { 12710 char_u *p; 12711 int n; 12712 int slen; 12713 int len; 12714 char_u *r; 12715 int i; 12716 list_T *l; 12717 12718 n = get_tv_number(&argvars[1]); 12719 if (argvars[0].v_type == VAR_LIST) 12720 { 12721 l = list_alloc(); 12722 if (l != NULL && argvars[0].vval.v_list != NULL) 12723 { 12724 l->lv_refcount = 1; 12725 while (n-- > 0) 12726 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12727 break; 12728 } 12729 rettv->v_type = VAR_LIST; 12730 rettv->vval.v_list = l; 12731 } 12732 else 12733 { 12734 p = get_tv_string(&argvars[0]); 12735 rettv->v_type = VAR_STRING; 12736 rettv->vval.v_string = NULL; 12737 12738 slen = (int)STRLEN(p); 12739 len = slen * n; 12740 if (len <= 0) 12741 return; 12742 12743 r = alloc(len + 1); 12744 if (r != NULL) 12745 { 12746 for (i = 0; i < n; i++) 12747 mch_memmove(r + i * slen, p, (size_t)slen); 12748 r[len] = NUL; 12749 } 12750 12751 rettv->vval.v_string = r; 12752 } 12753 } 12754 12755 /* 12756 * "resolve()" function 12757 */ 12758 static void 12759 f_resolve(argvars, rettv) 12760 typval_T *argvars; 12761 typval_T *rettv; 12762 { 12763 char_u *p; 12764 12765 p = get_tv_string(&argvars[0]); 12766 #ifdef FEAT_SHORTCUT 12767 { 12768 char_u *v = NULL; 12769 12770 v = mch_resolve_shortcut(p); 12771 if (v != NULL) 12772 rettv->vval.v_string = v; 12773 else 12774 rettv->vval.v_string = vim_strsave(p); 12775 } 12776 #else 12777 # ifdef HAVE_READLINK 12778 { 12779 char_u buf[MAXPATHL + 1]; 12780 char_u *cpy; 12781 int len; 12782 char_u *remain = NULL; 12783 char_u *q; 12784 int is_relative_to_current = FALSE; 12785 int has_trailing_pathsep = FALSE; 12786 int limit = 100; 12787 12788 p = vim_strsave(p); 12789 12790 if (p[0] == '.' && (vim_ispathsep(p[1]) 12791 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12792 is_relative_to_current = TRUE; 12793 12794 len = STRLEN(p); 12795 if (len > 0 && after_pathsep(p, p + len)) 12796 has_trailing_pathsep = TRUE; 12797 12798 q = getnextcomp(p); 12799 if (*q != NUL) 12800 { 12801 /* Separate the first path component in "p", and keep the 12802 * remainder (beginning with the path separator). */ 12803 remain = vim_strsave(q - 1); 12804 q[-1] = NUL; 12805 } 12806 12807 for (;;) 12808 { 12809 for (;;) 12810 { 12811 len = readlink((char *)p, (char *)buf, MAXPATHL); 12812 if (len <= 0) 12813 break; 12814 buf[len] = NUL; 12815 12816 if (limit-- == 0) 12817 { 12818 vim_free(p); 12819 vim_free(remain); 12820 EMSG(_("E655: Too many symbolic links (cycle?)")); 12821 rettv->vval.v_string = NULL; 12822 goto fail; 12823 } 12824 12825 /* Ensure that the result will have a trailing path separator 12826 * if the argument has one. */ 12827 if (remain == NULL && has_trailing_pathsep) 12828 add_pathsep(buf); 12829 12830 /* Separate the first path component in the link value and 12831 * concatenate the remainders. */ 12832 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12833 if (*q != NUL) 12834 { 12835 if (remain == NULL) 12836 remain = vim_strsave(q - 1); 12837 else 12838 { 12839 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12840 if (cpy != NULL) 12841 { 12842 STRCAT(cpy, remain); 12843 vim_free(remain); 12844 remain = cpy; 12845 } 12846 } 12847 q[-1] = NUL; 12848 } 12849 12850 q = gettail(p); 12851 if (q > p && *q == NUL) 12852 { 12853 /* Ignore trailing path separator. */ 12854 q[-1] = NUL; 12855 q = gettail(p); 12856 } 12857 if (q > p && !mch_isFullName(buf)) 12858 { 12859 /* symlink is relative to directory of argument */ 12860 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12861 if (cpy != NULL) 12862 { 12863 STRCPY(cpy, p); 12864 STRCPY(gettail(cpy), buf); 12865 vim_free(p); 12866 p = cpy; 12867 } 12868 } 12869 else 12870 { 12871 vim_free(p); 12872 p = vim_strsave(buf); 12873 } 12874 } 12875 12876 if (remain == NULL) 12877 break; 12878 12879 /* Append the first path component of "remain" to "p". */ 12880 q = getnextcomp(remain + 1); 12881 len = q - remain - (*q != NUL); 12882 cpy = vim_strnsave(p, STRLEN(p) + len); 12883 if (cpy != NULL) 12884 { 12885 STRNCAT(cpy, remain, len); 12886 vim_free(p); 12887 p = cpy; 12888 } 12889 /* Shorten "remain". */ 12890 if (*q != NUL) 12891 STRCPY(remain, q - 1); 12892 else 12893 { 12894 vim_free(remain); 12895 remain = NULL; 12896 } 12897 } 12898 12899 /* If the result is a relative path name, make it explicitly relative to 12900 * the current directory if and only if the argument had this form. */ 12901 if (!vim_ispathsep(*p)) 12902 { 12903 if (is_relative_to_current 12904 && *p != NUL 12905 && !(p[0] == '.' 12906 && (p[1] == NUL 12907 || vim_ispathsep(p[1]) 12908 || (p[1] == '.' 12909 && (p[2] == NUL 12910 || vim_ispathsep(p[2])))))) 12911 { 12912 /* Prepend "./". */ 12913 cpy = concat_str((char_u *)"./", p); 12914 if (cpy != NULL) 12915 { 12916 vim_free(p); 12917 p = cpy; 12918 } 12919 } 12920 else if (!is_relative_to_current) 12921 { 12922 /* Strip leading "./". */ 12923 q = p; 12924 while (q[0] == '.' && vim_ispathsep(q[1])) 12925 q += 2; 12926 if (q > p) 12927 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12928 } 12929 } 12930 12931 /* Ensure that the result will have no trailing path separator 12932 * if the argument had none. But keep "/" or "//". */ 12933 if (!has_trailing_pathsep) 12934 { 12935 q = p + STRLEN(p); 12936 if (after_pathsep(p, q)) 12937 *gettail_sep(p) = NUL; 12938 } 12939 12940 rettv->vval.v_string = p; 12941 } 12942 # else 12943 rettv->vval.v_string = vim_strsave(p); 12944 # endif 12945 #endif 12946 12947 simplify_filename(rettv->vval.v_string); 12948 12949 #ifdef HAVE_READLINK 12950 fail: 12951 #endif 12952 rettv->v_type = VAR_STRING; 12953 } 12954 12955 /* 12956 * "reverse({list})" function 12957 */ 12958 static void 12959 f_reverse(argvars, rettv) 12960 typval_T *argvars; 12961 typval_T *rettv; 12962 { 12963 list_T *l; 12964 listitem_T *li, *ni; 12965 12966 rettv->vval.v_number = 0; 12967 if (argvars[0].v_type != VAR_LIST) 12968 EMSG2(_(e_listarg), "reverse()"); 12969 else if ((l = argvars[0].vval.v_list) != NULL 12970 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12971 { 12972 li = l->lv_last; 12973 l->lv_first = l->lv_last = NULL; 12974 l->lv_len = 0; 12975 while (li != NULL) 12976 { 12977 ni = li->li_prev; 12978 list_append(l, li); 12979 li = ni; 12980 } 12981 rettv->vval.v_list = l; 12982 rettv->v_type = VAR_LIST; 12983 ++l->lv_refcount; 12984 } 12985 } 12986 12987 #define SP_NOMOVE 1 /* don't move cursor */ 12988 #define SP_REPEAT 2 /* repeat to find outer pair */ 12989 #define SP_RETCOUNT 4 /* return matchcount */ 12990 #define SP_SETPCMARK 8 /* set previous context mark */ 12991 12992 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12993 12994 /* 12995 * Get flags for a search function. 12996 * Possibly sets "p_ws". 12997 * Returns BACKWARD, FORWARD or zero (for an error). 12998 */ 12999 static int 13000 get_search_arg(varp, flagsp) 13001 typval_T *varp; 13002 int *flagsp; 13003 { 13004 int dir = FORWARD; 13005 char_u *flags; 13006 char_u nbuf[NUMBUFLEN]; 13007 int mask; 13008 13009 if (varp->v_type != VAR_UNKNOWN) 13010 { 13011 flags = get_tv_string_buf_chk(varp, nbuf); 13012 if (flags == NULL) 13013 return 0; /* type error; errmsg already given */ 13014 while (*flags != NUL) 13015 { 13016 switch (*flags) 13017 { 13018 case 'b': dir = BACKWARD; break; 13019 case 'w': p_ws = TRUE; break; 13020 case 'W': p_ws = FALSE; break; 13021 default: mask = 0; 13022 if (flagsp != NULL) 13023 switch (*flags) 13024 { 13025 case 'n': mask = SP_NOMOVE; break; 13026 case 'r': mask = SP_REPEAT; break; 13027 case 'm': mask = SP_RETCOUNT; break; 13028 case 's': mask = SP_SETPCMARK; break; 13029 } 13030 if (mask == 0) 13031 { 13032 EMSG2(_(e_invarg2), flags); 13033 dir = 0; 13034 } 13035 else 13036 *flagsp |= mask; 13037 } 13038 if (dir == 0) 13039 break; 13040 ++flags; 13041 } 13042 } 13043 return dir; 13044 } 13045 13046 /* 13047 * "search()" function 13048 */ 13049 static void 13050 f_search(argvars, rettv) 13051 typval_T *argvars; 13052 typval_T *rettv; 13053 { 13054 char_u *pat; 13055 pos_T pos; 13056 pos_T save_cursor; 13057 int save_p_ws = p_ws; 13058 int dir; 13059 int flags = 0; 13060 13061 rettv->vval.v_number = 0; /* default: FAIL */ 13062 13063 pat = get_tv_string(&argvars[0]); 13064 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 13065 if (dir == 0) 13066 goto theend; 13067 /* 13068 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 13069 * Check to make sure only those flags are set. 13070 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13071 * flags cannot be set. Check for that condition also. 13072 */ 13073 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 13074 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13075 { 13076 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13077 goto theend; 13078 } 13079 13080 pos = save_cursor = curwin->w_cursor; 13081 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 13082 SEARCH_KEEP, RE_SEARCH) != FAIL) 13083 { 13084 rettv->vval.v_number = pos.lnum; 13085 if (flags & SP_SETPCMARK) 13086 setpcmark(); 13087 curwin->w_cursor = pos; 13088 /* "/$" will put the cursor after the end of the line, may need to 13089 * correct that here */ 13090 check_cursor(); 13091 } 13092 13093 /* If 'n' flag is used: restore cursor position. */ 13094 if (flags & SP_NOMOVE) 13095 curwin->w_cursor = save_cursor; 13096 theend: 13097 p_ws = save_p_ws; 13098 } 13099 13100 /* 13101 * "searchdecl()" function 13102 */ 13103 static void 13104 f_searchdecl(argvars, rettv) 13105 typval_T *argvars; 13106 typval_T *rettv; 13107 { 13108 int locally = 1; 13109 int thisblock = 0; 13110 int error = FALSE; 13111 char_u *name; 13112 13113 rettv->vval.v_number = 1; /* default: FAIL */ 13114 13115 name = get_tv_string_chk(&argvars[0]); 13116 if (argvars[1].v_type != VAR_UNKNOWN) 13117 { 13118 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13119 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13120 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13121 } 13122 if (!error && name != NULL) 13123 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13124 locally, thisblock, SEARCH_KEEP) == FAIL; 13125 } 13126 13127 /* 13128 * "searchpair()" function 13129 */ 13130 static void 13131 f_searchpair(argvars, rettv) 13132 typval_T *argvars; 13133 typval_T *rettv; 13134 { 13135 char_u *spat, *mpat, *epat; 13136 char_u *skip; 13137 int save_p_ws = p_ws; 13138 int dir; 13139 int flags = 0; 13140 char_u nbuf1[NUMBUFLEN]; 13141 char_u nbuf2[NUMBUFLEN]; 13142 char_u nbuf3[NUMBUFLEN]; 13143 13144 rettv->vval.v_number = 0; /* default: FAIL */ 13145 13146 /* Get the three pattern arguments: start, middle, end. */ 13147 spat = get_tv_string_chk(&argvars[0]); 13148 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13149 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13150 if (spat == NULL || mpat == NULL || epat == NULL) 13151 goto theend; /* type error */ 13152 13153 /* Handle the optional fourth argument: flags */ 13154 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13155 if (dir == 0) 13156 goto theend; 13157 /* 13158 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13159 */ 13160 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13161 { 13162 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13163 goto theend; 13164 } 13165 13166 /* Optional fifth argument: skip expresion */ 13167 if (argvars[3].v_type == VAR_UNKNOWN 13168 || argvars[4].v_type == VAR_UNKNOWN) 13169 skip = (char_u *)""; 13170 else 13171 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13172 if (skip == NULL) 13173 goto theend; /* type error */ 13174 13175 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13176 13177 theend: 13178 p_ws = save_p_ws; 13179 } 13180 13181 /* 13182 * Search for a start/middle/end thing. 13183 * Used by searchpair(), see its documentation for the details. 13184 * Returns 0 or -1 for no match, 13185 */ 13186 long 13187 do_searchpair(spat, mpat, epat, dir, skip, flags) 13188 char_u *spat; /* start pattern */ 13189 char_u *mpat; /* middle pattern */ 13190 char_u *epat; /* end pattern */ 13191 int dir; /* BACKWARD or FORWARD */ 13192 char_u *skip; /* skip expression */ 13193 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13194 { 13195 char_u *save_cpo; 13196 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13197 long retval = 0; 13198 pos_T pos; 13199 pos_T firstpos; 13200 pos_T foundpos; 13201 pos_T save_cursor; 13202 pos_T save_pos; 13203 int n; 13204 int r; 13205 int nest = 1; 13206 int err; 13207 13208 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13209 save_cpo = p_cpo; 13210 p_cpo = (char_u *)""; 13211 13212 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13213 * start/middle/end (pat3, for the top pair). */ 13214 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13215 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13216 if (pat2 == NULL || pat3 == NULL) 13217 goto theend; 13218 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13219 if (*mpat == NUL) 13220 STRCPY(pat3, pat2); 13221 else 13222 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13223 spat, epat, mpat); 13224 13225 save_cursor = curwin->w_cursor; 13226 pos = curwin->w_cursor; 13227 firstpos.lnum = 0; 13228 foundpos.lnum = 0; 13229 pat = pat3; 13230 for (;;) 13231 { 13232 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13233 SEARCH_KEEP, RE_SEARCH); 13234 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13235 /* didn't find it or found the first match again: FAIL */ 13236 break; 13237 13238 if (firstpos.lnum == 0) 13239 firstpos = pos; 13240 if (equalpos(pos, foundpos)) 13241 { 13242 /* Found the same position again. Can happen with a pattern that 13243 * has "\zs" at the end and searching backwards. Advance one 13244 * character and try again. */ 13245 if (dir == BACKWARD) 13246 decl(&pos); 13247 else 13248 incl(&pos); 13249 } 13250 foundpos = pos; 13251 13252 /* If the skip pattern matches, ignore this match. */ 13253 if (*skip != NUL) 13254 { 13255 save_pos = curwin->w_cursor; 13256 curwin->w_cursor = pos; 13257 r = eval_to_bool(skip, &err, NULL, FALSE); 13258 curwin->w_cursor = save_pos; 13259 if (err) 13260 { 13261 /* Evaluating {skip} caused an error, break here. */ 13262 curwin->w_cursor = save_cursor; 13263 retval = -1; 13264 break; 13265 } 13266 if (r) 13267 continue; 13268 } 13269 13270 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13271 { 13272 /* Found end when searching backwards or start when searching 13273 * forward: nested pair. */ 13274 ++nest; 13275 pat = pat2; /* nested, don't search for middle */ 13276 } 13277 else 13278 { 13279 /* Found end when searching forward or start when searching 13280 * backward: end of (nested) pair; or found middle in outer pair. */ 13281 if (--nest == 1) 13282 pat = pat3; /* outer level, search for middle */ 13283 } 13284 13285 if (nest == 0) 13286 { 13287 /* Found the match: return matchcount or line number. */ 13288 if (flags & SP_RETCOUNT) 13289 ++retval; 13290 else 13291 retval = pos.lnum; 13292 if (flags & SP_SETPCMARK) 13293 setpcmark(); 13294 curwin->w_cursor = pos; 13295 if (!(flags & SP_REPEAT)) 13296 break; 13297 nest = 1; /* search for next unmatched */ 13298 } 13299 } 13300 13301 /* If 'n' flag is used or search failed: restore cursor position. */ 13302 if ((flags & SP_NOMOVE) || retval == 0) 13303 curwin->w_cursor = save_cursor; 13304 13305 theend: 13306 vim_free(pat2); 13307 vim_free(pat3); 13308 p_cpo = save_cpo; 13309 13310 return retval; 13311 } 13312 13313 /*ARGSUSED*/ 13314 static void 13315 f_server2client(argvars, rettv) 13316 typval_T *argvars; 13317 typval_T *rettv; 13318 { 13319 #ifdef FEAT_CLIENTSERVER 13320 char_u buf[NUMBUFLEN]; 13321 char_u *server = get_tv_string_chk(&argvars[0]); 13322 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13323 13324 rettv->vval.v_number = -1; 13325 if (server == NULL || reply == NULL) 13326 return; 13327 if (check_restricted() || check_secure()) 13328 return; 13329 # ifdef FEAT_X11 13330 if (check_connection() == FAIL) 13331 return; 13332 # endif 13333 13334 if (serverSendReply(server, reply) < 0) 13335 { 13336 EMSG(_("E258: Unable to send to client")); 13337 return; 13338 } 13339 rettv->vval.v_number = 0; 13340 #else 13341 rettv->vval.v_number = -1; 13342 #endif 13343 } 13344 13345 /*ARGSUSED*/ 13346 static void 13347 f_serverlist(argvars, rettv) 13348 typval_T *argvars; 13349 typval_T *rettv; 13350 { 13351 char_u *r = NULL; 13352 13353 #ifdef FEAT_CLIENTSERVER 13354 # ifdef WIN32 13355 r = serverGetVimNames(); 13356 # else 13357 make_connection(); 13358 if (X_DISPLAY != NULL) 13359 r = serverGetVimNames(X_DISPLAY); 13360 # endif 13361 #endif 13362 rettv->v_type = VAR_STRING; 13363 rettv->vval.v_string = r; 13364 } 13365 13366 /* 13367 * "setbufvar()" function 13368 */ 13369 /*ARGSUSED*/ 13370 static void 13371 f_setbufvar(argvars, rettv) 13372 typval_T *argvars; 13373 typval_T *rettv; 13374 { 13375 buf_T *buf; 13376 #ifdef FEAT_AUTOCMD 13377 aco_save_T aco; 13378 #else 13379 buf_T *save_curbuf; 13380 #endif 13381 char_u *varname, *bufvarname; 13382 typval_T *varp; 13383 char_u nbuf[NUMBUFLEN]; 13384 13385 rettv->vval.v_number = 0; 13386 13387 if (check_restricted() || check_secure()) 13388 return; 13389 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13390 varname = get_tv_string_chk(&argvars[1]); 13391 buf = get_buf_tv(&argvars[0]); 13392 varp = &argvars[2]; 13393 13394 if (buf != NULL && varname != NULL && varp != NULL) 13395 { 13396 /* set curbuf to be our buf, temporarily */ 13397 #ifdef FEAT_AUTOCMD 13398 aucmd_prepbuf(&aco, buf); 13399 #else 13400 save_curbuf = curbuf; 13401 curbuf = buf; 13402 #endif 13403 13404 if (*varname == '&') 13405 { 13406 long numval; 13407 char_u *strval; 13408 int error = FALSE; 13409 13410 ++varname; 13411 numval = get_tv_number_chk(varp, &error); 13412 strval = get_tv_string_buf_chk(varp, nbuf); 13413 if (!error && strval != NULL) 13414 set_option_value(varname, numval, strval, OPT_LOCAL); 13415 } 13416 else 13417 { 13418 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13419 if (bufvarname != NULL) 13420 { 13421 STRCPY(bufvarname, "b:"); 13422 STRCPY(bufvarname + 2, varname); 13423 set_var(bufvarname, varp, TRUE); 13424 vim_free(bufvarname); 13425 } 13426 } 13427 13428 /* reset notion of buffer */ 13429 #ifdef FEAT_AUTOCMD 13430 aucmd_restbuf(&aco); 13431 #else 13432 curbuf = save_curbuf; 13433 #endif 13434 } 13435 } 13436 13437 /* 13438 * "setcmdpos()" function 13439 */ 13440 static void 13441 f_setcmdpos(argvars, rettv) 13442 typval_T *argvars; 13443 typval_T *rettv; 13444 { 13445 int pos = (int)get_tv_number(&argvars[0]) - 1; 13446 13447 if (pos >= 0) 13448 rettv->vval.v_number = set_cmdline_pos(pos); 13449 } 13450 13451 /* 13452 * "setline()" function 13453 */ 13454 static void 13455 f_setline(argvars, rettv) 13456 typval_T *argvars; 13457 typval_T *rettv; 13458 { 13459 linenr_T lnum; 13460 char_u *line = NULL; 13461 list_T *l = NULL; 13462 listitem_T *li = NULL; 13463 long added = 0; 13464 linenr_T lcount = curbuf->b_ml.ml_line_count; 13465 13466 lnum = get_tv_lnum(&argvars[0]); 13467 if (argvars[1].v_type == VAR_LIST) 13468 { 13469 l = argvars[1].vval.v_list; 13470 li = l->lv_first; 13471 } 13472 else 13473 line = get_tv_string_chk(&argvars[1]); 13474 13475 rettv->vval.v_number = 0; /* OK */ 13476 for (;;) 13477 { 13478 if (l != NULL) 13479 { 13480 /* list argument, get next string */ 13481 if (li == NULL) 13482 break; 13483 line = get_tv_string_chk(&li->li_tv); 13484 li = li->li_next; 13485 } 13486 13487 rettv->vval.v_number = 1; /* FAIL */ 13488 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13489 break; 13490 if (lnum <= curbuf->b_ml.ml_line_count) 13491 { 13492 /* existing line, replace it */ 13493 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13494 { 13495 changed_bytes(lnum, 0); 13496 check_cursor_col(); 13497 rettv->vval.v_number = 0; /* OK */ 13498 } 13499 } 13500 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13501 { 13502 /* lnum is one past the last line, append the line */ 13503 ++added; 13504 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13505 rettv->vval.v_number = 0; /* OK */ 13506 } 13507 13508 if (l == NULL) /* only one string argument */ 13509 break; 13510 ++lnum; 13511 } 13512 13513 if (added > 0) 13514 appended_lines_mark(lcount, added); 13515 } 13516 13517 /* 13518 * "setqflist()" function 13519 */ 13520 /*ARGSUSED*/ 13521 static void 13522 f_setqflist(argvars, rettv) 13523 typval_T *argvars; 13524 typval_T *rettv; 13525 { 13526 char_u *act; 13527 int action = ' '; 13528 13529 rettv->vval.v_number = -1; 13530 13531 #ifdef FEAT_QUICKFIX 13532 if (argvars[0].v_type != VAR_LIST) 13533 EMSG(_(e_listreq)); 13534 else 13535 { 13536 list_T *l = argvars[0].vval.v_list; 13537 13538 if (argvars[1].v_type == VAR_STRING) 13539 { 13540 act = get_tv_string_chk(&argvars[1]); 13541 if (act == NULL) 13542 return; /* type error; errmsg already given */ 13543 if (*act == 'a' || *act == 'r') 13544 action = *act; 13545 } 13546 13547 if (l != NULL && set_errorlist(l, action) == OK) 13548 rettv->vval.v_number = 0; 13549 } 13550 #endif 13551 } 13552 13553 /* 13554 * "setreg()" function 13555 */ 13556 static void 13557 f_setreg(argvars, rettv) 13558 typval_T *argvars; 13559 typval_T *rettv; 13560 { 13561 int regname; 13562 char_u *strregname; 13563 char_u *stropt; 13564 char_u *strval; 13565 int append; 13566 char_u yank_type; 13567 long block_len; 13568 13569 block_len = -1; 13570 yank_type = MAUTO; 13571 append = FALSE; 13572 13573 strregname = get_tv_string_chk(argvars); 13574 rettv->vval.v_number = 1; /* FAIL is default */ 13575 13576 if (strregname == NULL) 13577 return; /* type error; errmsg already given */ 13578 regname = *strregname; 13579 if (regname == 0 || regname == '@') 13580 regname = '"'; 13581 else if (regname == '=') 13582 return; 13583 13584 if (argvars[2].v_type != VAR_UNKNOWN) 13585 { 13586 stropt = get_tv_string_chk(&argvars[2]); 13587 if (stropt == NULL) 13588 return; /* type error */ 13589 for (; *stropt != NUL; ++stropt) 13590 switch (*stropt) 13591 { 13592 case 'a': case 'A': /* append */ 13593 append = TRUE; 13594 break; 13595 case 'v': case 'c': /* character-wise selection */ 13596 yank_type = MCHAR; 13597 break; 13598 case 'V': case 'l': /* line-wise selection */ 13599 yank_type = MLINE; 13600 break; 13601 #ifdef FEAT_VISUAL 13602 case 'b': case Ctrl_V: /* block-wise selection */ 13603 yank_type = MBLOCK; 13604 if (VIM_ISDIGIT(stropt[1])) 13605 { 13606 ++stropt; 13607 block_len = getdigits(&stropt) - 1; 13608 --stropt; 13609 } 13610 break; 13611 #endif 13612 } 13613 } 13614 13615 strval = get_tv_string_chk(&argvars[1]); 13616 if (strval != NULL) 13617 write_reg_contents_ex(regname, strval, -1, 13618 append, yank_type, block_len); 13619 rettv->vval.v_number = 0; 13620 } 13621 13622 13623 /* 13624 * "setwinvar(expr)" function 13625 */ 13626 /*ARGSUSED*/ 13627 static void 13628 f_setwinvar(argvars, rettv) 13629 typval_T *argvars; 13630 typval_T *rettv; 13631 { 13632 win_T *win; 13633 #ifdef FEAT_WINDOWS 13634 win_T *save_curwin; 13635 #endif 13636 char_u *varname, *winvarname; 13637 typval_T *varp; 13638 char_u nbuf[NUMBUFLEN]; 13639 13640 rettv->vval.v_number = 0; 13641 13642 if (check_restricted() || check_secure()) 13643 return; 13644 win = find_win_by_nr(&argvars[0]); 13645 varname = get_tv_string_chk(&argvars[1]); 13646 varp = &argvars[2]; 13647 13648 if (win != NULL && varname != NULL && varp != NULL) 13649 { 13650 #ifdef FEAT_WINDOWS 13651 /* set curwin to be our win, temporarily */ 13652 save_curwin = curwin; 13653 curwin = win; 13654 curbuf = curwin->w_buffer; 13655 #endif 13656 13657 if (*varname == '&') 13658 { 13659 long numval; 13660 char_u *strval; 13661 int error = FALSE; 13662 13663 ++varname; 13664 numval = get_tv_number_chk(varp, &error); 13665 strval = get_tv_string_buf_chk(varp, nbuf); 13666 if (!error && strval != NULL) 13667 set_option_value(varname, numval, strval, OPT_LOCAL); 13668 } 13669 else 13670 { 13671 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13672 if (winvarname != NULL) 13673 { 13674 STRCPY(winvarname, "w:"); 13675 STRCPY(winvarname + 2, varname); 13676 set_var(winvarname, varp, TRUE); 13677 vim_free(winvarname); 13678 } 13679 } 13680 13681 #ifdef FEAT_WINDOWS 13682 /* Restore current window, if it's still valid (autocomands can make 13683 * it invalid). */ 13684 if (win_valid(save_curwin)) 13685 { 13686 curwin = save_curwin; 13687 curbuf = curwin->w_buffer; 13688 } 13689 #endif 13690 } 13691 } 13692 13693 /* 13694 * "simplify()" function 13695 */ 13696 static void 13697 f_simplify(argvars, rettv) 13698 typval_T *argvars; 13699 typval_T *rettv; 13700 { 13701 char_u *p; 13702 13703 p = get_tv_string(&argvars[0]); 13704 rettv->vval.v_string = vim_strsave(p); 13705 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13706 rettv->v_type = VAR_STRING; 13707 } 13708 13709 static int 13710 #ifdef __BORLANDC__ 13711 _RTLENTRYF 13712 #endif 13713 item_compare __ARGS((const void *s1, const void *s2)); 13714 static int 13715 #ifdef __BORLANDC__ 13716 _RTLENTRYF 13717 #endif 13718 item_compare2 __ARGS((const void *s1, const void *s2)); 13719 13720 static int item_compare_ic; 13721 static char_u *item_compare_func; 13722 static int item_compare_func_err; 13723 #define ITEM_COMPARE_FAIL 999 13724 13725 /* 13726 * Compare functions for f_sort() below. 13727 */ 13728 static int 13729 #ifdef __BORLANDC__ 13730 _RTLENTRYF 13731 #endif 13732 item_compare(s1, s2) 13733 const void *s1; 13734 const void *s2; 13735 { 13736 char_u *p1, *p2; 13737 char_u *tofree1, *tofree2; 13738 int res; 13739 char_u numbuf1[NUMBUFLEN]; 13740 char_u numbuf2[NUMBUFLEN]; 13741 13742 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13743 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13744 if (item_compare_ic) 13745 res = STRICMP(p1, p2); 13746 else 13747 res = STRCMP(p1, p2); 13748 vim_free(tofree1); 13749 vim_free(tofree2); 13750 return res; 13751 } 13752 13753 static int 13754 #ifdef __BORLANDC__ 13755 _RTLENTRYF 13756 #endif 13757 item_compare2(s1, s2) 13758 const void *s1; 13759 const void *s2; 13760 { 13761 int res; 13762 typval_T rettv; 13763 typval_T argv[2]; 13764 int dummy; 13765 13766 /* shortcut after failure in previous call; compare all items equal */ 13767 if (item_compare_func_err) 13768 return 0; 13769 13770 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13771 * in the copy without changing the original list items. */ 13772 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13773 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13774 13775 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13776 res = call_func(item_compare_func, STRLEN(item_compare_func), 13777 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13778 clear_tv(&argv[0]); 13779 clear_tv(&argv[1]); 13780 13781 if (res == FAIL) 13782 res = ITEM_COMPARE_FAIL; 13783 else 13784 /* return value has wrong type */ 13785 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13786 if (item_compare_func_err) 13787 res = ITEM_COMPARE_FAIL; 13788 clear_tv(&rettv); 13789 return res; 13790 } 13791 13792 /* 13793 * "sort({list})" function 13794 */ 13795 static void 13796 f_sort(argvars, rettv) 13797 typval_T *argvars; 13798 typval_T *rettv; 13799 { 13800 list_T *l; 13801 listitem_T *li; 13802 listitem_T **ptrs; 13803 long len; 13804 long i; 13805 13806 rettv->vval.v_number = 0; 13807 if (argvars[0].v_type != VAR_LIST) 13808 EMSG2(_(e_listarg), "sort()"); 13809 else 13810 { 13811 l = argvars[0].vval.v_list; 13812 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13813 return; 13814 rettv->vval.v_list = l; 13815 rettv->v_type = VAR_LIST; 13816 ++l->lv_refcount; 13817 13818 len = list_len(l); 13819 if (len <= 1) 13820 return; /* short list sorts pretty quickly */ 13821 13822 item_compare_ic = FALSE; 13823 item_compare_func = NULL; 13824 if (argvars[1].v_type != VAR_UNKNOWN) 13825 { 13826 if (argvars[1].v_type == VAR_FUNC) 13827 item_compare_func = argvars[1].vval.v_string; 13828 else 13829 { 13830 int error = FALSE; 13831 13832 i = get_tv_number_chk(&argvars[1], &error); 13833 if (error) 13834 return; /* type error; errmsg already given */ 13835 if (i == 1) 13836 item_compare_ic = TRUE; 13837 else 13838 item_compare_func = get_tv_string(&argvars[1]); 13839 } 13840 } 13841 13842 /* Make an array with each entry pointing to an item in the List. */ 13843 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13844 if (ptrs == NULL) 13845 return; 13846 i = 0; 13847 for (li = l->lv_first; li != NULL; li = li->li_next) 13848 ptrs[i++] = li; 13849 13850 item_compare_func_err = FALSE; 13851 /* test the compare function */ 13852 if (item_compare_func != NULL 13853 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13854 == ITEM_COMPARE_FAIL) 13855 EMSG(_("E702: Sort compare function failed")); 13856 else 13857 { 13858 /* Sort the array with item pointers. */ 13859 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13860 item_compare_func == NULL ? item_compare : item_compare2); 13861 13862 if (!item_compare_func_err) 13863 { 13864 /* Clear the List and append the items in the sorted order. */ 13865 l->lv_first = l->lv_last = NULL; 13866 l->lv_len = 0; 13867 for (i = 0; i < len; ++i) 13868 list_append(l, ptrs[i]); 13869 } 13870 } 13871 13872 vim_free(ptrs); 13873 } 13874 } 13875 13876 /* 13877 * "soundfold({word})" function 13878 */ 13879 static void 13880 f_soundfold(argvars, rettv) 13881 typval_T *argvars; 13882 typval_T *rettv; 13883 { 13884 char_u *s; 13885 13886 rettv->v_type = VAR_STRING; 13887 s = get_tv_string(&argvars[0]); 13888 #ifdef FEAT_SYN_HL 13889 rettv->vval.v_string = eval_soundfold(s); 13890 #else 13891 rettv->vval.v_string = vim_strsave(s); 13892 #endif 13893 } 13894 13895 /* 13896 * "spellbadword()" function 13897 */ 13898 /* ARGSUSED */ 13899 static void 13900 f_spellbadword(argvars, rettv) 13901 typval_T *argvars; 13902 typval_T *rettv; 13903 { 13904 char_u *word = (char_u *)""; 13905 #ifdef FEAT_SYN_HL 13906 int len = 0; 13907 hlf_T attr = HLF_COUNT; 13908 list_T *l; 13909 #endif 13910 13911 l = list_alloc(); 13912 if (l == NULL) 13913 return; 13914 rettv->v_type = VAR_LIST; 13915 rettv->vval.v_list = l; 13916 ++l->lv_refcount; 13917 13918 #ifdef FEAT_SYN_HL 13919 if (argvars[0].v_type == VAR_UNKNOWN) 13920 { 13921 /* Find the start and length of the badly spelled word. */ 13922 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 13923 if (len != 0) 13924 word = ml_get_cursor(); 13925 } 13926 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13927 { 13928 char_u *str = get_tv_string_chk(&argvars[0]); 13929 int capcol = -1; 13930 13931 if (str != NULL) 13932 { 13933 /* Check the argument for spelling. */ 13934 while (*str != NUL) 13935 { 13936 len = spell_check(curwin, str, &attr, &capcol); 13937 if (attr != HLF_COUNT) 13938 { 13939 word = str; 13940 break; 13941 } 13942 str += len; 13943 } 13944 } 13945 } 13946 #endif 13947 13948 list_append_string(l, word, len); 13949 list_append_string(l, (char_u *)( 13950 attr == HLF_SPB ? "bad" : 13951 attr == HLF_SPR ? "rare" : 13952 attr == HLF_SPL ? "local" : 13953 attr == HLF_SPC ? "caps" : 13954 ""), -1); 13955 } 13956 13957 /* 13958 * "spellsuggest()" function 13959 */ 13960 static void 13961 f_spellsuggest(argvars, rettv) 13962 typval_T *argvars; 13963 typval_T *rettv; 13964 { 13965 list_T *l; 13966 #ifdef FEAT_SYN_HL 13967 char_u *str; 13968 int typeerr = FALSE; 13969 int maxcount; 13970 garray_T ga; 13971 int i; 13972 listitem_T *li; 13973 int need_capital = FALSE; 13974 #endif 13975 13976 l = list_alloc(); 13977 if (l == NULL) 13978 return; 13979 rettv->v_type = VAR_LIST; 13980 rettv->vval.v_list = l; 13981 ++l->lv_refcount; 13982 13983 #ifdef FEAT_SYN_HL 13984 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13985 { 13986 str = get_tv_string(&argvars[0]); 13987 if (argvars[1].v_type != VAR_UNKNOWN) 13988 { 13989 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 13990 if (maxcount <= 0) 13991 return; 13992 if (argvars[2].v_type != VAR_UNKNOWN) 13993 { 13994 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 13995 if (typeerr) 13996 return; 13997 } 13998 } 13999 else 14000 maxcount = 25; 14001 14002 spell_suggest_list(&ga, str, maxcount, need_capital); 14003 14004 for (i = 0; i < ga.ga_len; ++i) 14005 { 14006 str = ((char_u **)ga.ga_data)[i]; 14007 14008 li = listitem_alloc(); 14009 if (li == NULL) 14010 vim_free(str); 14011 else 14012 { 14013 li->li_tv.v_type = VAR_STRING; 14014 li->li_tv.v_lock = 0; 14015 li->li_tv.vval.v_string = str; 14016 list_append(l, li); 14017 } 14018 } 14019 ga_clear(&ga); 14020 } 14021 #endif 14022 } 14023 14024 static void 14025 f_split(argvars, rettv) 14026 typval_T *argvars; 14027 typval_T *rettv; 14028 { 14029 char_u *str; 14030 char_u *end; 14031 char_u *pat = NULL; 14032 regmatch_T regmatch; 14033 char_u patbuf[NUMBUFLEN]; 14034 char_u *save_cpo; 14035 int match; 14036 list_T *l; 14037 colnr_T col = 0; 14038 int keepempty = FALSE; 14039 int typeerr = FALSE; 14040 14041 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14042 save_cpo = p_cpo; 14043 p_cpo = (char_u *)""; 14044 14045 str = get_tv_string(&argvars[0]); 14046 if (argvars[1].v_type != VAR_UNKNOWN) 14047 { 14048 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14049 if (pat == NULL) 14050 typeerr = TRUE; 14051 if (argvars[2].v_type != VAR_UNKNOWN) 14052 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 14053 } 14054 if (pat == NULL || *pat == NUL) 14055 pat = (char_u *)"[\\x01- ]\\+"; 14056 14057 l = list_alloc(); 14058 if (l == NULL) 14059 return; 14060 rettv->v_type = VAR_LIST; 14061 rettv->vval.v_list = l; 14062 ++l->lv_refcount; 14063 if (typeerr) 14064 return; 14065 14066 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14067 if (regmatch.regprog != NULL) 14068 { 14069 regmatch.rm_ic = FALSE; 14070 while (*str != NUL || keepempty) 14071 { 14072 if (*str == NUL) 14073 match = FALSE; /* empty item at the end */ 14074 else 14075 match = vim_regexec_nl(®match, str, col); 14076 if (match) 14077 end = regmatch.startp[0]; 14078 else 14079 end = str + STRLEN(str); 14080 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 14081 && match && end < regmatch.endp[0])) 14082 { 14083 if (list_append_string(l, str, (int)(end - str)) == FAIL) 14084 break; 14085 } 14086 if (!match) 14087 break; 14088 /* Advance to just after the match. */ 14089 if (regmatch.endp[0] > str) 14090 col = 0; 14091 else 14092 { 14093 /* Don't get stuck at the same match. */ 14094 #ifdef FEAT_MBYTE 14095 col = (*mb_ptr2len)(regmatch.endp[0]); 14096 #else 14097 col = 1; 14098 #endif 14099 } 14100 str = regmatch.endp[0]; 14101 } 14102 14103 vim_free(regmatch.regprog); 14104 } 14105 14106 p_cpo = save_cpo; 14107 } 14108 14109 #ifdef HAVE_STRFTIME 14110 /* 14111 * "strftime({format}[, {time}])" function 14112 */ 14113 static void 14114 f_strftime(argvars, rettv) 14115 typval_T *argvars; 14116 typval_T *rettv; 14117 { 14118 char_u result_buf[256]; 14119 struct tm *curtime; 14120 time_t seconds; 14121 char_u *p; 14122 14123 rettv->v_type = VAR_STRING; 14124 14125 p = get_tv_string(&argvars[0]); 14126 if (argvars[1].v_type == VAR_UNKNOWN) 14127 seconds = time(NULL); 14128 else 14129 seconds = (time_t)get_tv_number(&argvars[1]); 14130 curtime = localtime(&seconds); 14131 /* MSVC returns NULL for an invalid value of seconds. */ 14132 if (curtime == NULL) 14133 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 14134 else 14135 { 14136 # ifdef FEAT_MBYTE 14137 vimconv_T conv; 14138 char_u *enc; 14139 14140 conv.vc_type = CONV_NONE; 14141 enc = enc_locale(); 14142 convert_setup(&conv, p_enc, enc); 14143 if (conv.vc_type != CONV_NONE) 14144 p = string_convert(&conv, p, NULL); 14145 # endif 14146 if (p != NULL) 14147 (void)strftime((char *)result_buf, sizeof(result_buf), 14148 (char *)p, curtime); 14149 else 14150 result_buf[0] = NUL; 14151 14152 # ifdef FEAT_MBYTE 14153 if (conv.vc_type != CONV_NONE) 14154 vim_free(p); 14155 convert_setup(&conv, enc, p_enc); 14156 if (conv.vc_type != CONV_NONE) 14157 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 14158 else 14159 # endif 14160 rettv->vval.v_string = vim_strsave(result_buf); 14161 14162 # ifdef FEAT_MBYTE 14163 /* Release conversion descriptors */ 14164 convert_setup(&conv, NULL, NULL); 14165 vim_free(enc); 14166 # endif 14167 } 14168 } 14169 #endif 14170 14171 /* 14172 * "stridx()" function 14173 */ 14174 static void 14175 f_stridx(argvars, rettv) 14176 typval_T *argvars; 14177 typval_T *rettv; 14178 { 14179 char_u buf[NUMBUFLEN]; 14180 char_u *needle; 14181 char_u *haystack; 14182 char_u *save_haystack; 14183 char_u *pos; 14184 int start_idx; 14185 14186 needle = get_tv_string_chk(&argvars[1]); 14187 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 14188 rettv->vval.v_number = -1; 14189 if (needle == NULL || haystack == NULL) 14190 return; /* type error; errmsg already given */ 14191 14192 if (argvars[2].v_type != VAR_UNKNOWN) 14193 { 14194 int error = FALSE; 14195 14196 start_idx = get_tv_number_chk(&argvars[2], &error); 14197 if (error || start_idx >= (int)STRLEN(haystack)) 14198 return; 14199 if (start_idx >= 0) 14200 haystack += start_idx; 14201 } 14202 14203 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14204 if (pos != NULL) 14205 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14206 } 14207 14208 /* 14209 * "string()" function 14210 */ 14211 static void 14212 f_string(argvars, rettv) 14213 typval_T *argvars; 14214 typval_T *rettv; 14215 { 14216 char_u *tofree; 14217 char_u numbuf[NUMBUFLEN]; 14218 14219 rettv->v_type = VAR_STRING; 14220 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14221 if (tofree == NULL) 14222 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14223 } 14224 14225 /* 14226 * "strlen()" function 14227 */ 14228 static void 14229 f_strlen(argvars, rettv) 14230 typval_T *argvars; 14231 typval_T *rettv; 14232 { 14233 rettv->vval.v_number = (varnumber_T)(STRLEN( 14234 get_tv_string(&argvars[0]))); 14235 } 14236 14237 /* 14238 * "strpart()" function 14239 */ 14240 static void 14241 f_strpart(argvars, rettv) 14242 typval_T *argvars; 14243 typval_T *rettv; 14244 { 14245 char_u *p; 14246 int n; 14247 int len; 14248 int slen; 14249 int error = FALSE; 14250 14251 p = get_tv_string(&argvars[0]); 14252 slen = (int)STRLEN(p); 14253 14254 n = get_tv_number_chk(&argvars[1], &error); 14255 if (error) 14256 len = 0; 14257 else if (argvars[2].v_type != VAR_UNKNOWN) 14258 len = get_tv_number(&argvars[2]); 14259 else 14260 len = slen - n; /* default len: all bytes that are available. */ 14261 14262 /* 14263 * Only return the overlap between the specified part and the actual 14264 * string. 14265 */ 14266 if (n < 0) 14267 { 14268 len += n; 14269 n = 0; 14270 } 14271 else if (n > slen) 14272 n = slen; 14273 if (len < 0) 14274 len = 0; 14275 else if (n + len > slen) 14276 len = slen - n; 14277 14278 rettv->v_type = VAR_STRING; 14279 rettv->vval.v_string = vim_strnsave(p + n, len); 14280 } 14281 14282 /* 14283 * "strridx()" function 14284 */ 14285 static void 14286 f_strridx(argvars, rettv) 14287 typval_T *argvars; 14288 typval_T *rettv; 14289 { 14290 char_u buf[NUMBUFLEN]; 14291 char_u *needle; 14292 char_u *haystack; 14293 char_u *rest; 14294 char_u *lastmatch = NULL; 14295 int haystack_len, end_idx; 14296 14297 needle = get_tv_string_chk(&argvars[1]); 14298 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14299 haystack_len = STRLEN(haystack); 14300 14301 rettv->vval.v_number = -1; 14302 if (needle == NULL || haystack == NULL) 14303 return; /* type error; errmsg already given */ 14304 if (argvars[2].v_type != VAR_UNKNOWN) 14305 { 14306 /* Third argument: upper limit for index */ 14307 end_idx = get_tv_number_chk(&argvars[2], NULL); 14308 if (end_idx < 0) 14309 return; /* can never find a match */ 14310 } 14311 else 14312 end_idx = haystack_len; 14313 14314 if (*needle == NUL) 14315 { 14316 /* Empty string matches past the end. */ 14317 lastmatch = haystack + end_idx; 14318 } 14319 else 14320 { 14321 for (rest = haystack; *rest != '\0'; ++rest) 14322 { 14323 rest = (char_u *)strstr((char *)rest, (char *)needle); 14324 if (rest == NULL || rest > haystack + end_idx) 14325 break; 14326 lastmatch = rest; 14327 } 14328 } 14329 14330 if (lastmatch == NULL) 14331 rettv->vval.v_number = -1; 14332 else 14333 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14334 } 14335 14336 /* 14337 * "strtrans()" function 14338 */ 14339 static void 14340 f_strtrans(argvars, rettv) 14341 typval_T *argvars; 14342 typval_T *rettv; 14343 { 14344 rettv->v_type = VAR_STRING; 14345 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14346 } 14347 14348 /* 14349 * "submatch()" function 14350 */ 14351 static void 14352 f_submatch(argvars, rettv) 14353 typval_T *argvars; 14354 typval_T *rettv; 14355 { 14356 rettv->v_type = VAR_STRING; 14357 rettv->vval.v_string = 14358 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14359 } 14360 14361 /* 14362 * "substitute()" function 14363 */ 14364 static void 14365 f_substitute(argvars, rettv) 14366 typval_T *argvars; 14367 typval_T *rettv; 14368 { 14369 char_u patbuf[NUMBUFLEN]; 14370 char_u subbuf[NUMBUFLEN]; 14371 char_u flagsbuf[NUMBUFLEN]; 14372 14373 char_u *str = get_tv_string_chk(&argvars[0]); 14374 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14375 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14376 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14377 14378 rettv->v_type = VAR_STRING; 14379 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14380 rettv->vval.v_string = NULL; 14381 else 14382 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14383 } 14384 14385 /* 14386 * "synID(lnum, col, trans)" function 14387 */ 14388 /*ARGSUSED*/ 14389 static void 14390 f_synID(argvars, rettv) 14391 typval_T *argvars; 14392 typval_T *rettv; 14393 { 14394 int id = 0; 14395 #ifdef FEAT_SYN_HL 14396 long lnum; 14397 long col; 14398 int trans; 14399 int transerr = FALSE; 14400 14401 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14402 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14403 trans = get_tv_number_chk(&argvars[2], &transerr); 14404 14405 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14406 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14407 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14408 #endif 14409 14410 rettv->vval.v_number = id; 14411 } 14412 14413 /* 14414 * "synIDattr(id, what [, mode])" function 14415 */ 14416 /*ARGSUSED*/ 14417 static void 14418 f_synIDattr(argvars, rettv) 14419 typval_T *argvars; 14420 typval_T *rettv; 14421 { 14422 char_u *p = NULL; 14423 #ifdef FEAT_SYN_HL 14424 int id; 14425 char_u *what; 14426 char_u *mode; 14427 char_u modebuf[NUMBUFLEN]; 14428 int modec; 14429 14430 id = get_tv_number(&argvars[0]); 14431 what = get_tv_string(&argvars[1]); 14432 if (argvars[2].v_type != VAR_UNKNOWN) 14433 { 14434 mode = get_tv_string_buf(&argvars[2], modebuf); 14435 modec = TOLOWER_ASC(mode[0]); 14436 if (modec != 't' && modec != 'c' 14437 #ifdef FEAT_GUI 14438 && modec != 'g' 14439 #endif 14440 ) 14441 modec = 0; /* replace invalid with current */ 14442 } 14443 else 14444 { 14445 #ifdef FEAT_GUI 14446 if (gui.in_use) 14447 modec = 'g'; 14448 else 14449 #endif 14450 if (t_colors > 1) 14451 modec = 'c'; 14452 else 14453 modec = 't'; 14454 } 14455 14456 14457 switch (TOLOWER_ASC(what[0])) 14458 { 14459 case 'b': 14460 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14461 p = highlight_color(id, what, modec); 14462 else /* bold */ 14463 p = highlight_has_attr(id, HL_BOLD, modec); 14464 break; 14465 14466 case 'f': /* fg[#] */ 14467 p = highlight_color(id, what, modec); 14468 break; 14469 14470 case 'i': 14471 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14472 p = highlight_has_attr(id, HL_INVERSE, modec); 14473 else /* italic */ 14474 p = highlight_has_attr(id, HL_ITALIC, modec); 14475 break; 14476 14477 case 'n': /* name */ 14478 p = get_highlight_name(NULL, id - 1); 14479 break; 14480 14481 case 'r': /* reverse */ 14482 p = highlight_has_attr(id, HL_INVERSE, modec); 14483 break; 14484 14485 case 's': /* standout */ 14486 p = highlight_has_attr(id, HL_STANDOUT, modec); 14487 break; 14488 14489 case 'u': 14490 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14491 /* underline */ 14492 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14493 else 14494 /* undercurl */ 14495 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14496 break; 14497 } 14498 14499 if (p != NULL) 14500 p = vim_strsave(p); 14501 #endif 14502 rettv->v_type = VAR_STRING; 14503 rettv->vval.v_string = p; 14504 } 14505 14506 /* 14507 * "synIDtrans(id)" function 14508 */ 14509 /*ARGSUSED*/ 14510 static void 14511 f_synIDtrans(argvars, rettv) 14512 typval_T *argvars; 14513 typval_T *rettv; 14514 { 14515 int id; 14516 14517 #ifdef FEAT_SYN_HL 14518 id = get_tv_number(&argvars[0]); 14519 14520 if (id > 0) 14521 id = syn_get_final_id(id); 14522 else 14523 #endif 14524 id = 0; 14525 14526 rettv->vval.v_number = id; 14527 } 14528 14529 /* 14530 * "system()" function 14531 */ 14532 static void 14533 f_system(argvars, rettv) 14534 typval_T *argvars; 14535 typval_T *rettv; 14536 { 14537 char_u *res = NULL; 14538 char_u *p; 14539 char_u *infile = NULL; 14540 char_u buf[NUMBUFLEN]; 14541 int err = FALSE; 14542 FILE *fd; 14543 14544 if (argvars[1].v_type != VAR_UNKNOWN) 14545 { 14546 /* 14547 * Write the string to a temp file, to be used for input of the shell 14548 * command. 14549 */ 14550 if ((infile = vim_tempname('i')) == NULL) 14551 { 14552 EMSG(_(e_notmp)); 14553 return; 14554 } 14555 14556 fd = mch_fopen((char *)infile, WRITEBIN); 14557 if (fd == NULL) 14558 { 14559 EMSG2(_(e_notopen), infile); 14560 goto done; 14561 } 14562 p = get_tv_string_buf_chk(&argvars[1], buf); 14563 if (p == NULL) 14564 goto done; /* type error; errmsg already given */ 14565 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14566 err = TRUE; 14567 if (fclose(fd) != 0) 14568 err = TRUE; 14569 if (err) 14570 { 14571 EMSG(_("E677: Error writing temp file")); 14572 goto done; 14573 } 14574 } 14575 14576 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14577 14578 #ifdef USE_CR 14579 /* translate <CR> into <NL> */ 14580 if (res != NULL) 14581 { 14582 char_u *s; 14583 14584 for (s = res; *s; ++s) 14585 { 14586 if (*s == CAR) 14587 *s = NL; 14588 } 14589 } 14590 #else 14591 # ifdef USE_CRNL 14592 /* translate <CR><NL> into <NL> */ 14593 if (res != NULL) 14594 { 14595 char_u *s, *d; 14596 14597 d = res; 14598 for (s = res; *s; ++s) 14599 { 14600 if (s[0] == CAR && s[1] == NL) 14601 ++s; 14602 *d++ = *s; 14603 } 14604 *d = NUL; 14605 } 14606 # endif 14607 #endif 14608 14609 done: 14610 if (infile != NULL) 14611 { 14612 mch_remove(infile); 14613 vim_free(infile); 14614 } 14615 rettv->v_type = VAR_STRING; 14616 rettv->vval.v_string = res; 14617 } 14618 14619 /* 14620 * "tagfiles()" function 14621 */ 14622 /*ARGSUSED*/ 14623 static void 14624 f_tagfiles(argvars, rettv) 14625 typval_T *argvars; 14626 typval_T *rettv; 14627 { 14628 char_u fname[MAXPATHL + 1]; 14629 list_T *l; 14630 14631 l = list_alloc(); 14632 if (l == NULL) 14633 { 14634 rettv->vval.v_number = 0; 14635 return; 14636 } 14637 rettv->vval.v_list = l; 14638 rettv->v_type = VAR_LIST; 14639 ++l->lv_refcount; 14640 14641 get_tagfname(TRUE, NULL); 14642 for (;;) 14643 if (get_tagfname(FALSE, fname) == FAIL 14644 || list_append_string(l, fname, -1) == FAIL) 14645 break; 14646 } 14647 14648 /* 14649 * "taglist()" function 14650 */ 14651 static void 14652 f_taglist(argvars, rettv) 14653 typval_T *argvars; 14654 typval_T *rettv; 14655 { 14656 char_u *tag_pattern; 14657 list_T *l; 14658 14659 tag_pattern = get_tv_string(&argvars[0]); 14660 14661 rettv->vval.v_number = FALSE; 14662 if (*tag_pattern == NUL) 14663 return; 14664 14665 l = list_alloc(); 14666 if (l != NULL) 14667 { 14668 if (get_tags(l, tag_pattern) != FAIL) 14669 { 14670 rettv->vval.v_list = l; 14671 rettv->v_type = VAR_LIST; 14672 ++l->lv_refcount; 14673 } 14674 else 14675 list_free(l); 14676 } 14677 } 14678 14679 /* 14680 * "tempname()" function 14681 */ 14682 /*ARGSUSED*/ 14683 static void 14684 f_tempname(argvars, rettv) 14685 typval_T *argvars; 14686 typval_T *rettv; 14687 { 14688 static int x = 'A'; 14689 14690 rettv->v_type = VAR_STRING; 14691 rettv->vval.v_string = vim_tempname(x); 14692 14693 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14694 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14695 do 14696 { 14697 if (x == 'Z') 14698 x = '0'; 14699 else if (x == '9') 14700 x = 'A'; 14701 else 14702 { 14703 #ifdef EBCDIC 14704 if (x == 'I') 14705 x = 'J'; 14706 else if (x == 'R') 14707 x = 'S'; 14708 else 14709 #endif 14710 ++x; 14711 } 14712 } while (x == 'I' || x == 'O'); 14713 } 14714 14715 /* 14716 * "test(list)" function: Just checking the walls... 14717 */ 14718 /*ARGSUSED*/ 14719 static void 14720 f_test(argvars, rettv) 14721 typval_T *argvars; 14722 typval_T *rettv; 14723 { 14724 /* Used for unit testing. Change the code below to your liking. */ 14725 #if 0 14726 listitem_T *li; 14727 list_T *l; 14728 char_u *bad, *good; 14729 14730 if (argvars[0].v_type != VAR_LIST) 14731 return; 14732 l = argvars[0].vval.v_list; 14733 if (l == NULL) 14734 return; 14735 li = l->lv_first; 14736 if (li == NULL) 14737 return; 14738 bad = get_tv_string(&li->li_tv); 14739 li = li->li_next; 14740 if (li == NULL) 14741 return; 14742 good = get_tv_string(&li->li_tv); 14743 rettv->vval.v_number = test_edit_score(bad, good); 14744 #endif 14745 } 14746 14747 /* 14748 * "tolower(string)" function 14749 */ 14750 static void 14751 f_tolower(argvars, rettv) 14752 typval_T *argvars; 14753 typval_T *rettv; 14754 { 14755 char_u *p; 14756 14757 p = vim_strsave(get_tv_string(&argvars[0])); 14758 rettv->v_type = VAR_STRING; 14759 rettv->vval.v_string = p; 14760 14761 if (p != NULL) 14762 while (*p != NUL) 14763 { 14764 #ifdef FEAT_MBYTE 14765 int l; 14766 14767 if (enc_utf8) 14768 { 14769 int c, lc; 14770 14771 c = utf_ptr2char(p); 14772 lc = utf_tolower(c); 14773 l = utf_ptr2len(p); 14774 /* TODO: reallocate string when byte count changes. */ 14775 if (utf_char2len(lc) == l) 14776 utf_char2bytes(lc, p); 14777 p += l; 14778 } 14779 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14780 p += l; /* skip multi-byte character */ 14781 else 14782 #endif 14783 { 14784 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14785 ++p; 14786 } 14787 } 14788 } 14789 14790 /* 14791 * "toupper(string)" function 14792 */ 14793 static void 14794 f_toupper(argvars, rettv) 14795 typval_T *argvars; 14796 typval_T *rettv; 14797 { 14798 rettv->v_type = VAR_STRING; 14799 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14800 } 14801 14802 /* 14803 * "tr(string, fromstr, tostr)" function 14804 */ 14805 static void 14806 f_tr(argvars, rettv) 14807 typval_T *argvars; 14808 typval_T *rettv; 14809 { 14810 char_u *instr; 14811 char_u *fromstr; 14812 char_u *tostr; 14813 char_u *p; 14814 #ifdef FEAT_MBYTE 14815 int inlen; 14816 int fromlen; 14817 int tolen; 14818 int idx; 14819 char_u *cpstr; 14820 int cplen; 14821 int first = TRUE; 14822 #endif 14823 char_u buf[NUMBUFLEN]; 14824 char_u buf2[NUMBUFLEN]; 14825 garray_T ga; 14826 14827 instr = get_tv_string(&argvars[0]); 14828 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14829 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14830 14831 /* Default return value: empty string. */ 14832 rettv->v_type = VAR_STRING; 14833 rettv->vval.v_string = NULL; 14834 if (fromstr == NULL || tostr == NULL) 14835 return; /* type error; errmsg already given */ 14836 ga_init2(&ga, (int)sizeof(char), 80); 14837 14838 #ifdef FEAT_MBYTE 14839 if (!has_mbyte) 14840 #endif 14841 /* not multi-byte: fromstr and tostr must be the same length */ 14842 if (STRLEN(fromstr) != STRLEN(tostr)) 14843 { 14844 #ifdef FEAT_MBYTE 14845 error: 14846 #endif 14847 EMSG2(_(e_invarg2), fromstr); 14848 ga_clear(&ga); 14849 return; 14850 } 14851 14852 /* fromstr and tostr have to contain the same number of chars */ 14853 while (*instr != NUL) 14854 { 14855 #ifdef FEAT_MBYTE 14856 if (has_mbyte) 14857 { 14858 inlen = (*mb_ptr2len)(instr); 14859 cpstr = instr; 14860 cplen = inlen; 14861 idx = 0; 14862 for (p = fromstr; *p != NUL; p += fromlen) 14863 { 14864 fromlen = (*mb_ptr2len)(p); 14865 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14866 { 14867 for (p = tostr; *p != NUL; p += tolen) 14868 { 14869 tolen = (*mb_ptr2len)(p); 14870 if (idx-- == 0) 14871 { 14872 cplen = tolen; 14873 cpstr = p; 14874 break; 14875 } 14876 } 14877 if (*p == NUL) /* tostr is shorter than fromstr */ 14878 goto error; 14879 break; 14880 } 14881 ++idx; 14882 } 14883 14884 if (first && cpstr == instr) 14885 { 14886 /* Check that fromstr and tostr have the same number of 14887 * (multi-byte) characters. Done only once when a character 14888 * of instr doesn't appear in fromstr. */ 14889 first = FALSE; 14890 for (p = tostr; *p != NUL; p += tolen) 14891 { 14892 tolen = (*mb_ptr2len)(p); 14893 --idx; 14894 } 14895 if (idx != 0) 14896 goto error; 14897 } 14898 14899 ga_grow(&ga, cplen); 14900 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14901 ga.ga_len += cplen; 14902 14903 instr += inlen; 14904 } 14905 else 14906 #endif 14907 { 14908 /* When not using multi-byte chars we can do it faster. */ 14909 p = vim_strchr(fromstr, *instr); 14910 if (p != NULL) 14911 ga_append(&ga, tostr[p - fromstr]); 14912 else 14913 ga_append(&ga, *instr); 14914 ++instr; 14915 } 14916 } 14917 14918 rettv->vval.v_string = ga.ga_data; 14919 } 14920 14921 /* 14922 * "type(expr)" function 14923 */ 14924 static void 14925 f_type(argvars, rettv) 14926 typval_T *argvars; 14927 typval_T *rettv; 14928 { 14929 int n; 14930 14931 switch (argvars[0].v_type) 14932 { 14933 case VAR_NUMBER: n = 0; break; 14934 case VAR_STRING: n = 1; break; 14935 case VAR_FUNC: n = 2; break; 14936 case VAR_LIST: n = 3; break; 14937 case VAR_DICT: n = 4; break; 14938 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14939 } 14940 rettv->vval.v_number = n; 14941 } 14942 14943 /* 14944 * "values(dict)" function 14945 */ 14946 static void 14947 f_values(argvars, rettv) 14948 typval_T *argvars; 14949 typval_T *rettv; 14950 { 14951 dict_list(argvars, rettv, 1); 14952 } 14953 14954 /* 14955 * "virtcol(string)" function 14956 */ 14957 static void 14958 f_virtcol(argvars, rettv) 14959 typval_T *argvars; 14960 typval_T *rettv; 14961 { 14962 colnr_T vcol = 0; 14963 pos_T *fp; 14964 14965 fp = var2fpos(&argvars[0], FALSE); 14966 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14967 { 14968 getvvcol(curwin, fp, NULL, NULL, &vcol); 14969 ++vcol; 14970 } 14971 14972 rettv->vval.v_number = vcol; 14973 } 14974 14975 /* 14976 * "visualmode()" function 14977 */ 14978 /*ARGSUSED*/ 14979 static void 14980 f_visualmode(argvars, rettv) 14981 typval_T *argvars; 14982 typval_T *rettv; 14983 { 14984 #ifdef FEAT_VISUAL 14985 char_u str[2]; 14986 14987 rettv->v_type = VAR_STRING; 14988 str[0] = curbuf->b_visual_mode_eval; 14989 str[1] = NUL; 14990 rettv->vval.v_string = vim_strsave(str); 14991 14992 /* A non-zero number or non-empty string argument: reset mode. */ 14993 if ((argvars[0].v_type == VAR_NUMBER 14994 && argvars[0].vval.v_number != 0) 14995 || (argvars[0].v_type == VAR_STRING 14996 && *get_tv_string(&argvars[0]) != NUL)) 14997 curbuf->b_visual_mode_eval = NUL; 14998 #else 14999 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 15000 #endif 15001 } 15002 15003 /* 15004 * "winbufnr(nr)" function 15005 */ 15006 static void 15007 f_winbufnr(argvars, rettv) 15008 typval_T *argvars; 15009 typval_T *rettv; 15010 { 15011 win_T *wp; 15012 15013 wp = find_win_by_nr(&argvars[0]); 15014 if (wp == NULL) 15015 rettv->vval.v_number = -1; 15016 else 15017 rettv->vval.v_number = wp->w_buffer->b_fnum; 15018 } 15019 15020 /* 15021 * "wincol()" function 15022 */ 15023 /*ARGSUSED*/ 15024 static void 15025 f_wincol(argvars, rettv) 15026 typval_T *argvars; 15027 typval_T *rettv; 15028 { 15029 validate_cursor(); 15030 rettv->vval.v_number = curwin->w_wcol + 1; 15031 } 15032 15033 /* 15034 * "winheight(nr)" function 15035 */ 15036 static void 15037 f_winheight(argvars, rettv) 15038 typval_T *argvars; 15039 typval_T *rettv; 15040 { 15041 win_T *wp; 15042 15043 wp = find_win_by_nr(&argvars[0]); 15044 if (wp == NULL) 15045 rettv->vval.v_number = -1; 15046 else 15047 rettv->vval.v_number = wp->w_height; 15048 } 15049 15050 /* 15051 * "winline()" function 15052 */ 15053 /*ARGSUSED*/ 15054 static void 15055 f_winline(argvars, rettv) 15056 typval_T *argvars; 15057 typval_T *rettv; 15058 { 15059 validate_cursor(); 15060 rettv->vval.v_number = curwin->w_wrow + 1; 15061 } 15062 15063 /* 15064 * "winnr()" function 15065 */ 15066 /* ARGSUSED */ 15067 static void 15068 f_winnr(argvars, rettv) 15069 typval_T *argvars; 15070 typval_T *rettv; 15071 { 15072 int nr = 1; 15073 #ifdef FEAT_WINDOWS 15074 win_T *wp; 15075 win_T *twin = curwin; 15076 char_u *arg; 15077 15078 if (argvars[0].v_type != VAR_UNKNOWN) 15079 { 15080 arg = get_tv_string_chk(&argvars[0]); 15081 if (arg == NULL) 15082 nr = 0; /* type error; errmsg already given */ 15083 else if (STRCMP(arg, "$") == 0) 15084 twin = lastwin; 15085 else if (STRCMP(arg, "#") == 0) 15086 { 15087 twin = prevwin; 15088 if (prevwin == NULL) 15089 nr = 0; 15090 } 15091 else 15092 { 15093 EMSG2(_(e_invexpr2), arg); 15094 nr = 0; 15095 } 15096 } 15097 15098 if (nr > 0) 15099 for (wp = firstwin; wp != twin; wp = wp->w_next) 15100 ++nr; 15101 #endif 15102 rettv->vval.v_number = nr; 15103 } 15104 15105 /* 15106 * "winrestcmd()" function 15107 */ 15108 /* ARGSUSED */ 15109 static void 15110 f_winrestcmd(argvars, rettv) 15111 typval_T *argvars; 15112 typval_T *rettv; 15113 { 15114 #ifdef FEAT_WINDOWS 15115 win_T *wp; 15116 int winnr = 1; 15117 garray_T ga; 15118 char_u buf[50]; 15119 15120 ga_init2(&ga, (int)sizeof(char), 70); 15121 for (wp = firstwin; wp != NULL; wp = wp->w_next) 15122 { 15123 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 15124 ga_concat(&ga, buf); 15125 # ifdef FEAT_VERTSPLIT 15126 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 15127 ga_concat(&ga, buf); 15128 # endif 15129 ++winnr; 15130 } 15131 ga_append(&ga, NUL); 15132 15133 rettv->vval.v_string = ga.ga_data; 15134 #else 15135 rettv->vval.v_string = NULL; 15136 #endif 15137 rettv->v_type = VAR_STRING; 15138 } 15139 15140 /* 15141 * "winwidth(nr)" function 15142 */ 15143 static void 15144 f_winwidth(argvars, rettv) 15145 typval_T *argvars; 15146 typval_T *rettv; 15147 { 15148 win_T *wp; 15149 15150 wp = find_win_by_nr(&argvars[0]); 15151 if (wp == NULL) 15152 rettv->vval.v_number = -1; 15153 else 15154 #ifdef FEAT_VERTSPLIT 15155 rettv->vval.v_number = wp->w_width; 15156 #else 15157 rettv->vval.v_number = Columns; 15158 #endif 15159 } 15160 15161 /* 15162 * "writefile()" function 15163 */ 15164 static void 15165 f_writefile(argvars, rettv) 15166 typval_T *argvars; 15167 typval_T *rettv; 15168 { 15169 int binary = FALSE; 15170 char_u *fname; 15171 FILE *fd; 15172 listitem_T *li; 15173 char_u *s; 15174 int ret = 0; 15175 int c; 15176 15177 if (argvars[0].v_type != VAR_LIST) 15178 { 15179 EMSG2(_(e_listarg), "writefile()"); 15180 return; 15181 } 15182 if (argvars[0].vval.v_list == NULL) 15183 return; 15184 15185 if (argvars[2].v_type != VAR_UNKNOWN 15186 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 15187 binary = TRUE; 15188 15189 /* Always open the file in binary mode, library functions have a mind of 15190 * their own about CR-LF conversion. */ 15191 fname = get_tv_string(&argvars[1]); 15192 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 15193 { 15194 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 15195 ret = -1; 15196 } 15197 else 15198 { 15199 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 15200 li = li->li_next) 15201 { 15202 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 15203 { 15204 if (*s == '\n') 15205 c = putc(NUL, fd); 15206 else 15207 c = putc(*s, fd); 15208 if (c == EOF) 15209 { 15210 ret = -1; 15211 break; 15212 } 15213 } 15214 if (!binary || li->li_next != NULL) 15215 if (putc('\n', fd) == EOF) 15216 { 15217 ret = -1; 15218 break; 15219 } 15220 if (ret < 0) 15221 { 15222 EMSG(_(e_write)); 15223 break; 15224 } 15225 } 15226 fclose(fd); 15227 } 15228 15229 rettv->vval.v_number = ret; 15230 } 15231 15232 /* 15233 * Translate a String variable into a position. 15234 */ 15235 static pos_T * 15236 var2fpos(varp, lnum) 15237 typval_T *varp; 15238 int lnum; /* TRUE when $ is last line */ 15239 { 15240 char_u *name; 15241 static pos_T pos; 15242 pos_T *pp; 15243 15244 name = get_tv_string_chk(varp); 15245 if (name == NULL) 15246 return NULL; 15247 if (name[0] == '.') /* cursor */ 15248 return &curwin->w_cursor; 15249 if (name[0] == '\'') /* mark */ 15250 { 15251 pp = getmark(name[1], FALSE); 15252 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15253 return NULL; 15254 return pp; 15255 } 15256 if (name[0] == '$') /* last column or line */ 15257 { 15258 if (lnum) 15259 { 15260 pos.lnum = curbuf->b_ml.ml_line_count; 15261 pos.col = 0; 15262 } 15263 else 15264 { 15265 pos.lnum = curwin->w_cursor.lnum; 15266 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15267 } 15268 return &pos; 15269 } 15270 return NULL; 15271 } 15272 15273 /* 15274 * Get the length of an environment variable name. 15275 * Advance "arg" to the first character after the name. 15276 * Return 0 for error. 15277 */ 15278 static int 15279 get_env_len(arg) 15280 char_u **arg; 15281 { 15282 char_u *p; 15283 int len; 15284 15285 for (p = *arg; vim_isIDc(*p); ++p) 15286 ; 15287 if (p == *arg) /* no name found */ 15288 return 0; 15289 15290 len = (int)(p - *arg); 15291 *arg = p; 15292 return len; 15293 } 15294 15295 /* 15296 * Get the length of the name of a function or internal variable. 15297 * "arg" is advanced to the first non-white character after the name. 15298 * Return 0 if something is wrong. 15299 */ 15300 static int 15301 get_id_len(arg) 15302 char_u **arg; 15303 { 15304 char_u *p; 15305 int len; 15306 15307 /* Find the end of the name. */ 15308 for (p = *arg; eval_isnamec(*p); ++p) 15309 ; 15310 if (p == *arg) /* no name found */ 15311 return 0; 15312 15313 len = (int)(p - *arg); 15314 *arg = skipwhite(p); 15315 15316 return len; 15317 } 15318 15319 /* 15320 * Get the length of the name of a variable or function. 15321 * Only the name is recognized, does not handle ".key" or "[idx]". 15322 * "arg" is advanced to the first non-white character after the name. 15323 * Return -1 if curly braces expansion failed. 15324 * Return 0 if something else is wrong. 15325 * If the name contains 'magic' {}'s, expand them and return the 15326 * expanded name in an allocated string via 'alias' - caller must free. 15327 */ 15328 static int 15329 get_name_len(arg, alias, evaluate, verbose) 15330 char_u **arg; 15331 char_u **alias; 15332 int evaluate; 15333 int verbose; 15334 { 15335 int len; 15336 char_u *p; 15337 char_u *expr_start; 15338 char_u *expr_end; 15339 15340 *alias = NULL; /* default to no alias */ 15341 15342 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15343 && (*arg)[2] == (int)KE_SNR) 15344 { 15345 /* hard coded <SNR>, already translated */ 15346 *arg += 3; 15347 return get_id_len(arg) + 3; 15348 } 15349 len = eval_fname_script(*arg); 15350 if (len > 0) 15351 { 15352 /* literal "<SID>", "s:" or "<SNR>" */ 15353 *arg += len; 15354 } 15355 15356 /* 15357 * Find the end of the name; check for {} construction. 15358 */ 15359 p = find_name_end(*arg, &expr_start, &expr_end, 15360 len > 0 ? 0 : FNE_CHECK_START); 15361 if (expr_start != NULL) 15362 { 15363 char_u *temp_string; 15364 15365 if (!evaluate) 15366 { 15367 len += (int)(p - *arg); 15368 *arg = skipwhite(p); 15369 return len; 15370 } 15371 15372 /* 15373 * Include any <SID> etc in the expanded string: 15374 * Thus the -len here. 15375 */ 15376 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15377 if (temp_string == NULL) 15378 return -1; 15379 *alias = temp_string; 15380 *arg = skipwhite(p); 15381 return (int)STRLEN(temp_string); 15382 } 15383 15384 len += get_id_len(arg); 15385 if (len == 0 && verbose) 15386 EMSG2(_(e_invexpr2), *arg); 15387 15388 return len; 15389 } 15390 15391 /* 15392 * Find the end of a variable or function name, taking care of magic braces. 15393 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15394 * start and end of the first magic braces item. 15395 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15396 * Return a pointer to just after the name. Equal to "arg" if there is no 15397 * valid name. 15398 */ 15399 static char_u * 15400 find_name_end(arg, expr_start, expr_end, flags) 15401 char_u *arg; 15402 char_u **expr_start; 15403 char_u **expr_end; 15404 int flags; 15405 { 15406 int mb_nest = 0; 15407 int br_nest = 0; 15408 char_u *p; 15409 15410 if (expr_start != NULL) 15411 { 15412 *expr_start = NULL; 15413 *expr_end = NULL; 15414 } 15415 15416 /* Quick check for valid starting character. */ 15417 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15418 return arg; 15419 15420 for (p = arg; *p != NUL 15421 && (eval_isnamec(*p) 15422 || *p == '{' 15423 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15424 || mb_nest != 0 15425 || br_nest != 0); mb_ptr_adv(p)) 15426 { 15427 if (*p == '\'') 15428 { 15429 /* skip over 'string' to avoid counting [ and ] inside it. */ 15430 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15431 ; 15432 if (*p == NUL) 15433 break; 15434 } 15435 else if (*p == '"') 15436 { 15437 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15438 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15439 if (*p == '\\' && p[1] != NUL) 15440 ++p; 15441 if (*p == NUL) 15442 break; 15443 } 15444 15445 if (mb_nest == 0) 15446 { 15447 if (*p == '[') 15448 ++br_nest; 15449 else if (*p == ']') 15450 --br_nest; 15451 } 15452 15453 if (br_nest == 0) 15454 { 15455 if (*p == '{') 15456 { 15457 mb_nest++; 15458 if (expr_start != NULL && *expr_start == NULL) 15459 *expr_start = p; 15460 } 15461 else if (*p == '}') 15462 { 15463 mb_nest--; 15464 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15465 *expr_end = p; 15466 } 15467 } 15468 } 15469 15470 return p; 15471 } 15472 15473 /* 15474 * Expands out the 'magic' {}'s in a variable/function name. 15475 * Note that this can call itself recursively, to deal with 15476 * constructs like foo{bar}{baz}{bam} 15477 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15478 * "in_start" ^ 15479 * "expr_start" ^ 15480 * "expr_end" ^ 15481 * "in_end" ^ 15482 * 15483 * Returns a new allocated string, which the caller must free. 15484 * Returns NULL for failure. 15485 */ 15486 static char_u * 15487 make_expanded_name(in_start, expr_start, expr_end, in_end) 15488 char_u *in_start; 15489 char_u *expr_start; 15490 char_u *expr_end; 15491 char_u *in_end; 15492 { 15493 char_u c1; 15494 char_u *retval = NULL; 15495 char_u *temp_result; 15496 char_u *nextcmd = NULL; 15497 15498 if (expr_end == NULL || in_end == NULL) 15499 return NULL; 15500 *expr_start = NUL; 15501 *expr_end = NUL; 15502 c1 = *in_end; 15503 *in_end = NUL; 15504 15505 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15506 if (temp_result != NULL && nextcmd == NULL) 15507 { 15508 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15509 + (in_end - expr_end) + 1)); 15510 if (retval != NULL) 15511 { 15512 STRCPY(retval, in_start); 15513 STRCAT(retval, temp_result); 15514 STRCAT(retval, expr_end + 1); 15515 } 15516 } 15517 vim_free(temp_result); 15518 15519 *in_end = c1; /* put char back for error messages */ 15520 *expr_start = '{'; 15521 *expr_end = '}'; 15522 15523 if (retval != NULL) 15524 { 15525 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15526 if (expr_start != NULL) 15527 { 15528 /* Further expansion! */ 15529 temp_result = make_expanded_name(retval, expr_start, 15530 expr_end, temp_result); 15531 vim_free(retval); 15532 retval = temp_result; 15533 } 15534 } 15535 15536 return retval; 15537 } 15538 15539 /* 15540 * Return TRUE if character "c" can be used in a variable or function name. 15541 * Does not include '{' or '}' for magic braces. 15542 */ 15543 static int 15544 eval_isnamec(c) 15545 int c; 15546 { 15547 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15548 } 15549 15550 /* 15551 * Return TRUE if character "c" can be used as the first character in a 15552 * variable or function name (excluding '{' and '}'). 15553 */ 15554 static int 15555 eval_isnamec1(c) 15556 int c; 15557 { 15558 return (ASCII_ISALPHA(c) || c == '_'); 15559 } 15560 15561 /* 15562 * Set number v: variable to "val". 15563 */ 15564 void 15565 set_vim_var_nr(idx, val) 15566 int idx; 15567 long val; 15568 { 15569 vimvars[idx].vv_nr = val; 15570 } 15571 15572 /* 15573 * Get number v: variable value. 15574 */ 15575 long 15576 get_vim_var_nr(idx) 15577 int idx; 15578 { 15579 return vimvars[idx].vv_nr; 15580 } 15581 15582 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15583 /* 15584 * Get string v: variable value. Uses a static buffer, can only be used once. 15585 */ 15586 char_u * 15587 get_vim_var_str(idx) 15588 int idx; 15589 { 15590 return get_tv_string(&vimvars[idx].vv_tv); 15591 } 15592 #endif 15593 15594 /* 15595 * Set v:count, v:count1 and v:prevcount. 15596 */ 15597 void 15598 set_vcount(count, count1) 15599 long count; 15600 long count1; 15601 { 15602 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15603 vimvars[VV_COUNT].vv_nr = count; 15604 vimvars[VV_COUNT1].vv_nr = count1; 15605 } 15606 15607 /* 15608 * Set string v: variable to a copy of "val". 15609 */ 15610 void 15611 set_vim_var_string(idx, val, len) 15612 int idx; 15613 char_u *val; 15614 int len; /* length of "val" to use or -1 (whole string) */ 15615 { 15616 /* Need to do this (at least) once, since we can't initialize a union. 15617 * Will always be invoked when "v:progname" is set. */ 15618 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15619 15620 vim_free(vimvars[idx].vv_str); 15621 if (val == NULL) 15622 vimvars[idx].vv_str = NULL; 15623 else if (len == -1) 15624 vimvars[idx].vv_str = vim_strsave(val); 15625 else 15626 vimvars[idx].vv_str = vim_strnsave(val, len); 15627 } 15628 15629 /* 15630 * Set v:register if needed. 15631 */ 15632 void 15633 set_reg_var(c) 15634 int c; 15635 { 15636 char_u regname; 15637 15638 if (c == 0 || c == ' ') 15639 regname = '"'; 15640 else 15641 regname = c; 15642 /* Avoid free/alloc when the value is already right. */ 15643 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15644 set_vim_var_string(VV_REG, ®name, 1); 15645 } 15646 15647 /* 15648 * Get or set v:exception. If "oldval" == NULL, return the current value. 15649 * Otherwise, restore the value to "oldval" and return NULL. 15650 * Must always be called in pairs to save and restore v:exception! Does not 15651 * take care of memory allocations. 15652 */ 15653 char_u * 15654 v_exception(oldval) 15655 char_u *oldval; 15656 { 15657 if (oldval == NULL) 15658 return vimvars[VV_EXCEPTION].vv_str; 15659 15660 vimvars[VV_EXCEPTION].vv_str = oldval; 15661 return NULL; 15662 } 15663 15664 /* 15665 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15666 * Otherwise, restore the value to "oldval" and return NULL. 15667 * Must always be called in pairs to save and restore v:throwpoint! Does not 15668 * take care of memory allocations. 15669 */ 15670 char_u * 15671 v_throwpoint(oldval) 15672 char_u *oldval; 15673 { 15674 if (oldval == NULL) 15675 return vimvars[VV_THROWPOINT].vv_str; 15676 15677 vimvars[VV_THROWPOINT].vv_str = oldval; 15678 return NULL; 15679 } 15680 15681 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15682 /* 15683 * Set v:cmdarg. 15684 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15685 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15686 * Must always be called in pairs! 15687 */ 15688 char_u * 15689 set_cmdarg(eap, oldarg) 15690 exarg_T *eap; 15691 char_u *oldarg; 15692 { 15693 char_u *oldval; 15694 char_u *newval; 15695 unsigned len; 15696 15697 oldval = vimvars[VV_CMDARG].vv_str; 15698 if (eap == NULL) 15699 { 15700 vim_free(oldval); 15701 vimvars[VV_CMDARG].vv_str = oldarg; 15702 return NULL; 15703 } 15704 15705 if (eap->force_bin == FORCE_BIN) 15706 len = 6; 15707 else if (eap->force_bin == FORCE_NOBIN) 15708 len = 8; 15709 else 15710 len = 0; 15711 if (eap->force_ff != 0) 15712 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15713 # ifdef FEAT_MBYTE 15714 if (eap->force_enc != 0) 15715 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15716 # endif 15717 15718 newval = alloc(len + 1); 15719 if (newval == NULL) 15720 return NULL; 15721 15722 if (eap->force_bin == FORCE_BIN) 15723 sprintf((char *)newval, " ++bin"); 15724 else if (eap->force_bin == FORCE_NOBIN) 15725 sprintf((char *)newval, " ++nobin"); 15726 else 15727 *newval = NUL; 15728 if (eap->force_ff != 0) 15729 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15730 eap->cmd + eap->force_ff); 15731 # ifdef FEAT_MBYTE 15732 if (eap->force_enc != 0) 15733 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15734 eap->cmd + eap->force_enc); 15735 # endif 15736 vimvars[VV_CMDARG].vv_str = newval; 15737 return oldval; 15738 } 15739 #endif 15740 15741 /* 15742 * Get the value of internal variable "name". 15743 * Return OK or FAIL. 15744 */ 15745 static int 15746 get_var_tv(name, len, rettv, verbose) 15747 char_u *name; 15748 int len; /* length of "name" */ 15749 typval_T *rettv; /* NULL when only checking existence */ 15750 int verbose; /* may give error message */ 15751 { 15752 int ret = OK; 15753 typval_T *tv = NULL; 15754 typval_T atv; 15755 dictitem_T *v; 15756 int cc; 15757 15758 /* truncate the name, so that we can use strcmp() */ 15759 cc = name[len]; 15760 name[len] = NUL; 15761 15762 /* 15763 * Check for "b:changedtick". 15764 */ 15765 if (STRCMP(name, "b:changedtick") == 0) 15766 { 15767 atv.v_type = VAR_NUMBER; 15768 atv.vval.v_number = curbuf->b_changedtick; 15769 tv = &atv; 15770 } 15771 15772 /* 15773 * Check for user-defined variables. 15774 */ 15775 else 15776 { 15777 v = find_var(name, NULL); 15778 if (v != NULL) 15779 tv = &v->di_tv; 15780 } 15781 15782 if (tv == NULL) 15783 { 15784 if (rettv != NULL && verbose) 15785 EMSG2(_(e_undefvar), name); 15786 ret = FAIL; 15787 } 15788 else if (rettv != NULL) 15789 copy_tv(tv, rettv); 15790 15791 name[len] = cc; 15792 15793 return ret; 15794 } 15795 15796 /* 15797 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15798 * Also handle function call with Funcref variable: func(expr) 15799 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15800 */ 15801 static int 15802 handle_subscript(arg, rettv, evaluate, verbose) 15803 char_u **arg; 15804 typval_T *rettv; 15805 int evaluate; /* do more than finding the end */ 15806 int verbose; /* give error messages */ 15807 { 15808 int ret = OK; 15809 dict_T *selfdict = NULL; 15810 char_u *s; 15811 int len; 15812 typval_T functv; 15813 15814 while (ret == OK 15815 && (**arg == '[' 15816 || (**arg == '.' && rettv->v_type == VAR_DICT) 15817 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15818 && !vim_iswhite(*(*arg - 1))) 15819 { 15820 if (**arg == '(') 15821 { 15822 /* need to copy the funcref so that we can clear rettv */ 15823 functv = *rettv; 15824 rettv->v_type = VAR_UNKNOWN; 15825 15826 /* Invoke the function. Recursive! */ 15827 s = functv.vval.v_string; 15828 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15829 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15830 &len, evaluate, selfdict); 15831 15832 /* Clear the funcref afterwards, so that deleting it while 15833 * evaluating the arguments is possible (see test55). */ 15834 clear_tv(&functv); 15835 15836 /* Stop the expression evaluation when immediately aborting on 15837 * error, or when an interrupt occurred or an exception was thrown 15838 * but not caught. */ 15839 if (aborting()) 15840 { 15841 if (ret == OK) 15842 clear_tv(rettv); 15843 ret = FAIL; 15844 } 15845 dict_unref(selfdict); 15846 selfdict = NULL; 15847 } 15848 else /* **arg == '[' || **arg == '.' */ 15849 { 15850 dict_unref(selfdict); 15851 if (rettv->v_type == VAR_DICT) 15852 { 15853 selfdict = rettv->vval.v_dict; 15854 if (selfdict != NULL) 15855 ++selfdict->dv_refcount; 15856 } 15857 else 15858 selfdict = NULL; 15859 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15860 { 15861 clear_tv(rettv); 15862 ret = FAIL; 15863 } 15864 } 15865 } 15866 dict_unref(selfdict); 15867 return ret; 15868 } 15869 15870 /* 15871 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15872 * value). 15873 */ 15874 static typval_T * 15875 alloc_tv() 15876 { 15877 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15878 } 15879 15880 /* 15881 * Allocate memory for a variable type-value, and assign a string to it. 15882 * The string "s" must have been allocated, it is consumed. 15883 * Return NULL for out of memory, the variable otherwise. 15884 */ 15885 static typval_T * 15886 alloc_string_tv(s) 15887 char_u *s; 15888 { 15889 typval_T *rettv; 15890 15891 rettv = alloc_tv(); 15892 if (rettv != NULL) 15893 { 15894 rettv->v_type = VAR_STRING; 15895 rettv->vval.v_string = s; 15896 } 15897 else 15898 vim_free(s); 15899 return rettv; 15900 } 15901 15902 /* 15903 * Free the memory for a variable type-value. 15904 */ 15905 static void 15906 free_tv(varp) 15907 typval_T *varp; 15908 { 15909 if (varp != NULL) 15910 { 15911 switch (varp->v_type) 15912 { 15913 case VAR_FUNC: 15914 func_unref(varp->vval.v_string); 15915 /*FALLTHROUGH*/ 15916 case VAR_STRING: 15917 vim_free(varp->vval.v_string); 15918 break; 15919 case VAR_LIST: 15920 list_unref(varp->vval.v_list); 15921 break; 15922 case VAR_DICT: 15923 dict_unref(varp->vval.v_dict); 15924 break; 15925 case VAR_NUMBER: 15926 case VAR_UNKNOWN: 15927 break; 15928 default: 15929 EMSG2(_(e_intern2), "free_tv()"); 15930 break; 15931 } 15932 vim_free(varp); 15933 } 15934 } 15935 15936 /* 15937 * Free the memory for a variable value and set the value to NULL or 0. 15938 */ 15939 void 15940 clear_tv(varp) 15941 typval_T *varp; 15942 { 15943 if (varp != NULL) 15944 { 15945 switch (varp->v_type) 15946 { 15947 case VAR_FUNC: 15948 func_unref(varp->vval.v_string); 15949 /*FALLTHROUGH*/ 15950 case VAR_STRING: 15951 vim_free(varp->vval.v_string); 15952 varp->vval.v_string = NULL; 15953 break; 15954 case VAR_LIST: 15955 list_unref(varp->vval.v_list); 15956 varp->vval.v_list = NULL; 15957 break; 15958 case VAR_DICT: 15959 dict_unref(varp->vval.v_dict); 15960 varp->vval.v_dict = NULL; 15961 break; 15962 case VAR_NUMBER: 15963 varp->vval.v_number = 0; 15964 break; 15965 case VAR_UNKNOWN: 15966 break; 15967 default: 15968 EMSG2(_(e_intern2), "clear_tv()"); 15969 } 15970 varp->v_lock = 0; 15971 } 15972 } 15973 15974 /* 15975 * Set the value of a variable to NULL without freeing items. 15976 */ 15977 static void 15978 init_tv(varp) 15979 typval_T *varp; 15980 { 15981 if (varp != NULL) 15982 vim_memset(varp, 0, sizeof(typval_T)); 15983 } 15984 15985 /* 15986 * Get the number value of a variable. 15987 * If it is a String variable, uses vim_str2nr(). 15988 * For incompatible types, return 0. 15989 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15990 * caller of incompatible types: it sets *denote to TRUE if "denote" 15991 * is not NULL or returns -1 otherwise. 15992 */ 15993 static long 15994 get_tv_number(varp) 15995 typval_T *varp; 15996 { 15997 int error = FALSE; 15998 15999 return get_tv_number_chk(varp, &error); /* return 0L on error */ 16000 } 16001 16002 long 16003 get_tv_number_chk(varp, denote) 16004 typval_T *varp; 16005 int *denote; 16006 { 16007 long n = 0L; 16008 16009 switch (varp->v_type) 16010 { 16011 case VAR_NUMBER: 16012 return (long)(varp->vval.v_number); 16013 case VAR_FUNC: 16014 EMSG(_("E703: Using a Funcref as a number")); 16015 break; 16016 case VAR_STRING: 16017 if (varp->vval.v_string != NULL) 16018 vim_str2nr(varp->vval.v_string, NULL, NULL, 16019 TRUE, TRUE, &n, NULL); 16020 return n; 16021 case VAR_LIST: 16022 EMSG(_("E745: Using a List as a number")); 16023 break; 16024 case VAR_DICT: 16025 EMSG(_("E728: Using a Dictionary as a number")); 16026 break; 16027 default: 16028 EMSG2(_(e_intern2), "get_tv_number()"); 16029 break; 16030 } 16031 if (denote == NULL) /* useful for values that must be unsigned */ 16032 n = -1; 16033 else 16034 *denote = TRUE; 16035 return n; 16036 } 16037 16038 /* 16039 * Get the lnum from the first argument. 16040 * Also accepts ".", "$", etc., but that only works for the current buffer. 16041 * Returns -1 on error. 16042 */ 16043 static linenr_T 16044 get_tv_lnum(argvars) 16045 typval_T *argvars; 16046 { 16047 typval_T rettv; 16048 linenr_T lnum; 16049 16050 lnum = get_tv_number_chk(&argvars[0], NULL); 16051 if (lnum == 0) /* no valid number, try using line() */ 16052 { 16053 rettv.v_type = VAR_NUMBER; 16054 f_line(argvars, &rettv); 16055 lnum = rettv.vval.v_number; 16056 clear_tv(&rettv); 16057 } 16058 return lnum; 16059 } 16060 16061 /* 16062 * Get the lnum from the first argument. 16063 * Also accepts "$", then "buf" is used. 16064 * Returns 0 on error. 16065 */ 16066 static linenr_T 16067 get_tv_lnum_buf(argvars, buf) 16068 typval_T *argvars; 16069 buf_T *buf; 16070 { 16071 if (argvars[0].v_type == VAR_STRING 16072 && argvars[0].vval.v_string != NULL 16073 && argvars[0].vval.v_string[0] == '$' 16074 && buf != NULL) 16075 return buf->b_ml.ml_line_count; 16076 return get_tv_number_chk(&argvars[0], NULL); 16077 } 16078 16079 /* 16080 * Get the string value of a variable. 16081 * If it is a Number variable, the number is converted into a string. 16082 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 16083 * get_tv_string_buf() uses a given buffer. 16084 * If the String variable has never been set, return an empty string. 16085 * Never returns NULL; 16086 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 16087 * NULL on error. 16088 */ 16089 static char_u * 16090 get_tv_string(varp) 16091 typval_T *varp; 16092 { 16093 static char_u mybuf[NUMBUFLEN]; 16094 16095 return get_tv_string_buf(varp, mybuf); 16096 } 16097 16098 static char_u * 16099 get_tv_string_buf(varp, buf) 16100 typval_T *varp; 16101 char_u *buf; 16102 { 16103 char_u *res = get_tv_string_buf_chk(varp, buf); 16104 16105 return res != NULL ? res : (char_u *)""; 16106 } 16107 16108 char_u * 16109 get_tv_string_chk(varp) 16110 typval_T *varp; 16111 { 16112 static char_u mybuf[NUMBUFLEN]; 16113 16114 return get_tv_string_buf_chk(varp, mybuf); 16115 } 16116 16117 static char_u * 16118 get_tv_string_buf_chk(varp, buf) 16119 typval_T *varp; 16120 char_u *buf; 16121 { 16122 switch (varp->v_type) 16123 { 16124 case VAR_NUMBER: 16125 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 16126 return buf; 16127 case VAR_FUNC: 16128 EMSG(_("E729: using Funcref as a String")); 16129 break; 16130 case VAR_LIST: 16131 EMSG(_("E730: using List as a String")); 16132 break; 16133 case VAR_DICT: 16134 EMSG(_("E731: using Dictionary as a String")); 16135 break; 16136 case VAR_STRING: 16137 if (varp->vval.v_string != NULL) 16138 return varp->vval.v_string; 16139 return (char_u *)""; 16140 default: 16141 EMSG2(_(e_intern2), "get_tv_string_buf()"); 16142 break; 16143 } 16144 return NULL; 16145 } 16146 16147 /* 16148 * Find variable "name" in the list of variables. 16149 * Return a pointer to it if found, NULL if not found. 16150 * Careful: "a:0" variables don't have a name. 16151 * When "htp" is not NULL we are writing to the variable, set "htp" to the 16152 * hashtab_T used. 16153 */ 16154 static dictitem_T * 16155 find_var(name, htp) 16156 char_u *name; 16157 hashtab_T **htp; 16158 { 16159 char_u *varname; 16160 hashtab_T *ht; 16161 16162 ht = find_var_ht(name, &varname); 16163 if (htp != NULL) 16164 *htp = ht; 16165 if (ht == NULL) 16166 return NULL; 16167 return find_var_in_ht(ht, varname, htp != NULL); 16168 } 16169 16170 /* 16171 * Find variable "varname" in hashtab "ht". 16172 * Returns NULL if not found. 16173 */ 16174 static dictitem_T * 16175 find_var_in_ht(ht, varname, writing) 16176 hashtab_T *ht; 16177 char_u *varname; 16178 int writing; 16179 { 16180 hashitem_T *hi; 16181 16182 if (*varname == NUL) 16183 { 16184 /* Must be something like "s:", otherwise "ht" would be NULL. */ 16185 switch (varname[-2]) 16186 { 16187 case 's': return &SCRIPT_SV(current_SID).sv_var; 16188 case 'g': return &globvars_var; 16189 case 'v': return &vimvars_var; 16190 case 'b': return &curbuf->b_bufvar; 16191 case 'w': return &curwin->w_winvar; 16192 case 'l': return current_funccal == NULL 16193 ? NULL : ¤t_funccal->l_vars_var; 16194 case 'a': return current_funccal == NULL 16195 ? NULL : ¤t_funccal->l_avars_var; 16196 } 16197 return NULL; 16198 } 16199 16200 hi = hash_find(ht, varname); 16201 if (HASHITEM_EMPTY(hi)) 16202 { 16203 /* For global variables we may try auto-loading the script. If it 16204 * worked find the variable again. Don't auto-load a script if it was 16205 * loaded already, otherwise it would be loaded every time when 16206 * checking if a function name is a Funcref variable. */ 16207 if (ht == &globvarht && !writing 16208 && script_autoload(varname, FALSE) && !aborting()) 16209 hi = hash_find(ht, varname); 16210 if (HASHITEM_EMPTY(hi)) 16211 return NULL; 16212 } 16213 return HI2DI(hi); 16214 } 16215 16216 /* 16217 * Find the hashtab used for a variable name. 16218 * Set "varname" to the start of name without ':'. 16219 */ 16220 static hashtab_T * 16221 find_var_ht(name, varname) 16222 char_u *name; 16223 char_u **varname; 16224 { 16225 hashitem_T *hi; 16226 16227 if (name[1] != ':') 16228 { 16229 /* The name must not start with a colon or #. */ 16230 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16231 return NULL; 16232 *varname = name; 16233 16234 /* "version" is "v:version" in all scopes */ 16235 hi = hash_find(&compat_hashtab, name); 16236 if (!HASHITEM_EMPTY(hi)) 16237 return &compat_hashtab; 16238 16239 if (current_funccal == NULL) 16240 return &globvarht; /* global variable */ 16241 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16242 } 16243 *varname = name + 2; 16244 if (*name == 'g') /* global variable */ 16245 return &globvarht; 16246 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16247 */ 16248 if (vim_strchr(name + 2, ':') != NULL 16249 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16250 return NULL; 16251 if (*name == 'b') /* buffer variable */ 16252 return &curbuf->b_vars.dv_hashtab; 16253 if (*name == 'w') /* window variable */ 16254 return &curwin->w_vars.dv_hashtab; 16255 if (*name == 'v') /* v: variable */ 16256 return &vimvarht; 16257 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16258 return ¤t_funccal->l_avars.dv_hashtab; 16259 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16260 return ¤t_funccal->l_vars.dv_hashtab; 16261 if (*name == 's' /* script variable */ 16262 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16263 return &SCRIPT_VARS(current_SID); 16264 return NULL; 16265 } 16266 16267 /* 16268 * Get the string value of a (global/local) variable. 16269 * Returns NULL when it doesn't exist. 16270 */ 16271 char_u * 16272 get_var_value(name) 16273 char_u *name; 16274 { 16275 dictitem_T *v; 16276 16277 v = find_var(name, NULL); 16278 if (v == NULL) 16279 return NULL; 16280 return get_tv_string(&v->di_tv); 16281 } 16282 16283 /* 16284 * Allocate a new hashtab for a sourced script. It will be used while 16285 * sourcing this script and when executing functions defined in the script. 16286 */ 16287 void 16288 new_script_vars(id) 16289 scid_T id; 16290 { 16291 int i; 16292 hashtab_T *ht; 16293 scriptvar_T *sv; 16294 16295 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16296 { 16297 /* Re-allocating ga_data means that an ht_array pointing to 16298 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16299 * at its init value. Also reset "v_dict", it's always the same. */ 16300 for (i = 1; i <= ga_scripts.ga_len; ++i) 16301 { 16302 ht = &SCRIPT_VARS(i); 16303 if (ht->ht_mask == HT_INIT_SIZE - 1) 16304 ht->ht_array = ht->ht_smallarray; 16305 sv = &SCRIPT_SV(i); 16306 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16307 } 16308 16309 while (ga_scripts.ga_len < id) 16310 { 16311 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16312 init_var_dict(&sv->sv_dict, &sv->sv_var); 16313 ++ga_scripts.ga_len; 16314 } 16315 } 16316 } 16317 16318 /* 16319 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16320 * point to it. 16321 */ 16322 void 16323 init_var_dict(dict, dict_var) 16324 dict_T *dict; 16325 dictitem_T *dict_var; 16326 { 16327 hash_init(&dict->dv_hashtab); 16328 dict->dv_refcount = 99999; 16329 dict_var->di_tv.vval.v_dict = dict; 16330 dict_var->di_tv.v_type = VAR_DICT; 16331 dict_var->di_tv.v_lock = VAR_FIXED; 16332 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16333 dict_var->di_key[0] = NUL; 16334 } 16335 16336 /* 16337 * Clean up a list of internal variables. 16338 * Frees all allocated variables and the value they contain. 16339 * Clears hashtab "ht", does not free it. 16340 */ 16341 void 16342 vars_clear(ht) 16343 hashtab_T *ht; 16344 { 16345 vars_clear_ext(ht, TRUE); 16346 } 16347 16348 /* 16349 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16350 */ 16351 static void 16352 vars_clear_ext(ht, free_val) 16353 hashtab_T *ht; 16354 int free_val; 16355 { 16356 int todo; 16357 hashitem_T *hi; 16358 dictitem_T *v; 16359 16360 hash_lock(ht); 16361 todo = ht->ht_used; 16362 for (hi = ht->ht_array; todo > 0; ++hi) 16363 { 16364 if (!HASHITEM_EMPTY(hi)) 16365 { 16366 --todo; 16367 16368 /* Free the variable. Don't remove it from the hashtab, 16369 * ht_array might change then. hash_clear() takes care of it 16370 * later. */ 16371 v = HI2DI(hi); 16372 if (free_val) 16373 clear_tv(&v->di_tv); 16374 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16375 vim_free(v); 16376 } 16377 } 16378 hash_clear(ht); 16379 ht->ht_used = 0; 16380 } 16381 16382 /* 16383 * Delete a variable from hashtab "ht" at item "hi". 16384 * Clear the variable value and free the dictitem. 16385 */ 16386 static void 16387 delete_var(ht, hi) 16388 hashtab_T *ht; 16389 hashitem_T *hi; 16390 { 16391 dictitem_T *di = HI2DI(hi); 16392 16393 hash_remove(ht, hi); 16394 clear_tv(&di->di_tv); 16395 vim_free(di); 16396 } 16397 16398 /* 16399 * List the value of one internal variable. 16400 */ 16401 static void 16402 list_one_var(v, prefix) 16403 dictitem_T *v; 16404 char_u *prefix; 16405 { 16406 char_u *tofree; 16407 char_u *s; 16408 char_u numbuf[NUMBUFLEN]; 16409 16410 s = echo_string(&v->di_tv, &tofree, numbuf); 16411 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16412 s == NULL ? (char_u *)"" : s); 16413 vim_free(tofree); 16414 } 16415 16416 static void 16417 list_one_var_a(prefix, name, type, string) 16418 char_u *prefix; 16419 char_u *name; 16420 int type; 16421 char_u *string; 16422 { 16423 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16424 if (name != NULL) /* "a:" vars don't have a name stored */ 16425 msg_puts(name); 16426 msg_putchar(' '); 16427 msg_advance(22); 16428 if (type == VAR_NUMBER) 16429 msg_putchar('#'); 16430 else if (type == VAR_FUNC) 16431 msg_putchar('*'); 16432 else if (type == VAR_LIST) 16433 { 16434 msg_putchar('['); 16435 if (*string == '[') 16436 ++string; 16437 } 16438 else if (type == VAR_DICT) 16439 { 16440 msg_putchar('{'); 16441 if (*string == '{') 16442 ++string; 16443 } 16444 else 16445 msg_putchar(' '); 16446 16447 msg_outtrans(string); 16448 16449 if (type == VAR_FUNC) 16450 msg_puts((char_u *)"()"); 16451 } 16452 16453 /* 16454 * Set variable "name" to value in "tv". 16455 * If the variable already exists, the value is updated. 16456 * Otherwise the variable is created. 16457 */ 16458 static void 16459 set_var(name, tv, copy) 16460 char_u *name; 16461 typval_T *tv; 16462 int copy; /* make copy of value in "tv" */ 16463 { 16464 dictitem_T *v; 16465 char_u *varname; 16466 hashtab_T *ht; 16467 char_u *p; 16468 16469 if (tv->v_type == VAR_FUNC) 16470 { 16471 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16472 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16473 ? name[2] : name[0])) 16474 { 16475 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16476 return; 16477 } 16478 if (function_exists(name)) 16479 { 16480 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16481 name); 16482 return; 16483 } 16484 } 16485 16486 ht = find_var_ht(name, &varname); 16487 if (ht == NULL || *varname == NUL) 16488 { 16489 EMSG2(_(e_illvar), name); 16490 return; 16491 } 16492 16493 v = find_var_in_ht(ht, varname, TRUE); 16494 if (v != NULL) 16495 { 16496 /* existing variable, need to clear the value */ 16497 if (var_check_ro(v->di_flags, name) 16498 || tv_check_lock(v->di_tv.v_lock, name)) 16499 return; 16500 if (v->di_tv.v_type != tv->v_type 16501 && !((v->di_tv.v_type == VAR_STRING 16502 || v->di_tv.v_type == VAR_NUMBER) 16503 && (tv->v_type == VAR_STRING 16504 || tv->v_type == VAR_NUMBER))) 16505 { 16506 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16507 return; 16508 } 16509 16510 /* 16511 * Handle setting internal v: variables separately: we don't change 16512 * the type. 16513 */ 16514 if (ht == &vimvarht) 16515 { 16516 if (v->di_tv.v_type == VAR_STRING) 16517 { 16518 vim_free(v->di_tv.vval.v_string); 16519 if (copy || tv->v_type != VAR_STRING) 16520 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16521 else 16522 { 16523 /* Take over the string to avoid an extra alloc/free. */ 16524 v->di_tv.vval.v_string = tv->vval.v_string; 16525 tv->vval.v_string = NULL; 16526 } 16527 } 16528 else if (v->di_tv.v_type != VAR_NUMBER) 16529 EMSG2(_(e_intern2), "set_var()"); 16530 else 16531 v->di_tv.vval.v_number = get_tv_number(tv); 16532 return; 16533 } 16534 16535 clear_tv(&v->di_tv); 16536 } 16537 else /* add a new variable */ 16538 { 16539 /* Make sure the variable name is valid. */ 16540 for (p = varname; *p != NUL; ++p) 16541 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16542 { 16543 EMSG2(_(e_illvar), varname); 16544 return; 16545 } 16546 16547 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16548 + STRLEN(varname))); 16549 if (v == NULL) 16550 return; 16551 STRCPY(v->di_key, varname); 16552 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16553 { 16554 vim_free(v); 16555 return; 16556 } 16557 v->di_flags = 0; 16558 } 16559 16560 if (copy || tv->v_type == VAR_NUMBER) 16561 copy_tv(tv, &v->di_tv); 16562 else 16563 { 16564 v->di_tv = *tv; 16565 v->di_tv.v_lock = 0; 16566 init_tv(tv); 16567 } 16568 } 16569 16570 /* 16571 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16572 * Also give an error message. 16573 */ 16574 static int 16575 var_check_ro(flags, name) 16576 int flags; 16577 char_u *name; 16578 { 16579 if (flags & DI_FLAGS_RO) 16580 { 16581 EMSG2(_(e_readonlyvar), name); 16582 return TRUE; 16583 } 16584 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16585 { 16586 EMSG2(_(e_readonlysbx), name); 16587 return TRUE; 16588 } 16589 return FALSE; 16590 } 16591 16592 /* 16593 * Return TRUE if typeval "tv" is set to be locked (immutable). 16594 * Also give an error message, using "name". 16595 */ 16596 static int 16597 tv_check_lock(lock, name) 16598 int lock; 16599 char_u *name; 16600 { 16601 if (lock & VAR_LOCKED) 16602 { 16603 EMSG2(_("E741: Value is locked: %s"), 16604 name == NULL ? (char_u *)_("Unknown") : name); 16605 return TRUE; 16606 } 16607 if (lock & VAR_FIXED) 16608 { 16609 EMSG2(_("E742: Cannot change value of %s"), 16610 name == NULL ? (char_u *)_("Unknown") : name); 16611 return TRUE; 16612 } 16613 return FALSE; 16614 } 16615 16616 /* 16617 * Copy the values from typval_T "from" to typval_T "to". 16618 * When needed allocates string or increases reference count. 16619 * Does not make a copy of a list or dict but copies the reference! 16620 */ 16621 static void 16622 copy_tv(from, to) 16623 typval_T *from; 16624 typval_T *to; 16625 { 16626 to->v_type = from->v_type; 16627 to->v_lock = 0; 16628 switch (from->v_type) 16629 { 16630 case VAR_NUMBER: 16631 to->vval.v_number = from->vval.v_number; 16632 break; 16633 case VAR_STRING: 16634 case VAR_FUNC: 16635 if (from->vval.v_string == NULL) 16636 to->vval.v_string = NULL; 16637 else 16638 { 16639 to->vval.v_string = vim_strsave(from->vval.v_string); 16640 if (from->v_type == VAR_FUNC) 16641 func_ref(to->vval.v_string); 16642 } 16643 break; 16644 case VAR_LIST: 16645 if (from->vval.v_list == NULL) 16646 to->vval.v_list = NULL; 16647 else 16648 { 16649 to->vval.v_list = from->vval.v_list; 16650 ++to->vval.v_list->lv_refcount; 16651 } 16652 break; 16653 case VAR_DICT: 16654 if (from->vval.v_dict == NULL) 16655 to->vval.v_dict = NULL; 16656 else 16657 { 16658 to->vval.v_dict = from->vval.v_dict; 16659 ++to->vval.v_dict->dv_refcount; 16660 } 16661 break; 16662 default: 16663 EMSG2(_(e_intern2), "copy_tv()"); 16664 break; 16665 } 16666 } 16667 16668 /* 16669 * Make a copy of an item. 16670 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16671 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16672 * reference to an already copied list/dict can be used. 16673 * Returns FAIL or OK. 16674 */ 16675 static int 16676 item_copy(from, to, deep, copyID) 16677 typval_T *from; 16678 typval_T *to; 16679 int deep; 16680 int copyID; 16681 { 16682 static int recurse = 0; 16683 int ret = OK; 16684 16685 if (recurse >= DICT_MAXNEST) 16686 { 16687 EMSG(_("E698: variable nested too deep for making a copy")); 16688 return FAIL; 16689 } 16690 ++recurse; 16691 16692 switch (from->v_type) 16693 { 16694 case VAR_NUMBER: 16695 case VAR_STRING: 16696 case VAR_FUNC: 16697 copy_tv(from, to); 16698 break; 16699 case VAR_LIST: 16700 to->v_type = VAR_LIST; 16701 to->v_lock = 0; 16702 if (from->vval.v_list == NULL) 16703 to->vval.v_list = NULL; 16704 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16705 { 16706 /* use the copy made earlier */ 16707 to->vval.v_list = from->vval.v_list->lv_copylist; 16708 ++to->vval.v_list->lv_refcount; 16709 } 16710 else 16711 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16712 if (to->vval.v_list == NULL) 16713 ret = FAIL; 16714 break; 16715 case VAR_DICT: 16716 to->v_type = VAR_DICT; 16717 to->v_lock = 0; 16718 if (from->vval.v_dict == NULL) 16719 to->vval.v_dict = NULL; 16720 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16721 { 16722 /* use the copy made earlier */ 16723 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16724 ++to->vval.v_dict->dv_refcount; 16725 } 16726 else 16727 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16728 if (to->vval.v_dict == NULL) 16729 ret = FAIL; 16730 break; 16731 default: 16732 EMSG2(_(e_intern2), "item_copy()"); 16733 ret = FAIL; 16734 } 16735 --recurse; 16736 return ret; 16737 } 16738 16739 /* 16740 * ":echo expr1 ..." print each argument separated with a space, add a 16741 * newline at the end. 16742 * ":echon expr1 ..." print each argument plain. 16743 */ 16744 void 16745 ex_echo(eap) 16746 exarg_T *eap; 16747 { 16748 char_u *arg = eap->arg; 16749 typval_T rettv; 16750 char_u *tofree; 16751 char_u *p; 16752 int needclr = TRUE; 16753 int atstart = TRUE; 16754 char_u numbuf[NUMBUFLEN]; 16755 16756 if (eap->skip) 16757 ++emsg_skip; 16758 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16759 { 16760 p = arg; 16761 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16762 { 16763 /* 16764 * Report the invalid expression unless the expression evaluation 16765 * has been cancelled due to an aborting error, an interrupt, or an 16766 * exception. 16767 */ 16768 if (!aborting()) 16769 EMSG2(_(e_invexpr2), p); 16770 break; 16771 } 16772 if (!eap->skip) 16773 { 16774 if (atstart) 16775 { 16776 atstart = FALSE; 16777 /* Call msg_start() after eval1(), evaluating the expression 16778 * may cause a message to appear. */ 16779 if (eap->cmdidx == CMD_echo) 16780 msg_start(); 16781 } 16782 else if (eap->cmdidx == CMD_echo) 16783 msg_puts_attr((char_u *)" ", echo_attr); 16784 p = echo_string(&rettv, &tofree, numbuf); 16785 if (p != NULL) 16786 for ( ; *p != NUL && !got_int; ++p) 16787 { 16788 if (*p == '\n' || *p == '\r' || *p == TAB) 16789 { 16790 if (*p != TAB && needclr) 16791 { 16792 /* remove any text still there from the command */ 16793 msg_clr_eos(); 16794 needclr = FALSE; 16795 } 16796 msg_putchar_attr(*p, echo_attr); 16797 } 16798 else 16799 { 16800 #ifdef FEAT_MBYTE 16801 if (has_mbyte) 16802 { 16803 int i = (*mb_ptr2len)(p); 16804 16805 (void)msg_outtrans_len_attr(p, i, echo_attr); 16806 p += i - 1; 16807 } 16808 else 16809 #endif 16810 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16811 } 16812 } 16813 vim_free(tofree); 16814 } 16815 clear_tv(&rettv); 16816 arg = skipwhite(arg); 16817 } 16818 eap->nextcmd = check_nextcmd(arg); 16819 16820 if (eap->skip) 16821 --emsg_skip; 16822 else 16823 { 16824 /* remove text that may still be there from the command */ 16825 if (needclr) 16826 msg_clr_eos(); 16827 if (eap->cmdidx == CMD_echo) 16828 msg_end(); 16829 } 16830 } 16831 16832 /* 16833 * ":echohl {name}". 16834 */ 16835 void 16836 ex_echohl(eap) 16837 exarg_T *eap; 16838 { 16839 int id; 16840 16841 id = syn_name2id(eap->arg); 16842 if (id == 0) 16843 echo_attr = 0; 16844 else 16845 echo_attr = syn_id2attr(id); 16846 } 16847 16848 /* 16849 * ":execute expr1 ..." execute the result of an expression. 16850 * ":echomsg expr1 ..." Print a message 16851 * ":echoerr expr1 ..." Print an error 16852 * Each gets spaces around each argument and a newline at the end for 16853 * echo commands 16854 */ 16855 void 16856 ex_execute(eap) 16857 exarg_T *eap; 16858 { 16859 char_u *arg = eap->arg; 16860 typval_T rettv; 16861 int ret = OK; 16862 char_u *p; 16863 garray_T ga; 16864 int len; 16865 int save_did_emsg; 16866 16867 ga_init2(&ga, 1, 80); 16868 16869 if (eap->skip) 16870 ++emsg_skip; 16871 while (*arg != NUL && *arg != '|' && *arg != '\n') 16872 { 16873 p = arg; 16874 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16875 { 16876 /* 16877 * Report the invalid expression unless the expression evaluation 16878 * has been cancelled due to an aborting error, an interrupt, or an 16879 * exception. 16880 */ 16881 if (!aborting()) 16882 EMSG2(_(e_invexpr2), p); 16883 ret = FAIL; 16884 break; 16885 } 16886 16887 if (!eap->skip) 16888 { 16889 p = get_tv_string(&rettv); 16890 len = (int)STRLEN(p); 16891 if (ga_grow(&ga, len + 2) == FAIL) 16892 { 16893 clear_tv(&rettv); 16894 ret = FAIL; 16895 break; 16896 } 16897 if (ga.ga_len) 16898 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16899 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16900 ga.ga_len += len; 16901 } 16902 16903 clear_tv(&rettv); 16904 arg = skipwhite(arg); 16905 } 16906 16907 if (ret != FAIL && ga.ga_data != NULL) 16908 { 16909 if (eap->cmdidx == CMD_echomsg) 16910 MSG_ATTR(ga.ga_data, echo_attr); 16911 else if (eap->cmdidx == CMD_echoerr) 16912 { 16913 /* We don't want to abort following commands, restore did_emsg. */ 16914 save_did_emsg = did_emsg; 16915 EMSG((char_u *)ga.ga_data); 16916 if (!force_abort) 16917 did_emsg = save_did_emsg; 16918 } 16919 else if (eap->cmdidx == CMD_execute) 16920 do_cmdline((char_u *)ga.ga_data, 16921 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16922 } 16923 16924 ga_clear(&ga); 16925 16926 if (eap->skip) 16927 --emsg_skip; 16928 16929 eap->nextcmd = check_nextcmd(arg); 16930 } 16931 16932 /* 16933 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16934 * "arg" points to the "&" or '+' when called, to "option" when returning. 16935 * Returns NULL when no option name found. Otherwise pointer to the char 16936 * after the option name. 16937 */ 16938 static char_u * 16939 find_option_end(arg, opt_flags) 16940 char_u **arg; 16941 int *opt_flags; 16942 { 16943 char_u *p = *arg; 16944 16945 ++p; 16946 if (*p == 'g' && p[1] == ':') 16947 { 16948 *opt_flags = OPT_GLOBAL; 16949 p += 2; 16950 } 16951 else if (*p == 'l' && p[1] == ':') 16952 { 16953 *opt_flags = OPT_LOCAL; 16954 p += 2; 16955 } 16956 else 16957 *opt_flags = 0; 16958 16959 if (!ASCII_ISALPHA(*p)) 16960 return NULL; 16961 *arg = p; 16962 16963 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16964 p += 4; /* termcap option */ 16965 else 16966 while (ASCII_ISALPHA(*p)) 16967 ++p; 16968 return p; 16969 } 16970 16971 /* 16972 * ":function" 16973 */ 16974 void 16975 ex_function(eap) 16976 exarg_T *eap; 16977 { 16978 char_u *theline; 16979 int j; 16980 int c; 16981 int saved_did_emsg; 16982 char_u *name = NULL; 16983 char_u *p; 16984 char_u *arg; 16985 garray_T newargs; 16986 garray_T newlines; 16987 int varargs = FALSE; 16988 int mustend = FALSE; 16989 int flags = 0; 16990 ufunc_T *fp; 16991 int indent; 16992 int nesting; 16993 char_u *skip_until = NULL; 16994 dictitem_T *v; 16995 funcdict_T fudi; 16996 static int func_nr = 0; /* number for nameless function */ 16997 int paren; 16998 hashtab_T *ht; 16999 int todo; 17000 hashitem_T *hi; 17001 17002 /* 17003 * ":function" without argument: list functions. 17004 */ 17005 if (ends_excmd(*eap->arg)) 17006 { 17007 if (!eap->skip) 17008 { 17009 todo = func_hashtab.ht_used; 17010 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17011 { 17012 if (!HASHITEM_EMPTY(hi)) 17013 { 17014 --todo; 17015 fp = HI2UF(hi); 17016 if (!isdigit(*fp->uf_name)) 17017 list_func_head(fp, FALSE); 17018 } 17019 } 17020 } 17021 eap->nextcmd = check_nextcmd(eap->arg); 17022 return; 17023 } 17024 17025 /* 17026 * ":function /pat": list functions matching pattern. 17027 */ 17028 if (*eap->arg == '/') 17029 { 17030 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 17031 if (!eap->skip) 17032 { 17033 regmatch_T regmatch; 17034 17035 c = *p; 17036 *p = NUL; 17037 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 17038 *p = c; 17039 if (regmatch.regprog != NULL) 17040 { 17041 regmatch.rm_ic = p_ic; 17042 17043 todo = func_hashtab.ht_used; 17044 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17045 { 17046 if (!HASHITEM_EMPTY(hi)) 17047 { 17048 --todo; 17049 fp = HI2UF(hi); 17050 if (!isdigit(*fp->uf_name) 17051 && vim_regexec(®match, fp->uf_name, 0)) 17052 list_func_head(fp, FALSE); 17053 } 17054 } 17055 } 17056 } 17057 if (*p == '/') 17058 ++p; 17059 eap->nextcmd = check_nextcmd(p); 17060 return; 17061 } 17062 17063 /* 17064 * Get the function name. There are these situations: 17065 * func normal function name 17066 * "name" == func, "fudi.fd_dict" == NULL 17067 * dict.func new dictionary entry 17068 * "name" == NULL, "fudi.fd_dict" set, 17069 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 17070 * dict.func existing dict entry with a Funcref 17071 * "name" == func, "fudi.fd_dict" set, 17072 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17073 * dict.func existing dict entry that's not a Funcref 17074 * "name" == NULL, "fudi.fd_dict" set, 17075 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17076 */ 17077 p = eap->arg; 17078 name = trans_function_name(&p, eap->skip, 0, &fudi); 17079 paren = (vim_strchr(p, '(') != NULL); 17080 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 17081 { 17082 /* 17083 * Return on an invalid expression in braces, unless the expression 17084 * evaluation has been cancelled due to an aborting error, an 17085 * interrupt, or an exception. 17086 */ 17087 if (!aborting()) 17088 { 17089 if (!eap->skip && fudi.fd_newkey != NULL) 17090 EMSG2(_(e_dictkey), fudi.fd_newkey); 17091 vim_free(fudi.fd_newkey); 17092 return; 17093 } 17094 else 17095 eap->skip = TRUE; 17096 } 17097 /* An error in a function call during evaluation of an expression in magic 17098 * braces should not cause the function not to be defined. */ 17099 saved_did_emsg = did_emsg; 17100 did_emsg = FALSE; 17101 17102 /* 17103 * ":function func" with only function name: list function. 17104 */ 17105 if (!paren) 17106 { 17107 if (!ends_excmd(*skipwhite(p))) 17108 { 17109 EMSG(_(e_trailing)); 17110 goto ret_free; 17111 } 17112 eap->nextcmd = check_nextcmd(p); 17113 if (eap->nextcmd != NULL) 17114 *p = NUL; 17115 if (!eap->skip && !got_int) 17116 { 17117 fp = find_func(name); 17118 if (fp != NULL) 17119 { 17120 list_func_head(fp, TRUE); 17121 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 17122 { 17123 msg_putchar('\n'); 17124 msg_outnum((long)(j + 1)); 17125 if (j < 9) 17126 msg_putchar(' '); 17127 if (j < 99) 17128 msg_putchar(' '); 17129 msg_prt_line(FUNCLINE(fp, j), FALSE); 17130 out_flush(); /* show a line at a time */ 17131 ui_breakcheck(); 17132 } 17133 if (!got_int) 17134 { 17135 msg_putchar('\n'); 17136 msg_puts((char_u *)" endfunction"); 17137 } 17138 } 17139 else 17140 emsg_funcname("E123: Undefined function: %s", name); 17141 } 17142 goto ret_free; 17143 } 17144 17145 /* 17146 * ":function name(arg1, arg2)" Define function. 17147 */ 17148 p = skipwhite(p); 17149 if (*p != '(') 17150 { 17151 if (!eap->skip) 17152 { 17153 EMSG2(_("E124: Missing '(': %s"), eap->arg); 17154 goto ret_free; 17155 } 17156 /* attempt to continue by skipping some text */ 17157 if (vim_strchr(p, '(') != NULL) 17158 p = vim_strchr(p, '('); 17159 } 17160 p = skipwhite(p + 1); 17161 17162 ga_init2(&newargs, (int)sizeof(char_u *), 3); 17163 ga_init2(&newlines, (int)sizeof(char_u *), 3); 17164 17165 if (!eap->skip) 17166 { 17167 /* Check the name of the function. */ 17168 if (name != NULL) 17169 arg = name; 17170 else 17171 arg = fudi.fd_newkey; 17172 if (arg != NULL) 17173 { 17174 if (*arg == K_SPECIAL) 17175 j = 3; 17176 else 17177 j = 0; 17178 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 17179 : eval_isnamec(arg[j]))) 17180 ++j; 17181 if (arg[j] != NUL) 17182 emsg_funcname(_(e_invarg2), arg); 17183 } 17184 } 17185 17186 /* 17187 * Isolate the arguments: "arg1, arg2, ...)" 17188 */ 17189 while (*p != ')') 17190 { 17191 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 17192 { 17193 varargs = TRUE; 17194 p += 3; 17195 mustend = TRUE; 17196 } 17197 else 17198 { 17199 arg = p; 17200 while (ASCII_ISALNUM(*p) || *p == '_') 17201 ++p; 17202 if (arg == p || isdigit(*arg) 17203 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 17204 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 17205 { 17206 if (!eap->skip) 17207 EMSG2(_("E125: Illegal argument: %s"), arg); 17208 break; 17209 } 17210 if (ga_grow(&newargs, 1) == FAIL) 17211 goto erret; 17212 c = *p; 17213 *p = NUL; 17214 arg = vim_strsave(arg); 17215 if (arg == NULL) 17216 goto erret; 17217 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 17218 *p = c; 17219 newargs.ga_len++; 17220 if (*p == ',') 17221 ++p; 17222 else 17223 mustend = TRUE; 17224 } 17225 p = skipwhite(p); 17226 if (mustend && *p != ')') 17227 { 17228 if (!eap->skip) 17229 EMSG2(_(e_invarg2), eap->arg); 17230 break; 17231 } 17232 } 17233 ++p; /* skip the ')' */ 17234 17235 /* find extra arguments "range", "dict" and "abort" */ 17236 for (;;) 17237 { 17238 p = skipwhite(p); 17239 if (STRNCMP(p, "range", 5) == 0) 17240 { 17241 flags |= FC_RANGE; 17242 p += 5; 17243 } 17244 else if (STRNCMP(p, "dict", 4) == 0) 17245 { 17246 flags |= FC_DICT; 17247 p += 4; 17248 } 17249 else if (STRNCMP(p, "abort", 5) == 0) 17250 { 17251 flags |= FC_ABORT; 17252 p += 5; 17253 } 17254 else 17255 break; 17256 } 17257 17258 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 17259 EMSG(_(e_trailing)); 17260 17261 /* 17262 * Read the body of the function, until ":endfunction" is found. 17263 */ 17264 if (KeyTyped) 17265 { 17266 /* Check if the function already exists, don't let the user type the 17267 * whole function before telling him it doesn't work! For a script we 17268 * need to skip the body to be able to find what follows. */ 17269 if (!eap->skip && !eap->forceit) 17270 { 17271 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 17272 EMSG(_(e_funcdict)); 17273 else if (name != NULL && find_func(name) != NULL) 17274 emsg_funcname(e_funcexts, name); 17275 } 17276 17277 if (!eap->skip && did_emsg) 17278 goto erret; 17279 17280 msg_putchar('\n'); /* don't overwrite the function name */ 17281 cmdline_row = msg_row; 17282 } 17283 17284 indent = 2; 17285 nesting = 0; 17286 for (;;) 17287 { 17288 msg_scroll = TRUE; 17289 need_wait_return = FALSE; 17290 if (eap->getline == NULL) 17291 theline = getcmdline(':', 0L, indent); 17292 else 17293 theline = eap->getline(':', eap->cookie, indent); 17294 if (KeyTyped) 17295 lines_left = Rows - 1; 17296 if (theline == NULL) 17297 { 17298 EMSG(_("E126: Missing :endfunction")); 17299 goto erret; 17300 } 17301 17302 if (skip_until != NULL) 17303 { 17304 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17305 * don't check for ":endfunc". */ 17306 if (STRCMP(theline, skip_until) == 0) 17307 { 17308 vim_free(skip_until); 17309 skip_until = NULL; 17310 } 17311 } 17312 else 17313 { 17314 /* skip ':' and blanks*/ 17315 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17316 ; 17317 17318 /* Check for "endfunction". */ 17319 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17320 { 17321 vim_free(theline); 17322 break; 17323 } 17324 17325 /* Increase indent inside "if", "while", "for" and "try", decrease 17326 * at "end". */ 17327 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17328 indent -= 2; 17329 else if (STRNCMP(p, "if", 2) == 0 17330 || STRNCMP(p, "wh", 2) == 0 17331 || STRNCMP(p, "for", 3) == 0 17332 || STRNCMP(p, "try", 3) == 0) 17333 indent += 2; 17334 17335 /* Check for defining a function inside this function. */ 17336 if (checkforcmd(&p, "function", 2)) 17337 { 17338 if (*p == '!') 17339 p = skipwhite(p + 1); 17340 p += eval_fname_script(p); 17341 if (ASCII_ISALPHA(*p)) 17342 { 17343 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17344 if (*skipwhite(p) == '(') 17345 { 17346 ++nesting; 17347 indent += 2; 17348 } 17349 } 17350 } 17351 17352 /* Check for ":append" or ":insert". */ 17353 p = skip_range(p, NULL); 17354 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17355 || (p[0] == 'i' 17356 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17357 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17358 skip_until = vim_strsave((char_u *)"."); 17359 17360 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17361 arg = skipwhite(skiptowhite(p)); 17362 if (arg[0] == '<' && arg[1] =='<' 17363 && ((p[0] == 'p' && p[1] == 'y' 17364 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17365 || (p[0] == 'p' && p[1] == 'e' 17366 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17367 || (p[0] == 't' && p[1] == 'c' 17368 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17369 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17370 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17371 || (p[0] == 'm' && p[1] == 'z' 17372 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17373 )) 17374 { 17375 /* ":python <<" continues until a dot, like ":append" */ 17376 p = skipwhite(arg + 2); 17377 if (*p == NUL) 17378 skip_until = vim_strsave((char_u *)"."); 17379 else 17380 skip_until = vim_strsave(p); 17381 } 17382 } 17383 17384 /* Add the line to the function. */ 17385 if (ga_grow(&newlines, 1) == FAIL) 17386 { 17387 vim_free(theline); 17388 goto erret; 17389 } 17390 17391 /* Copy the line to newly allocated memory. get_one_sourceline() 17392 * allocates 250 bytes per line, this saves 80% on average. The cost 17393 * is an extra alloc/free. */ 17394 p = vim_strsave(theline); 17395 if (p != NULL) 17396 { 17397 vim_free(theline); 17398 theline = p; 17399 } 17400 17401 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17402 newlines.ga_len++; 17403 } 17404 17405 /* Don't define the function when skipping commands or when an error was 17406 * detected. */ 17407 if (eap->skip || did_emsg) 17408 goto erret; 17409 17410 /* 17411 * If there are no errors, add the function 17412 */ 17413 if (fudi.fd_dict == NULL) 17414 { 17415 v = find_var(name, &ht); 17416 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17417 { 17418 emsg_funcname("E707: Function name conflicts with variable: %s", 17419 name); 17420 goto erret; 17421 } 17422 17423 fp = find_func(name); 17424 if (fp != NULL) 17425 { 17426 if (!eap->forceit) 17427 { 17428 emsg_funcname(e_funcexts, name); 17429 goto erret; 17430 } 17431 if (fp->uf_calls > 0) 17432 { 17433 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17434 name); 17435 goto erret; 17436 } 17437 /* redefine existing function */ 17438 ga_clear_strings(&(fp->uf_args)); 17439 ga_clear_strings(&(fp->uf_lines)); 17440 vim_free(name); 17441 name = NULL; 17442 } 17443 } 17444 else 17445 { 17446 char numbuf[20]; 17447 17448 fp = NULL; 17449 if (fudi.fd_newkey == NULL && !eap->forceit) 17450 { 17451 EMSG(_(e_funcdict)); 17452 goto erret; 17453 } 17454 if (fudi.fd_di == NULL) 17455 { 17456 /* Can't add a function to a locked dictionary */ 17457 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17458 goto erret; 17459 } 17460 /* Can't change an existing function if it is locked */ 17461 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17462 goto erret; 17463 17464 /* Give the function a sequential number. Can only be used with a 17465 * Funcref! */ 17466 vim_free(name); 17467 sprintf(numbuf, "%d", ++func_nr); 17468 name = vim_strsave((char_u *)numbuf); 17469 if (name == NULL) 17470 goto erret; 17471 } 17472 17473 if (fp == NULL) 17474 { 17475 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17476 { 17477 int slen, plen; 17478 char_u *scriptname; 17479 17480 /* Check that the autoload name matches the script name. */ 17481 j = FAIL; 17482 if (sourcing_name != NULL) 17483 { 17484 scriptname = autoload_name(name); 17485 if (scriptname != NULL) 17486 { 17487 p = vim_strchr(scriptname, '/'); 17488 plen = STRLEN(p); 17489 slen = STRLEN(sourcing_name); 17490 if (slen > plen && fnamecmp(p, 17491 sourcing_name + slen - plen) == 0) 17492 j = OK; 17493 vim_free(scriptname); 17494 } 17495 } 17496 if (j == FAIL) 17497 { 17498 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17499 goto erret; 17500 } 17501 } 17502 17503 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17504 if (fp == NULL) 17505 goto erret; 17506 17507 if (fudi.fd_dict != NULL) 17508 { 17509 if (fudi.fd_di == NULL) 17510 { 17511 /* add new dict entry */ 17512 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17513 if (fudi.fd_di == NULL) 17514 { 17515 vim_free(fp); 17516 goto erret; 17517 } 17518 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17519 { 17520 vim_free(fudi.fd_di); 17521 goto erret; 17522 } 17523 } 17524 else 17525 /* overwrite existing dict entry */ 17526 clear_tv(&fudi.fd_di->di_tv); 17527 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17528 fudi.fd_di->di_tv.v_lock = 0; 17529 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17530 fp->uf_refcount = 1; 17531 } 17532 17533 /* insert the new function in the function list */ 17534 STRCPY(fp->uf_name, name); 17535 hash_add(&func_hashtab, UF2HIKEY(fp)); 17536 } 17537 fp->uf_args = newargs; 17538 fp->uf_lines = newlines; 17539 #ifdef FEAT_PROFILE 17540 fp->uf_tml_count = NULL; 17541 fp->uf_tml_total = NULL; 17542 fp->uf_tml_self = NULL; 17543 fp->uf_profiling = FALSE; 17544 if (prof_def_func()) 17545 func_do_profile(fp); 17546 #endif 17547 fp->uf_varargs = varargs; 17548 fp->uf_flags = flags; 17549 fp->uf_calls = 0; 17550 fp->uf_script_ID = current_SID; 17551 goto ret_free; 17552 17553 erret: 17554 ga_clear_strings(&newargs); 17555 ga_clear_strings(&newlines); 17556 ret_free: 17557 vim_free(skip_until); 17558 vim_free(fudi.fd_newkey); 17559 vim_free(name); 17560 did_emsg |= saved_did_emsg; 17561 } 17562 17563 /* 17564 * Get a function name, translating "<SID>" and "<SNR>". 17565 * Also handles a Funcref in a List or Dictionary. 17566 * Returns the function name in allocated memory, or NULL for failure. 17567 * flags: 17568 * TFN_INT: internal function name OK 17569 * TFN_QUIET: be quiet 17570 * Advances "pp" to just after the function name (if no error). 17571 */ 17572 static char_u * 17573 trans_function_name(pp, skip, flags, fdp) 17574 char_u **pp; 17575 int skip; /* only find the end, don't evaluate */ 17576 int flags; 17577 funcdict_T *fdp; /* return: info about dictionary used */ 17578 { 17579 char_u *name = NULL; 17580 char_u *start; 17581 char_u *end; 17582 int lead; 17583 char_u sid_buf[20]; 17584 int len; 17585 lval_T lv; 17586 17587 if (fdp != NULL) 17588 vim_memset(fdp, 0, sizeof(funcdict_T)); 17589 start = *pp; 17590 17591 /* Check for hard coded <SNR>: already translated function ID (from a user 17592 * command). */ 17593 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17594 && (*pp)[2] == (int)KE_SNR) 17595 { 17596 *pp += 3; 17597 len = get_id_len(pp) + 3; 17598 return vim_strnsave(start, len); 17599 } 17600 17601 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17602 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17603 lead = eval_fname_script(start); 17604 if (lead > 2) 17605 start += lead; 17606 17607 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17608 lead > 2 ? 0 : FNE_CHECK_START); 17609 if (end == start) 17610 { 17611 if (!skip) 17612 EMSG(_("E129: Function name required")); 17613 goto theend; 17614 } 17615 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17616 { 17617 /* 17618 * Report an invalid expression in braces, unless the expression 17619 * evaluation has been cancelled due to an aborting error, an 17620 * interrupt, or an exception. 17621 */ 17622 if (!aborting()) 17623 { 17624 if (end != NULL) 17625 EMSG2(_(e_invarg2), start); 17626 } 17627 else 17628 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17629 goto theend; 17630 } 17631 17632 if (lv.ll_tv != NULL) 17633 { 17634 if (fdp != NULL) 17635 { 17636 fdp->fd_dict = lv.ll_dict; 17637 fdp->fd_newkey = lv.ll_newkey; 17638 lv.ll_newkey = NULL; 17639 fdp->fd_di = lv.ll_di; 17640 } 17641 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17642 { 17643 name = vim_strsave(lv.ll_tv->vval.v_string); 17644 *pp = end; 17645 } 17646 else 17647 { 17648 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17649 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17650 EMSG(_(e_funcref)); 17651 else 17652 *pp = end; 17653 name = NULL; 17654 } 17655 goto theend; 17656 } 17657 17658 if (lv.ll_name == NULL) 17659 { 17660 /* Error found, but continue after the function name. */ 17661 *pp = end; 17662 goto theend; 17663 } 17664 17665 if (lv.ll_exp_name != NULL) 17666 len = STRLEN(lv.ll_exp_name); 17667 else 17668 { 17669 if (lead == 2) /* skip over "s:" */ 17670 lv.ll_name += 2; 17671 len = (int)(end - lv.ll_name); 17672 } 17673 17674 /* 17675 * Copy the function name to allocated memory. 17676 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17677 * Accept <SNR>123_name() outside a script. 17678 */ 17679 if (skip) 17680 lead = 0; /* do nothing */ 17681 else if (lead > 0) 17682 { 17683 lead = 3; 17684 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17685 { 17686 if (current_SID <= 0) 17687 { 17688 EMSG(_(e_usingsid)); 17689 goto theend; 17690 } 17691 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17692 lead += (int)STRLEN(sid_buf); 17693 } 17694 } 17695 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17696 { 17697 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17698 goto theend; 17699 } 17700 name = alloc((unsigned)(len + lead + 1)); 17701 if (name != NULL) 17702 { 17703 if (lead > 0) 17704 { 17705 name[0] = K_SPECIAL; 17706 name[1] = KS_EXTRA; 17707 name[2] = (int)KE_SNR; 17708 if (lead > 3) /* If it's "<SID>" */ 17709 STRCPY(name + 3, sid_buf); 17710 } 17711 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17712 name[len + lead] = NUL; 17713 } 17714 *pp = end; 17715 17716 theend: 17717 clear_lval(&lv); 17718 return name; 17719 } 17720 17721 /* 17722 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17723 * Return 2 if "p" starts with "s:". 17724 * Return 0 otherwise. 17725 */ 17726 static int 17727 eval_fname_script(p) 17728 char_u *p; 17729 { 17730 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17731 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17732 return 5; 17733 if (p[0] == 's' && p[1] == ':') 17734 return 2; 17735 return 0; 17736 } 17737 17738 /* 17739 * Return TRUE if "p" starts with "<SID>" or "s:". 17740 * Only works if eval_fname_script() returned non-zero for "p"! 17741 */ 17742 static int 17743 eval_fname_sid(p) 17744 char_u *p; 17745 { 17746 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17747 } 17748 17749 /* 17750 * List the head of the function: "name(arg1, arg2)". 17751 */ 17752 static void 17753 list_func_head(fp, indent) 17754 ufunc_T *fp; 17755 int indent; 17756 { 17757 int j; 17758 17759 msg_start(); 17760 if (indent) 17761 MSG_PUTS(" "); 17762 MSG_PUTS("function "); 17763 if (fp->uf_name[0] == K_SPECIAL) 17764 { 17765 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17766 msg_puts(fp->uf_name + 3); 17767 } 17768 else 17769 msg_puts(fp->uf_name); 17770 msg_putchar('('); 17771 for (j = 0; j < fp->uf_args.ga_len; ++j) 17772 { 17773 if (j) 17774 MSG_PUTS(", "); 17775 msg_puts(FUNCARG(fp, j)); 17776 } 17777 if (fp->uf_varargs) 17778 { 17779 if (j) 17780 MSG_PUTS(", "); 17781 MSG_PUTS("..."); 17782 } 17783 msg_putchar(')'); 17784 msg_clr_eos(); 17785 if (p_verbose > 0) 17786 last_set_msg(fp->uf_script_ID); 17787 } 17788 17789 /* 17790 * Find a function by name, return pointer to it in ufuncs. 17791 * Return NULL for unknown function. 17792 */ 17793 static ufunc_T * 17794 find_func(name) 17795 char_u *name; 17796 { 17797 hashitem_T *hi; 17798 17799 hi = hash_find(&func_hashtab, name); 17800 if (!HASHITEM_EMPTY(hi)) 17801 return HI2UF(hi); 17802 return NULL; 17803 } 17804 17805 #if defined(EXITFREE) || defined(PROTO) 17806 void 17807 free_all_functions() 17808 { 17809 hashitem_T *hi; 17810 17811 /* Need to start all over every time, because func_free() may change the 17812 * hash table. */ 17813 while (func_hashtab.ht_used > 0) 17814 for (hi = func_hashtab.ht_array; ; ++hi) 17815 if (!HASHITEM_EMPTY(hi)) 17816 { 17817 func_free(HI2UF(hi)); 17818 break; 17819 } 17820 } 17821 #endif 17822 17823 /* 17824 * Return TRUE if a function "name" exists. 17825 */ 17826 static int 17827 function_exists(name) 17828 char_u *name; 17829 { 17830 char_u *p = name; 17831 int n = FALSE; 17832 17833 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17834 if (p != NULL) 17835 { 17836 if (builtin_function(p)) 17837 n = (find_internal_func(p) >= 0); 17838 else 17839 n = (find_func(p) != NULL); 17840 vim_free(p); 17841 } 17842 return n; 17843 } 17844 17845 /* 17846 * Return TRUE if "name" looks like a builtin function name: starts with a 17847 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17848 */ 17849 static int 17850 builtin_function(name) 17851 char_u *name; 17852 { 17853 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17854 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17855 } 17856 17857 #if defined(FEAT_PROFILE) || defined(PROTO) 17858 /* 17859 * Start profiling function "fp". 17860 */ 17861 static void 17862 func_do_profile(fp) 17863 ufunc_T *fp; 17864 { 17865 fp->uf_tm_count = 0; 17866 profile_zero(&fp->uf_tm_self); 17867 profile_zero(&fp->uf_tm_total); 17868 if (fp->uf_tml_count == NULL) 17869 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17870 (sizeof(int) * fp->uf_lines.ga_len)); 17871 if (fp->uf_tml_total == NULL) 17872 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17873 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17874 if (fp->uf_tml_self == NULL) 17875 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17876 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17877 fp->uf_tml_idx = -1; 17878 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17879 || fp->uf_tml_self == NULL) 17880 return; /* out of memory */ 17881 17882 fp->uf_profiling = TRUE; 17883 } 17884 17885 /* 17886 * Dump the profiling results for all functions in file "fd". 17887 */ 17888 void 17889 func_dump_profile(fd) 17890 FILE *fd; 17891 { 17892 hashitem_T *hi; 17893 int todo; 17894 ufunc_T *fp; 17895 int i; 17896 ufunc_T **sorttab; 17897 int st_len = 0; 17898 17899 todo = func_hashtab.ht_used; 17900 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17901 17902 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17903 { 17904 if (!HASHITEM_EMPTY(hi)) 17905 { 17906 --todo; 17907 fp = HI2UF(hi); 17908 if (fp->uf_profiling) 17909 { 17910 if (sorttab != NULL) 17911 sorttab[st_len++] = fp; 17912 17913 if (fp->uf_name[0] == K_SPECIAL) 17914 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17915 else 17916 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17917 if (fp->uf_tm_count == 1) 17918 fprintf(fd, "Called 1 time\n"); 17919 else 17920 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17921 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17922 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17923 fprintf(fd, "\n"); 17924 fprintf(fd, "count total (s) self (s)\n"); 17925 17926 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17927 { 17928 prof_func_line(fd, fp->uf_tml_count[i], 17929 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17930 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17931 } 17932 fprintf(fd, "\n"); 17933 } 17934 } 17935 } 17936 17937 if (sorttab != NULL && st_len > 0) 17938 { 17939 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17940 prof_total_cmp); 17941 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17942 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17943 prof_self_cmp); 17944 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17945 } 17946 } 17947 17948 static void 17949 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17950 FILE *fd; 17951 ufunc_T **sorttab; 17952 int st_len; 17953 char *title; 17954 int prefer_self; /* when equal print only self time */ 17955 { 17956 int i; 17957 ufunc_T *fp; 17958 17959 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17960 fprintf(fd, "count total (s) self (s) function\n"); 17961 for (i = 0; i < 20 && i < st_len; ++i) 17962 { 17963 fp = sorttab[i]; 17964 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17965 prefer_self); 17966 if (fp->uf_name[0] == K_SPECIAL) 17967 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17968 else 17969 fprintf(fd, " %s()\n", fp->uf_name); 17970 } 17971 fprintf(fd, "\n"); 17972 } 17973 17974 /* 17975 * Print the count and times for one function or function line. 17976 */ 17977 static void 17978 prof_func_line(fd, count, total, self, prefer_self) 17979 FILE *fd; 17980 int count; 17981 proftime_T *total; 17982 proftime_T *self; 17983 int prefer_self; /* when equal print only self time */ 17984 { 17985 if (count > 0) 17986 { 17987 fprintf(fd, "%5d ", count); 17988 if (prefer_self && profile_equal(total, self)) 17989 fprintf(fd, " "); 17990 else 17991 fprintf(fd, "%s ", profile_msg(total)); 17992 if (!prefer_self && profile_equal(total, self)) 17993 fprintf(fd, " "); 17994 else 17995 fprintf(fd, "%s ", profile_msg(self)); 17996 } 17997 else 17998 fprintf(fd, " "); 17999 } 18000 18001 /* 18002 * Compare function for total time sorting. 18003 */ 18004 static int 18005 #ifdef __BORLANDC__ 18006 _RTLENTRYF 18007 #endif 18008 prof_total_cmp(s1, s2) 18009 const void *s1; 18010 const void *s2; 18011 { 18012 ufunc_T *p1, *p2; 18013 18014 p1 = *(ufunc_T **)s1; 18015 p2 = *(ufunc_T **)s2; 18016 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 18017 } 18018 18019 /* 18020 * Compare function for self time sorting. 18021 */ 18022 static int 18023 #ifdef __BORLANDC__ 18024 _RTLENTRYF 18025 #endif 18026 prof_self_cmp(s1, s2) 18027 const void *s1; 18028 const void *s2; 18029 { 18030 ufunc_T *p1, *p2; 18031 18032 p1 = *(ufunc_T **)s1; 18033 p2 = *(ufunc_T **)s2; 18034 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 18035 } 18036 18037 #endif 18038 18039 /* The names of packages that once were loaded is remembered. */ 18040 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 18041 18042 /* 18043 * If "name" has a package name try autoloading the script for it. 18044 * Return TRUE if a package was loaded. 18045 */ 18046 static int 18047 script_autoload(name, reload) 18048 char_u *name; 18049 int reload; /* load script again when already loaded */ 18050 { 18051 char_u *p; 18052 char_u *scriptname, *tofree; 18053 int ret = FALSE; 18054 int i; 18055 18056 /* If there is no '#' after name[0] there is no package name. */ 18057 p = vim_strchr(name, AUTOLOAD_CHAR); 18058 if (p == NULL || p == name) 18059 return FALSE; 18060 18061 tofree = scriptname = autoload_name(name); 18062 18063 /* Find the name in the list of previously loaded package names. Skip 18064 * "autoload/", it's always the same. */ 18065 for (i = 0; i < ga_loaded.ga_len; ++i) 18066 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 18067 break; 18068 if (!reload && i < ga_loaded.ga_len) 18069 ret = FALSE; /* was loaded already */ 18070 else 18071 { 18072 /* Remember the name if it wasn't loaded already. */ 18073 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 18074 { 18075 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 18076 tofree = NULL; 18077 } 18078 18079 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 18080 if (source_runtime(scriptname, FALSE) == OK) 18081 ret = TRUE; 18082 } 18083 18084 vim_free(tofree); 18085 return ret; 18086 } 18087 18088 /* 18089 * Return the autoload script name for a function or variable name. 18090 * Returns NULL when out of memory. 18091 */ 18092 static char_u * 18093 autoload_name(name) 18094 char_u *name; 18095 { 18096 char_u *p; 18097 char_u *scriptname; 18098 18099 /* Get the script file name: replace '#' with '/', append ".vim". */ 18100 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 18101 if (scriptname == NULL) 18102 return FALSE; 18103 STRCPY(scriptname, "autoload/"); 18104 STRCAT(scriptname, name); 18105 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 18106 STRCAT(scriptname, ".vim"); 18107 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 18108 *p = '/'; 18109 return scriptname; 18110 } 18111 18112 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 18113 18114 /* 18115 * Function given to ExpandGeneric() to obtain the list of user defined 18116 * function names. 18117 */ 18118 char_u * 18119 get_user_func_name(xp, idx) 18120 expand_T *xp; 18121 int idx; 18122 { 18123 static long_u done; 18124 static hashitem_T *hi; 18125 ufunc_T *fp; 18126 18127 if (idx == 0) 18128 { 18129 done = 0; 18130 hi = func_hashtab.ht_array; 18131 } 18132 if (done < func_hashtab.ht_used) 18133 { 18134 if (done++ > 0) 18135 ++hi; 18136 while (HASHITEM_EMPTY(hi)) 18137 ++hi; 18138 fp = HI2UF(hi); 18139 18140 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 18141 return fp->uf_name; /* prevents overflow */ 18142 18143 cat_func_name(IObuff, fp); 18144 if (xp->xp_context != EXPAND_USER_FUNC) 18145 { 18146 STRCAT(IObuff, "("); 18147 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 18148 STRCAT(IObuff, ")"); 18149 } 18150 return IObuff; 18151 } 18152 return NULL; 18153 } 18154 18155 #endif /* FEAT_CMDL_COMPL */ 18156 18157 /* 18158 * Copy the function name of "fp" to buffer "buf". 18159 * "buf" must be able to hold the function name plus three bytes. 18160 * Takes care of script-local function names. 18161 */ 18162 static void 18163 cat_func_name(buf, fp) 18164 char_u *buf; 18165 ufunc_T *fp; 18166 { 18167 if (fp->uf_name[0] == K_SPECIAL) 18168 { 18169 STRCPY(buf, "<SNR>"); 18170 STRCAT(buf, fp->uf_name + 3); 18171 } 18172 else 18173 STRCPY(buf, fp->uf_name); 18174 } 18175 18176 /* 18177 * ":delfunction {name}" 18178 */ 18179 void 18180 ex_delfunction(eap) 18181 exarg_T *eap; 18182 { 18183 ufunc_T *fp = NULL; 18184 char_u *p; 18185 char_u *name; 18186 funcdict_T fudi; 18187 18188 p = eap->arg; 18189 name = trans_function_name(&p, eap->skip, 0, &fudi); 18190 vim_free(fudi.fd_newkey); 18191 if (name == NULL) 18192 { 18193 if (fudi.fd_dict != NULL && !eap->skip) 18194 EMSG(_(e_funcref)); 18195 return; 18196 } 18197 if (!ends_excmd(*skipwhite(p))) 18198 { 18199 vim_free(name); 18200 EMSG(_(e_trailing)); 18201 return; 18202 } 18203 eap->nextcmd = check_nextcmd(p); 18204 if (eap->nextcmd != NULL) 18205 *p = NUL; 18206 18207 if (!eap->skip) 18208 fp = find_func(name); 18209 vim_free(name); 18210 18211 if (!eap->skip) 18212 { 18213 if (fp == NULL) 18214 { 18215 EMSG2(_(e_nofunc), eap->arg); 18216 return; 18217 } 18218 if (fp->uf_calls > 0) 18219 { 18220 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 18221 return; 18222 } 18223 18224 if (fudi.fd_dict != NULL) 18225 { 18226 /* Delete the dict item that refers to the function, it will 18227 * invoke func_unref() and possibly delete the function. */ 18228 dictitem_remove(fudi.fd_dict, fudi.fd_di); 18229 } 18230 else 18231 func_free(fp); 18232 } 18233 } 18234 18235 /* 18236 * Free a function and remove it from the list of functions. 18237 */ 18238 static void 18239 func_free(fp) 18240 ufunc_T *fp; 18241 { 18242 hashitem_T *hi; 18243 18244 /* clear this function */ 18245 ga_clear_strings(&(fp->uf_args)); 18246 ga_clear_strings(&(fp->uf_lines)); 18247 #ifdef FEAT_PROFILE 18248 vim_free(fp->uf_tml_count); 18249 vim_free(fp->uf_tml_total); 18250 vim_free(fp->uf_tml_self); 18251 #endif 18252 18253 /* remove the function from the function hashtable */ 18254 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 18255 if (HASHITEM_EMPTY(hi)) 18256 EMSG2(_(e_intern2), "func_free()"); 18257 else 18258 hash_remove(&func_hashtab, hi); 18259 18260 vim_free(fp); 18261 } 18262 18263 /* 18264 * Unreference a Function: decrement the reference count and free it when it 18265 * becomes zero. Only for numbered functions. 18266 */ 18267 static void 18268 func_unref(name) 18269 char_u *name; 18270 { 18271 ufunc_T *fp; 18272 18273 if (name != NULL && isdigit(*name)) 18274 { 18275 fp = find_func(name); 18276 if (fp == NULL) 18277 EMSG2(_(e_intern2), "func_unref()"); 18278 else if (--fp->uf_refcount <= 0) 18279 { 18280 /* Only delete it when it's not being used. Otherwise it's done 18281 * when "uf_calls" becomes zero. */ 18282 if (fp->uf_calls == 0) 18283 func_free(fp); 18284 } 18285 } 18286 } 18287 18288 /* 18289 * Count a reference to a Function. 18290 */ 18291 static void 18292 func_ref(name) 18293 char_u *name; 18294 { 18295 ufunc_T *fp; 18296 18297 if (name != NULL && isdigit(*name)) 18298 { 18299 fp = find_func(name); 18300 if (fp == NULL) 18301 EMSG2(_(e_intern2), "func_ref()"); 18302 else 18303 ++fp->uf_refcount; 18304 } 18305 } 18306 18307 /* 18308 * Call a user function. 18309 */ 18310 static void 18311 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18312 ufunc_T *fp; /* pointer to function */ 18313 int argcount; /* nr of args */ 18314 typval_T *argvars; /* arguments */ 18315 typval_T *rettv; /* return value */ 18316 linenr_T firstline; /* first line of range */ 18317 linenr_T lastline; /* last line of range */ 18318 dict_T *selfdict; /* Dictionary for "self" */ 18319 { 18320 char_u *save_sourcing_name; 18321 linenr_T save_sourcing_lnum; 18322 scid_T save_current_SID; 18323 funccall_T fc; 18324 int save_did_emsg; 18325 static int depth = 0; 18326 dictitem_T *v; 18327 int fixvar_idx = 0; /* index in fixvar[] */ 18328 int i; 18329 int ai; 18330 char_u numbuf[NUMBUFLEN]; 18331 char_u *name; 18332 #ifdef FEAT_PROFILE 18333 proftime_T wait_start; 18334 #endif 18335 18336 /* If depth of calling is getting too high, don't execute the function */ 18337 if (depth >= p_mfd) 18338 { 18339 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18340 rettv->v_type = VAR_NUMBER; 18341 rettv->vval.v_number = -1; 18342 return; 18343 } 18344 ++depth; 18345 18346 line_breakcheck(); /* check for CTRL-C hit */ 18347 18348 fc.caller = current_funccal; 18349 current_funccal = &fc; 18350 fc.func = fp; 18351 fc.rettv = rettv; 18352 rettv->vval.v_number = 0; 18353 fc.linenr = 0; 18354 fc.returned = FALSE; 18355 fc.level = ex_nesting_level; 18356 /* Check if this function has a breakpoint. */ 18357 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18358 fc.dbg_tick = debug_tick; 18359 18360 /* 18361 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18362 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18363 * each argument variable and saves a lot of time. 18364 */ 18365 /* 18366 * Init l: variables. 18367 */ 18368 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18369 if (selfdict != NULL) 18370 { 18371 /* Set l:self to "selfdict". */ 18372 v = &fc.fixvar[fixvar_idx++].var; 18373 STRCPY(v->di_key, "self"); 18374 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18375 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18376 v->di_tv.v_type = VAR_DICT; 18377 v->di_tv.v_lock = 0; 18378 v->di_tv.vval.v_dict = selfdict; 18379 ++selfdict->dv_refcount; 18380 } 18381 18382 /* 18383 * Init a: variables. 18384 * Set a:0 to "argcount". 18385 * Set a:000 to a list with room for the "..." arguments. 18386 */ 18387 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18388 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18389 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18390 v = &fc.fixvar[fixvar_idx++].var; 18391 STRCPY(v->di_key, "000"); 18392 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18393 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18394 v->di_tv.v_type = VAR_LIST; 18395 v->di_tv.v_lock = VAR_FIXED; 18396 v->di_tv.vval.v_list = &fc.l_varlist; 18397 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18398 fc.l_varlist.lv_refcount = 99999; 18399 18400 /* 18401 * Set a:firstline to "firstline" and a:lastline to "lastline". 18402 * Set a:name to named arguments. 18403 * Set a:N to the "..." arguments. 18404 */ 18405 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18406 (varnumber_T)firstline); 18407 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18408 (varnumber_T)lastline); 18409 for (i = 0; i < argcount; ++i) 18410 { 18411 ai = i - fp->uf_args.ga_len; 18412 if (ai < 0) 18413 /* named argument a:name */ 18414 name = FUNCARG(fp, i); 18415 else 18416 { 18417 /* "..." argument a:1, a:2, etc. */ 18418 sprintf((char *)numbuf, "%d", ai + 1); 18419 name = numbuf; 18420 } 18421 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18422 { 18423 v = &fc.fixvar[fixvar_idx++].var; 18424 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18425 } 18426 else 18427 { 18428 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18429 + STRLEN(name))); 18430 if (v == NULL) 18431 break; 18432 v->di_flags = DI_FLAGS_RO; 18433 } 18434 STRCPY(v->di_key, name); 18435 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18436 18437 /* Note: the values are copied directly to avoid alloc/free. 18438 * "argvars" must have VAR_FIXED for v_lock. */ 18439 v->di_tv = argvars[i]; 18440 v->di_tv.v_lock = VAR_FIXED; 18441 18442 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18443 { 18444 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18445 fc.l_listitems[ai].li_tv = argvars[i]; 18446 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18447 } 18448 } 18449 18450 /* Don't redraw while executing the function. */ 18451 ++RedrawingDisabled; 18452 save_sourcing_name = sourcing_name; 18453 save_sourcing_lnum = sourcing_lnum; 18454 sourcing_lnum = 1; 18455 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18456 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18457 if (sourcing_name != NULL) 18458 { 18459 if (save_sourcing_name != NULL 18460 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18461 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18462 else 18463 STRCPY(sourcing_name, "function "); 18464 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18465 18466 if (p_verbose >= 12) 18467 { 18468 ++no_wait_return; 18469 verbose_enter_scroll(); 18470 18471 smsg((char_u *)_("calling %s"), sourcing_name); 18472 if (p_verbose >= 14) 18473 { 18474 char_u buf[MSG_BUF_LEN]; 18475 char_u numbuf[NUMBUFLEN]; 18476 char_u *tofree; 18477 18478 msg_puts((char_u *)"("); 18479 for (i = 0; i < argcount; ++i) 18480 { 18481 if (i > 0) 18482 msg_puts((char_u *)", "); 18483 if (argvars[i].v_type == VAR_NUMBER) 18484 msg_outnum((long)argvars[i].vval.v_number); 18485 else 18486 { 18487 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18488 buf, MSG_BUF_CLEN); 18489 msg_puts(buf); 18490 vim_free(tofree); 18491 } 18492 } 18493 msg_puts((char_u *)")"); 18494 } 18495 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18496 18497 verbose_leave_scroll(); 18498 --no_wait_return; 18499 } 18500 } 18501 #ifdef FEAT_PROFILE 18502 if (do_profiling) 18503 { 18504 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18505 func_do_profile(fp); 18506 if (fp->uf_profiling 18507 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18508 { 18509 ++fp->uf_tm_count; 18510 profile_start(&fp->uf_tm_start); 18511 profile_zero(&fp->uf_tm_children); 18512 } 18513 script_prof_save(&wait_start); 18514 } 18515 #endif 18516 18517 save_current_SID = current_SID; 18518 current_SID = fp->uf_script_ID; 18519 save_did_emsg = did_emsg; 18520 did_emsg = FALSE; 18521 18522 /* call do_cmdline() to execute the lines */ 18523 do_cmdline(NULL, get_func_line, (void *)&fc, 18524 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18525 18526 --RedrawingDisabled; 18527 18528 /* when the function was aborted because of an error, return -1 */ 18529 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18530 { 18531 clear_tv(rettv); 18532 rettv->v_type = VAR_NUMBER; 18533 rettv->vval.v_number = -1; 18534 } 18535 18536 #ifdef FEAT_PROFILE 18537 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18538 { 18539 profile_end(&fp->uf_tm_start); 18540 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18541 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18542 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18543 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18544 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18545 { 18546 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18547 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18548 } 18549 } 18550 #endif 18551 18552 /* when being verbose, mention the return value */ 18553 if (p_verbose >= 12) 18554 { 18555 ++no_wait_return; 18556 verbose_enter_scroll(); 18557 18558 if (aborting()) 18559 smsg((char_u *)_("%s aborted"), sourcing_name); 18560 else if (fc.rettv->v_type == VAR_NUMBER) 18561 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18562 (long)fc.rettv->vval.v_number); 18563 else 18564 { 18565 char_u buf[MSG_BUF_LEN]; 18566 char_u numbuf[NUMBUFLEN]; 18567 char_u *tofree; 18568 18569 /* The value may be very long. Skip the middle part, so that we 18570 * have some idea how it starts and ends. smsg() would always 18571 * truncate it at the end. */ 18572 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18573 buf, MSG_BUF_CLEN); 18574 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18575 vim_free(tofree); 18576 } 18577 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18578 18579 verbose_leave_scroll(); 18580 --no_wait_return; 18581 } 18582 18583 vim_free(sourcing_name); 18584 sourcing_name = save_sourcing_name; 18585 sourcing_lnum = save_sourcing_lnum; 18586 current_SID = save_current_SID; 18587 #ifdef FEAT_PROFILE 18588 if (do_profiling) 18589 script_prof_restore(&wait_start); 18590 #endif 18591 18592 if (p_verbose >= 12 && sourcing_name != NULL) 18593 { 18594 ++no_wait_return; 18595 verbose_enter_scroll(); 18596 18597 smsg((char_u *)_("continuing in %s"), sourcing_name); 18598 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18599 18600 verbose_leave_scroll(); 18601 --no_wait_return; 18602 } 18603 18604 did_emsg |= save_did_emsg; 18605 current_funccal = fc.caller; 18606 18607 /* The a: variables typevals were not alloced, only free the allocated 18608 * variables. */ 18609 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18610 18611 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18612 --depth; 18613 } 18614 18615 /* 18616 * Add a number variable "name" to dict "dp" with value "nr". 18617 */ 18618 static void 18619 add_nr_var(dp, v, name, nr) 18620 dict_T *dp; 18621 dictitem_T *v; 18622 char *name; 18623 varnumber_T nr; 18624 { 18625 STRCPY(v->di_key, name); 18626 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18627 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18628 v->di_tv.v_type = VAR_NUMBER; 18629 v->di_tv.v_lock = VAR_FIXED; 18630 v->di_tv.vval.v_number = nr; 18631 } 18632 18633 /* 18634 * ":return [expr]" 18635 */ 18636 void 18637 ex_return(eap) 18638 exarg_T *eap; 18639 { 18640 char_u *arg = eap->arg; 18641 typval_T rettv; 18642 int returning = FALSE; 18643 18644 if (current_funccal == NULL) 18645 { 18646 EMSG(_("E133: :return not inside a function")); 18647 return; 18648 } 18649 18650 if (eap->skip) 18651 ++emsg_skip; 18652 18653 eap->nextcmd = NULL; 18654 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18655 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18656 { 18657 if (!eap->skip) 18658 returning = do_return(eap, FALSE, TRUE, &rettv); 18659 else 18660 clear_tv(&rettv); 18661 } 18662 /* It's safer to return also on error. */ 18663 else if (!eap->skip) 18664 { 18665 /* 18666 * Return unless the expression evaluation has been cancelled due to an 18667 * aborting error, an interrupt, or an exception. 18668 */ 18669 if (!aborting()) 18670 returning = do_return(eap, FALSE, TRUE, NULL); 18671 } 18672 18673 /* When skipping or the return gets pending, advance to the next command 18674 * in this line (!returning). Otherwise, ignore the rest of the line. 18675 * Following lines will be ignored by get_func_line(). */ 18676 if (returning) 18677 eap->nextcmd = NULL; 18678 else if (eap->nextcmd == NULL) /* no argument */ 18679 eap->nextcmd = check_nextcmd(arg); 18680 18681 if (eap->skip) 18682 --emsg_skip; 18683 } 18684 18685 /* 18686 * Return from a function. Possibly makes the return pending. Also called 18687 * for a pending return at the ":endtry" or after returning from an extra 18688 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18689 * when called due to a ":return" command. "rettv" may point to a typval_T 18690 * with the return rettv. Returns TRUE when the return can be carried out, 18691 * FALSE when the return gets pending. 18692 */ 18693 int 18694 do_return(eap, reanimate, is_cmd, rettv) 18695 exarg_T *eap; 18696 int reanimate; 18697 int is_cmd; 18698 void *rettv; 18699 { 18700 int idx; 18701 struct condstack *cstack = eap->cstack; 18702 18703 if (reanimate) 18704 /* Undo the return. */ 18705 current_funccal->returned = FALSE; 18706 18707 /* 18708 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18709 * not in its finally clause (which then is to be executed next) is found. 18710 * In this case, make the ":return" pending for execution at the ":endtry". 18711 * Otherwise, return normally. 18712 */ 18713 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18714 if (idx >= 0) 18715 { 18716 cstack->cs_pending[idx] = CSTP_RETURN; 18717 18718 if (!is_cmd && !reanimate) 18719 /* A pending return again gets pending. "rettv" points to an 18720 * allocated variable with the rettv of the original ":return"'s 18721 * argument if present or is NULL else. */ 18722 cstack->cs_rettv[idx] = rettv; 18723 else 18724 { 18725 /* When undoing a return in order to make it pending, get the stored 18726 * return rettv. */ 18727 if (reanimate) 18728 rettv = current_funccal->rettv; 18729 18730 if (rettv != NULL) 18731 { 18732 /* Store the value of the pending return. */ 18733 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18734 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18735 else 18736 EMSG(_(e_outofmem)); 18737 } 18738 else 18739 cstack->cs_rettv[idx] = NULL; 18740 18741 if (reanimate) 18742 { 18743 /* The pending return value could be overwritten by a ":return" 18744 * without argument in a finally clause; reset the default 18745 * return value. */ 18746 current_funccal->rettv->v_type = VAR_NUMBER; 18747 current_funccal->rettv->vval.v_number = 0; 18748 } 18749 } 18750 report_make_pending(CSTP_RETURN, rettv); 18751 } 18752 else 18753 { 18754 current_funccal->returned = TRUE; 18755 18756 /* If the return is carried out now, store the return value. For 18757 * a return immediately after reanimation, the value is already 18758 * there. */ 18759 if (!reanimate && rettv != NULL) 18760 { 18761 clear_tv(current_funccal->rettv); 18762 *current_funccal->rettv = *(typval_T *)rettv; 18763 if (!is_cmd) 18764 vim_free(rettv); 18765 } 18766 } 18767 18768 return idx < 0; 18769 } 18770 18771 /* 18772 * Free the variable with a pending return value. 18773 */ 18774 void 18775 discard_pending_return(rettv) 18776 void *rettv; 18777 { 18778 free_tv((typval_T *)rettv); 18779 } 18780 18781 /* 18782 * Generate a return command for producing the value of "rettv". The result 18783 * is an allocated string. Used by report_pending() for verbose messages. 18784 */ 18785 char_u * 18786 get_return_cmd(rettv) 18787 void *rettv; 18788 { 18789 char_u *s = NULL; 18790 char_u *tofree = NULL; 18791 char_u numbuf[NUMBUFLEN]; 18792 18793 if (rettv != NULL) 18794 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18795 if (s == NULL) 18796 s = (char_u *)""; 18797 18798 STRCPY(IObuff, ":return "); 18799 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18800 if (STRLEN(s) + 8 >= IOSIZE) 18801 STRCPY(IObuff + IOSIZE - 4, "..."); 18802 vim_free(tofree); 18803 return vim_strsave(IObuff); 18804 } 18805 18806 /* 18807 * Get next function line. 18808 * Called by do_cmdline() to get the next line. 18809 * Returns allocated string, or NULL for end of function. 18810 */ 18811 /* ARGSUSED */ 18812 char_u * 18813 get_func_line(c, cookie, indent) 18814 int c; /* not used */ 18815 void *cookie; 18816 int indent; /* not used */ 18817 { 18818 funccall_T *fcp = (funccall_T *)cookie; 18819 ufunc_T *fp = fcp->func; 18820 char_u *retval; 18821 garray_T *gap; /* growarray with function lines */ 18822 18823 /* If breakpoints have been added/deleted need to check for it. */ 18824 if (fcp->dbg_tick != debug_tick) 18825 { 18826 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18827 sourcing_lnum); 18828 fcp->dbg_tick = debug_tick; 18829 } 18830 #ifdef FEAT_PROFILE 18831 if (do_profiling) 18832 func_line_end(cookie); 18833 #endif 18834 18835 gap = &fp->uf_lines; 18836 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18837 retval = NULL; 18838 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18839 retval = NULL; 18840 else 18841 { 18842 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18843 sourcing_lnum = fcp->linenr; 18844 #ifdef FEAT_PROFILE 18845 if (do_profiling) 18846 func_line_start(cookie); 18847 #endif 18848 } 18849 18850 /* Did we encounter a breakpoint? */ 18851 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18852 { 18853 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18854 /* Find next breakpoint. */ 18855 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18856 sourcing_lnum); 18857 fcp->dbg_tick = debug_tick; 18858 } 18859 18860 return retval; 18861 } 18862 18863 #if defined(FEAT_PROFILE) || defined(PROTO) 18864 /* 18865 * Called when starting to read a function line. 18866 * "sourcing_lnum" must be correct! 18867 * When skipping lines it may not actually be executed, but we won't find out 18868 * until later and we need to store the time now. 18869 */ 18870 void 18871 func_line_start(cookie) 18872 void *cookie; 18873 { 18874 funccall_T *fcp = (funccall_T *)cookie; 18875 ufunc_T *fp = fcp->func; 18876 18877 if (fp->uf_profiling && sourcing_lnum >= 1 18878 && sourcing_lnum <= fp->uf_lines.ga_len) 18879 { 18880 fp->uf_tml_idx = sourcing_lnum - 1; 18881 fp->uf_tml_execed = FALSE; 18882 profile_start(&fp->uf_tml_start); 18883 profile_zero(&fp->uf_tml_children); 18884 profile_get_wait(&fp->uf_tml_wait); 18885 } 18886 } 18887 18888 /* 18889 * Called when actually executing a function line. 18890 */ 18891 void 18892 func_line_exec(cookie) 18893 void *cookie; 18894 { 18895 funccall_T *fcp = (funccall_T *)cookie; 18896 ufunc_T *fp = fcp->func; 18897 18898 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18899 fp->uf_tml_execed = TRUE; 18900 } 18901 18902 /* 18903 * Called when done with a function line. 18904 */ 18905 void 18906 func_line_end(cookie) 18907 void *cookie; 18908 { 18909 funccall_T *fcp = (funccall_T *)cookie; 18910 ufunc_T *fp = fcp->func; 18911 18912 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18913 { 18914 if (fp->uf_tml_execed) 18915 { 18916 ++fp->uf_tml_count[fp->uf_tml_idx]; 18917 profile_end(&fp->uf_tml_start); 18918 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18919 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18920 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18921 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18922 } 18923 fp->uf_tml_idx = -1; 18924 } 18925 } 18926 #endif 18927 18928 /* 18929 * Return TRUE if the currently active function should be ended, because a 18930 * return was encountered or an error occured. Used inside a ":while". 18931 */ 18932 int 18933 func_has_ended(cookie) 18934 void *cookie; 18935 { 18936 funccall_T *fcp = (funccall_T *)cookie; 18937 18938 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18939 * an error inside a try conditional. */ 18940 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18941 || fcp->returned); 18942 } 18943 18944 /* 18945 * return TRUE if cookie indicates a function which "abort"s on errors. 18946 */ 18947 int 18948 func_has_abort(cookie) 18949 void *cookie; 18950 { 18951 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18952 } 18953 18954 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18955 typedef enum 18956 { 18957 VAR_FLAVOUR_DEFAULT, 18958 VAR_FLAVOUR_SESSION, 18959 VAR_FLAVOUR_VIMINFO 18960 } var_flavour_T; 18961 18962 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18963 18964 static var_flavour_T 18965 var_flavour(varname) 18966 char_u *varname; 18967 { 18968 char_u *p = varname; 18969 18970 if (ASCII_ISUPPER(*p)) 18971 { 18972 while (*(++p)) 18973 if (ASCII_ISLOWER(*p)) 18974 return VAR_FLAVOUR_SESSION; 18975 return VAR_FLAVOUR_VIMINFO; 18976 } 18977 else 18978 return VAR_FLAVOUR_DEFAULT; 18979 } 18980 #endif 18981 18982 #if defined(FEAT_VIMINFO) || defined(PROTO) 18983 /* 18984 * Restore global vars that start with a capital from the viminfo file 18985 */ 18986 int 18987 read_viminfo_varlist(virp, writing) 18988 vir_T *virp; 18989 int writing; 18990 { 18991 char_u *tab; 18992 int is_string = FALSE; 18993 typval_T tv; 18994 18995 if (!writing && (find_viminfo_parameter('!') != NULL)) 18996 { 18997 tab = vim_strchr(virp->vir_line + 1, '\t'); 18998 if (tab != NULL) 18999 { 19000 *tab++ = '\0'; /* isolate the variable name */ 19001 if (*tab == 'S') /* string var */ 19002 is_string = TRUE; 19003 19004 tab = vim_strchr(tab, '\t'); 19005 if (tab != NULL) 19006 { 19007 if (is_string) 19008 { 19009 tv.v_type = VAR_STRING; 19010 tv.vval.v_string = viminfo_readstring(virp, 19011 (int)(tab - virp->vir_line + 1), TRUE); 19012 } 19013 else 19014 { 19015 tv.v_type = VAR_NUMBER; 19016 tv.vval.v_number = atol((char *)tab + 1); 19017 } 19018 set_var(virp->vir_line + 1, &tv, FALSE); 19019 if (is_string) 19020 vim_free(tv.vval.v_string); 19021 } 19022 } 19023 } 19024 19025 return viminfo_readline(virp); 19026 } 19027 19028 /* 19029 * Write global vars that start with a capital to the viminfo file 19030 */ 19031 void 19032 write_viminfo_varlist(fp) 19033 FILE *fp; 19034 { 19035 hashitem_T *hi; 19036 dictitem_T *this_var; 19037 int todo; 19038 char *s; 19039 char_u *p; 19040 char_u *tofree; 19041 char_u numbuf[NUMBUFLEN]; 19042 19043 if (find_viminfo_parameter('!') == NULL) 19044 return; 19045 19046 fprintf(fp, _("\n# global variables:\n")); 19047 19048 todo = globvarht.ht_used; 19049 for (hi = globvarht.ht_array; todo > 0; ++hi) 19050 { 19051 if (!HASHITEM_EMPTY(hi)) 19052 { 19053 --todo; 19054 this_var = HI2DI(hi); 19055 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 19056 { 19057 switch (this_var->di_tv.v_type) 19058 { 19059 case VAR_STRING: s = "STR"; break; 19060 case VAR_NUMBER: s = "NUM"; break; 19061 default: continue; 19062 } 19063 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 19064 p = echo_string(&this_var->di_tv, &tofree, numbuf); 19065 if (p != NULL) 19066 viminfo_writestring(fp, p); 19067 vim_free(tofree); 19068 } 19069 } 19070 } 19071 } 19072 #endif 19073 19074 #if defined(FEAT_SESSION) || defined(PROTO) 19075 int 19076 store_session_globals(fd) 19077 FILE *fd; 19078 { 19079 hashitem_T *hi; 19080 dictitem_T *this_var; 19081 int todo; 19082 char_u *p, *t; 19083 19084 todo = globvarht.ht_used; 19085 for (hi = globvarht.ht_array; todo > 0; ++hi) 19086 { 19087 if (!HASHITEM_EMPTY(hi)) 19088 { 19089 --todo; 19090 this_var = HI2DI(hi); 19091 if ((this_var->di_tv.v_type == VAR_NUMBER 19092 || this_var->di_tv.v_type == VAR_STRING) 19093 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 19094 { 19095 /* Escape special characters with a backslash. Turn a LF and 19096 * CR into \n and \r. */ 19097 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 19098 (char_u *)"\\\"\n\r"); 19099 if (p == NULL) /* out of memory */ 19100 break; 19101 for (t = p; *t != NUL; ++t) 19102 if (*t == '\n') 19103 *t = 'n'; 19104 else if (*t == '\r') 19105 *t = 'r'; 19106 if ((fprintf(fd, "let %s = %c%s%c", 19107 this_var->di_key, 19108 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19109 : ' ', 19110 p, 19111 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19112 : ' ') < 0) 19113 || put_eol(fd) == FAIL) 19114 { 19115 vim_free(p); 19116 return FAIL; 19117 } 19118 vim_free(p); 19119 } 19120 } 19121 } 19122 return OK; 19123 } 19124 #endif 19125 19126 /* 19127 * Display script name where an item was last set. 19128 * Should only be invoked when 'verbose' is non-zero. 19129 */ 19130 void 19131 last_set_msg(scriptID) 19132 scid_T scriptID; 19133 { 19134 char_u *p; 19135 19136 if (scriptID != 0) 19137 { 19138 p = home_replace_save(NULL, get_scriptname(scriptID)); 19139 if (p != NULL) 19140 { 19141 verbose_enter(); 19142 MSG_PUTS(_("\n\tLast set from ")); 19143 MSG_PUTS(p); 19144 vim_free(p); 19145 verbose_leave(); 19146 } 19147 } 19148 } 19149 19150 #endif /* FEAT_EVAL */ 19151 19152 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 19153 19154 19155 #ifdef WIN3264 19156 /* 19157 * Functions for ":8" filename modifier: get 8.3 version of a filename. 19158 */ 19159 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19160 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 19161 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19162 19163 /* 19164 * Get the short pathname of a file. 19165 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 19166 */ 19167 static int 19168 get_short_pathname(fnamep, bufp, fnamelen) 19169 char_u **fnamep; 19170 char_u **bufp; 19171 int *fnamelen; 19172 { 19173 int l,len; 19174 char_u *newbuf; 19175 19176 len = *fnamelen; 19177 19178 l = GetShortPathName(*fnamep, *fnamep, len); 19179 if (l > len - 1) 19180 { 19181 /* If that doesn't work (not enough space), then save the string 19182 * and try again with a new buffer big enough 19183 */ 19184 newbuf = vim_strnsave(*fnamep, l); 19185 if (newbuf == NULL) 19186 return 0; 19187 19188 vim_free(*bufp); 19189 *fnamep = *bufp = newbuf; 19190 19191 l = GetShortPathName(*fnamep,*fnamep,l+1); 19192 19193 /* Really should always succeed, as the buffer is big enough */ 19194 } 19195 19196 *fnamelen = l; 19197 return 1; 19198 } 19199 19200 /* 19201 * Create a short path name. Returns the length of the buffer it needs. 19202 * Doesn't copy over the end of the buffer passed in. 19203 */ 19204 static int 19205 shortpath_for_invalid_fname(fname, bufp, fnamelen) 19206 char_u **fname; 19207 char_u **bufp; 19208 int *fnamelen; 19209 { 19210 char_u *s, *p, *pbuf2, *pbuf3; 19211 char_u ch; 19212 int len, len2, plen, slen; 19213 19214 /* Make a copy */ 19215 len2 = *fnamelen; 19216 pbuf2 = vim_strnsave(*fname, len2); 19217 pbuf3 = NULL; 19218 19219 s = pbuf2 + len2 - 1; /* Find the end */ 19220 slen = 1; 19221 plen = len2; 19222 19223 if (after_pathsep(pbuf2, s + 1)) 19224 { 19225 --s; 19226 ++slen; 19227 --plen; 19228 } 19229 19230 do 19231 { 19232 /* Go back one path-seperator */ 19233 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 19234 { 19235 --s; 19236 ++slen; 19237 --plen; 19238 } 19239 if (s <= pbuf2) 19240 break; 19241 19242 /* Remeber the character that is about to be blatted */ 19243 ch = *s; 19244 *s = 0; /* get_short_pathname requires a null-terminated string */ 19245 19246 /* Try it in situ */ 19247 p = pbuf2; 19248 if (!get_short_pathname(&p, &pbuf3, &plen)) 19249 { 19250 vim_free(pbuf2); 19251 return -1; 19252 } 19253 *s = ch; /* Preserve the string */ 19254 } while (plen == 0); 19255 19256 if (plen > 0) 19257 { 19258 /* Remeber the length of the new string. */ 19259 *fnamelen = len = plen + slen; 19260 vim_free(*bufp); 19261 if (len > len2) 19262 { 19263 /* If there's not enough space in the currently allocated string, 19264 * then copy it to a buffer big enough. 19265 */ 19266 *fname= *bufp = vim_strnsave(p, len); 19267 if (*fname == NULL) 19268 return -1; 19269 } 19270 else 19271 { 19272 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 19273 *fname = *bufp = pbuf2; 19274 if (p != pbuf2) 19275 strncpy(*fname, p, plen); 19276 pbuf2 = NULL; 19277 } 19278 /* Concat the next bit */ 19279 strncpy(*fname + plen, s, slen); 19280 (*fname)[len] = '\0'; 19281 } 19282 vim_free(pbuf3); 19283 vim_free(pbuf2); 19284 return 0; 19285 } 19286 19287 /* 19288 * Get a pathname for a partial path. 19289 */ 19290 static int 19291 shortpath_for_partial(fnamep, bufp, fnamelen) 19292 char_u **fnamep; 19293 char_u **bufp; 19294 int *fnamelen; 19295 { 19296 int sepcount, len, tflen; 19297 char_u *p; 19298 char_u *pbuf, *tfname; 19299 int hasTilde; 19300 19301 /* Count up the path seperators from the RHS.. so we know which part 19302 * of the path to return. 19303 */ 19304 sepcount = 0; 19305 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19306 if (vim_ispathsep(*p)) 19307 ++sepcount; 19308 19309 /* Need full path first (use expand_env() to remove a "~/") */ 19310 hasTilde = (**fnamep == '~'); 19311 if (hasTilde) 19312 pbuf = tfname = expand_env_save(*fnamep); 19313 else 19314 pbuf = tfname = FullName_save(*fnamep, FALSE); 19315 19316 len = tflen = STRLEN(tfname); 19317 19318 if (!get_short_pathname(&tfname, &pbuf, &len)) 19319 return -1; 19320 19321 if (len == 0) 19322 { 19323 /* Don't have a valid filename, so shorten the rest of the 19324 * path if we can. This CAN give us invalid 8.3 filenames, but 19325 * there's not a lot of point in guessing what it might be. 19326 */ 19327 len = tflen; 19328 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19329 return -1; 19330 } 19331 19332 /* Count the paths backward to find the beginning of the desired string. */ 19333 for (p = tfname + len - 1; p >= tfname; --p) 19334 { 19335 #ifdef FEAT_MBYTE 19336 if (has_mbyte) 19337 p -= mb_head_off(tfname, p); 19338 #endif 19339 if (vim_ispathsep(*p)) 19340 { 19341 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19342 break; 19343 else 19344 sepcount --; 19345 } 19346 } 19347 if (hasTilde) 19348 { 19349 --p; 19350 if (p >= tfname) 19351 *p = '~'; 19352 else 19353 return -1; 19354 } 19355 else 19356 ++p; 19357 19358 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19359 vim_free(*bufp); 19360 *fnamelen = (int)STRLEN(p); 19361 *bufp = pbuf; 19362 *fnamep = p; 19363 19364 return 0; 19365 } 19366 #endif /* WIN3264 */ 19367 19368 /* 19369 * Adjust a filename, according to a string of modifiers. 19370 * *fnamep must be NUL terminated when called. When returning, the length is 19371 * determined by *fnamelen. 19372 * Returns valid flags. 19373 * When there is an error, *fnamep is set to NULL. 19374 */ 19375 int 19376 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19377 char_u *src; /* string with modifiers */ 19378 int *usedlen; /* characters after src that are used */ 19379 char_u **fnamep; /* file name so far */ 19380 char_u **bufp; /* buffer for allocated file name or NULL */ 19381 int *fnamelen; /* length of fnamep */ 19382 { 19383 int valid = 0; 19384 char_u *tail; 19385 char_u *s, *p, *pbuf; 19386 char_u dirname[MAXPATHL]; 19387 int c; 19388 int has_fullname = 0; 19389 #ifdef WIN3264 19390 int has_shortname = 0; 19391 #endif 19392 19393 repeat: 19394 /* ":p" - full path/file_name */ 19395 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19396 { 19397 has_fullname = 1; 19398 19399 valid |= VALID_PATH; 19400 *usedlen += 2; 19401 19402 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19403 if ((*fnamep)[0] == '~' 19404 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19405 && ((*fnamep)[1] == '/' 19406 # ifdef BACKSLASH_IN_FILENAME 19407 || (*fnamep)[1] == '\\' 19408 # endif 19409 || (*fnamep)[1] == NUL) 19410 19411 #endif 19412 ) 19413 { 19414 *fnamep = expand_env_save(*fnamep); 19415 vim_free(*bufp); /* free any allocated file name */ 19416 *bufp = *fnamep; 19417 if (*fnamep == NULL) 19418 return -1; 19419 } 19420 19421 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19422 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19423 { 19424 if (vim_ispathsep(*p) 19425 && p[1] == '.' 19426 && (p[2] == NUL 19427 || vim_ispathsep(p[2]) 19428 || (p[2] == '.' 19429 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19430 break; 19431 } 19432 19433 /* FullName_save() is slow, don't use it when not needed. */ 19434 if (*p != NUL || !vim_isAbsName(*fnamep)) 19435 { 19436 *fnamep = FullName_save(*fnamep, *p != NUL); 19437 vim_free(*bufp); /* free any allocated file name */ 19438 *bufp = *fnamep; 19439 if (*fnamep == NULL) 19440 return -1; 19441 } 19442 19443 /* Append a path separator to a directory. */ 19444 if (mch_isdir(*fnamep)) 19445 { 19446 /* Make room for one or two extra characters. */ 19447 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19448 vim_free(*bufp); /* free any allocated file name */ 19449 *bufp = *fnamep; 19450 if (*fnamep == NULL) 19451 return -1; 19452 add_pathsep(*fnamep); 19453 } 19454 } 19455 19456 /* ":." - path relative to the current directory */ 19457 /* ":~" - path relative to the home directory */ 19458 /* ":8" - shortname path - postponed till after */ 19459 while (src[*usedlen] == ':' 19460 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19461 { 19462 *usedlen += 2; 19463 if (c == '8') 19464 { 19465 #ifdef WIN3264 19466 has_shortname = 1; /* Postpone this. */ 19467 #endif 19468 continue; 19469 } 19470 pbuf = NULL; 19471 /* Need full path first (use expand_env() to remove a "~/") */ 19472 if (!has_fullname) 19473 { 19474 if (c == '.' && **fnamep == '~') 19475 p = pbuf = expand_env_save(*fnamep); 19476 else 19477 p = pbuf = FullName_save(*fnamep, FALSE); 19478 } 19479 else 19480 p = *fnamep; 19481 19482 has_fullname = 0; 19483 19484 if (p != NULL) 19485 { 19486 if (c == '.') 19487 { 19488 mch_dirname(dirname, MAXPATHL); 19489 s = shorten_fname(p, dirname); 19490 if (s != NULL) 19491 { 19492 *fnamep = s; 19493 if (pbuf != NULL) 19494 { 19495 vim_free(*bufp); /* free any allocated file name */ 19496 *bufp = pbuf; 19497 pbuf = NULL; 19498 } 19499 } 19500 } 19501 else 19502 { 19503 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19504 /* Only replace it when it starts with '~' */ 19505 if (*dirname == '~') 19506 { 19507 s = vim_strsave(dirname); 19508 if (s != NULL) 19509 { 19510 *fnamep = s; 19511 vim_free(*bufp); 19512 *bufp = s; 19513 } 19514 } 19515 } 19516 vim_free(pbuf); 19517 } 19518 } 19519 19520 tail = gettail(*fnamep); 19521 *fnamelen = (int)STRLEN(*fnamep); 19522 19523 /* ":h" - head, remove "/file_name", can be repeated */ 19524 /* Don't remove the first "/" or "c:\" */ 19525 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19526 { 19527 valid |= VALID_HEAD; 19528 *usedlen += 2; 19529 s = get_past_head(*fnamep); 19530 while (tail > s && after_pathsep(s, tail)) 19531 --tail; 19532 *fnamelen = (int)(tail - *fnamep); 19533 #ifdef VMS 19534 if (*fnamelen > 0) 19535 *fnamelen += 1; /* the path separator is part of the path */ 19536 #endif 19537 while (tail > s && !after_pathsep(s, tail)) 19538 mb_ptr_back(*fnamep, tail); 19539 } 19540 19541 /* ":8" - shortname */ 19542 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19543 { 19544 *usedlen += 2; 19545 #ifdef WIN3264 19546 has_shortname = 1; 19547 #endif 19548 } 19549 19550 #ifdef WIN3264 19551 /* Check shortname after we have done 'heads' and before we do 'tails' 19552 */ 19553 if (has_shortname) 19554 { 19555 pbuf = NULL; 19556 /* Copy the string if it is shortened by :h */ 19557 if (*fnamelen < (int)STRLEN(*fnamep)) 19558 { 19559 p = vim_strnsave(*fnamep, *fnamelen); 19560 if (p == 0) 19561 return -1; 19562 vim_free(*bufp); 19563 *bufp = *fnamep = p; 19564 } 19565 19566 /* Split into two implementations - makes it easier. First is where 19567 * there isn't a full name already, second is where there is. 19568 */ 19569 if (!has_fullname && !vim_isAbsName(*fnamep)) 19570 { 19571 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19572 return -1; 19573 } 19574 else 19575 { 19576 int l; 19577 19578 /* Simple case, already have the full-name 19579 * Nearly always shorter, so try first time. */ 19580 l = *fnamelen; 19581 if (!get_short_pathname(fnamep, bufp, &l)) 19582 return -1; 19583 19584 if (l == 0) 19585 { 19586 /* Couldn't find the filename.. search the paths. 19587 */ 19588 l = *fnamelen; 19589 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19590 return -1; 19591 } 19592 *fnamelen = l; 19593 } 19594 } 19595 #endif /* WIN3264 */ 19596 19597 /* ":t" - tail, just the basename */ 19598 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19599 { 19600 *usedlen += 2; 19601 *fnamelen -= (int)(tail - *fnamep); 19602 *fnamep = tail; 19603 } 19604 19605 /* ":e" - extension, can be repeated */ 19606 /* ":r" - root, without extension, can be repeated */ 19607 while (src[*usedlen] == ':' 19608 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19609 { 19610 /* find a '.' in the tail: 19611 * - for second :e: before the current fname 19612 * - otherwise: The last '.' 19613 */ 19614 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19615 s = *fnamep - 2; 19616 else 19617 s = *fnamep + *fnamelen - 1; 19618 for ( ; s > tail; --s) 19619 if (s[0] == '.') 19620 break; 19621 if (src[*usedlen + 1] == 'e') /* :e */ 19622 { 19623 if (s > tail) 19624 { 19625 *fnamelen += (int)(*fnamep - (s + 1)); 19626 *fnamep = s + 1; 19627 #ifdef VMS 19628 /* cut version from the extension */ 19629 s = *fnamep + *fnamelen - 1; 19630 for ( ; s > *fnamep; --s) 19631 if (s[0] == ';') 19632 break; 19633 if (s > *fnamep) 19634 *fnamelen = s - *fnamep; 19635 #endif 19636 } 19637 else if (*fnamep <= tail) 19638 *fnamelen = 0; 19639 } 19640 else /* :r */ 19641 { 19642 if (s > tail) /* remove one extension */ 19643 *fnamelen = (int)(s - *fnamep); 19644 } 19645 *usedlen += 2; 19646 } 19647 19648 /* ":s?pat?foo?" - substitute */ 19649 /* ":gs?pat?foo?" - global substitute */ 19650 if (src[*usedlen] == ':' 19651 && (src[*usedlen + 1] == 's' 19652 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19653 { 19654 char_u *str; 19655 char_u *pat; 19656 char_u *sub; 19657 int sep; 19658 char_u *flags; 19659 int didit = FALSE; 19660 19661 flags = (char_u *)""; 19662 s = src + *usedlen + 2; 19663 if (src[*usedlen + 1] == 'g') 19664 { 19665 flags = (char_u *)"g"; 19666 ++s; 19667 } 19668 19669 sep = *s++; 19670 if (sep) 19671 { 19672 /* find end of pattern */ 19673 p = vim_strchr(s, sep); 19674 if (p != NULL) 19675 { 19676 pat = vim_strnsave(s, (int)(p - s)); 19677 if (pat != NULL) 19678 { 19679 s = p + 1; 19680 /* find end of substitution */ 19681 p = vim_strchr(s, sep); 19682 if (p != NULL) 19683 { 19684 sub = vim_strnsave(s, (int)(p - s)); 19685 str = vim_strnsave(*fnamep, *fnamelen); 19686 if (sub != NULL && str != NULL) 19687 { 19688 *usedlen = (int)(p + 1 - src); 19689 s = do_string_sub(str, pat, sub, flags); 19690 if (s != NULL) 19691 { 19692 *fnamep = s; 19693 *fnamelen = (int)STRLEN(s); 19694 vim_free(*bufp); 19695 *bufp = s; 19696 didit = TRUE; 19697 } 19698 } 19699 vim_free(sub); 19700 vim_free(str); 19701 } 19702 vim_free(pat); 19703 } 19704 } 19705 /* after using ":s", repeat all the modifiers */ 19706 if (didit) 19707 goto repeat; 19708 } 19709 } 19710 19711 return valid; 19712 } 19713 19714 /* 19715 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19716 * "flags" can be "g" to do a global substitute. 19717 * Returns an allocated string, NULL for error. 19718 */ 19719 char_u * 19720 do_string_sub(str, pat, sub, flags) 19721 char_u *str; 19722 char_u *pat; 19723 char_u *sub; 19724 char_u *flags; 19725 { 19726 int sublen; 19727 regmatch_T regmatch; 19728 int i; 19729 int do_all; 19730 char_u *tail; 19731 garray_T ga; 19732 char_u *ret; 19733 char_u *save_cpo; 19734 19735 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19736 save_cpo = p_cpo; 19737 p_cpo = (char_u *)""; 19738 19739 ga_init2(&ga, 1, 200); 19740 19741 do_all = (flags[0] == 'g'); 19742 19743 regmatch.rm_ic = p_ic; 19744 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19745 if (regmatch.regprog != NULL) 19746 { 19747 tail = str; 19748 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19749 { 19750 /* 19751 * Get some space for a temporary buffer to do the substitution 19752 * into. It will contain: 19753 * - The text up to where the match is. 19754 * - The substituted text. 19755 * - The text after the match. 19756 */ 19757 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19758 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19759 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19760 { 19761 ga_clear(&ga); 19762 break; 19763 } 19764 19765 /* copy the text up to where the match is */ 19766 i = (int)(regmatch.startp[0] - tail); 19767 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19768 /* add the substituted text */ 19769 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19770 + ga.ga_len + i, TRUE, TRUE, FALSE); 19771 ga.ga_len += i + sublen - 1; 19772 /* avoid getting stuck on a match with an empty string */ 19773 if (tail == regmatch.endp[0]) 19774 { 19775 if (*tail == NUL) 19776 break; 19777 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19778 ++ga.ga_len; 19779 } 19780 else 19781 { 19782 tail = regmatch.endp[0]; 19783 if (*tail == NUL) 19784 break; 19785 } 19786 if (!do_all) 19787 break; 19788 } 19789 19790 if (ga.ga_data != NULL) 19791 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19792 19793 vim_free(regmatch.regprog); 19794 } 19795 19796 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19797 ga_clear(&ga); 19798 p_cpo = save_cpo; 19799 19800 return ret; 19801 } 19802 19803 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19804