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 {VV_NAME("swapname", VAR_STRING), VV_RO}, 342 {VV_NAME("swapchoice", VAR_STRING), 0}, 343 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 344 }; 345 346 /* shorthand */ 347 #define vv_type vv_di.di_tv.v_type 348 #define vv_nr vv_di.di_tv.vval.v_number 349 #define vv_str vv_di.di_tv.vval.v_string 350 #define vv_tv vv_di.di_tv 351 352 /* 353 * The v: variables are stored in dictionary "vimvardict". 354 * "vimvars_var" is the variable that is used for the "l:" scope. 355 */ 356 static dict_T vimvardict; 357 static dictitem_T vimvars_var; 358 #define vimvarht vimvardict.dv_hashtab 359 360 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 361 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 362 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 363 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 364 #endif 365 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 366 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 367 static char_u *skip_var_one __ARGS((char_u *arg)); 368 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 369 static void list_glob_vars __ARGS((void)); 370 static void list_buf_vars __ARGS((void)); 371 static void list_win_vars __ARGS((void)); 372 static void list_vim_vars __ARGS((void)); 373 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 374 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 375 static int check_changedtick __ARGS((char_u *arg)); 376 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 377 static void clear_lval __ARGS((lval_T *lp)); 378 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 379 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 380 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 381 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 382 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 383 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 384 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 385 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 386 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 387 static int tv_islocked __ARGS((typval_T *tv)); 388 389 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 390 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 391 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 392 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 393 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 394 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 395 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 396 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 397 398 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 399 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 400 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 401 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 402 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 403 static list_T *list_alloc __ARGS((void)); 404 static void list_free __ARGS((list_T *l)); 405 static listitem_T *listitem_alloc __ARGS((void)); 406 static void listitem_free __ARGS((listitem_T *item)); 407 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 408 static long list_len __ARGS((list_T *l)); 409 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 410 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 411 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 412 static listitem_T *list_find __ARGS((list_T *l, long n)); 413 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 414 static void list_append __ARGS((list_T *l, listitem_T *item)); 415 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 416 static int list_append_string __ARGS((list_T *l, char_u *str, int len)); 417 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 418 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 419 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 420 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 421 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 422 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 423 static char_u *list2string __ARGS((typval_T *tv)); 424 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); 425 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 426 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 427 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 428 static void dict_unref __ARGS((dict_T *d)); 429 static void dict_free __ARGS((dict_T *d)); 430 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 431 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 432 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 433 static void dictitem_free __ARGS((dictitem_T *item)); 434 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 435 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 436 static long dict_len __ARGS((dict_T *d)); 437 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 438 static char_u *dict2string __ARGS((typval_T *tv)); 439 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 440 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 441 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 442 static char_u *string_quote __ARGS((char_u *str, int function)); 443 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 444 static int find_internal_func __ARGS((char_u *name)); 445 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 446 static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 447 static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 448 static void emsg_funcname __ARGS((char *msg, char_u *name)); 449 450 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 468 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 469 #if defined(FEAT_INS_EXPAND) 470 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 472 #endif 473 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 478 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 570 #ifdef vim_mkdir 571 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 572 #endif 573 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 607 #ifdef HAVE_STRFTIME 608 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 609 #endif 610 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 636 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 637 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 640 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 641 642 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 643 static int get_env_len __ARGS((char_u **arg)); 644 static int get_id_len __ARGS((char_u **arg)); 645 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 646 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 647 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 648 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 649 valid character */ 650 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 651 static int eval_isnamec __ARGS((int c)); 652 static int eval_isnamec1 __ARGS((int c)); 653 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 654 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 655 static typval_T *alloc_tv __ARGS((void)); 656 static typval_T *alloc_string_tv __ARGS((char_u *string)); 657 static void free_tv __ARGS((typval_T *varp)); 658 static void init_tv __ARGS((typval_T *varp)); 659 static long get_tv_number __ARGS((typval_T *varp)); 660 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 661 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 662 static char_u *get_tv_string __ARGS((typval_T *varp)); 663 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 664 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 665 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 666 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 667 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 668 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 669 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 670 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 671 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 672 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 673 static int var_check_ro __ARGS((int flags, char_u *name)); 674 static int tv_check_lock __ARGS((int lock, char_u *name)); 675 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 676 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 677 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 678 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 679 static int eval_fname_script __ARGS((char_u *p)); 680 static int eval_fname_sid __ARGS((char_u *p)); 681 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 682 static ufunc_T *find_func __ARGS((char_u *name)); 683 static int function_exists __ARGS((char_u *name)); 684 static int builtin_function __ARGS((char_u *name)); 685 #ifdef FEAT_PROFILE 686 static void func_do_profile __ARGS((ufunc_T *fp)); 687 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 688 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 689 static int 690 # ifdef __BORLANDC__ 691 _RTLENTRYF 692 # endif 693 prof_total_cmp __ARGS((const void *s1, const void *s2)); 694 static int 695 # ifdef __BORLANDC__ 696 _RTLENTRYF 697 # endif 698 prof_self_cmp __ARGS((const void *s1, const void *s2)); 699 #endif 700 static int script_autoload __ARGS((char_u *name, int reload)); 701 static char_u *autoload_name __ARGS((char_u *name)); 702 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 703 static void func_free __ARGS((ufunc_T *fp)); 704 static void func_unref __ARGS((char_u *name)); 705 static void func_ref __ARGS((char_u *name)); 706 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)); 707 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 708 709 /* Character used as separated in autoload function/variable names. */ 710 #define AUTOLOAD_CHAR '#' 711 712 /* 713 * Initialize the global and v: variables. 714 */ 715 void 716 eval_init() 717 { 718 int i; 719 struct vimvar *p; 720 721 init_var_dict(&globvardict, &globvars_var); 722 init_var_dict(&vimvardict, &vimvars_var); 723 hash_init(&compat_hashtab); 724 hash_init(&func_hashtab); 725 726 for (i = 0; i < VV_LEN; ++i) 727 { 728 p = &vimvars[i]; 729 STRCPY(p->vv_di.di_key, p->vv_name); 730 if (p->vv_flags & VV_RO) 731 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 732 else if (p->vv_flags & VV_RO_SBX) 733 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 734 else 735 p->vv_di.di_flags = DI_FLAGS_FIX; 736 737 /* add to v: scope dict, unless the value is not always available */ 738 if (p->vv_type != VAR_UNKNOWN) 739 hash_add(&vimvarht, p->vv_di.di_key); 740 if (p->vv_flags & VV_COMPAT) 741 /* add to compat scope dict */ 742 hash_add(&compat_hashtab, p->vv_di.di_key); 743 } 744 } 745 746 #if defined(EXITFREE) || defined(PROTO) 747 void 748 eval_clear() 749 { 750 int i; 751 struct vimvar *p; 752 753 for (i = 0; i < VV_LEN; ++i) 754 { 755 p = &vimvars[i]; 756 if (p->vv_di.di_tv.v_type == VAR_STRING) 757 { 758 vim_free(p->vv_di.di_tv.vval.v_string); 759 p->vv_di.di_tv.vval.v_string = NULL; 760 } 761 } 762 hash_clear(&vimvarht); 763 hash_clear(&compat_hashtab); 764 765 /* script-local variables */ 766 for (i = 1; i <= ga_scripts.ga_len; ++i) 767 vars_clear(&SCRIPT_VARS(i)); 768 ga_clear(&ga_scripts); 769 free_scriptnames(); 770 771 /* global variables */ 772 vars_clear(&globvarht); 773 774 /* functions */ 775 free_all_functions(); 776 hash_clear(&func_hashtab); 777 778 /* unreferenced lists and dicts */ 779 (void)garbage_collect(); 780 } 781 #endif 782 783 /* 784 * Return the name of the executed function. 785 */ 786 char_u * 787 func_name(cookie) 788 void *cookie; 789 { 790 return ((funccall_T *)cookie)->func->uf_name; 791 } 792 793 /* 794 * Return the address holding the next breakpoint line for a funccall cookie. 795 */ 796 linenr_T * 797 func_breakpoint(cookie) 798 void *cookie; 799 { 800 return &((funccall_T *)cookie)->breakpoint; 801 } 802 803 /* 804 * Return the address holding the debug tick for a funccall cookie. 805 */ 806 int * 807 func_dbg_tick(cookie) 808 void *cookie; 809 { 810 return &((funccall_T *)cookie)->dbg_tick; 811 } 812 813 /* 814 * Return the nesting level for a funccall cookie. 815 */ 816 int 817 func_level(cookie) 818 void *cookie; 819 { 820 return ((funccall_T *)cookie)->level; 821 } 822 823 /* pointer to funccal for currently active function */ 824 funccall_T *current_funccal = NULL; 825 826 /* 827 * Return TRUE when a function was ended by a ":return" command. 828 */ 829 int 830 current_func_returned() 831 { 832 return current_funccal->returned; 833 } 834 835 836 /* 837 * Set an internal variable to a string value. Creates the variable if it does 838 * not already exist. 839 */ 840 void 841 set_internal_string_var(name, value) 842 char_u *name; 843 char_u *value; 844 { 845 char_u *val; 846 typval_T *tvp; 847 848 val = vim_strsave(value); 849 if (val != NULL) 850 { 851 tvp = alloc_string_tv(val); 852 if (tvp != NULL) 853 { 854 set_var(name, tvp, FALSE); 855 free_tv(tvp); 856 } 857 } 858 } 859 860 static lval_T *redir_lval = NULL; 861 static char_u *redir_endp = NULL; 862 static char_u *redir_varname = NULL; 863 864 /* 865 * Start recording command output to a variable 866 * Returns OK if successfully completed the setup. FAIL otherwise. 867 */ 868 int 869 var_redir_start(name, append) 870 char_u *name; 871 int append; /* append to an existing variable */ 872 { 873 int save_emsg; 874 int err; 875 typval_T tv; 876 877 /* Make sure a valid variable name is specified */ 878 if (!eval_isnamec1(*name)) 879 { 880 EMSG(_(e_invarg)); 881 return FAIL; 882 } 883 884 redir_varname = vim_strsave(name); 885 if (redir_varname == NULL) 886 return FAIL; 887 888 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 889 if (redir_lval == NULL) 890 { 891 var_redir_stop(); 892 return FAIL; 893 } 894 895 /* Parse the variable name (can be a dict or list entry). */ 896 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 897 FNE_CHECK_START); 898 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 899 { 900 if (redir_endp != NULL && *redir_endp != NUL) 901 /* Trailing characters are present after the variable name */ 902 EMSG(_(e_trailing)); 903 else 904 EMSG(_(e_invarg)); 905 var_redir_stop(); 906 return FAIL; 907 } 908 909 /* check if we can write to the variable: set it to or append an empty 910 * string */ 911 save_emsg = did_emsg; 912 did_emsg = FALSE; 913 tv.v_type = VAR_STRING; 914 tv.vval.v_string = (char_u *)""; 915 if (append) 916 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 917 else 918 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 919 err = did_emsg; 920 did_emsg += save_emsg; 921 if (err) 922 { 923 var_redir_stop(); 924 return FAIL; 925 } 926 if (redir_lval->ll_newkey != NULL) 927 { 928 /* Dictionary item was created, don't do it again. */ 929 vim_free(redir_lval->ll_newkey); 930 redir_lval->ll_newkey = NULL; 931 } 932 933 return OK; 934 } 935 936 /* 937 * Append "value[len]" to the variable set by var_redir_start(). 938 */ 939 void 940 var_redir_str(value, len) 941 char_u *value; 942 int len; 943 { 944 char_u *val; 945 typval_T tv; 946 int save_emsg; 947 int err; 948 949 if (redir_lval == NULL) 950 return; 951 952 if (len == -1) 953 /* Append the entire string */ 954 val = vim_strsave(value); 955 else 956 /* Append only the specified number of characters */ 957 val = vim_strnsave(value, len); 958 if (val == NULL) 959 return; 960 961 tv.v_type = VAR_STRING; 962 tv.vval.v_string = val; 963 964 save_emsg = did_emsg; 965 did_emsg = FALSE; 966 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 967 err = did_emsg; 968 did_emsg += save_emsg; 969 if (err) 970 var_redir_stop(); 971 972 vim_free(tv.vval.v_string); 973 } 974 975 /* 976 * Stop redirecting command output to a variable. 977 */ 978 void 979 var_redir_stop() 980 { 981 if (redir_lval != NULL) 982 { 983 clear_lval(redir_lval); 984 vim_free(redir_lval); 985 redir_lval = NULL; 986 } 987 vim_free(redir_varname); 988 redir_varname = NULL; 989 } 990 991 # if defined(FEAT_MBYTE) || defined(PROTO) 992 int 993 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 994 char_u *enc_from; 995 char_u *enc_to; 996 char_u *fname_from; 997 char_u *fname_to; 998 { 999 int err = FALSE; 1000 1001 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1002 set_vim_var_string(VV_CC_TO, enc_to, -1); 1003 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1004 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1005 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1006 err = TRUE; 1007 set_vim_var_string(VV_CC_FROM, NULL, -1); 1008 set_vim_var_string(VV_CC_TO, NULL, -1); 1009 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1010 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1011 1012 if (err) 1013 return FAIL; 1014 return OK; 1015 } 1016 # endif 1017 1018 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1019 int 1020 eval_printexpr(fname, args) 1021 char_u *fname; 1022 char_u *args; 1023 { 1024 int err = FALSE; 1025 1026 set_vim_var_string(VV_FNAME_IN, fname, -1); 1027 set_vim_var_string(VV_CMDARG, args, -1); 1028 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1029 err = TRUE; 1030 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1031 set_vim_var_string(VV_CMDARG, NULL, -1); 1032 1033 if (err) 1034 { 1035 mch_remove(fname); 1036 return FAIL; 1037 } 1038 return OK; 1039 } 1040 # endif 1041 1042 # if defined(FEAT_DIFF) || defined(PROTO) 1043 void 1044 eval_diff(origfile, newfile, outfile) 1045 char_u *origfile; 1046 char_u *newfile; 1047 char_u *outfile; 1048 { 1049 int err = FALSE; 1050 1051 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1052 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1053 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1054 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1055 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1056 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1057 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1058 } 1059 1060 void 1061 eval_patch(origfile, difffile, outfile) 1062 char_u *origfile; 1063 char_u *difffile; 1064 char_u *outfile; 1065 { 1066 int err; 1067 1068 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1069 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1070 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1071 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1072 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1073 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1074 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1075 } 1076 # endif 1077 1078 /* 1079 * Top level evaluation function, returning a boolean. 1080 * Sets "error" to TRUE if there was an error. 1081 * Return TRUE or FALSE. 1082 */ 1083 int 1084 eval_to_bool(arg, error, nextcmd, skip) 1085 char_u *arg; 1086 int *error; 1087 char_u **nextcmd; 1088 int skip; /* only parse, don't execute */ 1089 { 1090 typval_T tv; 1091 int retval = FALSE; 1092 1093 if (skip) 1094 ++emsg_skip; 1095 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1096 *error = TRUE; 1097 else 1098 { 1099 *error = FALSE; 1100 if (!skip) 1101 { 1102 retval = (get_tv_number_chk(&tv, error) != 0); 1103 clear_tv(&tv); 1104 } 1105 } 1106 if (skip) 1107 --emsg_skip; 1108 1109 return retval; 1110 } 1111 1112 /* 1113 * Top level evaluation function, returning a string. If "skip" is TRUE, 1114 * only parsing to "nextcmd" is done, without reporting errors. Return 1115 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1116 */ 1117 char_u * 1118 eval_to_string_skip(arg, nextcmd, skip) 1119 char_u *arg; 1120 char_u **nextcmd; 1121 int skip; /* only parse, don't execute */ 1122 { 1123 typval_T tv; 1124 char_u *retval; 1125 1126 if (skip) 1127 ++emsg_skip; 1128 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1129 retval = NULL; 1130 else 1131 { 1132 retval = vim_strsave(get_tv_string(&tv)); 1133 clear_tv(&tv); 1134 } 1135 if (skip) 1136 --emsg_skip; 1137 1138 return retval; 1139 } 1140 1141 /* 1142 * Skip over an expression at "*pp". 1143 * Return FAIL for an error, OK otherwise. 1144 */ 1145 int 1146 skip_expr(pp) 1147 char_u **pp; 1148 { 1149 typval_T rettv; 1150 1151 *pp = skipwhite(*pp); 1152 return eval1(pp, &rettv, FALSE); 1153 } 1154 1155 /* 1156 * Top level evaluation function, returning a string. 1157 * Return pointer to allocated memory, or NULL for failure. 1158 */ 1159 char_u * 1160 eval_to_string(arg, nextcmd) 1161 char_u *arg; 1162 char_u **nextcmd; 1163 { 1164 typval_T tv; 1165 char_u *retval; 1166 1167 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1168 retval = NULL; 1169 else 1170 { 1171 retval = vim_strsave(get_tv_string(&tv)); 1172 clear_tv(&tv); 1173 } 1174 1175 return retval; 1176 } 1177 1178 /* 1179 * Call eval_to_string() with "sandbox" set and not using local variables. 1180 */ 1181 char_u * 1182 eval_to_string_safe(arg, nextcmd) 1183 char_u *arg; 1184 char_u **nextcmd; 1185 { 1186 char_u *retval; 1187 void *save_funccalp; 1188 1189 save_funccalp = save_funccal(); 1190 ++sandbox; 1191 retval = eval_to_string(arg, nextcmd); 1192 --sandbox; 1193 restore_funccal(save_funccalp); 1194 return retval; 1195 } 1196 1197 /* 1198 * Top level evaluation function, returning a number. 1199 * Evaluates "expr" silently. 1200 * Returns -1 for an error. 1201 */ 1202 int 1203 eval_to_number(expr) 1204 char_u *expr; 1205 { 1206 typval_T rettv; 1207 int retval; 1208 char_u *p = skipwhite(expr); 1209 1210 ++emsg_off; 1211 1212 if (eval1(&p, &rettv, TRUE) == FAIL) 1213 retval = -1; 1214 else 1215 { 1216 retval = get_tv_number_chk(&rettv, NULL); 1217 clear_tv(&rettv); 1218 } 1219 --emsg_off; 1220 1221 return retval; 1222 } 1223 1224 /* 1225 * Prepare v: variable "idx" to be used. 1226 * Save the current typeval in "save_tv". 1227 * When not used yet add the variable to the v: hashtable. 1228 */ 1229 static void 1230 prepare_vimvar(idx, save_tv) 1231 int idx; 1232 typval_T *save_tv; 1233 { 1234 *save_tv = vimvars[idx].vv_tv; 1235 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1236 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1237 } 1238 1239 /* 1240 * Restore v: variable "idx" to typeval "save_tv". 1241 * When no longer defined, remove the variable from the v: hashtable. 1242 */ 1243 static void 1244 restore_vimvar(idx, save_tv) 1245 int idx; 1246 typval_T *save_tv; 1247 { 1248 hashitem_T *hi; 1249 1250 clear_tv(&vimvars[idx].vv_tv); 1251 vimvars[idx].vv_tv = *save_tv; 1252 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1253 { 1254 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1255 if (HASHITEM_EMPTY(hi)) 1256 EMSG2(_(e_intern2), "restore_vimvar()"); 1257 else 1258 hash_remove(&vimvarht, hi); 1259 } 1260 } 1261 1262 #if defined(FEAT_SYN_HL) || defined(PROTO) 1263 /* 1264 * Evaluate an expression to a list with suggestions. 1265 * For the "expr:" part of 'spellsuggest'. 1266 */ 1267 list_T * 1268 eval_spell_expr(badword, expr) 1269 char_u *badword; 1270 char_u *expr; 1271 { 1272 typval_T save_val; 1273 typval_T rettv; 1274 list_T *list = NULL; 1275 char_u *p = skipwhite(expr); 1276 1277 /* Set "v:val" to the bad word. */ 1278 prepare_vimvar(VV_VAL, &save_val); 1279 vimvars[VV_VAL].vv_type = VAR_STRING; 1280 vimvars[VV_VAL].vv_str = badword; 1281 if (p_verbose == 0) 1282 ++emsg_off; 1283 1284 if (eval1(&p, &rettv, TRUE) == OK) 1285 { 1286 if (rettv.v_type != VAR_LIST) 1287 clear_tv(&rettv); 1288 else 1289 list = rettv.vval.v_list; 1290 } 1291 1292 if (p_verbose == 0) 1293 --emsg_off; 1294 vimvars[VV_VAL].vv_str = NULL; 1295 restore_vimvar(VV_VAL, &save_val); 1296 1297 return list; 1298 } 1299 1300 /* 1301 * "list" is supposed to contain two items: a word and a number. Return the 1302 * word in "pp" and the number as the return value. 1303 * Return -1 if anything isn't right. 1304 * Used to get the good word and score from the eval_spell_expr() result. 1305 */ 1306 int 1307 get_spellword(list, pp) 1308 list_T *list; 1309 char_u **pp; 1310 { 1311 listitem_T *li; 1312 1313 li = list->lv_first; 1314 if (li == NULL) 1315 return -1; 1316 *pp = get_tv_string(&li->li_tv); 1317 1318 li = li->li_next; 1319 if (li == NULL) 1320 return -1; 1321 return get_tv_number(&li->li_tv); 1322 } 1323 #endif 1324 1325 /* 1326 * Top level evaluation function, 1327 */ 1328 typval_T * 1329 eval_expr(arg, nextcmd) 1330 char_u *arg; 1331 char_u **nextcmd; 1332 { 1333 typval_T *tv; 1334 1335 tv = (typval_T *)alloc(sizeof(typval_T)); 1336 if (!tv) 1337 return NULL; 1338 1339 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1340 { 1341 vim_free(tv); 1342 return NULL; 1343 } 1344 1345 return tv; 1346 } 1347 1348 1349 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1350 /* 1351 * Call some vimL function and return the result in "*rettv". 1352 * Uses argv[argc] for the function arguments. 1353 * Returns OK or FAIL. 1354 */ 1355 static int 1356 call_vim_function(func, argc, argv, safe, rettv) 1357 char_u *func; 1358 int argc; 1359 char_u **argv; 1360 int safe; /* use the sandbox */ 1361 typval_T *rettv; 1362 { 1363 typval_T *argvars; 1364 long n; 1365 int len; 1366 int i; 1367 int doesrange; 1368 void *save_funccalp = NULL; 1369 int ret; 1370 1371 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1372 if (argvars == NULL) 1373 return FAIL; 1374 1375 for (i = 0; i < argc; i++) 1376 { 1377 /* Pass a NULL or empty argument as an empty string */ 1378 if (argv[i] == NULL || *argv[i] == NUL) 1379 { 1380 argvars[i].v_type = VAR_STRING; 1381 argvars[i].vval.v_string = (char_u *)""; 1382 continue; 1383 } 1384 1385 /* Recognize a number argument, the others must be strings. */ 1386 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1387 if (len != 0 && len == (int)STRLEN(argv[i])) 1388 { 1389 argvars[i].v_type = VAR_NUMBER; 1390 argvars[i].vval.v_number = n; 1391 } 1392 else 1393 { 1394 argvars[i].v_type = VAR_STRING; 1395 argvars[i].vval.v_string = argv[i]; 1396 } 1397 } 1398 1399 if (safe) 1400 { 1401 save_funccalp = save_funccal(); 1402 ++sandbox; 1403 } 1404 1405 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1406 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1407 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1408 &doesrange, TRUE, NULL); 1409 if (safe) 1410 { 1411 --sandbox; 1412 restore_funccal(save_funccalp); 1413 } 1414 vim_free(argvars); 1415 1416 if (ret == FAIL) 1417 clear_tv(rettv); 1418 1419 return ret; 1420 } 1421 1422 /* 1423 * Call vimL function "func" and return the result as a string. 1424 * Returns NULL when calling the function fails. 1425 * Uses argv[argc] for the function arguments. 1426 */ 1427 void * 1428 call_func_retstr(func, argc, argv, safe) 1429 char_u *func; 1430 int argc; 1431 char_u **argv; 1432 int safe; /* use the sandbox */ 1433 { 1434 typval_T rettv; 1435 char_u *retval; 1436 1437 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1438 return NULL; 1439 1440 retval = vim_strsave(get_tv_string(&rettv)); 1441 clear_tv(&rettv); 1442 return retval; 1443 } 1444 1445 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1446 /* 1447 * Call vimL function "func" and return the result as a number. 1448 * Returns -1 when calling the function fails. 1449 * Uses argv[argc] for the function arguments. 1450 */ 1451 long 1452 call_func_retnr(func, argc, argv, safe) 1453 char_u *func; 1454 int argc; 1455 char_u **argv; 1456 int safe; /* use the sandbox */ 1457 { 1458 typval_T rettv; 1459 long retval; 1460 1461 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1462 return -1; 1463 1464 retval = get_tv_number_chk(&rettv, NULL); 1465 clear_tv(&rettv); 1466 return retval; 1467 } 1468 #endif 1469 1470 /* 1471 * Call vimL function "func" and return the result as a list 1472 * Uses argv[argc] for the function arguments. 1473 */ 1474 void * 1475 call_func_retlist(func, argc, argv, safe) 1476 char_u *func; 1477 int argc; 1478 char_u **argv; 1479 int safe; /* use the sandbox */ 1480 { 1481 typval_T rettv; 1482 1483 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1484 return NULL; 1485 1486 if (rettv.v_type != VAR_LIST) 1487 { 1488 clear_tv(&rettv); 1489 return NULL; 1490 } 1491 1492 return rettv.vval.v_list; 1493 } 1494 1495 #endif 1496 1497 /* 1498 * Save the current function call pointer, and set it to NULL. 1499 * Used when executing autocommands and for ":source". 1500 */ 1501 void * 1502 save_funccal() 1503 { 1504 funccall_T *fc = current_funccal; 1505 1506 current_funccal = NULL; 1507 return (void *)fc; 1508 } 1509 1510 void 1511 restore_funccal(vfc) 1512 void *vfc; 1513 { 1514 funccall_T *fc = (funccall_T *)vfc; 1515 1516 current_funccal = fc; 1517 } 1518 1519 #if defined(FEAT_PROFILE) || defined(PROTO) 1520 /* 1521 * Prepare profiling for entering a child or something else that is not 1522 * counted for the script/function itself. 1523 * Should always be called in pair with prof_child_exit(). 1524 */ 1525 void 1526 prof_child_enter(tm) 1527 proftime_T *tm; /* place to store waittime */ 1528 { 1529 funccall_T *fc = current_funccal; 1530 1531 if (fc != NULL && fc->func->uf_profiling) 1532 profile_start(&fc->prof_child); 1533 script_prof_save(tm); 1534 } 1535 1536 /* 1537 * Take care of time spent in a child. 1538 * Should always be called after prof_child_enter(). 1539 */ 1540 void 1541 prof_child_exit(tm) 1542 proftime_T *tm; /* where waittime was stored */ 1543 { 1544 funccall_T *fc = current_funccal; 1545 1546 if (fc != NULL && fc->func->uf_profiling) 1547 { 1548 profile_end(&fc->prof_child); 1549 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1550 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1551 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1552 } 1553 script_prof_restore(tm); 1554 } 1555 #endif 1556 1557 1558 #ifdef FEAT_FOLDING 1559 /* 1560 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1561 * it in "*cp". Doesn't give error messages. 1562 */ 1563 int 1564 eval_foldexpr(arg, cp) 1565 char_u *arg; 1566 int *cp; 1567 { 1568 typval_T tv; 1569 int retval; 1570 char_u *s; 1571 1572 ++emsg_off; 1573 ++sandbox; 1574 *cp = NUL; 1575 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1576 retval = 0; 1577 else 1578 { 1579 /* If the result is a number, just return the number. */ 1580 if (tv.v_type == VAR_NUMBER) 1581 retval = tv.vval.v_number; 1582 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1583 retval = 0; 1584 else 1585 { 1586 /* If the result is a string, check if there is a non-digit before 1587 * the number. */ 1588 s = tv.vval.v_string; 1589 if (!VIM_ISDIGIT(*s) && *s != '-') 1590 *cp = *s++; 1591 retval = atol((char *)s); 1592 } 1593 clear_tv(&tv); 1594 } 1595 --emsg_off; 1596 --sandbox; 1597 1598 return retval; 1599 } 1600 #endif 1601 1602 /* 1603 * ":let" list all variable values 1604 * ":let var1 var2" list variable values 1605 * ":let var = expr" assignment command. 1606 * ":let var += expr" assignment command. 1607 * ":let var -= expr" assignment command. 1608 * ":let var .= expr" assignment command. 1609 * ":let [var1, var2] = expr" unpack list. 1610 */ 1611 void 1612 ex_let(eap) 1613 exarg_T *eap; 1614 { 1615 char_u *arg = eap->arg; 1616 char_u *expr = NULL; 1617 typval_T rettv; 1618 int i; 1619 int var_count = 0; 1620 int semicolon = 0; 1621 char_u op[2]; 1622 1623 expr = skip_var_list(arg, &var_count, &semicolon); 1624 if (expr == NULL) 1625 return; 1626 expr = vim_strchr(expr, '='); 1627 if (expr == NULL) 1628 { 1629 /* 1630 * ":let" without "=": list variables 1631 */ 1632 if (*arg == '[') 1633 EMSG(_(e_invarg)); 1634 else if (!ends_excmd(*arg)) 1635 /* ":let var1 var2" */ 1636 arg = list_arg_vars(eap, arg); 1637 else if (!eap->skip) 1638 { 1639 /* ":let" */ 1640 list_glob_vars(); 1641 list_buf_vars(); 1642 list_win_vars(); 1643 list_vim_vars(); 1644 } 1645 eap->nextcmd = check_nextcmd(arg); 1646 } 1647 else 1648 { 1649 op[0] = '='; 1650 op[1] = NUL; 1651 if (expr > arg) 1652 { 1653 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1654 op[0] = expr[-1]; /* +=, -= or .= */ 1655 } 1656 expr = skipwhite(expr + 1); 1657 1658 if (eap->skip) 1659 ++emsg_skip; 1660 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1661 if (eap->skip) 1662 { 1663 if (i != FAIL) 1664 clear_tv(&rettv); 1665 --emsg_skip; 1666 } 1667 else if (i != FAIL) 1668 { 1669 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1670 op); 1671 clear_tv(&rettv); 1672 } 1673 } 1674 } 1675 1676 /* 1677 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1678 * Handles both "var" with any type and "[var, var; var]" with a list type. 1679 * When "nextchars" is not NULL it points to a string with characters that 1680 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1681 * or concatenate. 1682 * Returns OK or FAIL; 1683 */ 1684 static int 1685 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1686 char_u *arg_start; 1687 typval_T *tv; 1688 int copy; /* copy values from "tv", don't move */ 1689 int semicolon; /* from skip_var_list() */ 1690 int var_count; /* from skip_var_list() */ 1691 char_u *nextchars; 1692 { 1693 char_u *arg = arg_start; 1694 list_T *l; 1695 int i; 1696 listitem_T *item; 1697 typval_T ltv; 1698 1699 if (*arg != '[') 1700 { 1701 /* 1702 * ":let var = expr" or ":for var in list" 1703 */ 1704 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1705 return FAIL; 1706 return OK; 1707 } 1708 1709 /* 1710 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1711 */ 1712 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1713 { 1714 EMSG(_(e_listreq)); 1715 return FAIL; 1716 } 1717 1718 i = list_len(l); 1719 if (semicolon == 0 && var_count < i) 1720 { 1721 EMSG(_("E687: Less targets than List items")); 1722 return FAIL; 1723 } 1724 if (var_count - semicolon > i) 1725 { 1726 EMSG(_("E688: More targets than List items")); 1727 return FAIL; 1728 } 1729 1730 item = l->lv_first; 1731 while (*arg != ']') 1732 { 1733 arg = skipwhite(arg + 1); 1734 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1735 item = item->li_next; 1736 if (arg == NULL) 1737 return FAIL; 1738 1739 arg = skipwhite(arg); 1740 if (*arg == ';') 1741 { 1742 /* Put the rest of the list (may be empty) in the var after ';'. 1743 * Create a new list for this. */ 1744 l = list_alloc(); 1745 if (l == NULL) 1746 return FAIL; 1747 while (item != NULL) 1748 { 1749 list_append_tv(l, &item->li_tv); 1750 item = item->li_next; 1751 } 1752 1753 ltv.v_type = VAR_LIST; 1754 ltv.v_lock = 0; 1755 ltv.vval.v_list = l; 1756 l->lv_refcount = 1; 1757 1758 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1759 (char_u *)"]", nextchars); 1760 clear_tv(<v); 1761 if (arg == NULL) 1762 return FAIL; 1763 break; 1764 } 1765 else if (*arg != ',' && *arg != ']') 1766 { 1767 EMSG2(_(e_intern2), "ex_let_vars()"); 1768 return FAIL; 1769 } 1770 } 1771 1772 return OK; 1773 } 1774 1775 /* 1776 * Skip over assignable variable "var" or list of variables "[var, var]". 1777 * Used for ":let varvar = expr" and ":for varvar in expr". 1778 * For "[var, var]" increment "*var_count" for each variable. 1779 * for "[var, var; var]" set "semicolon". 1780 * Return NULL for an error. 1781 */ 1782 static char_u * 1783 skip_var_list(arg, var_count, semicolon) 1784 char_u *arg; 1785 int *var_count; 1786 int *semicolon; 1787 { 1788 char_u *p, *s; 1789 1790 if (*arg == '[') 1791 { 1792 /* "[var, var]": find the matching ']'. */ 1793 p = arg; 1794 for (;;) 1795 { 1796 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1797 s = skip_var_one(p); 1798 if (s == p) 1799 { 1800 EMSG2(_(e_invarg2), p); 1801 return NULL; 1802 } 1803 ++*var_count; 1804 1805 p = skipwhite(s); 1806 if (*p == ']') 1807 break; 1808 else if (*p == ';') 1809 { 1810 if (*semicolon == 1) 1811 { 1812 EMSG(_("Double ; in list of variables")); 1813 return NULL; 1814 } 1815 *semicolon = 1; 1816 } 1817 else if (*p != ',') 1818 { 1819 EMSG2(_(e_invarg2), p); 1820 return NULL; 1821 } 1822 } 1823 return p + 1; 1824 } 1825 else 1826 return skip_var_one(arg); 1827 } 1828 1829 /* 1830 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1831 * l[idx]. 1832 */ 1833 static char_u * 1834 skip_var_one(arg) 1835 char_u *arg; 1836 { 1837 if (*arg == '@' && arg[1] != NUL) 1838 return arg + 2; 1839 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1840 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1841 } 1842 1843 /* 1844 * List variables for hashtab "ht" with prefix "prefix". 1845 * If "empty" is TRUE also list NULL strings as empty strings. 1846 */ 1847 static void 1848 list_hashtable_vars(ht, prefix, empty) 1849 hashtab_T *ht; 1850 char_u *prefix; 1851 int empty; 1852 { 1853 hashitem_T *hi; 1854 dictitem_T *di; 1855 int todo; 1856 1857 todo = ht->ht_used; 1858 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1859 { 1860 if (!HASHITEM_EMPTY(hi)) 1861 { 1862 --todo; 1863 di = HI2DI(hi); 1864 if (empty || di->di_tv.v_type != VAR_STRING 1865 || di->di_tv.vval.v_string != NULL) 1866 list_one_var(di, prefix); 1867 } 1868 } 1869 } 1870 1871 /* 1872 * List global variables. 1873 */ 1874 static void 1875 list_glob_vars() 1876 { 1877 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1878 } 1879 1880 /* 1881 * List buffer variables. 1882 */ 1883 static void 1884 list_buf_vars() 1885 { 1886 char_u numbuf[NUMBUFLEN]; 1887 1888 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1889 1890 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1891 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1892 } 1893 1894 /* 1895 * List window variables. 1896 */ 1897 static void 1898 list_win_vars() 1899 { 1900 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1901 } 1902 1903 /* 1904 * List Vim variables. 1905 */ 1906 static void 1907 list_vim_vars() 1908 { 1909 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1910 } 1911 1912 /* 1913 * List variables in "arg". 1914 */ 1915 static char_u * 1916 list_arg_vars(eap, arg) 1917 exarg_T *eap; 1918 char_u *arg; 1919 { 1920 int error = FALSE; 1921 int len; 1922 char_u *name; 1923 char_u *name_start; 1924 char_u *arg_subsc; 1925 char_u *tofree; 1926 typval_T tv; 1927 1928 while (!ends_excmd(*arg) && !got_int) 1929 { 1930 if (error || eap->skip) 1931 { 1932 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1933 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1934 { 1935 emsg_severe = TRUE; 1936 EMSG(_(e_trailing)); 1937 break; 1938 } 1939 } 1940 else 1941 { 1942 /* get_name_len() takes care of expanding curly braces */ 1943 name_start = name = arg; 1944 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1945 if (len <= 0) 1946 { 1947 /* This is mainly to keep test 49 working: when expanding 1948 * curly braces fails overrule the exception error message. */ 1949 if (len < 0 && !aborting()) 1950 { 1951 emsg_severe = TRUE; 1952 EMSG2(_(e_invarg2), arg); 1953 break; 1954 } 1955 error = TRUE; 1956 } 1957 else 1958 { 1959 if (tofree != NULL) 1960 name = tofree; 1961 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1962 error = TRUE; 1963 else 1964 { 1965 /* handle d.key, l[idx], f(expr) */ 1966 arg_subsc = arg; 1967 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1968 error = TRUE; 1969 else 1970 { 1971 if (arg == arg_subsc && len == 2 && name[1] == ':') 1972 { 1973 switch (*name) 1974 { 1975 case 'g': list_glob_vars(); break; 1976 case 'b': list_buf_vars(); break; 1977 case 'w': list_win_vars(); break; 1978 case 'v': list_vim_vars(); break; 1979 default: 1980 EMSG2(_("E738: Can't list variables for %s"), name); 1981 } 1982 } 1983 else 1984 { 1985 char_u numbuf[NUMBUFLEN]; 1986 char_u *tf; 1987 int c; 1988 char_u *s; 1989 1990 s = echo_string(&tv, &tf, numbuf); 1991 c = *arg; 1992 *arg = NUL; 1993 list_one_var_a((char_u *)"", 1994 arg == arg_subsc ? name : name_start, 1995 tv.v_type, s == NULL ? (char_u *)"" : s); 1996 *arg = c; 1997 vim_free(tf); 1998 } 1999 clear_tv(&tv); 2000 } 2001 } 2002 } 2003 2004 vim_free(tofree); 2005 } 2006 2007 arg = skipwhite(arg); 2008 } 2009 2010 return arg; 2011 } 2012 2013 /* 2014 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2015 * Returns a pointer to the char just after the var name. 2016 * Returns NULL if there is an error. 2017 */ 2018 static char_u * 2019 ex_let_one(arg, tv, copy, endchars, op) 2020 char_u *arg; /* points to variable name */ 2021 typval_T *tv; /* value to assign to variable */ 2022 int copy; /* copy value from "tv" */ 2023 char_u *endchars; /* valid chars after variable name or NULL */ 2024 char_u *op; /* "+", "-", "." or NULL*/ 2025 { 2026 int c1; 2027 char_u *name; 2028 char_u *p; 2029 char_u *arg_end = NULL; 2030 int len; 2031 int opt_flags; 2032 char_u *tofree = NULL; 2033 2034 /* 2035 * ":let $VAR = expr": Set environment variable. 2036 */ 2037 if (*arg == '$') 2038 { 2039 /* Find the end of the name. */ 2040 ++arg; 2041 name = arg; 2042 len = get_env_len(&arg); 2043 if (len == 0) 2044 EMSG2(_(e_invarg2), name - 1); 2045 else 2046 { 2047 if (op != NULL && (*op == '+' || *op == '-')) 2048 EMSG2(_(e_letwrong), op); 2049 else if (endchars != NULL 2050 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2051 EMSG(_(e_letunexp)); 2052 else 2053 { 2054 c1 = name[len]; 2055 name[len] = NUL; 2056 p = get_tv_string_chk(tv); 2057 if (p != NULL && op != NULL && *op == '.') 2058 { 2059 int mustfree = FALSE; 2060 char_u *s = vim_getenv(name, &mustfree); 2061 2062 if (s != NULL) 2063 { 2064 p = tofree = concat_str(s, p); 2065 if (mustfree) 2066 vim_free(s); 2067 } 2068 } 2069 if (p != NULL) 2070 { 2071 vim_setenv(name, p); 2072 if (STRICMP(name, "HOME") == 0) 2073 init_homedir(); 2074 else if (didset_vim && STRICMP(name, "VIM") == 0) 2075 didset_vim = FALSE; 2076 else if (didset_vimruntime 2077 && STRICMP(name, "VIMRUNTIME") == 0) 2078 didset_vimruntime = FALSE; 2079 arg_end = arg; 2080 } 2081 name[len] = c1; 2082 vim_free(tofree); 2083 } 2084 } 2085 } 2086 2087 /* 2088 * ":let &option = expr": Set option value. 2089 * ":let &l:option = expr": Set local option value. 2090 * ":let &g:option = expr": Set global option value. 2091 */ 2092 else if (*arg == '&') 2093 { 2094 /* Find the end of the name. */ 2095 p = find_option_end(&arg, &opt_flags); 2096 if (p == NULL || (endchars != NULL 2097 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2098 EMSG(_(e_letunexp)); 2099 else 2100 { 2101 long n; 2102 int opt_type; 2103 long numval; 2104 char_u *stringval = NULL; 2105 char_u *s; 2106 2107 c1 = *p; 2108 *p = NUL; 2109 2110 n = get_tv_number(tv); 2111 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2112 if (s != NULL && op != NULL && *op != '=') 2113 { 2114 opt_type = get_option_value(arg, &numval, 2115 &stringval, opt_flags); 2116 if ((opt_type == 1 && *op == '.') 2117 || (opt_type == 0 && *op != '.')) 2118 EMSG2(_(e_letwrong), op); 2119 else 2120 { 2121 if (opt_type == 1) /* number */ 2122 { 2123 if (*op == '+') 2124 n = numval + n; 2125 else 2126 n = numval - n; 2127 } 2128 else if (opt_type == 0 && stringval != NULL) /* string */ 2129 { 2130 s = concat_str(stringval, s); 2131 vim_free(stringval); 2132 stringval = s; 2133 } 2134 } 2135 } 2136 if (s != NULL) 2137 { 2138 set_option_value(arg, n, s, opt_flags); 2139 arg_end = p; 2140 } 2141 *p = c1; 2142 vim_free(stringval); 2143 } 2144 } 2145 2146 /* 2147 * ":let @r = expr": Set register contents. 2148 */ 2149 else if (*arg == '@') 2150 { 2151 ++arg; 2152 if (op != NULL && (*op == '+' || *op == '-')) 2153 EMSG2(_(e_letwrong), op); 2154 else if (endchars != NULL 2155 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2156 EMSG(_(e_letunexp)); 2157 else 2158 { 2159 char_u *tofree = NULL; 2160 char_u *s; 2161 2162 p = get_tv_string_chk(tv); 2163 if (p != NULL && op != NULL && *op == '.') 2164 { 2165 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2166 if (s != NULL) 2167 { 2168 p = tofree = concat_str(s, p); 2169 vim_free(s); 2170 } 2171 } 2172 if (p != NULL) 2173 { 2174 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2175 arg_end = arg + 1; 2176 } 2177 vim_free(tofree); 2178 } 2179 } 2180 2181 /* 2182 * ":let var = expr": Set internal variable. 2183 * ":let {expr} = expr": Idem, name made with curly braces 2184 */ 2185 else if (eval_isnamec1(*arg) || *arg == '{') 2186 { 2187 lval_T lv; 2188 2189 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2190 if (p != NULL && lv.ll_name != NULL) 2191 { 2192 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2193 EMSG(_(e_letunexp)); 2194 else 2195 { 2196 set_var_lval(&lv, p, tv, copy, op); 2197 arg_end = p; 2198 } 2199 } 2200 clear_lval(&lv); 2201 } 2202 2203 else 2204 EMSG2(_(e_invarg2), arg); 2205 2206 return arg_end; 2207 } 2208 2209 /* 2210 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2211 */ 2212 static int 2213 check_changedtick(arg) 2214 char_u *arg; 2215 { 2216 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2217 { 2218 EMSG2(_(e_readonlyvar), arg); 2219 return TRUE; 2220 } 2221 return FALSE; 2222 } 2223 2224 /* 2225 * Get an lval: variable, Dict item or List item that can be assigned a value 2226 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2227 * "name.key", "name.key[expr]" etc. 2228 * Indexing only works if "name" is an existing List or Dictionary. 2229 * "name" points to the start of the name. 2230 * If "rettv" is not NULL it points to the value to be assigned. 2231 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2232 * wrong; must end in space or cmd separator. 2233 * 2234 * Returns a pointer to just after the name, including indexes. 2235 * When an evaluation error occurs "lp->ll_name" is NULL; 2236 * Returns NULL for a parsing error. Still need to free items in "lp"! 2237 */ 2238 static char_u * 2239 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2240 char_u *name; 2241 typval_T *rettv; 2242 lval_T *lp; 2243 int unlet; 2244 int skip; 2245 int quiet; /* don't give error messages */ 2246 int fne_flags; /* flags for find_name_end() */ 2247 { 2248 char_u *p; 2249 char_u *expr_start, *expr_end; 2250 int cc; 2251 dictitem_T *v; 2252 typval_T var1; 2253 typval_T var2; 2254 int empty1 = FALSE; 2255 listitem_T *ni; 2256 char_u *key = NULL; 2257 int len; 2258 hashtab_T *ht; 2259 2260 /* Clear everything in "lp". */ 2261 vim_memset(lp, 0, sizeof(lval_T)); 2262 2263 if (skip) 2264 { 2265 /* When skipping just find the end of the name. */ 2266 lp->ll_name = name; 2267 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2268 } 2269 2270 /* Find the end of the name. */ 2271 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2272 if (expr_start != NULL) 2273 { 2274 /* Don't expand the name when we already know there is an error. */ 2275 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2276 && *p != '[' && *p != '.') 2277 { 2278 EMSG(_(e_trailing)); 2279 return NULL; 2280 } 2281 2282 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2283 if (lp->ll_exp_name == NULL) 2284 { 2285 /* Report an invalid expression in braces, unless the 2286 * expression evaluation has been cancelled due to an 2287 * aborting error, an interrupt, or an exception. */ 2288 if (!aborting() && !quiet) 2289 { 2290 emsg_severe = TRUE; 2291 EMSG2(_(e_invarg2), name); 2292 return NULL; 2293 } 2294 } 2295 lp->ll_name = lp->ll_exp_name; 2296 } 2297 else 2298 lp->ll_name = name; 2299 2300 /* Without [idx] or .key we are done. */ 2301 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2302 return p; 2303 2304 cc = *p; 2305 *p = NUL; 2306 v = find_var(lp->ll_name, &ht); 2307 if (v == NULL && !quiet) 2308 EMSG2(_(e_undefvar), lp->ll_name); 2309 *p = cc; 2310 if (v == NULL) 2311 return NULL; 2312 2313 /* 2314 * Loop until no more [idx] or .key is following. 2315 */ 2316 lp->ll_tv = &v->di_tv; 2317 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2318 { 2319 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2320 && !(lp->ll_tv->v_type == VAR_DICT 2321 && lp->ll_tv->vval.v_dict != NULL)) 2322 { 2323 if (!quiet) 2324 EMSG(_("E689: Can only index a List or Dictionary")); 2325 return NULL; 2326 } 2327 if (lp->ll_range) 2328 { 2329 if (!quiet) 2330 EMSG(_("E708: [:] must come last")); 2331 return NULL; 2332 } 2333 2334 len = -1; 2335 if (*p == '.') 2336 { 2337 key = p + 1; 2338 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2339 ; 2340 if (len == 0) 2341 { 2342 if (!quiet) 2343 EMSG(_(e_emptykey)); 2344 return NULL; 2345 } 2346 p = key + len; 2347 } 2348 else 2349 { 2350 /* Get the index [expr] or the first index [expr: ]. */ 2351 p = skipwhite(p + 1); 2352 if (*p == ':') 2353 empty1 = TRUE; 2354 else 2355 { 2356 empty1 = FALSE; 2357 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2358 return NULL; 2359 if (get_tv_string_chk(&var1) == NULL) 2360 { 2361 /* not a number or string */ 2362 clear_tv(&var1); 2363 return NULL; 2364 } 2365 } 2366 2367 /* Optionally get the second index [ :expr]. */ 2368 if (*p == ':') 2369 { 2370 if (lp->ll_tv->v_type == VAR_DICT) 2371 { 2372 if (!quiet) 2373 EMSG(_(e_dictrange)); 2374 if (!empty1) 2375 clear_tv(&var1); 2376 return NULL; 2377 } 2378 if (rettv != NULL && (rettv->v_type != VAR_LIST 2379 || rettv->vval.v_list == NULL)) 2380 { 2381 if (!quiet) 2382 EMSG(_("E709: [:] requires a List value")); 2383 if (!empty1) 2384 clear_tv(&var1); 2385 return NULL; 2386 } 2387 p = skipwhite(p + 1); 2388 if (*p == ']') 2389 lp->ll_empty2 = TRUE; 2390 else 2391 { 2392 lp->ll_empty2 = FALSE; 2393 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2394 { 2395 if (!empty1) 2396 clear_tv(&var1); 2397 return NULL; 2398 } 2399 if (get_tv_string_chk(&var2) == NULL) 2400 { 2401 /* not a number or string */ 2402 if (!empty1) 2403 clear_tv(&var1); 2404 clear_tv(&var2); 2405 return NULL; 2406 } 2407 } 2408 lp->ll_range = TRUE; 2409 } 2410 else 2411 lp->ll_range = FALSE; 2412 2413 if (*p != ']') 2414 { 2415 if (!quiet) 2416 EMSG(_(e_missbrac)); 2417 if (!empty1) 2418 clear_tv(&var1); 2419 if (lp->ll_range && !lp->ll_empty2) 2420 clear_tv(&var2); 2421 return NULL; 2422 } 2423 2424 /* Skip to past ']'. */ 2425 ++p; 2426 } 2427 2428 if (lp->ll_tv->v_type == VAR_DICT) 2429 { 2430 if (len == -1) 2431 { 2432 /* "[key]": get key from "var1" */ 2433 key = get_tv_string(&var1); /* is number or string */ 2434 if (*key == NUL) 2435 { 2436 if (!quiet) 2437 EMSG(_(e_emptykey)); 2438 clear_tv(&var1); 2439 return NULL; 2440 } 2441 } 2442 lp->ll_list = NULL; 2443 lp->ll_dict = lp->ll_tv->vval.v_dict; 2444 lp->ll_di = dict_find(lp->ll_dict, key, len); 2445 if (lp->ll_di == NULL) 2446 { 2447 /* Key does not exist in dict: may need to add it. */ 2448 if (*p == '[' || *p == '.' || unlet) 2449 { 2450 if (!quiet) 2451 EMSG2(_(e_dictkey), key); 2452 if (len == -1) 2453 clear_tv(&var1); 2454 return NULL; 2455 } 2456 if (len == -1) 2457 lp->ll_newkey = vim_strsave(key); 2458 else 2459 lp->ll_newkey = vim_strnsave(key, len); 2460 if (len == -1) 2461 clear_tv(&var1); 2462 if (lp->ll_newkey == NULL) 2463 p = NULL; 2464 break; 2465 } 2466 if (len == -1) 2467 clear_tv(&var1); 2468 lp->ll_tv = &lp->ll_di->di_tv; 2469 } 2470 else 2471 { 2472 /* 2473 * Get the number and item for the only or first index of the List. 2474 */ 2475 if (empty1) 2476 lp->ll_n1 = 0; 2477 else 2478 { 2479 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2480 clear_tv(&var1); 2481 } 2482 lp->ll_dict = NULL; 2483 lp->ll_list = lp->ll_tv->vval.v_list; 2484 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2485 if (lp->ll_li == NULL) 2486 { 2487 if (!quiet) 2488 EMSGN(_(e_listidx), lp->ll_n1); 2489 if (lp->ll_range && !lp->ll_empty2) 2490 clear_tv(&var2); 2491 return NULL; 2492 } 2493 2494 /* 2495 * May need to find the item or absolute index for the second 2496 * index of a range. 2497 * When no index given: "lp->ll_empty2" is TRUE. 2498 * Otherwise "lp->ll_n2" is set to the second index. 2499 */ 2500 if (lp->ll_range && !lp->ll_empty2) 2501 { 2502 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2503 clear_tv(&var2); 2504 if (lp->ll_n2 < 0) 2505 { 2506 ni = list_find(lp->ll_list, lp->ll_n2); 2507 if (ni == NULL) 2508 { 2509 if (!quiet) 2510 EMSGN(_(e_listidx), lp->ll_n2); 2511 return NULL; 2512 } 2513 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2514 } 2515 2516 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2517 if (lp->ll_n1 < 0) 2518 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2519 if (lp->ll_n2 < lp->ll_n1) 2520 { 2521 if (!quiet) 2522 EMSGN(_(e_listidx), lp->ll_n2); 2523 return NULL; 2524 } 2525 } 2526 2527 lp->ll_tv = &lp->ll_li->li_tv; 2528 } 2529 } 2530 2531 return p; 2532 } 2533 2534 /* 2535 * Clear lval "lp" that was filled by get_lval(). 2536 */ 2537 static void 2538 clear_lval(lp) 2539 lval_T *lp; 2540 { 2541 vim_free(lp->ll_exp_name); 2542 vim_free(lp->ll_newkey); 2543 } 2544 2545 /* 2546 * Set a variable that was parsed by get_lval() to "rettv". 2547 * "endp" points to just after the parsed name. 2548 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2549 */ 2550 static void 2551 set_var_lval(lp, endp, rettv, copy, op) 2552 lval_T *lp; 2553 char_u *endp; 2554 typval_T *rettv; 2555 int copy; 2556 char_u *op; 2557 { 2558 int cc; 2559 listitem_T *ri; 2560 dictitem_T *di; 2561 2562 if (lp->ll_tv == NULL) 2563 { 2564 if (!check_changedtick(lp->ll_name)) 2565 { 2566 cc = *endp; 2567 *endp = NUL; 2568 if (op != NULL && *op != '=') 2569 { 2570 typval_T tv; 2571 2572 /* handle +=, -= and .= */ 2573 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2574 &tv, TRUE) == OK) 2575 { 2576 if (tv_op(&tv, rettv, op) == OK) 2577 set_var(lp->ll_name, &tv, FALSE); 2578 clear_tv(&tv); 2579 } 2580 } 2581 else 2582 set_var(lp->ll_name, rettv, copy); 2583 *endp = cc; 2584 } 2585 } 2586 else if (tv_check_lock(lp->ll_newkey == NULL 2587 ? lp->ll_tv->v_lock 2588 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2589 ; 2590 else if (lp->ll_range) 2591 { 2592 /* 2593 * Assign the List values to the list items. 2594 */ 2595 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2596 { 2597 if (op != NULL && *op != '=') 2598 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2599 else 2600 { 2601 clear_tv(&lp->ll_li->li_tv); 2602 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2603 } 2604 ri = ri->li_next; 2605 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2606 break; 2607 if (lp->ll_li->li_next == NULL) 2608 { 2609 /* Need to add an empty item. */ 2610 if (list_append_number(lp->ll_list, 0) == FAIL) 2611 { 2612 ri = NULL; 2613 break; 2614 } 2615 } 2616 lp->ll_li = lp->ll_li->li_next; 2617 ++lp->ll_n1; 2618 } 2619 if (ri != NULL) 2620 EMSG(_("E710: List value has more items than target")); 2621 else if (lp->ll_empty2 2622 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2623 : lp->ll_n1 != lp->ll_n2) 2624 EMSG(_("E711: List value has not enough items")); 2625 } 2626 else 2627 { 2628 /* 2629 * Assign to a List or Dictionary item. 2630 */ 2631 if (lp->ll_newkey != NULL) 2632 { 2633 if (op != NULL && *op != '=') 2634 { 2635 EMSG2(_(e_letwrong), op); 2636 return; 2637 } 2638 2639 /* Need to add an item to the Dictionary. */ 2640 di = dictitem_alloc(lp->ll_newkey); 2641 if (di == NULL) 2642 return; 2643 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2644 { 2645 vim_free(di); 2646 return; 2647 } 2648 lp->ll_tv = &di->di_tv; 2649 } 2650 else if (op != NULL && *op != '=') 2651 { 2652 tv_op(lp->ll_tv, rettv, op); 2653 return; 2654 } 2655 else 2656 clear_tv(lp->ll_tv); 2657 2658 /* 2659 * Assign the value to the variable or list item. 2660 */ 2661 if (copy) 2662 copy_tv(rettv, lp->ll_tv); 2663 else 2664 { 2665 *lp->ll_tv = *rettv; 2666 lp->ll_tv->v_lock = 0; 2667 init_tv(rettv); 2668 } 2669 } 2670 } 2671 2672 /* 2673 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2674 * Returns OK or FAIL. 2675 */ 2676 static int 2677 tv_op(tv1, tv2, op) 2678 typval_T *tv1; 2679 typval_T *tv2; 2680 char_u *op; 2681 { 2682 long n; 2683 char_u numbuf[NUMBUFLEN]; 2684 char_u *s; 2685 2686 /* Can't do anything with a Funcref or a Dict on the right. */ 2687 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2688 { 2689 switch (tv1->v_type) 2690 { 2691 case VAR_DICT: 2692 case VAR_FUNC: 2693 break; 2694 2695 case VAR_LIST: 2696 if (*op != '+' || tv2->v_type != VAR_LIST) 2697 break; 2698 /* List += List */ 2699 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2700 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2701 return OK; 2702 2703 case VAR_NUMBER: 2704 case VAR_STRING: 2705 if (tv2->v_type == VAR_LIST) 2706 break; 2707 if (*op == '+' || *op == '-') 2708 { 2709 /* nr += nr or nr -= nr*/ 2710 n = get_tv_number(tv1); 2711 if (*op == '+') 2712 n += get_tv_number(tv2); 2713 else 2714 n -= get_tv_number(tv2); 2715 clear_tv(tv1); 2716 tv1->v_type = VAR_NUMBER; 2717 tv1->vval.v_number = n; 2718 } 2719 else 2720 { 2721 /* str .= str */ 2722 s = get_tv_string(tv1); 2723 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2724 clear_tv(tv1); 2725 tv1->v_type = VAR_STRING; 2726 tv1->vval.v_string = s; 2727 } 2728 return OK; 2729 } 2730 } 2731 2732 EMSG2(_(e_letwrong), op); 2733 return FAIL; 2734 } 2735 2736 /* 2737 * Add a watcher to a list. 2738 */ 2739 static void 2740 list_add_watch(l, lw) 2741 list_T *l; 2742 listwatch_T *lw; 2743 { 2744 lw->lw_next = l->lv_watch; 2745 l->lv_watch = lw; 2746 } 2747 2748 /* 2749 * Remove a watcher from a list. 2750 * No warning when it isn't found... 2751 */ 2752 static void 2753 list_rem_watch(l, lwrem) 2754 list_T *l; 2755 listwatch_T *lwrem; 2756 { 2757 listwatch_T *lw, **lwp; 2758 2759 lwp = &l->lv_watch; 2760 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2761 { 2762 if (lw == lwrem) 2763 { 2764 *lwp = lw->lw_next; 2765 break; 2766 } 2767 lwp = &lw->lw_next; 2768 } 2769 } 2770 2771 /* 2772 * Just before removing an item from a list: advance watchers to the next 2773 * item. 2774 */ 2775 static void 2776 list_fix_watch(l, item) 2777 list_T *l; 2778 listitem_T *item; 2779 { 2780 listwatch_T *lw; 2781 2782 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2783 if (lw->lw_item == item) 2784 lw->lw_item = item->li_next; 2785 } 2786 2787 /* 2788 * Evaluate the expression used in a ":for var in expr" command. 2789 * "arg" points to "var". 2790 * Set "*errp" to TRUE for an error, FALSE otherwise; 2791 * Return a pointer that holds the info. Null when there is an error. 2792 */ 2793 void * 2794 eval_for_line(arg, errp, nextcmdp, skip) 2795 char_u *arg; 2796 int *errp; 2797 char_u **nextcmdp; 2798 int skip; 2799 { 2800 forinfo_T *fi; 2801 char_u *expr; 2802 typval_T tv; 2803 list_T *l; 2804 2805 *errp = TRUE; /* default: there is an error */ 2806 2807 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2808 if (fi == NULL) 2809 return NULL; 2810 2811 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2812 if (expr == NULL) 2813 return fi; 2814 2815 expr = skipwhite(expr); 2816 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2817 { 2818 EMSG(_("E690: Missing \"in\" after :for")); 2819 return fi; 2820 } 2821 2822 if (skip) 2823 ++emsg_skip; 2824 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2825 { 2826 *errp = FALSE; 2827 if (!skip) 2828 { 2829 l = tv.vval.v_list; 2830 if (tv.v_type != VAR_LIST || l == NULL) 2831 { 2832 EMSG(_(e_listreq)); 2833 clear_tv(&tv); 2834 } 2835 else 2836 { 2837 /* No need to increment the refcount, it's already set for the 2838 * list being used in "tv". */ 2839 fi->fi_list = l; 2840 list_add_watch(l, &fi->fi_lw); 2841 fi->fi_lw.lw_item = l->lv_first; 2842 } 2843 } 2844 } 2845 if (skip) 2846 --emsg_skip; 2847 2848 return fi; 2849 } 2850 2851 /* 2852 * Use the first item in a ":for" list. Advance to the next. 2853 * Assign the values to the variable (list). "arg" points to the first one. 2854 * Return TRUE when a valid item was found, FALSE when at end of list or 2855 * something wrong. 2856 */ 2857 int 2858 next_for_item(fi_void, arg) 2859 void *fi_void; 2860 char_u *arg; 2861 { 2862 forinfo_T *fi = (forinfo_T *)fi_void; 2863 int result; 2864 listitem_T *item; 2865 2866 item = fi->fi_lw.lw_item; 2867 if (item == NULL) 2868 result = FALSE; 2869 else 2870 { 2871 fi->fi_lw.lw_item = item->li_next; 2872 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2873 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2874 } 2875 return result; 2876 } 2877 2878 /* 2879 * Free the structure used to store info used by ":for". 2880 */ 2881 void 2882 free_for_info(fi_void) 2883 void *fi_void; 2884 { 2885 forinfo_T *fi = (forinfo_T *)fi_void; 2886 2887 if (fi != NULL && fi->fi_list != NULL) 2888 { 2889 list_rem_watch(fi->fi_list, &fi->fi_lw); 2890 list_unref(fi->fi_list); 2891 } 2892 vim_free(fi); 2893 } 2894 2895 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2896 2897 void 2898 set_context_for_expression(xp, arg, cmdidx) 2899 expand_T *xp; 2900 char_u *arg; 2901 cmdidx_T cmdidx; 2902 { 2903 int got_eq = FALSE; 2904 int c; 2905 char_u *p; 2906 2907 if (cmdidx == CMD_let) 2908 { 2909 xp->xp_context = EXPAND_USER_VARS; 2910 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2911 { 2912 /* ":let var1 var2 ...": find last space. */ 2913 for (p = arg + STRLEN(arg); p >= arg; ) 2914 { 2915 xp->xp_pattern = p; 2916 mb_ptr_back(arg, p); 2917 if (vim_iswhite(*p)) 2918 break; 2919 } 2920 return; 2921 } 2922 } 2923 else 2924 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2925 : EXPAND_EXPRESSION; 2926 while ((xp->xp_pattern = vim_strpbrk(arg, 2927 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2928 { 2929 c = *xp->xp_pattern; 2930 if (c == '&') 2931 { 2932 c = xp->xp_pattern[1]; 2933 if (c == '&') 2934 { 2935 ++xp->xp_pattern; 2936 xp->xp_context = cmdidx != CMD_let || got_eq 2937 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2938 } 2939 else if (c != ' ') 2940 { 2941 xp->xp_context = EXPAND_SETTINGS; 2942 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2943 xp->xp_pattern += 2; 2944 2945 } 2946 } 2947 else if (c == '$') 2948 { 2949 /* environment variable */ 2950 xp->xp_context = EXPAND_ENV_VARS; 2951 } 2952 else if (c == '=') 2953 { 2954 got_eq = TRUE; 2955 xp->xp_context = EXPAND_EXPRESSION; 2956 } 2957 else if (c == '<' 2958 && xp->xp_context == EXPAND_FUNCTIONS 2959 && vim_strchr(xp->xp_pattern, '(') == NULL) 2960 { 2961 /* Function name can start with "<SNR>" */ 2962 break; 2963 } 2964 else if (cmdidx != CMD_let || got_eq) 2965 { 2966 if (c == '"') /* string */ 2967 { 2968 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2969 if (c == '\\' && xp->xp_pattern[1] != NUL) 2970 ++xp->xp_pattern; 2971 xp->xp_context = EXPAND_NOTHING; 2972 } 2973 else if (c == '\'') /* literal string */ 2974 { 2975 /* Trick: '' is like stopping and starting a literal string. */ 2976 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2977 /* skip */ ; 2978 xp->xp_context = EXPAND_NOTHING; 2979 } 2980 else if (c == '|') 2981 { 2982 if (xp->xp_pattern[1] == '|') 2983 { 2984 ++xp->xp_pattern; 2985 xp->xp_context = EXPAND_EXPRESSION; 2986 } 2987 else 2988 xp->xp_context = EXPAND_COMMANDS; 2989 } 2990 else 2991 xp->xp_context = EXPAND_EXPRESSION; 2992 } 2993 else 2994 /* Doesn't look like something valid, expand as an expression 2995 * anyway. */ 2996 xp->xp_context = EXPAND_EXPRESSION; 2997 arg = xp->xp_pattern; 2998 if (*arg != NUL) 2999 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3000 /* skip */ ; 3001 } 3002 xp->xp_pattern = arg; 3003 } 3004 3005 #endif /* FEAT_CMDL_COMPL */ 3006 3007 /* 3008 * ":1,25call func(arg1, arg2)" function call. 3009 */ 3010 void 3011 ex_call(eap) 3012 exarg_T *eap; 3013 { 3014 char_u *arg = eap->arg; 3015 char_u *startarg; 3016 char_u *name; 3017 char_u *tofree; 3018 int len; 3019 typval_T rettv; 3020 linenr_T lnum; 3021 int doesrange; 3022 int failed = FALSE; 3023 funcdict_T fudi; 3024 3025 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3026 vim_free(fudi.fd_newkey); 3027 if (tofree == NULL) 3028 return; 3029 3030 /* Increase refcount on dictionary, it could get deleted when evaluating 3031 * the arguments. */ 3032 if (fudi.fd_dict != NULL) 3033 ++fudi.fd_dict->dv_refcount; 3034 3035 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3036 len = STRLEN(tofree); 3037 name = deref_func_name(tofree, &len); 3038 3039 /* Skip white space to allow ":call func ()". Not good, but required for 3040 * backward compatibility. */ 3041 startarg = skipwhite(arg); 3042 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3043 3044 if (*startarg != '(') 3045 { 3046 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3047 goto end; 3048 } 3049 3050 /* 3051 * When skipping, evaluate the function once, to find the end of the 3052 * arguments. 3053 * When the function takes a range, this is discovered after the first 3054 * call, and the loop is broken. 3055 */ 3056 if (eap->skip) 3057 { 3058 ++emsg_skip; 3059 lnum = eap->line2; /* do it once, also with an invalid range */ 3060 } 3061 else 3062 lnum = eap->line1; 3063 for ( ; lnum <= eap->line2; ++lnum) 3064 { 3065 if (!eap->skip && eap->addr_count > 0) 3066 { 3067 curwin->w_cursor.lnum = lnum; 3068 curwin->w_cursor.col = 0; 3069 } 3070 arg = startarg; 3071 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3072 eap->line1, eap->line2, &doesrange, 3073 !eap->skip, fudi.fd_dict) == FAIL) 3074 { 3075 failed = TRUE; 3076 break; 3077 } 3078 clear_tv(&rettv); 3079 if (doesrange || eap->skip) 3080 break; 3081 /* Stop when immediately aborting on error, or when an interrupt 3082 * occurred or an exception was thrown but not caught. 3083 * get_func_tv() returned OK, so that the check for trailing 3084 * characters below is executed. */ 3085 if (aborting()) 3086 break; 3087 } 3088 if (eap->skip) 3089 --emsg_skip; 3090 3091 if (!failed) 3092 { 3093 /* Check for trailing illegal characters and a following command. */ 3094 if (!ends_excmd(*arg)) 3095 { 3096 emsg_severe = TRUE; 3097 EMSG(_(e_trailing)); 3098 } 3099 else 3100 eap->nextcmd = check_nextcmd(arg); 3101 } 3102 3103 end: 3104 dict_unref(fudi.fd_dict); 3105 vim_free(tofree); 3106 } 3107 3108 /* 3109 * ":unlet[!] var1 ... " command. 3110 */ 3111 void 3112 ex_unlet(eap) 3113 exarg_T *eap; 3114 { 3115 ex_unletlock(eap, eap->arg, 0); 3116 } 3117 3118 /* 3119 * ":lockvar" and ":unlockvar" commands 3120 */ 3121 void 3122 ex_lockvar(eap) 3123 exarg_T *eap; 3124 { 3125 char_u *arg = eap->arg; 3126 int deep = 2; 3127 3128 if (eap->forceit) 3129 deep = -1; 3130 else if (vim_isdigit(*arg)) 3131 { 3132 deep = getdigits(&arg); 3133 arg = skipwhite(arg); 3134 } 3135 3136 ex_unletlock(eap, arg, deep); 3137 } 3138 3139 /* 3140 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3141 */ 3142 static void 3143 ex_unletlock(eap, argstart, deep) 3144 exarg_T *eap; 3145 char_u *argstart; 3146 int deep; 3147 { 3148 char_u *arg = argstart; 3149 char_u *name_end; 3150 int error = FALSE; 3151 lval_T lv; 3152 3153 do 3154 { 3155 /* Parse the name and find the end. */ 3156 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3157 FNE_CHECK_START); 3158 if (lv.ll_name == NULL) 3159 error = TRUE; /* error but continue parsing */ 3160 if (name_end == NULL || (!vim_iswhite(*name_end) 3161 && !ends_excmd(*name_end))) 3162 { 3163 if (name_end != NULL) 3164 { 3165 emsg_severe = TRUE; 3166 EMSG(_(e_trailing)); 3167 } 3168 if (!(eap->skip || error)) 3169 clear_lval(&lv); 3170 break; 3171 } 3172 3173 if (!error && !eap->skip) 3174 { 3175 if (eap->cmdidx == CMD_unlet) 3176 { 3177 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3178 error = TRUE; 3179 } 3180 else 3181 { 3182 if (do_lock_var(&lv, name_end, deep, 3183 eap->cmdidx == CMD_lockvar) == FAIL) 3184 error = TRUE; 3185 } 3186 } 3187 3188 if (!eap->skip) 3189 clear_lval(&lv); 3190 3191 arg = skipwhite(name_end); 3192 } while (!ends_excmd(*arg)); 3193 3194 eap->nextcmd = check_nextcmd(arg); 3195 } 3196 3197 static int 3198 do_unlet_var(lp, name_end, forceit) 3199 lval_T *lp; 3200 char_u *name_end; 3201 int forceit; 3202 { 3203 int ret = OK; 3204 int cc; 3205 3206 if (lp->ll_tv == NULL) 3207 { 3208 cc = *name_end; 3209 *name_end = NUL; 3210 3211 /* Normal name or expanded name. */ 3212 if (check_changedtick(lp->ll_name)) 3213 ret = FAIL; 3214 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3215 ret = FAIL; 3216 *name_end = cc; 3217 } 3218 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3219 return FAIL; 3220 else if (lp->ll_range) 3221 { 3222 listitem_T *li; 3223 3224 /* Delete a range of List items. */ 3225 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3226 { 3227 li = lp->ll_li->li_next; 3228 listitem_remove(lp->ll_list, lp->ll_li); 3229 lp->ll_li = li; 3230 ++lp->ll_n1; 3231 } 3232 } 3233 else 3234 { 3235 if (lp->ll_list != NULL) 3236 /* unlet a List item. */ 3237 listitem_remove(lp->ll_list, lp->ll_li); 3238 else 3239 /* unlet a Dictionary item. */ 3240 dictitem_remove(lp->ll_dict, lp->ll_di); 3241 } 3242 3243 return ret; 3244 } 3245 3246 /* 3247 * "unlet" a variable. Return OK if it existed, FAIL if not. 3248 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3249 */ 3250 int 3251 do_unlet(name, forceit) 3252 char_u *name; 3253 int forceit; 3254 { 3255 hashtab_T *ht; 3256 hashitem_T *hi; 3257 char_u *varname; 3258 3259 ht = find_var_ht(name, &varname); 3260 if (ht != NULL && *varname != NUL) 3261 { 3262 hi = hash_find(ht, varname); 3263 if (!HASHITEM_EMPTY(hi)) 3264 { 3265 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3266 return FAIL; 3267 delete_var(ht, hi); 3268 return OK; 3269 } 3270 } 3271 if (forceit) 3272 return OK; 3273 EMSG2(_("E108: No such variable: \"%s\""), name); 3274 return FAIL; 3275 } 3276 3277 /* 3278 * Lock or unlock variable indicated by "lp". 3279 * "deep" is the levels to go (-1 for unlimited); 3280 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3281 */ 3282 static int 3283 do_lock_var(lp, name_end, deep, lock) 3284 lval_T *lp; 3285 char_u *name_end; 3286 int deep; 3287 int lock; 3288 { 3289 int ret = OK; 3290 int cc; 3291 dictitem_T *di; 3292 3293 if (deep == 0) /* nothing to do */ 3294 return OK; 3295 3296 if (lp->ll_tv == NULL) 3297 { 3298 cc = *name_end; 3299 *name_end = NUL; 3300 3301 /* Normal name or expanded name. */ 3302 if (check_changedtick(lp->ll_name)) 3303 ret = FAIL; 3304 else 3305 { 3306 di = find_var(lp->ll_name, NULL); 3307 if (di == NULL) 3308 ret = FAIL; 3309 else 3310 { 3311 if (lock) 3312 di->di_flags |= DI_FLAGS_LOCK; 3313 else 3314 di->di_flags &= ~DI_FLAGS_LOCK; 3315 item_lock(&di->di_tv, deep, lock); 3316 } 3317 } 3318 *name_end = cc; 3319 } 3320 else if (lp->ll_range) 3321 { 3322 listitem_T *li = lp->ll_li; 3323 3324 /* (un)lock a range of List items. */ 3325 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3326 { 3327 item_lock(&li->li_tv, deep, lock); 3328 li = li->li_next; 3329 ++lp->ll_n1; 3330 } 3331 } 3332 else if (lp->ll_list != NULL) 3333 /* (un)lock a List item. */ 3334 item_lock(&lp->ll_li->li_tv, deep, lock); 3335 else 3336 /* un(lock) a Dictionary item. */ 3337 item_lock(&lp->ll_di->di_tv, deep, lock); 3338 3339 return ret; 3340 } 3341 3342 /* 3343 * Lock or unlock an item. "deep" is nr of levels to go. 3344 */ 3345 static void 3346 item_lock(tv, deep, lock) 3347 typval_T *tv; 3348 int deep; 3349 int lock; 3350 { 3351 static int recurse = 0; 3352 list_T *l; 3353 listitem_T *li; 3354 dict_T *d; 3355 hashitem_T *hi; 3356 int todo; 3357 3358 if (recurse >= DICT_MAXNEST) 3359 { 3360 EMSG(_("E743: variable nested too deep for (un)lock")); 3361 return; 3362 } 3363 if (deep == 0) 3364 return; 3365 ++recurse; 3366 3367 /* lock/unlock the item itself */ 3368 if (lock) 3369 tv->v_lock |= VAR_LOCKED; 3370 else 3371 tv->v_lock &= ~VAR_LOCKED; 3372 3373 switch (tv->v_type) 3374 { 3375 case VAR_LIST: 3376 if ((l = tv->vval.v_list) != NULL) 3377 { 3378 if (lock) 3379 l->lv_lock |= VAR_LOCKED; 3380 else 3381 l->lv_lock &= ~VAR_LOCKED; 3382 if (deep < 0 || deep > 1) 3383 /* recursive: lock/unlock the items the List contains */ 3384 for (li = l->lv_first; li != NULL; li = li->li_next) 3385 item_lock(&li->li_tv, deep - 1, lock); 3386 } 3387 break; 3388 case VAR_DICT: 3389 if ((d = tv->vval.v_dict) != NULL) 3390 { 3391 if (lock) 3392 d->dv_lock |= VAR_LOCKED; 3393 else 3394 d->dv_lock &= ~VAR_LOCKED; 3395 if (deep < 0 || deep > 1) 3396 { 3397 /* recursive: lock/unlock the items the List contains */ 3398 todo = d->dv_hashtab.ht_used; 3399 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3400 { 3401 if (!HASHITEM_EMPTY(hi)) 3402 { 3403 --todo; 3404 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3405 } 3406 } 3407 } 3408 } 3409 } 3410 --recurse; 3411 } 3412 3413 /* 3414 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3415 * it refers to a List or Dictionary that is locked. 3416 */ 3417 static int 3418 tv_islocked(tv) 3419 typval_T *tv; 3420 { 3421 return (tv->v_lock & VAR_LOCKED) 3422 || (tv->v_type == VAR_LIST 3423 && tv->vval.v_list != NULL 3424 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3425 || (tv->v_type == VAR_DICT 3426 && tv->vval.v_dict != NULL 3427 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3428 } 3429 3430 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3431 /* 3432 * Delete all "menutrans_" variables. 3433 */ 3434 void 3435 del_menutrans_vars() 3436 { 3437 hashitem_T *hi; 3438 int todo; 3439 3440 hash_lock(&globvarht); 3441 todo = globvarht.ht_used; 3442 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3443 { 3444 if (!HASHITEM_EMPTY(hi)) 3445 { 3446 --todo; 3447 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3448 delete_var(&globvarht, hi); 3449 } 3450 } 3451 hash_unlock(&globvarht); 3452 } 3453 #endif 3454 3455 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3456 3457 /* 3458 * Local string buffer for the next two functions to store a variable name 3459 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3460 * get_user_var_name(). 3461 */ 3462 3463 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3464 3465 static char_u *varnamebuf = NULL; 3466 static int varnamebuflen = 0; 3467 3468 /* 3469 * Function to concatenate a prefix and a variable name. 3470 */ 3471 static char_u * 3472 cat_prefix_varname(prefix, name) 3473 int prefix; 3474 char_u *name; 3475 { 3476 int len; 3477 3478 len = (int)STRLEN(name) + 3; 3479 if (len > varnamebuflen) 3480 { 3481 vim_free(varnamebuf); 3482 len += 10; /* some additional space */ 3483 varnamebuf = alloc(len); 3484 if (varnamebuf == NULL) 3485 { 3486 varnamebuflen = 0; 3487 return NULL; 3488 } 3489 varnamebuflen = len; 3490 } 3491 *varnamebuf = prefix; 3492 varnamebuf[1] = ':'; 3493 STRCPY(varnamebuf + 2, name); 3494 return varnamebuf; 3495 } 3496 3497 /* 3498 * Function given to ExpandGeneric() to obtain the list of user defined 3499 * (global/buffer/window/built-in) variable names. 3500 */ 3501 /*ARGSUSED*/ 3502 char_u * 3503 get_user_var_name(xp, idx) 3504 expand_T *xp; 3505 int idx; 3506 { 3507 static long_u gdone; 3508 static long_u bdone; 3509 static long_u wdone; 3510 static int vidx; 3511 static hashitem_T *hi; 3512 hashtab_T *ht; 3513 3514 if (idx == 0) 3515 gdone = bdone = wdone = vidx = 0; 3516 3517 /* Global variables */ 3518 if (gdone < globvarht.ht_used) 3519 { 3520 if (gdone++ == 0) 3521 hi = globvarht.ht_array; 3522 else 3523 ++hi; 3524 while (HASHITEM_EMPTY(hi)) 3525 ++hi; 3526 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3527 return cat_prefix_varname('g', hi->hi_key); 3528 return hi->hi_key; 3529 } 3530 3531 /* b: variables */ 3532 ht = &curbuf->b_vars.dv_hashtab; 3533 if (bdone < ht->ht_used) 3534 { 3535 if (bdone++ == 0) 3536 hi = ht->ht_array; 3537 else 3538 ++hi; 3539 while (HASHITEM_EMPTY(hi)) 3540 ++hi; 3541 return cat_prefix_varname('b', hi->hi_key); 3542 } 3543 if (bdone == ht->ht_used) 3544 { 3545 ++bdone; 3546 return (char_u *)"b:changedtick"; 3547 } 3548 3549 /* w: variables */ 3550 ht = &curwin->w_vars.dv_hashtab; 3551 if (wdone < ht->ht_used) 3552 { 3553 if (wdone++ == 0) 3554 hi = ht->ht_array; 3555 else 3556 ++hi; 3557 while (HASHITEM_EMPTY(hi)) 3558 ++hi; 3559 return cat_prefix_varname('w', hi->hi_key); 3560 } 3561 3562 /* v: variables */ 3563 if (vidx < VV_LEN) 3564 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3565 3566 vim_free(varnamebuf); 3567 varnamebuf = NULL; 3568 varnamebuflen = 0; 3569 return NULL; 3570 } 3571 3572 #endif /* FEAT_CMDL_COMPL */ 3573 3574 /* 3575 * types for expressions. 3576 */ 3577 typedef enum 3578 { 3579 TYPE_UNKNOWN = 0 3580 , TYPE_EQUAL /* == */ 3581 , TYPE_NEQUAL /* != */ 3582 , TYPE_GREATER /* > */ 3583 , TYPE_GEQUAL /* >= */ 3584 , TYPE_SMALLER /* < */ 3585 , TYPE_SEQUAL /* <= */ 3586 , TYPE_MATCH /* =~ */ 3587 , TYPE_NOMATCH /* !~ */ 3588 } exptype_T; 3589 3590 /* 3591 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3592 * executed. The function may return OK, but the rettv will be of type 3593 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3594 */ 3595 3596 /* 3597 * Handle zero level expression. 3598 * This calls eval1() and handles error message and nextcmd. 3599 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3600 * Note: "rettv.v_lock" is not set. 3601 * Return OK or FAIL. 3602 */ 3603 static int 3604 eval0(arg, rettv, nextcmd, evaluate) 3605 char_u *arg; 3606 typval_T *rettv; 3607 char_u **nextcmd; 3608 int evaluate; 3609 { 3610 int ret; 3611 char_u *p; 3612 3613 p = skipwhite(arg); 3614 ret = eval1(&p, rettv, evaluate); 3615 if (ret == FAIL || !ends_excmd(*p)) 3616 { 3617 if (ret != FAIL) 3618 clear_tv(rettv); 3619 /* 3620 * Report the invalid expression unless the expression evaluation has 3621 * been cancelled due to an aborting error, an interrupt, or an 3622 * exception. 3623 */ 3624 if (!aborting()) 3625 EMSG2(_(e_invexpr2), arg); 3626 ret = FAIL; 3627 } 3628 if (nextcmd != NULL) 3629 *nextcmd = check_nextcmd(p); 3630 3631 return ret; 3632 } 3633 3634 /* 3635 * Handle top level expression: 3636 * expr1 ? expr0 : expr0 3637 * 3638 * "arg" must point to the first non-white of the expression. 3639 * "arg" is advanced to the next non-white after the recognized expression. 3640 * 3641 * Note: "rettv.v_lock" is not set. 3642 * 3643 * Return OK or FAIL. 3644 */ 3645 static int 3646 eval1(arg, rettv, evaluate) 3647 char_u **arg; 3648 typval_T *rettv; 3649 int evaluate; 3650 { 3651 int result; 3652 typval_T var2; 3653 3654 /* 3655 * Get the first variable. 3656 */ 3657 if (eval2(arg, rettv, evaluate) == FAIL) 3658 return FAIL; 3659 3660 if ((*arg)[0] == '?') 3661 { 3662 result = FALSE; 3663 if (evaluate) 3664 { 3665 int error = FALSE; 3666 3667 if (get_tv_number_chk(rettv, &error) != 0) 3668 result = TRUE; 3669 clear_tv(rettv); 3670 if (error) 3671 return FAIL; 3672 } 3673 3674 /* 3675 * Get the second variable. 3676 */ 3677 *arg = skipwhite(*arg + 1); 3678 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3679 return FAIL; 3680 3681 /* 3682 * Check for the ":". 3683 */ 3684 if ((*arg)[0] != ':') 3685 { 3686 EMSG(_("E109: Missing ':' after '?'")); 3687 if (evaluate && result) 3688 clear_tv(rettv); 3689 return FAIL; 3690 } 3691 3692 /* 3693 * Get the third variable. 3694 */ 3695 *arg = skipwhite(*arg + 1); 3696 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3697 { 3698 if (evaluate && result) 3699 clear_tv(rettv); 3700 return FAIL; 3701 } 3702 if (evaluate && !result) 3703 *rettv = var2; 3704 } 3705 3706 return OK; 3707 } 3708 3709 /* 3710 * Handle first level expression: 3711 * expr2 || expr2 || expr2 logical OR 3712 * 3713 * "arg" must point to the first non-white of the expression. 3714 * "arg" is advanced to the next non-white after the recognized expression. 3715 * 3716 * Return OK or FAIL. 3717 */ 3718 static int 3719 eval2(arg, rettv, evaluate) 3720 char_u **arg; 3721 typval_T *rettv; 3722 int evaluate; 3723 { 3724 typval_T var2; 3725 long result; 3726 int first; 3727 int error = FALSE; 3728 3729 /* 3730 * Get the first variable. 3731 */ 3732 if (eval3(arg, rettv, evaluate) == FAIL) 3733 return FAIL; 3734 3735 /* 3736 * Repeat until there is no following "||". 3737 */ 3738 first = TRUE; 3739 result = FALSE; 3740 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3741 { 3742 if (evaluate && first) 3743 { 3744 if (get_tv_number_chk(rettv, &error) != 0) 3745 result = TRUE; 3746 clear_tv(rettv); 3747 if (error) 3748 return FAIL; 3749 first = FALSE; 3750 } 3751 3752 /* 3753 * Get the second variable. 3754 */ 3755 *arg = skipwhite(*arg + 2); 3756 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3757 return FAIL; 3758 3759 /* 3760 * Compute the result. 3761 */ 3762 if (evaluate && !result) 3763 { 3764 if (get_tv_number_chk(&var2, &error) != 0) 3765 result = TRUE; 3766 clear_tv(&var2); 3767 if (error) 3768 return FAIL; 3769 } 3770 if (evaluate) 3771 { 3772 rettv->v_type = VAR_NUMBER; 3773 rettv->vval.v_number = result; 3774 } 3775 } 3776 3777 return OK; 3778 } 3779 3780 /* 3781 * Handle second level expression: 3782 * expr3 && expr3 && expr3 logical AND 3783 * 3784 * "arg" must point to the first non-white of the expression. 3785 * "arg" is advanced to the next non-white after the recognized expression. 3786 * 3787 * Return OK or FAIL. 3788 */ 3789 static int 3790 eval3(arg, rettv, evaluate) 3791 char_u **arg; 3792 typval_T *rettv; 3793 int evaluate; 3794 { 3795 typval_T var2; 3796 long result; 3797 int first; 3798 int error = FALSE; 3799 3800 /* 3801 * Get the first variable. 3802 */ 3803 if (eval4(arg, rettv, evaluate) == FAIL) 3804 return FAIL; 3805 3806 /* 3807 * Repeat until there is no following "&&". 3808 */ 3809 first = TRUE; 3810 result = TRUE; 3811 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3812 { 3813 if (evaluate && first) 3814 { 3815 if (get_tv_number_chk(rettv, &error) == 0) 3816 result = FALSE; 3817 clear_tv(rettv); 3818 if (error) 3819 return FAIL; 3820 first = FALSE; 3821 } 3822 3823 /* 3824 * Get the second variable. 3825 */ 3826 *arg = skipwhite(*arg + 2); 3827 if (eval4(arg, &var2, evaluate && result) == FAIL) 3828 return FAIL; 3829 3830 /* 3831 * Compute the result. 3832 */ 3833 if (evaluate && result) 3834 { 3835 if (get_tv_number_chk(&var2, &error) == 0) 3836 result = FALSE; 3837 clear_tv(&var2); 3838 if (error) 3839 return FAIL; 3840 } 3841 if (evaluate) 3842 { 3843 rettv->v_type = VAR_NUMBER; 3844 rettv->vval.v_number = result; 3845 } 3846 } 3847 3848 return OK; 3849 } 3850 3851 /* 3852 * Handle third level expression: 3853 * var1 == var2 3854 * var1 =~ var2 3855 * var1 != var2 3856 * var1 !~ var2 3857 * var1 > var2 3858 * var1 >= var2 3859 * var1 < var2 3860 * var1 <= var2 3861 * var1 is var2 3862 * var1 isnot var2 3863 * 3864 * "arg" must point to the first non-white of the expression. 3865 * "arg" is advanced to the next non-white after the recognized expression. 3866 * 3867 * Return OK or FAIL. 3868 */ 3869 static int 3870 eval4(arg, rettv, evaluate) 3871 char_u **arg; 3872 typval_T *rettv; 3873 int evaluate; 3874 { 3875 typval_T var2; 3876 char_u *p; 3877 int i; 3878 exptype_T type = TYPE_UNKNOWN; 3879 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3880 int len = 2; 3881 long n1, n2; 3882 char_u *s1, *s2; 3883 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3884 regmatch_T regmatch; 3885 int ic; 3886 char_u *save_cpo; 3887 3888 /* 3889 * Get the first variable. 3890 */ 3891 if (eval5(arg, rettv, evaluate) == FAIL) 3892 return FAIL; 3893 3894 p = *arg; 3895 switch (p[0]) 3896 { 3897 case '=': if (p[1] == '=') 3898 type = TYPE_EQUAL; 3899 else if (p[1] == '~') 3900 type = TYPE_MATCH; 3901 break; 3902 case '!': if (p[1] == '=') 3903 type = TYPE_NEQUAL; 3904 else if (p[1] == '~') 3905 type = TYPE_NOMATCH; 3906 break; 3907 case '>': if (p[1] != '=') 3908 { 3909 type = TYPE_GREATER; 3910 len = 1; 3911 } 3912 else 3913 type = TYPE_GEQUAL; 3914 break; 3915 case '<': if (p[1] != '=') 3916 { 3917 type = TYPE_SMALLER; 3918 len = 1; 3919 } 3920 else 3921 type = TYPE_SEQUAL; 3922 break; 3923 case 'i': if (p[1] == 's') 3924 { 3925 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3926 len = 5; 3927 if (!vim_isIDc(p[len])) 3928 { 3929 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3930 type_is = TRUE; 3931 } 3932 } 3933 break; 3934 } 3935 3936 /* 3937 * If there is a comparitive operator, use it. 3938 */ 3939 if (type != TYPE_UNKNOWN) 3940 { 3941 /* extra question mark appended: ignore case */ 3942 if (p[len] == '?') 3943 { 3944 ic = TRUE; 3945 ++len; 3946 } 3947 /* extra '#' appended: match case */ 3948 else if (p[len] == '#') 3949 { 3950 ic = FALSE; 3951 ++len; 3952 } 3953 /* nothing appened: use 'ignorecase' */ 3954 else 3955 ic = p_ic; 3956 3957 /* 3958 * Get the second variable. 3959 */ 3960 *arg = skipwhite(p + len); 3961 if (eval5(arg, &var2, evaluate) == FAIL) 3962 { 3963 clear_tv(rettv); 3964 return FAIL; 3965 } 3966 3967 if (evaluate) 3968 { 3969 if (type_is && rettv->v_type != var2.v_type) 3970 { 3971 /* For "is" a different type always means FALSE, for "notis" 3972 * it means TRUE. */ 3973 n1 = (type == TYPE_NEQUAL); 3974 } 3975 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3976 { 3977 if (type_is) 3978 { 3979 n1 = (rettv->v_type == var2.v_type 3980 && rettv->vval.v_list == var2.vval.v_list); 3981 if (type == TYPE_NEQUAL) 3982 n1 = !n1; 3983 } 3984 else if (rettv->v_type != var2.v_type 3985 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3986 { 3987 if (rettv->v_type != var2.v_type) 3988 EMSG(_("E691: Can only compare List with List")); 3989 else 3990 EMSG(_("E692: Invalid operation for Lists")); 3991 clear_tv(rettv); 3992 clear_tv(&var2); 3993 return FAIL; 3994 } 3995 else 3996 { 3997 /* Compare two Lists for being equal or unequal. */ 3998 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3999 if (type == TYPE_NEQUAL) 4000 n1 = !n1; 4001 } 4002 } 4003 4004 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4005 { 4006 if (type_is) 4007 { 4008 n1 = (rettv->v_type == var2.v_type 4009 && rettv->vval.v_dict == var2.vval.v_dict); 4010 if (type == TYPE_NEQUAL) 4011 n1 = !n1; 4012 } 4013 else if (rettv->v_type != var2.v_type 4014 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4015 { 4016 if (rettv->v_type != var2.v_type) 4017 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4018 else 4019 EMSG(_("E736: Invalid operation for Dictionary")); 4020 clear_tv(rettv); 4021 clear_tv(&var2); 4022 return FAIL; 4023 } 4024 else 4025 { 4026 /* Compare two Dictionaries for being equal or unequal. */ 4027 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4028 if (type == TYPE_NEQUAL) 4029 n1 = !n1; 4030 } 4031 } 4032 4033 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4034 { 4035 if (rettv->v_type != var2.v_type 4036 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4037 { 4038 if (rettv->v_type != var2.v_type) 4039 EMSG(_("E693: Can only compare Funcref with Funcref")); 4040 else 4041 EMSG(_("E694: Invalid operation for Funcrefs")); 4042 clear_tv(rettv); 4043 clear_tv(&var2); 4044 return FAIL; 4045 } 4046 else 4047 { 4048 /* Compare two Funcrefs for being equal or unequal. */ 4049 if (rettv->vval.v_string == NULL 4050 || var2.vval.v_string == NULL) 4051 n1 = FALSE; 4052 else 4053 n1 = STRCMP(rettv->vval.v_string, 4054 var2.vval.v_string) == 0; 4055 if (type == TYPE_NEQUAL) 4056 n1 = !n1; 4057 } 4058 } 4059 4060 /* 4061 * If one of the two variables is a number, compare as a number. 4062 * When using "=~" or "!~", always compare as string. 4063 */ 4064 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4065 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4066 { 4067 n1 = get_tv_number(rettv); 4068 n2 = get_tv_number(&var2); 4069 switch (type) 4070 { 4071 case TYPE_EQUAL: n1 = (n1 == n2); break; 4072 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4073 case TYPE_GREATER: n1 = (n1 > n2); break; 4074 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4075 case TYPE_SMALLER: n1 = (n1 < n2); break; 4076 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4077 case TYPE_UNKNOWN: 4078 case TYPE_MATCH: 4079 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4080 } 4081 } 4082 else 4083 { 4084 s1 = get_tv_string_buf(rettv, buf1); 4085 s2 = get_tv_string_buf(&var2, buf2); 4086 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4087 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4088 else 4089 i = 0; 4090 n1 = FALSE; 4091 switch (type) 4092 { 4093 case TYPE_EQUAL: n1 = (i == 0); break; 4094 case TYPE_NEQUAL: n1 = (i != 0); break; 4095 case TYPE_GREATER: n1 = (i > 0); break; 4096 case TYPE_GEQUAL: n1 = (i >= 0); break; 4097 case TYPE_SMALLER: n1 = (i < 0); break; 4098 case TYPE_SEQUAL: n1 = (i <= 0); break; 4099 4100 case TYPE_MATCH: 4101 case TYPE_NOMATCH: 4102 /* avoid 'l' flag in 'cpoptions' */ 4103 save_cpo = p_cpo; 4104 p_cpo = (char_u *)""; 4105 regmatch.regprog = vim_regcomp(s2, 4106 RE_MAGIC + RE_STRING); 4107 regmatch.rm_ic = ic; 4108 if (regmatch.regprog != NULL) 4109 { 4110 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4111 vim_free(regmatch.regprog); 4112 if (type == TYPE_NOMATCH) 4113 n1 = !n1; 4114 } 4115 p_cpo = save_cpo; 4116 break; 4117 4118 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4119 } 4120 } 4121 clear_tv(rettv); 4122 clear_tv(&var2); 4123 rettv->v_type = VAR_NUMBER; 4124 rettv->vval.v_number = n1; 4125 } 4126 } 4127 4128 return OK; 4129 } 4130 4131 /* 4132 * Handle fourth level expression: 4133 * + number addition 4134 * - number subtraction 4135 * . string concatenation 4136 * 4137 * "arg" must point to the first non-white of the expression. 4138 * "arg" is advanced to the next non-white after the recognized expression. 4139 * 4140 * Return OK or FAIL. 4141 */ 4142 static int 4143 eval5(arg, rettv, evaluate) 4144 char_u **arg; 4145 typval_T *rettv; 4146 int evaluate; 4147 { 4148 typval_T var2; 4149 typval_T var3; 4150 int op; 4151 long n1, n2; 4152 char_u *s1, *s2; 4153 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4154 char_u *p; 4155 4156 /* 4157 * Get the first variable. 4158 */ 4159 if (eval6(arg, rettv, evaluate) == FAIL) 4160 return FAIL; 4161 4162 /* 4163 * Repeat computing, until no '+', '-' or '.' is following. 4164 */ 4165 for (;;) 4166 { 4167 op = **arg; 4168 if (op != '+' && op != '-' && op != '.') 4169 break; 4170 4171 if (op != '+' || rettv->v_type != VAR_LIST) 4172 { 4173 /* For "list + ...", an illegal use of the first operand as 4174 * a number cannot be determined before evaluating the 2nd 4175 * operand: if this is also a list, all is ok. 4176 * For "something . ...", "something - ..." or "non-list + ...", 4177 * we know that the first operand needs to be a string or number 4178 * without evaluating the 2nd operand. So check before to avoid 4179 * side effects after an error. */ 4180 if (evaluate && get_tv_string_chk(rettv) == NULL) 4181 { 4182 clear_tv(rettv); 4183 return FAIL; 4184 } 4185 } 4186 4187 /* 4188 * Get the second variable. 4189 */ 4190 *arg = skipwhite(*arg + 1); 4191 if (eval6(arg, &var2, evaluate) == FAIL) 4192 { 4193 clear_tv(rettv); 4194 return FAIL; 4195 } 4196 4197 if (evaluate) 4198 { 4199 /* 4200 * Compute the result. 4201 */ 4202 if (op == '.') 4203 { 4204 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4205 s2 = get_tv_string_buf_chk(&var2, buf2); 4206 if (s2 == NULL) /* type error ? */ 4207 { 4208 clear_tv(rettv); 4209 clear_tv(&var2); 4210 return FAIL; 4211 } 4212 p = concat_str(s1, s2); 4213 clear_tv(rettv); 4214 rettv->v_type = VAR_STRING; 4215 rettv->vval.v_string = p; 4216 } 4217 else if (op == '+' && rettv->v_type == VAR_LIST 4218 && var2.v_type == VAR_LIST) 4219 { 4220 /* concatenate Lists */ 4221 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4222 &var3) == FAIL) 4223 { 4224 clear_tv(rettv); 4225 clear_tv(&var2); 4226 return FAIL; 4227 } 4228 clear_tv(rettv); 4229 *rettv = var3; 4230 } 4231 else 4232 { 4233 int error = FALSE; 4234 4235 n1 = get_tv_number_chk(rettv, &error); 4236 if (error) 4237 { 4238 /* This can only happen for "list + non-list". 4239 * For "non-list + ..." or "something - ...", we returned 4240 * before evaluating the 2nd operand. */ 4241 clear_tv(rettv); 4242 return FAIL; 4243 } 4244 n2 = get_tv_number_chk(&var2, &error); 4245 if (error) 4246 { 4247 clear_tv(rettv); 4248 clear_tv(&var2); 4249 return FAIL; 4250 } 4251 clear_tv(rettv); 4252 if (op == '+') 4253 n1 = n1 + n2; 4254 else 4255 n1 = n1 - n2; 4256 rettv->v_type = VAR_NUMBER; 4257 rettv->vval.v_number = n1; 4258 } 4259 clear_tv(&var2); 4260 } 4261 } 4262 return OK; 4263 } 4264 4265 /* 4266 * Handle fifth level expression: 4267 * * number multiplication 4268 * / number division 4269 * % number modulo 4270 * 4271 * "arg" must point to the first non-white of the expression. 4272 * "arg" is advanced to the next non-white after the recognized expression. 4273 * 4274 * Return OK or FAIL. 4275 */ 4276 static int 4277 eval6(arg, rettv, evaluate) 4278 char_u **arg; 4279 typval_T *rettv; 4280 int evaluate; 4281 { 4282 typval_T var2; 4283 int op; 4284 long n1, n2; 4285 int error = FALSE; 4286 4287 /* 4288 * Get the first variable. 4289 */ 4290 if (eval7(arg, rettv, evaluate) == FAIL) 4291 return FAIL; 4292 4293 /* 4294 * Repeat computing, until no '*', '/' or '%' is following. 4295 */ 4296 for (;;) 4297 { 4298 op = **arg; 4299 if (op != '*' && op != '/' && op != '%') 4300 break; 4301 4302 if (evaluate) 4303 { 4304 n1 = get_tv_number_chk(rettv, &error); 4305 clear_tv(rettv); 4306 if (error) 4307 return FAIL; 4308 } 4309 else 4310 n1 = 0; 4311 4312 /* 4313 * Get the second variable. 4314 */ 4315 *arg = skipwhite(*arg + 1); 4316 if (eval7(arg, &var2, evaluate) == FAIL) 4317 return FAIL; 4318 4319 if (evaluate) 4320 { 4321 n2 = get_tv_number_chk(&var2, &error); 4322 clear_tv(&var2); 4323 if (error) 4324 return FAIL; 4325 4326 /* 4327 * Compute the result. 4328 */ 4329 if (op == '*') 4330 n1 = n1 * n2; 4331 else if (op == '/') 4332 { 4333 if (n2 == 0) /* give an error message? */ 4334 n1 = 0x7fffffffL; 4335 else 4336 n1 = n1 / n2; 4337 } 4338 else 4339 { 4340 if (n2 == 0) /* give an error message? */ 4341 n1 = 0; 4342 else 4343 n1 = n1 % n2; 4344 } 4345 rettv->v_type = VAR_NUMBER; 4346 rettv->vval.v_number = n1; 4347 } 4348 } 4349 4350 return OK; 4351 } 4352 4353 /* 4354 * Handle sixth level expression: 4355 * number number constant 4356 * "string" string contstant 4357 * 'string' literal string contstant 4358 * &option-name option value 4359 * @r register contents 4360 * identifier variable value 4361 * function() function call 4362 * $VAR environment variable 4363 * (expression) nested expression 4364 * [expr, expr] List 4365 * {key: val, key: val} Dictionary 4366 * 4367 * Also handle: 4368 * ! in front logical NOT 4369 * - in front unary minus 4370 * + in front unary plus (ignored) 4371 * trailing [] subscript in String or List 4372 * trailing .name entry in Dictionary 4373 * 4374 * "arg" must point to the first non-white of the expression. 4375 * "arg" is advanced to the next non-white after the recognized expression. 4376 * 4377 * Return OK or FAIL. 4378 */ 4379 static int 4380 eval7(arg, rettv, evaluate) 4381 char_u **arg; 4382 typval_T *rettv; 4383 int evaluate; 4384 { 4385 long n; 4386 int len; 4387 char_u *s; 4388 int val; 4389 char_u *start_leader, *end_leader; 4390 int ret = OK; 4391 char_u *alias; 4392 4393 /* 4394 * Initialise variable so that clear_tv() can't mistake this for a 4395 * string and free a string that isn't there. 4396 */ 4397 rettv->v_type = VAR_UNKNOWN; 4398 4399 /* 4400 * Skip '!' and '-' characters. They are handled later. 4401 */ 4402 start_leader = *arg; 4403 while (**arg == '!' || **arg == '-' || **arg == '+') 4404 *arg = skipwhite(*arg + 1); 4405 end_leader = *arg; 4406 4407 switch (**arg) 4408 { 4409 /* 4410 * Number constant. 4411 */ 4412 case '0': 4413 case '1': 4414 case '2': 4415 case '3': 4416 case '4': 4417 case '5': 4418 case '6': 4419 case '7': 4420 case '8': 4421 case '9': 4422 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4423 *arg += len; 4424 if (evaluate) 4425 { 4426 rettv->v_type = VAR_NUMBER; 4427 rettv->vval.v_number = n; 4428 } 4429 break; 4430 4431 /* 4432 * String constant: "string". 4433 */ 4434 case '"': ret = get_string_tv(arg, rettv, evaluate); 4435 break; 4436 4437 /* 4438 * Literal string constant: 'str''ing'. 4439 */ 4440 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4441 break; 4442 4443 /* 4444 * List: [expr, expr] 4445 */ 4446 case '[': ret = get_list_tv(arg, rettv, evaluate); 4447 break; 4448 4449 /* 4450 * Dictionary: {key: val, key: val} 4451 */ 4452 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4453 break; 4454 4455 /* 4456 * Option value: &name 4457 */ 4458 case '&': ret = get_option_tv(arg, rettv, evaluate); 4459 break; 4460 4461 /* 4462 * Environment variable: $VAR. 4463 */ 4464 case '$': ret = get_env_tv(arg, rettv, evaluate); 4465 break; 4466 4467 /* 4468 * Register contents: @r. 4469 */ 4470 case '@': ++*arg; 4471 if (evaluate) 4472 { 4473 rettv->v_type = VAR_STRING; 4474 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4475 } 4476 if (**arg != NUL) 4477 ++*arg; 4478 break; 4479 4480 /* 4481 * nested expression: (expression). 4482 */ 4483 case '(': *arg = skipwhite(*arg + 1); 4484 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4485 if (**arg == ')') 4486 ++*arg; 4487 else if (ret == OK) 4488 { 4489 EMSG(_("E110: Missing ')'")); 4490 clear_tv(rettv); 4491 ret = FAIL; 4492 } 4493 break; 4494 4495 default: ret = NOTDONE; 4496 break; 4497 } 4498 4499 if (ret == NOTDONE) 4500 { 4501 /* 4502 * Must be a variable or function name. 4503 * Can also be a curly-braces kind of name: {expr}. 4504 */ 4505 s = *arg; 4506 len = get_name_len(arg, &alias, evaluate, TRUE); 4507 if (alias != NULL) 4508 s = alias; 4509 4510 if (len <= 0) 4511 ret = FAIL; 4512 else 4513 { 4514 if (**arg == '(') /* recursive! */ 4515 { 4516 /* If "s" is the name of a variable of type VAR_FUNC 4517 * use its contents. */ 4518 s = deref_func_name(s, &len); 4519 4520 /* Invoke the function. */ 4521 ret = get_func_tv(s, len, rettv, arg, 4522 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4523 &len, evaluate, NULL); 4524 /* Stop the expression evaluation when immediately 4525 * aborting on error, or when an interrupt occurred or 4526 * an exception was thrown but not caught. */ 4527 if (aborting()) 4528 { 4529 if (ret == OK) 4530 clear_tv(rettv); 4531 ret = FAIL; 4532 } 4533 } 4534 else if (evaluate) 4535 ret = get_var_tv(s, len, rettv, TRUE); 4536 else 4537 ret = OK; 4538 } 4539 4540 if (alias != NULL) 4541 vim_free(alias); 4542 } 4543 4544 *arg = skipwhite(*arg); 4545 4546 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4547 * expr(expr). */ 4548 if (ret == OK) 4549 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4550 4551 /* 4552 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4553 */ 4554 if (ret == OK && evaluate && end_leader > start_leader) 4555 { 4556 int error = FALSE; 4557 4558 val = get_tv_number_chk(rettv, &error); 4559 if (error) 4560 { 4561 clear_tv(rettv); 4562 ret = FAIL; 4563 } 4564 else 4565 { 4566 while (end_leader > start_leader) 4567 { 4568 --end_leader; 4569 if (*end_leader == '!') 4570 val = !val; 4571 else if (*end_leader == '-') 4572 val = -val; 4573 } 4574 clear_tv(rettv); 4575 rettv->v_type = VAR_NUMBER; 4576 rettv->vval.v_number = val; 4577 } 4578 } 4579 4580 return ret; 4581 } 4582 4583 /* 4584 * Evaluate an "[expr]" or "[expr:expr]" index. 4585 * "*arg" points to the '['. 4586 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4587 */ 4588 static int 4589 eval_index(arg, rettv, evaluate, verbose) 4590 char_u **arg; 4591 typval_T *rettv; 4592 int evaluate; 4593 int verbose; /* give error messages */ 4594 { 4595 int empty1 = FALSE, empty2 = FALSE; 4596 typval_T var1, var2; 4597 long n1, n2 = 0; 4598 long len = -1; 4599 int range = FALSE; 4600 char_u *s; 4601 char_u *key = NULL; 4602 4603 if (rettv->v_type == VAR_FUNC) 4604 { 4605 if (verbose) 4606 EMSG(_("E695: Cannot index a Funcref")); 4607 return FAIL; 4608 } 4609 4610 if (**arg == '.') 4611 { 4612 /* 4613 * dict.name 4614 */ 4615 key = *arg + 1; 4616 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4617 ; 4618 if (len == 0) 4619 return FAIL; 4620 *arg = skipwhite(key + len); 4621 } 4622 else 4623 { 4624 /* 4625 * something[idx] 4626 * 4627 * Get the (first) variable from inside the []. 4628 */ 4629 *arg = skipwhite(*arg + 1); 4630 if (**arg == ':') 4631 empty1 = TRUE; 4632 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4633 return FAIL; 4634 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4635 { 4636 /* not a number or string */ 4637 clear_tv(&var1); 4638 return FAIL; 4639 } 4640 4641 /* 4642 * Get the second variable from inside the [:]. 4643 */ 4644 if (**arg == ':') 4645 { 4646 range = TRUE; 4647 *arg = skipwhite(*arg + 1); 4648 if (**arg == ']') 4649 empty2 = TRUE; 4650 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4651 { 4652 if (!empty1) 4653 clear_tv(&var1); 4654 return FAIL; 4655 } 4656 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4657 { 4658 /* not a number or string */ 4659 if (!empty1) 4660 clear_tv(&var1); 4661 clear_tv(&var2); 4662 return FAIL; 4663 } 4664 } 4665 4666 /* Check for the ']'. */ 4667 if (**arg != ']') 4668 { 4669 if (verbose) 4670 EMSG(_(e_missbrac)); 4671 clear_tv(&var1); 4672 if (range) 4673 clear_tv(&var2); 4674 return FAIL; 4675 } 4676 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4677 } 4678 4679 if (evaluate) 4680 { 4681 n1 = 0; 4682 if (!empty1 && rettv->v_type != VAR_DICT) 4683 { 4684 n1 = get_tv_number(&var1); 4685 clear_tv(&var1); 4686 } 4687 if (range) 4688 { 4689 if (empty2) 4690 n2 = -1; 4691 else 4692 { 4693 n2 = get_tv_number(&var2); 4694 clear_tv(&var2); 4695 } 4696 } 4697 4698 switch (rettv->v_type) 4699 { 4700 case VAR_NUMBER: 4701 case VAR_STRING: 4702 s = get_tv_string(rettv); 4703 len = (long)STRLEN(s); 4704 if (range) 4705 { 4706 /* The resulting variable is a substring. If the indexes 4707 * are out of range the result is empty. */ 4708 if (n1 < 0) 4709 { 4710 n1 = len + n1; 4711 if (n1 < 0) 4712 n1 = 0; 4713 } 4714 if (n2 < 0) 4715 n2 = len + n2; 4716 else if (n2 >= len) 4717 n2 = len; 4718 if (n1 >= len || n2 < 0 || n1 > n2) 4719 s = NULL; 4720 else 4721 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4722 } 4723 else 4724 { 4725 /* The resulting variable is a string of a single 4726 * character. If the index is too big or negative the 4727 * result is empty. */ 4728 if (n1 >= len || n1 < 0) 4729 s = NULL; 4730 else 4731 s = vim_strnsave(s + n1, 1); 4732 } 4733 clear_tv(rettv); 4734 rettv->v_type = VAR_STRING; 4735 rettv->vval.v_string = s; 4736 break; 4737 4738 case VAR_LIST: 4739 len = list_len(rettv->vval.v_list); 4740 if (n1 < 0) 4741 n1 = len + n1; 4742 if (!empty1 && (n1 < 0 || n1 >= len)) 4743 { 4744 if (verbose) 4745 EMSGN(_(e_listidx), n1); 4746 return FAIL; 4747 } 4748 if (range) 4749 { 4750 list_T *l; 4751 listitem_T *item; 4752 4753 if (n2 < 0) 4754 n2 = len + n2; 4755 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4756 { 4757 if (verbose) 4758 EMSGN(_(e_listidx), n2); 4759 return FAIL; 4760 } 4761 l = list_alloc(); 4762 if (l == NULL) 4763 return FAIL; 4764 for (item = list_find(rettv->vval.v_list, n1); 4765 n1 <= n2; ++n1) 4766 { 4767 if (list_append_tv(l, &item->li_tv) == FAIL) 4768 { 4769 list_free(l); 4770 return FAIL; 4771 } 4772 item = item->li_next; 4773 } 4774 clear_tv(rettv); 4775 rettv->v_type = VAR_LIST; 4776 rettv->vval.v_list = l; 4777 ++l->lv_refcount; 4778 } 4779 else 4780 { 4781 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4782 &var1); 4783 clear_tv(rettv); 4784 *rettv = var1; 4785 } 4786 break; 4787 4788 case VAR_DICT: 4789 if (range) 4790 { 4791 if (verbose) 4792 EMSG(_(e_dictrange)); 4793 if (len == -1) 4794 clear_tv(&var1); 4795 return FAIL; 4796 } 4797 { 4798 dictitem_T *item; 4799 4800 if (len == -1) 4801 { 4802 key = get_tv_string(&var1); 4803 if (*key == NUL) 4804 { 4805 if (verbose) 4806 EMSG(_(e_emptykey)); 4807 clear_tv(&var1); 4808 return FAIL; 4809 } 4810 } 4811 4812 item = dict_find(rettv->vval.v_dict, key, (int)len); 4813 4814 if (item == NULL && verbose) 4815 EMSG2(_(e_dictkey), key); 4816 if (len == -1) 4817 clear_tv(&var1); 4818 if (item == NULL) 4819 return FAIL; 4820 4821 copy_tv(&item->di_tv, &var1); 4822 clear_tv(rettv); 4823 *rettv = var1; 4824 } 4825 break; 4826 } 4827 } 4828 4829 return OK; 4830 } 4831 4832 /* 4833 * Get an option value. 4834 * "arg" points to the '&' or '+' before the option name. 4835 * "arg" is advanced to character after the option name. 4836 * Return OK or FAIL. 4837 */ 4838 static int 4839 get_option_tv(arg, rettv, evaluate) 4840 char_u **arg; 4841 typval_T *rettv; /* when NULL, only check if option exists */ 4842 int evaluate; 4843 { 4844 char_u *option_end; 4845 long numval; 4846 char_u *stringval; 4847 int opt_type; 4848 int c; 4849 int working = (**arg == '+'); /* has("+option") */ 4850 int ret = OK; 4851 int opt_flags; 4852 4853 /* 4854 * Isolate the option name and find its value. 4855 */ 4856 option_end = find_option_end(arg, &opt_flags); 4857 if (option_end == NULL) 4858 { 4859 if (rettv != NULL) 4860 EMSG2(_("E112: Option name missing: %s"), *arg); 4861 return FAIL; 4862 } 4863 4864 if (!evaluate) 4865 { 4866 *arg = option_end; 4867 return OK; 4868 } 4869 4870 c = *option_end; 4871 *option_end = NUL; 4872 opt_type = get_option_value(*arg, &numval, 4873 rettv == NULL ? NULL : &stringval, opt_flags); 4874 4875 if (opt_type == -3) /* invalid name */ 4876 { 4877 if (rettv != NULL) 4878 EMSG2(_("E113: Unknown option: %s"), *arg); 4879 ret = FAIL; 4880 } 4881 else if (rettv != NULL) 4882 { 4883 if (opt_type == -2) /* hidden string option */ 4884 { 4885 rettv->v_type = VAR_STRING; 4886 rettv->vval.v_string = NULL; 4887 } 4888 else if (opt_type == -1) /* hidden number option */ 4889 { 4890 rettv->v_type = VAR_NUMBER; 4891 rettv->vval.v_number = 0; 4892 } 4893 else if (opt_type == 1) /* number option */ 4894 { 4895 rettv->v_type = VAR_NUMBER; 4896 rettv->vval.v_number = numval; 4897 } 4898 else /* string option */ 4899 { 4900 rettv->v_type = VAR_STRING; 4901 rettv->vval.v_string = stringval; 4902 } 4903 } 4904 else if (working && (opt_type == -2 || opt_type == -1)) 4905 ret = FAIL; 4906 4907 *option_end = c; /* put back for error messages */ 4908 *arg = option_end; 4909 4910 return ret; 4911 } 4912 4913 /* 4914 * Allocate a variable for a string constant. 4915 * Return OK or FAIL. 4916 */ 4917 static int 4918 get_string_tv(arg, rettv, evaluate) 4919 char_u **arg; 4920 typval_T *rettv; 4921 int evaluate; 4922 { 4923 char_u *p; 4924 char_u *name; 4925 int extra = 0; 4926 4927 /* 4928 * Find the end of the string, skipping backslashed characters. 4929 */ 4930 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4931 { 4932 if (*p == '\\' && p[1] != NUL) 4933 { 4934 ++p; 4935 /* A "\<x>" form occupies at least 4 characters, and produces up 4936 * to 6 characters: reserve space for 2 extra */ 4937 if (*p == '<') 4938 extra += 2; 4939 } 4940 } 4941 4942 if (*p != '"') 4943 { 4944 EMSG2(_("E114: Missing quote: %s"), *arg); 4945 return FAIL; 4946 } 4947 4948 /* If only parsing, set *arg and return here */ 4949 if (!evaluate) 4950 { 4951 *arg = p + 1; 4952 return OK; 4953 } 4954 4955 /* 4956 * Copy the string into allocated memory, handling backslashed 4957 * characters. 4958 */ 4959 name = alloc((unsigned)(p - *arg + extra)); 4960 if (name == NULL) 4961 return FAIL; 4962 rettv->v_type = VAR_STRING; 4963 rettv->vval.v_string = name; 4964 4965 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4966 { 4967 if (*p == '\\') 4968 { 4969 switch (*++p) 4970 { 4971 case 'b': *name++ = BS; ++p; break; 4972 case 'e': *name++ = ESC; ++p; break; 4973 case 'f': *name++ = FF; ++p; break; 4974 case 'n': *name++ = NL; ++p; break; 4975 case 'r': *name++ = CAR; ++p; break; 4976 case 't': *name++ = TAB; ++p; break; 4977 4978 case 'X': /* hex: "\x1", "\x12" */ 4979 case 'x': 4980 case 'u': /* Unicode: "\u0023" */ 4981 case 'U': 4982 if (vim_isxdigit(p[1])) 4983 { 4984 int n, nr; 4985 int c = toupper(*p); 4986 4987 if (c == 'X') 4988 n = 2; 4989 else 4990 n = 4; 4991 nr = 0; 4992 while (--n >= 0 && vim_isxdigit(p[1])) 4993 { 4994 ++p; 4995 nr = (nr << 4) + hex2nr(*p); 4996 } 4997 ++p; 4998 #ifdef FEAT_MBYTE 4999 /* For "\u" store the number according to 5000 * 'encoding'. */ 5001 if (c != 'X') 5002 name += (*mb_char2bytes)(nr, name); 5003 else 5004 #endif 5005 *name++ = nr; 5006 } 5007 break; 5008 5009 /* octal: "\1", "\12", "\123" */ 5010 case '0': 5011 case '1': 5012 case '2': 5013 case '3': 5014 case '4': 5015 case '5': 5016 case '6': 5017 case '7': *name = *p++ - '0'; 5018 if (*p >= '0' && *p <= '7') 5019 { 5020 *name = (*name << 3) + *p++ - '0'; 5021 if (*p >= '0' && *p <= '7') 5022 *name = (*name << 3) + *p++ - '0'; 5023 } 5024 ++name; 5025 break; 5026 5027 /* Special key, e.g.: "\<C-W>" */ 5028 case '<': extra = trans_special(&p, name, TRUE); 5029 if (extra != 0) 5030 { 5031 name += extra; 5032 break; 5033 } 5034 /* FALLTHROUGH */ 5035 5036 default: MB_COPY_CHAR(p, name); 5037 break; 5038 } 5039 } 5040 else 5041 MB_COPY_CHAR(p, name); 5042 5043 } 5044 *name = NUL; 5045 *arg = p + 1; 5046 5047 return OK; 5048 } 5049 5050 /* 5051 * Allocate a variable for a 'str''ing' constant. 5052 * Return OK or FAIL. 5053 */ 5054 static int 5055 get_lit_string_tv(arg, rettv, evaluate) 5056 char_u **arg; 5057 typval_T *rettv; 5058 int evaluate; 5059 { 5060 char_u *p; 5061 char_u *str; 5062 int reduce = 0; 5063 5064 /* 5065 * Find the end of the string, skipping ''. 5066 */ 5067 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5068 { 5069 if (*p == '\'') 5070 { 5071 if (p[1] != '\'') 5072 break; 5073 ++reduce; 5074 ++p; 5075 } 5076 } 5077 5078 if (*p != '\'') 5079 { 5080 EMSG2(_("E115: Missing quote: %s"), *arg); 5081 return FAIL; 5082 } 5083 5084 /* If only parsing return after setting "*arg" */ 5085 if (!evaluate) 5086 { 5087 *arg = p + 1; 5088 return OK; 5089 } 5090 5091 /* 5092 * Copy the string into allocated memory, handling '' to ' reduction. 5093 */ 5094 str = alloc((unsigned)((p - *arg) - reduce)); 5095 if (str == NULL) 5096 return FAIL; 5097 rettv->v_type = VAR_STRING; 5098 rettv->vval.v_string = str; 5099 5100 for (p = *arg + 1; *p != NUL; ) 5101 { 5102 if (*p == '\'') 5103 { 5104 if (p[1] != '\'') 5105 break; 5106 ++p; 5107 } 5108 MB_COPY_CHAR(p, str); 5109 } 5110 *str = NUL; 5111 *arg = p + 1; 5112 5113 return OK; 5114 } 5115 5116 /* 5117 * Allocate a variable for a List and fill it from "*arg". 5118 * Return OK or FAIL. 5119 */ 5120 static int 5121 get_list_tv(arg, rettv, evaluate) 5122 char_u **arg; 5123 typval_T *rettv; 5124 int evaluate; 5125 { 5126 list_T *l = NULL; 5127 typval_T tv; 5128 listitem_T *item; 5129 5130 if (evaluate) 5131 { 5132 l = list_alloc(); 5133 if (l == NULL) 5134 return FAIL; 5135 } 5136 5137 *arg = skipwhite(*arg + 1); 5138 while (**arg != ']' && **arg != NUL) 5139 { 5140 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5141 goto failret; 5142 if (evaluate) 5143 { 5144 item = listitem_alloc(); 5145 if (item != NULL) 5146 { 5147 item->li_tv = tv; 5148 item->li_tv.v_lock = 0; 5149 list_append(l, item); 5150 } 5151 else 5152 clear_tv(&tv); 5153 } 5154 5155 if (**arg == ']') 5156 break; 5157 if (**arg != ',') 5158 { 5159 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5160 goto failret; 5161 } 5162 *arg = skipwhite(*arg + 1); 5163 } 5164 5165 if (**arg != ']') 5166 { 5167 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5168 failret: 5169 if (evaluate) 5170 list_free(l); 5171 return FAIL; 5172 } 5173 5174 *arg = skipwhite(*arg + 1); 5175 if (evaluate) 5176 { 5177 rettv->v_type = VAR_LIST; 5178 rettv->vval.v_list = l; 5179 ++l->lv_refcount; 5180 } 5181 5182 return OK; 5183 } 5184 5185 /* 5186 * Allocate an empty header for a list. 5187 * Caller should take care of the reference count. 5188 */ 5189 static list_T * 5190 list_alloc() 5191 { 5192 list_T *l; 5193 5194 l = (list_T *)alloc_clear(sizeof(list_T)); 5195 if (l != NULL) 5196 { 5197 /* Prepend the list to the list of lists for garbage collection. */ 5198 if (first_list != NULL) 5199 first_list->lv_used_prev = l; 5200 l->lv_used_prev = NULL; 5201 l->lv_used_next = first_list; 5202 first_list = l; 5203 } 5204 return l; 5205 } 5206 5207 /* 5208 * Unreference a list: decrement the reference count and free it when it 5209 * becomes zero. 5210 */ 5211 void 5212 list_unref(l) 5213 list_T *l; 5214 { 5215 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5216 list_free(l); 5217 } 5218 5219 /* 5220 * Free a list, including all items it points to. 5221 * Ignores the reference count. 5222 */ 5223 static void 5224 list_free(l) 5225 list_T *l; 5226 { 5227 listitem_T *item; 5228 5229 /* Avoid that recursive reference to the list frees us again. */ 5230 l->lv_refcount = DEL_REFCOUNT; 5231 5232 /* Remove the list from the list of lists for garbage collection. */ 5233 if (l->lv_used_prev == NULL) 5234 first_list = l->lv_used_next; 5235 else 5236 l->lv_used_prev->lv_used_next = l->lv_used_next; 5237 if (l->lv_used_next != NULL) 5238 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5239 5240 for (item = l->lv_first; item != NULL; item = l->lv_first) 5241 { 5242 /* Remove the item before deleting it. */ 5243 l->lv_first = item->li_next; 5244 listitem_free(item); 5245 } 5246 vim_free(l); 5247 } 5248 5249 /* 5250 * Allocate a list item. 5251 */ 5252 static listitem_T * 5253 listitem_alloc() 5254 { 5255 return (listitem_T *)alloc(sizeof(listitem_T)); 5256 } 5257 5258 /* 5259 * Free a list item. Also clears the value. Does not notify watchers. 5260 */ 5261 static void 5262 listitem_free(item) 5263 listitem_T *item; 5264 { 5265 clear_tv(&item->li_tv); 5266 vim_free(item); 5267 } 5268 5269 /* 5270 * Remove a list item from a List and free it. Also clears the value. 5271 */ 5272 static void 5273 listitem_remove(l, item) 5274 list_T *l; 5275 listitem_T *item; 5276 { 5277 list_remove(l, item, item); 5278 listitem_free(item); 5279 } 5280 5281 /* 5282 * Get the number of items in a list. 5283 */ 5284 static long 5285 list_len(l) 5286 list_T *l; 5287 { 5288 if (l == NULL) 5289 return 0L; 5290 return l->lv_len; 5291 } 5292 5293 /* 5294 * Return TRUE when two lists have exactly the same values. 5295 */ 5296 static int 5297 list_equal(l1, l2, ic) 5298 list_T *l1; 5299 list_T *l2; 5300 int ic; /* ignore case for strings */ 5301 { 5302 listitem_T *item1, *item2; 5303 5304 if (list_len(l1) != list_len(l2)) 5305 return FALSE; 5306 5307 for (item1 = l1->lv_first, item2 = l2->lv_first; 5308 item1 != NULL && item2 != NULL; 5309 item1 = item1->li_next, item2 = item2->li_next) 5310 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5311 return FALSE; 5312 return item1 == NULL && item2 == NULL; 5313 } 5314 5315 /* 5316 * Return TRUE when two dictionaries have exactly the same key/values. 5317 */ 5318 static int 5319 dict_equal(d1, d2, ic) 5320 dict_T *d1; 5321 dict_T *d2; 5322 int ic; /* ignore case for strings */ 5323 { 5324 hashitem_T *hi; 5325 dictitem_T *item2; 5326 int todo; 5327 5328 if (dict_len(d1) != dict_len(d2)) 5329 return FALSE; 5330 5331 todo = d1->dv_hashtab.ht_used; 5332 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5333 { 5334 if (!HASHITEM_EMPTY(hi)) 5335 { 5336 item2 = dict_find(d2, hi->hi_key, -1); 5337 if (item2 == NULL) 5338 return FALSE; 5339 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5340 return FALSE; 5341 --todo; 5342 } 5343 } 5344 return TRUE; 5345 } 5346 5347 /* 5348 * Return TRUE if "tv1" and "tv2" have the same value. 5349 * Compares the items just like "==" would compare them, but strings and 5350 * numbers are different. 5351 */ 5352 static int 5353 tv_equal(tv1, tv2, ic) 5354 typval_T *tv1; 5355 typval_T *tv2; 5356 int ic; /* ignore case */ 5357 { 5358 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5359 char_u *s1, *s2; 5360 5361 if (tv1->v_type != tv2->v_type) 5362 return FALSE; 5363 5364 switch (tv1->v_type) 5365 { 5366 case VAR_LIST: 5367 /* recursive! */ 5368 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5369 5370 case VAR_DICT: 5371 /* recursive! */ 5372 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5373 5374 case VAR_FUNC: 5375 return (tv1->vval.v_string != NULL 5376 && tv2->vval.v_string != NULL 5377 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5378 5379 case VAR_NUMBER: 5380 return tv1->vval.v_number == tv2->vval.v_number; 5381 5382 case VAR_STRING: 5383 s1 = get_tv_string_buf(tv1, buf1); 5384 s2 = get_tv_string_buf(tv2, buf2); 5385 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5386 } 5387 5388 EMSG2(_(e_intern2), "tv_equal()"); 5389 return TRUE; 5390 } 5391 5392 /* 5393 * Locate item with index "n" in list "l" and return it. 5394 * A negative index is counted from the end; -1 is the last item. 5395 * Returns NULL when "n" is out of range. 5396 */ 5397 static listitem_T * 5398 list_find(l, n) 5399 list_T *l; 5400 long n; 5401 { 5402 listitem_T *item; 5403 long idx; 5404 5405 if (l == NULL) 5406 return NULL; 5407 5408 /* Negative index is relative to the end. */ 5409 if (n < 0) 5410 n = l->lv_len + n; 5411 5412 /* Check for index out of range. */ 5413 if (n < 0 || n >= l->lv_len) 5414 return NULL; 5415 5416 /* When there is a cached index may start search from there. */ 5417 if (l->lv_idx_item != NULL) 5418 { 5419 if (n < l->lv_idx / 2) 5420 { 5421 /* closest to the start of the list */ 5422 item = l->lv_first; 5423 idx = 0; 5424 } 5425 else if (n > (l->lv_idx + l->lv_len) / 2) 5426 { 5427 /* closest to the end of the list */ 5428 item = l->lv_last; 5429 idx = l->lv_len - 1; 5430 } 5431 else 5432 { 5433 /* closest to the cached index */ 5434 item = l->lv_idx_item; 5435 idx = l->lv_idx; 5436 } 5437 } 5438 else 5439 { 5440 if (n < l->lv_len / 2) 5441 { 5442 /* closest to the start of the list */ 5443 item = l->lv_first; 5444 idx = 0; 5445 } 5446 else 5447 { 5448 /* closest to the end of the list */ 5449 item = l->lv_last; 5450 idx = l->lv_len - 1; 5451 } 5452 } 5453 5454 while (n > idx) 5455 { 5456 /* search forward */ 5457 item = item->li_next; 5458 ++idx; 5459 } 5460 while (n < idx) 5461 { 5462 /* search backward */ 5463 item = item->li_prev; 5464 --idx; 5465 } 5466 5467 /* cache the used index */ 5468 l->lv_idx = idx; 5469 l->lv_idx_item = item; 5470 5471 return item; 5472 } 5473 5474 /* 5475 * Locate "item" list "l" and return its index. 5476 * Returns -1 when "item" is not in the list. 5477 */ 5478 static long 5479 list_idx_of_item(l, item) 5480 list_T *l; 5481 listitem_T *item; 5482 { 5483 long idx = 0; 5484 listitem_T *li; 5485 5486 if (l == NULL) 5487 return -1; 5488 idx = 0; 5489 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5490 ++idx; 5491 if (li == NULL) 5492 return -1; 5493 return idx; 5494 } 5495 5496 /* 5497 * Append item "item" to the end of list "l". 5498 */ 5499 static void 5500 list_append(l, item) 5501 list_T *l; 5502 listitem_T *item; 5503 { 5504 if (l->lv_last == NULL) 5505 { 5506 /* empty list */ 5507 l->lv_first = item; 5508 l->lv_last = item; 5509 item->li_prev = NULL; 5510 } 5511 else 5512 { 5513 l->lv_last->li_next = item; 5514 item->li_prev = l->lv_last; 5515 l->lv_last = item; 5516 } 5517 ++l->lv_len; 5518 item->li_next = NULL; 5519 } 5520 5521 /* 5522 * Append typval_T "tv" to the end of list "l". 5523 * Return FAIL when out of memory. 5524 */ 5525 static int 5526 list_append_tv(l, tv) 5527 list_T *l; 5528 typval_T *tv; 5529 { 5530 listitem_T *li = listitem_alloc(); 5531 5532 if (li == NULL) 5533 return FAIL; 5534 copy_tv(tv, &li->li_tv); 5535 list_append(l, li); 5536 return OK; 5537 } 5538 5539 /* 5540 * Add a dictionary to a list. Used by getqflist(). 5541 * Return FAIL when out of memory. 5542 */ 5543 int 5544 list_append_dict(list, dict) 5545 list_T *list; 5546 dict_T *dict; 5547 { 5548 listitem_T *li = listitem_alloc(); 5549 5550 if (li == NULL) 5551 return FAIL; 5552 li->li_tv.v_type = VAR_DICT; 5553 li->li_tv.v_lock = 0; 5554 li->li_tv.vval.v_dict = dict; 5555 list_append(list, li); 5556 ++dict->dv_refcount; 5557 return OK; 5558 } 5559 5560 /* 5561 * Make a copy of "str" and append it as an item to list "l". 5562 * When "len" >= 0 use "str[len]". 5563 * Returns FAIL when out of memory. 5564 */ 5565 static int 5566 list_append_string(l, str, len) 5567 list_T *l; 5568 char_u *str; 5569 int len; 5570 { 5571 listitem_T *li = listitem_alloc(); 5572 5573 if (li == NULL) 5574 return FAIL; 5575 list_append(l, li); 5576 li->li_tv.v_type = VAR_STRING; 5577 li->li_tv.v_lock = 0; 5578 if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 5579 : vim_strsave(str))) == NULL) 5580 return FAIL; 5581 return OK; 5582 } 5583 5584 /* 5585 * Append "n" to list "l". 5586 * Returns FAIL when out of memory. 5587 */ 5588 static int 5589 list_append_number(l, n) 5590 list_T *l; 5591 varnumber_T n; 5592 { 5593 listitem_T *li; 5594 5595 li = listitem_alloc(); 5596 if (li == NULL) 5597 return FAIL; 5598 li->li_tv.v_type = VAR_NUMBER; 5599 li->li_tv.v_lock = 0; 5600 li->li_tv.vval.v_number = n; 5601 list_append(l, li); 5602 return OK; 5603 } 5604 5605 /* 5606 * Insert typval_T "tv" in list "l" before "item". 5607 * If "item" is NULL append at the end. 5608 * Return FAIL when out of memory. 5609 */ 5610 static int 5611 list_insert_tv(l, tv, item) 5612 list_T *l; 5613 typval_T *tv; 5614 listitem_T *item; 5615 { 5616 listitem_T *ni = listitem_alloc(); 5617 5618 if (ni == NULL) 5619 return FAIL; 5620 copy_tv(tv, &ni->li_tv); 5621 if (item == NULL) 5622 /* Append new item at end of list. */ 5623 list_append(l, ni); 5624 else 5625 { 5626 /* Insert new item before existing item. */ 5627 ni->li_prev = item->li_prev; 5628 ni->li_next = item; 5629 if (item->li_prev == NULL) 5630 { 5631 l->lv_first = ni; 5632 ++l->lv_idx; 5633 } 5634 else 5635 { 5636 item->li_prev->li_next = ni; 5637 l->lv_idx_item = NULL; 5638 } 5639 item->li_prev = ni; 5640 ++l->lv_len; 5641 } 5642 return OK; 5643 } 5644 5645 /* 5646 * Extend "l1" with "l2". 5647 * If "bef" is NULL append at the end, otherwise insert before this item. 5648 * Returns FAIL when out of memory. 5649 */ 5650 static int 5651 list_extend(l1, l2, bef) 5652 list_T *l1; 5653 list_T *l2; 5654 listitem_T *bef; 5655 { 5656 listitem_T *item; 5657 5658 for (item = l2->lv_first; item != NULL; item = item->li_next) 5659 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5660 return FAIL; 5661 return OK; 5662 } 5663 5664 /* 5665 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5666 * Return FAIL when out of memory. 5667 */ 5668 static int 5669 list_concat(l1, l2, tv) 5670 list_T *l1; 5671 list_T *l2; 5672 typval_T *tv; 5673 { 5674 list_T *l; 5675 5676 /* make a copy of the first list. */ 5677 l = list_copy(l1, FALSE, 0); 5678 if (l == NULL) 5679 return FAIL; 5680 tv->v_type = VAR_LIST; 5681 tv->vval.v_list = l; 5682 5683 /* append all items from the second list */ 5684 return list_extend(l, l2, NULL); 5685 } 5686 5687 /* 5688 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5689 * The refcount of the new list is set to 1. 5690 * See item_copy() for "copyID". 5691 * Returns NULL when out of memory. 5692 */ 5693 static list_T * 5694 list_copy(orig, deep, copyID) 5695 list_T *orig; 5696 int deep; 5697 int copyID; 5698 { 5699 list_T *copy; 5700 listitem_T *item; 5701 listitem_T *ni; 5702 5703 if (orig == NULL) 5704 return NULL; 5705 5706 copy = list_alloc(); 5707 if (copy != NULL) 5708 { 5709 if (copyID != 0) 5710 { 5711 /* Do this before adding the items, because one of the items may 5712 * refer back to this list. */ 5713 orig->lv_copyID = copyID; 5714 orig->lv_copylist = copy; 5715 } 5716 for (item = orig->lv_first; item != NULL && !got_int; 5717 item = item->li_next) 5718 { 5719 ni = listitem_alloc(); 5720 if (ni == NULL) 5721 break; 5722 if (deep) 5723 { 5724 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5725 { 5726 vim_free(ni); 5727 break; 5728 } 5729 } 5730 else 5731 copy_tv(&item->li_tv, &ni->li_tv); 5732 list_append(copy, ni); 5733 } 5734 ++copy->lv_refcount; 5735 if (item != NULL) 5736 { 5737 list_unref(copy); 5738 copy = NULL; 5739 } 5740 } 5741 5742 return copy; 5743 } 5744 5745 /* 5746 * Remove items "item" to "item2" from list "l". 5747 * Does not free the listitem or the value! 5748 */ 5749 static void 5750 list_remove(l, item, item2) 5751 list_T *l; 5752 listitem_T *item; 5753 listitem_T *item2; 5754 { 5755 listitem_T *ip; 5756 5757 /* notify watchers */ 5758 for (ip = item; ip != NULL; ip = ip->li_next) 5759 { 5760 --l->lv_len; 5761 list_fix_watch(l, ip); 5762 if (ip == item2) 5763 break; 5764 } 5765 5766 if (item2->li_next == NULL) 5767 l->lv_last = item->li_prev; 5768 else 5769 item2->li_next->li_prev = item->li_prev; 5770 if (item->li_prev == NULL) 5771 l->lv_first = item2->li_next; 5772 else 5773 item->li_prev->li_next = item2->li_next; 5774 l->lv_idx_item = NULL; 5775 } 5776 5777 /* 5778 * Return an allocated string with the string representation of a list. 5779 * May return NULL. 5780 */ 5781 static char_u * 5782 list2string(tv) 5783 typval_T *tv; 5784 { 5785 garray_T ga; 5786 5787 if (tv->vval.v_list == NULL) 5788 return NULL; 5789 ga_init2(&ga, (int)sizeof(char), 80); 5790 ga_append(&ga, '['); 5791 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5792 { 5793 vim_free(ga.ga_data); 5794 return NULL; 5795 } 5796 ga_append(&ga, ']'); 5797 ga_append(&ga, NUL); 5798 return (char_u *)ga.ga_data; 5799 } 5800 5801 /* 5802 * Join list "l" into a string in "*gap", using separator "sep". 5803 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5804 * Return FAIL or OK. 5805 */ 5806 static int 5807 list_join(gap, l, sep, echo) 5808 garray_T *gap; 5809 list_T *l; 5810 char_u *sep; 5811 int echo; 5812 { 5813 int first = TRUE; 5814 char_u *tofree; 5815 char_u numbuf[NUMBUFLEN]; 5816 listitem_T *item; 5817 char_u *s; 5818 5819 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5820 { 5821 if (first) 5822 first = FALSE; 5823 else 5824 ga_concat(gap, sep); 5825 5826 if (echo) 5827 s = echo_string(&item->li_tv, &tofree, numbuf); 5828 else 5829 s = tv2string(&item->li_tv, &tofree, numbuf); 5830 if (s != NULL) 5831 ga_concat(gap, s); 5832 vim_free(tofree); 5833 if (s == NULL) 5834 return FAIL; 5835 } 5836 return OK; 5837 } 5838 5839 /* 5840 * Garbage collection for lists and dictionaries. 5841 * 5842 * We use reference counts to be able to free most items right away when they 5843 * are no longer used. But for composite items it's possible that it becomes 5844 * unused while the reference count is > 0: When there is a recursive 5845 * reference. Example: 5846 * :let l = [1, 2, 3] 5847 * :let d = {9: l} 5848 * :let l[1] = d 5849 * 5850 * Since this is quite unusual we handle this with garbage collection: every 5851 * once in a while find out which lists and dicts are not referenced from any 5852 * variable. 5853 * 5854 * Here is a good reference text about garbage collection (refers to Python 5855 * but it applies to all reference-counting mechanisms): 5856 * http://python.ca/nas/python/gc/ 5857 */ 5858 5859 /* 5860 * Do garbage collection for lists and dicts. 5861 * Return TRUE if some memory was freed. 5862 */ 5863 int 5864 garbage_collect() 5865 { 5866 dict_T *dd; 5867 list_T *ll; 5868 int copyID = ++current_copyID; 5869 buf_T *buf; 5870 win_T *wp; 5871 int i; 5872 funccall_T *fc; 5873 int did_free = FALSE; 5874 5875 /* 5876 * 1. Go through all accessible variables and mark all lists and dicts 5877 * with copyID. 5878 */ 5879 /* script-local variables */ 5880 for (i = 1; i <= ga_scripts.ga_len; ++i) 5881 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5882 5883 /* buffer-local variables */ 5884 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5885 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5886 5887 /* window-local variables */ 5888 FOR_ALL_WINDOWS(wp) 5889 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5890 5891 /* global variables */ 5892 set_ref_in_ht(&globvarht, copyID); 5893 5894 /* function-local variables */ 5895 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5896 { 5897 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5898 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5899 } 5900 5901 /* 5902 * 2. Go through the list of dicts and free items without the copyID. 5903 */ 5904 for (dd = first_dict; dd != NULL; ) 5905 if (dd->dv_copyID != copyID) 5906 { 5907 dict_free(dd); 5908 did_free = TRUE; 5909 5910 /* restart, next dict may also have been freed */ 5911 dd = first_dict; 5912 } 5913 else 5914 dd = dd->dv_used_next; 5915 5916 /* 5917 * 3. Go through the list of lists and free items without the copyID. 5918 * But don't free a list that has a watcher (used in a for loop), these 5919 * are not referenced anywhere. 5920 */ 5921 for (ll = first_list; ll != NULL; ) 5922 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 5923 { 5924 list_free(ll); 5925 did_free = TRUE; 5926 5927 /* restart, next list may also have been freed */ 5928 ll = first_list; 5929 } 5930 else 5931 ll = ll->lv_used_next; 5932 5933 return did_free; 5934 } 5935 5936 /* 5937 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5938 */ 5939 static void 5940 set_ref_in_ht(ht, copyID) 5941 hashtab_T *ht; 5942 int copyID; 5943 { 5944 int todo; 5945 hashitem_T *hi; 5946 5947 todo = ht->ht_used; 5948 for (hi = ht->ht_array; todo > 0; ++hi) 5949 if (!HASHITEM_EMPTY(hi)) 5950 { 5951 --todo; 5952 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5953 } 5954 } 5955 5956 /* 5957 * Mark all lists and dicts referenced through list "l" with "copyID". 5958 */ 5959 static void 5960 set_ref_in_list(l, copyID) 5961 list_T *l; 5962 int copyID; 5963 { 5964 listitem_T *li; 5965 5966 for (li = l->lv_first; li != NULL; li = li->li_next) 5967 set_ref_in_item(&li->li_tv, copyID); 5968 } 5969 5970 /* 5971 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5972 */ 5973 static void 5974 set_ref_in_item(tv, copyID) 5975 typval_T *tv; 5976 int copyID; 5977 { 5978 dict_T *dd; 5979 list_T *ll; 5980 5981 switch (tv->v_type) 5982 { 5983 case VAR_DICT: 5984 dd = tv->vval.v_dict; 5985 if (dd->dv_copyID != copyID) 5986 { 5987 /* Didn't see this dict yet. */ 5988 dd->dv_copyID = copyID; 5989 set_ref_in_ht(&dd->dv_hashtab, copyID); 5990 } 5991 break; 5992 5993 case VAR_LIST: 5994 ll = tv->vval.v_list; 5995 if (ll->lv_copyID != copyID) 5996 { 5997 /* Didn't see this list yet. */ 5998 ll->lv_copyID = copyID; 5999 set_ref_in_list(ll, copyID); 6000 } 6001 break; 6002 } 6003 return; 6004 } 6005 6006 /* 6007 * Allocate an empty header for a dictionary. 6008 */ 6009 dict_T * 6010 dict_alloc() 6011 { 6012 dict_T *d; 6013 6014 d = (dict_T *)alloc(sizeof(dict_T)); 6015 if (d != NULL) 6016 { 6017 /* Add the list to the hashtable for garbage collection. */ 6018 if (first_dict != NULL) 6019 first_dict->dv_used_prev = d; 6020 d->dv_used_next = first_dict; 6021 d->dv_used_prev = NULL; 6022 6023 hash_init(&d->dv_hashtab); 6024 d->dv_lock = 0; 6025 d->dv_refcount = 0; 6026 d->dv_copyID = 0; 6027 } 6028 return d; 6029 } 6030 6031 /* 6032 * Unreference a Dictionary: decrement the reference count and free it when it 6033 * becomes zero. 6034 */ 6035 static void 6036 dict_unref(d) 6037 dict_T *d; 6038 { 6039 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6040 dict_free(d); 6041 } 6042 6043 /* 6044 * Free a Dictionary, including all items it contains. 6045 * Ignores the reference count. 6046 */ 6047 static void 6048 dict_free(d) 6049 dict_T *d; 6050 { 6051 int todo; 6052 hashitem_T *hi; 6053 dictitem_T *di; 6054 6055 /* Avoid that recursive reference to the dict frees us again. */ 6056 d->dv_refcount = DEL_REFCOUNT; 6057 6058 /* Remove the dict from the list of dicts for garbage collection. */ 6059 if (d->dv_used_prev == NULL) 6060 first_dict = d->dv_used_next; 6061 else 6062 d->dv_used_prev->dv_used_next = d->dv_used_next; 6063 if (d->dv_used_next != NULL) 6064 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6065 6066 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6067 hash_lock(&d->dv_hashtab); 6068 todo = d->dv_hashtab.ht_used; 6069 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6070 { 6071 if (!HASHITEM_EMPTY(hi)) 6072 { 6073 /* Remove the item before deleting it, just in case there is 6074 * something recursive causing trouble. */ 6075 di = HI2DI(hi); 6076 hash_remove(&d->dv_hashtab, hi); 6077 dictitem_free(di); 6078 --todo; 6079 } 6080 } 6081 hash_clear(&d->dv_hashtab); 6082 vim_free(d); 6083 } 6084 6085 /* 6086 * Allocate a Dictionary item. 6087 * The "key" is copied to the new item. 6088 * Note that the value of the item "di_tv" still needs to be initialized! 6089 * Returns NULL when out of memory. 6090 */ 6091 static dictitem_T * 6092 dictitem_alloc(key) 6093 char_u *key; 6094 { 6095 dictitem_T *di; 6096 6097 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6098 if (di != NULL) 6099 { 6100 STRCPY(di->di_key, key); 6101 di->di_flags = 0; 6102 } 6103 return di; 6104 } 6105 6106 /* 6107 * Make a copy of a Dictionary item. 6108 */ 6109 static dictitem_T * 6110 dictitem_copy(org) 6111 dictitem_T *org; 6112 { 6113 dictitem_T *di; 6114 6115 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6116 if (di != NULL) 6117 { 6118 STRCPY(di->di_key, org->di_key); 6119 di->di_flags = 0; 6120 copy_tv(&org->di_tv, &di->di_tv); 6121 } 6122 return di; 6123 } 6124 6125 /* 6126 * Remove item "item" from Dictionary "dict" and free it. 6127 */ 6128 static void 6129 dictitem_remove(dict, item) 6130 dict_T *dict; 6131 dictitem_T *item; 6132 { 6133 hashitem_T *hi; 6134 6135 hi = hash_find(&dict->dv_hashtab, item->di_key); 6136 if (HASHITEM_EMPTY(hi)) 6137 EMSG2(_(e_intern2), "dictitem_remove()"); 6138 else 6139 hash_remove(&dict->dv_hashtab, hi); 6140 dictitem_free(item); 6141 } 6142 6143 /* 6144 * Free a dict item. Also clears the value. 6145 */ 6146 static void 6147 dictitem_free(item) 6148 dictitem_T *item; 6149 { 6150 clear_tv(&item->di_tv); 6151 vim_free(item); 6152 } 6153 6154 /* 6155 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6156 * The refcount of the new dict is set to 1. 6157 * See item_copy() for "copyID". 6158 * Returns NULL when out of memory. 6159 */ 6160 static dict_T * 6161 dict_copy(orig, deep, copyID) 6162 dict_T *orig; 6163 int deep; 6164 int copyID; 6165 { 6166 dict_T *copy; 6167 dictitem_T *di; 6168 int todo; 6169 hashitem_T *hi; 6170 6171 if (orig == NULL) 6172 return NULL; 6173 6174 copy = dict_alloc(); 6175 if (copy != NULL) 6176 { 6177 if (copyID != 0) 6178 { 6179 orig->dv_copyID = copyID; 6180 orig->dv_copydict = copy; 6181 } 6182 todo = orig->dv_hashtab.ht_used; 6183 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6184 { 6185 if (!HASHITEM_EMPTY(hi)) 6186 { 6187 --todo; 6188 6189 di = dictitem_alloc(hi->hi_key); 6190 if (di == NULL) 6191 break; 6192 if (deep) 6193 { 6194 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6195 copyID) == FAIL) 6196 { 6197 vim_free(di); 6198 break; 6199 } 6200 } 6201 else 6202 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6203 if (dict_add(copy, di) == FAIL) 6204 { 6205 dictitem_free(di); 6206 break; 6207 } 6208 } 6209 } 6210 6211 ++copy->dv_refcount; 6212 if (todo > 0) 6213 { 6214 dict_unref(copy); 6215 copy = NULL; 6216 } 6217 } 6218 6219 return copy; 6220 } 6221 6222 /* 6223 * Add item "item" to Dictionary "d". 6224 * Returns FAIL when out of memory and when key already existed. 6225 */ 6226 static int 6227 dict_add(d, item) 6228 dict_T *d; 6229 dictitem_T *item; 6230 { 6231 return hash_add(&d->dv_hashtab, item->di_key); 6232 } 6233 6234 /* 6235 * Add a number or string entry to dictionary "d". 6236 * When "str" is NULL use number "nr", otherwise use "str". 6237 * Returns FAIL when out of memory and when key already exists. 6238 */ 6239 int 6240 dict_add_nr_str(d, key, nr, str) 6241 dict_T *d; 6242 char *key; 6243 long nr; 6244 char_u *str; 6245 { 6246 dictitem_T *item; 6247 6248 item = dictitem_alloc((char_u *)key); 6249 if (item == NULL) 6250 return FAIL; 6251 item->di_tv.v_lock = 0; 6252 if (str == NULL) 6253 { 6254 item->di_tv.v_type = VAR_NUMBER; 6255 item->di_tv.vval.v_number = nr; 6256 } 6257 else 6258 { 6259 item->di_tv.v_type = VAR_STRING; 6260 item->di_tv.vval.v_string = vim_strsave(str); 6261 } 6262 if (dict_add(d, item) == FAIL) 6263 { 6264 dictitem_free(item); 6265 return FAIL; 6266 } 6267 return OK; 6268 } 6269 6270 /* 6271 * Get the number of items in a Dictionary. 6272 */ 6273 static long 6274 dict_len(d) 6275 dict_T *d; 6276 { 6277 if (d == NULL) 6278 return 0L; 6279 return d->dv_hashtab.ht_used; 6280 } 6281 6282 /* 6283 * Find item "key[len]" in Dictionary "d". 6284 * If "len" is negative use strlen(key). 6285 * Returns NULL when not found. 6286 */ 6287 static dictitem_T * 6288 dict_find(d, key, len) 6289 dict_T *d; 6290 char_u *key; 6291 int len; 6292 { 6293 #define AKEYLEN 200 6294 char_u buf[AKEYLEN]; 6295 char_u *akey; 6296 char_u *tofree = NULL; 6297 hashitem_T *hi; 6298 6299 if (len < 0) 6300 akey = key; 6301 else if (len >= AKEYLEN) 6302 { 6303 tofree = akey = vim_strnsave(key, len); 6304 if (akey == NULL) 6305 return NULL; 6306 } 6307 else 6308 { 6309 /* Avoid a malloc/free by using buf[]. */ 6310 vim_strncpy(buf, key, len); 6311 akey = buf; 6312 } 6313 6314 hi = hash_find(&d->dv_hashtab, akey); 6315 vim_free(tofree); 6316 if (HASHITEM_EMPTY(hi)) 6317 return NULL; 6318 return HI2DI(hi); 6319 } 6320 6321 /* 6322 * Get a string item from a dictionary in allocated memory. 6323 * Returns NULL if the entry doesn't exist or out of memory. 6324 */ 6325 char_u * 6326 get_dict_string(d, key) 6327 dict_T *d; 6328 char_u *key; 6329 { 6330 dictitem_T *di; 6331 6332 di = dict_find(d, key, -1); 6333 if (di == NULL) 6334 return NULL; 6335 return vim_strsave(get_tv_string(&di->di_tv)); 6336 } 6337 6338 /* 6339 * Get a number item from a dictionary. 6340 * Returns 0 if the entry doesn't exist or out of memory. 6341 */ 6342 long 6343 get_dict_number(d, key) 6344 dict_T *d; 6345 char_u *key; 6346 { 6347 dictitem_T *di; 6348 6349 di = dict_find(d, key, -1); 6350 if (di == NULL) 6351 return 0; 6352 return get_tv_number(&di->di_tv); 6353 } 6354 6355 /* 6356 * Return an allocated string with the string representation of a Dictionary. 6357 * May return NULL. 6358 */ 6359 static char_u * 6360 dict2string(tv) 6361 typval_T *tv; 6362 { 6363 garray_T ga; 6364 int first = TRUE; 6365 char_u *tofree; 6366 char_u numbuf[NUMBUFLEN]; 6367 hashitem_T *hi; 6368 char_u *s; 6369 dict_T *d; 6370 int todo; 6371 6372 if ((d = tv->vval.v_dict) == NULL) 6373 return NULL; 6374 ga_init2(&ga, (int)sizeof(char), 80); 6375 ga_append(&ga, '{'); 6376 6377 todo = d->dv_hashtab.ht_used; 6378 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6379 { 6380 if (!HASHITEM_EMPTY(hi)) 6381 { 6382 --todo; 6383 6384 if (first) 6385 first = FALSE; 6386 else 6387 ga_concat(&ga, (char_u *)", "); 6388 6389 tofree = string_quote(hi->hi_key, FALSE); 6390 if (tofree != NULL) 6391 { 6392 ga_concat(&ga, tofree); 6393 vim_free(tofree); 6394 } 6395 ga_concat(&ga, (char_u *)": "); 6396 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6397 if (s != NULL) 6398 ga_concat(&ga, s); 6399 vim_free(tofree); 6400 if (s == NULL) 6401 break; 6402 } 6403 } 6404 if (todo > 0) 6405 { 6406 vim_free(ga.ga_data); 6407 return NULL; 6408 } 6409 6410 ga_append(&ga, '}'); 6411 ga_append(&ga, NUL); 6412 return (char_u *)ga.ga_data; 6413 } 6414 6415 /* 6416 * Allocate a variable for a Dictionary and fill it from "*arg". 6417 * Return OK or FAIL. Returns NOTDONE for {expr}. 6418 */ 6419 static int 6420 get_dict_tv(arg, rettv, evaluate) 6421 char_u **arg; 6422 typval_T *rettv; 6423 int evaluate; 6424 { 6425 dict_T *d = NULL; 6426 typval_T tvkey; 6427 typval_T tv; 6428 char_u *key; 6429 dictitem_T *item; 6430 char_u *start = skipwhite(*arg + 1); 6431 char_u buf[NUMBUFLEN]; 6432 6433 /* 6434 * First check if it's not a curly-braces thing: {expr}. 6435 * Must do this without evaluating, otherwise a function may be called 6436 * twice. Unfortunately this means we need to call eval1() twice for the 6437 * first item. 6438 * But {} is an empty Dictionary. 6439 */ 6440 if (*start != '}') 6441 { 6442 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6443 return FAIL; 6444 if (*start == '}') 6445 return NOTDONE; 6446 } 6447 6448 if (evaluate) 6449 { 6450 d = dict_alloc(); 6451 if (d == NULL) 6452 return FAIL; 6453 } 6454 tvkey.v_type = VAR_UNKNOWN; 6455 tv.v_type = VAR_UNKNOWN; 6456 6457 *arg = skipwhite(*arg + 1); 6458 while (**arg != '}' && **arg != NUL) 6459 { 6460 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6461 goto failret; 6462 if (**arg != ':') 6463 { 6464 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6465 clear_tv(&tvkey); 6466 goto failret; 6467 } 6468 key = get_tv_string_buf_chk(&tvkey, buf); 6469 if (key == NULL || *key == NUL) 6470 { 6471 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6472 if (key != NULL) 6473 EMSG(_(e_emptykey)); 6474 clear_tv(&tvkey); 6475 goto failret; 6476 } 6477 6478 *arg = skipwhite(*arg + 1); 6479 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6480 { 6481 clear_tv(&tvkey); 6482 goto failret; 6483 } 6484 if (evaluate) 6485 { 6486 item = dict_find(d, key, -1); 6487 if (item != NULL) 6488 { 6489 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6490 clear_tv(&tvkey); 6491 clear_tv(&tv); 6492 goto failret; 6493 } 6494 item = dictitem_alloc(key); 6495 clear_tv(&tvkey); 6496 if (item != NULL) 6497 { 6498 item->di_tv = tv; 6499 item->di_tv.v_lock = 0; 6500 if (dict_add(d, item) == FAIL) 6501 dictitem_free(item); 6502 } 6503 } 6504 6505 if (**arg == '}') 6506 break; 6507 if (**arg != ',') 6508 { 6509 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6510 goto failret; 6511 } 6512 *arg = skipwhite(*arg + 1); 6513 } 6514 6515 if (**arg != '}') 6516 { 6517 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6518 failret: 6519 if (evaluate) 6520 dict_free(d); 6521 return FAIL; 6522 } 6523 6524 *arg = skipwhite(*arg + 1); 6525 if (evaluate) 6526 { 6527 rettv->v_type = VAR_DICT; 6528 rettv->vval.v_dict = d; 6529 ++d->dv_refcount; 6530 } 6531 6532 return OK; 6533 } 6534 6535 /* 6536 * Return a string with the string representation of a variable. 6537 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6538 * "numbuf" is used for a number. 6539 * Does not put quotes around strings, as ":echo" displays values. 6540 * May return NULL; 6541 */ 6542 static char_u * 6543 echo_string(tv, tofree, numbuf) 6544 typval_T *tv; 6545 char_u **tofree; 6546 char_u *numbuf; 6547 { 6548 static int recurse = 0; 6549 char_u *r = NULL; 6550 6551 if (recurse >= DICT_MAXNEST) 6552 { 6553 EMSG(_("E724: variable nested too deep for displaying")); 6554 *tofree = NULL; 6555 return NULL; 6556 } 6557 ++recurse; 6558 6559 switch (tv->v_type) 6560 { 6561 case VAR_FUNC: 6562 *tofree = NULL; 6563 r = tv->vval.v_string; 6564 break; 6565 case VAR_LIST: 6566 *tofree = list2string(tv); 6567 r = *tofree; 6568 break; 6569 case VAR_DICT: 6570 *tofree = dict2string(tv); 6571 r = *tofree; 6572 break; 6573 case VAR_STRING: 6574 case VAR_NUMBER: 6575 *tofree = NULL; 6576 r = get_tv_string_buf(tv, numbuf); 6577 break; 6578 default: 6579 EMSG2(_(e_intern2), "echo_string()"); 6580 *tofree = NULL; 6581 } 6582 6583 --recurse; 6584 return r; 6585 } 6586 6587 /* 6588 * Return a string with the string representation of a variable. 6589 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6590 * "numbuf" is used for a number. 6591 * Puts quotes around strings, so that they can be parsed back by eval(). 6592 * May return NULL; 6593 */ 6594 static char_u * 6595 tv2string(tv, tofree, numbuf) 6596 typval_T *tv; 6597 char_u **tofree; 6598 char_u *numbuf; 6599 { 6600 switch (tv->v_type) 6601 { 6602 case VAR_FUNC: 6603 *tofree = string_quote(tv->vval.v_string, TRUE); 6604 return *tofree; 6605 case VAR_STRING: 6606 *tofree = string_quote(tv->vval.v_string, FALSE); 6607 return *tofree; 6608 case VAR_NUMBER: 6609 case VAR_LIST: 6610 case VAR_DICT: 6611 break; 6612 default: 6613 EMSG2(_(e_intern2), "tv2string()"); 6614 } 6615 return echo_string(tv, tofree, numbuf); 6616 } 6617 6618 /* 6619 * Return string "str" in ' quotes, doubling ' characters. 6620 * If "str" is NULL an empty string is assumed. 6621 * If "function" is TRUE make it function('string'). 6622 */ 6623 static char_u * 6624 string_quote(str, function) 6625 char_u *str; 6626 int function; 6627 { 6628 unsigned len; 6629 char_u *p, *r, *s; 6630 6631 len = (function ? 13 : 3); 6632 if (str != NULL) 6633 { 6634 len += STRLEN(str); 6635 for (p = str; *p != NUL; mb_ptr_adv(p)) 6636 if (*p == '\'') 6637 ++len; 6638 } 6639 s = r = alloc(len); 6640 if (r != NULL) 6641 { 6642 if (function) 6643 { 6644 STRCPY(r, "function('"); 6645 r += 10; 6646 } 6647 else 6648 *r++ = '\''; 6649 if (str != NULL) 6650 for (p = str; *p != NUL; ) 6651 { 6652 if (*p == '\'') 6653 *r++ = '\''; 6654 MB_COPY_CHAR(p, r); 6655 } 6656 *r++ = '\''; 6657 if (function) 6658 *r++ = ')'; 6659 *r++ = NUL; 6660 } 6661 return s; 6662 } 6663 6664 /* 6665 * Get the value of an environment variable. 6666 * "arg" is pointing to the '$'. It is advanced to after the name. 6667 * If the environment variable was not set, silently assume it is empty. 6668 * Always return OK. 6669 */ 6670 static int 6671 get_env_tv(arg, rettv, evaluate) 6672 char_u **arg; 6673 typval_T *rettv; 6674 int evaluate; 6675 { 6676 char_u *string = NULL; 6677 int len; 6678 int cc; 6679 char_u *name; 6680 int mustfree = FALSE; 6681 6682 ++*arg; 6683 name = *arg; 6684 len = get_env_len(arg); 6685 if (evaluate) 6686 { 6687 if (len != 0) 6688 { 6689 cc = name[len]; 6690 name[len] = NUL; 6691 /* first try vim_getenv(), fast for normal environment vars */ 6692 string = vim_getenv(name, &mustfree); 6693 if (string != NULL && *string != NUL) 6694 { 6695 if (!mustfree) 6696 string = vim_strsave(string); 6697 } 6698 else 6699 { 6700 if (mustfree) 6701 vim_free(string); 6702 6703 /* next try expanding things like $VIM and ${HOME} */ 6704 string = expand_env_save(name - 1); 6705 if (string != NULL && *string == '$') 6706 { 6707 vim_free(string); 6708 string = NULL; 6709 } 6710 } 6711 name[len] = cc; 6712 } 6713 rettv->v_type = VAR_STRING; 6714 rettv->vval.v_string = string; 6715 } 6716 6717 return OK; 6718 } 6719 6720 /* 6721 * Array with names and number of arguments of all internal functions 6722 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6723 */ 6724 static struct fst 6725 { 6726 char *f_name; /* function name */ 6727 char f_min_argc; /* minimal number of arguments */ 6728 char f_max_argc; /* maximal number of arguments */ 6729 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6730 /* implemenation of function */ 6731 } functions[] = 6732 { 6733 {"add", 2, 2, f_add}, 6734 {"append", 2, 2, f_append}, 6735 {"argc", 0, 0, f_argc}, 6736 {"argidx", 0, 0, f_argidx}, 6737 {"argv", 1, 1, f_argv}, 6738 {"browse", 4, 4, f_browse}, 6739 {"browsedir", 2, 2, f_browsedir}, 6740 {"bufexists", 1, 1, f_bufexists}, 6741 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6742 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6743 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6744 {"buflisted", 1, 1, f_buflisted}, 6745 {"bufloaded", 1, 1, f_bufloaded}, 6746 {"bufname", 1, 1, f_bufname}, 6747 {"bufnr", 1, 1, f_bufnr}, 6748 {"bufwinnr", 1, 1, f_bufwinnr}, 6749 {"byte2line", 1, 1, f_byte2line}, 6750 {"byteidx", 2, 2, f_byteidx}, 6751 {"call", 2, 3, f_call}, 6752 {"char2nr", 1, 1, f_char2nr}, 6753 {"cindent", 1, 1, f_cindent}, 6754 {"col", 1, 1, f_col}, 6755 #if defined(FEAT_INS_EXPAND) 6756 {"complete_add", 1, 1, f_complete_add}, 6757 {"complete_check", 0, 0, f_complete_check}, 6758 #endif 6759 {"confirm", 1, 4, f_confirm}, 6760 {"copy", 1, 1, f_copy}, 6761 {"count", 2, 4, f_count}, 6762 {"cscope_connection",0,3, f_cscope_connection}, 6763 {"cursor", 2, 2, f_cursor}, 6764 {"deepcopy", 1, 2, f_deepcopy}, 6765 {"delete", 1, 1, f_delete}, 6766 {"did_filetype", 0, 0, f_did_filetype}, 6767 {"diff_filler", 1, 1, f_diff_filler}, 6768 {"diff_hlID", 2, 2, f_diff_hlID}, 6769 {"empty", 1, 1, f_empty}, 6770 {"escape", 2, 2, f_escape}, 6771 {"eval", 1, 1, f_eval}, 6772 {"eventhandler", 0, 0, f_eventhandler}, 6773 {"executable", 1, 1, f_executable}, 6774 {"exists", 1, 1, f_exists}, 6775 {"expand", 1, 2, f_expand}, 6776 {"extend", 2, 3, f_extend}, 6777 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6778 {"filereadable", 1, 1, f_filereadable}, 6779 {"filewritable", 1, 1, f_filewritable}, 6780 {"filter", 2, 2, f_filter}, 6781 {"finddir", 1, 3, f_finddir}, 6782 {"findfile", 1, 3, f_findfile}, 6783 {"fnamemodify", 2, 2, f_fnamemodify}, 6784 {"foldclosed", 1, 1, f_foldclosed}, 6785 {"foldclosedend", 1, 1, f_foldclosedend}, 6786 {"foldlevel", 1, 1, f_foldlevel}, 6787 {"foldtext", 0, 0, f_foldtext}, 6788 {"foldtextresult", 1, 1, f_foldtextresult}, 6789 {"foreground", 0, 0, f_foreground}, 6790 {"function", 1, 1, f_function}, 6791 {"garbagecollect", 0, 0, f_garbagecollect}, 6792 {"get", 2, 3, f_get}, 6793 {"getbufline", 2, 3, f_getbufline}, 6794 {"getbufvar", 2, 2, f_getbufvar}, 6795 {"getchar", 0, 1, f_getchar}, 6796 {"getcharmod", 0, 0, f_getcharmod}, 6797 {"getcmdline", 0, 0, f_getcmdline}, 6798 {"getcmdpos", 0, 0, f_getcmdpos}, 6799 {"getcmdtype", 0, 0, f_getcmdtype}, 6800 {"getcwd", 0, 0, f_getcwd}, 6801 {"getfontname", 0, 1, f_getfontname}, 6802 {"getfperm", 1, 1, f_getfperm}, 6803 {"getfsize", 1, 1, f_getfsize}, 6804 {"getftime", 1, 1, f_getftime}, 6805 {"getftype", 1, 1, f_getftype}, 6806 {"getline", 1, 2, f_getline}, 6807 {"getqflist", 0, 0, f_getqflist}, 6808 {"getreg", 0, 2, f_getreg}, 6809 {"getregtype", 0, 1, f_getregtype}, 6810 {"getwinposx", 0, 0, f_getwinposx}, 6811 {"getwinposy", 0, 0, f_getwinposy}, 6812 {"getwinvar", 2, 2, f_getwinvar}, 6813 {"glob", 1, 1, f_glob}, 6814 {"globpath", 2, 2, f_globpath}, 6815 {"has", 1, 1, f_has}, 6816 {"has_key", 2, 2, f_has_key}, 6817 {"hasmapto", 1, 2, f_hasmapto}, 6818 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6819 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6820 {"histadd", 2, 2, f_histadd}, 6821 {"histdel", 1, 2, f_histdel}, 6822 {"histget", 1, 2, f_histget}, 6823 {"histnr", 1, 1, f_histnr}, 6824 {"hlID", 1, 1, f_hlID}, 6825 {"hlexists", 1, 1, f_hlexists}, 6826 {"hostname", 0, 0, f_hostname}, 6827 {"iconv", 3, 3, f_iconv}, 6828 {"indent", 1, 1, f_indent}, 6829 {"index", 2, 4, f_index}, 6830 {"input", 1, 3, f_input}, 6831 {"inputdialog", 1, 3, f_inputdialog}, 6832 {"inputlist", 1, 1, f_inputlist}, 6833 {"inputrestore", 0, 0, f_inputrestore}, 6834 {"inputsave", 0, 0, f_inputsave}, 6835 {"inputsecret", 1, 2, f_inputsecret}, 6836 {"insert", 2, 3, f_insert}, 6837 {"isdirectory", 1, 1, f_isdirectory}, 6838 {"islocked", 1, 1, f_islocked}, 6839 {"items", 1, 1, f_items}, 6840 {"join", 1, 2, f_join}, 6841 {"keys", 1, 1, f_keys}, 6842 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6843 {"len", 1, 1, f_len}, 6844 {"libcall", 3, 3, f_libcall}, 6845 {"libcallnr", 3, 3, f_libcallnr}, 6846 {"line", 1, 1, f_line}, 6847 {"line2byte", 1, 1, f_line2byte}, 6848 {"lispindent", 1, 1, f_lispindent}, 6849 {"localtime", 0, 0, f_localtime}, 6850 {"map", 2, 2, f_map}, 6851 {"maparg", 1, 2, f_maparg}, 6852 {"mapcheck", 1, 2, f_mapcheck}, 6853 {"match", 2, 4, f_match}, 6854 {"matchend", 2, 4, f_matchend}, 6855 {"matchlist", 2, 4, f_matchlist}, 6856 {"matchstr", 2, 4, f_matchstr}, 6857 {"max", 1, 1, f_max}, 6858 {"min", 1, 1, f_min}, 6859 #ifdef vim_mkdir 6860 {"mkdir", 1, 3, f_mkdir}, 6861 #endif 6862 {"mode", 0, 0, f_mode}, 6863 {"nextnonblank", 1, 1, f_nextnonblank}, 6864 {"nr2char", 1, 1, f_nr2char}, 6865 {"prevnonblank", 1, 1, f_prevnonblank}, 6866 {"printf", 2, 19, f_printf}, 6867 {"range", 1, 3, f_range}, 6868 {"readfile", 1, 3, f_readfile}, 6869 {"remote_expr", 2, 3, f_remote_expr}, 6870 {"remote_foreground", 1, 1, f_remote_foreground}, 6871 {"remote_peek", 1, 2, f_remote_peek}, 6872 {"remote_read", 1, 1, f_remote_read}, 6873 {"remote_send", 2, 3, f_remote_send}, 6874 {"remove", 2, 3, f_remove}, 6875 {"rename", 2, 2, f_rename}, 6876 {"repeat", 2, 2, f_repeat}, 6877 {"resolve", 1, 1, f_resolve}, 6878 {"reverse", 1, 1, f_reverse}, 6879 {"search", 1, 2, f_search}, 6880 {"searchdecl", 1, 3, f_searchdecl}, 6881 {"searchpair", 3, 5, f_searchpair}, 6882 {"server2client", 2, 2, f_server2client}, 6883 {"serverlist", 0, 0, f_serverlist}, 6884 {"setbufvar", 3, 3, f_setbufvar}, 6885 {"setcmdpos", 1, 1, f_setcmdpos}, 6886 {"setline", 2, 2, f_setline}, 6887 {"setqflist", 1, 2, f_setqflist}, 6888 {"setreg", 2, 3, f_setreg}, 6889 {"setwinvar", 3, 3, f_setwinvar}, 6890 {"simplify", 1, 1, f_simplify}, 6891 {"sort", 1, 2, f_sort}, 6892 {"soundfold", 1, 1, f_soundfold}, 6893 {"spellbadword", 0, 1, f_spellbadword}, 6894 {"spellsuggest", 1, 3, f_spellsuggest}, 6895 {"split", 1, 3, f_split}, 6896 #ifdef HAVE_STRFTIME 6897 {"strftime", 1, 2, f_strftime}, 6898 #endif 6899 {"stridx", 2, 3, f_stridx}, 6900 {"string", 1, 1, f_string}, 6901 {"strlen", 1, 1, f_strlen}, 6902 {"strpart", 2, 3, f_strpart}, 6903 {"strridx", 2, 3, f_strridx}, 6904 {"strtrans", 1, 1, f_strtrans}, 6905 {"submatch", 1, 1, f_submatch}, 6906 {"substitute", 4, 4, f_substitute}, 6907 {"synID", 3, 3, f_synID}, 6908 {"synIDattr", 2, 3, f_synIDattr}, 6909 {"synIDtrans", 1, 1, f_synIDtrans}, 6910 {"system", 1, 2, f_system}, 6911 {"tagfiles", 0, 0, f_tagfiles}, 6912 {"taglist", 1, 1, f_taglist}, 6913 {"tempname", 0, 0, f_tempname}, 6914 {"test", 1, 1, f_test}, 6915 {"tolower", 1, 1, f_tolower}, 6916 {"toupper", 1, 1, f_toupper}, 6917 {"tr", 3, 3, f_tr}, 6918 {"type", 1, 1, f_type}, 6919 {"values", 1, 1, f_values}, 6920 {"virtcol", 1, 1, f_virtcol}, 6921 {"visualmode", 0, 1, f_visualmode}, 6922 {"winbufnr", 1, 1, f_winbufnr}, 6923 {"wincol", 0, 0, f_wincol}, 6924 {"winheight", 1, 1, f_winheight}, 6925 {"winline", 0, 0, f_winline}, 6926 {"winnr", 0, 1, f_winnr}, 6927 {"winrestcmd", 0, 0, f_winrestcmd}, 6928 {"winwidth", 1, 1, f_winwidth}, 6929 {"writefile", 2, 3, f_writefile}, 6930 }; 6931 6932 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6933 6934 /* 6935 * Function given to ExpandGeneric() to obtain the list of internal 6936 * or user defined function names. 6937 */ 6938 char_u * 6939 get_function_name(xp, idx) 6940 expand_T *xp; 6941 int idx; 6942 { 6943 static int intidx = -1; 6944 char_u *name; 6945 6946 if (idx == 0) 6947 intidx = -1; 6948 if (intidx < 0) 6949 { 6950 name = get_user_func_name(xp, idx); 6951 if (name != NULL) 6952 return name; 6953 } 6954 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6955 { 6956 STRCPY(IObuff, functions[intidx].f_name); 6957 STRCAT(IObuff, "("); 6958 if (functions[intidx].f_max_argc == 0) 6959 STRCAT(IObuff, ")"); 6960 return IObuff; 6961 } 6962 6963 return NULL; 6964 } 6965 6966 /* 6967 * Function given to ExpandGeneric() to obtain the list of internal or 6968 * user defined variable or function names. 6969 */ 6970 /*ARGSUSED*/ 6971 char_u * 6972 get_expr_name(xp, idx) 6973 expand_T *xp; 6974 int idx; 6975 { 6976 static int intidx = -1; 6977 char_u *name; 6978 6979 if (idx == 0) 6980 intidx = -1; 6981 if (intidx < 0) 6982 { 6983 name = get_function_name(xp, idx); 6984 if (name != NULL) 6985 return name; 6986 } 6987 return get_user_var_name(xp, ++intidx); 6988 } 6989 6990 #endif /* FEAT_CMDL_COMPL */ 6991 6992 /* 6993 * Find internal function in table above. 6994 * Return index, or -1 if not found 6995 */ 6996 static int 6997 find_internal_func(name) 6998 char_u *name; /* name of the function */ 6999 { 7000 int first = 0; 7001 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 7002 int cmp; 7003 int x; 7004 7005 /* 7006 * Find the function name in the table. Binary search. 7007 */ 7008 while (first <= last) 7009 { 7010 x = first + ((unsigned)(last - first) >> 1); 7011 cmp = STRCMP(name, functions[x].f_name); 7012 if (cmp < 0) 7013 last = x - 1; 7014 else if (cmp > 0) 7015 first = x + 1; 7016 else 7017 return x; 7018 } 7019 return -1; 7020 } 7021 7022 /* 7023 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7024 * name it contains, otherwise return "name". 7025 */ 7026 static char_u * 7027 deref_func_name(name, lenp) 7028 char_u *name; 7029 int *lenp; 7030 { 7031 dictitem_T *v; 7032 int cc; 7033 7034 cc = name[*lenp]; 7035 name[*lenp] = NUL; 7036 v = find_var(name, NULL); 7037 name[*lenp] = cc; 7038 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7039 { 7040 if (v->di_tv.vval.v_string == NULL) 7041 { 7042 *lenp = 0; 7043 return (char_u *)""; /* just in case */ 7044 } 7045 *lenp = STRLEN(v->di_tv.vval.v_string); 7046 return v->di_tv.vval.v_string; 7047 } 7048 7049 return name; 7050 } 7051 7052 /* 7053 * Allocate a variable for the result of a function. 7054 * Return OK or FAIL. 7055 */ 7056 static int 7057 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7058 evaluate, selfdict) 7059 char_u *name; /* name of the function */ 7060 int len; /* length of "name" */ 7061 typval_T *rettv; 7062 char_u **arg; /* argument, pointing to the '(' */ 7063 linenr_T firstline; /* first line of range */ 7064 linenr_T lastline; /* last line of range */ 7065 int *doesrange; /* return: function handled range */ 7066 int evaluate; 7067 dict_T *selfdict; /* Dictionary for "self" */ 7068 { 7069 char_u *argp; 7070 int ret = OK; 7071 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7072 int argcount = 0; /* number of arguments found */ 7073 7074 /* 7075 * Get the arguments. 7076 */ 7077 argp = *arg; 7078 while (argcount < MAX_FUNC_ARGS) 7079 { 7080 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7081 if (*argp == ')' || *argp == ',' || *argp == NUL) 7082 break; 7083 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7084 { 7085 ret = FAIL; 7086 break; 7087 } 7088 ++argcount; 7089 if (*argp != ',') 7090 break; 7091 } 7092 if (*argp == ')') 7093 ++argp; 7094 else 7095 ret = FAIL; 7096 7097 if (ret == OK) 7098 ret = call_func(name, len, rettv, argcount, argvars, 7099 firstline, lastline, doesrange, evaluate, selfdict); 7100 else if (!aborting()) 7101 { 7102 if (argcount == MAX_FUNC_ARGS) 7103 emsg_funcname("E740: Too many arguments for function %s", name); 7104 else 7105 emsg_funcname("E116: Invalid arguments for function %s", name); 7106 } 7107 7108 while (--argcount >= 0) 7109 clear_tv(&argvars[argcount]); 7110 7111 *arg = skipwhite(argp); 7112 return ret; 7113 } 7114 7115 7116 /* 7117 * Call a function with its resolved parameters 7118 * Return OK or FAIL. 7119 */ 7120 static int 7121 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7122 doesrange, evaluate, selfdict) 7123 char_u *name; /* name of the function */ 7124 int len; /* length of "name" */ 7125 typval_T *rettv; /* return value goes here */ 7126 int argcount; /* number of "argvars" */ 7127 typval_T *argvars; /* vars for arguments */ 7128 linenr_T firstline; /* first line of range */ 7129 linenr_T lastline; /* last line of range */ 7130 int *doesrange; /* return: function handled range */ 7131 int evaluate; 7132 dict_T *selfdict; /* Dictionary for "self" */ 7133 { 7134 int ret = FAIL; 7135 #define ERROR_UNKNOWN 0 7136 #define ERROR_TOOMANY 1 7137 #define ERROR_TOOFEW 2 7138 #define ERROR_SCRIPT 3 7139 #define ERROR_DICT 4 7140 #define ERROR_NONE 5 7141 #define ERROR_OTHER 6 7142 int error = ERROR_NONE; 7143 int i; 7144 int llen; 7145 ufunc_T *fp; 7146 int cc; 7147 #define FLEN_FIXED 40 7148 char_u fname_buf[FLEN_FIXED + 1]; 7149 char_u *fname; 7150 7151 /* 7152 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7153 * Change <SNR>123_name() to K_SNR 123_name(). 7154 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7155 */ 7156 cc = name[len]; 7157 name[len] = NUL; 7158 llen = eval_fname_script(name); 7159 if (llen > 0) 7160 { 7161 fname_buf[0] = K_SPECIAL; 7162 fname_buf[1] = KS_EXTRA; 7163 fname_buf[2] = (int)KE_SNR; 7164 i = 3; 7165 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7166 { 7167 if (current_SID <= 0) 7168 error = ERROR_SCRIPT; 7169 else 7170 { 7171 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7172 i = (int)STRLEN(fname_buf); 7173 } 7174 } 7175 if (i + STRLEN(name + llen) < FLEN_FIXED) 7176 { 7177 STRCPY(fname_buf + i, name + llen); 7178 fname = fname_buf; 7179 } 7180 else 7181 { 7182 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7183 if (fname == NULL) 7184 error = ERROR_OTHER; 7185 else 7186 { 7187 mch_memmove(fname, fname_buf, (size_t)i); 7188 STRCPY(fname + i, name + llen); 7189 } 7190 } 7191 } 7192 else 7193 fname = name; 7194 7195 *doesrange = FALSE; 7196 7197 7198 /* execute the function if no errors detected and executing */ 7199 if (evaluate && error == ERROR_NONE) 7200 { 7201 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7202 error = ERROR_UNKNOWN; 7203 7204 if (!builtin_function(fname)) 7205 { 7206 /* 7207 * User defined function. 7208 */ 7209 fp = find_func(fname); 7210 7211 #ifdef FEAT_AUTOCMD 7212 /* Trigger FuncUndefined event, may load the function. */ 7213 if (fp == NULL 7214 && apply_autocmds(EVENT_FUNCUNDEFINED, 7215 fname, fname, TRUE, NULL) 7216 && !aborting()) 7217 { 7218 /* executed an autocommand, search for the function again */ 7219 fp = find_func(fname); 7220 } 7221 #endif 7222 /* Try loading a package. */ 7223 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7224 { 7225 /* loaded a package, search for the function again */ 7226 fp = find_func(fname); 7227 } 7228 7229 if (fp != NULL) 7230 { 7231 if (fp->uf_flags & FC_RANGE) 7232 *doesrange = TRUE; 7233 if (argcount < fp->uf_args.ga_len) 7234 error = ERROR_TOOFEW; 7235 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7236 error = ERROR_TOOMANY; 7237 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7238 error = ERROR_DICT; 7239 else 7240 { 7241 /* 7242 * Call the user function. 7243 * Save and restore search patterns, script variables and 7244 * redo buffer. 7245 */ 7246 save_search_patterns(); 7247 saveRedobuff(); 7248 ++fp->uf_calls; 7249 call_user_func(fp, argcount, argvars, rettv, 7250 firstline, lastline, 7251 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7252 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7253 && fp->uf_refcount <= 0) 7254 /* Function was unreferenced while being used, free it 7255 * now. */ 7256 func_free(fp); 7257 restoreRedobuff(); 7258 restore_search_patterns(); 7259 error = ERROR_NONE; 7260 } 7261 } 7262 } 7263 else 7264 { 7265 /* 7266 * Find the function name in the table, call its implementation. 7267 */ 7268 i = find_internal_func(fname); 7269 if (i >= 0) 7270 { 7271 if (argcount < functions[i].f_min_argc) 7272 error = ERROR_TOOFEW; 7273 else if (argcount > functions[i].f_max_argc) 7274 error = ERROR_TOOMANY; 7275 else 7276 { 7277 argvars[argcount].v_type = VAR_UNKNOWN; 7278 functions[i].f_func(argvars, rettv); 7279 error = ERROR_NONE; 7280 } 7281 } 7282 } 7283 /* 7284 * The function call (or "FuncUndefined" autocommand sequence) might 7285 * have been aborted by an error, an interrupt, or an explicitly thrown 7286 * exception that has not been caught so far. This situation can be 7287 * tested for by calling aborting(). For an error in an internal 7288 * function or for the "E132" error in call_user_func(), however, the 7289 * throw point at which the "force_abort" flag (temporarily reset by 7290 * emsg()) is normally updated has not been reached yet. We need to 7291 * update that flag first to make aborting() reliable. 7292 */ 7293 update_force_abort(); 7294 } 7295 if (error == ERROR_NONE) 7296 ret = OK; 7297 7298 /* 7299 * Report an error unless the argument evaluation or function call has been 7300 * cancelled due to an aborting error, an interrupt, or an exception. 7301 */ 7302 if (!aborting()) 7303 { 7304 switch (error) 7305 { 7306 case ERROR_UNKNOWN: 7307 emsg_funcname("E117: Unknown function: %s", name); 7308 break; 7309 case ERROR_TOOMANY: 7310 emsg_funcname(e_toomanyarg, name); 7311 break; 7312 case ERROR_TOOFEW: 7313 emsg_funcname("E119: Not enough arguments for function: %s", 7314 name); 7315 break; 7316 case ERROR_SCRIPT: 7317 emsg_funcname("E120: Using <SID> not in a script context: %s", 7318 name); 7319 break; 7320 case ERROR_DICT: 7321 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7322 name); 7323 break; 7324 } 7325 } 7326 7327 name[len] = cc; 7328 if (fname != name && fname != fname_buf) 7329 vim_free(fname); 7330 7331 return ret; 7332 } 7333 7334 /* 7335 * Give an error message with a function name. Handle <SNR> things. 7336 */ 7337 static void 7338 emsg_funcname(msg, name) 7339 char *msg; 7340 char_u *name; 7341 { 7342 char_u *p; 7343 7344 if (*name == K_SPECIAL) 7345 p = concat_str((char_u *)"<SNR>", name + 3); 7346 else 7347 p = name; 7348 EMSG2(_(msg), p); 7349 if (p != name) 7350 vim_free(p); 7351 } 7352 7353 /********************************************* 7354 * Implementation of the built-in functions 7355 */ 7356 7357 /* 7358 * "add(list, item)" function 7359 */ 7360 static void 7361 f_add(argvars, rettv) 7362 typval_T *argvars; 7363 typval_T *rettv; 7364 { 7365 list_T *l; 7366 7367 rettv->vval.v_number = 1; /* Default: Failed */ 7368 if (argvars[0].v_type == VAR_LIST) 7369 { 7370 if ((l = argvars[0].vval.v_list) != NULL 7371 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7372 && list_append_tv(l, &argvars[1]) == OK) 7373 copy_tv(&argvars[0], rettv); 7374 } 7375 else 7376 EMSG(_(e_listreq)); 7377 } 7378 7379 /* 7380 * "append(lnum, string/list)" function 7381 */ 7382 static void 7383 f_append(argvars, rettv) 7384 typval_T *argvars; 7385 typval_T *rettv; 7386 { 7387 long lnum; 7388 char_u *line; 7389 list_T *l = NULL; 7390 listitem_T *li = NULL; 7391 typval_T *tv; 7392 long added = 0; 7393 7394 lnum = get_tv_lnum(argvars); 7395 if (lnum >= 0 7396 && lnum <= curbuf->b_ml.ml_line_count 7397 && u_save(lnum, lnum + 1) == OK) 7398 { 7399 if (argvars[1].v_type == VAR_LIST) 7400 { 7401 l = argvars[1].vval.v_list; 7402 if (l == NULL) 7403 return; 7404 li = l->lv_first; 7405 } 7406 rettv->vval.v_number = 0; /* Default: Success */ 7407 for (;;) 7408 { 7409 if (l == NULL) 7410 tv = &argvars[1]; /* append a string */ 7411 else if (li == NULL) 7412 break; /* end of list */ 7413 else 7414 tv = &li->li_tv; /* append item from list */ 7415 line = get_tv_string_chk(tv); 7416 if (line == NULL) /* type error */ 7417 { 7418 rettv->vval.v_number = 1; /* Failed */ 7419 break; 7420 } 7421 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7422 ++added; 7423 if (l == NULL) 7424 break; 7425 li = li->li_next; 7426 } 7427 7428 appended_lines_mark(lnum, added); 7429 if (curwin->w_cursor.lnum > lnum) 7430 curwin->w_cursor.lnum += added; 7431 } 7432 else 7433 rettv->vval.v_number = 1; /* Failed */ 7434 } 7435 7436 /* 7437 * "argc()" function 7438 */ 7439 /* ARGSUSED */ 7440 static void 7441 f_argc(argvars, rettv) 7442 typval_T *argvars; 7443 typval_T *rettv; 7444 { 7445 rettv->vval.v_number = ARGCOUNT; 7446 } 7447 7448 /* 7449 * "argidx()" function 7450 */ 7451 /* ARGSUSED */ 7452 static void 7453 f_argidx(argvars, rettv) 7454 typval_T *argvars; 7455 typval_T *rettv; 7456 { 7457 rettv->vval.v_number = curwin->w_arg_idx; 7458 } 7459 7460 /* 7461 * "argv(nr)" function 7462 */ 7463 static void 7464 f_argv(argvars, rettv) 7465 typval_T *argvars; 7466 typval_T *rettv; 7467 { 7468 int idx; 7469 7470 idx = get_tv_number_chk(&argvars[0], NULL); 7471 if (idx >= 0 && idx < ARGCOUNT) 7472 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7473 else 7474 rettv->vval.v_string = NULL; 7475 rettv->v_type = VAR_STRING; 7476 } 7477 7478 /* 7479 * "browse(save, title, initdir, default)" function 7480 */ 7481 /* ARGSUSED */ 7482 static void 7483 f_browse(argvars, rettv) 7484 typval_T *argvars; 7485 typval_T *rettv; 7486 { 7487 #ifdef FEAT_BROWSE 7488 int save; 7489 char_u *title; 7490 char_u *initdir; 7491 char_u *defname; 7492 char_u buf[NUMBUFLEN]; 7493 char_u buf2[NUMBUFLEN]; 7494 int error = FALSE; 7495 7496 save = get_tv_number_chk(&argvars[0], &error); 7497 title = get_tv_string_chk(&argvars[1]); 7498 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7499 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7500 7501 if (error || title == NULL || initdir == NULL || defname == NULL) 7502 rettv->vval.v_string = NULL; 7503 else 7504 rettv->vval.v_string = 7505 do_browse(save ? BROWSE_SAVE : 0, 7506 title, defname, NULL, initdir, NULL, curbuf); 7507 #else 7508 rettv->vval.v_string = NULL; 7509 #endif 7510 rettv->v_type = VAR_STRING; 7511 } 7512 7513 /* 7514 * "browsedir(title, initdir)" function 7515 */ 7516 /* ARGSUSED */ 7517 static void 7518 f_browsedir(argvars, rettv) 7519 typval_T *argvars; 7520 typval_T *rettv; 7521 { 7522 #ifdef FEAT_BROWSE 7523 char_u *title; 7524 char_u *initdir; 7525 char_u buf[NUMBUFLEN]; 7526 7527 title = get_tv_string_chk(&argvars[0]); 7528 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7529 7530 if (title == NULL || initdir == NULL) 7531 rettv->vval.v_string = NULL; 7532 else 7533 rettv->vval.v_string = do_browse(BROWSE_DIR, 7534 title, NULL, NULL, initdir, NULL, curbuf); 7535 #else 7536 rettv->vval.v_string = NULL; 7537 #endif 7538 rettv->v_type = VAR_STRING; 7539 } 7540 7541 static buf_T *find_buffer __ARGS((typval_T *avar)); 7542 7543 /* 7544 * Find a buffer by number or exact name. 7545 */ 7546 static buf_T * 7547 find_buffer(avar) 7548 typval_T *avar; 7549 { 7550 buf_T *buf = NULL; 7551 7552 if (avar->v_type == VAR_NUMBER) 7553 buf = buflist_findnr((int)avar->vval.v_number); 7554 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7555 { 7556 buf = buflist_findname_exp(avar->vval.v_string); 7557 if (buf == NULL) 7558 { 7559 /* No full path name match, try a match with a URL or a "nofile" 7560 * buffer, these don't use the full path. */ 7561 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7562 if (buf->b_fname != NULL 7563 && (path_with_url(buf->b_fname) 7564 #ifdef FEAT_QUICKFIX 7565 || bt_nofile(buf) 7566 #endif 7567 ) 7568 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7569 break; 7570 } 7571 } 7572 return buf; 7573 } 7574 7575 /* 7576 * "bufexists(expr)" function 7577 */ 7578 static void 7579 f_bufexists(argvars, rettv) 7580 typval_T *argvars; 7581 typval_T *rettv; 7582 { 7583 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7584 } 7585 7586 /* 7587 * "buflisted(expr)" function 7588 */ 7589 static void 7590 f_buflisted(argvars, rettv) 7591 typval_T *argvars; 7592 typval_T *rettv; 7593 { 7594 buf_T *buf; 7595 7596 buf = find_buffer(&argvars[0]); 7597 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7598 } 7599 7600 /* 7601 * "bufloaded(expr)" function 7602 */ 7603 static void 7604 f_bufloaded(argvars, rettv) 7605 typval_T *argvars; 7606 typval_T *rettv; 7607 { 7608 buf_T *buf; 7609 7610 buf = find_buffer(&argvars[0]); 7611 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7612 } 7613 7614 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7615 7616 /* 7617 * Get buffer by number or pattern. 7618 */ 7619 static buf_T * 7620 get_buf_tv(tv) 7621 typval_T *tv; 7622 { 7623 char_u *name = tv->vval.v_string; 7624 int save_magic; 7625 char_u *save_cpo; 7626 buf_T *buf; 7627 7628 if (tv->v_type == VAR_NUMBER) 7629 return buflist_findnr((int)tv->vval.v_number); 7630 if (tv->v_type != VAR_STRING) 7631 return NULL; 7632 if (name == NULL || *name == NUL) 7633 return curbuf; 7634 if (name[0] == '$' && name[1] == NUL) 7635 return lastbuf; 7636 7637 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7638 save_magic = p_magic; 7639 p_magic = TRUE; 7640 save_cpo = p_cpo; 7641 p_cpo = (char_u *)""; 7642 7643 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7644 TRUE, FALSE)); 7645 7646 p_magic = save_magic; 7647 p_cpo = save_cpo; 7648 7649 /* If not found, try expanding the name, like done for bufexists(). */ 7650 if (buf == NULL) 7651 buf = find_buffer(tv); 7652 7653 return buf; 7654 } 7655 7656 /* 7657 * "bufname(expr)" function 7658 */ 7659 static void 7660 f_bufname(argvars, rettv) 7661 typval_T *argvars; 7662 typval_T *rettv; 7663 { 7664 buf_T *buf; 7665 7666 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7667 ++emsg_off; 7668 buf = get_buf_tv(&argvars[0]); 7669 rettv->v_type = VAR_STRING; 7670 if (buf != NULL && buf->b_fname != NULL) 7671 rettv->vval.v_string = vim_strsave(buf->b_fname); 7672 else 7673 rettv->vval.v_string = NULL; 7674 --emsg_off; 7675 } 7676 7677 /* 7678 * "bufnr(expr)" function 7679 */ 7680 static void 7681 f_bufnr(argvars, rettv) 7682 typval_T *argvars; 7683 typval_T *rettv; 7684 { 7685 buf_T *buf; 7686 7687 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7688 ++emsg_off; 7689 buf = get_buf_tv(&argvars[0]); 7690 if (buf != NULL) 7691 rettv->vval.v_number = buf->b_fnum; 7692 else 7693 rettv->vval.v_number = -1; 7694 --emsg_off; 7695 } 7696 7697 /* 7698 * "bufwinnr(nr)" function 7699 */ 7700 static void 7701 f_bufwinnr(argvars, rettv) 7702 typval_T *argvars; 7703 typval_T *rettv; 7704 { 7705 #ifdef FEAT_WINDOWS 7706 win_T *wp; 7707 int winnr = 0; 7708 #endif 7709 buf_T *buf; 7710 7711 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7712 ++emsg_off; 7713 buf = get_buf_tv(&argvars[0]); 7714 #ifdef FEAT_WINDOWS 7715 for (wp = firstwin; wp; wp = wp->w_next) 7716 { 7717 ++winnr; 7718 if (wp->w_buffer == buf) 7719 break; 7720 } 7721 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7722 #else 7723 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7724 #endif 7725 --emsg_off; 7726 } 7727 7728 /* 7729 * "byte2line(byte)" function 7730 */ 7731 /*ARGSUSED*/ 7732 static void 7733 f_byte2line(argvars, rettv) 7734 typval_T *argvars; 7735 typval_T *rettv; 7736 { 7737 #ifndef FEAT_BYTEOFF 7738 rettv->vval.v_number = -1; 7739 #else 7740 long boff = 0; 7741 7742 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7743 if (boff < 0) 7744 rettv->vval.v_number = -1; 7745 else 7746 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7747 (linenr_T)0, &boff); 7748 #endif 7749 } 7750 7751 /* 7752 * "byteidx()" function 7753 */ 7754 /*ARGSUSED*/ 7755 static void 7756 f_byteidx(argvars, rettv) 7757 typval_T *argvars; 7758 typval_T *rettv; 7759 { 7760 #ifdef FEAT_MBYTE 7761 char_u *t; 7762 #endif 7763 char_u *str; 7764 long idx; 7765 7766 str = get_tv_string_chk(&argvars[0]); 7767 idx = get_tv_number_chk(&argvars[1], NULL); 7768 rettv->vval.v_number = -1; 7769 if (str == NULL || idx < 0) 7770 return; 7771 7772 #ifdef FEAT_MBYTE 7773 t = str; 7774 for ( ; idx > 0; idx--) 7775 { 7776 if (*t == NUL) /* EOL reached */ 7777 return; 7778 t += (*mb_ptr2len)(t); 7779 } 7780 rettv->vval.v_number = t - str; 7781 #else 7782 if (idx <= STRLEN(str)) 7783 rettv->vval.v_number = idx; 7784 #endif 7785 } 7786 7787 /* 7788 * "call(func, arglist)" function 7789 */ 7790 static void 7791 f_call(argvars, rettv) 7792 typval_T *argvars; 7793 typval_T *rettv; 7794 { 7795 char_u *func; 7796 typval_T argv[MAX_FUNC_ARGS]; 7797 int argc = 0; 7798 listitem_T *item; 7799 int dummy; 7800 dict_T *selfdict = NULL; 7801 7802 rettv->vval.v_number = 0; 7803 if (argvars[1].v_type != VAR_LIST) 7804 { 7805 EMSG(_(e_listreq)); 7806 return; 7807 } 7808 if (argvars[1].vval.v_list == NULL) 7809 return; 7810 7811 if (argvars[0].v_type == VAR_FUNC) 7812 func = argvars[0].vval.v_string; 7813 else 7814 func = get_tv_string(&argvars[0]); 7815 if (*func == NUL) 7816 return; /* type error or empty name */ 7817 7818 if (argvars[2].v_type != VAR_UNKNOWN) 7819 { 7820 if (argvars[2].v_type != VAR_DICT) 7821 { 7822 EMSG(_(e_dictreq)); 7823 return; 7824 } 7825 selfdict = argvars[2].vval.v_dict; 7826 } 7827 7828 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7829 item = item->li_next) 7830 { 7831 if (argc == MAX_FUNC_ARGS) 7832 { 7833 EMSG(_("E699: Too many arguments")); 7834 break; 7835 } 7836 /* Make a copy of each argument. This is needed to be able to set 7837 * v_lock to VAR_FIXED in the copy without changing the original list. 7838 */ 7839 copy_tv(&item->li_tv, &argv[argc++]); 7840 } 7841 7842 if (item == NULL) 7843 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7844 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7845 &dummy, TRUE, selfdict); 7846 7847 /* Free the arguments. */ 7848 while (argc > 0) 7849 clear_tv(&argv[--argc]); 7850 } 7851 7852 /* 7853 * "char2nr(string)" function 7854 */ 7855 static void 7856 f_char2nr(argvars, rettv) 7857 typval_T *argvars; 7858 typval_T *rettv; 7859 { 7860 #ifdef FEAT_MBYTE 7861 if (has_mbyte) 7862 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7863 else 7864 #endif 7865 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7866 } 7867 7868 /* 7869 * "cindent(lnum)" function 7870 */ 7871 static void 7872 f_cindent(argvars, rettv) 7873 typval_T *argvars; 7874 typval_T *rettv; 7875 { 7876 #ifdef FEAT_CINDENT 7877 pos_T pos; 7878 linenr_T lnum; 7879 7880 pos = curwin->w_cursor; 7881 lnum = get_tv_lnum(argvars); 7882 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7883 { 7884 curwin->w_cursor.lnum = lnum; 7885 rettv->vval.v_number = get_c_indent(); 7886 curwin->w_cursor = pos; 7887 } 7888 else 7889 #endif 7890 rettv->vval.v_number = -1; 7891 } 7892 7893 /* 7894 * "col(string)" function 7895 */ 7896 static void 7897 f_col(argvars, rettv) 7898 typval_T *argvars; 7899 typval_T *rettv; 7900 { 7901 colnr_T col = 0; 7902 pos_T *fp; 7903 7904 fp = var2fpos(&argvars[0], FALSE); 7905 if (fp != NULL) 7906 { 7907 if (fp->col == MAXCOL) 7908 { 7909 /* '> can be MAXCOL, get the length of the line then */ 7910 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7911 col = STRLEN(ml_get(fp->lnum)) + 1; 7912 else 7913 col = MAXCOL; 7914 } 7915 else 7916 { 7917 col = fp->col + 1; 7918 #ifdef FEAT_VIRTUALEDIT 7919 /* col(".") when the cursor is on the NUL at the end of the line 7920 * because of "coladd" can be seen as an extra column. */ 7921 if (virtual_active() && fp == &curwin->w_cursor) 7922 { 7923 char_u *p = ml_get_cursor(); 7924 7925 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7926 curwin->w_virtcol - curwin->w_cursor.coladd)) 7927 { 7928 # ifdef FEAT_MBYTE 7929 int l; 7930 7931 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 7932 col += l; 7933 # else 7934 if (*p != NUL && p[1] == NUL) 7935 ++col; 7936 # endif 7937 } 7938 } 7939 #endif 7940 } 7941 } 7942 rettv->vval.v_number = col; 7943 } 7944 7945 #if defined(FEAT_INS_EXPAND) 7946 /* 7947 * "complete_add()" function 7948 */ 7949 /*ARGSUSED*/ 7950 static void 7951 f_complete_add(argvars, rettv) 7952 typval_T *argvars; 7953 typval_T *rettv; 7954 { 7955 char_u *s; 7956 7957 s = get_tv_string_chk(&argvars[0]); 7958 if (s != NULL) 7959 rettv->vval.v_number = ins_compl_add(s, -1, NULL, FORWARD, 0); 7960 } 7961 7962 /* 7963 * "complete_check()" function 7964 */ 7965 /*ARGSUSED*/ 7966 static void 7967 f_complete_check(argvars, rettv) 7968 typval_T *argvars; 7969 typval_T *rettv; 7970 { 7971 int saved = RedrawingDisabled; 7972 7973 RedrawingDisabled = 0; 7974 ins_compl_check_keys(0); 7975 rettv->vval.v_number = compl_interrupted; 7976 RedrawingDisabled = saved; 7977 } 7978 #endif 7979 7980 /* 7981 * "confirm(message, buttons[, default [, type]])" function 7982 */ 7983 /*ARGSUSED*/ 7984 static void 7985 f_confirm(argvars, rettv) 7986 typval_T *argvars; 7987 typval_T *rettv; 7988 { 7989 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7990 char_u *message; 7991 char_u *buttons = NULL; 7992 char_u buf[NUMBUFLEN]; 7993 char_u buf2[NUMBUFLEN]; 7994 int def = 1; 7995 int type = VIM_GENERIC; 7996 char_u *typestr; 7997 int error = FALSE; 7998 7999 message = get_tv_string_chk(&argvars[0]); 8000 if (message == NULL) 8001 error = TRUE; 8002 if (argvars[1].v_type != VAR_UNKNOWN) 8003 { 8004 buttons = get_tv_string_buf_chk(&argvars[1], buf); 8005 if (buttons == NULL) 8006 error = TRUE; 8007 if (argvars[2].v_type != VAR_UNKNOWN) 8008 { 8009 def = get_tv_number_chk(&argvars[2], &error); 8010 if (argvars[3].v_type != VAR_UNKNOWN) 8011 { 8012 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 8013 if (typestr == NULL) 8014 error = TRUE; 8015 else 8016 { 8017 switch (TOUPPER_ASC(*typestr)) 8018 { 8019 case 'E': type = VIM_ERROR; break; 8020 case 'Q': type = VIM_QUESTION; break; 8021 case 'I': type = VIM_INFO; break; 8022 case 'W': type = VIM_WARNING; break; 8023 case 'G': type = VIM_GENERIC; break; 8024 } 8025 } 8026 } 8027 } 8028 } 8029 8030 if (buttons == NULL || *buttons == NUL) 8031 buttons = (char_u *)_("&Ok"); 8032 8033 if (error) 8034 rettv->vval.v_number = 0; 8035 else 8036 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8037 def, NULL); 8038 #else 8039 rettv->vval.v_number = 0; 8040 #endif 8041 } 8042 8043 /* 8044 * "copy()" function 8045 */ 8046 static void 8047 f_copy(argvars, rettv) 8048 typval_T *argvars; 8049 typval_T *rettv; 8050 { 8051 item_copy(&argvars[0], rettv, FALSE, 0); 8052 } 8053 8054 /* 8055 * "count()" function 8056 */ 8057 static void 8058 f_count(argvars, rettv) 8059 typval_T *argvars; 8060 typval_T *rettv; 8061 { 8062 long n = 0; 8063 int ic = FALSE; 8064 8065 if (argvars[0].v_type == VAR_LIST) 8066 { 8067 listitem_T *li; 8068 list_T *l; 8069 long idx; 8070 8071 if ((l = argvars[0].vval.v_list) != NULL) 8072 { 8073 li = l->lv_first; 8074 if (argvars[2].v_type != VAR_UNKNOWN) 8075 { 8076 int error = FALSE; 8077 8078 ic = get_tv_number_chk(&argvars[2], &error); 8079 if (argvars[3].v_type != VAR_UNKNOWN) 8080 { 8081 idx = get_tv_number_chk(&argvars[3], &error); 8082 if (!error) 8083 { 8084 li = list_find(l, idx); 8085 if (li == NULL) 8086 EMSGN(_(e_listidx), idx); 8087 } 8088 } 8089 if (error) 8090 li = NULL; 8091 } 8092 8093 for ( ; li != NULL; li = li->li_next) 8094 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8095 ++n; 8096 } 8097 } 8098 else if (argvars[0].v_type == VAR_DICT) 8099 { 8100 int todo; 8101 dict_T *d; 8102 hashitem_T *hi; 8103 8104 if ((d = argvars[0].vval.v_dict) != NULL) 8105 { 8106 int error = FALSE; 8107 8108 if (argvars[2].v_type != VAR_UNKNOWN) 8109 { 8110 ic = get_tv_number_chk(&argvars[2], &error); 8111 if (argvars[3].v_type != VAR_UNKNOWN) 8112 EMSG(_(e_invarg)); 8113 } 8114 8115 todo = error ? 0 : d->dv_hashtab.ht_used; 8116 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8117 { 8118 if (!HASHITEM_EMPTY(hi)) 8119 { 8120 --todo; 8121 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8122 ++n; 8123 } 8124 } 8125 } 8126 } 8127 else 8128 EMSG2(_(e_listdictarg), "count()"); 8129 rettv->vval.v_number = n; 8130 } 8131 8132 /* 8133 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8134 * 8135 * Checks the existence of a cscope connection. 8136 */ 8137 /*ARGSUSED*/ 8138 static void 8139 f_cscope_connection(argvars, rettv) 8140 typval_T *argvars; 8141 typval_T *rettv; 8142 { 8143 #ifdef FEAT_CSCOPE 8144 int num = 0; 8145 char_u *dbpath = NULL; 8146 char_u *prepend = NULL; 8147 char_u buf[NUMBUFLEN]; 8148 8149 if (argvars[0].v_type != VAR_UNKNOWN 8150 && argvars[1].v_type != VAR_UNKNOWN) 8151 { 8152 num = (int)get_tv_number(&argvars[0]); 8153 dbpath = get_tv_string(&argvars[1]); 8154 if (argvars[2].v_type != VAR_UNKNOWN) 8155 prepend = get_tv_string_buf(&argvars[2], buf); 8156 } 8157 8158 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8159 #else 8160 rettv->vval.v_number = 0; 8161 #endif 8162 } 8163 8164 /* 8165 * "cursor(lnum, col)" function 8166 * 8167 * Moves the cursor to the specified line and column 8168 */ 8169 /*ARGSUSED*/ 8170 static void 8171 f_cursor(argvars, rettv) 8172 typval_T *argvars; 8173 typval_T *rettv; 8174 { 8175 long line, col; 8176 8177 line = get_tv_lnum(argvars); 8178 col = get_tv_number_chk(&argvars[1], NULL); 8179 if (line < 0 || col < 0) 8180 return; /* type error; errmsg already given */ 8181 if (line > 0) 8182 curwin->w_cursor.lnum = line; 8183 if (col > 0) 8184 curwin->w_cursor.col = col - 1; 8185 #ifdef FEAT_VIRTUALEDIT 8186 curwin->w_cursor.coladd = 0; 8187 #endif 8188 8189 /* Make sure the cursor is in a valid position. */ 8190 check_cursor(); 8191 #ifdef FEAT_MBYTE 8192 /* Correct cursor for multi-byte character. */ 8193 if (has_mbyte) 8194 mb_adjust_cursor(); 8195 #endif 8196 8197 curwin->w_set_curswant = TRUE; 8198 } 8199 8200 /* 8201 * "deepcopy()" function 8202 */ 8203 static void 8204 f_deepcopy(argvars, rettv) 8205 typval_T *argvars; 8206 typval_T *rettv; 8207 { 8208 int noref = 0; 8209 8210 if (argvars[1].v_type != VAR_UNKNOWN) 8211 noref = get_tv_number_chk(&argvars[1], NULL); 8212 if (noref < 0 || noref > 1) 8213 EMSG(_(e_invarg)); 8214 else 8215 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8216 } 8217 8218 /* 8219 * "delete()" function 8220 */ 8221 static void 8222 f_delete(argvars, rettv) 8223 typval_T *argvars; 8224 typval_T *rettv; 8225 { 8226 if (check_restricted() || check_secure()) 8227 rettv->vval.v_number = -1; 8228 else 8229 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8230 } 8231 8232 /* 8233 * "did_filetype()" function 8234 */ 8235 /*ARGSUSED*/ 8236 static void 8237 f_did_filetype(argvars, rettv) 8238 typval_T *argvars; 8239 typval_T *rettv; 8240 { 8241 #ifdef FEAT_AUTOCMD 8242 rettv->vval.v_number = did_filetype; 8243 #else 8244 rettv->vval.v_number = 0; 8245 #endif 8246 } 8247 8248 /* 8249 * "diff_filler()" function 8250 */ 8251 /*ARGSUSED*/ 8252 static void 8253 f_diff_filler(argvars, rettv) 8254 typval_T *argvars; 8255 typval_T *rettv; 8256 { 8257 #ifdef FEAT_DIFF 8258 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8259 #endif 8260 } 8261 8262 /* 8263 * "diff_hlID()" function 8264 */ 8265 /*ARGSUSED*/ 8266 static void 8267 f_diff_hlID(argvars, rettv) 8268 typval_T *argvars; 8269 typval_T *rettv; 8270 { 8271 #ifdef FEAT_DIFF 8272 linenr_T lnum = get_tv_lnum(argvars); 8273 static linenr_T prev_lnum = 0; 8274 static int changedtick = 0; 8275 static int fnum = 0; 8276 static int change_start = 0; 8277 static int change_end = 0; 8278 static hlf_T hlID = 0; 8279 int filler_lines; 8280 int col; 8281 8282 if (lnum < 0) /* ignore type error in {lnum} arg */ 8283 lnum = 0; 8284 if (lnum != prev_lnum 8285 || changedtick != curbuf->b_changedtick 8286 || fnum != curbuf->b_fnum) 8287 { 8288 /* New line, buffer, change: need to get the values. */ 8289 filler_lines = diff_check(curwin, lnum); 8290 if (filler_lines < 0) 8291 { 8292 if (filler_lines == -1) 8293 { 8294 change_start = MAXCOL; 8295 change_end = -1; 8296 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8297 hlID = HLF_ADD; /* added line */ 8298 else 8299 hlID = HLF_CHD; /* changed line */ 8300 } 8301 else 8302 hlID = HLF_ADD; /* added line */ 8303 } 8304 else 8305 hlID = (hlf_T)0; 8306 prev_lnum = lnum; 8307 changedtick = curbuf->b_changedtick; 8308 fnum = curbuf->b_fnum; 8309 } 8310 8311 if (hlID == HLF_CHD || hlID == HLF_TXD) 8312 { 8313 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8314 if (col >= change_start && col <= change_end) 8315 hlID = HLF_TXD; /* changed text */ 8316 else 8317 hlID = HLF_CHD; /* changed line */ 8318 } 8319 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 8320 #endif 8321 } 8322 8323 /* 8324 * "empty({expr})" function 8325 */ 8326 static void 8327 f_empty(argvars, rettv) 8328 typval_T *argvars; 8329 typval_T *rettv; 8330 { 8331 int n; 8332 8333 switch (argvars[0].v_type) 8334 { 8335 case VAR_STRING: 8336 case VAR_FUNC: 8337 n = argvars[0].vval.v_string == NULL 8338 || *argvars[0].vval.v_string == NUL; 8339 break; 8340 case VAR_NUMBER: 8341 n = argvars[0].vval.v_number == 0; 8342 break; 8343 case VAR_LIST: 8344 n = argvars[0].vval.v_list == NULL 8345 || argvars[0].vval.v_list->lv_first == NULL; 8346 break; 8347 case VAR_DICT: 8348 n = argvars[0].vval.v_dict == NULL 8349 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8350 break; 8351 default: 8352 EMSG2(_(e_intern2), "f_empty()"); 8353 n = 0; 8354 } 8355 8356 rettv->vval.v_number = n; 8357 } 8358 8359 /* 8360 * "escape({string}, {chars})" function 8361 */ 8362 static void 8363 f_escape(argvars, rettv) 8364 typval_T *argvars; 8365 typval_T *rettv; 8366 { 8367 char_u buf[NUMBUFLEN]; 8368 8369 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8370 get_tv_string_buf(&argvars[1], buf)); 8371 rettv->v_type = VAR_STRING; 8372 } 8373 8374 /* 8375 * "eval()" function 8376 */ 8377 /*ARGSUSED*/ 8378 static void 8379 f_eval(argvars, rettv) 8380 typval_T *argvars; 8381 typval_T *rettv; 8382 { 8383 char_u *s; 8384 8385 s = get_tv_string_chk(&argvars[0]); 8386 if (s != NULL) 8387 s = skipwhite(s); 8388 8389 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8390 { 8391 rettv->v_type = VAR_NUMBER; 8392 rettv->vval.v_number = 0; 8393 } 8394 else if (*s != NUL) 8395 EMSG(_(e_trailing)); 8396 } 8397 8398 /* 8399 * "eventhandler()" function 8400 */ 8401 /*ARGSUSED*/ 8402 static void 8403 f_eventhandler(argvars, rettv) 8404 typval_T *argvars; 8405 typval_T *rettv; 8406 { 8407 rettv->vval.v_number = vgetc_busy; 8408 } 8409 8410 /* 8411 * "executable()" function 8412 */ 8413 static void 8414 f_executable(argvars, rettv) 8415 typval_T *argvars; 8416 typval_T *rettv; 8417 { 8418 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8419 } 8420 8421 /* 8422 * "exists()" function 8423 */ 8424 static void 8425 f_exists(argvars, rettv) 8426 typval_T *argvars; 8427 typval_T *rettv; 8428 { 8429 char_u *p; 8430 char_u *name; 8431 int n = FALSE; 8432 int len = 0; 8433 8434 p = get_tv_string(&argvars[0]); 8435 if (*p == '$') /* environment variable */ 8436 { 8437 /* first try "normal" environment variables (fast) */ 8438 if (mch_getenv(p + 1) != NULL) 8439 n = TRUE; 8440 else 8441 { 8442 /* try expanding things like $VIM and ${HOME} */ 8443 p = expand_env_save(p); 8444 if (p != NULL && *p != '$') 8445 n = TRUE; 8446 vim_free(p); 8447 } 8448 } 8449 else if (*p == '&' || *p == '+') /* option */ 8450 n = (get_option_tv(&p, NULL, TRUE) == OK); 8451 else if (*p == '*') /* internal or user defined function */ 8452 { 8453 n = function_exists(p + 1); 8454 } 8455 else if (*p == ':') 8456 { 8457 n = cmd_exists(p + 1); 8458 } 8459 else if (*p == '#') 8460 { 8461 #ifdef FEAT_AUTOCMD 8462 if (p[1] == '#') 8463 n = autocmd_supported(p + 2); 8464 else 8465 n = au_exists(p + 1); 8466 #endif 8467 } 8468 else /* internal variable */ 8469 { 8470 char_u *tofree; 8471 typval_T tv; 8472 8473 /* get_name_len() takes care of expanding curly braces */ 8474 name = p; 8475 len = get_name_len(&p, &tofree, TRUE, FALSE); 8476 if (len > 0) 8477 { 8478 if (tofree != NULL) 8479 name = tofree; 8480 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8481 if (n) 8482 { 8483 /* handle d.key, l[idx], f(expr) */ 8484 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8485 if (n) 8486 clear_tv(&tv); 8487 } 8488 } 8489 8490 vim_free(tofree); 8491 } 8492 8493 rettv->vval.v_number = n; 8494 } 8495 8496 /* 8497 * "expand()" function 8498 */ 8499 static void 8500 f_expand(argvars, rettv) 8501 typval_T *argvars; 8502 typval_T *rettv; 8503 { 8504 char_u *s; 8505 int len; 8506 char_u *errormsg; 8507 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8508 expand_T xpc; 8509 int error = FALSE; 8510 8511 rettv->v_type = VAR_STRING; 8512 s = get_tv_string(&argvars[0]); 8513 if (*s == '%' || *s == '#' || *s == '<') 8514 { 8515 ++emsg_off; 8516 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8517 --emsg_off; 8518 } 8519 else 8520 { 8521 /* When the optional second argument is non-zero, don't remove matches 8522 * for 'suffixes' and 'wildignore' */ 8523 if (argvars[1].v_type != VAR_UNKNOWN 8524 && get_tv_number_chk(&argvars[1], &error)) 8525 flags |= WILD_KEEP_ALL; 8526 if (!error) 8527 { 8528 ExpandInit(&xpc); 8529 xpc.xp_context = EXPAND_FILES; 8530 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8531 ExpandCleanup(&xpc); 8532 } 8533 else 8534 rettv->vval.v_string = NULL; 8535 } 8536 } 8537 8538 /* 8539 * "extend(list, list [, idx])" function 8540 * "extend(dict, dict [, action])" function 8541 */ 8542 static void 8543 f_extend(argvars, rettv) 8544 typval_T *argvars; 8545 typval_T *rettv; 8546 { 8547 rettv->vval.v_number = 0; 8548 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8549 { 8550 list_T *l1, *l2; 8551 listitem_T *item; 8552 long before; 8553 int error = FALSE; 8554 8555 l1 = argvars[0].vval.v_list; 8556 l2 = argvars[1].vval.v_list; 8557 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8558 && l2 != NULL) 8559 { 8560 if (argvars[2].v_type != VAR_UNKNOWN) 8561 { 8562 before = get_tv_number_chk(&argvars[2], &error); 8563 if (error) 8564 return; /* type error; errmsg already given */ 8565 8566 if (before == l1->lv_len) 8567 item = NULL; 8568 else 8569 { 8570 item = list_find(l1, before); 8571 if (item == NULL) 8572 { 8573 EMSGN(_(e_listidx), before); 8574 return; 8575 } 8576 } 8577 } 8578 else 8579 item = NULL; 8580 list_extend(l1, l2, item); 8581 8582 copy_tv(&argvars[0], rettv); 8583 } 8584 } 8585 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8586 { 8587 dict_T *d1, *d2; 8588 dictitem_T *di1; 8589 char_u *action; 8590 int i; 8591 hashitem_T *hi2; 8592 int todo; 8593 8594 d1 = argvars[0].vval.v_dict; 8595 d2 = argvars[1].vval.v_dict; 8596 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8597 && d2 != NULL) 8598 { 8599 /* Check the third argument. */ 8600 if (argvars[2].v_type != VAR_UNKNOWN) 8601 { 8602 static char *(av[]) = {"keep", "force", "error"}; 8603 8604 action = get_tv_string_chk(&argvars[2]); 8605 if (action == NULL) 8606 return; /* type error; errmsg already given */ 8607 for (i = 0; i < 3; ++i) 8608 if (STRCMP(action, av[i]) == 0) 8609 break; 8610 if (i == 3) 8611 { 8612 EMSGN(_(e_invarg2), action); 8613 return; 8614 } 8615 } 8616 else 8617 action = (char_u *)"force"; 8618 8619 /* Go over all entries in the second dict and add them to the 8620 * first dict. */ 8621 todo = d2->dv_hashtab.ht_used; 8622 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8623 { 8624 if (!HASHITEM_EMPTY(hi2)) 8625 { 8626 --todo; 8627 di1 = dict_find(d1, hi2->hi_key, -1); 8628 if (di1 == NULL) 8629 { 8630 di1 = dictitem_copy(HI2DI(hi2)); 8631 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8632 dictitem_free(di1); 8633 } 8634 else if (*action == 'e') 8635 { 8636 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8637 break; 8638 } 8639 else if (*action == 'f') 8640 { 8641 clear_tv(&di1->di_tv); 8642 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8643 } 8644 } 8645 } 8646 8647 copy_tv(&argvars[0], rettv); 8648 } 8649 } 8650 else 8651 EMSG2(_(e_listdictarg), "extend()"); 8652 } 8653 8654 /* 8655 * "filereadable()" function 8656 */ 8657 static void 8658 f_filereadable(argvars, rettv) 8659 typval_T *argvars; 8660 typval_T *rettv; 8661 { 8662 FILE *fd; 8663 char_u *p; 8664 int n; 8665 8666 p = get_tv_string(&argvars[0]); 8667 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8668 { 8669 n = TRUE; 8670 fclose(fd); 8671 } 8672 else 8673 n = FALSE; 8674 8675 rettv->vval.v_number = n; 8676 } 8677 8678 /* 8679 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8680 * rights to write into. 8681 */ 8682 static void 8683 f_filewritable(argvars, rettv) 8684 typval_T *argvars; 8685 typval_T *rettv; 8686 { 8687 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8688 } 8689 8690 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8691 8692 static void 8693 findfilendir(argvars, rettv, dir) 8694 typval_T *argvars; 8695 typval_T *rettv; 8696 int dir; 8697 { 8698 #ifdef FEAT_SEARCHPATH 8699 char_u *fname; 8700 char_u *fresult = NULL; 8701 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8702 char_u *p; 8703 char_u pathbuf[NUMBUFLEN]; 8704 int count = 1; 8705 int first = TRUE; 8706 8707 fname = get_tv_string(&argvars[0]); 8708 8709 if (argvars[1].v_type != VAR_UNKNOWN) 8710 { 8711 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8712 if (p == NULL) 8713 count = -1; /* error */ 8714 else 8715 { 8716 if (*p != NUL) 8717 path = p; 8718 8719 if (argvars[2].v_type != VAR_UNKNOWN) 8720 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8721 } 8722 } 8723 8724 if (*fname != NUL && count >= 0) 8725 { 8726 do 8727 { 8728 vim_free(fresult); 8729 fresult = find_file_in_path_option(first ? fname : NULL, 8730 first ? (int)STRLEN(fname) : 0, 8731 0, first, path, dir, NULL); 8732 first = FALSE; 8733 } while (--count > 0 && fresult != NULL); 8734 } 8735 8736 rettv->vval.v_string = fresult; 8737 #else 8738 rettv->vval.v_string = NULL; 8739 #endif 8740 rettv->v_type = VAR_STRING; 8741 } 8742 8743 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8744 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8745 8746 /* 8747 * Implementation of map() and filter(). 8748 */ 8749 static void 8750 filter_map(argvars, rettv, map) 8751 typval_T *argvars; 8752 typval_T *rettv; 8753 int map; 8754 { 8755 char_u buf[NUMBUFLEN]; 8756 char_u *expr; 8757 listitem_T *li, *nli; 8758 list_T *l = NULL; 8759 dictitem_T *di; 8760 hashtab_T *ht; 8761 hashitem_T *hi; 8762 dict_T *d = NULL; 8763 typval_T save_val; 8764 typval_T save_key; 8765 int rem; 8766 int todo; 8767 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8768 8769 8770 rettv->vval.v_number = 0; 8771 if (argvars[0].v_type == VAR_LIST) 8772 { 8773 if ((l = argvars[0].vval.v_list) == NULL 8774 || (map && tv_check_lock(l->lv_lock, msg))) 8775 return; 8776 } 8777 else if (argvars[0].v_type == VAR_DICT) 8778 { 8779 if ((d = argvars[0].vval.v_dict) == NULL 8780 || (map && tv_check_lock(d->dv_lock, msg))) 8781 return; 8782 } 8783 else 8784 { 8785 EMSG2(_(e_listdictarg), msg); 8786 return; 8787 } 8788 8789 expr = get_tv_string_buf_chk(&argvars[1], buf); 8790 /* On type errors, the preceding call has already displayed an error 8791 * message. Avoid a misleading error message for an empty string that 8792 * was not passed as argument. */ 8793 if (expr != NULL) 8794 { 8795 prepare_vimvar(VV_VAL, &save_val); 8796 expr = skipwhite(expr); 8797 8798 if (argvars[0].v_type == VAR_DICT) 8799 { 8800 prepare_vimvar(VV_KEY, &save_key); 8801 vimvars[VV_KEY].vv_type = VAR_STRING; 8802 8803 ht = &d->dv_hashtab; 8804 hash_lock(ht); 8805 todo = ht->ht_used; 8806 for (hi = ht->ht_array; todo > 0; ++hi) 8807 { 8808 if (!HASHITEM_EMPTY(hi)) 8809 { 8810 --todo; 8811 di = HI2DI(hi); 8812 if (tv_check_lock(di->di_tv.v_lock, msg)) 8813 break; 8814 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8815 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8816 break; 8817 if (!map && rem) 8818 dictitem_remove(d, di); 8819 clear_tv(&vimvars[VV_KEY].vv_tv); 8820 } 8821 } 8822 hash_unlock(ht); 8823 8824 restore_vimvar(VV_KEY, &save_key); 8825 } 8826 else 8827 { 8828 for (li = l->lv_first; li != NULL; li = nli) 8829 { 8830 if (tv_check_lock(li->li_tv.v_lock, msg)) 8831 break; 8832 nli = li->li_next; 8833 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8834 break; 8835 if (!map && rem) 8836 listitem_remove(l, li); 8837 } 8838 } 8839 8840 restore_vimvar(VV_VAL, &save_val); 8841 } 8842 8843 copy_tv(&argvars[0], rettv); 8844 } 8845 8846 static int 8847 filter_map_one(tv, expr, map, remp) 8848 typval_T *tv; 8849 char_u *expr; 8850 int map; 8851 int *remp; 8852 { 8853 typval_T rettv; 8854 char_u *s; 8855 8856 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8857 s = expr; 8858 if (eval1(&s, &rettv, TRUE) == FAIL) 8859 return FAIL; 8860 if (*s != NUL) /* check for trailing chars after expr */ 8861 { 8862 EMSG2(_(e_invexpr2), s); 8863 return FAIL; 8864 } 8865 if (map) 8866 { 8867 /* map(): replace the list item value */ 8868 clear_tv(tv); 8869 rettv.v_lock = 0; 8870 *tv = rettv; 8871 } 8872 else 8873 { 8874 int error = FALSE; 8875 8876 /* filter(): when expr is zero remove the item */ 8877 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8878 clear_tv(&rettv); 8879 /* On type error, nothing has been removed; return FAIL to stop the 8880 * loop. The error message was given by get_tv_number_chk(). */ 8881 if (error) 8882 return FAIL; 8883 } 8884 clear_tv(&vimvars[VV_VAL].vv_tv); 8885 return OK; 8886 } 8887 8888 /* 8889 * "filter()" function 8890 */ 8891 static void 8892 f_filter(argvars, rettv) 8893 typval_T *argvars; 8894 typval_T *rettv; 8895 { 8896 filter_map(argvars, rettv, FALSE); 8897 } 8898 8899 /* 8900 * "finddir({fname}[, {path}[, {count}]])" function 8901 */ 8902 static void 8903 f_finddir(argvars, rettv) 8904 typval_T *argvars; 8905 typval_T *rettv; 8906 { 8907 findfilendir(argvars, rettv, TRUE); 8908 } 8909 8910 /* 8911 * "findfile({fname}[, {path}[, {count}]])" function 8912 */ 8913 static void 8914 f_findfile(argvars, rettv) 8915 typval_T *argvars; 8916 typval_T *rettv; 8917 { 8918 findfilendir(argvars, rettv, FALSE); 8919 } 8920 8921 /* 8922 * "fnamemodify({fname}, {mods})" function 8923 */ 8924 static void 8925 f_fnamemodify(argvars, rettv) 8926 typval_T *argvars; 8927 typval_T *rettv; 8928 { 8929 char_u *fname; 8930 char_u *mods; 8931 int usedlen = 0; 8932 int len; 8933 char_u *fbuf = NULL; 8934 char_u buf[NUMBUFLEN]; 8935 8936 fname = get_tv_string_chk(&argvars[0]); 8937 mods = get_tv_string_buf_chk(&argvars[1], buf); 8938 if (fname == NULL || mods == NULL) 8939 fname = NULL; 8940 else 8941 { 8942 len = (int)STRLEN(fname); 8943 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8944 } 8945 8946 rettv->v_type = VAR_STRING; 8947 if (fname == NULL) 8948 rettv->vval.v_string = NULL; 8949 else 8950 rettv->vval.v_string = vim_strnsave(fname, len); 8951 vim_free(fbuf); 8952 } 8953 8954 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8955 8956 /* 8957 * "foldclosed()" function 8958 */ 8959 static void 8960 foldclosed_both(argvars, rettv, end) 8961 typval_T *argvars; 8962 typval_T *rettv; 8963 int end; 8964 { 8965 #ifdef FEAT_FOLDING 8966 linenr_T lnum; 8967 linenr_T first, last; 8968 8969 lnum = get_tv_lnum(argvars); 8970 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8971 { 8972 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8973 { 8974 if (end) 8975 rettv->vval.v_number = (varnumber_T)last; 8976 else 8977 rettv->vval.v_number = (varnumber_T)first; 8978 return; 8979 } 8980 } 8981 #endif 8982 rettv->vval.v_number = -1; 8983 } 8984 8985 /* 8986 * "foldclosed()" function 8987 */ 8988 static void 8989 f_foldclosed(argvars, rettv) 8990 typval_T *argvars; 8991 typval_T *rettv; 8992 { 8993 foldclosed_both(argvars, rettv, FALSE); 8994 } 8995 8996 /* 8997 * "foldclosedend()" function 8998 */ 8999 static void 9000 f_foldclosedend(argvars, rettv) 9001 typval_T *argvars; 9002 typval_T *rettv; 9003 { 9004 foldclosed_both(argvars, rettv, TRUE); 9005 } 9006 9007 /* 9008 * "foldlevel()" function 9009 */ 9010 static void 9011 f_foldlevel(argvars, rettv) 9012 typval_T *argvars; 9013 typval_T *rettv; 9014 { 9015 #ifdef FEAT_FOLDING 9016 linenr_T lnum; 9017 9018 lnum = get_tv_lnum(argvars); 9019 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9020 rettv->vval.v_number = foldLevel(lnum); 9021 else 9022 #endif 9023 rettv->vval.v_number = 0; 9024 } 9025 9026 /* 9027 * "foldtext()" function 9028 */ 9029 /*ARGSUSED*/ 9030 static void 9031 f_foldtext(argvars, rettv) 9032 typval_T *argvars; 9033 typval_T *rettv; 9034 { 9035 #ifdef FEAT_FOLDING 9036 linenr_T lnum; 9037 char_u *s; 9038 char_u *r; 9039 int len; 9040 char *txt; 9041 #endif 9042 9043 rettv->v_type = VAR_STRING; 9044 rettv->vval.v_string = NULL; 9045 #ifdef FEAT_FOLDING 9046 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9047 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9048 <= curbuf->b_ml.ml_line_count 9049 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9050 { 9051 /* Find first non-empty line in the fold. */ 9052 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9053 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9054 { 9055 if (!linewhite(lnum)) 9056 break; 9057 ++lnum; 9058 } 9059 9060 /* Find interesting text in this line. */ 9061 s = skipwhite(ml_get(lnum)); 9062 /* skip C comment-start */ 9063 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9064 { 9065 s = skipwhite(s + 2); 9066 if (*skipwhite(s) == NUL 9067 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9068 { 9069 s = skipwhite(ml_get(lnum + 1)); 9070 if (*s == '*') 9071 s = skipwhite(s + 1); 9072 } 9073 } 9074 txt = _("+-%s%3ld lines: "); 9075 r = alloc((unsigned)(STRLEN(txt) 9076 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9077 + 20 /* for %3ld */ 9078 + STRLEN(s))); /* concatenated */ 9079 if (r != NULL) 9080 { 9081 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9082 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9083 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9084 len = (int)STRLEN(r); 9085 STRCAT(r, s); 9086 /* remove 'foldmarker' and 'commentstring' */ 9087 foldtext_cleanup(r + len); 9088 rettv->vval.v_string = r; 9089 } 9090 } 9091 #endif 9092 } 9093 9094 /* 9095 * "foldtextresult(lnum)" function 9096 */ 9097 /*ARGSUSED*/ 9098 static void 9099 f_foldtextresult(argvars, rettv) 9100 typval_T *argvars; 9101 typval_T *rettv; 9102 { 9103 #ifdef FEAT_FOLDING 9104 linenr_T lnum; 9105 char_u *text; 9106 char_u buf[51]; 9107 foldinfo_T foldinfo; 9108 int fold_count; 9109 #endif 9110 9111 rettv->v_type = VAR_STRING; 9112 rettv->vval.v_string = NULL; 9113 #ifdef FEAT_FOLDING 9114 lnum = get_tv_lnum(argvars); 9115 /* treat illegal types and illegal string values for {lnum} the same */ 9116 if (lnum < 0) 9117 lnum = 0; 9118 fold_count = foldedCount(curwin, lnum, &foldinfo); 9119 if (fold_count > 0) 9120 { 9121 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9122 &foldinfo, buf); 9123 if (text == buf) 9124 text = vim_strsave(text); 9125 rettv->vval.v_string = text; 9126 } 9127 #endif 9128 } 9129 9130 /* 9131 * "foreground()" function 9132 */ 9133 /*ARGSUSED*/ 9134 static void 9135 f_foreground(argvars, rettv) 9136 typval_T *argvars; 9137 typval_T *rettv; 9138 { 9139 rettv->vval.v_number = 0; 9140 #ifdef FEAT_GUI 9141 if (gui.in_use) 9142 gui_mch_set_foreground(); 9143 #else 9144 # ifdef WIN32 9145 win32_set_foreground(); 9146 # endif 9147 #endif 9148 } 9149 9150 /* 9151 * "function()" function 9152 */ 9153 /*ARGSUSED*/ 9154 static void 9155 f_function(argvars, rettv) 9156 typval_T *argvars; 9157 typval_T *rettv; 9158 { 9159 char_u *s; 9160 9161 rettv->vval.v_number = 0; 9162 s = get_tv_string(&argvars[0]); 9163 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9164 EMSG2(_(e_invarg2), s); 9165 else if (!function_exists(s)) 9166 EMSG2(_("E700: Unknown function: %s"), s); 9167 else 9168 { 9169 rettv->vval.v_string = vim_strsave(s); 9170 rettv->v_type = VAR_FUNC; 9171 } 9172 } 9173 9174 /* 9175 * "garbagecollect()" function 9176 */ 9177 /*ARGSUSED*/ 9178 static void 9179 f_garbagecollect(argvars, rettv) 9180 typval_T *argvars; 9181 typval_T *rettv; 9182 { 9183 garbage_collect(); 9184 } 9185 9186 /* 9187 * "get()" function 9188 */ 9189 static void 9190 f_get(argvars, rettv) 9191 typval_T *argvars; 9192 typval_T *rettv; 9193 { 9194 listitem_T *li; 9195 list_T *l; 9196 dictitem_T *di; 9197 dict_T *d; 9198 typval_T *tv = NULL; 9199 9200 if (argvars[0].v_type == VAR_LIST) 9201 { 9202 if ((l = argvars[0].vval.v_list) != NULL) 9203 { 9204 int error = FALSE; 9205 9206 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9207 if (!error && li != NULL) 9208 tv = &li->li_tv; 9209 } 9210 } 9211 else if (argvars[0].v_type == VAR_DICT) 9212 { 9213 if ((d = argvars[0].vval.v_dict) != NULL) 9214 { 9215 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9216 if (di != NULL) 9217 tv = &di->di_tv; 9218 } 9219 } 9220 else 9221 EMSG2(_(e_listdictarg), "get()"); 9222 9223 if (tv == NULL) 9224 { 9225 if (argvars[2].v_type == VAR_UNKNOWN) 9226 rettv->vval.v_number = 0; 9227 else 9228 copy_tv(&argvars[2], rettv); 9229 } 9230 else 9231 copy_tv(tv, rettv); 9232 } 9233 9234 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9235 9236 /* 9237 * Get line or list of lines from buffer "buf" into "rettv". 9238 * Return a range (from start to end) of lines in rettv from the specified 9239 * buffer. 9240 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9241 */ 9242 static void 9243 get_buffer_lines(buf, start, end, retlist, rettv) 9244 buf_T *buf; 9245 linenr_T start; 9246 linenr_T end; 9247 int retlist; 9248 typval_T *rettv; 9249 { 9250 char_u *p; 9251 list_T *l = NULL; 9252 9253 if (retlist) 9254 { 9255 l = list_alloc(); 9256 if (l == NULL) 9257 return; 9258 9259 rettv->vval.v_list = l; 9260 rettv->v_type = VAR_LIST; 9261 ++l->lv_refcount; 9262 } 9263 else 9264 rettv->vval.v_number = 0; 9265 9266 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9267 return; 9268 9269 if (!retlist) 9270 { 9271 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9272 p = ml_get_buf(buf, start, FALSE); 9273 else 9274 p = (char_u *)""; 9275 9276 rettv->v_type = VAR_STRING; 9277 rettv->vval.v_string = vim_strsave(p); 9278 } 9279 else 9280 { 9281 if (end < start) 9282 return; 9283 9284 if (start < 1) 9285 start = 1; 9286 if (end > buf->b_ml.ml_line_count) 9287 end = buf->b_ml.ml_line_count; 9288 while (start <= end) 9289 if (list_append_string(l, ml_get_buf(buf, start++, FALSE), -1) 9290 == FAIL) 9291 break; 9292 } 9293 } 9294 9295 /* 9296 * "getbufline()" function 9297 */ 9298 static void 9299 f_getbufline(argvars, rettv) 9300 typval_T *argvars; 9301 typval_T *rettv; 9302 { 9303 linenr_T lnum; 9304 linenr_T end; 9305 buf_T *buf; 9306 9307 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9308 ++emsg_off; 9309 buf = get_buf_tv(&argvars[0]); 9310 --emsg_off; 9311 9312 lnum = get_tv_lnum_buf(&argvars[1], buf); 9313 if (argvars[2].v_type == VAR_UNKNOWN) 9314 end = lnum; 9315 else 9316 end = get_tv_lnum_buf(&argvars[2], buf); 9317 9318 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9319 } 9320 9321 /* 9322 * "getbufvar()" function 9323 */ 9324 static void 9325 f_getbufvar(argvars, rettv) 9326 typval_T *argvars; 9327 typval_T *rettv; 9328 { 9329 buf_T *buf; 9330 buf_T *save_curbuf; 9331 char_u *varname; 9332 dictitem_T *v; 9333 9334 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9335 varname = get_tv_string_chk(&argvars[1]); 9336 ++emsg_off; 9337 buf = get_buf_tv(&argvars[0]); 9338 9339 rettv->v_type = VAR_STRING; 9340 rettv->vval.v_string = NULL; 9341 9342 if (buf != NULL && varname != NULL) 9343 { 9344 if (*varname == '&') /* buffer-local-option */ 9345 { 9346 /* set curbuf to be our buf, temporarily */ 9347 save_curbuf = curbuf; 9348 curbuf = buf; 9349 9350 get_option_tv(&varname, rettv, TRUE); 9351 9352 /* restore previous notion of curbuf */ 9353 curbuf = save_curbuf; 9354 } 9355 else 9356 { 9357 if (*varname == NUL) 9358 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9359 * scope prefix before the NUL byte is required by 9360 * find_var_in_ht(). */ 9361 varname = (char_u *)"b:" + 2; 9362 /* look up the variable */ 9363 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9364 if (v != NULL) 9365 copy_tv(&v->di_tv, rettv); 9366 } 9367 } 9368 9369 --emsg_off; 9370 } 9371 9372 /* 9373 * "getchar()" function 9374 */ 9375 static void 9376 f_getchar(argvars, rettv) 9377 typval_T *argvars; 9378 typval_T *rettv; 9379 { 9380 varnumber_T n; 9381 int error = FALSE; 9382 9383 ++no_mapping; 9384 ++allow_keys; 9385 if (argvars[0].v_type == VAR_UNKNOWN) 9386 /* getchar(): blocking wait. */ 9387 n = safe_vgetc(); 9388 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9389 /* getchar(1): only check if char avail */ 9390 n = vpeekc(); 9391 else if (error || vpeekc() == NUL) 9392 /* illegal argument or getchar(0) and no char avail: return zero */ 9393 n = 0; 9394 else 9395 /* getchar(0) and char avail: return char */ 9396 n = safe_vgetc(); 9397 --no_mapping; 9398 --allow_keys; 9399 9400 rettv->vval.v_number = n; 9401 if (IS_SPECIAL(n) || mod_mask != 0) 9402 { 9403 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9404 int i = 0; 9405 9406 /* Turn a special key into three bytes, plus modifier. */ 9407 if (mod_mask != 0) 9408 { 9409 temp[i++] = K_SPECIAL; 9410 temp[i++] = KS_MODIFIER; 9411 temp[i++] = mod_mask; 9412 } 9413 if (IS_SPECIAL(n)) 9414 { 9415 temp[i++] = K_SPECIAL; 9416 temp[i++] = K_SECOND(n); 9417 temp[i++] = K_THIRD(n); 9418 } 9419 #ifdef FEAT_MBYTE 9420 else if (has_mbyte) 9421 i += (*mb_char2bytes)(n, temp + i); 9422 #endif 9423 else 9424 temp[i++] = n; 9425 temp[i++] = NUL; 9426 rettv->v_type = VAR_STRING; 9427 rettv->vval.v_string = vim_strsave(temp); 9428 } 9429 } 9430 9431 /* 9432 * "getcharmod()" function 9433 */ 9434 /*ARGSUSED*/ 9435 static void 9436 f_getcharmod(argvars, rettv) 9437 typval_T *argvars; 9438 typval_T *rettv; 9439 { 9440 rettv->vval.v_number = mod_mask; 9441 } 9442 9443 /* 9444 * "getcmdline()" function 9445 */ 9446 /*ARGSUSED*/ 9447 static void 9448 f_getcmdline(argvars, rettv) 9449 typval_T *argvars; 9450 typval_T *rettv; 9451 { 9452 rettv->v_type = VAR_STRING; 9453 rettv->vval.v_string = get_cmdline_str(); 9454 } 9455 9456 /* 9457 * "getcmdpos()" function 9458 */ 9459 /*ARGSUSED*/ 9460 static void 9461 f_getcmdpos(argvars, rettv) 9462 typval_T *argvars; 9463 typval_T *rettv; 9464 { 9465 rettv->vval.v_number = get_cmdline_pos() + 1; 9466 } 9467 9468 /* 9469 * "getcmdtype()" function 9470 */ 9471 /*ARGSUSED*/ 9472 static void 9473 f_getcmdtype(argvars, rettv) 9474 typval_T *argvars; 9475 typval_T *rettv; 9476 { 9477 rettv->v_type = VAR_STRING; 9478 rettv->vval.v_string = alloc(2); 9479 if (rettv->vval.v_string != NULL) 9480 { 9481 rettv->vval.v_string[0] = get_cmdline_type(); 9482 rettv->vval.v_string[1] = NUL; 9483 } 9484 } 9485 9486 /* 9487 * "getcwd()" function 9488 */ 9489 /*ARGSUSED*/ 9490 static void 9491 f_getcwd(argvars, rettv) 9492 typval_T *argvars; 9493 typval_T *rettv; 9494 { 9495 char_u cwd[MAXPATHL]; 9496 9497 rettv->v_type = VAR_STRING; 9498 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9499 rettv->vval.v_string = NULL; 9500 else 9501 { 9502 rettv->vval.v_string = vim_strsave(cwd); 9503 #ifdef BACKSLASH_IN_FILENAME 9504 if (rettv->vval.v_string != NULL) 9505 slash_adjust(rettv->vval.v_string); 9506 #endif 9507 } 9508 } 9509 9510 /* 9511 * "getfontname()" function 9512 */ 9513 /*ARGSUSED*/ 9514 static void 9515 f_getfontname(argvars, rettv) 9516 typval_T *argvars; 9517 typval_T *rettv; 9518 { 9519 rettv->v_type = VAR_STRING; 9520 rettv->vval.v_string = NULL; 9521 #ifdef FEAT_GUI 9522 if (gui.in_use) 9523 { 9524 GuiFont font; 9525 char_u *name = NULL; 9526 9527 if (argvars[0].v_type == VAR_UNKNOWN) 9528 { 9529 /* Get the "Normal" font. Either the name saved by 9530 * hl_set_font_name() or from the font ID. */ 9531 font = gui.norm_font; 9532 name = hl_get_font_name(); 9533 } 9534 else 9535 { 9536 name = get_tv_string(&argvars[0]); 9537 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9538 return; 9539 font = gui_mch_get_font(name, FALSE); 9540 if (font == NOFONT) 9541 return; /* Invalid font name, return empty string. */ 9542 } 9543 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9544 if (argvars[0].v_type != VAR_UNKNOWN) 9545 gui_mch_free_font(font); 9546 } 9547 #endif 9548 } 9549 9550 /* 9551 * "getfperm({fname})" function 9552 */ 9553 static void 9554 f_getfperm(argvars, rettv) 9555 typval_T *argvars; 9556 typval_T *rettv; 9557 { 9558 char_u *fname; 9559 struct stat st; 9560 char_u *perm = NULL; 9561 char_u flags[] = "rwx"; 9562 int i; 9563 9564 fname = get_tv_string(&argvars[0]); 9565 9566 rettv->v_type = VAR_STRING; 9567 if (mch_stat((char *)fname, &st) >= 0) 9568 { 9569 perm = vim_strsave((char_u *)"---------"); 9570 if (perm != NULL) 9571 { 9572 for (i = 0; i < 9; i++) 9573 { 9574 if (st.st_mode & (1 << (8 - i))) 9575 perm[i] = flags[i % 3]; 9576 } 9577 } 9578 } 9579 rettv->vval.v_string = perm; 9580 } 9581 9582 /* 9583 * "getfsize({fname})" function 9584 */ 9585 static void 9586 f_getfsize(argvars, rettv) 9587 typval_T *argvars; 9588 typval_T *rettv; 9589 { 9590 char_u *fname; 9591 struct stat st; 9592 9593 fname = get_tv_string(&argvars[0]); 9594 9595 rettv->v_type = VAR_NUMBER; 9596 9597 if (mch_stat((char *)fname, &st) >= 0) 9598 { 9599 if (mch_isdir(fname)) 9600 rettv->vval.v_number = 0; 9601 else 9602 rettv->vval.v_number = (varnumber_T)st.st_size; 9603 } 9604 else 9605 rettv->vval.v_number = -1; 9606 } 9607 9608 /* 9609 * "getftime({fname})" function 9610 */ 9611 static void 9612 f_getftime(argvars, rettv) 9613 typval_T *argvars; 9614 typval_T *rettv; 9615 { 9616 char_u *fname; 9617 struct stat st; 9618 9619 fname = get_tv_string(&argvars[0]); 9620 9621 if (mch_stat((char *)fname, &st) >= 0) 9622 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9623 else 9624 rettv->vval.v_number = -1; 9625 } 9626 9627 /* 9628 * "getftype({fname})" function 9629 */ 9630 static void 9631 f_getftype(argvars, rettv) 9632 typval_T *argvars; 9633 typval_T *rettv; 9634 { 9635 char_u *fname; 9636 struct stat st; 9637 char_u *type = NULL; 9638 char *t; 9639 9640 fname = get_tv_string(&argvars[0]); 9641 9642 rettv->v_type = VAR_STRING; 9643 if (mch_lstat((char *)fname, &st) >= 0) 9644 { 9645 #ifdef S_ISREG 9646 if (S_ISREG(st.st_mode)) 9647 t = "file"; 9648 else if (S_ISDIR(st.st_mode)) 9649 t = "dir"; 9650 # ifdef S_ISLNK 9651 else if (S_ISLNK(st.st_mode)) 9652 t = "link"; 9653 # endif 9654 # ifdef S_ISBLK 9655 else if (S_ISBLK(st.st_mode)) 9656 t = "bdev"; 9657 # endif 9658 # ifdef S_ISCHR 9659 else if (S_ISCHR(st.st_mode)) 9660 t = "cdev"; 9661 # endif 9662 # ifdef S_ISFIFO 9663 else if (S_ISFIFO(st.st_mode)) 9664 t = "fifo"; 9665 # endif 9666 # ifdef S_ISSOCK 9667 else if (S_ISSOCK(st.st_mode)) 9668 t = "fifo"; 9669 # endif 9670 else 9671 t = "other"; 9672 #else 9673 # ifdef S_IFMT 9674 switch (st.st_mode & S_IFMT) 9675 { 9676 case S_IFREG: t = "file"; break; 9677 case S_IFDIR: t = "dir"; break; 9678 # ifdef S_IFLNK 9679 case S_IFLNK: t = "link"; break; 9680 # endif 9681 # ifdef S_IFBLK 9682 case S_IFBLK: t = "bdev"; break; 9683 # endif 9684 # ifdef S_IFCHR 9685 case S_IFCHR: t = "cdev"; break; 9686 # endif 9687 # ifdef S_IFIFO 9688 case S_IFIFO: t = "fifo"; break; 9689 # endif 9690 # ifdef S_IFSOCK 9691 case S_IFSOCK: t = "socket"; break; 9692 # endif 9693 default: t = "other"; 9694 } 9695 # else 9696 if (mch_isdir(fname)) 9697 t = "dir"; 9698 else 9699 t = "file"; 9700 # endif 9701 #endif 9702 type = vim_strsave((char_u *)t); 9703 } 9704 rettv->vval.v_string = type; 9705 } 9706 9707 /* 9708 * "getline(lnum, [end])" function 9709 */ 9710 static void 9711 f_getline(argvars, rettv) 9712 typval_T *argvars; 9713 typval_T *rettv; 9714 { 9715 linenr_T lnum; 9716 linenr_T end; 9717 int retlist; 9718 9719 lnum = get_tv_lnum(argvars); 9720 if (argvars[1].v_type == VAR_UNKNOWN) 9721 { 9722 end = 0; 9723 retlist = FALSE; 9724 } 9725 else 9726 { 9727 end = get_tv_lnum(&argvars[1]); 9728 retlist = TRUE; 9729 } 9730 9731 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9732 } 9733 9734 /* 9735 * "getqflist()" function 9736 */ 9737 /*ARGSUSED*/ 9738 static void 9739 f_getqflist(argvars, rettv) 9740 typval_T *argvars; 9741 typval_T *rettv; 9742 { 9743 #ifdef FEAT_QUICKFIX 9744 list_T *l; 9745 #endif 9746 9747 rettv->vval.v_number = FALSE; 9748 #ifdef FEAT_QUICKFIX 9749 l = list_alloc(); 9750 if (l != NULL) 9751 { 9752 rettv->vval.v_list = l; 9753 rettv->v_type = VAR_LIST; 9754 ++l->lv_refcount; 9755 (void)get_errorlist(l); 9756 } 9757 #endif 9758 } 9759 9760 /* 9761 * "getreg()" function 9762 */ 9763 static void 9764 f_getreg(argvars, rettv) 9765 typval_T *argvars; 9766 typval_T *rettv; 9767 { 9768 char_u *strregname; 9769 int regname; 9770 int arg2 = FALSE; 9771 int error = FALSE; 9772 9773 if (argvars[0].v_type != VAR_UNKNOWN) 9774 { 9775 strregname = get_tv_string_chk(&argvars[0]); 9776 error = strregname == NULL; 9777 if (argvars[1].v_type != VAR_UNKNOWN) 9778 arg2 = get_tv_number_chk(&argvars[1], &error); 9779 } 9780 else 9781 strregname = vimvars[VV_REG].vv_str; 9782 regname = (strregname == NULL ? '"' : *strregname); 9783 if (regname == 0) 9784 regname = '"'; 9785 9786 rettv->v_type = VAR_STRING; 9787 rettv->vval.v_string = error ? NULL : 9788 get_reg_contents(regname, TRUE, arg2); 9789 } 9790 9791 /* 9792 * "getregtype()" function 9793 */ 9794 static void 9795 f_getregtype(argvars, rettv) 9796 typval_T *argvars; 9797 typval_T *rettv; 9798 { 9799 char_u *strregname; 9800 int regname; 9801 char_u buf[NUMBUFLEN + 2]; 9802 long reglen = 0; 9803 9804 if (argvars[0].v_type != VAR_UNKNOWN) 9805 { 9806 strregname = get_tv_string_chk(&argvars[0]); 9807 if (strregname == NULL) /* type error; errmsg already given */ 9808 { 9809 rettv->v_type = VAR_STRING; 9810 rettv->vval.v_string = NULL; 9811 return; 9812 } 9813 } 9814 else 9815 /* Default to v:register */ 9816 strregname = vimvars[VV_REG].vv_str; 9817 9818 regname = (strregname == NULL ? '"' : *strregname); 9819 if (regname == 0) 9820 regname = '"'; 9821 9822 buf[0] = NUL; 9823 buf[1] = NUL; 9824 switch (get_reg_type(regname, ®len)) 9825 { 9826 case MLINE: buf[0] = 'V'; break; 9827 case MCHAR: buf[0] = 'v'; break; 9828 #ifdef FEAT_VISUAL 9829 case MBLOCK: 9830 buf[0] = Ctrl_V; 9831 sprintf((char *)buf + 1, "%ld", reglen + 1); 9832 break; 9833 #endif 9834 } 9835 rettv->v_type = VAR_STRING; 9836 rettv->vval.v_string = vim_strsave(buf); 9837 } 9838 9839 /* 9840 * "getwinposx()" function 9841 */ 9842 /*ARGSUSED*/ 9843 static void 9844 f_getwinposx(argvars, rettv) 9845 typval_T *argvars; 9846 typval_T *rettv; 9847 { 9848 rettv->vval.v_number = -1; 9849 #ifdef FEAT_GUI 9850 if (gui.in_use) 9851 { 9852 int x, y; 9853 9854 if (gui_mch_get_winpos(&x, &y) == OK) 9855 rettv->vval.v_number = x; 9856 } 9857 #endif 9858 } 9859 9860 /* 9861 * "getwinposy()" function 9862 */ 9863 /*ARGSUSED*/ 9864 static void 9865 f_getwinposy(argvars, rettv) 9866 typval_T *argvars; 9867 typval_T *rettv; 9868 { 9869 rettv->vval.v_number = -1; 9870 #ifdef FEAT_GUI 9871 if (gui.in_use) 9872 { 9873 int x, y; 9874 9875 if (gui_mch_get_winpos(&x, &y) == OK) 9876 rettv->vval.v_number = y; 9877 } 9878 #endif 9879 } 9880 9881 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9882 9883 static win_T * 9884 find_win_by_nr(vp) 9885 typval_T *vp; 9886 { 9887 #ifdef FEAT_WINDOWS 9888 win_T *wp; 9889 #endif 9890 int nr; 9891 9892 nr = get_tv_number_chk(vp, NULL); 9893 9894 #ifdef FEAT_WINDOWS 9895 if (nr < 0) 9896 return NULL; 9897 if (nr == 0) 9898 return curwin; 9899 9900 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9901 if (--nr <= 0) 9902 break; 9903 return wp; 9904 #else 9905 if (nr == 0 || nr == 1) 9906 return curwin; 9907 return NULL; 9908 #endif 9909 } 9910 9911 /* 9912 * "getwinvar()" function 9913 */ 9914 static void 9915 f_getwinvar(argvars, rettv) 9916 typval_T *argvars; 9917 typval_T *rettv; 9918 { 9919 win_T *win, *oldcurwin; 9920 char_u *varname; 9921 dictitem_T *v; 9922 9923 win = find_win_by_nr(&argvars[0]); 9924 varname = get_tv_string_chk(&argvars[1]); 9925 ++emsg_off; 9926 9927 rettv->v_type = VAR_STRING; 9928 rettv->vval.v_string = NULL; 9929 9930 if (win != NULL && varname != NULL) 9931 { 9932 if (*varname == '&') /* window-local-option */ 9933 { 9934 /* Set curwin to be our win, temporarily. Also set curbuf, so 9935 * that we can get buffer-local options. */ 9936 oldcurwin = curwin; 9937 curwin = win; 9938 curbuf = win->w_buffer; 9939 9940 get_option_tv(&varname, rettv, 1); 9941 9942 /* restore previous notion of curwin */ 9943 curwin = oldcurwin; 9944 curbuf = curwin->w_buffer; 9945 } 9946 else 9947 { 9948 if (*varname == NUL) 9949 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9950 * scope prefix before the NUL byte is required by 9951 * find_var_in_ht(). */ 9952 varname = (char_u *)"w:" + 2; 9953 /* look up the variable */ 9954 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9955 if (v != NULL) 9956 copy_tv(&v->di_tv, rettv); 9957 } 9958 } 9959 9960 --emsg_off; 9961 } 9962 9963 /* 9964 * "glob()" function 9965 */ 9966 static void 9967 f_glob(argvars, rettv) 9968 typval_T *argvars; 9969 typval_T *rettv; 9970 { 9971 expand_T xpc; 9972 9973 ExpandInit(&xpc); 9974 xpc.xp_context = EXPAND_FILES; 9975 rettv->v_type = VAR_STRING; 9976 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9977 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9978 ExpandCleanup(&xpc); 9979 } 9980 9981 /* 9982 * "globpath()" function 9983 */ 9984 static void 9985 f_globpath(argvars, rettv) 9986 typval_T *argvars; 9987 typval_T *rettv; 9988 { 9989 char_u buf1[NUMBUFLEN]; 9990 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9991 9992 rettv->v_type = VAR_STRING; 9993 if (file == NULL) 9994 rettv->vval.v_string = NULL; 9995 else 9996 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9997 } 9998 9999 /* 10000 * "has()" function 10001 */ 10002 static void 10003 f_has(argvars, rettv) 10004 typval_T *argvars; 10005 typval_T *rettv; 10006 { 10007 int i; 10008 char_u *name; 10009 int n = FALSE; 10010 static char *(has_list[]) = 10011 { 10012 #ifdef AMIGA 10013 "amiga", 10014 # ifdef FEAT_ARP 10015 "arp", 10016 # endif 10017 #endif 10018 #ifdef __BEOS__ 10019 "beos", 10020 #endif 10021 #ifdef MSDOS 10022 # ifdef DJGPP 10023 "dos32", 10024 # else 10025 "dos16", 10026 # endif 10027 #endif 10028 #ifdef MACOS 10029 "mac", 10030 #endif 10031 #if defined(MACOS_X_UNIX) 10032 "macunix", 10033 #endif 10034 #ifdef OS2 10035 "os2", 10036 #endif 10037 #ifdef __QNX__ 10038 "qnx", 10039 #endif 10040 #ifdef RISCOS 10041 "riscos", 10042 #endif 10043 #ifdef UNIX 10044 "unix", 10045 #endif 10046 #ifdef VMS 10047 "vms", 10048 #endif 10049 #ifdef WIN16 10050 "win16", 10051 #endif 10052 #ifdef WIN32 10053 "win32", 10054 #endif 10055 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10056 "win32unix", 10057 #endif 10058 #ifdef WIN64 10059 "win64", 10060 #endif 10061 #ifdef EBCDIC 10062 "ebcdic", 10063 #endif 10064 #ifndef CASE_INSENSITIVE_FILENAME 10065 "fname_case", 10066 #endif 10067 #ifdef FEAT_ARABIC 10068 "arabic", 10069 #endif 10070 #ifdef FEAT_AUTOCMD 10071 "autocmd", 10072 #endif 10073 #ifdef FEAT_BEVAL 10074 "balloon_eval", 10075 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10076 "balloon_multiline", 10077 # endif 10078 #endif 10079 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10080 "builtin_terms", 10081 # ifdef ALL_BUILTIN_TCAPS 10082 "all_builtin_terms", 10083 # endif 10084 #endif 10085 #ifdef FEAT_BYTEOFF 10086 "byte_offset", 10087 #endif 10088 #ifdef FEAT_CINDENT 10089 "cindent", 10090 #endif 10091 #ifdef FEAT_CLIENTSERVER 10092 "clientserver", 10093 #endif 10094 #ifdef FEAT_CLIPBOARD 10095 "clipboard", 10096 #endif 10097 #ifdef FEAT_CMDL_COMPL 10098 "cmdline_compl", 10099 #endif 10100 #ifdef FEAT_CMDHIST 10101 "cmdline_hist", 10102 #endif 10103 #ifdef FEAT_COMMENTS 10104 "comments", 10105 #endif 10106 #ifdef FEAT_CRYPT 10107 "cryptv", 10108 #endif 10109 #ifdef FEAT_CSCOPE 10110 "cscope", 10111 #endif 10112 #ifdef CURSOR_SHAPE 10113 "cursorshape", 10114 #endif 10115 #ifdef DEBUG 10116 "debug", 10117 #endif 10118 #ifdef FEAT_CON_DIALOG 10119 "dialog_con", 10120 #endif 10121 #ifdef FEAT_GUI_DIALOG 10122 "dialog_gui", 10123 #endif 10124 #ifdef FEAT_DIFF 10125 "diff", 10126 #endif 10127 #ifdef FEAT_DIGRAPHS 10128 "digraphs", 10129 #endif 10130 #ifdef FEAT_DND 10131 "dnd", 10132 #endif 10133 #ifdef FEAT_EMACS_TAGS 10134 "emacs_tags", 10135 #endif 10136 "eval", /* always present, of course! */ 10137 #ifdef FEAT_EX_EXTRA 10138 "ex_extra", 10139 #endif 10140 #ifdef FEAT_SEARCH_EXTRA 10141 "extra_search", 10142 #endif 10143 #ifdef FEAT_FKMAP 10144 "farsi", 10145 #endif 10146 #ifdef FEAT_SEARCHPATH 10147 "file_in_path", 10148 #endif 10149 #if defined(UNIX) && !defined(USE_SYSTEM) 10150 "filterpipe", 10151 #endif 10152 #ifdef FEAT_FIND_ID 10153 "find_in_path", 10154 #endif 10155 #ifdef FEAT_FOLDING 10156 "folding", 10157 #endif 10158 #ifdef FEAT_FOOTER 10159 "footer", 10160 #endif 10161 #if !defined(USE_SYSTEM) && defined(UNIX) 10162 "fork", 10163 #endif 10164 #ifdef FEAT_GETTEXT 10165 "gettext", 10166 #endif 10167 #ifdef FEAT_GUI 10168 "gui", 10169 #endif 10170 #ifdef FEAT_GUI_ATHENA 10171 # ifdef FEAT_GUI_NEXTAW 10172 "gui_neXtaw", 10173 # else 10174 "gui_athena", 10175 # endif 10176 #endif 10177 #ifdef FEAT_GUI_GTK 10178 "gui_gtk", 10179 # ifdef HAVE_GTK2 10180 "gui_gtk2", 10181 # endif 10182 #endif 10183 #ifdef FEAT_GUI_MAC 10184 "gui_mac", 10185 #endif 10186 #ifdef FEAT_GUI_MOTIF 10187 "gui_motif", 10188 #endif 10189 #ifdef FEAT_GUI_PHOTON 10190 "gui_photon", 10191 #endif 10192 #ifdef FEAT_GUI_W16 10193 "gui_win16", 10194 #endif 10195 #ifdef FEAT_GUI_W32 10196 "gui_win32", 10197 #endif 10198 #ifdef FEAT_HANGULIN 10199 "hangul_input", 10200 #endif 10201 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10202 "iconv", 10203 #endif 10204 #ifdef FEAT_INS_EXPAND 10205 "insert_expand", 10206 #endif 10207 #ifdef FEAT_JUMPLIST 10208 "jumplist", 10209 #endif 10210 #ifdef FEAT_KEYMAP 10211 "keymap", 10212 #endif 10213 #ifdef FEAT_LANGMAP 10214 "langmap", 10215 #endif 10216 #ifdef FEAT_LIBCALL 10217 "libcall", 10218 #endif 10219 #ifdef FEAT_LINEBREAK 10220 "linebreak", 10221 #endif 10222 #ifdef FEAT_LISP 10223 "lispindent", 10224 #endif 10225 #ifdef FEAT_LISTCMDS 10226 "listcmds", 10227 #endif 10228 #ifdef FEAT_LOCALMAP 10229 "localmap", 10230 #endif 10231 #ifdef FEAT_MENU 10232 "menu", 10233 #endif 10234 #ifdef FEAT_SESSION 10235 "mksession", 10236 #endif 10237 #ifdef FEAT_MODIFY_FNAME 10238 "modify_fname", 10239 #endif 10240 #ifdef FEAT_MOUSE 10241 "mouse", 10242 #endif 10243 #ifdef FEAT_MOUSESHAPE 10244 "mouseshape", 10245 #endif 10246 #if defined(UNIX) || defined(VMS) 10247 # ifdef FEAT_MOUSE_DEC 10248 "mouse_dec", 10249 # endif 10250 # ifdef FEAT_MOUSE_GPM 10251 "mouse_gpm", 10252 # endif 10253 # ifdef FEAT_MOUSE_JSB 10254 "mouse_jsbterm", 10255 # endif 10256 # ifdef FEAT_MOUSE_NET 10257 "mouse_netterm", 10258 # endif 10259 # ifdef FEAT_MOUSE_PTERM 10260 "mouse_pterm", 10261 # endif 10262 # ifdef FEAT_MOUSE_XTERM 10263 "mouse_xterm", 10264 # endif 10265 #endif 10266 #ifdef FEAT_MBYTE 10267 "multi_byte", 10268 #endif 10269 #ifdef FEAT_MBYTE_IME 10270 "multi_byte_ime", 10271 #endif 10272 #ifdef FEAT_MULTI_LANG 10273 "multi_lang", 10274 #endif 10275 #ifdef FEAT_MZSCHEME 10276 #ifndef DYNAMIC_MZSCHEME 10277 "mzscheme", 10278 #endif 10279 #endif 10280 #ifdef FEAT_OLE 10281 "ole", 10282 #endif 10283 #ifdef FEAT_OSFILETYPE 10284 "osfiletype", 10285 #endif 10286 #ifdef FEAT_PATH_EXTRA 10287 "path_extra", 10288 #endif 10289 #ifdef FEAT_PERL 10290 #ifndef DYNAMIC_PERL 10291 "perl", 10292 #endif 10293 #endif 10294 #ifdef FEAT_PYTHON 10295 #ifndef DYNAMIC_PYTHON 10296 "python", 10297 #endif 10298 #endif 10299 #ifdef FEAT_POSTSCRIPT 10300 "postscript", 10301 #endif 10302 #ifdef FEAT_PRINTER 10303 "printer", 10304 #endif 10305 #ifdef FEAT_PROFILE 10306 "profile", 10307 #endif 10308 #ifdef FEAT_QUICKFIX 10309 "quickfix", 10310 #endif 10311 #ifdef FEAT_RIGHTLEFT 10312 "rightleft", 10313 #endif 10314 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10315 "ruby", 10316 #endif 10317 #ifdef FEAT_SCROLLBIND 10318 "scrollbind", 10319 #endif 10320 #ifdef FEAT_CMDL_INFO 10321 "showcmd", 10322 "cmdline_info", 10323 #endif 10324 #ifdef FEAT_SIGNS 10325 "signs", 10326 #endif 10327 #ifdef FEAT_SMARTINDENT 10328 "smartindent", 10329 #endif 10330 #ifdef FEAT_SNIFF 10331 "sniff", 10332 #endif 10333 #ifdef FEAT_STL_OPT 10334 "statusline", 10335 #endif 10336 #ifdef FEAT_SUN_WORKSHOP 10337 "sun_workshop", 10338 #endif 10339 #ifdef FEAT_NETBEANS_INTG 10340 "netbeans_intg", 10341 #endif 10342 #ifdef FEAT_SYN_HL 10343 "spell", 10344 #endif 10345 #ifdef FEAT_SYN_HL 10346 "syntax", 10347 #endif 10348 #if defined(USE_SYSTEM) || !defined(UNIX) 10349 "system", 10350 #endif 10351 #ifdef FEAT_TAG_BINS 10352 "tag_binary", 10353 #endif 10354 #ifdef FEAT_TAG_OLDSTATIC 10355 "tag_old_static", 10356 #endif 10357 #ifdef FEAT_TAG_ANYWHITE 10358 "tag_any_white", 10359 #endif 10360 #ifdef FEAT_TCL 10361 # ifndef DYNAMIC_TCL 10362 "tcl", 10363 # endif 10364 #endif 10365 #ifdef TERMINFO 10366 "terminfo", 10367 #endif 10368 #ifdef FEAT_TERMRESPONSE 10369 "termresponse", 10370 #endif 10371 #ifdef FEAT_TEXTOBJ 10372 "textobjects", 10373 #endif 10374 #ifdef HAVE_TGETENT 10375 "tgetent", 10376 #endif 10377 #ifdef FEAT_TITLE 10378 "title", 10379 #endif 10380 #ifdef FEAT_TOOLBAR 10381 "toolbar", 10382 #endif 10383 #ifdef FEAT_USR_CMDS 10384 "user-commands", /* was accidentally included in 5.4 */ 10385 "user_commands", 10386 #endif 10387 #ifdef FEAT_VIMINFO 10388 "viminfo", 10389 #endif 10390 #ifdef FEAT_VERTSPLIT 10391 "vertsplit", 10392 #endif 10393 #ifdef FEAT_VIRTUALEDIT 10394 "virtualedit", 10395 #endif 10396 #ifdef FEAT_VISUAL 10397 "visual", 10398 #endif 10399 #ifdef FEAT_VISUALEXTRA 10400 "visualextra", 10401 #endif 10402 #ifdef FEAT_VREPLACE 10403 "vreplace", 10404 #endif 10405 #ifdef FEAT_WILDIGN 10406 "wildignore", 10407 #endif 10408 #ifdef FEAT_WILDMENU 10409 "wildmenu", 10410 #endif 10411 #ifdef FEAT_WINDOWS 10412 "windows", 10413 #endif 10414 #ifdef FEAT_WAK 10415 "winaltkeys", 10416 #endif 10417 #ifdef FEAT_WRITEBACKUP 10418 "writebackup", 10419 #endif 10420 #ifdef FEAT_XIM 10421 "xim", 10422 #endif 10423 #ifdef FEAT_XFONTSET 10424 "xfontset", 10425 #endif 10426 #ifdef USE_XSMP 10427 "xsmp", 10428 #endif 10429 #ifdef USE_XSMP_INTERACT 10430 "xsmp_interact", 10431 #endif 10432 #ifdef FEAT_XCLIPBOARD 10433 "xterm_clipboard", 10434 #endif 10435 #ifdef FEAT_XTERM_SAVE 10436 "xterm_save", 10437 #endif 10438 #if defined(UNIX) && defined(FEAT_X11) 10439 "X11", 10440 #endif 10441 NULL 10442 }; 10443 10444 name = get_tv_string(&argvars[0]); 10445 for (i = 0; has_list[i] != NULL; ++i) 10446 if (STRICMP(name, has_list[i]) == 0) 10447 { 10448 n = TRUE; 10449 break; 10450 } 10451 10452 if (n == FALSE) 10453 { 10454 if (STRNICMP(name, "patch", 5) == 0) 10455 n = has_patch(atoi((char *)name + 5)); 10456 else if (STRICMP(name, "vim_starting") == 0) 10457 n = (starting != 0); 10458 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10459 else if (STRICMP(name, "balloon_multiline") == 0) 10460 n = multiline_balloon_available(); 10461 #endif 10462 #ifdef DYNAMIC_TCL 10463 else if (STRICMP(name, "tcl") == 0) 10464 n = tcl_enabled(FALSE); 10465 #endif 10466 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10467 else if (STRICMP(name, "iconv") == 0) 10468 n = iconv_enabled(FALSE); 10469 #endif 10470 #ifdef DYNAMIC_MZSCHEME 10471 else if (STRICMP(name, "mzscheme") == 0) 10472 n = mzscheme_enabled(FALSE); 10473 #endif 10474 #ifdef DYNAMIC_RUBY 10475 else if (STRICMP(name, "ruby") == 0) 10476 n = ruby_enabled(FALSE); 10477 #endif 10478 #ifdef DYNAMIC_PYTHON 10479 else if (STRICMP(name, "python") == 0) 10480 n = python_enabled(FALSE); 10481 #endif 10482 #ifdef DYNAMIC_PERL 10483 else if (STRICMP(name, "perl") == 0) 10484 n = perl_enabled(FALSE); 10485 #endif 10486 #ifdef FEAT_GUI 10487 else if (STRICMP(name, "gui_running") == 0) 10488 n = (gui.in_use || gui.starting); 10489 # ifdef FEAT_GUI_W32 10490 else if (STRICMP(name, "gui_win32s") == 0) 10491 n = gui_is_win32s(); 10492 # endif 10493 # ifdef FEAT_BROWSE 10494 else if (STRICMP(name, "browse") == 0) 10495 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10496 # endif 10497 #endif 10498 #ifdef FEAT_SYN_HL 10499 else if (STRICMP(name, "syntax_items") == 0) 10500 n = syntax_present(curbuf); 10501 #endif 10502 #if defined(WIN3264) 10503 else if (STRICMP(name, "win95") == 0) 10504 n = mch_windows95(); 10505 #endif 10506 #ifdef FEAT_NETBEANS_INTG 10507 else if (STRICMP(name, "netbeans_enabled") == 0) 10508 n = usingNetbeans; 10509 #endif 10510 } 10511 10512 rettv->vval.v_number = n; 10513 } 10514 10515 /* 10516 * "has_key()" function 10517 */ 10518 static void 10519 f_has_key(argvars, rettv) 10520 typval_T *argvars; 10521 typval_T *rettv; 10522 { 10523 rettv->vval.v_number = 0; 10524 if (argvars[0].v_type != VAR_DICT) 10525 { 10526 EMSG(_(e_dictreq)); 10527 return; 10528 } 10529 if (argvars[0].vval.v_dict == NULL) 10530 return; 10531 10532 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10533 get_tv_string(&argvars[1]), -1) != NULL; 10534 } 10535 10536 /* 10537 * "hasmapto()" function 10538 */ 10539 static void 10540 f_hasmapto(argvars, rettv) 10541 typval_T *argvars; 10542 typval_T *rettv; 10543 { 10544 char_u *name; 10545 char_u *mode; 10546 char_u buf[NUMBUFLEN]; 10547 10548 name = get_tv_string(&argvars[0]); 10549 if (argvars[1].v_type == VAR_UNKNOWN) 10550 mode = (char_u *)"nvo"; 10551 else 10552 mode = get_tv_string_buf(&argvars[1], buf); 10553 10554 if (map_to_exists(name, mode)) 10555 rettv->vval.v_number = TRUE; 10556 else 10557 rettv->vval.v_number = FALSE; 10558 } 10559 10560 /* 10561 * "histadd()" function 10562 */ 10563 /*ARGSUSED*/ 10564 static void 10565 f_histadd(argvars, rettv) 10566 typval_T *argvars; 10567 typval_T *rettv; 10568 { 10569 #ifdef FEAT_CMDHIST 10570 int histype; 10571 char_u *str; 10572 char_u buf[NUMBUFLEN]; 10573 #endif 10574 10575 rettv->vval.v_number = FALSE; 10576 if (check_restricted() || check_secure()) 10577 return; 10578 #ifdef FEAT_CMDHIST 10579 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10580 histype = str != NULL ? get_histtype(str) : -1; 10581 if (histype >= 0) 10582 { 10583 str = get_tv_string_buf(&argvars[1], buf); 10584 if (*str != NUL) 10585 { 10586 add_to_history(histype, str, FALSE, NUL); 10587 rettv->vval.v_number = TRUE; 10588 return; 10589 } 10590 } 10591 #endif 10592 } 10593 10594 /* 10595 * "histdel()" function 10596 */ 10597 /*ARGSUSED*/ 10598 static void 10599 f_histdel(argvars, rettv) 10600 typval_T *argvars; 10601 typval_T *rettv; 10602 { 10603 #ifdef FEAT_CMDHIST 10604 int n; 10605 char_u buf[NUMBUFLEN]; 10606 char_u *str; 10607 10608 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10609 if (str == NULL) 10610 n = 0; 10611 else if (argvars[1].v_type == VAR_UNKNOWN) 10612 /* only one argument: clear entire history */ 10613 n = clr_history(get_histtype(str)); 10614 else if (argvars[1].v_type == VAR_NUMBER) 10615 /* index given: remove that entry */ 10616 n = del_history_idx(get_histtype(str), 10617 (int)get_tv_number(&argvars[1])); 10618 else 10619 /* string given: remove all matching entries */ 10620 n = del_history_entry(get_histtype(str), 10621 get_tv_string_buf(&argvars[1], buf)); 10622 rettv->vval.v_number = n; 10623 #else 10624 rettv->vval.v_number = 0; 10625 #endif 10626 } 10627 10628 /* 10629 * "histget()" function 10630 */ 10631 /*ARGSUSED*/ 10632 static void 10633 f_histget(argvars, rettv) 10634 typval_T *argvars; 10635 typval_T *rettv; 10636 { 10637 #ifdef FEAT_CMDHIST 10638 int type; 10639 int idx; 10640 char_u *str; 10641 10642 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10643 if (str == NULL) 10644 rettv->vval.v_string = NULL; 10645 else 10646 { 10647 type = get_histtype(str); 10648 if (argvars[1].v_type == VAR_UNKNOWN) 10649 idx = get_history_idx(type); 10650 else 10651 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10652 /* -1 on type error */ 10653 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10654 } 10655 #else 10656 rettv->vval.v_string = NULL; 10657 #endif 10658 rettv->v_type = VAR_STRING; 10659 } 10660 10661 /* 10662 * "histnr()" function 10663 */ 10664 /*ARGSUSED*/ 10665 static void 10666 f_histnr(argvars, rettv) 10667 typval_T *argvars; 10668 typval_T *rettv; 10669 { 10670 int i; 10671 10672 #ifdef FEAT_CMDHIST 10673 char_u *history = get_tv_string_chk(&argvars[0]); 10674 10675 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10676 if (i >= HIST_CMD && i < HIST_COUNT) 10677 i = get_history_idx(i); 10678 else 10679 #endif 10680 i = -1; 10681 rettv->vval.v_number = i; 10682 } 10683 10684 /* 10685 * "highlightID(name)" function 10686 */ 10687 static void 10688 f_hlID(argvars, rettv) 10689 typval_T *argvars; 10690 typval_T *rettv; 10691 { 10692 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10693 } 10694 10695 /* 10696 * "highlight_exists()" function 10697 */ 10698 static void 10699 f_hlexists(argvars, rettv) 10700 typval_T *argvars; 10701 typval_T *rettv; 10702 { 10703 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10704 } 10705 10706 /* 10707 * "hostname()" function 10708 */ 10709 /*ARGSUSED*/ 10710 static void 10711 f_hostname(argvars, rettv) 10712 typval_T *argvars; 10713 typval_T *rettv; 10714 { 10715 char_u hostname[256]; 10716 10717 mch_get_host_name(hostname, 256); 10718 rettv->v_type = VAR_STRING; 10719 rettv->vval.v_string = vim_strsave(hostname); 10720 } 10721 10722 /* 10723 * iconv() function 10724 */ 10725 /*ARGSUSED*/ 10726 static void 10727 f_iconv(argvars, rettv) 10728 typval_T *argvars; 10729 typval_T *rettv; 10730 { 10731 #ifdef FEAT_MBYTE 10732 char_u buf1[NUMBUFLEN]; 10733 char_u buf2[NUMBUFLEN]; 10734 char_u *from, *to, *str; 10735 vimconv_T vimconv; 10736 #endif 10737 10738 rettv->v_type = VAR_STRING; 10739 rettv->vval.v_string = NULL; 10740 10741 #ifdef FEAT_MBYTE 10742 str = get_tv_string(&argvars[0]); 10743 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10744 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10745 vimconv.vc_type = CONV_NONE; 10746 convert_setup(&vimconv, from, to); 10747 10748 /* If the encodings are equal, no conversion needed. */ 10749 if (vimconv.vc_type == CONV_NONE) 10750 rettv->vval.v_string = vim_strsave(str); 10751 else 10752 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10753 10754 convert_setup(&vimconv, NULL, NULL); 10755 vim_free(from); 10756 vim_free(to); 10757 #endif 10758 } 10759 10760 /* 10761 * "indent()" function 10762 */ 10763 static void 10764 f_indent(argvars, rettv) 10765 typval_T *argvars; 10766 typval_T *rettv; 10767 { 10768 linenr_T lnum; 10769 10770 lnum = get_tv_lnum(argvars); 10771 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10772 rettv->vval.v_number = get_indent_lnum(lnum); 10773 else 10774 rettv->vval.v_number = -1; 10775 } 10776 10777 /* 10778 * "index()" function 10779 */ 10780 static void 10781 f_index(argvars, rettv) 10782 typval_T *argvars; 10783 typval_T *rettv; 10784 { 10785 list_T *l; 10786 listitem_T *item; 10787 long idx = 0; 10788 int ic = FALSE; 10789 10790 rettv->vval.v_number = -1; 10791 if (argvars[0].v_type != VAR_LIST) 10792 { 10793 EMSG(_(e_listreq)); 10794 return; 10795 } 10796 l = argvars[0].vval.v_list; 10797 if (l != NULL) 10798 { 10799 item = l->lv_first; 10800 if (argvars[2].v_type != VAR_UNKNOWN) 10801 { 10802 int error = FALSE; 10803 10804 /* Start at specified item. Use the cached index that list_find() 10805 * sets, so that a negative number also works. */ 10806 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10807 idx = l->lv_idx; 10808 if (argvars[3].v_type != VAR_UNKNOWN) 10809 ic = get_tv_number_chk(&argvars[3], &error); 10810 if (error) 10811 item = NULL; 10812 } 10813 10814 for ( ; item != NULL; item = item->li_next, ++idx) 10815 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10816 { 10817 rettv->vval.v_number = idx; 10818 break; 10819 } 10820 } 10821 } 10822 10823 static int inputsecret_flag = 0; 10824 10825 /* 10826 * "input()" function 10827 * Also handles inputsecret() when inputsecret is set. 10828 */ 10829 static void 10830 f_input(argvars, rettv) 10831 typval_T *argvars; 10832 typval_T *rettv; 10833 { 10834 char_u *prompt = get_tv_string_chk(&argvars[0]); 10835 char_u *p = NULL; 10836 int c; 10837 char_u buf[NUMBUFLEN]; 10838 int cmd_silent_save = cmd_silent; 10839 char_u *defstr = (char_u *)""; 10840 int xp_type = EXPAND_NOTHING; 10841 char_u *xp_arg = NULL; 10842 10843 rettv->v_type = VAR_STRING; 10844 10845 #ifdef NO_CONSOLE_INPUT 10846 /* While starting up, there is no place to enter text. */ 10847 if (no_console_input()) 10848 { 10849 rettv->vval.v_string = NULL; 10850 return; 10851 } 10852 #endif 10853 10854 cmd_silent = FALSE; /* Want to see the prompt. */ 10855 if (prompt != NULL) 10856 { 10857 /* Only the part of the message after the last NL is considered as 10858 * prompt for the command line */ 10859 p = vim_strrchr(prompt, '\n'); 10860 if (p == NULL) 10861 p = prompt; 10862 else 10863 { 10864 ++p; 10865 c = *p; 10866 *p = NUL; 10867 msg_start(); 10868 msg_clr_eos(); 10869 msg_puts_attr(prompt, echo_attr); 10870 msg_didout = FALSE; 10871 msg_starthere(); 10872 *p = c; 10873 } 10874 cmdline_row = msg_row; 10875 10876 if (argvars[1].v_type != VAR_UNKNOWN) 10877 { 10878 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10879 if (defstr != NULL) 10880 stuffReadbuffSpec(defstr); 10881 10882 if (argvars[2].v_type != VAR_UNKNOWN) 10883 { 10884 char_u *xp_name; 10885 int xp_namelen; 10886 long argt; 10887 10888 rettv->vval.v_string = NULL; 10889 10890 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 10891 if (xp_name == NULL) 10892 return; 10893 10894 xp_namelen = STRLEN(xp_name); 10895 10896 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 10897 &xp_arg) == FAIL) 10898 return; 10899 } 10900 } 10901 10902 if (defstr != NULL) 10903 rettv->vval.v_string = 10904 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 10905 xp_type, xp_arg); 10906 10907 vim_free(xp_arg); 10908 10909 /* since the user typed this, no need to wait for return */ 10910 need_wait_return = FALSE; 10911 msg_didout = FALSE; 10912 } 10913 cmd_silent = cmd_silent_save; 10914 } 10915 10916 /* 10917 * "inputdialog()" function 10918 */ 10919 static void 10920 f_inputdialog(argvars, rettv) 10921 typval_T *argvars; 10922 typval_T *rettv; 10923 { 10924 #if defined(FEAT_GUI_TEXTDIALOG) 10925 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10926 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10927 { 10928 char_u *message; 10929 char_u buf[NUMBUFLEN]; 10930 char_u *defstr = (char_u *)""; 10931 10932 message = get_tv_string_chk(&argvars[0]); 10933 if (argvars[1].v_type != VAR_UNKNOWN 10934 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10935 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10936 else 10937 IObuff[0] = NUL; 10938 if (message != NULL && defstr != NULL 10939 && do_dialog(VIM_QUESTION, NULL, message, 10940 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10941 rettv->vval.v_string = vim_strsave(IObuff); 10942 else 10943 { 10944 if (message != NULL && defstr != NULL 10945 && argvars[1].v_type != VAR_UNKNOWN 10946 && argvars[2].v_type != VAR_UNKNOWN) 10947 rettv->vval.v_string = vim_strsave( 10948 get_tv_string_buf(&argvars[2], buf)); 10949 else 10950 rettv->vval.v_string = NULL; 10951 } 10952 rettv->v_type = VAR_STRING; 10953 } 10954 else 10955 #endif 10956 f_input(argvars, rettv); 10957 } 10958 10959 /* 10960 * "inputlist()" function 10961 */ 10962 static void 10963 f_inputlist(argvars, rettv) 10964 typval_T *argvars; 10965 typval_T *rettv; 10966 { 10967 listitem_T *li; 10968 int selected; 10969 int mouse_used; 10970 10971 rettv->vval.v_number = 0; 10972 #ifdef NO_CONSOLE_INPUT 10973 /* While starting up, there is no place to enter text. */ 10974 if (no_console_input()) 10975 return; 10976 #endif 10977 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 10978 { 10979 EMSG2(_(e_listarg), "inputlist()"); 10980 return; 10981 } 10982 10983 msg_start(); 10984 lines_left = Rows; /* avoid more prompt */ 10985 msg_scroll = TRUE; 10986 msg_clr_eos(); 10987 10988 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 10989 { 10990 msg_puts(get_tv_string(&li->li_tv)); 10991 msg_putchar('\n'); 10992 } 10993 10994 /* Ask for choice. */ 10995 selected = prompt_for_number(&mouse_used); 10996 if (mouse_used) 10997 selected -= lines_left; 10998 10999 rettv->vval.v_number = selected; 11000 } 11001 11002 11003 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 11004 11005 /* 11006 * "inputrestore()" function 11007 */ 11008 /*ARGSUSED*/ 11009 static void 11010 f_inputrestore(argvars, rettv) 11011 typval_T *argvars; 11012 typval_T *rettv; 11013 { 11014 if (ga_userinput.ga_len > 0) 11015 { 11016 --ga_userinput.ga_len; 11017 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 11018 + ga_userinput.ga_len); 11019 rettv->vval.v_number = 0; /* OK */ 11020 } 11021 else if (p_verbose > 1) 11022 { 11023 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11024 rettv->vval.v_number = 1; /* Failed */ 11025 } 11026 } 11027 11028 /* 11029 * "inputsave()" function 11030 */ 11031 /*ARGSUSED*/ 11032 static void 11033 f_inputsave(argvars, rettv) 11034 typval_T *argvars; 11035 typval_T *rettv; 11036 { 11037 /* Add an entry to the stack of typehead storage. */ 11038 if (ga_grow(&ga_userinput, 1) == OK) 11039 { 11040 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11041 + ga_userinput.ga_len); 11042 ++ga_userinput.ga_len; 11043 rettv->vval.v_number = 0; /* OK */ 11044 } 11045 else 11046 rettv->vval.v_number = 1; /* Failed */ 11047 } 11048 11049 /* 11050 * "inputsecret()" function 11051 */ 11052 static void 11053 f_inputsecret(argvars, rettv) 11054 typval_T *argvars; 11055 typval_T *rettv; 11056 { 11057 ++cmdline_star; 11058 ++inputsecret_flag; 11059 f_input(argvars, rettv); 11060 --cmdline_star; 11061 --inputsecret_flag; 11062 } 11063 11064 /* 11065 * "insert()" function 11066 */ 11067 static void 11068 f_insert(argvars, rettv) 11069 typval_T *argvars; 11070 typval_T *rettv; 11071 { 11072 long before = 0; 11073 listitem_T *item; 11074 list_T *l; 11075 int error = FALSE; 11076 11077 rettv->vval.v_number = 0; 11078 if (argvars[0].v_type != VAR_LIST) 11079 EMSG2(_(e_listarg), "insert()"); 11080 else if ((l = argvars[0].vval.v_list) != NULL 11081 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11082 { 11083 if (argvars[2].v_type != VAR_UNKNOWN) 11084 before = get_tv_number_chk(&argvars[2], &error); 11085 if (error) 11086 return; /* type error; errmsg already given */ 11087 11088 if (before == l->lv_len) 11089 item = NULL; 11090 else 11091 { 11092 item = list_find(l, before); 11093 if (item == NULL) 11094 { 11095 EMSGN(_(e_listidx), before); 11096 l = NULL; 11097 } 11098 } 11099 if (l != NULL) 11100 { 11101 list_insert_tv(l, &argvars[1], item); 11102 copy_tv(&argvars[0], rettv); 11103 } 11104 } 11105 } 11106 11107 /* 11108 * "isdirectory()" function 11109 */ 11110 static void 11111 f_isdirectory(argvars, rettv) 11112 typval_T *argvars; 11113 typval_T *rettv; 11114 { 11115 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11116 } 11117 11118 /* 11119 * "islocked()" function 11120 */ 11121 static void 11122 f_islocked(argvars, rettv) 11123 typval_T *argvars; 11124 typval_T *rettv; 11125 { 11126 lval_T lv; 11127 char_u *end; 11128 dictitem_T *di; 11129 11130 rettv->vval.v_number = -1; 11131 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11132 FNE_CHECK_START); 11133 if (end != NULL && lv.ll_name != NULL) 11134 { 11135 if (*end != NUL) 11136 EMSG(_(e_trailing)); 11137 else 11138 { 11139 if (lv.ll_tv == NULL) 11140 { 11141 if (check_changedtick(lv.ll_name)) 11142 rettv->vval.v_number = 1; /* always locked */ 11143 else 11144 { 11145 di = find_var(lv.ll_name, NULL); 11146 if (di != NULL) 11147 { 11148 /* Consider a variable locked when: 11149 * 1. the variable itself is locked 11150 * 2. the value of the variable is locked. 11151 * 3. the List or Dict value is locked. 11152 */ 11153 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11154 || tv_islocked(&di->di_tv)); 11155 } 11156 } 11157 } 11158 else if (lv.ll_range) 11159 EMSG(_("E745: Range not allowed")); 11160 else if (lv.ll_newkey != NULL) 11161 EMSG2(_(e_dictkey), lv.ll_newkey); 11162 else if (lv.ll_list != NULL) 11163 /* List item. */ 11164 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11165 else 11166 /* Dictionary item. */ 11167 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11168 } 11169 } 11170 11171 clear_lval(&lv); 11172 } 11173 11174 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11175 11176 /* 11177 * Turn a dict into a list: 11178 * "what" == 0: list of keys 11179 * "what" == 1: list of values 11180 * "what" == 2: list of items 11181 */ 11182 static void 11183 dict_list(argvars, rettv, what) 11184 typval_T *argvars; 11185 typval_T *rettv; 11186 int what; 11187 { 11188 list_T *l; 11189 list_T *l2; 11190 dictitem_T *di; 11191 hashitem_T *hi; 11192 listitem_T *li; 11193 listitem_T *li2; 11194 dict_T *d; 11195 int todo; 11196 11197 rettv->vval.v_number = 0; 11198 if (argvars[0].v_type != VAR_DICT) 11199 { 11200 EMSG(_(e_dictreq)); 11201 return; 11202 } 11203 if ((d = argvars[0].vval.v_dict) == NULL) 11204 return; 11205 11206 l = list_alloc(); 11207 if (l == NULL) 11208 return; 11209 rettv->v_type = VAR_LIST; 11210 rettv->vval.v_list = l; 11211 ++l->lv_refcount; 11212 11213 todo = d->dv_hashtab.ht_used; 11214 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11215 { 11216 if (!HASHITEM_EMPTY(hi)) 11217 { 11218 --todo; 11219 di = HI2DI(hi); 11220 11221 li = listitem_alloc(); 11222 if (li == NULL) 11223 break; 11224 list_append(l, li); 11225 11226 if (what == 0) 11227 { 11228 /* keys() */ 11229 li->li_tv.v_type = VAR_STRING; 11230 li->li_tv.v_lock = 0; 11231 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11232 } 11233 else if (what == 1) 11234 { 11235 /* values() */ 11236 copy_tv(&di->di_tv, &li->li_tv); 11237 } 11238 else 11239 { 11240 /* items() */ 11241 l2 = list_alloc(); 11242 li->li_tv.v_type = VAR_LIST; 11243 li->li_tv.v_lock = 0; 11244 li->li_tv.vval.v_list = l2; 11245 if (l2 == NULL) 11246 break; 11247 ++l2->lv_refcount; 11248 11249 li2 = listitem_alloc(); 11250 if (li2 == NULL) 11251 break; 11252 list_append(l2, li2); 11253 li2->li_tv.v_type = VAR_STRING; 11254 li2->li_tv.v_lock = 0; 11255 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11256 11257 li2 = listitem_alloc(); 11258 if (li2 == NULL) 11259 break; 11260 list_append(l2, li2); 11261 copy_tv(&di->di_tv, &li2->li_tv); 11262 } 11263 } 11264 } 11265 } 11266 11267 /* 11268 * "items(dict)" function 11269 */ 11270 static void 11271 f_items(argvars, rettv) 11272 typval_T *argvars; 11273 typval_T *rettv; 11274 { 11275 dict_list(argvars, rettv, 2); 11276 } 11277 11278 /* 11279 * "join()" function 11280 */ 11281 static void 11282 f_join(argvars, rettv) 11283 typval_T *argvars; 11284 typval_T *rettv; 11285 { 11286 garray_T ga; 11287 char_u *sep; 11288 11289 rettv->vval.v_number = 0; 11290 if (argvars[0].v_type != VAR_LIST) 11291 { 11292 EMSG(_(e_listreq)); 11293 return; 11294 } 11295 if (argvars[0].vval.v_list == NULL) 11296 return; 11297 if (argvars[1].v_type == VAR_UNKNOWN) 11298 sep = (char_u *)" "; 11299 else 11300 sep = get_tv_string_chk(&argvars[1]); 11301 11302 rettv->v_type = VAR_STRING; 11303 11304 if (sep != NULL) 11305 { 11306 ga_init2(&ga, (int)sizeof(char), 80); 11307 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11308 ga_append(&ga, NUL); 11309 rettv->vval.v_string = (char_u *)ga.ga_data; 11310 } 11311 else 11312 rettv->vval.v_string = NULL; 11313 } 11314 11315 /* 11316 * "keys()" function 11317 */ 11318 static void 11319 f_keys(argvars, rettv) 11320 typval_T *argvars; 11321 typval_T *rettv; 11322 { 11323 dict_list(argvars, rettv, 0); 11324 } 11325 11326 /* 11327 * "last_buffer_nr()" function. 11328 */ 11329 /*ARGSUSED*/ 11330 static void 11331 f_last_buffer_nr(argvars, rettv) 11332 typval_T *argvars; 11333 typval_T *rettv; 11334 { 11335 int n = 0; 11336 buf_T *buf; 11337 11338 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11339 if (n < buf->b_fnum) 11340 n = buf->b_fnum; 11341 11342 rettv->vval.v_number = n; 11343 } 11344 11345 /* 11346 * "len()" function 11347 */ 11348 static void 11349 f_len(argvars, rettv) 11350 typval_T *argvars; 11351 typval_T *rettv; 11352 { 11353 switch (argvars[0].v_type) 11354 { 11355 case VAR_STRING: 11356 case VAR_NUMBER: 11357 rettv->vval.v_number = (varnumber_T)STRLEN( 11358 get_tv_string(&argvars[0])); 11359 break; 11360 case VAR_LIST: 11361 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11362 break; 11363 case VAR_DICT: 11364 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11365 break; 11366 default: 11367 EMSG(_("E701: Invalid type for len()")); 11368 break; 11369 } 11370 } 11371 11372 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11373 11374 static void 11375 libcall_common(argvars, rettv, type) 11376 typval_T *argvars; 11377 typval_T *rettv; 11378 int type; 11379 { 11380 #ifdef FEAT_LIBCALL 11381 char_u *string_in; 11382 char_u **string_result; 11383 int nr_result; 11384 #endif 11385 11386 rettv->v_type = type; 11387 if (type == VAR_NUMBER) 11388 rettv->vval.v_number = 0; 11389 else 11390 rettv->vval.v_string = NULL; 11391 11392 if (check_restricted() || check_secure()) 11393 return; 11394 11395 #ifdef FEAT_LIBCALL 11396 /* The first two args must be strings, otherwise its meaningless */ 11397 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11398 { 11399 string_in = NULL; 11400 if (argvars[2].v_type == VAR_STRING) 11401 string_in = argvars[2].vval.v_string; 11402 if (type == VAR_NUMBER) 11403 string_result = NULL; 11404 else 11405 string_result = &rettv->vval.v_string; 11406 if (mch_libcall(argvars[0].vval.v_string, 11407 argvars[1].vval.v_string, 11408 string_in, 11409 argvars[2].vval.v_number, 11410 string_result, 11411 &nr_result) == OK 11412 && type == VAR_NUMBER) 11413 rettv->vval.v_number = nr_result; 11414 } 11415 #endif 11416 } 11417 11418 /* 11419 * "libcall()" function 11420 */ 11421 static void 11422 f_libcall(argvars, rettv) 11423 typval_T *argvars; 11424 typval_T *rettv; 11425 { 11426 libcall_common(argvars, rettv, VAR_STRING); 11427 } 11428 11429 /* 11430 * "libcallnr()" function 11431 */ 11432 static void 11433 f_libcallnr(argvars, rettv) 11434 typval_T *argvars; 11435 typval_T *rettv; 11436 { 11437 libcall_common(argvars, rettv, VAR_NUMBER); 11438 } 11439 11440 /* 11441 * "line(string)" function 11442 */ 11443 static void 11444 f_line(argvars, rettv) 11445 typval_T *argvars; 11446 typval_T *rettv; 11447 { 11448 linenr_T lnum = 0; 11449 pos_T *fp; 11450 11451 fp = var2fpos(&argvars[0], TRUE); 11452 if (fp != NULL) 11453 lnum = fp->lnum; 11454 rettv->vval.v_number = lnum; 11455 } 11456 11457 /* 11458 * "line2byte(lnum)" function 11459 */ 11460 /*ARGSUSED*/ 11461 static void 11462 f_line2byte(argvars, rettv) 11463 typval_T *argvars; 11464 typval_T *rettv; 11465 { 11466 #ifndef FEAT_BYTEOFF 11467 rettv->vval.v_number = -1; 11468 #else 11469 linenr_T lnum; 11470 11471 lnum = get_tv_lnum(argvars); 11472 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11473 rettv->vval.v_number = -1; 11474 else 11475 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11476 if (rettv->vval.v_number >= 0) 11477 ++rettv->vval.v_number; 11478 #endif 11479 } 11480 11481 /* 11482 * "lispindent(lnum)" function 11483 */ 11484 static void 11485 f_lispindent(argvars, rettv) 11486 typval_T *argvars; 11487 typval_T *rettv; 11488 { 11489 #ifdef FEAT_LISP 11490 pos_T pos; 11491 linenr_T lnum; 11492 11493 pos = curwin->w_cursor; 11494 lnum = get_tv_lnum(argvars); 11495 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11496 { 11497 curwin->w_cursor.lnum = lnum; 11498 rettv->vval.v_number = get_lisp_indent(); 11499 curwin->w_cursor = pos; 11500 } 11501 else 11502 #endif 11503 rettv->vval.v_number = -1; 11504 } 11505 11506 /* 11507 * "localtime()" function 11508 */ 11509 /*ARGSUSED*/ 11510 static void 11511 f_localtime(argvars, rettv) 11512 typval_T *argvars; 11513 typval_T *rettv; 11514 { 11515 rettv->vval.v_number = (varnumber_T)time(NULL); 11516 } 11517 11518 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11519 11520 static void 11521 get_maparg(argvars, rettv, exact) 11522 typval_T *argvars; 11523 typval_T *rettv; 11524 int exact; 11525 { 11526 char_u *keys; 11527 char_u *which; 11528 char_u buf[NUMBUFLEN]; 11529 char_u *keys_buf = NULL; 11530 char_u *rhs; 11531 int mode; 11532 garray_T ga; 11533 11534 /* return empty string for failure */ 11535 rettv->v_type = VAR_STRING; 11536 rettv->vval.v_string = NULL; 11537 11538 keys = get_tv_string(&argvars[0]); 11539 if (*keys == NUL) 11540 return; 11541 11542 if (argvars[1].v_type != VAR_UNKNOWN) 11543 which = get_tv_string_buf_chk(&argvars[1], buf); 11544 else 11545 which = (char_u *)""; 11546 if (which == NULL) 11547 return; 11548 11549 mode = get_map_mode(&which, 0); 11550 11551 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11552 rhs = check_map(keys, mode, exact, FALSE); 11553 vim_free(keys_buf); 11554 if (rhs != NULL) 11555 { 11556 ga_init(&ga); 11557 ga.ga_itemsize = 1; 11558 ga.ga_growsize = 40; 11559 11560 while (*rhs != NUL) 11561 ga_concat(&ga, str2special(&rhs, FALSE)); 11562 11563 ga_append(&ga, NUL); 11564 rettv->vval.v_string = (char_u *)ga.ga_data; 11565 } 11566 } 11567 11568 /* 11569 * "map()" function 11570 */ 11571 static void 11572 f_map(argvars, rettv) 11573 typval_T *argvars; 11574 typval_T *rettv; 11575 { 11576 filter_map(argvars, rettv, TRUE); 11577 } 11578 11579 /* 11580 * "maparg()" function 11581 */ 11582 static void 11583 f_maparg(argvars, rettv) 11584 typval_T *argvars; 11585 typval_T *rettv; 11586 { 11587 get_maparg(argvars, rettv, TRUE); 11588 } 11589 11590 /* 11591 * "mapcheck()" function 11592 */ 11593 static void 11594 f_mapcheck(argvars, rettv) 11595 typval_T *argvars; 11596 typval_T *rettv; 11597 { 11598 get_maparg(argvars, rettv, FALSE); 11599 } 11600 11601 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11602 11603 static void 11604 find_some_match(argvars, rettv, type) 11605 typval_T *argvars; 11606 typval_T *rettv; 11607 int type; 11608 { 11609 char_u *str = NULL; 11610 char_u *expr = NULL; 11611 char_u *pat; 11612 regmatch_T regmatch; 11613 char_u patbuf[NUMBUFLEN]; 11614 char_u strbuf[NUMBUFLEN]; 11615 char_u *save_cpo; 11616 long start = 0; 11617 long nth = 1; 11618 int match = 0; 11619 list_T *l = NULL; 11620 listitem_T *li = NULL; 11621 long idx = 0; 11622 char_u *tofree = NULL; 11623 11624 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11625 save_cpo = p_cpo; 11626 p_cpo = (char_u *)""; 11627 11628 rettv->vval.v_number = -1; 11629 if (type == 3) 11630 { 11631 /* return empty list when there are no matches */ 11632 if ((rettv->vval.v_list = list_alloc()) == NULL) 11633 goto theend; 11634 rettv->v_type = VAR_LIST; 11635 ++rettv->vval.v_list->lv_refcount; 11636 } 11637 else if (type == 2) 11638 { 11639 rettv->v_type = VAR_STRING; 11640 rettv->vval.v_string = NULL; 11641 } 11642 11643 if (argvars[0].v_type == VAR_LIST) 11644 { 11645 if ((l = argvars[0].vval.v_list) == NULL) 11646 goto theend; 11647 li = l->lv_first; 11648 } 11649 else 11650 expr = str = get_tv_string(&argvars[0]); 11651 11652 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11653 if (pat == NULL) 11654 goto theend; 11655 11656 if (argvars[2].v_type != VAR_UNKNOWN) 11657 { 11658 int error = FALSE; 11659 11660 start = get_tv_number_chk(&argvars[2], &error); 11661 if (error) 11662 goto theend; 11663 if (l != NULL) 11664 { 11665 li = list_find(l, start); 11666 if (li == NULL) 11667 goto theend; 11668 idx = l->lv_idx; /* use the cached index */ 11669 } 11670 else 11671 { 11672 if (start < 0) 11673 start = 0; 11674 if (start > (long)STRLEN(str)) 11675 goto theend; 11676 str += start; 11677 } 11678 11679 if (argvars[3].v_type != VAR_UNKNOWN) 11680 nth = get_tv_number_chk(&argvars[3], &error); 11681 if (error) 11682 goto theend; 11683 } 11684 11685 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11686 if (regmatch.regprog != NULL) 11687 { 11688 regmatch.rm_ic = p_ic; 11689 11690 for (;;) 11691 { 11692 if (l != NULL) 11693 { 11694 if (li == NULL) 11695 { 11696 match = FALSE; 11697 break; 11698 } 11699 vim_free(tofree); 11700 str = echo_string(&li->li_tv, &tofree, strbuf); 11701 if (str == NULL) 11702 break; 11703 } 11704 11705 match = vim_regexec_nl(®match, str, (colnr_T)0); 11706 11707 if (match && --nth <= 0) 11708 break; 11709 if (l == NULL && !match) 11710 break; 11711 11712 /* Advance to just after the match. */ 11713 if (l != NULL) 11714 { 11715 li = li->li_next; 11716 ++idx; 11717 } 11718 else 11719 { 11720 #ifdef FEAT_MBYTE 11721 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11722 #else 11723 str = regmatch.startp[0] + 1; 11724 #endif 11725 } 11726 } 11727 11728 if (match) 11729 { 11730 if (type == 3) 11731 { 11732 int i; 11733 11734 /* return list with matched string and submatches */ 11735 for (i = 0; i < NSUBEXP; ++i) 11736 { 11737 if (regmatch.endp[i] == NULL) 11738 break; 11739 if (list_append_string(rettv->vval.v_list, 11740 regmatch.startp[i], 11741 (int)(regmatch.endp[i] - regmatch.startp[i])) 11742 == FAIL) 11743 break; 11744 } 11745 } 11746 else if (type == 2) 11747 { 11748 /* return matched string */ 11749 if (l != NULL) 11750 copy_tv(&li->li_tv, rettv); 11751 else 11752 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11753 (int)(regmatch.endp[0] - regmatch.startp[0])); 11754 } 11755 else if (l != NULL) 11756 rettv->vval.v_number = idx; 11757 else 11758 { 11759 if (type != 0) 11760 rettv->vval.v_number = 11761 (varnumber_T)(regmatch.startp[0] - str); 11762 else 11763 rettv->vval.v_number = 11764 (varnumber_T)(regmatch.endp[0] - str); 11765 rettv->vval.v_number += str - expr; 11766 } 11767 } 11768 vim_free(regmatch.regprog); 11769 } 11770 11771 theend: 11772 vim_free(tofree); 11773 p_cpo = save_cpo; 11774 } 11775 11776 /* 11777 * "match()" function 11778 */ 11779 static void 11780 f_match(argvars, rettv) 11781 typval_T *argvars; 11782 typval_T *rettv; 11783 { 11784 find_some_match(argvars, rettv, 1); 11785 } 11786 11787 /* 11788 * "matchend()" function 11789 */ 11790 static void 11791 f_matchend(argvars, rettv) 11792 typval_T *argvars; 11793 typval_T *rettv; 11794 { 11795 find_some_match(argvars, rettv, 0); 11796 } 11797 11798 /* 11799 * "matchlist()" function 11800 */ 11801 static void 11802 f_matchlist(argvars, rettv) 11803 typval_T *argvars; 11804 typval_T *rettv; 11805 { 11806 find_some_match(argvars, rettv, 3); 11807 } 11808 11809 /* 11810 * "matchstr()" function 11811 */ 11812 static void 11813 f_matchstr(argvars, rettv) 11814 typval_T *argvars; 11815 typval_T *rettv; 11816 { 11817 find_some_match(argvars, rettv, 2); 11818 } 11819 11820 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11821 11822 static void 11823 max_min(argvars, rettv, domax) 11824 typval_T *argvars; 11825 typval_T *rettv; 11826 int domax; 11827 { 11828 long n = 0; 11829 long i; 11830 int error = FALSE; 11831 11832 if (argvars[0].v_type == VAR_LIST) 11833 { 11834 list_T *l; 11835 listitem_T *li; 11836 11837 l = argvars[0].vval.v_list; 11838 if (l != NULL) 11839 { 11840 li = l->lv_first; 11841 if (li != NULL) 11842 { 11843 n = get_tv_number_chk(&li->li_tv, &error); 11844 for (;;) 11845 { 11846 li = li->li_next; 11847 if (li == NULL) 11848 break; 11849 i = get_tv_number_chk(&li->li_tv, &error); 11850 if (domax ? i > n : i < n) 11851 n = i; 11852 } 11853 } 11854 } 11855 } 11856 else if (argvars[0].v_type == VAR_DICT) 11857 { 11858 dict_T *d; 11859 int first = TRUE; 11860 hashitem_T *hi; 11861 int todo; 11862 11863 d = argvars[0].vval.v_dict; 11864 if (d != NULL) 11865 { 11866 todo = d->dv_hashtab.ht_used; 11867 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11868 { 11869 if (!HASHITEM_EMPTY(hi)) 11870 { 11871 --todo; 11872 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11873 if (first) 11874 { 11875 n = i; 11876 first = FALSE; 11877 } 11878 else if (domax ? i > n : i < n) 11879 n = i; 11880 } 11881 } 11882 } 11883 } 11884 else 11885 EMSG(_(e_listdictarg)); 11886 rettv->vval.v_number = error ? 0 : n; 11887 } 11888 11889 /* 11890 * "max()" function 11891 */ 11892 static void 11893 f_max(argvars, rettv) 11894 typval_T *argvars; 11895 typval_T *rettv; 11896 { 11897 max_min(argvars, rettv, TRUE); 11898 } 11899 11900 /* 11901 * "min()" function 11902 */ 11903 static void 11904 f_min(argvars, rettv) 11905 typval_T *argvars; 11906 typval_T *rettv; 11907 { 11908 max_min(argvars, rettv, FALSE); 11909 } 11910 11911 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11912 11913 /* 11914 * Create the directory in which "dir" is located, and higher levels when 11915 * needed. 11916 */ 11917 static int 11918 mkdir_recurse(dir, prot) 11919 char_u *dir; 11920 int prot; 11921 { 11922 char_u *p; 11923 char_u *updir; 11924 int r = FAIL; 11925 11926 /* Get end of directory name in "dir". 11927 * We're done when it's "/" or "c:/". */ 11928 p = gettail_sep(dir); 11929 if (p <= get_past_head(dir)) 11930 return OK; 11931 11932 /* If the directory exists we're done. Otherwise: create it.*/ 11933 updir = vim_strnsave(dir, (int)(p - dir)); 11934 if (updir == NULL) 11935 return FAIL; 11936 if (mch_isdir(updir)) 11937 r = OK; 11938 else if (mkdir_recurse(updir, prot) == OK) 11939 r = vim_mkdir_emsg(updir, prot); 11940 vim_free(updir); 11941 return r; 11942 } 11943 11944 #ifdef vim_mkdir 11945 /* 11946 * "mkdir()" function 11947 */ 11948 static void 11949 f_mkdir(argvars, rettv) 11950 typval_T *argvars; 11951 typval_T *rettv; 11952 { 11953 char_u *dir; 11954 char_u buf[NUMBUFLEN]; 11955 int prot = 0755; 11956 11957 rettv->vval.v_number = FAIL; 11958 if (check_restricted() || check_secure()) 11959 return; 11960 11961 dir = get_tv_string_buf(&argvars[0], buf); 11962 if (argvars[1].v_type != VAR_UNKNOWN) 11963 { 11964 if (argvars[2].v_type != VAR_UNKNOWN) 11965 prot = get_tv_number_chk(&argvars[2], NULL); 11966 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11967 mkdir_recurse(dir, prot); 11968 } 11969 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11970 } 11971 #endif 11972 11973 /* 11974 * "mode()" function 11975 */ 11976 /*ARGSUSED*/ 11977 static void 11978 f_mode(argvars, rettv) 11979 typval_T *argvars; 11980 typval_T *rettv; 11981 { 11982 char_u buf[2]; 11983 11984 #ifdef FEAT_VISUAL 11985 if (VIsual_active) 11986 { 11987 if (VIsual_select) 11988 buf[0] = VIsual_mode + 's' - 'v'; 11989 else 11990 buf[0] = VIsual_mode; 11991 } 11992 else 11993 #endif 11994 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11995 buf[0] = 'r'; 11996 else if (State & INSERT) 11997 { 11998 if (State & REPLACE_FLAG) 11999 buf[0] = 'R'; 12000 else 12001 buf[0] = 'i'; 12002 } 12003 else if (State & CMDLINE) 12004 buf[0] = 'c'; 12005 else 12006 buf[0] = 'n'; 12007 12008 buf[1] = NUL; 12009 rettv->vval.v_string = vim_strsave(buf); 12010 rettv->v_type = VAR_STRING; 12011 } 12012 12013 /* 12014 * "nextnonblank()" function 12015 */ 12016 static void 12017 f_nextnonblank(argvars, rettv) 12018 typval_T *argvars; 12019 typval_T *rettv; 12020 { 12021 linenr_T lnum; 12022 12023 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12024 { 12025 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12026 { 12027 lnum = 0; 12028 break; 12029 } 12030 if (*skipwhite(ml_get(lnum)) != NUL) 12031 break; 12032 } 12033 rettv->vval.v_number = lnum; 12034 } 12035 12036 /* 12037 * "nr2char()" function 12038 */ 12039 static void 12040 f_nr2char(argvars, rettv) 12041 typval_T *argvars; 12042 typval_T *rettv; 12043 { 12044 char_u buf[NUMBUFLEN]; 12045 12046 #ifdef FEAT_MBYTE 12047 if (has_mbyte) 12048 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12049 else 12050 #endif 12051 { 12052 buf[0] = (char_u)get_tv_number(&argvars[0]); 12053 buf[1] = NUL; 12054 } 12055 rettv->v_type = VAR_STRING; 12056 rettv->vval.v_string = vim_strsave(buf); 12057 } 12058 12059 /* 12060 * "prevnonblank()" function 12061 */ 12062 static void 12063 f_prevnonblank(argvars, rettv) 12064 typval_T *argvars; 12065 typval_T *rettv; 12066 { 12067 linenr_T lnum; 12068 12069 lnum = get_tv_lnum(argvars); 12070 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12071 lnum = 0; 12072 else 12073 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12074 --lnum; 12075 rettv->vval.v_number = lnum; 12076 } 12077 12078 #ifdef HAVE_STDARG_H 12079 /* This dummy va_list is here because: 12080 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12081 * - locally in the function results in a "used before set" warning 12082 * - using va_start() to initialize it gives "function with fixed args" error */ 12083 static va_list ap; 12084 #endif 12085 12086 /* 12087 * "printf()" function 12088 */ 12089 static void 12090 f_printf(argvars, rettv) 12091 typval_T *argvars; 12092 typval_T *rettv; 12093 { 12094 rettv->v_type = VAR_STRING; 12095 rettv->vval.v_string = NULL; 12096 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12097 { 12098 char_u buf[NUMBUFLEN]; 12099 int len; 12100 char_u *s; 12101 int saved_did_emsg = did_emsg; 12102 char *fmt; 12103 12104 /* Get the required length, allocate the buffer and do it for real. */ 12105 did_emsg = FALSE; 12106 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12107 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12108 if (!did_emsg) 12109 { 12110 s = alloc(len + 1); 12111 if (s != NULL) 12112 { 12113 rettv->vval.v_string = s; 12114 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12115 } 12116 } 12117 did_emsg |= saved_did_emsg; 12118 } 12119 #endif 12120 } 12121 12122 /* 12123 * "range()" function 12124 */ 12125 static void 12126 f_range(argvars, rettv) 12127 typval_T *argvars; 12128 typval_T *rettv; 12129 { 12130 long start; 12131 long end; 12132 long stride = 1; 12133 long i; 12134 list_T *l; 12135 int error = FALSE; 12136 12137 start = get_tv_number_chk(&argvars[0], &error); 12138 if (argvars[1].v_type == VAR_UNKNOWN) 12139 { 12140 end = start - 1; 12141 start = 0; 12142 } 12143 else 12144 { 12145 end = get_tv_number_chk(&argvars[1], &error); 12146 if (argvars[2].v_type != VAR_UNKNOWN) 12147 stride = get_tv_number_chk(&argvars[2], &error); 12148 } 12149 12150 rettv->vval.v_number = 0; 12151 if (error) 12152 return; /* type error; errmsg already given */ 12153 if (stride == 0) 12154 EMSG(_("E726: Stride is zero")); 12155 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12156 EMSG(_("E727: Start past end")); 12157 else 12158 { 12159 l = list_alloc(); 12160 if (l != NULL) 12161 { 12162 rettv->v_type = VAR_LIST; 12163 rettv->vval.v_list = l; 12164 ++l->lv_refcount; 12165 12166 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12167 if (list_append_number(l, (varnumber_T)i) == FAIL) 12168 break; 12169 } 12170 } 12171 } 12172 12173 /* 12174 * "readfile()" function 12175 */ 12176 static void 12177 f_readfile(argvars, rettv) 12178 typval_T *argvars; 12179 typval_T *rettv; 12180 { 12181 int binary = FALSE; 12182 char_u *fname; 12183 FILE *fd; 12184 list_T *l; 12185 listitem_T *li; 12186 #define FREAD_SIZE 200 /* optimized for text lines */ 12187 char_u buf[FREAD_SIZE]; 12188 int readlen; /* size of last fread() */ 12189 int buflen; /* nr of valid chars in buf[] */ 12190 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12191 int tolist; /* first byte in buf[] still to be put in list */ 12192 int chop; /* how many CR to chop off */ 12193 char_u *prev = NULL; /* previously read bytes, if any */ 12194 int prevlen = 0; /* length of "prev" if not NULL */ 12195 char_u *s; 12196 int len; 12197 long maxline = MAXLNUM; 12198 long cnt = 0; 12199 12200 if (argvars[1].v_type != VAR_UNKNOWN) 12201 { 12202 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12203 binary = TRUE; 12204 if (argvars[2].v_type != VAR_UNKNOWN) 12205 maxline = get_tv_number(&argvars[2]); 12206 } 12207 12208 l = list_alloc(); 12209 if (l == NULL) 12210 return; 12211 rettv->v_type = VAR_LIST; 12212 rettv->vval.v_list = l; 12213 l->lv_refcount = 1; 12214 12215 /* Always open the file in binary mode, library functions have a mind of 12216 * their own about CR-LF conversion. */ 12217 fname = get_tv_string(&argvars[0]); 12218 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12219 { 12220 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12221 return; 12222 } 12223 12224 filtd = 0; 12225 while (cnt < maxline || maxline < 0) 12226 { 12227 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12228 buflen = filtd + readlen; 12229 tolist = 0; 12230 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12231 { 12232 if (buf[filtd] == '\n' || readlen <= 0) 12233 { 12234 /* Only when in binary mode add an empty list item when the 12235 * last line ends in a '\n'. */ 12236 if (!binary && readlen == 0 && filtd == 0) 12237 break; 12238 12239 /* Found end-of-line or end-of-file: add a text line to the 12240 * list. */ 12241 chop = 0; 12242 if (!binary) 12243 while (filtd - chop - 1 >= tolist 12244 && buf[filtd - chop - 1] == '\r') 12245 ++chop; 12246 len = filtd - tolist - chop; 12247 if (prev == NULL) 12248 s = vim_strnsave(buf + tolist, len); 12249 else 12250 { 12251 s = alloc((unsigned)(prevlen + len + 1)); 12252 if (s != NULL) 12253 { 12254 mch_memmove(s, prev, prevlen); 12255 vim_free(prev); 12256 prev = NULL; 12257 mch_memmove(s + prevlen, buf + tolist, len); 12258 s[prevlen + len] = NUL; 12259 } 12260 } 12261 tolist = filtd + 1; 12262 12263 li = listitem_alloc(); 12264 if (li == NULL) 12265 { 12266 vim_free(s); 12267 break; 12268 } 12269 li->li_tv.v_type = VAR_STRING; 12270 li->li_tv.v_lock = 0; 12271 li->li_tv.vval.v_string = s; 12272 list_append(l, li); 12273 12274 if (++cnt >= maxline && maxline >= 0) 12275 break; 12276 if (readlen <= 0) 12277 break; 12278 } 12279 else if (buf[filtd] == NUL) 12280 buf[filtd] = '\n'; 12281 } 12282 if (readlen <= 0) 12283 break; 12284 12285 if (tolist == 0) 12286 { 12287 /* "buf" is full, need to move text to an allocated buffer */ 12288 if (prev == NULL) 12289 { 12290 prev = vim_strnsave(buf, buflen); 12291 prevlen = buflen; 12292 } 12293 else 12294 { 12295 s = alloc((unsigned)(prevlen + buflen)); 12296 if (s != NULL) 12297 { 12298 mch_memmove(s, prev, prevlen); 12299 mch_memmove(s + prevlen, buf, buflen); 12300 vim_free(prev); 12301 prev = s; 12302 prevlen += buflen; 12303 } 12304 } 12305 filtd = 0; 12306 } 12307 else 12308 { 12309 mch_memmove(buf, buf + tolist, buflen - tolist); 12310 filtd -= tolist; 12311 } 12312 } 12313 12314 /* 12315 * For a negative line count use only the lines at the end of the file, 12316 * free the rest. 12317 */ 12318 if (maxline < 0) 12319 while (cnt > -maxline) 12320 { 12321 listitem_remove(l, l->lv_first); 12322 --cnt; 12323 } 12324 12325 vim_free(prev); 12326 fclose(fd); 12327 } 12328 12329 12330 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12331 static void make_connection __ARGS((void)); 12332 static int check_connection __ARGS((void)); 12333 12334 static void 12335 make_connection() 12336 { 12337 if (X_DISPLAY == NULL 12338 # ifdef FEAT_GUI 12339 && !gui.in_use 12340 # endif 12341 ) 12342 { 12343 x_force_connect = TRUE; 12344 setup_term_clip(); 12345 x_force_connect = FALSE; 12346 } 12347 } 12348 12349 static int 12350 check_connection() 12351 { 12352 make_connection(); 12353 if (X_DISPLAY == NULL) 12354 { 12355 EMSG(_("E240: No connection to Vim server")); 12356 return FAIL; 12357 } 12358 return OK; 12359 } 12360 #endif 12361 12362 #ifdef FEAT_CLIENTSERVER 12363 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12364 12365 static void 12366 remote_common(argvars, rettv, expr) 12367 typval_T *argvars; 12368 typval_T *rettv; 12369 int expr; 12370 { 12371 char_u *server_name; 12372 char_u *keys; 12373 char_u *r = NULL; 12374 char_u buf[NUMBUFLEN]; 12375 # ifdef WIN32 12376 HWND w; 12377 # else 12378 Window w; 12379 # endif 12380 12381 if (check_restricted() || check_secure()) 12382 return; 12383 12384 # ifdef FEAT_X11 12385 if (check_connection() == FAIL) 12386 return; 12387 # endif 12388 12389 server_name = get_tv_string_chk(&argvars[0]); 12390 if (server_name == NULL) 12391 return; /* type error; errmsg already given */ 12392 keys = get_tv_string_buf(&argvars[1], buf); 12393 # ifdef WIN32 12394 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12395 # else 12396 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12397 < 0) 12398 # endif 12399 { 12400 if (r != NULL) 12401 EMSG(r); /* sending worked but evaluation failed */ 12402 else 12403 EMSG2(_("E241: Unable to send to %s"), server_name); 12404 return; 12405 } 12406 12407 rettv->vval.v_string = r; 12408 12409 if (argvars[2].v_type != VAR_UNKNOWN) 12410 { 12411 dictitem_T v; 12412 char_u str[30]; 12413 char_u *idvar; 12414 12415 sprintf((char *)str, "0x%x", (unsigned int)w); 12416 v.di_tv.v_type = VAR_STRING; 12417 v.di_tv.vval.v_string = vim_strsave(str); 12418 idvar = get_tv_string_chk(&argvars[2]); 12419 if (idvar != NULL) 12420 set_var(idvar, &v.di_tv, FALSE); 12421 vim_free(v.di_tv.vval.v_string); 12422 } 12423 } 12424 #endif 12425 12426 /* 12427 * "remote_expr()" function 12428 */ 12429 /*ARGSUSED*/ 12430 static void 12431 f_remote_expr(argvars, rettv) 12432 typval_T *argvars; 12433 typval_T *rettv; 12434 { 12435 rettv->v_type = VAR_STRING; 12436 rettv->vval.v_string = NULL; 12437 #ifdef FEAT_CLIENTSERVER 12438 remote_common(argvars, rettv, TRUE); 12439 #endif 12440 } 12441 12442 /* 12443 * "remote_foreground()" function 12444 */ 12445 /*ARGSUSED*/ 12446 static void 12447 f_remote_foreground(argvars, rettv) 12448 typval_T *argvars; 12449 typval_T *rettv; 12450 { 12451 rettv->vval.v_number = 0; 12452 #ifdef FEAT_CLIENTSERVER 12453 # ifdef WIN32 12454 /* On Win32 it's done in this application. */ 12455 { 12456 char_u *server_name = get_tv_string_chk(&argvars[0]); 12457 12458 if (server_name != NULL) 12459 serverForeground(server_name); 12460 } 12461 # else 12462 /* Send a foreground() expression to the server. */ 12463 argvars[1].v_type = VAR_STRING; 12464 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12465 argvars[2].v_type = VAR_UNKNOWN; 12466 remote_common(argvars, rettv, TRUE); 12467 vim_free(argvars[1].vval.v_string); 12468 # endif 12469 #endif 12470 } 12471 12472 /*ARGSUSED*/ 12473 static void 12474 f_remote_peek(argvars, rettv) 12475 typval_T *argvars; 12476 typval_T *rettv; 12477 { 12478 #ifdef FEAT_CLIENTSERVER 12479 dictitem_T v; 12480 char_u *s = NULL; 12481 # ifdef WIN32 12482 int n = 0; 12483 # endif 12484 char_u *serverid; 12485 12486 if (check_restricted() || check_secure()) 12487 { 12488 rettv->vval.v_number = -1; 12489 return; 12490 } 12491 serverid = get_tv_string_chk(&argvars[0]); 12492 if (serverid == NULL) 12493 { 12494 rettv->vval.v_number = -1; 12495 return; /* type error; errmsg already given */ 12496 } 12497 # ifdef WIN32 12498 sscanf(serverid, "%x", &n); 12499 if (n == 0) 12500 rettv->vval.v_number = -1; 12501 else 12502 { 12503 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12504 rettv->vval.v_number = (s != NULL); 12505 } 12506 # else 12507 rettv->vval.v_number = 0; 12508 if (check_connection() == FAIL) 12509 return; 12510 12511 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12512 serverStrToWin(serverid), &s); 12513 # endif 12514 12515 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12516 { 12517 char_u *retvar; 12518 12519 v.di_tv.v_type = VAR_STRING; 12520 v.di_tv.vval.v_string = vim_strsave(s); 12521 retvar = get_tv_string_chk(&argvars[1]); 12522 if (retvar != NULL) 12523 set_var(retvar, &v.di_tv, FALSE); 12524 vim_free(v.di_tv.vval.v_string); 12525 } 12526 #else 12527 rettv->vval.v_number = -1; 12528 #endif 12529 } 12530 12531 /*ARGSUSED*/ 12532 static void 12533 f_remote_read(argvars, rettv) 12534 typval_T *argvars; 12535 typval_T *rettv; 12536 { 12537 char_u *r = NULL; 12538 12539 #ifdef FEAT_CLIENTSERVER 12540 char_u *serverid = get_tv_string_chk(&argvars[0]); 12541 12542 if (serverid != NULL && !check_restricted() && !check_secure()) 12543 { 12544 # ifdef WIN32 12545 /* The server's HWND is encoded in the 'id' parameter */ 12546 int n = 0; 12547 12548 sscanf(serverid, "%x", &n); 12549 if (n != 0) 12550 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12551 if (r == NULL) 12552 # else 12553 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12554 serverStrToWin(serverid), &r, FALSE) < 0) 12555 # endif 12556 EMSG(_("E277: Unable to read a server reply")); 12557 } 12558 #endif 12559 rettv->v_type = VAR_STRING; 12560 rettv->vval.v_string = r; 12561 } 12562 12563 /* 12564 * "remote_send()" function 12565 */ 12566 /*ARGSUSED*/ 12567 static void 12568 f_remote_send(argvars, rettv) 12569 typval_T *argvars; 12570 typval_T *rettv; 12571 { 12572 rettv->v_type = VAR_STRING; 12573 rettv->vval.v_string = NULL; 12574 #ifdef FEAT_CLIENTSERVER 12575 remote_common(argvars, rettv, FALSE); 12576 #endif 12577 } 12578 12579 /* 12580 * "remove()" function 12581 */ 12582 static void 12583 f_remove(argvars, rettv) 12584 typval_T *argvars; 12585 typval_T *rettv; 12586 { 12587 list_T *l; 12588 listitem_T *item, *item2; 12589 listitem_T *li; 12590 long idx; 12591 long end; 12592 char_u *key; 12593 dict_T *d; 12594 dictitem_T *di; 12595 12596 rettv->vval.v_number = 0; 12597 if (argvars[0].v_type == VAR_DICT) 12598 { 12599 if (argvars[2].v_type != VAR_UNKNOWN) 12600 EMSG2(_(e_toomanyarg), "remove()"); 12601 else if ((d = argvars[0].vval.v_dict) != NULL 12602 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12603 { 12604 key = get_tv_string_chk(&argvars[1]); 12605 if (key != NULL) 12606 { 12607 di = dict_find(d, key, -1); 12608 if (di == NULL) 12609 EMSG2(_(e_dictkey), key); 12610 else 12611 { 12612 *rettv = di->di_tv; 12613 init_tv(&di->di_tv); 12614 dictitem_remove(d, di); 12615 } 12616 } 12617 } 12618 } 12619 else if (argvars[0].v_type != VAR_LIST) 12620 EMSG2(_(e_listdictarg), "remove()"); 12621 else if ((l = argvars[0].vval.v_list) != NULL 12622 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12623 { 12624 int error = FALSE; 12625 12626 idx = get_tv_number_chk(&argvars[1], &error); 12627 if (error) 12628 ; /* type error: do nothing, errmsg already given */ 12629 else if ((item = list_find(l, idx)) == NULL) 12630 EMSGN(_(e_listidx), idx); 12631 else 12632 { 12633 if (argvars[2].v_type == VAR_UNKNOWN) 12634 { 12635 /* Remove one item, return its value. */ 12636 list_remove(l, item, item); 12637 *rettv = item->li_tv; 12638 vim_free(item); 12639 } 12640 else 12641 { 12642 /* Remove range of items, return list with values. */ 12643 end = get_tv_number_chk(&argvars[2], &error); 12644 if (error) 12645 ; /* type error: do nothing */ 12646 else if ((item2 = list_find(l, end)) == NULL) 12647 EMSGN(_(e_listidx), end); 12648 else 12649 { 12650 int cnt = 0; 12651 12652 for (li = item; li != NULL; li = li->li_next) 12653 { 12654 ++cnt; 12655 if (li == item2) 12656 break; 12657 } 12658 if (li == NULL) /* didn't find "item2" after "item" */ 12659 EMSG(_(e_invrange)); 12660 else 12661 { 12662 list_remove(l, item, item2); 12663 l = list_alloc(); 12664 if (l != NULL) 12665 { 12666 rettv->v_type = VAR_LIST; 12667 rettv->vval.v_list = l; 12668 l->lv_first = item; 12669 l->lv_last = item2; 12670 l->lv_refcount = 1; 12671 item->li_prev = NULL; 12672 item2->li_next = NULL; 12673 l->lv_len = cnt; 12674 } 12675 } 12676 } 12677 } 12678 } 12679 } 12680 } 12681 12682 /* 12683 * "rename({from}, {to})" function 12684 */ 12685 static void 12686 f_rename(argvars, rettv) 12687 typval_T *argvars; 12688 typval_T *rettv; 12689 { 12690 char_u buf[NUMBUFLEN]; 12691 12692 if (check_restricted() || check_secure()) 12693 rettv->vval.v_number = -1; 12694 else 12695 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12696 get_tv_string_buf(&argvars[1], buf)); 12697 } 12698 12699 /* 12700 * "repeat()" function 12701 */ 12702 /*ARGSUSED*/ 12703 static void 12704 f_repeat(argvars, rettv) 12705 typval_T *argvars; 12706 typval_T *rettv; 12707 { 12708 char_u *p; 12709 int n; 12710 int slen; 12711 int len; 12712 char_u *r; 12713 int i; 12714 list_T *l; 12715 12716 n = get_tv_number(&argvars[1]); 12717 if (argvars[0].v_type == VAR_LIST) 12718 { 12719 l = list_alloc(); 12720 if (l != NULL && argvars[0].vval.v_list != NULL) 12721 { 12722 l->lv_refcount = 1; 12723 while (n-- > 0) 12724 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12725 break; 12726 } 12727 rettv->v_type = VAR_LIST; 12728 rettv->vval.v_list = l; 12729 } 12730 else 12731 { 12732 p = get_tv_string(&argvars[0]); 12733 rettv->v_type = VAR_STRING; 12734 rettv->vval.v_string = NULL; 12735 12736 slen = (int)STRLEN(p); 12737 len = slen * n; 12738 if (len <= 0) 12739 return; 12740 12741 r = alloc(len + 1); 12742 if (r != NULL) 12743 { 12744 for (i = 0; i < n; i++) 12745 mch_memmove(r + i * slen, p, (size_t)slen); 12746 r[len] = NUL; 12747 } 12748 12749 rettv->vval.v_string = r; 12750 } 12751 } 12752 12753 /* 12754 * "resolve()" function 12755 */ 12756 static void 12757 f_resolve(argvars, rettv) 12758 typval_T *argvars; 12759 typval_T *rettv; 12760 { 12761 char_u *p; 12762 12763 p = get_tv_string(&argvars[0]); 12764 #ifdef FEAT_SHORTCUT 12765 { 12766 char_u *v = NULL; 12767 12768 v = mch_resolve_shortcut(p); 12769 if (v != NULL) 12770 rettv->vval.v_string = v; 12771 else 12772 rettv->vval.v_string = vim_strsave(p); 12773 } 12774 #else 12775 # ifdef HAVE_READLINK 12776 { 12777 char_u buf[MAXPATHL + 1]; 12778 char_u *cpy; 12779 int len; 12780 char_u *remain = NULL; 12781 char_u *q; 12782 int is_relative_to_current = FALSE; 12783 int has_trailing_pathsep = FALSE; 12784 int limit = 100; 12785 12786 p = vim_strsave(p); 12787 12788 if (p[0] == '.' && (vim_ispathsep(p[1]) 12789 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12790 is_relative_to_current = TRUE; 12791 12792 len = STRLEN(p); 12793 if (len > 0 && after_pathsep(p, p + len)) 12794 has_trailing_pathsep = TRUE; 12795 12796 q = getnextcomp(p); 12797 if (*q != NUL) 12798 { 12799 /* Separate the first path component in "p", and keep the 12800 * remainder (beginning with the path separator). */ 12801 remain = vim_strsave(q - 1); 12802 q[-1] = NUL; 12803 } 12804 12805 for (;;) 12806 { 12807 for (;;) 12808 { 12809 len = readlink((char *)p, (char *)buf, MAXPATHL); 12810 if (len <= 0) 12811 break; 12812 buf[len] = NUL; 12813 12814 if (limit-- == 0) 12815 { 12816 vim_free(p); 12817 vim_free(remain); 12818 EMSG(_("E655: Too many symbolic links (cycle?)")); 12819 rettv->vval.v_string = NULL; 12820 goto fail; 12821 } 12822 12823 /* Ensure that the result will have a trailing path separator 12824 * if the argument has one. */ 12825 if (remain == NULL && has_trailing_pathsep) 12826 add_pathsep(buf); 12827 12828 /* Separate the first path component in the link value and 12829 * concatenate the remainders. */ 12830 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12831 if (*q != NUL) 12832 { 12833 if (remain == NULL) 12834 remain = vim_strsave(q - 1); 12835 else 12836 { 12837 cpy = concat_str(q - 1, remain); 12838 if (cpy != NULL) 12839 { 12840 vim_free(remain); 12841 remain = cpy; 12842 } 12843 } 12844 q[-1] = NUL; 12845 } 12846 12847 q = gettail(p); 12848 if (q > p && *q == NUL) 12849 { 12850 /* Ignore trailing path separator. */ 12851 q[-1] = NUL; 12852 q = gettail(p); 12853 } 12854 if (q > p && !mch_isFullName(buf)) 12855 { 12856 /* symlink is relative to directory of argument */ 12857 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12858 if (cpy != NULL) 12859 { 12860 STRCPY(cpy, p); 12861 STRCPY(gettail(cpy), buf); 12862 vim_free(p); 12863 p = cpy; 12864 } 12865 } 12866 else 12867 { 12868 vim_free(p); 12869 p = vim_strsave(buf); 12870 } 12871 } 12872 12873 if (remain == NULL) 12874 break; 12875 12876 /* Append the first path component of "remain" to "p". */ 12877 q = getnextcomp(remain + 1); 12878 len = q - remain - (*q != NUL); 12879 cpy = vim_strnsave(p, STRLEN(p) + len); 12880 if (cpy != NULL) 12881 { 12882 STRNCAT(cpy, remain, len); 12883 vim_free(p); 12884 p = cpy; 12885 } 12886 /* Shorten "remain". */ 12887 if (*q != NUL) 12888 STRCPY(remain, q - 1); 12889 else 12890 { 12891 vim_free(remain); 12892 remain = NULL; 12893 } 12894 } 12895 12896 /* If the result is a relative path name, make it explicitly relative to 12897 * the current directory if and only if the argument had this form. */ 12898 if (!vim_ispathsep(*p)) 12899 { 12900 if (is_relative_to_current 12901 && *p != NUL 12902 && !(p[0] == '.' 12903 && (p[1] == NUL 12904 || vim_ispathsep(p[1]) 12905 || (p[1] == '.' 12906 && (p[2] == NUL 12907 || vim_ispathsep(p[2])))))) 12908 { 12909 /* Prepend "./". */ 12910 cpy = concat_str((char_u *)"./", p); 12911 if (cpy != NULL) 12912 { 12913 vim_free(p); 12914 p = cpy; 12915 } 12916 } 12917 else if (!is_relative_to_current) 12918 { 12919 /* Strip leading "./". */ 12920 q = p; 12921 while (q[0] == '.' && vim_ispathsep(q[1])) 12922 q += 2; 12923 if (q > p) 12924 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12925 } 12926 } 12927 12928 /* Ensure that the result will have no trailing path separator 12929 * if the argument had none. But keep "/" or "//". */ 12930 if (!has_trailing_pathsep) 12931 { 12932 q = p + STRLEN(p); 12933 if (after_pathsep(p, q)) 12934 *gettail_sep(p) = NUL; 12935 } 12936 12937 rettv->vval.v_string = p; 12938 } 12939 # else 12940 rettv->vval.v_string = vim_strsave(p); 12941 # endif 12942 #endif 12943 12944 simplify_filename(rettv->vval.v_string); 12945 12946 #ifdef HAVE_READLINK 12947 fail: 12948 #endif 12949 rettv->v_type = VAR_STRING; 12950 } 12951 12952 /* 12953 * "reverse({list})" function 12954 */ 12955 static void 12956 f_reverse(argvars, rettv) 12957 typval_T *argvars; 12958 typval_T *rettv; 12959 { 12960 list_T *l; 12961 listitem_T *li, *ni; 12962 12963 rettv->vval.v_number = 0; 12964 if (argvars[0].v_type != VAR_LIST) 12965 EMSG2(_(e_listarg), "reverse()"); 12966 else if ((l = argvars[0].vval.v_list) != NULL 12967 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12968 { 12969 li = l->lv_last; 12970 l->lv_first = l->lv_last = NULL; 12971 l->lv_len = 0; 12972 while (li != NULL) 12973 { 12974 ni = li->li_prev; 12975 list_append(l, li); 12976 li = ni; 12977 } 12978 rettv->vval.v_list = l; 12979 rettv->v_type = VAR_LIST; 12980 ++l->lv_refcount; 12981 } 12982 } 12983 12984 #define SP_NOMOVE 1 /* don't move cursor */ 12985 #define SP_REPEAT 2 /* repeat to find outer pair */ 12986 #define SP_RETCOUNT 4 /* return matchcount */ 12987 #define SP_SETPCMARK 8 /* set previous context mark */ 12988 12989 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12990 12991 /* 12992 * Get flags for a search function. 12993 * Possibly sets "p_ws". 12994 * Returns BACKWARD, FORWARD or zero (for an error). 12995 */ 12996 static int 12997 get_search_arg(varp, flagsp) 12998 typval_T *varp; 12999 int *flagsp; 13000 { 13001 int dir = FORWARD; 13002 char_u *flags; 13003 char_u nbuf[NUMBUFLEN]; 13004 int mask; 13005 13006 if (varp->v_type != VAR_UNKNOWN) 13007 { 13008 flags = get_tv_string_buf_chk(varp, nbuf); 13009 if (flags == NULL) 13010 return 0; /* type error; errmsg already given */ 13011 while (*flags != NUL) 13012 { 13013 switch (*flags) 13014 { 13015 case 'b': dir = BACKWARD; break; 13016 case 'w': p_ws = TRUE; break; 13017 case 'W': p_ws = FALSE; break; 13018 default: mask = 0; 13019 if (flagsp != NULL) 13020 switch (*flags) 13021 { 13022 case 'n': mask = SP_NOMOVE; break; 13023 case 'r': mask = SP_REPEAT; break; 13024 case 'm': mask = SP_RETCOUNT; break; 13025 case 's': mask = SP_SETPCMARK; break; 13026 } 13027 if (mask == 0) 13028 { 13029 EMSG2(_(e_invarg2), flags); 13030 dir = 0; 13031 } 13032 else 13033 *flagsp |= mask; 13034 } 13035 if (dir == 0) 13036 break; 13037 ++flags; 13038 } 13039 } 13040 return dir; 13041 } 13042 13043 /* 13044 * "search()" function 13045 */ 13046 static void 13047 f_search(argvars, rettv) 13048 typval_T *argvars; 13049 typval_T *rettv; 13050 { 13051 char_u *pat; 13052 pos_T pos; 13053 pos_T save_cursor; 13054 int save_p_ws = p_ws; 13055 int dir; 13056 int flags = 0; 13057 13058 rettv->vval.v_number = 0; /* default: FAIL */ 13059 13060 pat = get_tv_string(&argvars[0]); 13061 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 13062 if (dir == 0) 13063 goto theend; 13064 /* 13065 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 13066 * Check to make sure only those flags are set. 13067 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13068 * flags cannot be set. Check for that condition also. 13069 */ 13070 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 13071 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13072 { 13073 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13074 goto theend; 13075 } 13076 13077 pos = save_cursor = curwin->w_cursor; 13078 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 13079 SEARCH_KEEP, RE_SEARCH) != FAIL) 13080 { 13081 rettv->vval.v_number = pos.lnum; 13082 if (flags & SP_SETPCMARK) 13083 setpcmark(); 13084 curwin->w_cursor = pos; 13085 /* "/$" will put the cursor after the end of the line, may need to 13086 * correct that here */ 13087 check_cursor(); 13088 } 13089 13090 /* If 'n' flag is used: restore cursor position. */ 13091 if (flags & SP_NOMOVE) 13092 curwin->w_cursor = save_cursor; 13093 theend: 13094 p_ws = save_p_ws; 13095 } 13096 13097 /* 13098 * "searchdecl()" function 13099 */ 13100 static void 13101 f_searchdecl(argvars, rettv) 13102 typval_T *argvars; 13103 typval_T *rettv; 13104 { 13105 int locally = 1; 13106 int thisblock = 0; 13107 int error = FALSE; 13108 char_u *name; 13109 13110 rettv->vval.v_number = 1; /* default: FAIL */ 13111 13112 name = get_tv_string_chk(&argvars[0]); 13113 if (argvars[1].v_type != VAR_UNKNOWN) 13114 { 13115 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13116 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13117 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13118 } 13119 if (!error && name != NULL) 13120 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13121 locally, thisblock, SEARCH_KEEP) == FAIL; 13122 } 13123 13124 /* 13125 * "searchpair()" function 13126 */ 13127 static void 13128 f_searchpair(argvars, rettv) 13129 typval_T *argvars; 13130 typval_T *rettv; 13131 { 13132 char_u *spat, *mpat, *epat; 13133 char_u *skip; 13134 int save_p_ws = p_ws; 13135 int dir; 13136 int flags = 0; 13137 char_u nbuf1[NUMBUFLEN]; 13138 char_u nbuf2[NUMBUFLEN]; 13139 char_u nbuf3[NUMBUFLEN]; 13140 13141 rettv->vval.v_number = 0; /* default: FAIL */ 13142 13143 /* Get the three pattern arguments: start, middle, end. */ 13144 spat = get_tv_string_chk(&argvars[0]); 13145 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13146 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13147 if (spat == NULL || mpat == NULL || epat == NULL) 13148 goto theend; /* type error */ 13149 13150 /* Handle the optional fourth argument: flags */ 13151 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13152 if (dir == 0) 13153 goto theend; 13154 /* 13155 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13156 */ 13157 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13158 { 13159 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13160 goto theend; 13161 } 13162 13163 /* Optional fifth argument: skip expresion */ 13164 if (argvars[3].v_type == VAR_UNKNOWN 13165 || argvars[4].v_type == VAR_UNKNOWN) 13166 skip = (char_u *)""; 13167 else 13168 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13169 if (skip == NULL) 13170 goto theend; /* type error */ 13171 13172 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13173 13174 theend: 13175 p_ws = save_p_ws; 13176 } 13177 13178 /* 13179 * Search for a start/middle/end thing. 13180 * Used by searchpair(), see its documentation for the details. 13181 * Returns 0 or -1 for no match, 13182 */ 13183 long 13184 do_searchpair(spat, mpat, epat, dir, skip, flags) 13185 char_u *spat; /* start pattern */ 13186 char_u *mpat; /* middle pattern */ 13187 char_u *epat; /* end pattern */ 13188 int dir; /* BACKWARD or FORWARD */ 13189 char_u *skip; /* skip expression */ 13190 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13191 { 13192 char_u *save_cpo; 13193 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13194 long retval = 0; 13195 pos_T pos; 13196 pos_T firstpos; 13197 pos_T foundpos; 13198 pos_T save_cursor; 13199 pos_T save_pos; 13200 int n; 13201 int r; 13202 int nest = 1; 13203 int err; 13204 13205 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13206 save_cpo = p_cpo; 13207 p_cpo = (char_u *)""; 13208 13209 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13210 * start/middle/end (pat3, for the top pair). */ 13211 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13212 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13213 if (pat2 == NULL || pat3 == NULL) 13214 goto theend; 13215 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13216 if (*mpat == NUL) 13217 STRCPY(pat3, pat2); 13218 else 13219 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13220 spat, epat, mpat); 13221 13222 save_cursor = curwin->w_cursor; 13223 pos = curwin->w_cursor; 13224 firstpos.lnum = 0; 13225 foundpos.lnum = 0; 13226 pat = pat3; 13227 for (;;) 13228 { 13229 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13230 SEARCH_KEEP, RE_SEARCH); 13231 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13232 /* didn't find it or found the first match again: FAIL */ 13233 break; 13234 13235 if (firstpos.lnum == 0) 13236 firstpos = pos; 13237 if (equalpos(pos, foundpos)) 13238 { 13239 /* Found the same position again. Can happen with a pattern that 13240 * has "\zs" at the end and searching backwards. Advance one 13241 * character and try again. */ 13242 if (dir == BACKWARD) 13243 decl(&pos); 13244 else 13245 incl(&pos); 13246 } 13247 foundpos = pos; 13248 13249 /* If the skip pattern matches, ignore this match. */ 13250 if (*skip != NUL) 13251 { 13252 save_pos = curwin->w_cursor; 13253 curwin->w_cursor = pos; 13254 r = eval_to_bool(skip, &err, NULL, FALSE); 13255 curwin->w_cursor = save_pos; 13256 if (err) 13257 { 13258 /* Evaluating {skip} caused an error, break here. */ 13259 curwin->w_cursor = save_cursor; 13260 retval = -1; 13261 break; 13262 } 13263 if (r) 13264 continue; 13265 } 13266 13267 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13268 { 13269 /* Found end when searching backwards or start when searching 13270 * forward: nested pair. */ 13271 ++nest; 13272 pat = pat2; /* nested, don't search for middle */ 13273 } 13274 else 13275 { 13276 /* Found end when searching forward or start when searching 13277 * backward: end of (nested) pair; or found middle in outer pair. */ 13278 if (--nest == 1) 13279 pat = pat3; /* outer level, search for middle */ 13280 } 13281 13282 if (nest == 0) 13283 { 13284 /* Found the match: return matchcount or line number. */ 13285 if (flags & SP_RETCOUNT) 13286 ++retval; 13287 else 13288 retval = pos.lnum; 13289 if (flags & SP_SETPCMARK) 13290 setpcmark(); 13291 curwin->w_cursor = pos; 13292 if (!(flags & SP_REPEAT)) 13293 break; 13294 nest = 1; /* search for next unmatched */ 13295 } 13296 } 13297 13298 /* If 'n' flag is used or search failed: restore cursor position. */ 13299 if ((flags & SP_NOMOVE) || retval == 0) 13300 curwin->w_cursor = save_cursor; 13301 13302 theend: 13303 vim_free(pat2); 13304 vim_free(pat3); 13305 p_cpo = save_cpo; 13306 13307 return retval; 13308 } 13309 13310 /*ARGSUSED*/ 13311 static void 13312 f_server2client(argvars, rettv) 13313 typval_T *argvars; 13314 typval_T *rettv; 13315 { 13316 #ifdef FEAT_CLIENTSERVER 13317 char_u buf[NUMBUFLEN]; 13318 char_u *server = get_tv_string_chk(&argvars[0]); 13319 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13320 13321 rettv->vval.v_number = -1; 13322 if (server == NULL || reply == NULL) 13323 return; 13324 if (check_restricted() || check_secure()) 13325 return; 13326 # ifdef FEAT_X11 13327 if (check_connection() == FAIL) 13328 return; 13329 # endif 13330 13331 if (serverSendReply(server, reply) < 0) 13332 { 13333 EMSG(_("E258: Unable to send to client")); 13334 return; 13335 } 13336 rettv->vval.v_number = 0; 13337 #else 13338 rettv->vval.v_number = -1; 13339 #endif 13340 } 13341 13342 /*ARGSUSED*/ 13343 static void 13344 f_serverlist(argvars, rettv) 13345 typval_T *argvars; 13346 typval_T *rettv; 13347 { 13348 char_u *r = NULL; 13349 13350 #ifdef FEAT_CLIENTSERVER 13351 # ifdef WIN32 13352 r = serverGetVimNames(); 13353 # else 13354 make_connection(); 13355 if (X_DISPLAY != NULL) 13356 r = serverGetVimNames(X_DISPLAY); 13357 # endif 13358 #endif 13359 rettv->v_type = VAR_STRING; 13360 rettv->vval.v_string = r; 13361 } 13362 13363 /* 13364 * "setbufvar()" function 13365 */ 13366 /*ARGSUSED*/ 13367 static void 13368 f_setbufvar(argvars, rettv) 13369 typval_T *argvars; 13370 typval_T *rettv; 13371 { 13372 buf_T *buf; 13373 #ifdef FEAT_AUTOCMD 13374 aco_save_T aco; 13375 #else 13376 buf_T *save_curbuf; 13377 #endif 13378 char_u *varname, *bufvarname; 13379 typval_T *varp; 13380 char_u nbuf[NUMBUFLEN]; 13381 13382 rettv->vval.v_number = 0; 13383 13384 if (check_restricted() || check_secure()) 13385 return; 13386 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13387 varname = get_tv_string_chk(&argvars[1]); 13388 buf = get_buf_tv(&argvars[0]); 13389 varp = &argvars[2]; 13390 13391 if (buf != NULL && varname != NULL && varp != NULL) 13392 { 13393 /* set curbuf to be our buf, temporarily */ 13394 #ifdef FEAT_AUTOCMD 13395 aucmd_prepbuf(&aco, buf); 13396 #else 13397 save_curbuf = curbuf; 13398 curbuf = buf; 13399 #endif 13400 13401 if (*varname == '&') 13402 { 13403 long numval; 13404 char_u *strval; 13405 int error = FALSE; 13406 13407 ++varname; 13408 numval = get_tv_number_chk(varp, &error); 13409 strval = get_tv_string_buf_chk(varp, nbuf); 13410 if (!error && strval != NULL) 13411 set_option_value(varname, numval, strval, OPT_LOCAL); 13412 } 13413 else 13414 { 13415 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13416 if (bufvarname != NULL) 13417 { 13418 STRCPY(bufvarname, "b:"); 13419 STRCPY(bufvarname + 2, varname); 13420 set_var(bufvarname, varp, TRUE); 13421 vim_free(bufvarname); 13422 } 13423 } 13424 13425 /* reset notion of buffer */ 13426 #ifdef FEAT_AUTOCMD 13427 aucmd_restbuf(&aco); 13428 #else 13429 curbuf = save_curbuf; 13430 #endif 13431 } 13432 } 13433 13434 /* 13435 * "setcmdpos()" function 13436 */ 13437 static void 13438 f_setcmdpos(argvars, rettv) 13439 typval_T *argvars; 13440 typval_T *rettv; 13441 { 13442 int pos = (int)get_tv_number(&argvars[0]) - 1; 13443 13444 if (pos >= 0) 13445 rettv->vval.v_number = set_cmdline_pos(pos); 13446 } 13447 13448 /* 13449 * "setline()" function 13450 */ 13451 static void 13452 f_setline(argvars, rettv) 13453 typval_T *argvars; 13454 typval_T *rettv; 13455 { 13456 linenr_T lnum; 13457 char_u *line = NULL; 13458 list_T *l = NULL; 13459 listitem_T *li = NULL; 13460 long added = 0; 13461 linenr_T lcount = curbuf->b_ml.ml_line_count; 13462 13463 lnum = get_tv_lnum(&argvars[0]); 13464 if (argvars[1].v_type == VAR_LIST) 13465 { 13466 l = argvars[1].vval.v_list; 13467 li = l->lv_first; 13468 } 13469 else 13470 line = get_tv_string_chk(&argvars[1]); 13471 13472 rettv->vval.v_number = 0; /* OK */ 13473 for (;;) 13474 { 13475 if (l != NULL) 13476 { 13477 /* list argument, get next string */ 13478 if (li == NULL) 13479 break; 13480 line = get_tv_string_chk(&li->li_tv); 13481 li = li->li_next; 13482 } 13483 13484 rettv->vval.v_number = 1; /* FAIL */ 13485 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13486 break; 13487 if (lnum <= curbuf->b_ml.ml_line_count) 13488 { 13489 /* existing line, replace it */ 13490 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13491 { 13492 changed_bytes(lnum, 0); 13493 check_cursor_col(); 13494 rettv->vval.v_number = 0; /* OK */ 13495 } 13496 } 13497 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13498 { 13499 /* lnum is one past the last line, append the line */ 13500 ++added; 13501 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13502 rettv->vval.v_number = 0; /* OK */ 13503 } 13504 13505 if (l == NULL) /* only one string argument */ 13506 break; 13507 ++lnum; 13508 } 13509 13510 if (added > 0) 13511 appended_lines_mark(lcount, added); 13512 } 13513 13514 /* 13515 * "setqflist()" function 13516 */ 13517 /*ARGSUSED*/ 13518 static void 13519 f_setqflist(argvars, rettv) 13520 typval_T *argvars; 13521 typval_T *rettv; 13522 { 13523 char_u *act; 13524 int action = ' '; 13525 13526 rettv->vval.v_number = -1; 13527 13528 #ifdef FEAT_QUICKFIX 13529 if (argvars[0].v_type != VAR_LIST) 13530 EMSG(_(e_listreq)); 13531 else 13532 { 13533 list_T *l = argvars[0].vval.v_list; 13534 13535 if (argvars[1].v_type == VAR_STRING) 13536 { 13537 act = get_tv_string_chk(&argvars[1]); 13538 if (act == NULL) 13539 return; /* type error; errmsg already given */ 13540 if (*act == 'a' || *act == 'r') 13541 action = *act; 13542 } 13543 13544 if (l != NULL && set_errorlist(l, action) == OK) 13545 rettv->vval.v_number = 0; 13546 } 13547 #endif 13548 } 13549 13550 /* 13551 * "setreg()" function 13552 */ 13553 static void 13554 f_setreg(argvars, rettv) 13555 typval_T *argvars; 13556 typval_T *rettv; 13557 { 13558 int regname; 13559 char_u *strregname; 13560 char_u *stropt; 13561 char_u *strval; 13562 int append; 13563 char_u yank_type; 13564 long block_len; 13565 13566 block_len = -1; 13567 yank_type = MAUTO; 13568 append = FALSE; 13569 13570 strregname = get_tv_string_chk(argvars); 13571 rettv->vval.v_number = 1; /* FAIL is default */ 13572 13573 if (strregname == NULL) 13574 return; /* type error; errmsg already given */ 13575 regname = *strregname; 13576 if (regname == 0 || regname == '@') 13577 regname = '"'; 13578 else if (regname == '=') 13579 return; 13580 13581 if (argvars[2].v_type != VAR_UNKNOWN) 13582 { 13583 stropt = get_tv_string_chk(&argvars[2]); 13584 if (stropt == NULL) 13585 return; /* type error */ 13586 for (; *stropt != NUL; ++stropt) 13587 switch (*stropt) 13588 { 13589 case 'a': case 'A': /* append */ 13590 append = TRUE; 13591 break; 13592 case 'v': case 'c': /* character-wise selection */ 13593 yank_type = MCHAR; 13594 break; 13595 case 'V': case 'l': /* line-wise selection */ 13596 yank_type = MLINE; 13597 break; 13598 #ifdef FEAT_VISUAL 13599 case 'b': case Ctrl_V: /* block-wise selection */ 13600 yank_type = MBLOCK; 13601 if (VIM_ISDIGIT(stropt[1])) 13602 { 13603 ++stropt; 13604 block_len = getdigits(&stropt) - 1; 13605 --stropt; 13606 } 13607 break; 13608 #endif 13609 } 13610 } 13611 13612 strval = get_tv_string_chk(&argvars[1]); 13613 if (strval != NULL) 13614 write_reg_contents_ex(regname, strval, -1, 13615 append, yank_type, block_len); 13616 rettv->vval.v_number = 0; 13617 } 13618 13619 13620 /* 13621 * "setwinvar(expr)" function 13622 */ 13623 /*ARGSUSED*/ 13624 static void 13625 f_setwinvar(argvars, rettv) 13626 typval_T *argvars; 13627 typval_T *rettv; 13628 { 13629 win_T *win; 13630 #ifdef FEAT_WINDOWS 13631 win_T *save_curwin; 13632 #endif 13633 char_u *varname, *winvarname; 13634 typval_T *varp; 13635 char_u nbuf[NUMBUFLEN]; 13636 13637 rettv->vval.v_number = 0; 13638 13639 if (check_restricted() || check_secure()) 13640 return; 13641 win = find_win_by_nr(&argvars[0]); 13642 varname = get_tv_string_chk(&argvars[1]); 13643 varp = &argvars[2]; 13644 13645 if (win != NULL && varname != NULL && varp != NULL) 13646 { 13647 #ifdef FEAT_WINDOWS 13648 /* set curwin to be our win, temporarily */ 13649 save_curwin = curwin; 13650 curwin = win; 13651 curbuf = curwin->w_buffer; 13652 #endif 13653 13654 if (*varname == '&') 13655 { 13656 long numval; 13657 char_u *strval; 13658 int error = FALSE; 13659 13660 ++varname; 13661 numval = get_tv_number_chk(varp, &error); 13662 strval = get_tv_string_buf_chk(varp, nbuf); 13663 if (!error && strval != NULL) 13664 set_option_value(varname, numval, strval, OPT_LOCAL); 13665 } 13666 else 13667 { 13668 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13669 if (winvarname != NULL) 13670 { 13671 STRCPY(winvarname, "w:"); 13672 STRCPY(winvarname + 2, varname); 13673 set_var(winvarname, varp, TRUE); 13674 vim_free(winvarname); 13675 } 13676 } 13677 13678 #ifdef FEAT_WINDOWS 13679 /* Restore current window, if it's still valid (autocomands can make 13680 * it invalid). */ 13681 if (win_valid(save_curwin)) 13682 { 13683 curwin = save_curwin; 13684 curbuf = curwin->w_buffer; 13685 } 13686 #endif 13687 } 13688 } 13689 13690 /* 13691 * "simplify()" function 13692 */ 13693 static void 13694 f_simplify(argvars, rettv) 13695 typval_T *argvars; 13696 typval_T *rettv; 13697 { 13698 char_u *p; 13699 13700 p = get_tv_string(&argvars[0]); 13701 rettv->vval.v_string = vim_strsave(p); 13702 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13703 rettv->v_type = VAR_STRING; 13704 } 13705 13706 static int 13707 #ifdef __BORLANDC__ 13708 _RTLENTRYF 13709 #endif 13710 item_compare __ARGS((const void *s1, const void *s2)); 13711 static int 13712 #ifdef __BORLANDC__ 13713 _RTLENTRYF 13714 #endif 13715 item_compare2 __ARGS((const void *s1, const void *s2)); 13716 13717 static int item_compare_ic; 13718 static char_u *item_compare_func; 13719 static int item_compare_func_err; 13720 #define ITEM_COMPARE_FAIL 999 13721 13722 /* 13723 * Compare functions for f_sort() below. 13724 */ 13725 static int 13726 #ifdef __BORLANDC__ 13727 _RTLENTRYF 13728 #endif 13729 item_compare(s1, s2) 13730 const void *s1; 13731 const void *s2; 13732 { 13733 char_u *p1, *p2; 13734 char_u *tofree1, *tofree2; 13735 int res; 13736 char_u numbuf1[NUMBUFLEN]; 13737 char_u numbuf2[NUMBUFLEN]; 13738 13739 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13740 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13741 if (item_compare_ic) 13742 res = STRICMP(p1, p2); 13743 else 13744 res = STRCMP(p1, p2); 13745 vim_free(tofree1); 13746 vim_free(tofree2); 13747 return res; 13748 } 13749 13750 static int 13751 #ifdef __BORLANDC__ 13752 _RTLENTRYF 13753 #endif 13754 item_compare2(s1, s2) 13755 const void *s1; 13756 const void *s2; 13757 { 13758 int res; 13759 typval_T rettv; 13760 typval_T argv[2]; 13761 int dummy; 13762 13763 /* shortcut after failure in previous call; compare all items equal */ 13764 if (item_compare_func_err) 13765 return 0; 13766 13767 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13768 * in the copy without changing the original list items. */ 13769 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13770 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13771 13772 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13773 res = call_func(item_compare_func, STRLEN(item_compare_func), 13774 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13775 clear_tv(&argv[0]); 13776 clear_tv(&argv[1]); 13777 13778 if (res == FAIL) 13779 res = ITEM_COMPARE_FAIL; 13780 else 13781 /* return value has wrong type */ 13782 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13783 if (item_compare_func_err) 13784 res = ITEM_COMPARE_FAIL; 13785 clear_tv(&rettv); 13786 return res; 13787 } 13788 13789 /* 13790 * "sort({list})" function 13791 */ 13792 static void 13793 f_sort(argvars, rettv) 13794 typval_T *argvars; 13795 typval_T *rettv; 13796 { 13797 list_T *l; 13798 listitem_T *li; 13799 listitem_T **ptrs; 13800 long len; 13801 long i; 13802 13803 rettv->vval.v_number = 0; 13804 if (argvars[0].v_type != VAR_LIST) 13805 EMSG2(_(e_listarg), "sort()"); 13806 else 13807 { 13808 l = argvars[0].vval.v_list; 13809 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13810 return; 13811 rettv->vval.v_list = l; 13812 rettv->v_type = VAR_LIST; 13813 ++l->lv_refcount; 13814 13815 len = list_len(l); 13816 if (len <= 1) 13817 return; /* short list sorts pretty quickly */ 13818 13819 item_compare_ic = FALSE; 13820 item_compare_func = NULL; 13821 if (argvars[1].v_type != VAR_UNKNOWN) 13822 { 13823 if (argvars[1].v_type == VAR_FUNC) 13824 item_compare_func = argvars[1].vval.v_string; 13825 else 13826 { 13827 int error = FALSE; 13828 13829 i = get_tv_number_chk(&argvars[1], &error); 13830 if (error) 13831 return; /* type error; errmsg already given */ 13832 if (i == 1) 13833 item_compare_ic = TRUE; 13834 else 13835 item_compare_func = get_tv_string(&argvars[1]); 13836 } 13837 } 13838 13839 /* Make an array with each entry pointing to an item in the List. */ 13840 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13841 if (ptrs == NULL) 13842 return; 13843 i = 0; 13844 for (li = l->lv_first; li != NULL; li = li->li_next) 13845 ptrs[i++] = li; 13846 13847 item_compare_func_err = FALSE; 13848 /* test the compare function */ 13849 if (item_compare_func != NULL 13850 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13851 == ITEM_COMPARE_FAIL) 13852 EMSG(_("E702: Sort compare function failed")); 13853 else 13854 { 13855 /* Sort the array with item pointers. */ 13856 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13857 item_compare_func == NULL ? item_compare : item_compare2); 13858 13859 if (!item_compare_func_err) 13860 { 13861 /* Clear the List and append the items in the sorted order. */ 13862 l->lv_first = l->lv_last = NULL; 13863 l->lv_len = 0; 13864 for (i = 0; i < len; ++i) 13865 list_append(l, ptrs[i]); 13866 } 13867 } 13868 13869 vim_free(ptrs); 13870 } 13871 } 13872 13873 /* 13874 * "soundfold({word})" function 13875 */ 13876 static void 13877 f_soundfold(argvars, rettv) 13878 typval_T *argvars; 13879 typval_T *rettv; 13880 { 13881 char_u *s; 13882 13883 rettv->v_type = VAR_STRING; 13884 s = get_tv_string(&argvars[0]); 13885 #ifdef FEAT_SYN_HL 13886 rettv->vval.v_string = eval_soundfold(s); 13887 #else 13888 rettv->vval.v_string = vim_strsave(s); 13889 #endif 13890 } 13891 13892 /* 13893 * "spellbadword()" function 13894 */ 13895 /* ARGSUSED */ 13896 static void 13897 f_spellbadword(argvars, rettv) 13898 typval_T *argvars; 13899 typval_T *rettv; 13900 { 13901 char_u *word = (char_u *)""; 13902 #ifdef FEAT_SYN_HL 13903 int len = 0; 13904 hlf_T attr = HLF_COUNT; 13905 list_T *l; 13906 #endif 13907 13908 l = list_alloc(); 13909 if (l == NULL) 13910 return; 13911 rettv->v_type = VAR_LIST; 13912 rettv->vval.v_list = l; 13913 ++l->lv_refcount; 13914 13915 #ifdef FEAT_SYN_HL 13916 if (argvars[0].v_type == VAR_UNKNOWN) 13917 { 13918 /* Find the start and length of the badly spelled word. */ 13919 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 13920 if (len != 0) 13921 word = ml_get_cursor(); 13922 } 13923 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13924 { 13925 char_u *str = get_tv_string_chk(&argvars[0]); 13926 int capcol = -1; 13927 13928 if (str != NULL) 13929 { 13930 /* Check the argument for spelling. */ 13931 while (*str != NUL) 13932 { 13933 len = spell_check(curwin, str, &attr, &capcol); 13934 if (attr != HLF_COUNT) 13935 { 13936 word = str; 13937 break; 13938 } 13939 str += len; 13940 } 13941 } 13942 } 13943 #endif 13944 13945 list_append_string(l, word, len); 13946 list_append_string(l, (char_u *)( 13947 attr == HLF_SPB ? "bad" : 13948 attr == HLF_SPR ? "rare" : 13949 attr == HLF_SPL ? "local" : 13950 attr == HLF_SPC ? "caps" : 13951 ""), -1); 13952 } 13953 13954 /* 13955 * "spellsuggest()" function 13956 */ 13957 static void 13958 f_spellsuggest(argvars, rettv) 13959 typval_T *argvars; 13960 typval_T *rettv; 13961 { 13962 list_T *l; 13963 #ifdef FEAT_SYN_HL 13964 char_u *str; 13965 int typeerr = FALSE; 13966 int maxcount; 13967 garray_T ga; 13968 int i; 13969 listitem_T *li; 13970 int need_capital = FALSE; 13971 #endif 13972 13973 l = list_alloc(); 13974 if (l == NULL) 13975 return; 13976 rettv->v_type = VAR_LIST; 13977 rettv->vval.v_list = l; 13978 ++l->lv_refcount; 13979 13980 #ifdef FEAT_SYN_HL 13981 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13982 { 13983 str = get_tv_string(&argvars[0]); 13984 if (argvars[1].v_type != VAR_UNKNOWN) 13985 { 13986 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 13987 if (maxcount <= 0) 13988 return; 13989 if (argvars[2].v_type != VAR_UNKNOWN) 13990 { 13991 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 13992 if (typeerr) 13993 return; 13994 } 13995 } 13996 else 13997 maxcount = 25; 13998 13999 spell_suggest_list(&ga, str, maxcount, need_capital); 14000 14001 for (i = 0; i < ga.ga_len; ++i) 14002 { 14003 str = ((char_u **)ga.ga_data)[i]; 14004 14005 li = listitem_alloc(); 14006 if (li == NULL) 14007 vim_free(str); 14008 else 14009 { 14010 li->li_tv.v_type = VAR_STRING; 14011 li->li_tv.v_lock = 0; 14012 li->li_tv.vval.v_string = str; 14013 list_append(l, li); 14014 } 14015 } 14016 ga_clear(&ga); 14017 } 14018 #endif 14019 } 14020 14021 static void 14022 f_split(argvars, rettv) 14023 typval_T *argvars; 14024 typval_T *rettv; 14025 { 14026 char_u *str; 14027 char_u *end; 14028 char_u *pat = NULL; 14029 regmatch_T regmatch; 14030 char_u patbuf[NUMBUFLEN]; 14031 char_u *save_cpo; 14032 int match; 14033 list_T *l; 14034 colnr_T col = 0; 14035 int keepempty = FALSE; 14036 int typeerr = FALSE; 14037 14038 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14039 save_cpo = p_cpo; 14040 p_cpo = (char_u *)""; 14041 14042 str = get_tv_string(&argvars[0]); 14043 if (argvars[1].v_type != VAR_UNKNOWN) 14044 { 14045 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14046 if (pat == NULL) 14047 typeerr = TRUE; 14048 if (argvars[2].v_type != VAR_UNKNOWN) 14049 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 14050 } 14051 if (pat == NULL || *pat == NUL) 14052 pat = (char_u *)"[\\x01- ]\\+"; 14053 14054 l = list_alloc(); 14055 if (l == NULL) 14056 return; 14057 rettv->v_type = VAR_LIST; 14058 rettv->vval.v_list = l; 14059 ++l->lv_refcount; 14060 if (typeerr) 14061 return; 14062 14063 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14064 if (regmatch.regprog != NULL) 14065 { 14066 regmatch.rm_ic = FALSE; 14067 while (*str != NUL || keepempty) 14068 { 14069 if (*str == NUL) 14070 match = FALSE; /* empty item at the end */ 14071 else 14072 match = vim_regexec_nl(®match, str, col); 14073 if (match) 14074 end = regmatch.startp[0]; 14075 else 14076 end = str + STRLEN(str); 14077 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 14078 && match && end < regmatch.endp[0])) 14079 { 14080 if (list_append_string(l, str, (int)(end - str)) == FAIL) 14081 break; 14082 } 14083 if (!match) 14084 break; 14085 /* Advance to just after the match. */ 14086 if (regmatch.endp[0] > str) 14087 col = 0; 14088 else 14089 { 14090 /* Don't get stuck at the same match. */ 14091 #ifdef FEAT_MBYTE 14092 col = (*mb_ptr2len)(regmatch.endp[0]); 14093 #else 14094 col = 1; 14095 #endif 14096 } 14097 str = regmatch.endp[0]; 14098 } 14099 14100 vim_free(regmatch.regprog); 14101 } 14102 14103 p_cpo = save_cpo; 14104 } 14105 14106 #ifdef HAVE_STRFTIME 14107 /* 14108 * "strftime({format}[, {time}])" function 14109 */ 14110 static void 14111 f_strftime(argvars, rettv) 14112 typval_T *argvars; 14113 typval_T *rettv; 14114 { 14115 char_u result_buf[256]; 14116 struct tm *curtime; 14117 time_t seconds; 14118 char_u *p; 14119 14120 rettv->v_type = VAR_STRING; 14121 14122 p = get_tv_string(&argvars[0]); 14123 if (argvars[1].v_type == VAR_UNKNOWN) 14124 seconds = time(NULL); 14125 else 14126 seconds = (time_t)get_tv_number(&argvars[1]); 14127 curtime = localtime(&seconds); 14128 /* MSVC returns NULL for an invalid value of seconds. */ 14129 if (curtime == NULL) 14130 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 14131 else 14132 { 14133 # ifdef FEAT_MBYTE 14134 vimconv_T conv; 14135 char_u *enc; 14136 14137 conv.vc_type = CONV_NONE; 14138 enc = enc_locale(); 14139 convert_setup(&conv, p_enc, enc); 14140 if (conv.vc_type != CONV_NONE) 14141 p = string_convert(&conv, p, NULL); 14142 # endif 14143 if (p != NULL) 14144 (void)strftime((char *)result_buf, sizeof(result_buf), 14145 (char *)p, curtime); 14146 else 14147 result_buf[0] = NUL; 14148 14149 # ifdef FEAT_MBYTE 14150 if (conv.vc_type != CONV_NONE) 14151 vim_free(p); 14152 convert_setup(&conv, enc, p_enc); 14153 if (conv.vc_type != CONV_NONE) 14154 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 14155 else 14156 # endif 14157 rettv->vval.v_string = vim_strsave(result_buf); 14158 14159 # ifdef FEAT_MBYTE 14160 /* Release conversion descriptors */ 14161 convert_setup(&conv, NULL, NULL); 14162 vim_free(enc); 14163 # endif 14164 } 14165 } 14166 #endif 14167 14168 /* 14169 * "stridx()" function 14170 */ 14171 static void 14172 f_stridx(argvars, rettv) 14173 typval_T *argvars; 14174 typval_T *rettv; 14175 { 14176 char_u buf[NUMBUFLEN]; 14177 char_u *needle; 14178 char_u *haystack; 14179 char_u *save_haystack; 14180 char_u *pos; 14181 int start_idx; 14182 14183 needle = get_tv_string_chk(&argvars[1]); 14184 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 14185 rettv->vval.v_number = -1; 14186 if (needle == NULL || haystack == NULL) 14187 return; /* type error; errmsg already given */ 14188 14189 if (argvars[2].v_type != VAR_UNKNOWN) 14190 { 14191 int error = FALSE; 14192 14193 start_idx = get_tv_number_chk(&argvars[2], &error); 14194 if (error || start_idx >= (int)STRLEN(haystack)) 14195 return; 14196 if (start_idx >= 0) 14197 haystack += start_idx; 14198 } 14199 14200 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14201 if (pos != NULL) 14202 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14203 } 14204 14205 /* 14206 * "string()" function 14207 */ 14208 static void 14209 f_string(argvars, rettv) 14210 typval_T *argvars; 14211 typval_T *rettv; 14212 { 14213 char_u *tofree; 14214 char_u numbuf[NUMBUFLEN]; 14215 14216 rettv->v_type = VAR_STRING; 14217 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14218 if (tofree == NULL) 14219 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14220 } 14221 14222 /* 14223 * "strlen()" function 14224 */ 14225 static void 14226 f_strlen(argvars, rettv) 14227 typval_T *argvars; 14228 typval_T *rettv; 14229 { 14230 rettv->vval.v_number = (varnumber_T)(STRLEN( 14231 get_tv_string(&argvars[0]))); 14232 } 14233 14234 /* 14235 * "strpart()" function 14236 */ 14237 static void 14238 f_strpart(argvars, rettv) 14239 typval_T *argvars; 14240 typval_T *rettv; 14241 { 14242 char_u *p; 14243 int n; 14244 int len; 14245 int slen; 14246 int error = FALSE; 14247 14248 p = get_tv_string(&argvars[0]); 14249 slen = (int)STRLEN(p); 14250 14251 n = get_tv_number_chk(&argvars[1], &error); 14252 if (error) 14253 len = 0; 14254 else if (argvars[2].v_type != VAR_UNKNOWN) 14255 len = get_tv_number(&argvars[2]); 14256 else 14257 len = slen - n; /* default len: all bytes that are available. */ 14258 14259 /* 14260 * Only return the overlap between the specified part and the actual 14261 * string. 14262 */ 14263 if (n < 0) 14264 { 14265 len += n; 14266 n = 0; 14267 } 14268 else if (n > slen) 14269 n = slen; 14270 if (len < 0) 14271 len = 0; 14272 else if (n + len > slen) 14273 len = slen - n; 14274 14275 rettv->v_type = VAR_STRING; 14276 rettv->vval.v_string = vim_strnsave(p + n, len); 14277 } 14278 14279 /* 14280 * "strridx()" function 14281 */ 14282 static void 14283 f_strridx(argvars, rettv) 14284 typval_T *argvars; 14285 typval_T *rettv; 14286 { 14287 char_u buf[NUMBUFLEN]; 14288 char_u *needle; 14289 char_u *haystack; 14290 char_u *rest; 14291 char_u *lastmatch = NULL; 14292 int haystack_len, end_idx; 14293 14294 needle = get_tv_string_chk(&argvars[1]); 14295 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14296 haystack_len = STRLEN(haystack); 14297 14298 rettv->vval.v_number = -1; 14299 if (needle == NULL || haystack == NULL) 14300 return; /* type error; errmsg already given */ 14301 if (argvars[2].v_type != VAR_UNKNOWN) 14302 { 14303 /* Third argument: upper limit for index */ 14304 end_idx = get_tv_number_chk(&argvars[2], NULL); 14305 if (end_idx < 0) 14306 return; /* can never find a match */ 14307 } 14308 else 14309 end_idx = haystack_len; 14310 14311 if (*needle == NUL) 14312 { 14313 /* Empty string matches past the end. */ 14314 lastmatch = haystack + end_idx; 14315 } 14316 else 14317 { 14318 for (rest = haystack; *rest != '\0'; ++rest) 14319 { 14320 rest = (char_u *)strstr((char *)rest, (char *)needle); 14321 if (rest == NULL || rest > haystack + end_idx) 14322 break; 14323 lastmatch = rest; 14324 } 14325 } 14326 14327 if (lastmatch == NULL) 14328 rettv->vval.v_number = -1; 14329 else 14330 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14331 } 14332 14333 /* 14334 * "strtrans()" function 14335 */ 14336 static void 14337 f_strtrans(argvars, rettv) 14338 typval_T *argvars; 14339 typval_T *rettv; 14340 { 14341 rettv->v_type = VAR_STRING; 14342 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14343 } 14344 14345 /* 14346 * "submatch()" function 14347 */ 14348 static void 14349 f_submatch(argvars, rettv) 14350 typval_T *argvars; 14351 typval_T *rettv; 14352 { 14353 rettv->v_type = VAR_STRING; 14354 rettv->vval.v_string = 14355 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14356 } 14357 14358 /* 14359 * "substitute()" function 14360 */ 14361 static void 14362 f_substitute(argvars, rettv) 14363 typval_T *argvars; 14364 typval_T *rettv; 14365 { 14366 char_u patbuf[NUMBUFLEN]; 14367 char_u subbuf[NUMBUFLEN]; 14368 char_u flagsbuf[NUMBUFLEN]; 14369 14370 char_u *str = get_tv_string_chk(&argvars[0]); 14371 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14372 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14373 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14374 14375 rettv->v_type = VAR_STRING; 14376 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14377 rettv->vval.v_string = NULL; 14378 else 14379 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14380 } 14381 14382 /* 14383 * "synID(lnum, col, trans)" function 14384 */ 14385 /*ARGSUSED*/ 14386 static void 14387 f_synID(argvars, rettv) 14388 typval_T *argvars; 14389 typval_T *rettv; 14390 { 14391 int id = 0; 14392 #ifdef FEAT_SYN_HL 14393 long lnum; 14394 long col; 14395 int trans; 14396 int transerr = FALSE; 14397 14398 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14399 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14400 trans = get_tv_number_chk(&argvars[2], &transerr); 14401 14402 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14403 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14404 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14405 #endif 14406 14407 rettv->vval.v_number = id; 14408 } 14409 14410 /* 14411 * "synIDattr(id, what [, mode])" function 14412 */ 14413 /*ARGSUSED*/ 14414 static void 14415 f_synIDattr(argvars, rettv) 14416 typval_T *argvars; 14417 typval_T *rettv; 14418 { 14419 char_u *p = NULL; 14420 #ifdef FEAT_SYN_HL 14421 int id; 14422 char_u *what; 14423 char_u *mode; 14424 char_u modebuf[NUMBUFLEN]; 14425 int modec; 14426 14427 id = get_tv_number(&argvars[0]); 14428 what = get_tv_string(&argvars[1]); 14429 if (argvars[2].v_type != VAR_UNKNOWN) 14430 { 14431 mode = get_tv_string_buf(&argvars[2], modebuf); 14432 modec = TOLOWER_ASC(mode[0]); 14433 if (modec != 't' && modec != 'c' 14434 #ifdef FEAT_GUI 14435 && modec != 'g' 14436 #endif 14437 ) 14438 modec = 0; /* replace invalid with current */ 14439 } 14440 else 14441 { 14442 #ifdef FEAT_GUI 14443 if (gui.in_use) 14444 modec = 'g'; 14445 else 14446 #endif 14447 if (t_colors > 1) 14448 modec = 'c'; 14449 else 14450 modec = 't'; 14451 } 14452 14453 14454 switch (TOLOWER_ASC(what[0])) 14455 { 14456 case 'b': 14457 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14458 p = highlight_color(id, what, modec); 14459 else /* bold */ 14460 p = highlight_has_attr(id, HL_BOLD, modec); 14461 break; 14462 14463 case 'f': /* fg[#] */ 14464 p = highlight_color(id, what, modec); 14465 break; 14466 14467 case 'i': 14468 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14469 p = highlight_has_attr(id, HL_INVERSE, modec); 14470 else /* italic */ 14471 p = highlight_has_attr(id, HL_ITALIC, modec); 14472 break; 14473 14474 case 'n': /* name */ 14475 p = get_highlight_name(NULL, id - 1); 14476 break; 14477 14478 case 'r': /* reverse */ 14479 p = highlight_has_attr(id, HL_INVERSE, modec); 14480 break; 14481 14482 case 's': /* standout */ 14483 p = highlight_has_attr(id, HL_STANDOUT, modec); 14484 break; 14485 14486 case 'u': 14487 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14488 /* underline */ 14489 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14490 else 14491 /* undercurl */ 14492 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14493 break; 14494 } 14495 14496 if (p != NULL) 14497 p = vim_strsave(p); 14498 #endif 14499 rettv->v_type = VAR_STRING; 14500 rettv->vval.v_string = p; 14501 } 14502 14503 /* 14504 * "synIDtrans(id)" function 14505 */ 14506 /*ARGSUSED*/ 14507 static void 14508 f_synIDtrans(argvars, rettv) 14509 typval_T *argvars; 14510 typval_T *rettv; 14511 { 14512 int id; 14513 14514 #ifdef FEAT_SYN_HL 14515 id = get_tv_number(&argvars[0]); 14516 14517 if (id > 0) 14518 id = syn_get_final_id(id); 14519 else 14520 #endif 14521 id = 0; 14522 14523 rettv->vval.v_number = id; 14524 } 14525 14526 /* 14527 * "system()" function 14528 */ 14529 static void 14530 f_system(argvars, rettv) 14531 typval_T *argvars; 14532 typval_T *rettv; 14533 { 14534 char_u *res = NULL; 14535 char_u *p; 14536 char_u *infile = NULL; 14537 char_u buf[NUMBUFLEN]; 14538 int err = FALSE; 14539 FILE *fd; 14540 14541 if (argvars[1].v_type != VAR_UNKNOWN) 14542 { 14543 /* 14544 * Write the string to a temp file, to be used for input of the shell 14545 * command. 14546 */ 14547 if ((infile = vim_tempname('i')) == NULL) 14548 { 14549 EMSG(_(e_notmp)); 14550 return; 14551 } 14552 14553 fd = mch_fopen((char *)infile, WRITEBIN); 14554 if (fd == NULL) 14555 { 14556 EMSG2(_(e_notopen), infile); 14557 goto done; 14558 } 14559 p = get_tv_string_buf_chk(&argvars[1], buf); 14560 if (p == NULL) 14561 goto done; /* type error; errmsg already given */ 14562 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14563 err = TRUE; 14564 if (fclose(fd) != 0) 14565 err = TRUE; 14566 if (err) 14567 { 14568 EMSG(_("E677: Error writing temp file")); 14569 goto done; 14570 } 14571 } 14572 14573 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14574 14575 #ifdef USE_CR 14576 /* translate <CR> into <NL> */ 14577 if (res != NULL) 14578 { 14579 char_u *s; 14580 14581 for (s = res; *s; ++s) 14582 { 14583 if (*s == CAR) 14584 *s = NL; 14585 } 14586 } 14587 #else 14588 # ifdef USE_CRNL 14589 /* translate <CR><NL> into <NL> */ 14590 if (res != NULL) 14591 { 14592 char_u *s, *d; 14593 14594 d = res; 14595 for (s = res; *s; ++s) 14596 { 14597 if (s[0] == CAR && s[1] == NL) 14598 ++s; 14599 *d++ = *s; 14600 } 14601 *d = NUL; 14602 } 14603 # endif 14604 #endif 14605 14606 done: 14607 if (infile != NULL) 14608 { 14609 mch_remove(infile); 14610 vim_free(infile); 14611 } 14612 rettv->v_type = VAR_STRING; 14613 rettv->vval.v_string = res; 14614 } 14615 14616 /* 14617 * "tagfiles()" function 14618 */ 14619 /*ARGSUSED*/ 14620 static void 14621 f_tagfiles(argvars, rettv) 14622 typval_T *argvars; 14623 typval_T *rettv; 14624 { 14625 char_u fname[MAXPATHL + 1]; 14626 list_T *l; 14627 14628 l = list_alloc(); 14629 if (l == NULL) 14630 { 14631 rettv->vval.v_number = 0; 14632 return; 14633 } 14634 rettv->vval.v_list = l; 14635 rettv->v_type = VAR_LIST; 14636 ++l->lv_refcount; 14637 14638 get_tagfname(TRUE, NULL); 14639 for (;;) 14640 if (get_tagfname(FALSE, fname) == FAIL 14641 || list_append_string(l, fname, -1) == FAIL) 14642 break; 14643 } 14644 14645 /* 14646 * "taglist()" function 14647 */ 14648 static void 14649 f_taglist(argvars, rettv) 14650 typval_T *argvars; 14651 typval_T *rettv; 14652 { 14653 char_u *tag_pattern; 14654 list_T *l; 14655 14656 tag_pattern = get_tv_string(&argvars[0]); 14657 14658 rettv->vval.v_number = FALSE; 14659 if (*tag_pattern == NUL) 14660 return; 14661 14662 l = list_alloc(); 14663 if (l != NULL) 14664 { 14665 if (get_tags(l, tag_pattern) != FAIL) 14666 { 14667 rettv->vval.v_list = l; 14668 rettv->v_type = VAR_LIST; 14669 ++l->lv_refcount; 14670 } 14671 else 14672 list_free(l); 14673 } 14674 } 14675 14676 /* 14677 * "tempname()" function 14678 */ 14679 /*ARGSUSED*/ 14680 static void 14681 f_tempname(argvars, rettv) 14682 typval_T *argvars; 14683 typval_T *rettv; 14684 { 14685 static int x = 'A'; 14686 14687 rettv->v_type = VAR_STRING; 14688 rettv->vval.v_string = vim_tempname(x); 14689 14690 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14691 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14692 do 14693 { 14694 if (x == 'Z') 14695 x = '0'; 14696 else if (x == '9') 14697 x = 'A'; 14698 else 14699 { 14700 #ifdef EBCDIC 14701 if (x == 'I') 14702 x = 'J'; 14703 else if (x == 'R') 14704 x = 'S'; 14705 else 14706 #endif 14707 ++x; 14708 } 14709 } while (x == 'I' || x == 'O'); 14710 } 14711 14712 /* 14713 * "test(list)" function: Just checking the walls... 14714 */ 14715 /*ARGSUSED*/ 14716 static void 14717 f_test(argvars, rettv) 14718 typval_T *argvars; 14719 typval_T *rettv; 14720 { 14721 /* Used for unit testing. Change the code below to your liking. */ 14722 #if 0 14723 listitem_T *li; 14724 list_T *l; 14725 char_u *bad, *good; 14726 14727 if (argvars[0].v_type != VAR_LIST) 14728 return; 14729 l = argvars[0].vval.v_list; 14730 if (l == NULL) 14731 return; 14732 li = l->lv_first; 14733 if (li == NULL) 14734 return; 14735 bad = get_tv_string(&li->li_tv); 14736 li = li->li_next; 14737 if (li == NULL) 14738 return; 14739 good = get_tv_string(&li->li_tv); 14740 rettv->vval.v_number = test_edit_score(bad, good); 14741 #endif 14742 } 14743 14744 /* 14745 * "tolower(string)" function 14746 */ 14747 static void 14748 f_tolower(argvars, rettv) 14749 typval_T *argvars; 14750 typval_T *rettv; 14751 { 14752 char_u *p; 14753 14754 p = vim_strsave(get_tv_string(&argvars[0])); 14755 rettv->v_type = VAR_STRING; 14756 rettv->vval.v_string = p; 14757 14758 if (p != NULL) 14759 while (*p != NUL) 14760 { 14761 #ifdef FEAT_MBYTE 14762 int l; 14763 14764 if (enc_utf8) 14765 { 14766 int c, lc; 14767 14768 c = utf_ptr2char(p); 14769 lc = utf_tolower(c); 14770 l = utf_ptr2len(p); 14771 /* TODO: reallocate string when byte count changes. */ 14772 if (utf_char2len(lc) == l) 14773 utf_char2bytes(lc, p); 14774 p += l; 14775 } 14776 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14777 p += l; /* skip multi-byte character */ 14778 else 14779 #endif 14780 { 14781 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14782 ++p; 14783 } 14784 } 14785 } 14786 14787 /* 14788 * "toupper(string)" function 14789 */ 14790 static void 14791 f_toupper(argvars, rettv) 14792 typval_T *argvars; 14793 typval_T *rettv; 14794 { 14795 rettv->v_type = VAR_STRING; 14796 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14797 } 14798 14799 /* 14800 * "tr(string, fromstr, tostr)" function 14801 */ 14802 static void 14803 f_tr(argvars, rettv) 14804 typval_T *argvars; 14805 typval_T *rettv; 14806 { 14807 char_u *instr; 14808 char_u *fromstr; 14809 char_u *tostr; 14810 char_u *p; 14811 #ifdef FEAT_MBYTE 14812 int inlen; 14813 int fromlen; 14814 int tolen; 14815 int idx; 14816 char_u *cpstr; 14817 int cplen; 14818 int first = TRUE; 14819 #endif 14820 char_u buf[NUMBUFLEN]; 14821 char_u buf2[NUMBUFLEN]; 14822 garray_T ga; 14823 14824 instr = get_tv_string(&argvars[0]); 14825 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14826 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14827 14828 /* Default return value: empty string. */ 14829 rettv->v_type = VAR_STRING; 14830 rettv->vval.v_string = NULL; 14831 if (fromstr == NULL || tostr == NULL) 14832 return; /* type error; errmsg already given */ 14833 ga_init2(&ga, (int)sizeof(char), 80); 14834 14835 #ifdef FEAT_MBYTE 14836 if (!has_mbyte) 14837 #endif 14838 /* not multi-byte: fromstr and tostr must be the same length */ 14839 if (STRLEN(fromstr) != STRLEN(tostr)) 14840 { 14841 #ifdef FEAT_MBYTE 14842 error: 14843 #endif 14844 EMSG2(_(e_invarg2), fromstr); 14845 ga_clear(&ga); 14846 return; 14847 } 14848 14849 /* fromstr and tostr have to contain the same number of chars */ 14850 while (*instr != NUL) 14851 { 14852 #ifdef FEAT_MBYTE 14853 if (has_mbyte) 14854 { 14855 inlen = (*mb_ptr2len)(instr); 14856 cpstr = instr; 14857 cplen = inlen; 14858 idx = 0; 14859 for (p = fromstr; *p != NUL; p += fromlen) 14860 { 14861 fromlen = (*mb_ptr2len)(p); 14862 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14863 { 14864 for (p = tostr; *p != NUL; p += tolen) 14865 { 14866 tolen = (*mb_ptr2len)(p); 14867 if (idx-- == 0) 14868 { 14869 cplen = tolen; 14870 cpstr = p; 14871 break; 14872 } 14873 } 14874 if (*p == NUL) /* tostr is shorter than fromstr */ 14875 goto error; 14876 break; 14877 } 14878 ++idx; 14879 } 14880 14881 if (first && cpstr == instr) 14882 { 14883 /* Check that fromstr and tostr have the same number of 14884 * (multi-byte) characters. Done only once when a character 14885 * of instr doesn't appear in fromstr. */ 14886 first = FALSE; 14887 for (p = tostr; *p != NUL; p += tolen) 14888 { 14889 tolen = (*mb_ptr2len)(p); 14890 --idx; 14891 } 14892 if (idx != 0) 14893 goto error; 14894 } 14895 14896 ga_grow(&ga, cplen); 14897 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14898 ga.ga_len += cplen; 14899 14900 instr += inlen; 14901 } 14902 else 14903 #endif 14904 { 14905 /* When not using multi-byte chars we can do it faster. */ 14906 p = vim_strchr(fromstr, *instr); 14907 if (p != NULL) 14908 ga_append(&ga, tostr[p - fromstr]); 14909 else 14910 ga_append(&ga, *instr); 14911 ++instr; 14912 } 14913 } 14914 14915 rettv->vval.v_string = ga.ga_data; 14916 } 14917 14918 /* 14919 * "type(expr)" function 14920 */ 14921 static void 14922 f_type(argvars, rettv) 14923 typval_T *argvars; 14924 typval_T *rettv; 14925 { 14926 int n; 14927 14928 switch (argvars[0].v_type) 14929 { 14930 case VAR_NUMBER: n = 0; break; 14931 case VAR_STRING: n = 1; break; 14932 case VAR_FUNC: n = 2; break; 14933 case VAR_LIST: n = 3; break; 14934 case VAR_DICT: n = 4; break; 14935 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14936 } 14937 rettv->vval.v_number = n; 14938 } 14939 14940 /* 14941 * "values(dict)" function 14942 */ 14943 static void 14944 f_values(argvars, rettv) 14945 typval_T *argvars; 14946 typval_T *rettv; 14947 { 14948 dict_list(argvars, rettv, 1); 14949 } 14950 14951 /* 14952 * "virtcol(string)" function 14953 */ 14954 static void 14955 f_virtcol(argvars, rettv) 14956 typval_T *argvars; 14957 typval_T *rettv; 14958 { 14959 colnr_T vcol = 0; 14960 pos_T *fp; 14961 14962 fp = var2fpos(&argvars[0], FALSE); 14963 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14964 { 14965 getvvcol(curwin, fp, NULL, NULL, &vcol); 14966 ++vcol; 14967 } 14968 14969 rettv->vval.v_number = vcol; 14970 } 14971 14972 /* 14973 * "visualmode()" function 14974 */ 14975 /*ARGSUSED*/ 14976 static void 14977 f_visualmode(argvars, rettv) 14978 typval_T *argvars; 14979 typval_T *rettv; 14980 { 14981 #ifdef FEAT_VISUAL 14982 char_u str[2]; 14983 14984 rettv->v_type = VAR_STRING; 14985 str[0] = curbuf->b_visual_mode_eval; 14986 str[1] = NUL; 14987 rettv->vval.v_string = vim_strsave(str); 14988 14989 /* A non-zero number or non-empty string argument: reset mode. */ 14990 if ((argvars[0].v_type == VAR_NUMBER 14991 && argvars[0].vval.v_number != 0) 14992 || (argvars[0].v_type == VAR_STRING 14993 && *get_tv_string(&argvars[0]) != NUL)) 14994 curbuf->b_visual_mode_eval = NUL; 14995 #else 14996 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14997 #endif 14998 } 14999 15000 /* 15001 * "winbufnr(nr)" function 15002 */ 15003 static void 15004 f_winbufnr(argvars, rettv) 15005 typval_T *argvars; 15006 typval_T *rettv; 15007 { 15008 win_T *wp; 15009 15010 wp = find_win_by_nr(&argvars[0]); 15011 if (wp == NULL) 15012 rettv->vval.v_number = -1; 15013 else 15014 rettv->vval.v_number = wp->w_buffer->b_fnum; 15015 } 15016 15017 /* 15018 * "wincol()" function 15019 */ 15020 /*ARGSUSED*/ 15021 static void 15022 f_wincol(argvars, rettv) 15023 typval_T *argvars; 15024 typval_T *rettv; 15025 { 15026 validate_cursor(); 15027 rettv->vval.v_number = curwin->w_wcol + 1; 15028 } 15029 15030 /* 15031 * "winheight(nr)" function 15032 */ 15033 static void 15034 f_winheight(argvars, rettv) 15035 typval_T *argvars; 15036 typval_T *rettv; 15037 { 15038 win_T *wp; 15039 15040 wp = find_win_by_nr(&argvars[0]); 15041 if (wp == NULL) 15042 rettv->vval.v_number = -1; 15043 else 15044 rettv->vval.v_number = wp->w_height; 15045 } 15046 15047 /* 15048 * "winline()" function 15049 */ 15050 /*ARGSUSED*/ 15051 static void 15052 f_winline(argvars, rettv) 15053 typval_T *argvars; 15054 typval_T *rettv; 15055 { 15056 validate_cursor(); 15057 rettv->vval.v_number = curwin->w_wrow + 1; 15058 } 15059 15060 /* 15061 * "winnr()" function 15062 */ 15063 /* ARGSUSED */ 15064 static void 15065 f_winnr(argvars, rettv) 15066 typval_T *argvars; 15067 typval_T *rettv; 15068 { 15069 int nr = 1; 15070 #ifdef FEAT_WINDOWS 15071 win_T *wp; 15072 win_T *twin = curwin; 15073 char_u *arg; 15074 15075 if (argvars[0].v_type != VAR_UNKNOWN) 15076 { 15077 arg = get_tv_string_chk(&argvars[0]); 15078 if (arg == NULL) 15079 nr = 0; /* type error; errmsg already given */ 15080 else if (STRCMP(arg, "$") == 0) 15081 twin = lastwin; 15082 else if (STRCMP(arg, "#") == 0) 15083 { 15084 twin = prevwin; 15085 if (prevwin == NULL) 15086 nr = 0; 15087 } 15088 else 15089 { 15090 EMSG2(_(e_invexpr2), arg); 15091 nr = 0; 15092 } 15093 } 15094 15095 if (nr > 0) 15096 for (wp = firstwin; wp != twin; wp = wp->w_next) 15097 ++nr; 15098 #endif 15099 rettv->vval.v_number = nr; 15100 } 15101 15102 /* 15103 * "winrestcmd()" function 15104 */ 15105 /* ARGSUSED */ 15106 static void 15107 f_winrestcmd(argvars, rettv) 15108 typval_T *argvars; 15109 typval_T *rettv; 15110 { 15111 #ifdef FEAT_WINDOWS 15112 win_T *wp; 15113 int winnr = 1; 15114 garray_T ga; 15115 char_u buf[50]; 15116 15117 ga_init2(&ga, (int)sizeof(char), 70); 15118 for (wp = firstwin; wp != NULL; wp = wp->w_next) 15119 { 15120 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 15121 ga_concat(&ga, buf); 15122 # ifdef FEAT_VERTSPLIT 15123 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 15124 ga_concat(&ga, buf); 15125 # endif 15126 ++winnr; 15127 } 15128 ga_append(&ga, NUL); 15129 15130 rettv->vval.v_string = ga.ga_data; 15131 #else 15132 rettv->vval.v_string = NULL; 15133 #endif 15134 rettv->v_type = VAR_STRING; 15135 } 15136 15137 /* 15138 * "winwidth(nr)" function 15139 */ 15140 static void 15141 f_winwidth(argvars, rettv) 15142 typval_T *argvars; 15143 typval_T *rettv; 15144 { 15145 win_T *wp; 15146 15147 wp = find_win_by_nr(&argvars[0]); 15148 if (wp == NULL) 15149 rettv->vval.v_number = -1; 15150 else 15151 #ifdef FEAT_VERTSPLIT 15152 rettv->vval.v_number = wp->w_width; 15153 #else 15154 rettv->vval.v_number = Columns; 15155 #endif 15156 } 15157 15158 /* 15159 * "writefile()" function 15160 */ 15161 static void 15162 f_writefile(argvars, rettv) 15163 typval_T *argvars; 15164 typval_T *rettv; 15165 { 15166 int binary = FALSE; 15167 char_u *fname; 15168 FILE *fd; 15169 listitem_T *li; 15170 char_u *s; 15171 int ret = 0; 15172 int c; 15173 15174 if (argvars[0].v_type != VAR_LIST) 15175 { 15176 EMSG2(_(e_listarg), "writefile()"); 15177 return; 15178 } 15179 if (argvars[0].vval.v_list == NULL) 15180 return; 15181 15182 if (argvars[2].v_type != VAR_UNKNOWN 15183 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 15184 binary = TRUE; 15185 15186 /* Always open the file in binary mode, library functions have a mind of 15187 * their own about CR-LF conversion. */ 15188 fname = get_tv_string(&argvars[1]); 15189 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 15190 { 15191 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 15192 ret = -1; 15193 } 15194 else 15195 { 15196 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 15197 li = li->li_next) 15198 { 15199 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 15200 { 15201 if (*s == '\n') 15202 c = putc(NUL, fd); 15203 else 15204 c = putc(*s, fd); 15205 if (c == EOF) 15206 { 15207 ret = -1; 15208 break; 15209 } 15210 } 15211 if (!binary || li->li_next != NULL) 15212 if (putc('\n', fd) == EOF) 15213 { 15214 ret = -1; 15215 break; 15216 } 15217 if (ret < 0) 15218 { 15219 EMSG(_(e_write)); 15220 break; 15221 } 15222 } 15223 fclose(fd); 15224 } 15225 15226 rettv->vval.v_number = ret; 15227 } 15228 15229 /* 15230 * Translate a String variable into a position. 15231 */ 15232 static pos_T * 15233 var2fpos(varp, lnum) 15234 typval_T *varp; 15235 int lnum; /* TRUE when $ is last line */ 15236 { 15237 char_u *name; 15238 static pos_T pos; 15239 pos_T *pp; 15240 15241 name = get_tv_string_chk(varp); 15242 if (name == NULL) 15243 return NULL; 15244 if (name[0] == '.') /* cursor */ 15245 return &curwin->w_cursor; 15246 if (name[0] == '\'') /* mark */ 15247 { 15248 pp = getmark(name[1], FALSE); 15249 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15250 return NULL; 15251 return pp; 15252 } 15253 if (name[0] == '$') /* last column or line */ 15254 { 15255 if (lnum) 15256 { 15257 pos.lnum = curbuf->b_ml.ml_line_count; 15258 pos.col = 0; 15259 } 15260 else 15261 { 15262 pos.lnum = curwin->w_cursor.lnum; 15263 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15264 } 15265 return &pos; 15266 } 15267 return NULL; 15268 } 15269 15270 /* 15271 * Get the length of an environment variable name. 15272 * Advance "arg" to the first character after the name. 15273 * Return 0 for error. 15274 */ 15275 static int 15276 get_env_len(arg) 15277 char_u **arg; 15278 { 15279 char_u *p; 15280 int len; 15281 15282 for (p = *arg; vim_isIDc(*p); ++p) 15283 ; 15284 if (p == *arg) /* no name found */ 15285 return 0; 15286 15287 len = (int)(p - *arg); 15288 *arg = p; 15289 return len; 15290 } 15291 15292 /* 15293 * Get the length of the name of a function or internal variable. 15294 * "arg" is advanced to the first non-white character after the name. 15295 * Return 0 if something is wrong. 15296 */ 15297 static int 15298 get_id_len(arg) 15299 char_u **arg; 15300 { 15301 char_u *p; 15302 int len; 15303 15304 /* Find the end of the name. */ 15305 for (p = *arg; eval_isnamec(*p); ++p) 15306 ; 15307 if (p == *arg) /* no name found */ 15308 return 0; 15309 15310 len = (int)(p - *arg); 15311 *arg = skipwhite(p); 15312 15313 return len; 15314 } 15315 15316 /* 15317 * Get the length of the name of a variable or function. 15318 * Only the name is recognized, does not handle ".key" or "[idx]". 15319 * "arg" is advanced to the first non-white character after the name. 15320 * Return -1 if curly braces expansion failed. 15321 * Return 0 if something else is wrong. 15322 * If the name contains 'magic' {}'s, expand them and return the 15323 * expanded name in an allocated string via 'alias' - caller must free. 15324 */ 15325 static int 15326 get_name_len(arg, alias, evaluate, verbose) 15327 char_u **arg; 15328 char_u **alias; 15329 int evaluate; 15330 int verbose; 15331 { 15332 int len; 15333 char_u *p; 15334 char_u *expr_start; 15335 char_u *expr_end; 15336 15337 *alias = NULL; /* default to no alias */ 15338 15339 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15340 && (*arg)[2] == (int)KE_SNR) 15341 { 15342 /* hard coded <SNR>, already translated */ 15343 *arg += 3; 15344 return get_id_len(arg) + 3; 15345 } 15346 len = eval_fname_script(*arg); 15347 if (len > 0) 15348 { 15349 /* literal "<SID>", "s:" or "<SNR>" */ 15350 *arg += len; 15351 } 15352 15353 /* 15354 * Find the end of the name; check for {} construction. 15355 */ 15356 p = find_name_end(*arg, &expr_start, &expr_end, 15357 len > 0 ? 0 : FNE_CHECK_START); 15358 if (expr_start != NULL) 15359 { 15360 char_u *temp_string; 15361 15362 if (!evaluate) 15363 { 15364 len += (int)(p - *arg); 15365 *arg = skipwhite(p); 15366 return len; 15367 } 15368 15369 /* 15370 * Include any <SID> etc in the expanded string: 15371 * Thus the -len here. 15372 */ 15373 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15374 if (temp_string == NULL) 15375 return -1; 15376 *alias = temp_string; 15377 *arg = skipwhite(p); 15378 return (int)STRLEN(temp_string); 15379 } 15380 15381 len += get_id_len(arg); 15382 if (len == 0 && verbose) 15383 EMSG2(_(e_invexpr2), *arg); 15384 15385 return len; 15386 } 15387 15388 /* 15389 * Find the end of a variable or function name, taking care of magic braces. 15390 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15391 * start and end of the first magic braces item. 15392 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15393 * Return a pointer to just after the name. Equal to "arg" if there is no 15394 * valid name. 15395 */ 15396 static char_u * 15397 find_name_end(arg, expr_start, expr_end, flags) 15398 char_u *arg; 15399 char_u **expr_start; 15400 char_u **expr_end; 15401 int flags; 15402 { 15403 int mb_nest = 0; 15404 int br_nest = 0; 15405 char_u *p; 15406 15407 if (expr_start != NULL) 15408 { 15409 *expr_start = NULL; 15410 *expr_end = NULL; 15411 } 15412 15413 /* Quick check for valid starting character. */ 15414 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15415 return arg; 15416 15417 for (p = arg; *p != NUL 15418 && (eval_isnamec(*p) 15419 || *p == '{' 15420 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15421 || mb_nest != 0 15422 || br_nest != 0); mb_ptr_adv(p)) 15423 { 15424 if (*p == '\'') 15425 { 15426 /* skip over 'string' to avoid counting [ and ] inside it. */ 15427 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15428 ; 15429 if (*p == NUL) 15430 break; 15431 } 15432 else if (*p == '"') 15433 { 15434 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15435 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15436 if (*p == '\\' && p[1] != NUL) 15437 ++p; 15438 if (*p == NUL) 15439 break; 15440 } 15441 15442 if (mb_nest == 0) 15443 { 15444 if (*p == '[') 15445 ++br_nest; 15446 else if (*p == ']') 15447 --br_nest; 15448 } 15449 15450 if (br_nest == 0) 15451 { 15452 if (*p == '{') 15453 { 15454 mb_nest++; 15455 if (expr_start != NULL && *expr_start == NULL) 15456 *expr_start = p; 15457 } 15458 else if (*p == '}') 15459 { 15460 mb_nest--; 15461 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15462 *expr_end = p; 15463 } 15464 } 15465 } 15466 15467 return p; 15468 } 15469 15470 /* 15471 * Expands out the 'magic' {}'s in a variable/function name. 15472 * Note that this can call itself recursively, to deal with 15473 * constructs like foo{bar}{baz}{bam} 15474 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15475 * "in_start" ^ 15476 * "expr_start" ^ 15477 * "expr_end" ^ 15478 * "in_end" ^ 15479 * 15480 * Returns a new allocated string, which the caller must free. 15481 * Returns NULL for failure. 15482 */ 15483 static char_u * 15484 make_expanded_name(in_start, expr_start, expr_end, in_end) 15485 char_u *in_start; 15486 char_u *expr_start; 15487 char_u *expr_end; 15488 char_u *in_end; 15489 { 15490 char_u c1; 15491 char_u *retval = NULL; 15492 char_u *temp_result; 15493 char_u *nextcmd = NULL; 15494 15495 if (expr_end == NULL || in_end == NULL) 15496 return NULL; 15497 *expr_start = NUL; 15498 *expr_end = NUL; 15499 c1 = *in_end; 15500 *in_end = NUL; 15501 15502 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15503 if (temp_result != NULL && nextcmd == NULL) 15504 { 15505 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15506 + (in_end - expr_end) + 1)); 15507 if (retval != NULL) 15508 { 15509 STRCPY(retval, in_start); 15510 STRCAT(retval, temp_result); 15511 STRCAT(retval, expr_end + 1); 15512 } 15513 } 15514 vim_free(temp_result); 15515 15516 *in_end = c1; /* put char back for error messages */ 15517 *expr_start = '{'; 15518 *expr_end = '}'; 15519 15520 if (retval != NULL) 15521 { 15522 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15523 if (expr_start != NULL) 15524 { 15525 /* Further expansion! */ 15526 temp_result = make_expanded_name(retval, expr_start, 15527 expr_end, temp_result); 15528 vim_free(retval); 15529 retval = temp_result; 15530 } 15531 } 15532 15533 return retval; 15534 } 15535 15536 /* 15537 * Return TRUE if character "c" can be used in a variable or function name. 15538 * Does not include '{' or '}' for magic braces. 15539 */ 15540 static int 15541 eval_isnamec(c) 15542 int c; 15543 { 15544 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15545 } 15546 15547 /* 15548 * Return TRUE if character "c" can be used as the first character in a 15549 * variable or function name (excluding '{' and '}'). 15550 */ 15551 static int 15552 eval_isnamec1(c) 15553 int c; 15554 { 15555 return (ASCII_ISALPHA(c) || c == '_'); 15556 } 15557 15558 /* 15559 * Set number v: variable to "val". 15560 */ 15561 void 15562 set_vim_var_nr(idx, val) 15563 int idx; 15564 long val; 15565 { 15566 vimvars[idx].vv_nr = val; 15567 } 15568 15569 /* 15570 * Get number v: variable value. 15571 */ 15572 long 15573 get_vim_var_nr(idx) 15574 int idx; 15575 { 15576 return vimvars[idx].vv_nr; 15577 } 15578 15579 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15580 /* 15581 * Get string v: variable value. Uses a static buffer, can only be used once. 15582 */ 15583 char_u * 15584 get_vim_var_str(idx) 15585 int idx; 15586 { 15587 return get_tv_string(&vimvars[idx].vv_tv); 15588 } 15589 #endif 15590 15591 /* 15592 * Set v:count, v:count1 and v:prevcount. 15593 */ 15594 void 15595 set_vcount(count, count1) 15596 long count; 15597 long count1; 15598 { 15599 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15600 vimvars[VV_COUNT].vv_nr = count; 15601 vimvars[VV_COUNT1].vv_nr = count1; 15602 } 15603 15604 /* 15605 * Set string v: variable to a copy of "val". 15606 */ 15607 void 15608 set_vim_var_string(idx, val, len) 15609 int idx; 15610 char_u *val; 15611 int len; /* length of "val" to use or -1 (whole string) */ 15612 { 15613 /* Need to do this (at least) once, since we can't initialize a union. 15614 * Will always be invoked when "v:progname" is set. */ 15615 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15616 15617 vim_free(vimvars[idx].vv_str); 15618 if (val == NULL) 15619 vimvars[idx].vv_str = NULL; 15620 else if (len == -1) 15621 vimvars[idx].vv_str = vim_strsave(val); 15622 else 15623 vimvars[idx].vv_str = vim_strnsave(val, len); 15624 } 15625 15626 /* 15627 * Set v:register if needed. 15628 */ 15629 void 15630 set_reg_var(c) 15631 int c; 15632 { 15633 char_u regname; 15634 15635 if (c == 0 || c == ' ') 15636 regname = '"'; 15637 else 15638 regname = c; 15639 /* Avoid free/alloc when the value is already right. */ 15640 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15641 set_vim_var_string(VV_REG, ®name, 1); 15642 } 15643 15644 /* 15645 * Get or set v:exception. If "oldval" == NULL, return the current value. 15646 * Otherwise, restore the value to "oldval" and return NULL. 15647 * Must always be called in pairs to save and restore v:exception! Does not 15648 * take care of memory allocations. 15649 */ 15650 char_u * 15651 v_exception(oldval) 15652 char_u *oldval; 15653 { 15654 if (oldval == NULL) 15655 return vimvars[VV_EXCEPTION].vv_str; 15656 15657 vimvars[VV_EXCEPTION].vv_str = oldval; 15658 return NULL; 15659 } 15660 15661 /* 15662 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15663 * Otherwise, restore the value to "oldval" and return NULL. 15664 * Must always be called in pairs to save and restore v:throwpoint! Does not 15665 * take care of memory allocations. 15666 */ 15667 char_u * 15668 v_throwpoint(oldval) 15669 char_u *oldval; 15670 { 15671 if (oldval == NULL) 15672 return vimvars[VV_THROWPOINT].vv_str; 15673 15674 vimvars[VV_THROWPOINT].vv_str = oldval; 15675 return NULL; 15676 } 15677 15678 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15679 /* 15680 * Set v:cmdarg. 15681 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15682 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15683 * Must always be called in pairs! 15684 */ 15685 char_u * 15686 set_cmdarg(eap, oldarg) 15687 exarg_T *eap; 15688 char_u *oldarg; 15689 { 15690 char_u *oldval; 15691 char_u *newval; 15692 unsigned len; 15693 15694 oldval = vimvars[VV_CMDARG].vv_str; 15695 if (eap == NULL) 15696 { 15697 vim_free(oldval); 15698 vimvars[VV_CMDARG].vv_str = oldarg; 15699 return NULL; 15700 } 15701 15702 if (eap->force_bin == FORCE_BIN) 15703 len = 6; 15704 else if (eap->force_bin == FORCE_NOBIN) 15705 len = 8; 15706 else 15707 len = 0; 15708 if (eap->force_ff != 0) 15709 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15710 # ifdef FEAT_MBYTE 15711 if (eap->force_enc != 0) 15712 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15713 if (eap->bad_char != 0) 15714 len += (unsigned)STRLEN(eap->cmd + eap->bad_char) + 7; 15715 # endif 15716 15717 newval = alloc(len + 1); 15718 if (newval == NULL) 15719 return NULL; 15720 15721 if (eap->force_bin == FORCE_BIN) 15722 sprintf((char *)newval, " ++bin"); 15723 else if (eap->force_bin == FORCE_NOBIN) 15724 sprintf((char *)newval, " ++nobin"); 15725 else 15726 *newval = NUL; 15727 if (eap->force_ff != 0) 15728 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15729 eap->cmd + eap->force_ff); 15730 # ifdef FEAT_MBYTE 15731 if (eap->force_enc != 0) 15732 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15733 eap->cmd + eap->force_enc); 15734 if (eap->bad_char != 0) 15735 sprintf((char *)newval + STRLEN(newval), " ++bad=%s", 15736 eap->cmd + eap->bad_char); 15737 # endif 15738 vimvars[VV_CMDARG].vv_str = newval; 15739 return oldval; 15740 } 15741 #endif 15742 15743 /* 15744 * Get the value of internal variable "name". 15745 * Return OK or FAIL. 15746 */ 15747 static int 15748 get_var_tv(name, len, rettv, verbose) 15749 char_u *name; 15750 int len; /* length of "name" */ 15751 typval_T *rettv; /* NULL when only checking existence */ 15752 int verbose; /* may give error message */ 15753 { 15754 int ret = OK; 15755 typval_T *tv = NULL; 15756 typval_T atv; 15757 dictitem_T *v; 15758 int cc; 15759 15760 /* truncate the name, so that we can use strcmp() */ 15761 cc = name[len]; 15762 name[len] = NUL; 15763 15764 /* 15765 * Check for "b:changedtick". 15766 */ 15767 if (STRCMP(name, "b:changedtick") == 0) 15768 { 15769 atv.v_type = VAR_NUMBER; 15770 atv.vval.v_number = curbuf->b_changedtick; 15771 tv = &atv; 15772 } 15773 15774 /* 15775 * Check for user-defined variables. 15776 */ 15777 else 15778 { 15779 v = find_var(name, NULL); 15780 if (v != NULL) 15781 tv = &v->di_tv; 15782 } 15783 15784 if (tv == NULL) 15785 { 15786 if (rettv != NULL && verbose) 15787 EMSG2(_(e_undefvar), name); 15788 ret = FAIL; 15789 } 15790 else if (rettv != NULL) 15791 copy_tv(tv, rettv); 15792 15793 name[len] = cc; 15794 15795 return ret; 15796 } 15797 15798 /* 15799 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15800 * Also handle function call with Funcref variable: func(expr) 15801 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15802 */ 15803 static int 15804 handle_subscript(arg, rettv, evaluate, verbose) 15805 char_u **arg; 15806 typval_T *rettv; 15807 int evaluate; /* do more than finding the end */ 15808 int verbose; /* give error messages */ 15809 { 15810 int ret = OK; 15811 dict_T *selfdict = NULL; 15812 char_u *s; 15813 int len; 15814 typval_T functv; 15815 15816 while (ret == OK 15817 && (**arg == '[' 15818 || (**arg == '.' && rettv->v_type == VAR_DICT) 15819 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15820 && !vim_iswhite(*(*arg - 1))) 15821 { 15822 if (**arg == '(') 15823 { 15824 /* need to copy the funcref so that we can clear rettv */ 15825 functv = *rettv; 15826 rettv->v_type = VAR_UNKNOWN; 15827 15828 /* Invoke the function. Recursive! */ 15829 s = functv.vval.v_string; 15830 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15831 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15832 &len, evaluate, selfdict); 15833 15834 /* Clear the funcref afterwards, so that deleting it while 15835 * evaluating the arguments is possible (see test55). */ 15836 clear_tv(&functv); 15837 15838 /* Stop the expression evaluation when immediately aborting on 15839 * error, or when an interrupt occurred or an exception was thrown 15840 * but not caught. */ 15841 if (aborting()) 15842 { 15843 if (ret == OK) 15844 clear_tv(rettv); 15845 ret = FAIL; 15846 } 15847 dict_unref(selfdict); 15848 selfdict = NULL; 15849 } 15850 else /* **arg == '[' || **arg == '.' */ 15851 { 15852 dict_unref(selfdict); 15853 if (rettv->v_type == VAR_DICT) 15854 { 15855 selfdict = rettv->vval.v_dict; 15856 if (selfdict != NULL) 15857 ++selfdict->dv_refcount; 15858 } 15859 else 15860 selfdict = NULL; 15861 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15862 { 15863 clear_tv(rettv); 15864 ret = FAIL; 15865 } 15866 } 15867 } 15868 dict_unref(selfdict); 15869 return ret; 15870 } 15871 15872 /* 15873 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15874 * value). 15875 */ 15876 static typval_T * 15877 alloc_tv() 15878 { 15879 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15880 } 15881 15882 /* 15883 * Allocate memory for a variable type-value, and assign a string to it. 15884 * The string "s" must have been allocated, it is consumed. 15885 * Return NULL for out of memory, the variable otherwise. 15886 */ 15887 static typval_T * 15888 alloc_string_tv(s) 15889 char_u *s; 15890 { 15891 typval_T *rettv; 15892 15893 rettv = alloc_tv(); 15894 if (rettv != NULL) 15895 { 15896 rettv->v_type = VAR_STRING; 15897 rettv->vval.v_string = s; 15898 } 15899 else 15900 vim_free(s); 15901 return rettv; 15902 } 15903 15904 /* 15905 * Free the memory for a variable type-value. 15906 */ 15907 static void 15908 free_tv(varp) 15909 typval_T *varp; 15910 { 15911 if (varp != NULL) 15912 { 15913 switch (varp->v_type) 15914 { 15915 case VAR_FUNC: 15916 func_unref(varp->vval.v_string); 15917 /*FALLTHROUGH*/ 15918 case VAR_STRING: 15919 vim_free(varp->vval.v_string); 15920 break; 15921 case VAR_LIST: 15922 list_unref(varp->vval.v_list); 15923 break; 15924 case VAR_DICT: 15925 dict_unref(varp->vval.v_dict); 15926 break; 15927 case VAR_NUMBER: 15928 case VAR_UNKNOWN: 15929 break; 15930 default: 15931 EMSG2(_(e_intern2), "free_tv()"); 15932 break; 15933 } 15934 vim_free(varp); 15935 } 15936 } 15937 15938 /* 15939 * Free the memory for a variable value and set the value to NULL or 0. 15940 */ 15941 void 15942 clear_tv(varp) 15943 typval_T *varp; 15944 { 15945 if (varp != NULL) 15946 { 15947 switch (varp->v_type) 15948 { 15949 case VAR_FUNC: 15950 func_unref(varp->vval.v_string); 15951 /*FALLTHROUGH*/ 15952 case VAR_STRING: 15953 vim_free(varp->vval.v_string); 15954 varp->vval.v_string = NULL; 15955 break; 15956 case VAR_LIST: 15957 list_unref(varp->vval.v_list); 15958 varp->vval.v_list = NULL; 15959 break; 15960 case VAR_DICT: 15961 dict_unref(varp->vval.v_dict); 15962 varp->vval.v_dict = NULL; 15963 break; 15964 case VAR_NUMBER: 15965 varp->vval.v_number = 0; 15966 break; 15967 case VAR_UNKNOWN: 15968 break; 15969 default: 15970 EMSG2(_(e_intern2), "clear_tv()"); 15971 } 15972 varp->v_lock = 0; 15973 } 15974 } 15975 15976 /* 15977 * Set the value of a variable to NULL without freeing items. 15978 */ 15979 static void 15980 init_tv(varp) 15981 typval_T *varp; 15982 { 15983 if (varp != NULL) 15984 vim_memset(varp, 0, sizeof(typval_T)); 15985 } 15986 15987 /* 15988 * Get the number value of a variable. 15989 * If it is a String variable, uses vim_str2nr(). 15990 * For incompatible types, return 0. 15991 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15992 * caller of incompatible types: it sets *denote to TRUE if "denote" 15993 * is not NULL or returns -1 otherwise. 15994 */ 15995 static long 15996 get_tv_number(varp) 15997 typval_T *varp; 15998 { 15999 int error = FALSE; 16000 16001 return get_tv_number_chk(varp, &error); /* return 0L on error */ 16002 } 16003 16004 long 16005 get_tv_number_chk(varp, denote) 16006 typval_T *varp; 16007 int *denote; 16008 { 16009 long n = 0L; 16010 16011 switch (varp->v_type) 16012 { 16013 case VAR_NUMBER: 16014 return (long)(varp->vval.v_number); 16015 case VAR_FUNC: 16016 EMSG(_("E703: Using a Funcref as a number")); 16017 break; 16018 case VAR_STRING: 16019 if (varp->vval.v_string != NULL) 16020 vim_str2nr(varp->vval.v_string, NULL, NULL, 16021 TRUE, TRUE, &n, NULL); 16022 return n; 16023 case VAR_LIST: 16024 EMSG(_("E745: Using a List as a number")); 16025 break; 16026 case VAR_DICT: 16027 EMSG(_("E728: Using a Dictionary as a number")); 16028 break; 16029 default: 16030 EMSG2(_(e_intern2), "get_tv_number()"); 16031 break; 16032 } 16033 if (denote == NULL) /* useful for values that must be unsigned */ 16034 n = -1; 16035 else 16036 *denote = TRUE; 16037 return n; 16038 } 16039 16040 /* 16041 * Get the lnum from the first argument. 16042 * Also accepts ".", "$", etc., but that only works for the current buffer. 16043 * Returns -1 on error. 16044 */ 16045 static linenr_T 16046 get_tv_lnum(argvars) 16047 typval_T *argvars; 16048 { 16049 typval_T rettv; 16050 linenr_T lnum; 16051 16052 lnum = get_tv_number_chk(&argvars[0], NULL); 16053 if (lnum == 0) /* no valid number, try using line() */ 16054 { 16055 rettv.v_type = VAR_NUMBER; 16056 f_line(argvars, &rettv); 16057 lnum = rettv.vval.v_number; 16058 clear_tv(&rettv); 16059 } 16060 return lnum; 16061 } 16062 16063 /* 16064 * Get the lnum from the first argument. 16065 * Also accepts "$", then "buf" is used. 16066 * Returns 0 on error. 16067 */ 16068 static linenr_T 16069 get_tv_lnum_buf(argvars, buf) 16070 typval_T *argvars; 16071 buf_T *buf; 16072 { 16073 if (argvars[0].v_type == VAR_STRING 16074 && argvars[0].vval.v_string != NULL 16075 && argvars[0].vval.v_string[0] == '$' 16076 && buf != NULL) 16077 return buf->b_ml.ml_line_count; 16078 return get_tv_number_chk(&argvars[0], NULL); 16079 } 16080 16081 /* 16082 * Get the string value of a variable. 16083 * If it is a Number variable, the number is converted into a string. 16084 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 16085 * get_tv_string_buf() uses a given buffer. 16086 * If the String variable has never been set, return an empty string. 16087 * Never returns NULL; 16088 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 16089 * NULL on error. 16090 */ 16091 static char_u * 16092 get_tv_string(varp) 16093 typval_T *varp; 16094 { 16095 static char_u mybuf[NUMBUFLEN]; 16096 16097 return get_tv_string_buf(varp, mybuf); 16098 } 16099 16100 static char_u * 16101 get_tv_string_buf(varp, buf) 16102 typval_T *varp; 16103 char_u *buf; 16104 { 16105 char_u *res = get_tv_string_buf_chk(varp, buf); 16106 16107 return res != NULL ? res : (char_u *)""; 16108 } 16109 16110 char_u * 16111 get_tv_string_chk(varp) 16112 typval_T *varp; 16113 { 16114 static char_u mybuf[NUMBUFLEN]; 16115 16116 return get_tv_string_buf_chk(varp, mybuf); 16117 } 16118 16119 static char_u * 16120 get_tv_string_buf_chk(varp, buf) 16121 typval_T *varp; 16122 char_u *buf; 16123 { 16124 switch (varp->v_type) 16125 { 16126 case VAR_NUMBER: 16127 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 16128 return buf; 16129 case VAR_FUNC: 16130 EMSG(_("E729: using Funcref as a String")); 16131 break; 16132 case VAR_LIST: 16133 EMSG(_("E730: using List as a String")); 16134 break; 16135 case VAR_DICT: 16136 EMSG(_("E731: using Dictionary as a String")); 16137 break; 16138 case VAR_STRING: 16139 if (varp->vval.v_string != NULL) 16140 return varp->vval.v_string; 16141 return (char_u *)""; 16142 default: 16143 EMSG2(_(e_intern2), "get_tv_string_buf()"); 16144 break; 16145 } 16146 return NULL; 16147 } 16148 16149 /* 16150 * Find variable "name" in the list of variables. 16151 * Return a pointer to it if found, NULL if not found. 16152 * Careful: "a:0" variables don't have a name. 16153 * When "htp" is not NULL we are writing to the variable, set "htp" to the 16154 * hashtab_T used. 16155 */ 16156 static dictitem_T * 16157 find_var(name, htp) 16158 char_u *name; 16159 hashtab_T **htp; 16160 { 16161 char_u *varname; 16162 hashtab_T *ht; 16163 16164 ht = find_var_ht(name, &varname); 16165 if (htp != NULL) 16166 *htp = ht; 16167 if (ht == NULL) 16168 return NULL; 16169 return find_var_in_ht(ht, varname, htp != NULL); 16170 } 16171 16172 /* 16173 * Find variable "varname" in hashtab "ht". 16174 * Returns NULL if not found. 16175 */ 16176 static dictitem_T * 16177 find_var_in_ht(ht, varname, writing) 16178 hashtab_T *ht; 16179 char_u *varname; 16180 int writing; 16181 { 16182 hashitem_T *hi; 16183 16184 if (*varname == NUL) 16185 { 16186 /* Must be something like "s:", otherwise "ht" would be NULL. */ 16187 switch (varname[-2]) 16188 { 16189 case 's': return &SCRIPT_SV(current_SID).sv_var; 16190 case 'g': return &globvars_var; 16191 case 'v': return &vimvars_var; 16192 case 'b': return &curbuf->b_bufvar; 16193 case 'w': return &curwin->w_winvar; 16194 case 'l': return current_funccal == NULL 16195 ? NULL : ¤t_funccal->l_vars_var; 16196 case 'a': return current_funccal == NULL 16197 ? NULL : ¤t_funccal->l_avars_var; 16198 } 16199 return NULL; 16200 } 16201 16202 hi = hash_find(ht, varname); 16203 if (HASHITEM_EMPTY(hi)) 16204 { 16205 /* For global variables we may try auto-loading the script. If it 16206 * worked find the variable again. Don't auto-load a script if it was 16207 * loaded already, otherwise it would be loaded every time when 16208 * checking if a function name is a Funcref variable. */ 16209 if (ht == &globvarht && !writing 16210 && script_autoload(varname, FALSE) && !aborting()) 16211 hi = hash_find(ht, varname); 16212 if (HASHITEM_EMPTY(hi)) 16213 return NULL; 16214 } 16215 return HI2DI(hi); 16216 } 16217 16218 /* 16219 * Find the hashtab used for a variable name. 16220 * Set "varname" to the start of name without ':'. 16221 */ 16222 static hashtab_T * 16223 find_var_ht(name, varname) 16224 char_u *name; 16225 char_u **varname; 16226 { 16227 hashitem_T *hi; 16228 16229 if (name[1] != ':') 16230 { 16231 /* The name must not start with a colon or #. */ 16232 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16233 return NULL; 16234 *varname = name; 16235 16236 /* "version" is "v:version" in all scopes */ 16237 hi = hash_find(&compat_hashtab, name); 16238 if (!HASHITEM_EMPTY(hi)) 16239 return &compat_hashtab; 16240 16241 if (current_funccal == NULL) 16242 return &globvarht; /* global variable */ 16243 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16244 } 16245 *varname = name + 2; 16246 if (*name == 'g') /* global variable */ 16247 return &globvarht; 16248 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16249 */ 16250 if (vim_strchr(name + 2, ':') != NULL 16251 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16252 return NULL; 16253 if (*name == 'b') /* buffer variable */ 16254 return &curbuf->b_vars.dv_hashtab; 16255 if (*name == 'w') /* window variable */ 16256 return &curwin->w_vars.dv_hashtab; 16257 if (*name == 'v') /* v: variable */ 16258 return &vimvarht; 16259 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16260 return ¤t_funccal->l_avars.dv_hashtab; 16261 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16262 return ¤t_funccal->l_vars.dv_hashtab; 16263 if (*name == 's' /* script variable */ 16264 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16265 return &SCRIPT_VARS(current_SID); 16266 return NULL; 16267 } 16268 16269 /* 16270 * Get the string value of a (global/local) variable. 16271 * Returns NULL when it doesn't exist. 16272 */ 16273 char_u * 16274 get_var_value(name) 16275 char_u *name; 16276 { 16277 dictitem_T *v; 16278 16279 v = find_var(name, NULL); 16280 if (v == NULL) 16281 return NULL; 16282 return get_tv_string(&v->di_tv); 16283 } 16284 16285 /* 16286 * Allocate a new hashtab for a sourced script. It will be used while 16287 * sourcing this script and when executing functions defined in the script. 16288 */ 16289 void 16290 new_script_vars(id) 16291 scid_T id; 16292 { 16293 int i; 16294 hashtab_T *ht; 16295 scriptvar_T *sv; 16296 16297 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16298 { 16299 /* Re-allocating ga_data means that an ht_array pointing to 16300 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16301 * at its init value. Also reset "v_dict", it's always the same. */ 16302 for (i = 1; i <= ga_scripts.ga_len; ++i) 16303 { 16304 ht = &SCRIPT_VARS(i); 16305 if (ht->ht_mask == HT_INIT_SIZE - 1) 16306 ht->ht_array = ht->ht_smallarray; 16307 sv = &SCRIPT_SV(i); 16308 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16309 } 16310 16311 while (ga_scripts.ga_len < id) 16312 { 16313 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16314 init_var_dict(&sv->sv_dict, &sv->sv_var); 16315 ++ga_scripts.ga_len; 16316 } 16317 } 16318 } 16319 16320 /* 16321 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16322 * point to it. 16323 */ 16324 void 16325 init_var_dict(dict, dict_var) 16326 dict_T *dict; 16327 dictitem_T *dict_var; 16328 { 16329 hash_init(&dict->dv_hashtab); 16330 dict->dv_refcount = 99999; 16331 dict_var->di_tv.vval.v_dict = dict; 16332 dict_var->di_tv.v_type = VAR_DICT; 16333 dict_var->di_tv.v_lock = VAR_FIXED; 16334 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16335 dict_var->di_key[0] = NUL; 16336 } 16337 16338 /* 16339 * Clean up a list of internal variables. 16340 * Frees all allocated variables and the value they contain. 16341 * Clears hashtab "ht", does not free it. 16342 */ 16343 void 16344 vars_clear(ht) 16345 hashtab_T *ht; 16346 { 16347 vars_clear_ext(ht, TRUE); 16348 } 16349 16350 /* 16351 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16352 */ 16353 static void 16354 vars_clear_ext(ht, free_val) 16355 hashtab_T *ht; 16356 int free_val; 16357 { 16358 int todo; 16359 hashitem_T *hi; 16360 dictitem_T *v; 16361 16362 hash_lock(ht); 16363 todo = ht->ht_used; 16364 for (hi = ht->ht_array; todo > 0; ++hi) 16365 { 16366 if (!HASHITEM_EMPTY(hi)) 16367 { 16368 --todo; 16369 16370 /* Free the variable. Don't remove it from the hashtab, 16371 * ht_array might change then. hash_clear() takes care of it 16372 * later. */ 16373 v = HI2DI(hi); 16374 if (free_val) 16375 clear_tv(&v->di_tv); 16376 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16377 vim_free(v); 16378 } 16379 } 16380 hash_clear(ht); 16381 ht->ht_used = 0; 16382 } 16383 16384 /* 16385 * Delete a variable from hashtab "ht" at item "hi". 16386 * Clear the variable value and free the dictitem. 16387 */ 16388 static void 16389 delete_var(ht, hi) 16390 hashtab_T *ht; 16391 hashitem_T *hi; 16392 { 16393 dictitem_T *di = HI2DI(hi); 16394 16395 hash_remove(ht, hi); 16396 clear_tv(&di->di_tv); 16397 vim_free(di); 16398 } 16399 16400 /* 16401 * List the value of one internal variable. 16402 */ 16403 static void 16404 list_one_var(v, prefix) 16405 dictitem_T *v; 16406 char_u *prefix; 16407 { 16408 char_u *tofree; 16409 char_u *s; 16410 char_u numbuf[NUMBUFLEN]; 16411 16412 s = echo_string(&v->di_tv, &tofree, numbuf); 16413 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16414 s == NULL ? (char_u *)"" : s); 16415 vim_free(tofree); 16416 } 16417 16418 static void 16419 list_one_var_a(prefix, name, type, string) 16420 char_u *prefix; 16421 char_u *name; 16422 int type; 16423 char_u *string; 16424 { 16425 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16426 if (name != NULL) /* "a:" vars don't have a name stored */ 16427 msg_puts(name); 16428 msg_putchar(' '); 16429 msg_advance(22); 16430 if (type == VAR_NUMBER) 16431 msg_putchar('#'); 16432 else if (type == VAR_FUNC) 16433 msg_putchar('*'); 16434 else if (type == VAR_LIST) 16435 { 16436 msg_putchar('['); 16437 if (*string == '[') 16438 ++string; 16439 } 16440 else if (type == VAR_DICT) 16441 { 16442 msg_putchar('{'); 16443 if (*string == '{') 16444 ++string; 16445 } 16446 else 16447 msg_putchar(' '); 16448 16449 msg_outtrans(string); 16450 16451 if (type == VAR_FUNC) 16452 msg_puts((char_u *)"()"); 16453 } 16454 16455 /* 16456 * Set variable "name" to value in "tv". 16457 * If the variable already exists, the value is updated. 16458 * Otherwise the variable is created. 16459 */ 16460 static void 16461 set_var(name, tv, copy) 16462 char_u *name; 16463 typval_T *tv; 16464 int copy; /* make copy of value in "tv" */ 16465 { 16466 dictitem_T *v; 16467 char_u *varname; 16468 hashtab_T *ht; 16469 char_u *p; 16470 16471 if (tv->v_type == VAR_FUNC) 16472 { 16473 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16474 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16475 ? name[2] : name[0])) 16476 { 16477 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16478 return; 16479 } 16480 if (function_exists(name)) 16481 { 16482 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16483 name); 16484 return; 16485 } 16486 } 16487 16488 ht = find_var_ht(name, &varname); 16489 if (ht == NULL || *varname == NUL) 16490 { 16491 EMSG2(_(e_illvar), name); 16492 return; 16493 } 16494 16495 v = find_var_in_ht(ht, varname, TRUE); 16496 if (v != NULL) 16497 { 16498 /* existing variable, need to clear the value */ 16499 if (var_check_ro(v->di_flags, name) 16500 || tv_check_lock(v->di_tv.v_lock, name)) 16501 return; 16502 if (v->di_tv.v_type != tv->v_type 16503 && !((v->di_tv.v_type == VAR_STRING 16504 || v->di_tv.v_type == VAR_NUMBER) 16505 && (tv->v_type == VAR_STRING 16506 || tv->v_type == VAR_NUMBER))) 16507 { 16508 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16509 return; 16510 } 16511 16512 /* 16513 * Handle setting internal v: variables separately: we don't change 16514 * the type. 16515 */ 16516 if (ht == &vimvarht) 16517 { 16518 if (v->di_tv.v_type == VAR_STRING) 16519 { 16520 vim_free(v->di_tv.vval.v_string); 16521 if (copy || tv->v_type != VAR_STRING) 16522 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16523 else 16524 { 16525 /* Take over the string to avoid an extra alloc/free. */ 16526 v->di_tv.vval.v_string = tv->vval.v_string; 16527 tv->vval.v_string = NULL; 16528 } 16529 } 16530 else if (v->di_tv.v_type != VAR_NUMBER) 16531 EMSG2(_(e_intern2), "set_var()"); 16532 else 16533 v->di_tv.vval.v_number = get_tv_number(tv); 16534 return; 16535 } 16536 16537 clear_tv(&v->di_tv); 16538 } 16539 else /* add a new variable */ 16540 { 16541 /* Make sure the variable name is valid. */ 16542 for (p = varname; *p != NUL; ++p) 16543 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 16544 && *p != AUTOLOAD_CHAR) 16545 { 16546 EMSG2(_(e_illvar), varname); 16547 return; 16548 } 16549 16550 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16551 + STRLEN(varname))); 16552 if (v == NULL) 16553 return; 16554 STRCPY(v->di_key, varname); 16555 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16556 { 16557 vim_free(v); 16558 return; 16559 } 16560 v->di_flags = 0; 16561 } 16562 16563 if (copy || tv->v_type == VAR_NUMBER) 16564 copy_tv(tv, &v->di_tv); 16565 else 16566 { 16567 v->di_tv = *tv; 16568 v->di_tv.v_lock = 0; 16569 init_tv(tv); 16570 } 16571 } 16572 16573 /* 16574 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16575 * Also give an error message. 16576 */ 16577 static int 16578 var_check_ro(flags, name) 16579 int flags; 16580 char_u *name; 16581 { 16582 if (flags & DI_FLAGS_RO) 16583 { 16584 EMSG2(_(e_readonlyvar), name); 16585 return TRUE; 16586 } 16587 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16588 { 16589 EMSG2(_(e_readonlysbx), name); 16590 return TRUE; 16591 } 16592 return FALSE; 16593 } 16594 16595 /* 16596 * Return TRUE if typeval "tv" is set to be locked (immutable). 16597 * Also give an error message, using "name". 16598 */ 16599 static int 16600 tv_check_lock(lock, name) 16601 int lock; 16602 char_u *name; 16603 { 16604 if (lock & VAR_LOCKED) 16605 { 16606 EMSG2(_("E741: Value is locked: %s"), 16607 name == NULL ? (char_u *)_("Unknown") : name); 16608 return TRUE; 16609 } 16610 if (lock & VAR_FIXED) 16611 { 16612 EMSG2(_("E742: Cannot change value of %s"), 16613 name == NULL ? (char_u *)_("Unknown") : name); 16614 return TRUE; 16615 } 16616 return FALSE; 16617 } 16618 16619 /* 16620 * Copy the values from typval_T "from" to typval_T "to". 16621 * When needed allocates string or increases reference count. 16622 * Does not make a copy of a list or dict but copies the reference! 16623 */ 16624 static void 16625 copy_tv(from, to) 16626 typval_T *from; 16627 typval_T *to; 16628 { 16629 to->v_type = from->v_type; 16630 to->v_lock = 0; 16631 switch (from->v_type) 16632 { 16633 case VAR_NUMBER: 16634 to->vval.v_number = from->vval.v_number; 16635 break; 16636 case VAR_STRING: 16637 case VAR_FUNC: 16638 if (from->vval.v_string == NULL) 16639 to->vval.v_string = NULL; 16640 else 16641 { 16642 to->vval.v_string = vim_strsave(from->vval.v_string); 16643 if (from->v_type == VAR_FUNC) 16644 func_ref(to->vval.v_string); 16645 } 16646 break; 16647 case VAR_LIST: 16648 if (from->vval.v_list == NULL) 16649 to->vval.v_list = NULL; 16650 else 16651 { 16652 to->vval.v_list = from->vval.v_list; 16653 ++to->vval.v_list->lv_refcount; 16654 } 16655 break; 16656 case VAR_DICT: 16657 if (from->vval.v_dict == NULL) 16658 to->vval.v_dict = NULL; 16659 else 16660 { 16661 to->vval.v_dict = from->vval.v_dict; 16662 ++to->vval.v_dict->dv_refcount; 16663 } 16664 break; 16665 default: 16666 EMSG2(_(e_intern2), "copy_tv()"); 16667 break; 16668 } 16669 } 16670 16671 /* 16672 * Make a copy of an item. 16673 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16674 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16675 * reference to an already copied list/dict can be used. 16676 * Returns FAIL or OK. 16677 */ 16678 static int 16679 item_copy(from, to, deep, copyID) 16680 typval_T *from; 16681 typval_T *to; 16682 int deep; 16683 int copyID; 16684 { 16685 static int recurse = 0; 16686 int ret = OK; 16687 16688 if (recurse >= DICT_MAXNEST) 16689 { 16690 EMSG(_("E698: variable nested too deep for making a copy")); 16691 return FAIL; 16692 } 16693 ++recurse; 16694 16695 switch (from->v_type) 16696 { 16697 case VAR_NUMBER: 16698 case VAR_STRING: 16699 case VAR_FUNC: 16700 copy_tv(from, to); 16701 break; 16702 case VAR_LIST: 16703 to->v_type = VAR_LIST; 16704 to->v_lock = 0; 16705 if (from->vval.v_list == NULL) 16706 to->vval.v_list = NULL; 16707 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16708 { 16709 /* use the copy made earlier */ 16710 to->vval.v_list = from->vval.v_list->lv_copylist; 16711 ++to->vval.v_list->lv_refcount; 16712 } 16713 else 16714 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16715 if (to->vval.v_list == NULL) 16716 ret = FAIL; 16717 break; 16718 case VAR_DICT: 16719 to->v_type = VAR_DICT; 16720 to->v_lock = 0; 16721 if (from->vval.v_dict == NULL) 16722 to->vval.v_dict = NULL; 16723 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16724 { 16725 /* use the copy made earlier */ 16726 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16727 ++to->vval.v_dict->dv_refcount; 16728 } 16729 else 16730 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16731 if (to->vval.v_dict == NULL) 16732 ret = FAIL; 16733 break; 16734 default: 16735 EMSG2(_(e_intern2), "item_copy()"); 16736 ret = FAIL; 16737 } 16738 --recurse; 16739 return ret; 16740 } 16741 16742 /* 16743 * ":echo expr1 ..." print each argument separated with a space, add a 16744 * newline at the end. 16745 * ":echon expr1 ..." print each argument plain. 16746 */ 16747 void 16748 ex_echo(eap) 16749 exarg_T *eap; 16750 { 16751 char_u *arg = eap->arg; 16752 typval_T rettv; 16753 char_u *tofree; 16754 char_u *p; 16755 int needclr = TRUE; 16756 int atstart = TRUE; 16757 char_u numbuf[NUMBUFLEN]; 16758 16759 if (eap->skip) 16760 ++emsg_skip; 16761 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16762 { 16763 p = arg; 16764 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16765 { 16766 /* 16767 * Report the invalid expression unless the expression evaluation 16768 * has been cancelled due to an aborting error, an interrupt, or an 16769 * exception. 16770 */ 16771 if (!aborting()) 16772 EMSG2(_(e_invexpr2), p); 16773 break; 16774 } 16775 if (!eap->skip) 16776 { 16777 if (atstart) 16778 { 16779 atstart = FALSE; 16780 /* Call msg_start() after eval1(), evaluating the expression 16781 * may cause a message to appear. */ 16782 if (eap->cmdidx == CMD_echo) 16783 msg_start(); 16784 } 16785 else if (eap->cmdidx == CMD_echo) 16786 msg_puts_attr((char_u *)" ", echo_attr); 16787 p = echo_string(&rettv, &tofree, numbuf); 16788 if (p != NULL) 16789 for ( ; *p != NUL && !got_int; ++p) 16790 { 16791 if (*p == '\n' || *p == '\r' || *p == TAB) 16792 { 16793 if (*p != TAB && needclr) 16794 { 16795 /* remove any text still there from the command */ 16796 msg_clr_eos(); 16797 needclr = FALSE; 16798 } 16799 msg_putchar_attr(*p, echo_attr); 16800 } 16801 else 16802 { 16803 #ifdef FEAT_MBYTE 16804 if (has_mbyte) 16805 { 16806 int i = (*mb_ptr2len)(p); 16807 16808 (void)msg_outtrans_len_attr(p, i, echo_attr); 16809 p += i - 1; 16810 } 16811 else 16812 #endif 16813 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16814 } 16815 } 16816 vim_free(tofree); 16817 } 16818 clear_tv(&rettv); 16819 arg = skipwhite(arg); 16820 } 16821 eap->nextcmd = check_nextcmd(arg); 16822 16823 if (eap->skip) 16824 --emsg_skip; 16825 else 16826 { 16827 /* remove text that may still be there from the command */ 16828 if (needclr) 16829 msg_clr_eos(); 16830 if (eap->cmdidx == CMD_echo) 16831 msg_end(); 16832 } 16833 } 16834 16835 /* 16836 * ":echohl {name}". 16837 */ 16838 void 16839 ex_echohl(eap) 16840 exarg_T *eap; 16841 { 16842 int id; 16843 16844 id = syn_name2id(eap->arg); 16845 if (id == 0) 16846 echo_attr = 0; 16847 else 16848 echo_attr = syn_id2attr(id); 16849 } 16850 16851 /* 16852 * ":execute expr1 ..." execute the result of an expression. 16853 * ":echomsg expr1 ..." Print a message 16854 * ":echoerr expr1 ..." Print an error 16855 * Each gets spaces around each argument and a newline at the end for 16856 * echo commands 16857 */ 16858 void 16859 ex_execute(eap) 16860 exarg_T *eap; 16861 { 16862 char_u *arg = eap->arg; 16863 typval_T rettv; 16864 int ret = OK; 16865 char_u *p; 16866 garray_T ga; 16867 int len; 16868 int save_did_emsg; 16869 16870 ga_init2(&ga, 1, 80); 16871 16872 if (eap->skip) 16873 ++emsg_skip; 16874 while (*arg != NUL && *arg != '|' && *arg != '\n') 16875 { 16876 p = arg; 16877 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16878 { 16879 /* 16880 * Report the invalid expression unless the expression evaluation 16881 * has been cancelled due to an aborting error, an interrupt, or an 16882 * exception. 16883 */ 16884 if (!aborting()) 16885 EMSG2(_(e_invexpr2), p); 16886 ret = FAIL; 16887 break; 16888 } 16889 16890 if (!eap->skip) 16891 { 16892 p = get_tv_string(&rettv); 16893 len = (int)STRLEN(p); 16894 if (ga_grow(&ga, len + 2) == FAIL) 16895 { 16896 clear_tv(&rettv); 16897 ret = FAIL; 16898 break; 16899 } 16900 if (ga.ga_len) 16901 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16902 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16903 ga.ga_len += len; 16904 } 16905 16906 clear_tv(&rettv); 16907 arg = skipwhite(arg); 16908 } 16909 16910 if (ret != FAIL && ga.ga_data != NULL) 16911 { 16912 if (eap->cmdidx == CMD_echomsg) 16913 MSG_ATTR(ga.ga_data, echo_attr); 16914 else if (eap->cmdidx == CMD_echoerr) 16915 { 16916 /* We don't want to abort following commands, restore did_emsg. */ 16917 save_did_emsg = did_emsg; 16918 EMSG((char_u *)ga.ga_data); 16919 if (!force_abort) 16920 did_emsg = save_did_emsg; 16921 } 16922 else if (eap->cmdidx == CMD_execute) 16923 do_cmdline((char_u *)ga.ga_data, 16924 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16925 } 16926 16927 ga_clear(&ga); 16928 16929 if (eap->skip) 16930 --emsg_skip; 16931 16932 eap->nextcmd = check_nextcmd(arg); 16933 } 16934 16935 /* 16936 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16937 * "arg" points to the "&" or '+' when called, to "option" when returning. 16938 * Returns NULL when no option name found. Otherwise pointer to the char 16939 * after the option name. 16940 */ 16941 static char_u * 16942 find_option_end(arg, opt_flags) 16943 char_u **arg; 16944 int *opt_flags; 16945 { 16946 char_u *p = *arg; 16947 16948 ++p; 16949 if (*p == 'g' && p[1] == ':') 16950 { 16951 *opt_flags = OPT_GLOBAL; 16952 p += 2; 16953 } 16954 else if (*p == 'l' && p[1] == ':') 16955 { 16956 *opt_flags = OPT_LOCAL; 16957 p += 2; 16958 } 16959 else 16960 *opt_flags = 0; 16961 16962 if (!ASCII_ISALPHA(*p)) 16963 return NULL; 16964 *arg = p; 16965 16966 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16967 p += 4; /* termcap option */ 16968 else 16969 while (ASCII_ISALPHA(*p)) 16970 ++p; 16971 return p; 16972 } 16973 16974 /* 16975 * ":function" 16976 */ 16977 void 16978 ex_function(eap) 16979 exarg_T *eap; 16980 { 16981 char_u *theline; 16982 int j; 16983 int c; 16984 int saved_did_emsg; 16985 char_u *name = NULL; 16986 char_u *p; 16987 char_u *arg; 16988 garray_T newargs; 16989 garray_T newlines; 16990 int varargs = FALSE; 16991 int mustend = FALSE; 16992 int flags = 0; 16993 ufunc_T *fp; 16994 int indent; 16995 int nesting; 16996 char_u *skip_until = NULL; 16997 dictitem_T *v; 16998 funcdict_T fudi; 16999 static int func_nr = 0; /* number for nameless function */ 17000 int paren; 17001 hashtab_T *ht; 17002 int todo; 17003 hashitem_T *hi; 17004 17005 /* 17006 * ":function" without argument: list functions. 17007 */ 17008 if (ends_excmd(*eap->arg)) 17009 { 17010 if (!eap->skip) 17011 { 17012 todo = func_hashtab.ht_used; 17013 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17014 { 17015 if (!HASHITEM_EMPTY(hi)) 17016 { 17017 --todo; 17018 fp = HI2UF(hi); 17019 if (!isdigit(*fp->uf_name)) 17020 list_func_head(fp, FALSE); 17021 } 17022 } 17023 } 17024 eap->nextcmd = check_nextcmd(eap->arg); 17025 return; 17026 } 17027 17028 /* 17029 * ":function /pat": list functions matching pattern. 17030 */ 17031 if (*eap->arg == '/') 17032 { 17033 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 17034 if (!eap->skip) 17035 { 17036 regmatch_T regmatch; 17037 17038 c = *p; 17039 *p = NUL; 17040 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 17041 *p = c; 17042 if (regmatch.regprog != NULL) 17043 { 17044 regmatch.rm_ic = p_ic; 17045 17046 todo = func_hashtab.ht_used; 17047 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 17048 { 17049 if (!HASHITEM_EMPTY(hi)) 17050 { 17051 --todo; 17052 fp = HI2UF(hi); 17053 if (!isdigit(*fp->uf_name) 17054 && vim_regexec(®match, fp->uf_name, 0)) 17055 list_func_head(fp, FALSE); 17056 } 17057 } 17058 } 17059 } 17060 if (*p == '/') 17061 ++p; 17062 eap->nextcmd = check_nextcmd(p); 17063 return; 17064 } 17065 17066 /* 17067 * Get the function name. There are these situations: 17068 * func normal function name 17069 * "name" == func, "fudi.fd_dict" == NULL 17070 * dict.func new dictionary entry 17071 * "name" == NULL, "fudi.fd_dict" set, 17072 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 17073 * dict.func existing dict entry with a Funcref 17074 * "name" == func, "fudi.fd_dict" set, 17075 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17076 * dict.func existing dict entry that's not a Funcref 17077 * "name" == NULL, "fudi.fd_dict" set, 17078 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17079 */ 17080 p = eap->arg; 17081 name = trans_function_name(&p, eap->skip, 0, &fudi); 17082 paren = (vim_strchr(p, '(') != NULL); 17083 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 17084 { 17085 /* 17086 * Return on an invalid expression in braces, unless the expression 17087 * evaluation has been cancelled due to an aborting error, an 17088 * interrupt, or an exception. 17089 */ 17090 if (!aborting()) 17091 { 17092 if (!eap->skip && fudi.fd_newkey != NULL) 17093 EMSG2(_(e_dictkey), fudi.fd_newkey); 17094 vim_free(fudi.fd_newkey); 17095 return; 17096 } 17097 else 17098 eap->skip = TRUE; 17099 } 17100 /* An error in a function call during evaluation of an expression in magic 17101 * braces should not cause the function not to be defined. */ 17102 saved_did_emsg = did_emsg; 17103 did_emsg = FALSE; 17104 17105 /* 17106 * ":function func" with only function name: list function. 17107 */ 17108 if (!paren) 17109 { 17110 if (!ends_excmd(*skipwhite(p))) 17111 { 17112 EMSG(_(e_trailing)); 17113 goto ret_free; 17114 } 17115 eap->nextcmd = check_nextcmd(p); 17116 if (eap->nextcmd != NULL) 17117 *p = NUL; 17118 if (!eap->skip && !got_int) 17119 { 17120 fp = find_func(name); 17121 if (fp != NULL) 17122 { 17123 list_func_head(fp, TRUE); 17124 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 17125 { 17126 msg_putchar('\n'); 17127 msg_outnum((long)(j + 1)); 17128 if (j < 9) 17129 msg_putchar(' '); 17130 if (j < 99) 17131 msg_putchar(' '); 17132 msg_prt_line(FUNCLINE(fp, j), FALSE); 17133 out_flush(); /* show a line at a time */ 17134 ui_breakcheck(); 17135 } 17136 if (!got_int) 17137 { 17138 msg_putchar('\n'); 17139 msg_puts((char_u *)" endfunction"); 17140 } 17141 } 17142 else 17143 emsg_funcname("E123: Undefined function: %s", name); 17144 } 17145 goto ret_free; 17146 } 17147 17148 /* 17149 * ":function name(arg1, arg2)" Define function. 17150 */ 17151 p = skipwhite(p); 17152 if (*p != '(') 17153 { 17154 if (!eap->skip) 17155 { 17156 EMSG2(_("E124: Missing '(': %s"), eap->arg); 17157 goto ret_free; 17158 } 17159 /* attempt to continue by skipping some text */ 17160 if (vim_strchr(p, '(') != NULL) 17161 p = vim_strchr(p, '('); 17162 } 17163 p = skipwhite(p + 1); 17164 17165 ga_init2(&newargs, (int)sizeof(char_u *), 3); 17166 ga_init2(&newlines, (int)sizeof(char_u *), 3); 17167 17168 if (!eap->skip) 17169 { 17170 /* Check the name of the function. */ 17171 if (name != NULL) 17172 arg = name; 17173 else 17174 arg = fudi.fd_newkey; 17175 if (arg != NULL) 17176 { 17177 if (*arg == K_SPECIAL) 17178 j = 3; 17179 else 17180 j = 0; 17181 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 17182 : eval_isnamec(arg[j]))) 17183 ++j; 17184 if (arg[j] != NUL) 17185 emsg_funcname(_(e_invarg2), arg); 17186 } 17187 } 17188 17189 /* 17190 * Isolate the arguments: "arg1, arg2, ...)" 17191 */ 17192 while (*p != ')') 17193 { 17194 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 17195 { 17196 varargs = TRUE; 17197 p += 3; 17198 mustend = TRUE; 17199 } 17200 else 17201 { 17202 arg = p; 17203 while (ASCII_ISALNUM(*p) || *p == '_') 17204 ++p; 17205 if (arg == p || isdigit(*arg) 17206 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 17207 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 17208 { 17209 if (!eap->skip) 17210 EMSG2(_("E125: Illegal argument: %s"), arg); 17211 break; 17212 } 17213 if (ga_grow(&newargs, 1) == FAIL) 17214 goto erret; 17215 c = *p; 17216 *p = NUL; 17217 arg = vim_strsave(arg); 17218 if (arg == NULL) 17219 goto erret; 17220 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 17221 *p = c; 17222 newargs.ga_len++; 17223 if (*p == ',') 17224 ++p; 17225 else 17226 mustend = TRUE; 17227 } 17228 p = skipwhite(p); 17229 if (mustend && *p != ')') 17230 { 17231 if (!eap->skip) 17232 EMSG2(_(e_invarg2), eap->arg); 17233 break; 17234 } 17235 } 17236 ++p; /* skip the ')' */ 17237 17238 /* find extra arguments "range", "dict" and "abort" */ 17239 for (;;) 17240 { 17241 p = skipwhite(p); 17242 if (STRNCMP(p, "range", 5) == 0) 17243 { 17244 flags |= FC_RANGE; 17245 p += 5; 17246 } 17247 else if (STRNCMP(p, "dict", 4) == 0) 17248 { 17249 flags |= FC_DICT; 17250 p += 4; 17251 } 17252 else if (STRNCMP(p, "abort", 5) == 0) 17253 { 17254 flags |= FC_ABORT; 17255 p += 5; 17256 } 17257 else 17258 break; 17259 } 17260 17261 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 17262 EMSG(_(e_trailing)); 17263 17264 /* 17265 * Read the body of the function, until ":endfunction" is found. 17266 */ 17267 if (KeyTyped) 17268 { 17269 /* Check if the function already exists, don't let the user type the 17270 * whole function before telling him it doesn't work! For a script we 17271 * need to skip the body to be able to find what follows. */ 17272 if (!eap->skip && !eap->forceit) 17273 { 17274 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 17275 EMSG(_(e_funcdict)); 17276 else if (name != NULL && find_func(name) != NULL) 17277 emsg_funcname(e_funcexts, name); 17278 } 17279 17280 if (!eap->skip && did_emsg) 17281 goto erret; 17282 17283 msg_putchar('\n'); /* don't overwrite the function name */ 17284 cmdline_row = msg_row; 17285 } 17286 17287 indent = 2; 17288 nesting = 0; 17289 for (;;) 17290 { 17291 msg_scroll = TRUE; 17292 need_wait_return = FALSE; 17293 if (eap->getline == NULL) 17294 theline = getcmdline(':', 0L, indent); 17295 else 17296 theline = eap->getline(':', eap->cookie, indent); 17297 if (KeyTyped) 17298 lines_left = Rows - 1; 17299 if (theline == NULL) 17300 { 17301 EMSG(_("E126: Missing :endfunction")); 17302 goto erret; 17303 } 17304 17305 if (skip_until != NULL) 17306 { 17307 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17308 * don't check for ":endfunc". */ 17309 if (STRCMP(theline, skip_until) == 0) 17310 { 17311 vim_free(skip_until); 17312 skip_until = NULL; 17313 } 17314 } 17315 else 17316 { 17317 /* skip ':' and blanks*/ 17318 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17319 ; 17320 17321 /* Check for "endfunction". */ 17322 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17323 { 17324 vim_free(theline); 17325 break; 17326 } 17327 17328 /* Increase indent inside "if", "while", "for" and "try", decrease 17329 * at "end". */ 17330 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17331 indent -= 2; 17332 else if (STRNCMP(p, "if", 2) == 0 17333 || STRNCMP(p, "wh", 2) == 0 17334 || STRNCMP(p, "for", 3) == 0 17335 || STRNCMP(p, "try", 3) == 0) 17336 indent += 2; 17337 17338 /* Check for defining a function inside this function. */ 17339 if (checkforcmd(&p, "function", 2)) 17340 { 17341 if (*p == '!') 17342 p = skipwhite(p + 1); 17343 p += eval_fname_script(p); 17344 if (ASCII_ISALPHA(*p)) 17345 { 17346 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17347 if (*skipwhite(p) == '(') 17348 { 17349 ++nesting; 17350 indent += 2; 17351 } 17352 } 17353 } 17354 17355 /* Check for ":append" or ":insert". */ 17356 p = skip_range(p, NULL); 17357 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17358 || (p[0] == 'i' 17359 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17360 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17361 skip_until = vim_strsave((char_u *)"."); 17362 17363 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17364 arg = skipwhite(skiptowhite(p)); 17365 if (arg[0] == '<' && arg[1] =='<' 17366 && ((p[0] == 'p' && p[1] == 'y' 17367 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17368 || (p[0] == 'p' && p[1] == 'e' 17369 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17370 || (p[0] == 't' && p[1] == 'c' 17371 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17372 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17373 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17374 || (p[0] == 'm' && p[1] == 'z' 17375 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17376 )) 17377 { 17378 /* ":python <<" continues until a dot, like ":append" */ 17379 p = skipwhite(arg + 2); 17380 if (*p == NUL) 17381 skip_until = vim_strsave((char_u *)"."); 17382 else 17383 skip_until = vim_strsave(p); 17384 } 17385 } 17386 17387 /* Add the line to the function. */ 17388 if (ga_grow(&newlines, 1) == FAIL) 17389 { 17390 vim_free(theline); 17391 goto erret; 17392 } 17393 17394 /* Copy the line to newly allocated memory. get_one_sourceline() 17395 * allocates 250 bytes per line, this saves 80% on average. The cost 17396 * is an extra alloc/free. */ 17397 p = vim_strsave(theline); 17398 if (p != NULL) 17399 { 17400 vim_free(theline); 17401 theline = p; 17402 } 17403 17404 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17405 newlines.ga_len++; 17406 } 17407 17408 /* Don't define the function when skipping commands or when an error was 17409 * detected. */ 17410 if (eap->skip || did_emsg) 17411 goto erret; 17412 17413 /* 17414 * If there are no errors, add the function 17415 */ 17416 if (fudi.fd_dict == NULL) 17417 { 17418 v = find_var(name, &ht); 17419 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17420 { 17421 emsg_funcname("E707: Function name conflicts with variable: %s", 17422 name); 17423 goto erret; 17424 } 17425 17426 fp = find_func(name); 17427 if (fp != NULL) 17428 { 17429 if (!eap->forceit) 17430 { 17431 emsg_funcname(e_funcexts, name); 17432 goto erret; 17433 } 17434 if (fp->uf_calls > 0) 17435 { 17436 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17437 name); 17438 goto erret; 17439 } 17440 /* redefine existing function */ 17441 ga_clear_strings(&(fp->uf_args)); 17442 ga_clear_strings(&(fp->uf_lines)); 17443 vim_free(name); 17444 name = NULL; 17445 } 17446 } 17447 else 17448 { 17449 char numbuf[20]; 17450 17451 fp = NULL; 17452 if (fudi.fd_newkey == NULL && !eap->forceit) 17453 { 17454 EMSG(_(e_funcdict)); 17455 goto erret; 17456 } 17457 if (fudi.fd_di == NULL) 17458 { 17459 /* Can't add a function to a locked dictionary */ 17460 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17461 goto erret; 17462 } 17463 /* Can't change an existing function if it is locked */ 17464 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17465 goto erret; 17466 17467 /* Give the function a sequential number. Can only be used with a 17468 * Funcref! */ 17469 vim_free(name); 17470 sprintf(numbuf, "%d", ++func_nr); 17471 name = vim_strsave((char_u *)numbuf); 17472 if (name == NULL) 17473 goto erret; 17474 } 17475 17476 if (fp == NULL) 17477 { 17478 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17479 { 17480 int slen, plen; 17481 char_u *scriptname; 17482 17483 /* Check that the autoload name matches the script name. */ 17484 j = FAIL; 17485 if (sourcing_name != NULL) 17486 { 17487 scriptname = autoload_name(name); 17488 if (scriptname != NULL) 17489 { 17490 p = vim_strchr(scriptname, '/'); 17491 plen = STRLEN(p); 17492 slen = STRLEN(sourcing_name); 17493 if (slen > plen && fnamecmp(p, 17494 sourcing_name + slen - plen) == 0) 17495 j = OK; 17496 vim_free(scriptname); 17497 } 17498 } 17499 if (j == FAIL) 17500 { 17501 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17502 goto erret; 17503 } 17504 } 17505 17506 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17507 if (fp == NULL) 17508 goto erret; 17509 17510 if (fudi.fd_dict != NULL) 17511 { 17512 if (fudi.fd_di == NULL) 17513 { 17514 /* add new dict entry */ 17515 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17516 if (fudi.fd_di == NULL) 17517 { 17518 vim_free(fp); 17519 goto erret; 17520 } 17521 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17522 { 17523 vim_free(fudi.fd_di); 17524 goto erret; 17525 } 17526 } 17527 else 17528 /* overwrite existing dict entry */ 17529 clear_tv(&fudi.fd_di->di_tv); 17530 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17531 fudi.fd_di->di_tv.v_lock = 0; 17532 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17533 fp->uf_refcount = 1; 17534 } 17535 17536 /* insert the new function in the function list */ 17537 STRCPY(fp->uf_name, name); 17538 hash_add(&func_hashtab, UF2HIKEY(fp)); 17539 } 17540 fp->uf_args = newargs; 17541 fp->uf_lines = newlines; 17542 #ifdef FEAT_PROFILE 17543 fp->uf_tml_count = NULL; 17544 fp->uf_tml_total = NULL; 17545 fp->uf_tml_self = NULL; 17546 fp->uf_profiling = FALSE; 17547 if (prof_def_func()) 17548 func_do_profile(fp); 17549 #endif 17550 fp->uf_varargs = varargs; 17551 fp->uf_flags = flags; 17552 fp->uf_calls = 0; 17553 fp->uf_script_ID = current_SID; 17554 goto ret_free; 17555 17556 erret: 17557 ga_clear_strings(&newargs); 17558 ga_clear_strings(&newlines); 17559 ret_free: 17560 vim_free(skip_until); 17561 vim_free(fudi.fd_newkey); 17562 vim_free(name); 17563 did_emsg |= saved_did_emsg; 17564 } 17565 17566 /* 17567 * Get a function name, translating "<SID>" and "<SNR>". 17568 * Also handles a Funcref in a List or Dictionary. 17569 * Returns the function name in allocated memory, or NULL for failure. 17570 * flags: 17571 * TFN_INT: internal function name OK 17572 * TFN_QUIET: be quiet 17573 * Advances "pp" to just after the function name (if no error). 17574 */ 17575 static char_u * 17576 trans_function_name(pp, skip, flags, fdp) 17577 char_u **pp; 17578 int skip; /* only find the end, don't evaluate */ 17579 int flags; 17580 funcdict_T *fdp; /* return: info about dictionary used */ 17581 { 17582 char_u *name = NULL; 17583 char_u *start; 17584 char_u *end; 17585 int lead; 17586 char_u sid_buf[20]; 17587 int len; 17588 lval_T lv; 17589 17590 if (fdp != NULL) 17591 vim_memset(fdp, 0, sizeof(funcdict_T)); 17592 start = *pp; 17593 17594 /* Check for hard coded <SNR>: already translated function ID (from a user 17595 * command). */ 17596 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17597 && (*pp)[2] == (int)KE_SNR) 17598 { 17599 *pp += 3; 17600 len = get_id_len(pp) + 3; 17601 return vim_strnsave(start, len); 17602 } 17603 17604 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17605 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17606 lead = eval_fname_script(start); 17607 if (lead > 2) 17608 start += lead; 17609 17610 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17611 lead > 2 ? 0 : FNE_CHECK_START); 17612 if (end == start) 17613 { 17614 if (!skip) 17615 EMSG(_("E129: Function name required")); 17616 goto theend; 17617 } 17618 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17619 { 17620 /* 17621 * Report an invalid expression in braces, unless the expression 17622 * evaluation has been cancelled due to an aborting error, an 17623 * interrupt, or an exception. 17624 */ 17625 if (!aborting()) 17626 { 17627 if (end != NULL) 17628 EMSG2(_(e_invarg2), start); 17629 } 17630 else 17631 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17632 goto theend; 17633 } 17634 17635 if (lv.ll_tv != NULL) 17636 { 17637 if (fdp != NULL) 17638 { 17639 fdp->fd_dict = lv.ll_dict; 17640 fdp->fd_newkey = lv.ll_newkey; 17641 lv.ll_newkey = NULL; 17642 fdp->fd_di = lv.ll_di; 17643 } 17644 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17645 { 17646 name = vim_strsave(lv.ll_tv->vval.v_string); 17647 *pp = end; 17648 } 17649 else 17650 { 17651 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17652 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17653 EMSG(_(e_funcref)); 17654 else 17655 *pp = end; 17656 name = NULL; 17657 } 17658 goto theend; 17659 } 17660 17661 if (lv.ll_name == NULL) 17662 { 17663 /* Error found, but continue after the function name. */ 17664 *pp = end; 17665 goto theend; 17666 } 17667 17668 if (lv.ll_exp_name != NULL) 17669 len = STRLEN(lv.ll_exp_name); 17670 else 17671 { 17672 if (lead == 2) /* skip over "s:" */ 17673 lv.ll_name += 2; 17674 len = (int)(end - lv.ll_name); 17675 } 17676 17677 /* 17678 * Copy the function name to allocated memory. 17679 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17680 * Accept <SNR>123_name() outside a script. 17681 */ 17682 if (skip) 17683 lead = 0; /* do nothing */ 17684 else if (lead > 0) 17685 { 17686 lead = 3; 17687 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17688 { 17689 if (current_SID <= 0) 17690 { 17691 EMSG(_(e_usingsid)); 17692 goto theend; 17693 } 17694 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17695 lead += (int)STRLEN(sid_buf); 17696 } 17697 } 17698 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17699 { 17700 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17701 goto theend; 17702 } 17703 name = alloc((unsigned)(len + lead + 1)); 17704 if (name != NULL) 17705 { 17706 if (lead > 0) 17707 { 17708 name[0] = K_SPECIAL; 17709 name[1] = KS_EXTRA; 17710 name[2] = (int)KE_SNR; 17711 if (lead > 3) /* If it's "<SID>" */ 17712 STRCPY(name + 3, sid_buf); 17713 } 17714 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17715 name[len + lead] = NUL; 17716 } 17717 *pp = end; 17718 17719 theend: 17720 clear_lval(&lv); 17721 return name; 17722 } 17723 17724 /* 17725 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17726 * Return 2 if "p" starts with "s:". 17727 * Return 0 otherwise. 17728 */ 17729 static int 17730 eval_fname_script(p) 17731 char_u *p; 17732 { 17733 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17734 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17735 return 5; 17736 if (p[0] == 's' && p[1] == ':') 17737 return 2; 17738 return 0; 17739 } 17740 17741 /* 17742 * Return TRUE if "p" starts with "<SID>" or "s:". 17743 * Only works if eval_fname_script() returned non-zero for "p"! 17744 */ 17745 static int 17746 eval_fname_sid(p) 17747 char_u *p; 17748 { 17749 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17750 } 17751 17752 /* 17753 * List the head of the function: "name(arg1, arg2)". 17754 */ 17755 static void 17756 list_func_head(fp, indent) 17757 ufunc_T *fp; 17758 int indent; 17759 { 17760 int j; 17761 17762 msg_start(); 17763 if (indent) 17764 MSG_PUTS(" "); 17765 MSG_PUTS("function "); 17766 if (fp->uf_name[0] == K_SPECIAL) 17767 { 17768 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17769 msg_puts(fp->uf_name + 3); 17770 } 17771 else 17772 msg_puts(fp->uf_name); 17773 msg_putchar('('); 17774 for (j = 0; j < fp->uf_args.ga_len; ++j) 17775 { 17776 if (j) 17777 MSG_PUTS(", "); 17778 msg_puts(FUNCARG(fp, j)); 17779 } 17780 if (fp->uf_varargs) 17781 { 17782 if (j) 17783 MSG_PUTS(", "); 17784 MSG_PUTS("..."); 17785 } 17786 msg_putchar(')'); 17787 msg_clr_eos(); 17788 if (p_verbose > 0) 17789 last_set_msg(fp->uf_script_ID); 17790 } 17791 17792 /* 17793 * Find a function by name, return pointer to it in ufuncs. 17794 * Return NULL for unknown function. 17795 */ 17796 static ufunc_T * 17797 find_func(name) 17798 char_u *name; 17799 { 17800 hashitem_T *hi; 17801 17802 hi = hash_find(&func_hashtab, name); 17803 if (!HASHITEM_EMPTY(hi)) 17804 return HI2UF(hi); 17805 return NULL; 17806 } 17807 17808 #if defined(EXITFREE) || defined(PROTO) 17809 void 17810 free_all_functions() 17811 { 17812 hashitem_T *hi; 17813 17814 /* Need to start all over every time, because func_free() may change the 17815 * hash table. */ 17816 while (func_hashtab.ht_used > 0) 17817 for (hi = func_hashtab.ht_array; ; ++hi) 17818 if (!HASHITEM_EMPTY(hi)) 17819 { 17820 func_free(HI2UF(hi)); 17821 break; 17822 } 17823 } 17824 #endif 17825 17826 /* 17827 * Return TRUE if a function "name" exists. 17828 */ 17829 static int 17830 function_exists(name) 17831 char_u *name; 17832 { 17833 char_u *p = name; 17834 int n = FALSE; 17835 17836 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17837 if (p != NULL) 17838 { 17839 if (builtin_function(p)) 17840 n = (find_internal_func(p) >= 0); 17841 else 17842 n = (find_func(p) != NULL); 17843 vim_free(p); 17844 } 17845 return n; 17846 } 17847 17848 /* 17849 * Return TRUE if "name" looks like a builtin function name: starts with a 17850 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17851 */ 17852 static int 17853 builtin_function(name) 17854 char_u *name; 17855 { 17856 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17857 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17858 } 17859 17860 #if defined(FEAT_PROFILE) || defined(PROTO) 17861 /* 17862 * Start profiling function "fp". 17863 */ 17864 static void 17865 func_do_profile(fp) 17866 ufunc_T *fp; 17867 { 17868 fp->uf_tm_count = 0; 17869 profile_zero(&fp->uf_tm_self); 17870 profile_zero(&fp->uf_tm_total); 17871 if (fp->uf_tml_count == NULL) 17872 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17873 (sizeof(int) * fp->uf_lines.ga_len)); 17874 if (fp->uf_tml_total == NULL) 17875 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17876 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17877 if (fp->uf_tml_self == NULL) 17878 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17879 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17880 fp->uf_tml_idx = -1; 17881 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17882 || fp->uf_tml_self == NULL) 17883 return; /* out of memory */ 17884 17885 fp->uf_profiling = TRUE; 17886 } 17887 17888 /* 17889 * Dump the profiling results for all functions in file "fd". 17890 */ 17891 void 17892 func_dump_profile(fd) 17893 FILE *fd; 17894 { 17895 hashitem_T *hi; 17896 int todo; 17897 ufunc_T *fp; 17898 int i; 17899 ufunc_T **sorttab; 17900 int st_len = 0; 17901 17902 todo = func_hashtab.ht_used; 17903 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17904 17905 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17906 { 17907 if (!HASHITEM_EMPTY(hi)) 17908 { 17909 --todo; 17910 fp = HI2UF(hi); 17911 if (fp->uf_profiling) 17912 { 17913 if (sorttab != NULL) 17914 sorttab[st_len++] = fp; 17915 17916 if (fp->uf_name[0] == K_SPECIAL) 17917 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17918 else 17919 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17920 if (fp->uf_tm_count == 1) 17921 fprintf(fd, "Called 1 time\n"); 17922 else 17923 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17924 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17925 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17926 fprintf(fd, "\n"); 17927 fprintf(fd, "count total (s) self (s)\n"); 17928 17929 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17930 { 17931 prof_func_line(fd, fp->uf_tml_count[i], 17932 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17933 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17934 } 17935 fprintf(fd, "\n"); 17936 } 17937 } 17938 } 17939 17940 if (sorttab != NULL && st_len > 0) 17941 { 17942 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17943 prof_total_cmp); 17944 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17945 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17946 prof_self_cmp); 17947 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17948 } 17949 } 17950 17951 static void 17952 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17953 FILE *fd; 17954 ufunc_T **sorttab; 17955 int st_len; 17956 char *title; 17957 int prefer_self; /* when equal print only self time */ 17958 { 17959 int i; 17960 ufunc_T *fp; 17961 17962 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17963 fprintf(fd, "count total (s) self (s) function\n"); 17964 for (i = 0; i < 20 && i < st_len; ++i) 17965 { 17966 fp = sorttab[i]; 17967 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17968 prefer_self); 17969 if (fp->uf_name[0] == K_SPECIAL) 17970 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17971 else 17972 fprintf(fd, " %s()\n", fp->uf_name); 17973 } 17974 fprintf(fd, "\n"); 17975 } 17976 17977 /* 17978 * Print the count and times for one function or function line. 17979 */ 17980 static void 17981 prof_func_line(fd, count, total, self, prefer_self) 17982 FILE *fd; 17983 int count; 17984 proftime_T *total; 17985 proftime_T *self; 17986 int prefer_self; /* when equal print only self time */ 17987 { 17988 if (count > 0) 17989 { 17990 fprintf(fd, "%5d ", count); 17991 if (prefer_self && profile_equal(total, self)) 17992 fprintf(fd, " "); 17993 else 17994 fprintf(fd, "%s ", profile_msg(total)); 17995 if (!prefer_self && profile_equal(total, self)) 17996 fprintf(fd, " "); 17997 else 17998 fprintf(fd, "%s ", profile_msg(self)); 17999 } 18000 else 18001 fprintf(fd, " "); 18002 } 18003 18004 /* 18005 * Compare function for total time sorting. 18006 */ 18007 static int 18008 #ifdef __BORLANDC__ 18009 _RTLENTRYF 18010 #endif 18011 prof_total_cmp(s1, s2) 18012 const void *s1; 18013 const void *s2; 18014 { 18015 ufunc_T *p1, *p2; 18016 18017 p1 = *(ufunc_T **)s1; 18018 p2 = *(ufunc_T **)s2; 18019 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 18020 } 18021 18022 /* 18023 * Compare function for self time sorting. 18024 */ 18025 static int 18026 #ifdef __BORLANDC__ 18027 _RTLENTRYF 18028 #endif 18029 prof_self_cmp(s1, s2) 18030 const void *s1; 18031 const void *s2; 18032 { 18033 ufunc_T *p1, *p2; 18034 18035 p1 = *(ufunc_T **)s1; 18036 p2 = *(ufunc_T **)s2; 18037 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 18038 } 18039 18040 #endif 18041 18042 /* The names of packages that once were loaded is remembered. */ 18043 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 18044 18045 /* 18046 * If "name" has a package name try autoloading the script for it. 18047 * Return TRUE if a package was loaded. 18048 */ 18049 static int 18050 script_autoload(name, reload) 18051 char_u *name; 18052 int reload; /* load script again when already loaded */ 18053 { 18054 char_u *p; 18055 char_u *scriptname, *tofree; 18056 int ret = FALSE; 18057 int i; 18058 18059 /* If there is no '#' after name[0] there is no package name. */ 18060 p = vim_strchr(name, AUTOLOAD_CHAR); 18061 if (p == NULL || p == name) 18062 return FALSE; 18063 18064 tofree = scriptname = autoload_name(name); 18065 18066 /* Find the name in the list of previously loaded package names. Skip 18067 * "autoload/", it's always the same. */ 18068 for (i = 0; i < ga_loaded.ga_len; ++i) 18069 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 18070 break; 18071 if (!reload && i < ga_loaded.ga_len) 18072 ret = FALSE; /* was loaded already */ 18073 else 18074 { 18075 /* Remember the name if it wasn't loaded already. */ 18076 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 18077 { 18078 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 18079 tofree = NULL; 18080 } 18081 18082 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 18083 if (source_runtime(scriptname, FALSE) == OK) 18084 ret = TRUE; 18085 } 18086 18087 vim_free(tofree); 18088 return ret; 18089 } 18090 18091 /* 18092 * Return the autoload script name for a function or variable name. 18093 * Returns NULL when out of memory. 18094 */ 18095 static char_u * 18096 autoload_name(name) 18097 char_u *name; 18098 { 18099 char_u *p; 18100 char_u *scriptname; 18101 18102 /* Get the script file name: replace '#' with '/', append ".vim". */ 18103 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 18104 if (scriptname == NULL) 18105 return FALSE; 18106 STRCPY(scriptname, "autoload/"); 18107 STRCAT(scriptname, name); 18108 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 18109 STRCAT(scriptname, ".vim"); 18110 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 18111 *p = '/'; 18112 return scriptname; 18113 } 18114 18115 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 18116 18117 /* 18118 * Function given to ExpandGeneric() to obtain the list of user defined 18119 * function names. 18120 */ 18121 char_u * 18122 get_user_func_name(xp, idx) 18123 expand_T *xp; 18124 int idx; 18125 { 18126 static long_u done; 18127 static hashitem_T *hi; 18128 ufunc_T *fp; 18129 18130 if (idx == 0) 18131 { 18132 done = 0; 18133 hi = func_hashtab.ht_array; 18134 } 18135 if (done < func_hashtab.ht_used) 18136 { 18137 if (done++ > 0) 18138 ++hi; 18139 while (HASHITEM_EMPTY(hi)) 18140 ++hi; 18141 fp = HI2UF(hi); 18142 18143 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 18144 return fp->uf_name; /* prevents overflow */ 18145 18146 cat_func_name(IObuff, fp); 18147 if (xp->xp_context != EXPAND_USER_FUNC) 18148 { 18149 STRCAT(IObuff, "("); 18150 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 18151 STRCAT(IObuff, ")"); 18152 } 18153 return IObuff; 18154 } 18155 return NULL; 18156 } 18157 18158 #endif /* FEAT_CMDL_COMPL */ 18159 18160 /* 18161 * Copy the function name of "fp" to buffer "buf". 18162 * "buf" must be able to hold the function name plus three bytes. 18163 * Takes care of script-local function names. 18164 */ 18165 static void 18166 cat_func_name(buf, fp) 18167 char_u *buf; 18168 ufunc_T *fp; 18169 { 18170 if (fp->uf_name[0] == K_SPECIAL) 18171 { 18172 STRCPY(buf, "<SNR>"); 18173 STRCAT(buf, fp->uf_name + 3); 18174 } 18175 else 18176 STRCPY(buf, fp->uf_name); 18177 } 18178 18179 /* 18180 * ":delfunction {name}" 18181 */ 18182 void 18183 ex_delfunction(eap) 18184 exarg_T *eap; 18185 { 18186 ufunc_T *fp = NULL; 18187 char_u *p; 18188 char_u *name; 18189 funcdict_T fudi; 18190 18191 p = eap->arg; 18192 name = trans_function_name(&p, eap->skip, 0, &fudi); 18193 vim_free(fudi.fd_newkey); 18194 if (name == NULL) 18195 { 18196 if (fudi.fd_dict != NULL && !eap->skip) 18197 EMSG(_(e_funcref)); 18198 return; 18199 } 18200 if (!ends_excmd(*skipwhite(p))) 18201 { 18202 vim_free(name); 18203 EMSG(_(e_trailing)); 18204 return; 18205 } 18206 eap->nextcmd = check_nextcmd(p); 18207 if (eap->nextcmd != NULL) 18208 *p = NUL; 18209 18210 if (!eap->skip) 18211 fp = find_func(name); 18212 vim_free(name); 18213 18214 if (!eap->skip) 18215 { 18216 if (fp == NULL) 18217 { 18218 EMSG2(_(e_nofunc), eap->arg); 18219 return; 18220 } 18221 if (fp->uf_calls > 0) 18222 { 18223 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 18224 return; 18225 } 18226 18227 if (fudi.fd_dict != NULL) 18228 { 18229 /* Delete the dict item that refers to the function, it will 18230 * invoke func_unref() and possibly delete the function. */ 18231 dictitem_remove(fudi.fd_dict, fudi.fd_di); 18232 } 18233 else 18234 func_free(fp); 18235 } 18236 } 18237 18238 /* 18239 * Free a function and remove it from the list of functions. 18240 */ 18241 static void 18242 func_free(fp) 18243 ufunc_T *fp; 18244 { 18245 hashitem_T *hi; 18246 18247 /* clear this function */ 18248 ga_clear_strings(&(fp->uf_args)); 18249 ga_clear_strings(&(fp->uf_lines)); 18250 #ifdef FEAT_PROFILE 18251 vim_free(fp->uf_tml_count); 18252 vim_free(fp->uf_tml_total); 18253 vim_free(fp->uf_tml_self); 18254 #endif 18255 18256 /* remove the function from the function hashtable */ 18257 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 18258 if (HASHITEM_EMPTY(hi)) 18259 EMSG2(_(e_intern2), "func_free()"); 18260 else 18261 hash_remove(&func_hashtab, hi); 18262 18263 vim_free(fp); 18264 } 18265 18266 /* 18267 * Unreference a Function: decrement the reference count and free it when it 18268 * becomes zero. Only for numbered functions. 18269 */ 18270 static void 18271 func_unref(name) 18272 char_u *name; 18273 { 18274 ufunc_T *fp; 18275 18276 if (name != NULL && isdigit(*name)) 18277 { 18278 fp = find_func(name); 18279 if (fp == NULL) 18280 EMSG2(_(e_intern2), "func_unref()"); 18281 else if (--fp->uf_refcount <= 0) 18282 { 18283 /* Only delete it when it's not being used. Otherwise it's done 18284 * when "uf_calls" becomes zero. */ 18285 if (fp->uf_calls == 0) 18286 func_free(fp); 18287 } 18288 } 18289 } 18290 18291 /* 18292 * Count a reference to a Function. 18293 */ 18294 static void 18295 func_ref(name) 18296 char_u *name; 18297 { 18298 ufunc_T *fp; 18299 18300 if (name != NULL && isdigit(*name)) 18301 { 18302 fp = find_func(name); 18303 if (fp == NULL) 18304 EMSG2(_(e_intern2), "func_ref()"); 18305 else 18306 ++fp->uf_refcount; 18307 } 18308 } 18309 18310 /* 18311 * Call a user function. 18312 */ 18313 static void 18314 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18315 ufunc_T *fp; /* pointer to function */ 18316 int argcount; /* nr of args */ 18317 typval_T *argvars; /* arguments */ 18318 typval_T *rettv; /* return value */ 18319 linenr_T firstline; /* first line of range */ 18320 linenr_T lastline; /* last line of range */ 18321 dict_T *selfdict; /* Dictionary for "self" */ 18322 { 18323 char_u *save_sourcing_name; 18324 linenr_T save_sourcing_lnum; 18325 scid_T save_current_SID; 18326 funccall_T fc; 18327 int save_did_emsg; 18328 static int depth = 0; 18329 dictitem_T *v; 18330 int fixvar_idx = 0; /* index in fixvar[] */ 18331 int i; 18332 int ai; 18333 char_u numbuf[NUMBUFLEN]; 18334 char_u *name; 18335 #ifdef FEAT_PROFILE 18336 proftime_T wait_start; 18337 #endif 18338 18339 /* If depth of calling is getting too high, don't execute the function */ 18340 if (depth >= p_mfd) 18341 { 18342 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18343 rettv->v_type = VAR_NUMBER; 18344 rettv->vval.v_number = -1; 18345 return; 18346 } 18347 ++depth; 18348 18349 line_breakcheck(); /* check for CTRL-C hit */ 18350 18351 fc.caller = current_funccal; 18352 current_funccal = &fc; 18353 fc.func = fp; 18354 fc.rettv = rettv; 18355 rettv->vval.v_number = 0; 18356 fc.linenr = 0; 18357 fc.returned = FALSE; 18358 fc.level = ex_nesting_level; 18359 /* Check if this function has a breakpoint. */ 18360 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18361 fc.dbg_tick = debug_tick; 18362 18363 /* 18364 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18365 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18366 * each argument variable and saves a lot of time. 18367 */ 18368 /* 18369 * Init l: variables. 18370 */ 18371 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18372 if (selfdict != NULL) 18373 { 18374 /* Set l:self to "selfdict". */ 18375 v = &fc.fixvar[fixvar_idx++].var; 18376 STRCPY(v->di_key, "self"); 18377 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18378 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18379 v->di_tv.v_type = VAR_DICT; 18380 v->di_tv.v_lock = 0; 18381 v->di_tv.vval.v_dict = selfdict; 18382 ++selfdict->dv_refcount; 18383 } 18384 18385 /* 18386 * Init a: variables. 18387 * Set a:0 to "argcount". 18388 * Set a:000 to a list with room for the "..." arguments. 18389 */ 18390 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18391 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18392 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18393 v = &fc.fixvar[fixvar_idx++].var; 18394 STRCPY(v->di_key, "000"); 18395 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18396 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18397 v->di_tv.v_type = VAR_LIST; 18398 v->di_tv.v_lock = VAR_FIXED; 18399 v->di_tv.vval.v_list = &fc.l_varlist; 18400 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18401 fc.l_varlist.lv_refcount = 99999; 18402 18403 /* 18404 * Set a:firstline to "firstline" and a:lastline to "lastline". 18405 * Set a:name to named arguments. 18406 * Set a:N to the "..." arguments. 18407 */ 18408 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18409 (varnumber_T)firstline); 18410 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18411 (varnumber_T)lastline); 18412 for (i = 0; i < argcount; ++i) 18413 { 18414 ai = i - fp->uf_args.ga_len; 18415 if (ai < 0) 18416 /* named argument a:name */ 18417 name = FUNCARG(fp, i); 18418 else 18419 { 18420 /* "..." argument a:1, a:2, etc. */ 18421 sprintf((char *)numbuf, "%d", ai + 1); 18422 name = numbuf; 18423 } 18424 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18425 { 18426 v = &fc.fixvar[fixvar_idx++].var; 18427 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18428 } 18429 else 18430 { 18431 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18432 + STRLEN(name))); 18433 if (v == NULL) 18434 break; 18435 v->di_flags = DI_FLAGS_RO; 18436 } 18437 STRCPY(v->di_key, name); 18438 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18439 18440 /* Note: the values are copied directly to avoid alloc/free. 18441 * "argvars" must have VAR_FIXED for v_lock. */ 18442 v->di_tv = argvars[i]; 18443 v->di_tv.v_lock = VAR_FIXED; 18444 18445 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18446 { 18447 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18448 fc.l_listitems[ai].li_tv = argvars[i]; 18449 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18450 } 18451 } 18452 18453 /* Don't redraw while executing the function. */ 18454 ++RedrawingDisabled; 18455 save_sourcing_name = sourcing_name; 18456 save_sourcing_lnum = sourcing_lnum; 18457 sourcing_lnum = 1; 18458 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18459 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18460 if (sourcing_name != NULL) 18461 { 18462 if (save_sourcing_name != NULL 18463 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18464 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18465 else 18466 STRCPY(sourcing_name, "function "); 18467 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18468 18469 if (p_verbose >= 12) 18470 { 18471 ++no_wait_return; 18472 verbose_enter_scroll(); 18473 18474 smsg((char_u *)_("calling %s"), sourcing_name); 18475 if (p_verbose >= 14) 18476 { 18477 char_u buf[MSG_BUF_LEN]; 18478 char_u numbuf[NUMBUFLEN]; 18479 char_u *tofree; 18480 18481 msg_puts((char_u *)"("); 18482 for (i = 0; i < argcount; ++i) 18483 { 18484 if (i > 0) 18485 msg_puts((char_u *)", "); 18486 if (argvars[i].v_type == VAR_NUMBER) 18487 msg_outnum((long)argvars[i].vval.v_number); 18488 else 18489 { 18490 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18491 buf, MSG_BUF_CLEN); 18492 msg_puts(buf); 18493 vim_free(tofree); 18494 } 18495 } 18496 msg_puts((char_u *)")"); 18497 } 18498 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18499 18500 verbose_leave_scroll(); 18501 --no_wait_return; 18502 } 18503 } 18504 #ifdef FEAT_PROFILE 18505 if (do_profiling) 18506 { 18507 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18508 func_do_profile(fp); 18509 if (fp->uf_profiling 18510 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18511 { 18512 ++fp->uf_tm_count; 18513 profile_start(&fp->uf_tm_start); 18514 profile_zero(&fp->uf_tm_children); 18515 } 18516 script_prof_save(&wait_start); 18517 } 18518 #endif 18519 18520 save_current_SID = current_SID; 18521 current_SID = fp->uf_script_ID; 18522 save_did_emsg = did_emsg; 18523 did_emsg = FALSE; 18524 18525 /* call do_cmdline() to execute the lines */ 18526 do_cmdline(NULL, get_func_line, (void *)&fc, 18527 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18528 18529 --RedrawingDisabled; 18530 18531 /* when the function was aborted because of an error, return -1 */ 18532 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18533 { 18534 clear_tv(rettv); 18535 rettv->v_type = VAR_NUMBER; 18536 rettv->vval.v_number = -1; 18537 } 18538 18539 #ifdef FEAT_PROFILE 18540 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18541 { 18542 profile_end(&fp->uf_tm_start); 18543 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18544 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18545 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18546 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18547 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18548 { 18549 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18550 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18551 } 18552 } 18553 #endif 18554 18555 /* when being verbose, mention the return value */ 18556 if (p_verbose >= 12) 18557 { 18558 ++no_wait_return; 18559 verbose_enter_scroll(); 18560 18561 if (aborting()) 18562 smsg((char_u *)_("%s aborted"), sourcing_name); 18563 else if (fc.rettv->v_type == VAR_NUMBER) 18564 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18565 (long)fc.rettv->vval.v_number); 18566 else 18567 { 18568 char_u buf[MSG_BUF_LEN]; 18569 char_u numbuf[NUMBUFLEN]; 18570 char_u *tofree; 18571 18572 /* The value may be very long. Skip the middle part, so that we 18573 * have some idea how it starts and ends. smsg() would always 18574 * truncate it at the end. */ 18575 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18576 buf, MSG_BUF_CLEN); 18577 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18578 vim_free(tofree); 18579 } 18580 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18581 18582 verbose_leave_scroll(); 18583 --no_wait_return; 18584 } 18585 18586 vim_free(sourcing_name); 18587 sourcing_name = save_sourcing_name; 18588 sourcing_lnum = save_sourcing_lnum; 18589 current_SID = save_current_SID; 18590 #ifdef FEAT_PROFILE 18591 if (do_profiling) 18592 script_prof_restore(&wait_start); 18593 #endif 18594 18595 if (p_verbose >= 12 && sourcing_name != NULL) 18596 { 18597 ++no_wait_return; 18598 verbose_enter_scroll(); 18599 18600 smsg((char_u *)_("continuing in %s"), sourcing_name); 18601 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18602 18603 verbose_leave_scroll(); 18604 --no_wait_return; 18605 } 18606 18607 did_emsg |= save_did_emsg; 18608 current_funccal = fc.caller; 18609 18610 /* The a: variables typevals were not alloced, only free the allocated 18611 * variables. */ 18612 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18613 18614 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18615 --depth; 18616 } 18617 18618 /* 18619 * Add a number variable "name" to dict "dp" with value "nr". 18620 */ 18621 static void 18622 add_nr_var(dp, v, name, nr) 18623 dict_T *dp; 18624 dictitem_T *v; 18625 char *name; 18626 varnumber_T nr; 18627 { 18628 STRCPY(v->di_key, name); 18629 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18630 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18631 v->di_tv.v_type = VAR_NUMBER; 18632 v->di_tv.v_lock = VAR_FIXED; 18633 v->di_tv.vval.v_number = nr; 18634 } 18635 18636 /* 18637 * ":return [expr]" 18638 */ 18639 void 18640 ex_return(eap) 18641 exarg_T *eap; 18642 { 18643 char_u *arg = eap->arg; 18644 typval_T rettv; 18645 int returning = FALSE; 18646 18647 if (current_funccal == NULL) 18648 { 18649 EMSG(_("E133: :return not inside a function")); 18650 return; 18651 } 18652 18653 if (eap->skip) 18654 ++emsg_skip; 18655 18656 eap->nextcmd = NULL; 18657 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18658 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18659 { 18660 if (!eap->skip) 18661 returning = do_return(eap, FALSE, TRUE, &rettv); 18662 else 18663 clear_tv(&rettv); 18664 } 18665 /* It's safer to return also on error. */ 18666 else if (!eap->skip) 18667 { 18668 /* 18669 * Return unless the expression evaluation has been cancelled due to an 18670 * aborting error, an interrupt, or an exception. 18671 */ 18672 if (!aborting()) 18673 returning = do_return(eap, FALSE, TRUE, NULL); 18674 } 18675 18676 /* When skipping or the return gets pending, advance to the next command 18677 * in this line (!returning). Otherwise, ignore the rest of the line. 18678 * Following lines will be ignored by get_func_line(). */ 18679 if (returning) 18680 eap->nextcmd = NULL; 18681 else if (eap->nextcmd == NULL) /* no argument */ 18682 eap->nextcmd = check_nextcmd(arg); 18683 18684 if (eap->skip) 18685 --emsg_skip; 18686 } 18687 18688 /* 18689 * Return from a function. Possibly makes the return pending. Also called 18690 * for a pending return at the ":endtry" or after returning from an extra 18691 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18692 * when called due to a ":return" command. "rettv" may point to a typval_T 18693 * with the return rettv. Returns TRUE when the return can be carried out, 18694 * FALSE when the return gets pending. 18695 */ 18696 int 18697 do_return(eap, reanimate, is_cmd, rettv) 18698 exarg_T *eap; 18699 int reanimate; 18700 int is_cmd; 18701 void *rettv; 18702 { 18703 int idx; 18704 struct condstack *cstack = eap->cstack; 18705 18706 if (reanimate) 18707 /* Undo the return. */ 18708 current_funccal->returned = FALSE; 18709 18710 /* 18711 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18712 * not in its finally clause (which then is to be executed next) is found. 18713 * In this case, make the ":return" pending for execution at the ":endtry". 18714 * Otherwise, return normally. 18715 */ 18716 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18717 if (idx >= 0) 18718 { 18719 cstack->cs_pending[idx] = CSTP_RETURN; 18720 18721 if (!is_cmd && !reanimate) 18722 /* A pending return again gets pending. "rettv" points to an 18723 * allocated variable with the rettv of the original ":return"'s 18724 * argument if present or is NULL else. */ 18725 cstack->cs_rettv[idx] = rettv; 18726 else 18727 { 18728 /* When undoing a return in order to make it pending, get the stored 18729 * return rettv. */ 18730 if (reanimate) 18731 rettv = current_funccal->rettv; 18732 18733 if (rettv != NULL) 18734 { 18735 /* Store the value of the pending return. */ 18736 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18737 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18738 else 18739 EMSG(_(e_outofmem)); 18740 } 18741 else 18742 cstack->cs_rettv[idx] = NULL; 18743 18744 if (reanimate) 18745 { 18746 /* The pending return value could be overwritten by a ":return" 18747 * without argument in a finally clause; reset the default 18748 * return value. */ 18749 current_funccal->rettv->v_type = VAR_NUMBER; 18750 current_funccal->rettv->vval.v_number = 0; 18751 } 18752 } 18753 report_make_pending(CSTP_RETURN, rettv); 18754 } 18755 else 18756 { 18757 current_funccal->returned = TRUE; 18758 18759 /* If the return is carried out now, store the return value. For 18760 * a return immediately after reanimation, the value is already 18761 * there. */ 18762 if (!reanimate && rettv != NULL) 18763 { 18764 clear_tv(current_funccal->rettv); 18765 *current_funccal->rettv = *(typval_T *)rettv; 18766 if (!is_cmd) 18767 vim_free(rettv); 18768 } 18769 } 18770 18771 return idx < 0; 18772 } 18773 18774 /* 18775 * Free the variable with a pending return value. 18776 */ 18777 void 18778 discard_pending_return(rettv) 18779 void *rettv; 18780 { 18781 free_tv((typval_T *)rettv); 18782 } 18783 18784 /* 18785 * Generate a return command for producing the value of "rettv". The result 18786 * is an allocated string. Used by report_pending() for verbose messages. 18787 */ 18788 char_u * 18789 get_return_cmd(rettv) 18790 void *rettv; 18791 { 18792 char_u *s = NULL; 18793 char_u *tofree = NULL; 18794 char_u numbuf[NUMBUFLEN]; 18795 18796 if (rettv != NULL) 18797 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18798 if (s == NULL) 18799 s = (char_u *)""; 18800 18801 STRCPY(IObuff, ":return "); 18802 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18803 if (STRLEN(s) + 8 >= IOSIZE) 18804 STRCPY(IObuff + IOSIZE - 4, "..."); 18805 vim_free(tofree); 18806 return vim_strsave(IObuff); 18807 } 18808 18809 /* 18810 * Get next function line. 18811 * Called by do_cmdline() to get the next line. 18812 * Returns allocated string, or NULL for end of function. 18813 */ 18814 /* ARGSUSED */ 18815 char_u * 18816 get_func_line(c, cookie, indent) 18817 int c; /* not used */ 18818 void *cookie; 18819 int indent; /* not used */ 18820 { 18821 funccall_T *fcp = (funccall_T *)cookie; 18822 ufunc_T *fp = fcp->func; 18823 char_u *retval; 18824 garray_T *gap; /* growarray with function lines */ 18825 18826 /* If breakpoints have been added/deleted need to check for it. */ 18827 if (fcp->dbg_tick != debug_tick) 18828 { 18829 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18830 sourcing_lnum); 18831 fcp->dbg_tick = debug_tick; 18832 } 18833 #ifdef FEAT_PROFILE 18834 if (do_profiling) 18835 func_line_end(cookie); 18836 #endif 18837 18838 gap = &fp->uf_lines; 18839 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18840 retval = NULL; 18841 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18842 retval = NULL; 18843 else 18844 { 18845 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18846 sourcing_lnum = fcp->linenr; 18847 #ifdef FEAT_PROFILE 18848 if (do_profiling) 18849 func_line_start(cookie); 18850 #endif 18851 } 18852 18853 /* Did we encounter a breakpoint? */ 18854 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18855 { 18856 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18857 /* Find next breakpoint. */ 18858 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18859 sourcing_lnum); 18860 fcp->dbg_tick = debug_tick; 18861 } 18862 18863 return retval; 18864 } 18865 18866 #if defined(FEAT_PROFILE) || defined(PROTO) 18867 /* 18868 * Called when starting to read a function line. 18869 * "sourcing_lnum" must be correct! 18870 * When skipping lines it may not actually be executed, but we won't find out 18871 * until later and we need to store the time now. 18872 */ 18873 void 18874 func_line_start(cookie) 18875 void *cookie; 18876 { 18877 funccall_T *fcp = (funccall_T *)cookie; 18878 ufunc_T *fp = fcp->func; 18879 18880 if (fp->uf_profiling && sourcing_lnum >= 1 18881 && sourcing_lnum <= fp->uf_lines.ga_len) 18882 { 18883 fp->uf_tml_idx = sourcing_lnum - 1; 18884 fp->uf_tml_execed = FALSE; 18885 profile_start(&fp->uf_tml_start); 18886 profile_zero(&fp->uf_tml_children); 18887 profile_get_wait(&fp->uf_tml_wait); 18888 } 18889 } 18890 18891 /* 18892 * Called when actually executing a function line. 18893 */ 18894 void 18895 func_line_exec(cookie) 18896 void *cookie; 18897 { 18898 funccall_T *fcp = (funccall_T *)cookie; 18899 ufunc_T *fp = fcp->func; 18900 18901 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18902 fp->uf_tml_execed = TRUE; 18903 } 18904 18905 /* 18906 * Called when done with a function line. 18907 */ 18908 void 18909 func_line_end(cookie) 18910 void *cookie; 18911 { 18912 funccall_T *fcp = (funccall_T *)cookie; 18913 ufunc_T *fp = fcp->func; 18914 18915 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18916 { 18917 if (fp->uf_tml_execed) 18918 { 18919 ++fp->uf_tml_count[fp->uf_tml_idx]; 18920 profile_end(&fp->uf_tml_start); 18921 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18922 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18923 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18924 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18925 } 18926 fp->uf_tml_idx = -1; 18927 } 18928 } 18929 #endif 18930 18931 /* 18932 * Return TRUE if the currently active function should be ended, because a 18933 * return was encountered or an error occured. Used inside a ":while". 18934 */ 18935 int 18936 func_has_ended(cookie) 18937 void *cookie; 18938 { 18939 funccall_T *fcp = (funccall_T *)cookie; 18940 18941 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18942 * an error inside a try conditional. */ 18943 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18944 || fcp->returned); 18945 } 18946 18947 /* 18948 * return TRUE if cookie indicates a function which "abort"s on errors. 18949 */ 18950 int 18951 func_has_abort(cookie) 18952 void *cookie; 18953 { 18954 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18955 } 18956 18957 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18958 typedef enum 18959 { 18960 VAR_FLAVOUR_DEFAULT, 18961 VAR_FLAVOUR_SESSION, 18962 VAR_FLAVOUR_VIMINFO 18963 } var_flavour_T; 18964 18965 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18966 18967 static var_flavour_T 18968 var_flavour(varname) 18969 char_u *varname; 18970 { 18971 char_u *p = varname; 18972 18973 if (ASCII_ISUPPER(*p)) 18974 { 18975 while (*(++p)) 18976 if (ASCII_ISLOWER(*p)) 18977 return VAR_FLAVOUR_SESSION; 18978 return VAR_FLAVOUR_VIMINFO; 18979 } 18980 else 18981 return VAR_FLAVOUR_DEFAULT; 18982 } 18983 #endif 18984 18985 #if defined(FEAT_VIMINFO) || defined(PROTO) 18986 /* 18987 * Restore global vars that start with a capital from the viminfo file 18988 */ 18989 int 18990 read_viminfo_varlist(virp, writing) 18991 vir_T *virp; 18992 int writing; 18993 { 18994 char_u *tab; 18995 int is_string = FALSE; 18996 typval_T tv; 18997 18998 if (!writing && (find_viminfo_parameter('!') != NULL)) 18999 { 19000 tab = vim_strchr(virp->vir_line + 1, '\t'); 19001 if (tab != NULL) 19002 { 19003 *tab++ = '\0'; /* isolate the variable name */ 19004 if (*tab == 'S') /* string var */ 19005 is_string = TRUE; 19006 19007 tab = vim_strchr(tab, '\t'); 19008 if (tab != NULL) 19009 { 19010 if (is_string) 19011 { 19012 tv.v_type = VAR_STRING; 19013 tv.vval.v_string = viminfo_readstring(virp, 19014 (int)(tab - virp->vir_line + 1), TRUE); 19015 } 19016 else 19017 { 19018 tv.v_type = VAR_NUMBER; 19019 tv.vval.v_number = atol((char *)tab + 1); 19020 } 19021 set_var(virp->vir_line + 1, &tv, FALSE); 19022 if (is_string) 19023 vim_free(tv.vval.v_string); 19024 } 19025 } 19026 } 19027 19028 return viminfo_readline(virp); 19029 } 19030 19031 /* 19032 * Write global vars that start with a capital to the viminfo file 19033 */ 19034 void 19035 write_viminfo_varlist(fp) 19036 FILE *fp; 19037 { 19038 hashitem_T *hi; 19039 dictitem_T *this_var; 19040 int todo; 19041 char *s; 19042 char_u *p; 19043 char_u *tofree; 19044 char_u numbuf[NUMBUFLEN]; 19045 19046 if (find_viminfo_parameter('!') == NULL) 19047 return; 19048 19049 fprintf(fp, _("\n# global variables:\n")); 19050 19051 todo = globvarht.ht_used; 19052 for (hi = globvarht.ht_array; todo > 0; ++hi) 19053 { 19054 if (!HASHITEM_EMPTY(hi)) 19055 { 19056 --todo; 19057 this_var = HI2DI(hi); 19058 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 19059 { 19060 switch (this_var->di_tv.v_type) 19061 { 19062 case VAR_STRING: s = "STR"; break; 19063 case VAR_NUMBER: s = "NUM"; break; 19064 default: continue; 19065 } 19066 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 19067 p = echo_string(&this_var->di_tv, &tofree, numbuf); 19068 if (p != NULL) 19069 viminfo_writestring(fp, p); 19070 vim_free(tofree); 19071 } 19072 } 19073 } 19074 } 19075 #endif 19076 19077 #if defined(FEAT_SESSION) || defined(PROTO) 19078 int 19079 store_session_globals(fd) 19080 FILE *fd; 19081 { 19082 hashitem_T *hi; 19083 dictitem_T *this_var; 19084 int todo; 19085 char_u *p, *t; 19086 19087 todo = globvarht.ht_used; 19088 for (hi = globvarht.ht_array; todo > 0; ++hi) 19089 { 19090 if (!HASHITEM_EMPTY(hi)) 19091 { 19092 --todo; 19093 this_var = HI2DI(hi); 19094 if ((this_var->di_tv.v_type == VAR_NUMBER 19095 || this_var->di_tv.v_type == VAR_STRING) 19096 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 19097 { 19098 /* Escape special characters with a backslash. Turn a LF and 19099 * CR into \n and \r. */ 19100 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 19101 (char_u *)"\\\"\n\r"); 19102 if (p == NULL) /* out of memory */ 19103 break; 19104 for (t = p; *t != NUL; ++t) 19105 if (*t == '\n') 19106 *t = 'n'; 19107 else if (*t == '\r') 19108 *t = 'r'; 19109 if ((fprintf(fd, "let %s = %c%s%c", 19110 this_var->di_key, 19111 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19112 : ' ', 19113 p, 19114 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19115 : ' ') < 0) 19116 || put_eol(fd) == FAIL) 19117 { 19118 vim_free(p); 19119 return FAIL; 19120 } 19121 vim_free(p); 19122 } 19123 } 19124 } 19125 return OK; 19126 } 19127 #endif 19128 19129 /* 19130 * Display script name where an item was last set. 19131 * Should only be invoked when 'verbose' is non-zero. 19132 */ 19133 void 19134 last_set_msg(scriptID) 19135 scid_T scriptID; 19136 { 19137 char_u *p; 19138 19139 if (scriptID != 0) 19140 { 19141 p = home_replace_save(NULL, get_scriptname(scriptID)); 19142 if (p != NULL) 19143 { 19144 verbose_enter(); 19145 MSG_PUTS(_("\n\tLast set from ")); 19146 MSG_PUTS(p); 19147 vim_free(p); 19148 verbose_leave(); 19149 } 19150 } 19151 } 19152 19153 #endif /* FEAT_EVAL */ 19154 19155 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 19156 19157 19158 #ifdef WIN3264 19159 /* 19160 * Functions for ":8" filename modifier: get 8.3 version of a filename. 19161 */ 19162 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19163 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 19164 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19165 19166 /* 19167 * Get the short pathname of a file. 19168 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 19169 */ 19170 static int 19171 get_short_pathname(fnamep, bufp, fnamelen) 19172 char_u **fnamep; 19173 char_u **bufp; 19174 int *fnamelen; 19175 { 19176 int l,len; 19177 char_u *newbuf; 19178 19179 len = *fnamelen; 19180 19181 l = GetShortPathName(*fnamep, *fnamep, len); 19182 if (l > len - 1) 19183 { 19184 /* If that doesn't work (not enough space), then save the string 19185 * and try again with a new buffer big enough 19186 */ 19187 newbuf = vim_strnsave(*fnamep, l); 19188 if (newbuf == NULL) 19189 return 0; 19190 19191 vim_free(*bufp); 19192 *fnamep = *bufp = newbuf; 19193 19194 l = GetShortPathName(*fnamep,*fnamep,l+1); 19195 19196 /* Really should always succeed, as the buffer is big enough */ 19197 } 19198 19199 *fnamelen = l; 19200 return 1; 19201 } 19202 19203 /* 19204 * Create a short path name. Returns the length of the buffer it needs. 19205 * Doesn't copy over the end of the buffer passed in. 19206 */ 19207 static int 19208 shortpath_for_invalid_fname(fname, bufp, fnamelen) 19209 char_u **fname; 19210 char_u **bufp; 19211 int *fnamelen; 19212 { 19213 char_u *s, *p, *pbuf2, *pbuf3; 19214 char_u ch; 19215 int len, len2, plen, slen; 19216 19217 /* Make a copy */ 19218 len2 = *fnamelen; 19219 pbuf2 = vim_strnsave(*fname, len2); 19220 pbuf3 = NULL; 19221 19222 s = pbuf2 + len2 - 1; /* Find the end */ 19223 slen = 1; 19224 plen = len2; 19225 19226 if (after_pathsep(pbuf2, s + 1)) 19227 { 19228 --s; 19229 ++slen; 19230 --plen; 19231 } 19232 19233 do 19234 { 19235 /* Go back one path-seperator */ 19236 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 19237 { 19238 --s; 19239 ++slen; 19240 --plen; 19241 } 19242 if (s <= pbuf2) 19243 break; 19244 19245 /* Remeber the character that is about to be blatted */ 19246 ch = *s; 19247 *s = 0; /* get_short_pathname requires a null-terminated string */ 19248 19249 /* Try it in situ */ 19250 p = pbuf2; 19251 if (!get_short_pathname(&p, &pbuf3, &plen)) 19252 { 19253 vim_free(pbuf2); 19254 return -1; 19255 } 19256 *s = ch; /* Preserve the string */ 19257 } while (plen == 0); 19258 19259 if (plen > 0) 19260 { 19261 /* Remeber the length of the new string. */ 19262 *fnamelen = len = plen + slen; 19263 vim_free(*bufp); 19264 if (len > len2) 19265 { 19266 /* If there's not enough space in the currently allocated string, 19267 * then copy it to a buffer big enough. 19268 */ 19269 *fname= *bufp = vim_strnsave(p, len); 19270 if (*fname == NULL) 19271 return -1; 19272 } 19273 else 19274 { 19275 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 19276 *fname = *bufp = pbuf2; 19277 if (p != pbuf2) 19278 strncpy(*fname, p, plen); 19279 pbuf2 = NULL; 19280 } 19281 /* Concat the next bit */ 19282 strncpy(*fname + plen, s, slen); 19283 (*fname)[len] = '\0'; 19284 } 19285 vim_free(pbuf3); 19286 vim_free(pbuf2); 19287 return 0; 19288 } 19289 19290 /* 19291 * Get a pathname for a partial path. 19292 */ 19293 static int 19294 shortpath_for_partial(fnamep, bufp, fnamelen) 19295 char_u **fnamep; 19296 char_u **bufp; 19297 int *fnamelen; 19298 { 19299 int sepcount, len, tflen; 19300 char_u *p; 19301 char_u *pbuf, *tfname; 19302 int hasTilde; 19303 19304 /* Count up the path seperators from the RHS.. so we know which part 19305 * of the path to return. 19306 */ 19307 sepcount = 0; 19308 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19309 if (vim_ispathsep(*p)) 19310 ++sepcount; 19311 19312 /* Need full path first (use expand_env() to remove a "~/") */ 19313 hasTilde = (**fnamep == '~'); 19314 if (hasTilde) 19315 pbuf = tfname = expand_env_save(*fnamep); 19316 else 19317 pbuf = tfname = FullName_save(*fnamep, FALSE); 19318 19319 len = tflen = STRLEN(tfname); 19320 19321 if (!get_short_pathname(&tfname, &pbuf, &len)) 19322 return -1; 19323 19324 if (len == 0) 19325 { 19326 /* Don't have a valid filename, so shorten the rest of the 19327 * path if we can. This CAN give us invalid 8.3 filenames, but 19328 * there's not a lot of point in guessing what it might be. 19329 */ 19330 len = tflen; 19331 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19332 return -1; 19333 } 19334 19335 /* Count the paths backward to find the beginning of the desired string. */ 19336 for (p = tfname + len - 1; p >= tfname; --p) 19337 { 19338 #ifdef FEAT_MBYTE 19339 if (has_mbyte) 19340 p -= mb_head_off(tfname, p); 19341 #endif 19342 if (vim_ispathsep(*p)) 19343 { 19344 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19345 break; 19346 else 19347 sepcount --; 19348 } 19349 } 19350 if (hasTilde) 19351 { 19352 --p; 19353 if (p >= tfname) 19354 *p = '~'; 19355 else 19356 return -1; 19357 } 19358 else 19359 ++p; 19360 19361 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19362 vim_free(*bufp); 19363 *fnamelen = (int)STRLEN(p); 19364 *bufp = pbuf; 19365 *fnamep = p; 19366 19367 return 0; 19368 } 19369 #endif /* WIN3264 */ 19370 19371 /* 19372 * Adjust a filename, according to a string of modifiers. 19373 * *fnamep must be NUL terminated when called. When returning, the length is 19374 * determined by *fnamelen. 19375 * Returns valid flags. 19376 * When there is an error, *fnamep is set to NULL. 19377 */ 19378 int 19379 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19380 char_u *src; /* string with modifiers */ 19381 int *usedlen; /* characters after src that are used */ 19382 char_u **fnamep; /* file name so far */ 19383 char_u **bufp; /* buffer for allocated file name or NULL */ 19384 int *fnamelen; /* length of fnamep */ 19385 { 19386 int valid = 0; 19387 char_u *tail; 19388 char_u *s, *p, *pbuf; 19389 char_u dirname[MAXPATHL]; 19390 int c; 19391 int has_fullname = 0; 19392 #ifdef WIN3264 19393 int has_shortname = 0; 19394 #endif 19395 19396 repeat: 19397 /* ":p" - full path/file_name */ 19398 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19399 { 19400 has_fullname = 1; 19401 19402 valid |= VALID_PATH; 19403 *usedlen += 2; 19404 19405 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19406 if ((*fnamep)[0] == '~' 19407 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19408 && ((*fnamep)[1] == '/' 19409 # ifdef BACKSLASH_IN_FILENAME 19410 || (*fnamep)[1] == '\\' 19411 # endif 19412 || (*fnamep)[1] == NUL) 19413 19414 #endif 19415 ) 19416 { 19417 *fnamep = expand_env_save(*fnamep); 19418 vim_free(*bufp); /* free any allocated file name */ 19419 *bufp = *fnamep; 19420 if (*fnamep == NULL) 19421 return -1; 19422 } 19423 19424 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19425 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19426 { 19427 if (vim_ispathsep(*p) 19428 && p[1] == '.' 19429 && (p[2] == NUL 19430 || vim_ispathsep(p[2]) 19431 || (p[2] == '.' 19432 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19433 break; 19434 } 19435 19436 /* FullName_save() is slow, don't use it when not needed. */ 19437 if (*p != NUL || !vim_isAbsName(*fnamep)) 19438 { 19439 *fnamep = FullName_save(*fnamep, *p != NUL); 19440 vim_free(*bufp); /* free any allocated file name */ 19441 *bufp = *fnamep; 19442 if (*fnamep == NULL) 19443 return -1; 19444 } 19445 19446 /* Append a path separator to a directory. */ 19447 if (mch_isdir(*fnamep)) 19448 { 19449 /* Make room for one or two extra characters. */ 19450 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19451 vim_free(*bufp); /* free any allocated file name */ 19452 *bufp = *fnamep; 19453 if (*fnamep == NULL) 19454 return -1; 19455 add_pathsep(*fnamep); 19456 } 19457 } 19458 19459 /* ":." - path relative to the current directory */ 19460 /* ":~" - path relative to the home directory */ 19461 /* ":8" - shortname path - postponed till after */ 19462 while (src[*usedlen] == ':' 19463 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19464 { 19465 *usedlen += 2; 19466 if (c == '8') 19467 { 19468 #ifdef WIN3264 19469 has_shortname = 1; /* Postpone this. */ 19470 #endif 19471 continue; 19472 } 19473 pbuf = NULL; 19474 /* Need full path first (use expand_env() to remove a "~/") */ 19475 if (!has_fullname) 19476 { 19477 if (c == '.' && **fnamep == '~') 19478 p = pbuf = expand_env_save(*fnamep); 19479 else 19480 p = pbuf = FullName_save(*fnamep, FALSE); 19481 } 19482 else 19483 p = *fnamep; 19484 19485 has_fullname = 0; 19486 19487 if (p != NULL) 19488 { 19489 if (c == '.') 19490 { 19491 mch_dirname(dirname, MAXPATHL); 19492 s = shorten_fname(p, dirname); 19493 if (s != NULL) 19494 { 19495 *fnamep = s; 19496 if (pbuf != NULL) 19497 { 19498 vim_free(*bufp); /* free any allocated file name */ 19499 *bufp = pbuf; 19500 pbuf = NULL; 19501 } 19502 } 19503 } 19504 else 19505 { 19506 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19507 /* Only replace it when it starts with '~' */ 19508 if (*dirname == '~') 19509 { 19510 s = vim_strsave(dirname); 19511 if (s != NULL) 19512 { 19513 *fnamep = s; 19514 vim_free(*bufp); 19515 *bufp = s; 19516 } 19517 } 19518 } 19519 vim_free(pbuf); 19520 } 19521 } 19522 19523 tail = gettail(*fnamep); 19524 *fnamelen = (int)STRLEN(*fnamep); 19525 19526 /* ":h" - head, remove "/file_name", can be repeated */ 19527 /* Don't remove the first "/" or "c:\" */ 19528 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19529 { 19530 valid |= VALID_HEAD; 19531 *usedlen += 2; 19532 s = get_past_head(*fnamep); 19533 while (tail > s && after_pathsep(s, tail)) 19534 --tail; 19535 *fnamelen = (int)(tail - *fnamep); 19536 #ifdef VMS 19537 if (*fnamelen > 0) 19538 *fnamelen += 1; /* the path separator is part of the path */ 19539 #endif 19540 while (tail > s && !after_pathsep(s, tail)) 19541 mb_ptr_back(*fnamep, tail); 19542 } 19543 19544 /* ":8" - shortname */ 19545 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19546 { 19547 *usedlen += 2; 19548 #ifdef WIN3264 19549 has_shortname = 1; 19550 #endif 19551 } 19552 19553 #ifdef WIN3264 19554 /* Check shortname after we have done 'heads' and before we do 'tails' 19555 */ 19556 if (has_shortname) 19557 { 19558 pbuf = NULL; 19559 /* Copy the string if it is shortened by :h */ 19560 if (*fnamelen < (int)STRLEN(*fnamep)) 19561 { 19562 p = vim_strnsave(*fnamep, *fnamelen); 19563 if (p == 0) 19564 return -1; 19565 vim_free(*bufp); 19566 *bufp = *fnamep = p; 19567 } 19568 19569 /* Split into two implementations - makes it easier. First is where 19570 * there isn't a full name already, second is where there is. 19571 */ 19572 if (!has_fullname && !vim_isAbsName(*fnamep)) 19573 { 19574 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19575 return -1; 19576 } 19577 else 19578 { 19579 int l; 19580 19581 /* Simple case, already have the full-name 19582 * Nearly always shorter, so try first time. */ 19583 l = *fnamelen; 19584 if (!get_short_pathname(fnamep, bufp, &l)) 19585 return -1; 19586 19587 if (l == 0) 19588 { 19589 /* Couldn't find the filename.. search the paths. 19590 */ 19591 l = *fnamelen; 19592 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19593 return -1; 19594 } 19595 *fnamelen = l; 19596 } 19597 } 19598 #endif /* WIN3264 */ 19599 19600 /* ":t" - tail, just the basename */ 19601 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19602 { 19603 *usedlen += 2; 19604 *fnamelen -= (int)(tail - *fnamep); 19605 *fnamep = tail; 19606 } 19607 19608 /* ":e" - extension, can be repeated */ 19609 /* ":r" - root, without extension, can be repeated */ 19610 while (src[*usedlen] == ':' 19611 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19612 { 19613 /* find a '.' in the tail: 19614 * - for second :e: before the current fname 19615 * - otherwise: The last '.' 19616 */ 19617 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19618 s = *fnamep - 2; 19619 else 19620 s = *fnamep + *fnamelen - 1; 19621 for ( ; s > tail; --s) 19622 if (s[0] == '.') 19623 break; 19624 if (src[*usedlen + 1] == 'e') /* :e */ 19625 { 19626 if (s > tail) 19627 { 19628 *fnamelen += (int)(*fnamep - (s + 1)); 19629 *fnamep = s + 1; 19630 #ifdef VMS 19631 /* cut version from the extension */ 19632 s = *fnamep + *fnamelen - 1; 19633 for ( ; s > *fnamep; --s) 19634 if (s[0] == ';') 19635 break; 19636 if (s > *fnamep) 19637 *fnamelen = s - *fnamep; 19638 #endif 19639 } 19640 else if (*fnamep <= tail) 19641 *fnamelen = 0; 19642 } 19643 else /* :r */ 19644 { 19645 if (s > tail) /* remove one extension */ 19646 *fnamelen = (int)(s - *fnamep); 19647 } 19648 *usedlen += 2; 19649 } 19650 19651 /* ":s?pat?foo?" - substitute */ 19652 /* ":gs?pat?foo?" - global substitute */ 19653 if (src[*usedlen] == ':' 19654 && (src[*usedlen + 1] == 's' 19655 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19656 { 19657 char_u *str; 19658 char_u *pat; 19659 char_u *sub; 19660 int sep; 19661 char_u *flags; 19662 int didit = FALSE; 19663 19664 flags = (char_u *)""; 19665 s = src + *usedlen + 2; 19666 if (src[*usedlen + 1] == 'g') 19667 { 19668 flags = (char_u *)"g"; 19669 ++s; 19670 } 19671 19672 sep = *s++; 19673 if (sep) 19674 { 19675 /* find end of pattern */ 19676 p = vim_strchr(s, sep); 19677 if (p != NULL) 19678 { 19679 pat = vim_strnsave(s, (int)(p - s)); 19680 if (pat != NULL) 19681 { 19682 s = p + 1; 19683 /* find end of substitution */ 19684 p = vim_strchr(s, sep); 19685 if (p != NULL) 19686 { 19687 sub = vim_strnsave(s, (int)(p - s)); 19688 str = vim_strnsave(*fnamep, *fnamelen); 19689 if (sub != NULL && str != NULL) 19690 { 19691 *usedlen = (int)(p + 1 - src); 19692 s = do_string_sub(str, pat, sub, flags); 19693 if (s != NULL) 19694 { 19695 *fnamep = s; 19696 *fnamelen = (int)STRLEN(s); 19697 vim_free(*bufp); 19698 *bufp = s; 19699 didit = TRUE; 19700 } 19701 } 19702 vim_free(sub); 19703 vim_free(str); 19704 } 19705 vim_free(pat); 19706 } 19707 } 19708 /* after using ":s", repeat all the modifiers */ 19709 if (didit) 19710 goto repeat; 19711 } 19712 } 19713 19714 return valid; 19715 } 19716 19717 /* 19718 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19719 * "flags" can be "g" to do a global substitute. 19720 * Returns an allocated string, NULL for error. 19721 */ 19722 char_u * 19723 do_string_sub(str, pat, sub, flags) 19724 char_u *str; 19725 char_u *pat; 19726 char_u *sub; 19727 char_u *flags; 19728 { 19729 int sublen; 19730 regmatch_T regmatch; 19731 int i; 19732 int do_all; 19733 char_u *tail; 19734 garray_T ga; 19735 char_u *ret; 19736 char_u *save_cpo; 19737 19738 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19739 save_cpo = p_cpo; 19740 p_cpo = (char_u *)""; 19741 19742 ga_init2(&ga, 1, 200); 19743 19744 do_all = (flags[0] == 'g'); 19745 19746 regmatch.rm_ic = p_ic; 19747 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19748 if (regmatch.regprog != NULL) 19749 { 19750 tail = str; 19751 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19752 { 19753 /* 19754 * Get some space for a temporary buffer to do the substitution 19755 * into. It will contain: 19756 * - The text up to where the match is. 19757 * - The substituted text. 19758 * - The text after the match. 19759 */ 19760 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19761 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19762 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19763 { 19764 ga_clear(&ga); 19765 break; 19766 } 19767 19768 /* copy the text up to where the match is */ 19769 i = (int)(regmatch.startp[0] - tail); 19770 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19771 /* add the substituted text */ 19772 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19773 + ga.ga_len + i, TRUE, TRUE, FALSE); 19774 ga.ga_len += i + sublen - 1; 19775 /* avoid getting stuck on a match with an empty string */ 19776 if (tail == regmatch.endp[0]) 19777 { 19778 if (*tail == NUL) 19779 break; 19780 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19781 ++ga.ga_len; 19782 } 19783 else 19784 { 19785 tail = regmatch.endp[0]; 19786 if (*tail == NUL) 19787 break; 19788 } 19789 if (!do_all) 19790 break; 19791 } 19792 19793 if (ga.ga_data != NULL) 19794 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19795 19796 vim_free(regmatch.regprog); 19797 } 19798 19799 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19800 ga_clear(&ga); 19801 p_cpo = save_cpo; 19802 19803 return ret; 19804 } 19805 19806 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19807