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 }; 341 342 /* shorthand */ 343 #define vv_type vv_di.di_tv.v_type 344 #define vv_nr vv_di.di_tv.vval.v_number 345 #define vv_str vv_di.di_tv.vval.v_string 346 #define vv_tv vv_di.di_tv 347 348 /* 349 * The v: variables are stored in dictionary "vimvardict". 350 * "vimvars_var" is the variable that is used for the "l:" scope. 351 */ 352 static dict_T vimvardict; 353 static dictitem_T vimvars_var; 354 #define vimvarht vimvardict.dv_hashtab 355 356 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 357 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 358 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 359 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 360 #endif 361 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 362 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 363 static char_u *skip_var_one __ARGS((char_u *arg)); 364 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 365 static void list_glob_vars __ARGS((void)); 366 static void list_buf_vars __ARGS((void)); 367 static void list_win_vars __ARGS((void)); 368 static void list_vim_vars __ARGS((void)); 369 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 370 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 371 static int check_changedtick __ARGS((char_u *arg)); 372 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 373 static void clear_lval __ARGS((lval_T *lp)); 374 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 375 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 376 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 377 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 378 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 379 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 380 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 381 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 382 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 383 static int tv_islocked __ARGS((typval_T *tv)); 384 385 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 386 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 387 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 388 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 389 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 390 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 391 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 392 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 393 394 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 395 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 396 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 397 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 398 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 399 static list_T *list_alloc __ARGS((void)); 400 static void list_free __ARGS((list_T *l)); 401 static listitem_T *listitem_alloc __ARGS((void)); 402 static void listitem_free __ARGS((listitem_T *item)); 403 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 404 static long list_len __ARGS((list_T *l)); 405 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 406 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 407 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 408 static listitem_T *list_find __ARGS((list_T *l, long n)); 409 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 410 static void list_append __ARGS((list_T *l, listitem_T *item)); 411 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 412 static int list_append_string __ARGS((list_T *l, char_u *str)); 413 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 414 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 415 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 416 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 417 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 418 static char_u *list2string __ARGS((typval_T *tv)); 419 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); 420 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 421 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 422 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 423 static void dict_unref __ARGS((dict_T *d)); 424 static void dict_free __ARGS((dict_T *d)); 425 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 426 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 427 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 428 static void dictitem_free __ARGS((dictitem_T *item)); 429 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 430 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 431 static long dict_len __ARGS((dict_T *d)); 432 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 433 static char_u *dict2string __ARGS((typval_T *tv)); 434 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 435 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 436 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 437 static char_u *string_quote __ARGS((char_u *str, int function)); 438 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 439 static int find_internal_func __ARGS((char_u *name)); 440 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 441 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)); 442 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)); 443 static void emsg_funcname __ARGS((char *msg, char_u *name)); 444 445 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 446 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 447 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 448 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 449 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 450 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 464 #if defined(FEAT_INS_EXPAND) 465 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 467 #endif 468 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 469 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 473 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 564 #ifdef vim_mkdir 565 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 566 #endif 567 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 601 #ifdef HAVE_STRFTIME 602 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 603 #endif 604 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 635 636 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 637 static int get_env_len __ARGS((char_u **arg)); 638 static int get_id_len __ARGS((char_u **arg)); 639 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 640 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 641 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 642 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 643 valid character */ 644 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 645 static int eval_isnamec __ARGS((int c)); 646 static int eval_isnamec1 __ARGS((int c)); 647 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 648 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 649 static typval_T *alloc_tv __ARGS((void)); 650 static typval_T *alloc_string_tv __ARGS((char_u *string)); 651 static void free_tv __ARGS((typval_T *varp)); 652 static void init_tv __ARGS((typval_T *varp)); 653 static long get_tv_number __ARGS((typval_T *varp)); 654 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 655 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 656 static char_u *get_tv_string __ARGS((typval_T *varp)); 657 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 658 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 659 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 660 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 661 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 662 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 663 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 664 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 665 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 666 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 667 static int var_check_ro __ARGS((int flags, char_u *name)); 668 static int tv_check_lock __ARGS((int lock, char_u *name)); 669 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 670 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 671 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 672 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 673 static int eval_fname_script __ARGS((char_u *p)); 674 static int eval_fname_sid __ARGS((char_u *p)); 675 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 676 static ufunc_T *find_func __ARGS((char_u *name)); 677 static int function_exists __ARGS((char_u *name)); 678 static int builtin_function __ARGS((char_u *name)); 679 #ifdef FEAT_PROFILE 680 static void func_do_profile __ARGS((ufunc_T *fp)); 681 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 682 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 683 static int 684 # ifdef __BORLANDC__ 685 _RTLENTRYF 686 # endif 687 prof_total_cmp __ARGS((const void *s1, const void *s2)); 688 static int 689 # ifdef __BORLANDC__ 690 _RTLENTRYF 691 # endif 692 prof_self_cmp __ARGS((const void *s1, const void *s2)); 693 #endif 694 static int script_autoload __ARGS((char_u *name, int reload)); 695 static char_u *autoload_name __ARGS((char_u *name)); 696 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 697 static void func_free __ARGS((ufunc_T *fp)); 698 static void func_unref __ARGS((char_u *name)); 699 static void func_ref __ARGS((char_u *name)); 700 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)); 701 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 702 703 /* Character used as separated in autoload function/variable names. */ 704 #define AUTOLOAD_CHAR '#' 705 706 /* 707 * Initialize the global and v: variables. 708 */ 709 void 710 eval_init() 711 { 712 int i; 713 struct vimvar *p; 714 715 init_var_dict(&globvardict, &globvars_var); 716 init_var_dict(&vimvardict, &vimvars_var); 717 hash_init(&compat_hashtab); 718 hash_init(&func_hashtab); 719 720 for (i = 0; i < VV_LEN; ++i) 721 { 722 p = &vimvars[i]; 723 STRCPY(p->vv_di.di_key, p->vv_name); 724 if (p->vv_flags & VV_RO) 725 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 726 else if (p->vv_flags & VV_RO_SBX) 727 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 728 else 729 p->vv_di.di_flags = DI_FLAGS_FIX; 730 731 /* add to v: scope dict, unless the value is not always available */ 732 if (p->vv_type != VAR_UNKNOWN) 733 hash_add(&vimvarht, p->vv_di.di_key); 734 if (p->vv_flags & VV_COMPAT) 735 /* add to compat scope dict */ 736 hash_add(&compat_hashtab, p->vv_di.di_key); 737 } 738 } 739 740 #if defined(EXITFREE) || defined(PROTO) 741 void 742 eval_clear() 743 { 744 int i; 745 struct vimvar *p; 746 747 for (i = 0; i < VV_LEN; ++i) 748 { 749 p = &vimvars[i]; 750 if (p->vv_di.di_tv.v_type == VAR_STRING) 751 { 752 vim_free(p->vv_di.di_tv.vval.v_string); 753 p->vv_di.di_tv.vval.v_string = NULL; 754 } 755 } 756 hash_clear(&vimvarht); 757 hash_clear(&compat_hashtab); 758 759 /* script-local variables */ 760 for (i = 1; i <= ga_scripts.ga_len; ++i) 761 vars_clear(&SCRIPT_VARS(i)); 762 ga_clear(&ga_scripts); 763 free_scriptnames(); 764 765 /* global variables */ 766 vars_clear(&globvarht); 767 768 /* functions */ 769 free_all_functions(); 770 hash_clear(&func_hashtab); 771 772 /* unreferenced lists and dicts */ 773 (void)garbage_collect(); 774 } 775 #endif 776 777 /* 778 * Return the name of the executed function. 779 */ 780 char_u * 781 func_name(cookie) 782 void *cookie; 783 { 784 return ((funccall_T *)cookie)->func->uf_name; 785 } 786 787 /* 788 * Return the address holding the next breakpoint line for a funccall cookie. 789 */ 790 linenr_T * 791 func_breakpoint(cookie) 792 void *cookie; 793 { 794 return &((funccall_T *)cookie)->breakpoint; 795 } 796 797 /* 798 * Return the address holding the debug tick for a funccall cookie. 799 */ 800 int * 801 func_dbg_tick(cookie) 802 void *cookie; 803 { 804 return &((funccall_T *)cookie)->dbg_tick; 805 } 806 807 /* 808 * Return the nesting level for a funccall cookie. 809 */ 810 int 811 func_level(cookie) 812 void *cookie; 813 { 814 return ((funccall_T *)cookie)->level; 815 } 816 817 /* pointer to funccal for currently active function */ 818 funccall_T *current_funccal = NULL; 819 820 /* 821 * Return TRUE when a function was ended by a ":return" command. 822 */ 823 int 824 current_func_returned() 825 { 826 return current_funccal->returned; 827 } 828 829 830 /* 831 * Set an internal variable to a string value. Creates the variable if it does 832 * not already exist. 833 */ 834 void 835 set_internal_string_var(name, value) 836 char_u *name; 837 char_u *value; 838 { 839 char_u *val; 840 typval_T *tvp; 841 842 val = vim_strsave(value); 843 if (val != NULL) 844 { 845 tvp = alloc_string_tv(val); 846 if (tvp != NULL) 847 { 848 set_var(name, tvp, FALSE); 849 free_tv(tvp); 850 } 851 } 852 } 853 854 static lval_T *redir_lval = NULL; 855 static char_u *redir_endp = NULL; 856 static char_u *redir_varname = NULL; 857 858 /* 859 * Start recording command output to a variable 860 * Returns OK if successfully completed the setup. FAIL otherwise. 861 */ 862 int 863 var_redir_start(name, append) 864 char_u *name; 865 int append; /* append to an existing variable */ 866 { 867 int save_emsg; 868 int err; 869 typval_T tv; 870 871 /* Make sure a valid variable name is specified */ 872 if (!eval_isnamec1(*name)) 873 { 874 EMSG(_(e_invarg)); 875 return FAIL; 876 } 877 878 redir_varname = vim_strsave(name); 879 if (redir_varname == NULL) 880 return FAIL; 881 882 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 883 if (redir_lval == NULL) 884 { 885 var_redir_stop(); 886 return FAIL; 887 } 888 889 /* Parse the variable name (can be a dict or list entry). */ 890 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 891 FNE_CHECK_START); 892 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 893 { 894 if (redir_endp != NULL && *redir_endp != NUL) 895 /* Trailing characters are present after the variable name */ 896 EMSG(_(e_trailing)); 897 else 898 EMSG(_(e_invarg)); 899 var_redir_stop(); 900 return FAIL; 901 } 902 903 /* check if we can write to the variable: set it to or append an empty 904 * string */ 905 save_emsg = did_emsg; 906 did_emsg = FALSE; 907 tv.v_type = VAR_STRING; 908 tv.vval.v_string = (char_u *)""; 909 if (append) 910 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 911 else 912 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 913 err = did_emsg; 914 did_emsg += save_emsg; 915 if (err) 916 { 917 var_redir_stop(); 918 return FAIL; 919 } 920 if (redir_lval->ll_newkey != NULL) 921 { 922 /* Dictionary item was created, don't do it again. */ 923 vim_free(redir_lval->ll_newkey); 924 redir_lval->ll_newkey = NULL; 925 } 926 927 return OK; 928 } 929 930 /* 931 * Append "value[len]" to the variable set by var_redir_start(). 932 */ 933 void 934 var_redir_str(value, len) 935 char_u *value; 936 int len; 937 { 938 char_u *val; 939 typval_T tv; 940 int save_emsg; 941 int err; 942 943 if (redir_lval == NULL) 944 return; 945 946 if (len == -1) 947 /* Append the entire string */ 948 val = vim_strsave(value); 949 else 950 /* Append only the specified number of characters */ 951 val = vim_strnsave(value, len); 952 if (val == NULL) 953 return; 954 955 tv.v_type = VAR_STRING; 956 tv.vval.v_string = val; 957 958 save_emsg = did_emsg; 959 did_emsg = FALSE; 960 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 961 err = did_emsg; 962 did_emsg += save_emsg; 963 if (err) 964 var_redir_stop(); 965 966 vim_free(tv.vval.v_string); 967 } 968 969 /* 970 * Stop redirecting command output to a variable. 971 */ 972 void 973 var_redir_stop() 974 { 975 if (redir_lval != NULL) 976 { 977 clear_lval(redir_lval); 978 vim_free(redir_lval); 979 redir_lval = NULL; 980 } 981 vim_free(redir_varname); 982 redir_varname = NULL; 983 } 984 985 # if defined(FEAT_MBYTE) || defined(PROTO) 986 int 987 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 988 char_u *enc_from; 989 char_u *enc_to; 990 char_u *fname_from; 991 char_u *fname_to; 992 { 993 int err = FALSE; 994 995 set_vim_var_string(VV_CC_FROM, enc_from, -1); 996 set_vim_var_string(VV_CC_TO, enc_to, -1); 997 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 998 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 999 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1000 err = TRUE; 1001 set_vim_var_string(VV_CC_FROM, NULL, -1); 1002 set_vim_var_string(VV_CC_TO, NULL, -1); 1003 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1004 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1005 1006 if (err) 1007 return FAIL; 1008 return OK; 1009 } 1010 # endif 1011 1012 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1013 int 1014 eval_printexpr(fname, args) 1015 char_u *fname; 1016 char_u *args; 1017 { 1018 int err = FALSE; 1019 1020 set_vim_var_string(VV_FNAME_IN, fname, -1); 1021 set_vim_var_string(VV_CMDARG, args, -1); 1022 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1023 err = TRUE; 1024 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1025 set_vim_var_string(VV_CMDARG, NULL, -1); 1026 1027 if (err) 1028 { 1029 mch_remove(fname); 1030 return FAIL; 1031 } 1032 return OK; 1033 } 1034 # endif 1035 1036 # if defined(FEAT_DIFF) || defined(PROTO) 1037 void 1038 eval_diff(origfile, newfile, outfile) 1039 char_u *origfile; 1040 char_u *newfile; 1041 char_u *outfile; 1042 { 1043 int err = FALSE; 1044 1045 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1046 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1047 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1048 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1049 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1050 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1051 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1052 } 1053 1054 void 1055 eval_patch(origfile, difffile, outfile) 1056 char_u *origfile; 1057 char_u *difffile; 1058 char_u *outfile; 1059 { 1060 int err; 1061 1062 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1063 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1064 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1065 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1066 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1067 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1068 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1069 } 1070 # endif 1071 1072 /* 1073 * Top level evaluation function, returning a boolean. 1074 * Sets "error" to TRUE if there was an error. 1075 * Return TRUE or FALSE. 1076 */ 1077 int 1078 eval_to_bool(arg, error, nextcmd, skip) 1079 char_u *arg; 1080 int *error; 1081 char_u **nextcmd; 1082 int skip; /* only parse, don't execute */ 1083 { 1084 typval_T tv; 1085 int retval = FALSE; 1086 1087 if (skip) 1088 ++emsg_skip; 1089 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1090 *error = TRUE; 1091 else 1092 { 1093 *error = FALSE; 1094 if (!skip) 1095 { 1096 retval = (get_tv_number_chk(&tv, error) != 0); 1097 clear_tv(&tv); 1098 } 1099 } 1100 if (skip) 1101 --emsg_skip; 1102 1103 return retval; 1104 } 1105 1106 /* 1107 * Top level evaluation function, returning a string. If "skip" is TRUE, 1108 * only parsing to "nextcmd" is done, without reporting errors. Return 1109 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1110 */ 1111 char_u * 1112 eval_to_string_skip(arg, nextcmd, skip) 1113 char_u *arg; 1114 char_u **nextcmd; 1115 int skip; /* only parse, don't execute */ 1116 { 1117 typval_T tv; 1118 char_u *retval; 1119 1120 if (skip) 1121 ++emsg_skip; 1122 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1123 retval = NULL; 1124 else 1125 { 1126 retval = vim_strsave(get_tv_string(&tv)); 1127 clear_tv(&tv); 1128 } 1129 if (skip) 1130 --emsg_skip; 1131 1132 return retval; 1133 } 1134 1135 /* 1136 * Skip over an expression at "*pp". 1137 * Return FAIL for an error, OK otherwise. 1138 */ 1139 int 1140 skip_expr(pp) 1141 char_u **pp; 1142 { 1143 typval_T rettv; 1144 1145 *pp = skipwhite(*pp); 1146 return eval1(pp, &rettv, FALSE); 1147 } 1148 1149 /* 1150 * Top level evaluation function, returning a string. 1151 * Return pointer to allocated memory, or NULL for failure. 1152 */ 1153 char_u * 1154 eval_to_string(arg, nextcmd) 1155 char_u *arg; 1156 char_u **nextcmd; 1157 { 1158 typval_T tv; 1159 char_u *retval; 1160 1161 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1162 retval = NULL; 1163 else 1164 { 1165 retval = vim_strsave(get_tv_string(&tv)); 1166 clear_tv(&tv); 1167 } 1168 1169 return retval; 1170 } 1171 1172 /* 1173 * Call eval_to_string() with "sandbox" set and not using local variables. 1174 */ 1175 char_u * 1176 eval_to_string_safe(arg, nextcmd) 1177 char_u *arg; 1178 char_u **nextcmd; 1179 { 1180 char_u *retval; 1181 void *save_funccalp; 1182 1183 save_funccalp = save_funccal(); 1184 ++sandbox; 1185 retval = eval_to_string(arg, nextcmd); 1186 --sandbox; 1187 restore_funccal(save_funccalp); 1188 return retval; 1189 } 1190 1191 /* 1192 * Top level evaluation function, returning a number. 1193 * Evaluates "expr" silently. 1194 * Returns -1 for an error. 1195 */ 1196 int 1197 eval_to_number(expr) 1198 char_u *expr; 1199 { 1200 typval_T rettv; 1201 int retval; 1202 char_u *p = skipwhite(expr); 1203 1204 ++emsg_off; 1205 1206 if (eval1(&p, &rettv, TRUE) == FAIL) 1207 retval = -1; 1208 else 1209 { 1210 retval = get_tv_number_chk(&rettv, NULL); 1211 clear_tv(&rettv); 1212 } 1213 --emsg_off; 1214 1215 return retval; 1216 } 1217 1218 /* 1219 * Prepare v: variable "idx" to be used. 1220 * Save the current typeval in "save_tv". 1221 * When not used yet add the variable to the v: hashtable. 1222 */ 1223 static void 1224 prepare_vimvar(idx, save_tv) 1225 int idx; 1226 typval_T *save_tv; 1227 { 1228 *save_tv = vimvars[idx].vv_tv; 1229 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1230 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1231 } 1232 1233 /* 1234 * Restore v: variable "idx" to typeval "save_tv". 1235 * When no longer defined, remove the variable from the v: hashtable. 1236 */ 1237 static void 1238 restore_vimvar(idx, save_tv) 1239 int idx; 1240 typval_T *save_tv; 1241 { 1242 hashitem_T *hi; 1243 1244 clear_tv(&vimvars[idx].vv_tv); 1245 vimvars[idx].vv_tv = *save_tv; 1246 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1247 { 1248 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1249 if (HASHITEM_EMPTY(hi)) 1250 EMSG2(_(e_intern2), "restore_vimvar()"); 1251 else 1252 hash_remove(&vimvarht, hi); 1253 } 1254 } 1255 1256 #if defined(FEAT_SYN_HL) || defined(PROTO) 1257 /* 1258 * Evaluate an expression to a list with suggestions. 1259 * For the "expr:" part of 'spellsuggest'. 1260 */ 1261 list_T * 1262 eval_spell_expr(badword, expr) 1263 char_u *badword; 1264 char_u *expr; 1265 { 1266 typval_T save_val; 1267 typval_T rettv; 1268 list_T *list = NULL; 1269 char_u *p = skipwhite(expr); 1270 1271 /* Set "v:val" to the bad word. */ 1272 prepare_vimvar(VV_VAL, &save_val); 1273 vimvars[VV_VAL].vv_type = VAR_STRING; 1274 vimvars[VV_VAL].vv_str = badword; 1275 if (p_verbose == 0) 1276 ++emsg_off; 1277 1278 if (eval1(&p, &rettv, TRUE) == OK) 1279 { 1280 if (rettv.v_type != VAR_LIST) 1281 clear_tv(&rettv); 1282 else 1283 list = rettv.vval.v_list; 1284 } 1285 1286 if (p_verbose == 0) 1287 --emsg_off; 1288 vimvars[VV_VAL].vv_str = NULL; 1289 restore_vimvar(VV_VAL, &save_val); 1290 1291 return list; 1292 } 1293 1294 /* 1295 * "list" is supposed to contain two items: a word and a number. Return the 1296 * word in "pp" and the number as the return value. 1297 * Return -1 if anything isn't right. 1298 * Used to get the good word and score from the eval_spell_expr() result. 1299 */ 1300 int 1301 get_spellword(list, pp) 1302 list_T *list; 1303 char_u **pp; 1304 { 1305 listitem_T *li; 1306 1307 li = list->lv_first; 1308 if (li == NULL) 1309 return -1; 1310 *pp = get_tv_string(&li->li_tv); 1311 1312 li = li->li_next; 1313 if (li == NULL) 1314 return -1; 1315 return get_tv_number(&li->li_tv); 1316 } 1317 #endif 1318 1319 /* 1320 * Top level evaluation function, 1321 */ 1322 typval_T * 1323 eval_expr(arg, nextcmd) 1324 char_u *arg; 1325 char_u **nextcmd; 1326 { 1327 typval_T *tv; 1328 1329 tv = (typval_T *)alloc(sizeof(typval_T)); 1330 if (!tv) 1331 return NULL; 1332 1333 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1334 { 1335 vim_free(tv); 1336 return NULL; 1337 } 1338 1339 return tv; 1340 } 1341 1342 1343 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1344 /* 1345 * Call some vimL function and return the result in "*rettv". 1346 * Uses argv[argc] for the function arguments. 1347 * Returns OK or FAIL. 1348 */ 1349 static int 1350 call_vim_function(func, argc, argv, safe, rettv) 1351 char_u *func; 1352 int argc; 1353 char_u **argv; 1354 int safe; /* use the sandbox */ 1355 typval_T *rettv; 1356 { 1357 typval_T *argvars; 1358 long n; 1359 int len; 1360 int i; 1361 int doesrange; 1362 void *save_funccalp = NULL; 1363 int ret; 1364 1365 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1366 if (argvars == NULL) 1367 return FAIL; 1368 1369 for (i = 0; i < argc; i++) 1370 { 1371 /* Pass a NULL or empty argument as an empty string */ 1372 if (argv[i] == NULL || *argv[i] == NUL) 1373 { 1374 argvars[i].v_type = VAR_STRING; 1375 argvars[i].vval.v_string = (char_u *)""; 1376 continue; 1377 } 1378 1379 /* Recognize a number argument, the others must be strings. */ 1380 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1381 if (len != 0 && len == (int)STRLEN(argv[i])) 1382 { 1383 argvars[i].v_type = VAR_NUMBER; 1384 argvars[i].vval.v_number = n; 1385 } 1386 else 1387 { 1388 argvars[i].v_type = VAR_STRING; 1389 argvars[i].vval.v_string = argv[i]; 1390 } 1391 } 1392 1393 if (safe) 1394 { 1395 save_funccalp = save_funccal(); 1396 ++sandbox; 1397 } 1398 1399 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1400 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1401 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1402 &doesrange, TRUE, NULL); 1403 if (safe) 1404 { 1405 --sandbox; 1406 restore_funccal(save_funccalp); 1407 } 1408 vim_free(argvars); 1409 1410 if (ret == FAIL) 1411 clear_tv(rettv); 1412 1413 return ret; 1414 } 1415 1416 /* 1417 * Call vimL function "func" and return the result as a string. 1418 * Returns NULL when calling the function fails. 1419 * Uses argv[argc] for the function arguments. 1420 */ 1421 void * 1422 call_func_retstr(func, argc, argv, safe) 1423 char_u *func; 1424 int argc; 1425 char_u **argv; 1426 int safe; /* use the sandbox */ 1427 { 1428 typval_T rettv; 1429 char_u *retval; 1430 1431 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1432 return NULL; 1433 1434 retval = vim_strsave(get_tv_string(&rettv)); 1435 clear_tv(&rettv); 1436 return retval; 1437 } 1438 1439 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1440 /* 1441 * Call vimL function "func" and return the result as a number. 1442 * Returns -1 when calling the function fails. 1443 * Uses argv[argc] for the function arguments. 1444 */ 1445 long 1446 call_func_retnr(func, argc, argv, safe) 1447 char_u *func; 1448 int argc; 1449 char_u **argv; 1450 int safe; /* use the sandbox */ 1451 { 1452 typval_T rettv; 1453 long retval; 1454 1455 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1456 return -1; 1457 1458 retval = get_tv_number_chk(&rettv, NULL); 1459 clear_tv(&rettv); 1460 return retval; 1461 } 1462 #endif 1463 1464 /* 1465 * Call vimL function "func" and return the result as a list 1466 * Uses argv[argc] for the function arguments. 1467 */ 1468 void * 1469 call_func_retlist(func, argc, argv, safe) 1470 char_u *func; 1471 int argc; 1472 char_u **argv; 1473 int safe; /* use the sandbox */ 1474 { 1475 typval_T rettv; 1476 1477 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1478 return NULL; 1479 1480 if (rettv.v_type != VAR_LIST) 1481 { 1482 clear_tv(&rettv); 1483 return NULL; 1484 } 1485 1486 return rettv.vval.v_list; 1487 } 1488 1489 #endif 1490 1491 /* 1492 * Save the current function call pointer, and set it to NULL. 1493 * Used when executing autocommands and for ":source". 1494 */ 1495 void * 1496 save_funccal() 1497 { 1498 funccall_T *fc = current_funccal; 1499 1500 current_funccal = NULL; 1501 return (void *)fc; 1502 } 1503 1504 void 1505 restore_funccal(vfc) 1506 void *vfc; 1507 { 1508 funccall_T *fc = (funccall_T *)vfc; 1509 1510 current_funccal = fc; 1511 } 1512 1513 #if defined(FEAT_PROFILE) || defined(PROTO) 1514 /* 1515 * Prepare profiling for entering a child or something else that is not 1516 * counted for the script/function itself. 1517 * Should always be called in pair with prof_child_exit(). 1518 */ 1519 void 1520 prof_child_enter(tm) 1521 proftime_T *tm; /* place to store waittime */ 1522 { 1523 funccall_T *fc = current_funccal; 1524 1525 if (fc != NULL && fc->func->uf_profiling) 1526 profile_start(&fc->prof_child); 1527 script_prof_save(tm); 1528 } 1529 1530 /* 1531 * Take care of time spent in a child. 1532 * Should always be called after prof_child_enter(). 1533 */ 1534 void 1535 prof_child_exit(tm) 1536 proftime_T *tm; /* where waittime was stored */ 1537 { 1538 funccall_T *fc = current_funccal; 1539 1540 if (fc != NULL && fc->func->uf_profiling) 1541 { 1542 profile_end(&fc->prof_child); 1543 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1544 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1545 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1546 } 1547 script_prof_restore(tm); 1548 } 1549 #endif 1550 1551 1552 #ifdef FEAT_FOLDING 1553 /* 1554 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1555 * it in "*cp". Doesn't give error messages. 1556 */ 1557 int 1558 eval_foldexpr(arg, cp) 1559 char_u *arg; 1560 int *cp; 1561 { 1562 typval_T tv; 1563 int retval; 1564 char_u *s; 1565 1566 ++emsg_off; 1567 ++sandbox; 1568 *cp = NUL; 1569 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1570 retval = 0; 1571 else 1572 { 1573 /* If the result is a number, just return the number. */ 1574 if (tv.v_type == VAR_NUMBER) 1575 retval = tv.vval.v_number; 1576 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1577 retval = 0; 1578 else 1579 { 1580 /* If the result is a string, check if there is a non-digit before 1581 * the number. */ 1582 s = tv.vval.v_string; 1583 if (!VIM_ISDIGIT(*s) && *s != '-') 1584 *cp = *s++; 1585 retval = atol((char *)s); 1586 } 1587 clear_tv(&tv); 1588 } 1589 --emsg_off; 1590 --sandbox; 1591 1592 return retval; 1593 } 1594 #endif 1595 1596 /* 1597 * ":let" list all variable values 1598 * ":let var1 var2" list variable values 1599 * ":let var = expr" assignment command. 1600 * ":let var += expr" assignment command. 1601 * ":let var -= expr" assignment command. 1602 * ":let var .= expr" assignment command. 1603 * ":let [var1, var2] = expr" unpack list. 1604 */ 1605 void 1606 ex_let(eap) 1607 exarg_T *eap; 1608 { 1609 char_u *arg = eap->arg; 1610 char_u *expr = NULL; 1611 typval_T rettv; 1612 int i; 1613 int var_count = 0; 1614 int semicolon = 0; 1615 char_u op[2]; 1616 1617 expr = skip_var_list(arg, &var_count, &semicolon); 1618 if (expr == NULL) 1619 return; 1620 expr = vim_strchr(expr, '='); 1621 if (expr == NULL) 1622 { 1623 /* 1624 * ":let" without "=": list variables 1625 */ 1626 if (*arg == '[') 1627 EMSG(_(e_invarg)); 1628 else if (!ends_excmd(*arg)) 1629 /* ":let var1 var2" */ 1630 arg = list_arg_vars(eap, arg); 1631 else if (!eap->skip) 1632 { 1633 /* ":let" */ 1634 list_glob_vars(); 1635 list_buf_vars(); 1636 list_win_vars(); 1637 list_vim_vars(); 1638 } 1639 eap->nextcmd = check_nextcmd(arg); 1640 } 1641 else 1642 { 1643 op[0] = '='; 1644 op[1] = NUL; 1645 if (expr > arg) 1646 { 1647 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1648 op[0] = expr[-1]; /* +=, -= or .= */ 1649 } 1650 expr = skipwhite(expr + 1); 1651 1652 if (eap->skip) 1653 ++emsg_skip; 1654 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1655 if (eap->skip) 1656 { 1657 if (i != FAIL) 1658 clear_tv(&rettv); 1659 --emsg_skip; 1660 } 1661 else if (i != FAIL) 1662 { 1663 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1664 op); 1665 clear_tv(&rettv); 1666 } 1667 } 1668 } 1669 1670 /* 1671 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1672 * Handles both "var" with any type and "[var, var; var]" with a list type. 1673 * When "nextchars" is not NULL it points to a string with characters that 1674 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1675 * or concatenate. 1676 * Returns OK or FAIL; 1677 */ 1678 static int 1679 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1680 char_u *arg_start; 1681 typval_T *tv; 1682 int copy; /* copy values from "tv", don't move */ 1683 int semicolon; /* from skip_var_list() */ 1684 int var_count; /* from skip_var_list() */ 1685 char_u *nextchars; 1686 { 1687 char_u *arg = arg_start; 1688 list_T *l; 1689 int i; 1690 listitem_T *item; 1691 typval_T ltv; 1692 1693 if (*arg != '[') 1694 { 1695 /* 1696 * ":let var = expr" or ":for var in list" 1697 */ 1698 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1699 return FAIL; 1700 return OK; 1701 } 1702 1703 /* 1704 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1705 */ 1706 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1707 { 1708 EMSG(_(e_listreq)); 1709 return FAIL; 1710 } 1711 1712 i = list_len(l); 1713 if (semicolon == 0 && var_count < i) 1714 { 1715 EMSG(_("E687: Less targets than List items")); 1716 return FAIL; 1717 } 1718 if (var_count - semicolon > i) 1719 { 1720 EMSG(_("E688: More targets than List items")); 1721 return FAIL; 1722 } 1723 1724 item = l->lv_first; 1725 while (*arg != ']') 1726 { 1727 arg = skipwhite(arg + 1); 1728 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1729 item = item->li_next; 1730 if (arg == NULL) 1731 return FAIL; 1732 1733 arg = skipwhite(arg); 1734 if (*arg == ';') 1735 { 1736 /* Put the rest of the list (may be empty) in the var after ';'. 1737 * Create a new list for this. */ 1738 l = list_alloc(); 1739 if (l == NULL) 1740 return FAIL; 1741 while (item != NULL) 1742 { 1743 list_append_tv(l, &item->li_tv); 1744 item = item->li_next; 1745 } 1746 1747 ltv.v_type = VAR_LIST; 1748 ltv.v_lock = 0; 1749 ltv.vval.v_list = l; 1750 l->lv_refcount = 1; 1751 1752 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1753 (char_u *)"]", nextchars); 1754 clear_tv(<v); 1755 if (arg == NULL) 1756 return FAIL; 1757 break; 1758 } 1759 else if (*arg != ',' && *arg != ']') 1760 { 1761 EMSG2(_(e_intern2), "ex_let_vars()"); 1762 return FAIL; 1763 } 1764 } 1765 1766 return OK; 1767 } 1768 1769 /* 1770 * Skip over assignable variable "var" or list of variables "[var, var]". 1771 * Used for ":let varvar = expr" and ":for varvar in expr". 1772 * For "[var, var]" increment "*var_count" for each variable. 1773 * for "[var, var; var]" set "semicolon". 1774 * Return NULL for an error. 1775 */ 1776 static char_u * 1777 skip_var_list(arg, var_count, semicolon) 1778 char_u *arg; 1779 int *var_count; 1780 int *semicolon; 1781 { 1782 char_u *p, *s; 1783 1784 if (*arg == '[') 1785 { 1786 /* "[var, var]": find the matching ']'. */ 1787 p = arg; 1788 for (;;) 1789 { 1790 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1791 s = skip_var_one(p); 1792 if (s == p) 1793 { 1794 EMSG2(_(e_invarg2), p); 1795 return NULL; 1796 } 1797 ++*var_count; 1798 1799 p = skipwhite(s); 1800 if (*p == ']') 1801 break; 1802 else if (*p == ';') 1803 { 1804 if (*semicolon == 1) 1805 { 1806 EMSG(_("Double ; in list of variables")); 1807 return NULL; 1808 } 1809 *semicolon = 1; 1810 } 1811 else if (*p != ',') 1812 { 1813 EMSG2(_(e_invarg2), p); 1814 return NULL; 1815 } 1816 } 1817 return p + 1; 1818 } 1819 else 1820 return skip_var_one(arg); 1821 } 1822 1823 /* 1824 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1825 * l[idx]. 1826 */ 1827 static char_u * 1828 skip_var_one(arg) 1829 char_u *arg; 1830 { 1831 if (*arg == '@' && arg[1] != NUL) 1832 return arg + 2; 1833 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1834 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1835 } 1836 1837 /* 1838 * List variables for hashtab "ht" with prefix "prefix". 1839 * If "empty" is TRUE also list NULL strings as empty strings. 1840 */ 1841 static void 1842 list_hashtable_vars(ht, prefix, empty) 1843 hashtab_T *ht; 1844 char_u *prefix; 1845 int empty; 1846 { 1847 hashitem_T *hi; 1848 dictitem_T *di; 1849 int todo; 1850 1851 todo = ht->ht_used; 1852 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1853 { 1854 if (!HASHITEM_EMPTY(hi)) 1855 { 1856 --todo; 1857 di = HI2DI(hi); 1858 if (empty || di->di_tv.v_type != VAR_STRING 1859 || di->di_tv.vval.v_string != NULL) 1860 list_one_var(di, prefix); 1861 } 1862 } 1863 } 1864 1865 /* 1866 * List global variables. 1867 */ 1868 static void 1869 list_glob_vars() 1870 { 1871 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1872 } 1873 1874 /* 1875 * List buffer variables. 1876 */ 1877 static void 1878 list_buf_vars() 1879 { 1880 char_u numbuf[NUMBUFLEN]; 1881 1882 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1883 1884 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1885 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1886 } 1887 1888 /* 1889 * List window variables. 1890 */ 1891 static void 1892 list_win_vars() 1893 { 1894 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1895 } 1896 1897 /* 1898 * List Vim variables. 1899 */ 1900 static void 1901 list_vim_vars() 1902 { 1903 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1904 } 1905 1906 /* 1907 * List variables in "arg". 1908 */ 1909 static char_u * 1910 list_arg_vars(eap, arg) 1911 exarg_T *eap; 1912 char_u *arg; 1913 { 1914 int error = FALSE; 1915 int len; 1916 char_u *name; 1917 char_u *name_start; 1918 char_u *arg_subsc; 1919 char_u *tofree; 1920 typval_T tv; 1921 1922 while (!ends_excmd(*arg) && !got_int) 1923 { 1924 if (error || eap->skip) 1925 { 1926 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1927 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1928 { 1929 emsg_severe = TRUE; 1930 EMSG(_(e_trailing)); 1931 break; 1932 } 1933 } 1934 else 1935 { 1936 /* get_name_len() takes care of expanding curly braces */ 1937 name_start = name = arg; 1938 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1939 if (len <= 0) 1940 { 1941 /* This is mainly to keep test 49 working: when expanding 1942 * curly braces fails overrule the exception error message. */ 1943 if (len < 0 && !aborting()) 1944 { 1945 emsg_severe = TRUE; 1946 EMSG2(_(e_invarg2), arg); 1947 break; 1948 } 1949 error = TRUE; 1950 } 1951 else 1952 { 1953 if (tofree != NULL) 1954 name = tofree; 1955 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1956 error = TRUE; 1957 else 1958 { 1959 /* handle d.key, l[idx], f(expr) */ 1960 arg_subsc = arg; 1961 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1962 error = TRUE; 1963 else 1964 { 1965 if (arg == arg_subsc && len == 2 && name[1] == ':') 1966 { 1967 switch (*name) 1968 { 1969 case 'g': list_glob_vars(); break; 1970 case 'b': list_buf_vars(); break; 1971 case 'w': list_win_vars(); break; 1972 case 'v': list_vim_vars(); break; 1973 default: 1974 EMSG2(_("E738: Can't list variables for %s"), name); 1975 } 1976 } 1977 else 1978 { 1979 char_u numbuf[NUMBUFLEN]; 1980 char_u *tf; 1981 int c; 1982 char_u *s; 1983 1984 s = echo_string(&tv, &tf, numbuf); 1985 c = *arg; 1986 *arg = NUL; 1987 list_one_var_a((char_u *)"", 1988 arg == arg_subsc ? name : name_start, 1989 tv.v_type, s == NULL ? (char_u *)"" : s); 1990 *arg = c; 1991 vim_free(tf); 1992 } 1993 clear_tv(&tv); 1994 } 1995 } 1996 } 1997 1998 vim_free(tofree); 1999 } 2000 2001 arg = skipwhite(arg); 2002 } 2003 2004 return arg; 2005 } 2006 2007 /* 2008 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2009 * Returns a pointer to the char just after the var name. 2010 * Returns NULL if there is an error. 2011 */ 2012 static char_u * 2013 ex_let_one(arg, tv, copy, endchars, op) 2014 char_u *arg; /* points to variable name */ 2015 typval_T *tv; /* value to assign to variable */ 2016 int copy; /* copy value from "tv" */ 2017 char_u *endchars; /* valid chars after variable name or NULL */ 2018 char_u *op; /* "+", "-", "." or NULL*/ 2019 { 2020 int c1; 2021 char_u *name; 2022 char_u *p; 2023 char_u *arg_end = NULL; 2024 int len; 2025 int opt_flags; 2026 char_u *tofree = NULL; 2027 2028 /* 2029 * ":let $VAR = expr": Set environment variable. 2030 */ 2031 if (*arg == '$') 2032 { 2033 /* Find the end of the name. */ 2034 ++arg; 2035 name = arg; 2036 len = get_env_len(&arg); 2037 if (len == 0) 2038 EMSG2(_(e_invarg2), name - 1); 2039 else 2040 { 2041 if (op != NULL && (*op == '+' || *op == '-')) 2042 EMSG2(_(e_letwrong), op); 2043 else if (endchars != NULL 2044 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2045 EMSG(_(e_letunexp)); 2046 else 2047 { 2048 c1 = name[len]; 2049 name[len] = NUL; 2050 p = get_tv_string_chk(tv); 2051 if (p != NULL && op != NULL && *op == '.') 2052 { 2053 int mustfree = FALSE; 2054 char_u *s = vim_getenv(name, &mustfree); 2055 2056 if (s != NULL) 2057 { 2058 p = tofree = concat_str(s, p); 2059 if (mustfree) 2060 vim_free(s); 2061 } 2062 } 2063 if (p != NULL) 2064 { 2065 vim_setenv(name, p); 2066 if (STRICMP(name, "HOME") == 0) 2067 init_homedir(); 2068 else if (didset_vim && STRICMP(name, "VIM") == 0) 2069 didset_vim = FALSE; 2070 else if (didset_vimruntime 2071 && STRICMP(name, "VIMRUNTIME") == 0) 2072 didset_vimruntime = FALSE; 2073 arg_end = arg; 2074 } 2075 name[len] = c1; 2076 vim_free(tofree); 2077 } 2078 } 2079 } 2080 2081 /* 2082 * ":let &option = expr": Set option value. 2083 * ":let &l:option = expr": Set local option value. 2084 * ":let &g:option = expr": Set global option value. 2085 */ 2086 else if (*arg == '&') 2087 { 2088 /* Find the end of the name. */ 2089 p = find_option_end(&arg, &opt_flags); 2090 if (p == NULL || (endchars != NULL 2091 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2092 EMSG(_(e_letunexp)); 2093 else 2094 { 2095 long n; 2096 int opt_type; 2097 long numval; 2098 char_u *stringval = NULL; 2099 char_u *s; 2100 2101 c1 = *p; 2102 *p = NUL; 2103 2104 n = get_tv_number(tv); 2105 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2106 if (s != NULL && op != NULL && *op != '=') 2107 { 2108 opt_type = get_option_value(arg, &numval, 2109 &stringval, opt_flags); 2110 if ((opt_type == 1 && *op == '.') 2111 || (opt_type == 0 && *op != '.')) 2112 EMSG2(_(e_letwrong), op); 2113 else 2114 { 2115 if (opt_type == 1) /* number */ 2116 { 2117 if (*op == '+') 2118 n = numval + n; 2119 else 2120 n = numval - n; 2121 } 2122 else if (opt_type == 0 && stringval != NULL) /* string */ 2123 { 2124 s = concat_str(stringval, s); 2125 vim_free(stringval); 2126 stringval = s; 2127 } 2128 } 2129 } 2130 if (s != NULL) 2131 { 2132 set_option_value(arg, n, s, opt_flags); 2133 arg_end = p; 2134 } 2135 *p = c1; 2136 vim_free(stringval); 2137 } 2138 } 2139 2140 /* 2141 * ":let @r = expr": Set register contents. 2142 */ 2143 else if (*arg == '@') 2144 { 2145 ++arg; 2146 if (op != NULL && (*op == '+' || *op == '-')) 2147 EMSG2(_(e_letwrong), op); 2148 else if (endchars != NULL 2149 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2150 EMSG(_(e_letunexp)); 2151 else 2152 { 2153 char_u *tofree = NULL; 2154 char_u *s; 2155 2156 p = get_tv_string_chk(tv); 2157 if (p != NULL && op != NULL && *op == '.') 2158 { 2159 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2160 if (s != NULL) 2161 { 2162 p = tofree = concat_str(s, p); 2163 vim_free(s); 2164 } 2165 } 2166 if (p != NULL) 2167 { 2168 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2169 arg_end = arg + 1; 2170 } 2171 vim_free(tofree); 2172 } 2173 } 2174 2175 /* 2176 * ":let var = expr": Set internal variable. 2177 * ":let {expr} = expr": Idem, name made with curly braces 2178 */ 2179 else if (eval_isnamec1(*arg) || *arg == '{') 2180 { 2181 lval_T lv; 2182 2183 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2184 if (p != NULL && lv.ll_name != NULL) 2185 { 2186 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2187 EMSG(_(e_letunexp)); 2188 else 2189 { 2190 set_var_lval(&lv, p, tv, copy, op); 2191 arg_end = p; 2192 } 2193 } 2194 clear_lval(&lv); 2195 } 2196 2197 else 2198 EMSG2(_(e_invarg2), arg); 2199 2200 return arg_end; 2201 } 2202 2203 /* 2204 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2205 */ 2206 static int 2207 check_changedtick(arg) 2208 char_u *arg; 2209 { 2210 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2211 { 2212 EMSG2(_(e_readonlyvar), arg); 2213 return TRUE; 2214 } 2215 return FALSE; 2216 } 2217 2218 /* 2219 * Get an lval: variable, Dict item or List item that can be assigned a value 2220 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2221 * "name.key", "name.key[expr]" etc. 2222 * Indexing only works if "name" is an existing List or Dictionary. 2223 * "name" points to the start of the name. 2224 * If "rettv" is not NULL it points to the value to be assigned. 2225 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2226 * wrong; must end in space or cmd separator. 2227 * 2228 * Returns a pointer to just after the name, including indexes. 2229 * When an evaluation error occurs "lp->ll_name" is NULL; 2230 * Returns NULL for a parsing error. Still need to free items in "lp"! 2231 */ 2232 static char_u * 2233 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2234 char_u *name; 2235 typval_T *rettv; 2236 lval_T *lp; 2237 int unlet; 2238 int skip; 2239 int quiet; /* don't give error messages */ 2240 int fne_flags; /* flags for find_name_end() */ 2241 { 2242 char_u *p; 2243 char_u *expr_start, *expr_end; 2244 int cc; 2245 dictitem_T *v; 2246 typval_T var1; 2247 typval_T var2; 2248 int empty1 = FALSE; 2249 listitem_T *ni; 2250 char_u *key = NULL; 2251 int len; 2252 hashtab_T *ht; 2253 2254 /* Clear everything in "lp". */ 2255 vim_memset(lp, 0, sizeof(lval_T)); 2256 2257 if (skip) 2258 { 2259 /* When skipping just find the end of the name. */ 2260 lp->ll_name = name; 2261 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2262 } 2263 2264 /* Find the end of the name. */ 2265 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2266 if (expr_start != NULL) 2267 { 2268 /* Don't expand the name when we already know there is an error. */ 2269 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2270 && *p != '[' && *p != '.') 2271 { 2272 EMSG(_(e_trailing)); 2273 return NULL; 2274 } 2275 2276 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2277 if (lp->ll_exp_name == NULL) 2278 { 2279 /* Report an invalid expression in braces, unless the 2280 * expression evaluation has been cancelled due to an 2281 * aborting error, an interrupt, or an exception. */ 2282 if (!aborting() && !quiet) 2283 { 2284 emsg_severe = TRUE; 2285 EMSG2(_(e_invarg2), name); 2286 return NULL; 2287 } 2288 } 2289 lp->ll_name = lp->ll_exp_name; 2290 } 2291 else 2292 lp->ll_name = name; 2293 2294 /* Without [idx] or .key we are done. */ 2295 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2296 return p; 2297 2298 cc = *p; 2299 *p = NUL; 2300 v = find_var(lp->ll_name, &ht); 2301 if (v == NULL && !quiet) 2302 EMSG2(_(e_undefvar), lp->ll_name); 2303 *p = cc; 2304 if (v == NULL) 2305 return NULL; 2306 2307 /* 2308 * Loop until no more [idx] or .key is following. 2309 */ 2310 lp->ll_tv = &v->di_tv; 2311 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2312 { 2313 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2314 && !(lp->ll_tv->v_type == VAR_DICT 2315 && lp->ll_tv->vval.v_dict != NULL)) 2316 { 2317 if (!quiet) 2318 EMSG(_("E689: Can only index a List or Dictionary")); 2319 return NULL; 2320 } 2321 if (lp->ll_range) 2322 { 2323 if (!quiet) 2324 EMSG(_("E708: [:] must come last")); 2325 return NULL; 2326 } 2327 2328 len = -1; 2329 if (*p == '.') 2330 { 2331 key = p + 1; 2332 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2333 ; 2334 if (len == 0) 2335 { 2336 if (!quiet) 2337 EMSG(_(e_emptykey)); 2338 return NULL; 2339 } 2340 p = key + len; 2341 } 2342 else 2343 { 2344 /* Get the index [expr] or the first index [expr: ]. */ 2345 p = skipwhite(p + 1); 2346 if (*p == ':') 2347 empty1 = TRUE; 2348 else 2349 { 2350 empty1 = FALSE; 2351 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2352 return NULL; 2353 if (get_tv_string_chk(&var1) == NULL) 2354 { 2355 /* not a number or string */ 2356 clear_tv(&var1); 2357 return NULL; 2358 } 2359 } 2360 2361 /* Optionally get the second index [ :expr]. */ 2362 if (*p == ':') 2363 { 2364 if (lp->ll_tv->v_type == VAR_DICT) 2365 { 2366 if (!quiet) 2367 EMSG(_(e_dictrange)); 2368 if (!empty1) 2369 clear_tv(&var1); 2370 return NULL; 2371 } 2372 if (rettv != NULL && (rettv->v_type != VAR_LIST 2373 || rettv->vval.v_list == NULL)) 2374 { 2375 if (!quiet) 2376 EMSG(_("E709: [:] requires a List value")); 2377 if (!empty1) 2378 clear_tv(&var1); 2379 return NULL; 2380 } 2381 p = skipwhite(p + 1); 2382 if (*p == ']') 2383 lp->ll_empty2 = TRUE; 2384 else 2385 { 2386 lp->ll_empty2 = FALSE; 2387 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2388 { 2389 if (!empty1) 2390 clear_tv(&var1); 2391 return NULL; 2392 } 2393 if (get_tv_string_chk(&var2) == NULL) 2394 { 2395 /* not a number or string */ 2396 if (!empty1) 2397 clear_tv(&var1); 2398 clear_tv(&var2); 2399 return NULL; 2400 } 2401 } 2402 lp->ll_range = TRUE; 2403 } 2404 else 2405 lp->ll_range = FALSE; 2406 2407 if (*p != ']') 2408 { 2409 if (!quiet) 2410 EMSG(_(e_missbrac)); 2411 if (!empty1) 2412 clear_tv(&var1); 2413 if (lp->ll_range && !lp->ll_empty2) 2414 clear_tv(&var2); 2415 return NULL; 2416 } 2417 2418 /* Skip to past ']'. */ 2419 ++p; 2420 } 2421 2422 if (lp->ll_tv->v_type == VAR_DICT) 2423 { 2424 if (len == -1) 2425 { 2426 /* "[key]": get key from "var1" */ 2427 key = get_tv_string(&var1); /* is number or string */ 2428 if (*key == NUL) 2429 { 2430 if (!quiet) 2431 EMSG(_(e_emptykey)); 2432 clear_tv(&var1); 2433 return NULL; 2434 } 2435 } 2436 lp->ll_list = NULL; 2437 lp->ll_dict = lp->ll_tv->vval.v_dict; 2438 lp->ll_di = dict_find(lp->ll_dict, key, len); 2439 if (lp->ll_di == NULL) 2440 { 2441 /* Key does not exist in dict: may need to add it. */ 2442 if (*p == '[' || *p == '.' || unlet) 2443 { 2444 if (!quiet) 2445 EMSG2(_(e_dictkey), key); 2446 if (len == -1) 2447 clear_tv(&var1); 2448 return NULL; 2449 } 2450 if (len == -1) 2451 lp->ll_newkey = vim_strsave(key); 2452 else 2453 lp->ll_newkey = vim_strnsave(key, len); 2454 if (len == -1) 2455 clear_tv(&var1); 2456 if (lp->ll_newkey == NULL) 2457 p = NULL; 2458 break; 2459 } 2460 if (len == -1) 2461 clear_tv(&var1); 2462 lp->ll_tv = &lp->ll_di->di_tv; 2463 } 2464 else 2465 { 2466 /* 2467 * Get the number and item for the only or first index of the List. 2468 */ 2469 if (empty1) 2470 lp->ll_n1 = 0; 2471 else 2472 { 2473 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2474 clear_tv(&var1); 2475 } 2476 lp->ll_dict = NULL; 2477 lp->ll_list = lp->ll_tv->vval.v_list; 2478 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2479 if (lp->ll_li == NULL) 2480 { 2481 if (!quiet) 2482 EMSGN(_(e_listidx), lp->ll_n1); 2483 if (lp->ll_range && !lp->ll_empty2) 2484 clear_tv(&var2); 2485 return NULL; 2486 } 2487 2488 /* 2489 * May need to find the item or absolute index for the second 2490 * index of a range. 2491 * When no index given: "lp->ll_empty2" is TRUE. 2492 * Otherwise "lp->ll_n2" is set to the second index. 2493 */ 2494 if (lp->ll_range && !lp->ll_empty2) 2495 { 2496 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2497 clear_tv(&var2); 2498 if (lp->ll_n2 < 0) 2499 { 2500 ni = list_find(lp->ll_list, lp->ll_n2); 2501 if (ni == NULL) 2502 { 2503 if (!quiet) 2504 EMSGN(_(e_listidx), lp->ll_n2); 2505 return NULL; 2506 } 2507 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2508 } 2509 2510 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2511 if (lp->ll_n1 < 0) 2512 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2513 if (lp->ll_n2 < lp->ll_n1) 2514 { 2515 if (!quiet) 2516 EMSGN(_(e_listidx), lp->ll_n2); 2517 return NULL; 2518 } 2519 } 2520 2521 lp->ll_tv = &lp->ll_li->li_tv; 2522 } 2523 } 2524 2525 return p; 2526 } 2527 2528 /* 2529 * Clear lval "lp" that was filled by get_lval(). 2530 */ 2531 static void 2532 clear_lval(lp) 2533 lval_T *lp; 2534 { 2535 vim_free(lp->ll_exp_name); 2536 vim_free(lp->ll_newkey); 2537 } 2538 2539 /* 2540 * Set a variable that was parsed by get_lval() to "rettv". 2541 * "endp" points to just after the parsed name. 2542 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2543 */ 2544 static void 2545 set_var_lval(lp, endp, rettv, copy, op) 2546 lval_T *lp; 2547 char_u *endp; 2548 typval_T *rettv; 2549 int copy; 2550 char_u *op; 2551 { 2552 int cc; 2553 listitem_T *ni; 2554 listitem_T *ri; 2555 dictitem_T *di; 2556 2557 if (lp->ll_tv == NULL) 2558 { 2559 if (!check_changedtick(lp->ll_name)) 2560 { 2561 cc = *endp; 2562 *endp = NUL; 2563 if (op != NULL && *op != '=') 2564 { 2565 typval_T tv; 2566 2567 /* handle +=, -= and .= */ 2568 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2569 &tv, TRUE) == OK) 2570 { 2571 if (tv_op(&tv, rettv, op) == OK) 2572 set_var(lp->ll_name, &tv, FALSE); 2573 clear_tv(&tv); 2574 } 2575 } 2576 else 2577 set_var(lp->ll_name, rettv, copy); 2578 *endp = cc; 2579 } 2580 } 2581 else if (tv_check_lock(lp->ll_newkey == NULL 2582 ? lp->ll_tv->v_lock 2583 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2584 ; 2585 else if (lp->ll_range) 2586 { 2587 /* 2588 * Assign the List values to the list items. 2589 */ 2590 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2591 { 2592 if (op != NULL && *op != '=') 2593 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2594 else 2595 { 2596 clear_tv(&lp->ll_li->li_tv); 2597 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2598 } 2599 ri = ri->li_next; 2600 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2601 break; 2602 if (lp->ll_li->li_next == NULL) 2603 { 2604 /* Need to add an empty item. */ 2605 ni = listitem_alloc(); 2606 if (ni == NULL) 2607 { 2608 ri = NULL; 2609 break; 2610 } 2611 ni->li_tv.v_type = VAR_NUMBER; 2612 ni->li_tv.v_lock = 0; 2613 ni->li_tv.vval.v_number = 0; 2614 list_append(lp->ll_list, ni); 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 * Return OK or FAIL. 3601 */ 3602 static int 3603 eval0(arg, rettv, nextcmd, evaluate) 3604 char_u *arg; 3605 typval_T *rettv; 3606 char_u **nextcmd; 3607 int evaluate; 3608 { 3609 int ret; 3610 char_u *p; 3611 3612 p = skipwhite(arg); 3613 ret = eval1(&p, rettv, evaluate); 3614 if (ret == FAIL || !ends_excmd(*p)) 3615 { 3616 if (ret != FAIL) 3617 clear_tv(rettv); 3618 /* 3619 * Report the invalid expression unless the expression evaluation has 3620 * been cancelled due to an aborting error, an interrupt, or an 3621 * exception. 3622 */ 3623 if (!aborting()) 3624 EMSG2(_(e_invexpr2), arg); 3625 ret = FAIL; 3626 } 3627 if (nextcmd != NULL) 3628 *nextcmd = check_nextcmd(p); 3629 3630 return ret; 3631 } 3632 3633 /* 3634 * Handle top level expression: 3635 * expr1 ? expr0 : expr0 3636 * 3637 * "arg" must point to the first non-white of the expression. 3638 * "arg" is advanced to the next non-white after the recognized expression. 3639 * 3640 * Return OK or FAIL. 3641 */ 3642 static int 3643 eval1(arg, rettv, evaluate) 3644 char_u **arg; 3645 typval_T *rettv; 3646 int evaluate; 3647 { 3648 int result; 3649 typval_T var2; 3650 3651 /* 3652 * Get the first variable. 3653 */ 3654 if (eval2(arg, rettv, evaluate) == FAIL) 3655 return FAIL; 3656 3657 if ((*arg)[0] == '?') 3658 { 3659 result = FALSE; 3660 if (evaluate) 3661 { 3662 int error = FALSE; 3663 3664 if (get_tv_number_chk(rettv, &error) != 0) 3665 result = TRUE; 3666 clear_tv(rettv); 3667 if (error) 3668 return FAIL; 3669 } 3670 3671 /* 3672 * Get the second variable. 3673 */ 3674 *arg = skipwhite(*arg + 1); 3675 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3676 return FAIL; 3677 3678 /* 3679 * Check for the ":". 3680 */ 3681 if ((*arg)[0] != ':') 3682 { 3683 EMSG(_("E109: Missing ':' after '?'")); 3684 if (evaluate && result) 3685 clear_tv(rettv); 3686 return FAIL; 3687 } 3688 3689 /* 3690 * Get the third variable. 3691 */ 3692 *arg = skipwhite(*arg + 1); 3693 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3694 { 3695 if (evaluate && result) 3696 clear_tv(rettv); 3697 return FAIL; 3698 } 3699 if (evaluate && !result) 3700 *rettv = var2; 3701 } 3702 3703 return OK; 3704 } 3705 3706 /* 3707 * Handle first level expression: 3708 * expr2 || expr2 || expr2 logical OR 3709 * 3710 * "arg" must point to the first non-white of the expression. 3711 * "arg" is advanced to the next non-white after the recognized expression. 3712 * 3713 * Return OK or FAIL. 3714 */ 3715 static int 3716 eval2(arg, rettv, evaluate) 3717 char_u **arg; 3718 typval_T *rettv; 3719 int evaluate; 3720 { 3721 typval_T var2; 3722 long result; 3723 int first; 3724 int error = FALSE; 3725 3726 /* 3727 * Get the first variable. 3728 */ 3729 if (eval3(arg, rettv, evaluate) == FAIL) 3730 return FAIL; 3731 3732 /* 3733 * Repeat until there is no following "||". 3734 */ 3735 first = TRUE; 3736 result = FALSE; 3737 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3738 { 3739 if (evaluate && first) 3740 { 3741 if (get_tv_number_chk(rettv, &error) != 0) 3742 result = TRUE; 3743 clear_tv(rettv); 3744 if (error) 3745 return FAIL; 3746 first = FALSE; 3747 } 3748 3749 /* 3750 * Get the second variable. 3751 */ 3752 *arg = skipwhite(*arg + 2); 3753 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3754 return FAIL; 3755 3756 /* 3757 * Compute the result. 3758 */ 3759 if (evaluate && !result) 3760 { 3761 if (get_tv_number_chk(&var2, &error) != 0) 3762 result = TRUE; 3763 clear_tv(&var2); 3764 if (error) 3765 return FAIL; 3766 } 3767 if (evaluate) 3768 { 3769 rettv->v_type = VAR_NUMBER; 3770 rettv->vval.v_number = result; 3771 } 3772 } 3773 3774 return OK; 3775 } 3776 3777 /* 3778 * Handle second level expression: 3779 * expr3 && expr3 && expr3 logical AND 3780 * 3781 * "arg" must point to the first non-white of the expression. 3782 * "arg" is advanced to the next non-white after the recognized expression. 3783 * 3784 * Return OK or FAIL. 3785 */ 3786 static int 3787 eval3(arg, rettv, evaluate) 3788 char_u **arg; 3789 typval_T *rettv; 3790 int evaluate; 3791 { 3792 typval_T var2; 3793 long result; 3794 int first; 3795 int error = FALSE; 3796 3797 /* 3798 * Get the first variable. 3799 */ 3800 if (eval4(arg, rettv, evaluate) == FAIL) 3801 return FAIL; 3802 3803 /* 3804 * Repeat until there is no following "&&". 3805 */ 3806 first = TRUE; 3807 result = TRUE; 3808 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3809 { 3810 if (evaluate && first) 3811 { 3812 if (get_tv_number_chk(rettv, &error) == 0) 3813 result = FALSE; 3814 clear_tv(rettv); 3815 if (error) 3816 return FAIL; 3817 first = FALSE; 3818 } 3819 3820 /* 3821 * Get the second variable. 3822 */ 3823 *arg = skipwhite(*arg + 2); 3824 if (eval4(arg, &var2, evaluate && result) == FAIL) 3825 return FAIL; 3826 3827 /* 3828 * Compute the result. 3829 */ 3830 if (evaluate && result) 3831 { 3832 if (get_tv_number_chk(&var2, &error) == 0) 3833 result = FALSE; 3834 clear_tv(&var2); 3835 if (error) 3836 return FAIL; 3837 } 3838 if (evaluate) 3839 { 3840 rettv->v_type = VAR_NUMBER; 3841 rettv->vval.v_number = result; 3842 } 3843 } 3844 3845 return OK; 3846 } 3847 3848 /* 3849 * Handle third level expression: 3850 * var1 == var2 3851 * var1 =~ var2 3852 * var1 != var2 3853 * var1 !~ var2 3854 * var1 > var2 3855 * var1 >= var2 3856 * var1 < var2 3857 * var1 <= var2 3858 * var1 is var2 3859 * var1 isnot var2 3860 * 3861 * "arg" must point to the first non-white of the expression. 3862 * "arg" is advanced to the next non-white after the recognized expression. 3863 * 3864 * Return OK or FAIL. 3865 */ 3866 static int 3867 eval4(arg, rettv, evaluate) 3868 char_u **arg; 3869 typval_T *rettv; 3870 int evaluate; 3871 { 3872 typval_T var2; 3873 char_u *p; 3874 int i; 3875 exptype_T type = TYPE_UNKNOWN; 3876 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3877 int len = 2; 3878 long n1, n2; 3879 char_u *s1, *s2; 3880 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3881 regmatch_T regmatch; 3882 int ic; 3883 char_u *save_cpo; 3884 3885 /* 3886 * Get the first variable. 3887 */ 3888 if (eval5(arg, rettv, evaluate) == FAIL) 3889 return FAIL; 3890 3891 p = *arg; 3892 switch (p[0]) 3893 { 3894 case '=': if (p[1] == '=') 3895 type = TYPE_EQUAL; 3896 else if (p[1] == '~') 3897 type = TYPE_MATCH; 3898 break; 3899 case '!': if (p[1] == '=') 3900 type = TYPE_NEQUAL; 3901 else if (p[1] == '~') 3902 type = TYPE_NOMATCH; 3903 break; 3904 case '>': if (p[1] != '=') 3905 { 3906 type = TYPE_GREATER; 3907 len = 1; 3908 } 3909 else 3910 type = TYPE_GEQUAL; 3911 break; 3912 case '<': if (p[1] != '=') 3913 { 3914 type = TYPE_SMALLER; 3915 len = 1; 3916 } 3917 else 3918 type = TYPE_SEQUAL; 3919 break; 3920 case 'i': if (p[1] == 's') 3921 { 3922 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3923 len = 5; 3924 if (!vim_isIDc(p[len])) 3925 { 3926 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3927 type_is = TRUE; 3928 } 3929 } 3930 break; 3931 } 3932 3933 /* 3934 * If there is a comparitive operator, use it. 3935 */ 3936 if (type != TYPE_UNKNOWN) 3937 { 3938 /* extra question mark appended: ignore case */ 3939 if (p[len] == '?') 3940 { 3941 ic = TRUE; 3942 ++len; 3943 } 3944 /* extra '#' appended: match case */ 3945 else if (p[len] == '#') 3946 { 3947 ic = FALSE; 3948 ++len; 3949 } 3950 /* nothing appened: use 'ignorecase' */ 3951 else 3952 ic = p_ic; 3953 3954 /* 3955 * Get the second variable. 3956 */ 3957 *arg = skipwhite(p + len); 3958 if (eval5(arg, &var2, evaluate) == FAIL) 3959 { 3960 clear_tv(rettv); 3961 return FAIL; 3962 } 3963 3964 if (evaluate) 3965 { 3966 if (type_is && rettv->v_type != var2.v_type) 3967 { 3968 /* For "is" a different type always means FALSE, for "notis" 3969 * it means TRUE. */ 3970 n1 = (type == TYPE_NEQUAL); 3971 } 3972 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3973 { 3974 if (type_is) 3975 { 3976 n1 = (rettv->v_type == var2.v_type 3977 && rettv->vval.v_list == var2.vval.v_list); 3978 if (type == TYPE_NEQUAL) 3979 n1 = !n1; 3980 } 3981 else if (rettv->v_type != var2.v_type 3982 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3983 { 3984 if (rettv->v_type != var2.v_type) 3985 EMSG(_("E691: Can only compare List with List")); 3986 else 3987 EMSG(_("E692: Invalid operation for Lists")); 3988 clear_tv(rettv); 3989 clear_tv(&var2); 3990 return FAIL; 3991 } 3992 else 3993 { 3994 /* Compare two Lists for being equal or unequal. */ 3995 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3996 if (type == TYPE_NEQUAL) 3997 n1 = !n1; 3998 } 3999 } 4000 4001 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4002 { 4003 if (type_is) 4004 { 4005 n1 = (rettv->v_type == var2.v_type 4006 && rettv->vval.v_dict == var2.vval.v_dict); 4007 if (type == TYPE_NEQUAL) 4008 n1 = !n1; 4009 } 4010 else if (rettv->v_type != var2.v_type 4011 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4012 { 4013 if (rettv->v_type != var2.v_type) 4014 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4015 else 4016 EMSG(_("E736: Invalid operation for Dictionary")); 4017 clear_tv(rettv); 4018 clear_tv(&var2); 4019 return FAIL; 4020 } 4021 else 4022 { 4023 /* Compare two Dictionaries for being equal or unequal. */ 4024 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4025 if (type == TYPE_NEQUAL) 4026 n1 = !n1; 4027 } 4028 } 4029 4030 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4031 { 4032 if (rettv->v_type != var2.v_type 4033 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4034 { 4035 if (rettv->v_type != var2.v_type) 4036 EMSG(_("E693: Can only compare Funcref with Funcref")); 4037 else 4038 EMSG(_("E694: Invalid operation for Funcrefs")); 4039 clear_tv(rettv); 4040 clear_tv(&var2); 4041 return FAIL; 4042 } 4043 else 4044 { 4045 /* Compare two Funcrefs for being equal or unequal. */ 4046 if (rettv->vval.v_string == NULL 4047 || var2.vval.v_string == NULL) 4048 n1 = FALSE; 4049 else 4050 n1 = STRCMP(rettv->vval.v_string, 4051 var2.vval.v_string) == 0; 4052 if (type == TYPE_NEQUAL) 4053 n1 = !n1; 4054 } 4055 } 4056 4057 /* 4058 * If one of the two variables is a number, compare as a number. 4059 * When using "=~" or "!~", always compare as string. 4060 */ 4061 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4062 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4063 { 4064 n1 = get_tv_number(rettv); 4065 n2 = get_tv_number(&var2); 4066 switch (type) 4067 { 4068 case TYPE_EQUAL: n1 = (n1 == n2); break; 4069 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4070 case TYPE_GREATER: n1 = (n1 > n2); break; 4071 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4072 case TYPE_SMALLER: n1 = (n1 < n2); break; 4073 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4074 case TYPE_UNKNOWN: 4075 case TYPE_MATCH: 4076 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4077 } 4078 } 4079 else 4080 { 4081 s1 = get_tv_string_buf(rettv, buf1); 4082 s2 = get_tv_string_buf(&var2, buf2); 4083 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4084 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4085 else 4086 i = 0; 4087 n1 = FALSE; 4088 switch (type) 4089 { 4090 case TYPE_EQUAL: n1 = (i == 0); break; 4091 case TYPE_NEQUAL: n1 = (i != 0); break; 4092 case TYPE_GREATER: n1 = (i > 0); break; 4093 case TYPE_GEQUAL: n1 = (i >= 0); break; 4094 case TYPE_SMALLER: n1 = (i < 0); break; 4095 case TYPE_SEQUAL: n1 = (i <= 0); break; 4096 4097 case TYPE_MATCH: 4098 case TYPE_NOMATCH: 4099 /* avoid 'l' flag in 'cpoptions' */ 4100 save_cpo = p_cpo; 4101 p_cpo = (char_u *)""; 4102 regmatch.regprog = vim_regcomp(s2, 4103 RE_MAGIC + RE_STRING); 4104 regmatch.rm_ic = ic; 4105 if (regmatch.regprog != NULL) 4106 { 4107 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4108 vim_free(regmatch.regprog); 4109 if (type == TYPE_NOMATCH) 4110 n1 = !n1; 4111 } 4112 p_cpo = save_cpo; 4113 break; 4114 4115 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4116 } 4117 } 4118 clear_tv(rettv); 4119 clear_tv(&var2); 4120 rettv->v_type = VAR_NUMBER; 4121 rettv->vval.v_number = n1; 4122 } 4123 } 4124 4125 return OK; 4126 } 4127 4128 /* 4129 * Handle fourth level expression: 4130 * + number addition 4131 * - number subtraction 4132 * . string concatenation 4133 * 4134 * "arg" must point to the first non-white of the expression. 4135 * "arg" is advanced to the next non-white after the recognized expression. 4136 * 4137 * Return OK or FAIL. 4138 */ 4139 static int 4140 eval5(arg, rettv, evaluate) 4141 char_u **arg; 4142 typval_T *rettv; 4143 int evaluate; 4144 { 4145 typval_T var2; 4146 typval_T var3; 4147 int op; 4148 long n1, n2; 4149 char_u *s1, *s2; 4150 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4151 char_u *p; 4152 4153 /* 4154 * Get the first variable. 4155 */ 4156 if (eval6(arg, rettv, evaluate) == FAIL) 4157 return FAIL; 4158 4159 /* 4160 * Repeat computing, until no '+', '-' or '.' is following. 4161 */ 4162 for (;;) 4163 { 4164 op = **arg; 4165 if (op != '+' && op != '-' && op != '.') 4166 break; 4167 4168 if (op != '+' || rettv->v_type != VAR_LIST) 4169 { 4170 /* For "list + ...", an illegal use of the first operand as 4171 * a number cannot be determined before evaluating the 2nd 4172 * operand: if this is also a list, all is ok. 4173 * For "something . ...", "something - ..." or "non-list + ...", 4174 * we know that the first operand needs to be a string or number 4175 * without evaluating the 2nd operand. So check before to avoid 4176 * side effects after an error. */ 4177 if (evaluate && get_tv_string_chk(rettv) == NULL) 4178 { 4179 clear_tv(rettv); 4180 return FAIL; 4181 } 4182 } 4183 4184 /* 4185 * Get the second variable. 4186 */ 4187 *arg = skipwhite(*arg + 1); 4188 if (eval6(arg, &var2, evaluate) == FAIL) 4189 { 4190 clear_tv(rettv); 4191 return FAIL; 4192 } 4193 4194 if (evaluate) 4195 { 4196 /* 4197 * Compute the result. 4198 */ 4199 if (op == '.') 4200 { 4201 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4202 s2 = get_tv_string_buf_chk(&var2, buf2); 4203 if (s2 == NULL) /* type error ? */ 4204 { 4205 clear_tv(rettv); 4206 clear_tv(&var2); 4207 return FAIL; 4208 } 4209 p = concat_str(s1, s2); 4210 clear_tv(rettv); 4211 rettv->v_type = VAR_STRING; 4212 rettv->vval.v_string = p; 4213 } 4214 else if (op == '+' && rettv->v_type == VAR_LIST 4215 && var2.v_type == VAR_LIST) 4216 { 4217 /* concatenate Lists */ 4218 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4219 &var3) == FAIL) 4220 { 4221 clear_tv(rettv); 4222 clear_tv(&var2); 4223 return FAIL; 4224 } 4225 clear_tv(rettv); 4226 *rettv = var3; 4227 } 4228 else 4229 { 4230 int error = FALSE; 4231 4232 n1 = get_tv_number_chk(rettv, &error); 4233 if (error) 4234 { 4235 /* This can only happen for "list + non-list". 4236 * For "non-list + ..." or "something - ...", we returned 4237 * before evaluating the 2nd operand. */ 4238 clear_tv(rettv); 4239 return FAIL; 4240 } 4241 n2 = get_tv_number_chk(&var2, &error); 4242 if (error) 4243 { 4244 clear_tv(rettv); 4245 clear_tv(&var2); 4246 return FAIL; 4247 } 4248 clear_tv(rettv); 4249 if (op == '+') 4250 n1 = n1 + n2; 4251 else 4252 n1 = n1 - n2; 4253 rettv->v_type = VAR_NUMBER; 4254 rettv->vval.v_number = n1; 4255 } 4256 clear_tv(&var2); 4257 } 4258 } 4259 return OK; 4260 } 4261 4262 /* 4263 * Handle fifth level expression: 4264 * * number multiplication 4265 * / number division 4266 * % number modulo 4267 * 4268 * "arg" must point to the first non-white of the expression. 4269 * "arg" is advanced to the next non-white after the recognized expression. 4270 * 4271 * Return OK or FAIL. 4272 */ 4273 static int 4274 eval6(arg, rettv, evaluate) 4275 char_u **arg; 4276 typval_T *rettv; 4277 int evaluate; 4278 { 4279 typval_T var2; 4280 int op; 4281 long n1, n2; 4282 int error = FALSE; 4283 4284 /* 4285 * Get the first variable. 4286 */ 4287 if (eval7(arg, rettv, evaluate) == FAIL) 4288 return FAIL; 4289 4290 /* 4291 * Repeat computing, until no '*', '/' or '%' is following. 4292 */ 4293 for (;;) 4294 { 4295 op = **arg; 4296 if (op != '*' && op != '/' && op != '%') 4297 break; 4298 4299 if (evaluate) 4300 { 4301 n1 = get_tv_number_chk(rettv, &error); 4302 clear_tv(rettv); 4303 if (error) 4304 return FAIL; 4305 } 4306 else 4307 n1 = 0; 4308 4309 /* 4310 * Get the second variable. 4311 */ 4312 *arg = skipwhite(*arg + 1); 4313 if (eval7(arg, &var2, evaluate) == FAIL) 4314 return FAIL; 4315 4316 if (evaluate) 4317 { 4318 n2 = get_tv_number_chk(&var2, &error); 4319 clear_tv(&var2); 4320 if (error) 4321 return FAIL; 4322 4323 /* 4324 * Compute the result. 4325 */ 4326 if (op == '*') 4327 n1 = n1 * n2; 4328 else if (op == '/') 4329 { 4330 if (n2 == 0) /* give an error message? */ 4331 n1 = 0x7fffffffL; 4332 else 4333 n1 = n1 / n2; 4334 } 4335 else 4336 { 4337 if (n2 == 0) /* give an error message? */ 4338 n1 = 0; 4339 else 4340 n1 = n1 % n2; 4341 } 4342 rettv->v_type = VAR_NUMBER; 4343 rettv->vval.v_number = n1; 4344 } 4345 } 4346 4347 return OK; 4348 } 4349 4350 /* 4351 * Handle sixth level expression: 4352 * number number constant 4353 * "string" string contstant 4354 * 'string' literal string contstant 4355 * &option-name option value 4356 * @r register contents 4357 * identifier variable value 4358 * function() function call 4359 * $VAR environment variable 4360 * (expression) nested expression 4361 * [expr, expr] List 4362 * {key: val, key: val} Dictionary 4363 * 4364 * Also handle: 4365 * ! in front logical NOT 4366 * - in front unary minus 4367 * + in front unary plus (ignored) 4368 * trailing [] subscript in String or List 4369 * trailing .name entry in Dictionary 4370 * 4371 * "arg" must point to the first non-white of the expression. 4372 * "arg" is advanced to the next non-white after the recognized expression. 4373 * 4374 * Return OK or FAIL. 4375 */ 4376 static int 4377 eval7(arg, rettv, evaluate) 4378 char_u **arg; 4379 typval_T *rettv; 4380 int evaluate; 4381 { 4382 long n; 4383 int len; 4384 char_u *s; 4385 int val; 4386 char_u *start_leader, *end_leader; 4387 int ret = OK; 4388 char_u *alias; 4389 4390 /* 4391 * Initialise variable so that clear_tv() can't mistake this for a 4392 * string and free a string that isn't there. 4393 */ 4394 rettv->v_type = VAR_UNKNOWN; 4395 4396 /* 4397 * Skip '!' and '-' characters. They are handled later. 4398 */ 4399 start_leader = *arg; 4400 while (**arg == '!' || **arg == '-' || **arg == '+') 4401 *arg = skipwhite(*arg + 1); 4402 end_leader = *arg; 4403 4404 switch (**arg) 4405 { 4406 /* 4407 * Number constant. 4408 */ 4409 case '0': 4410 case '1': 4411 case '2': 4412 case '3': 4413 case '4': 4414 case '5': 4415 case '6': 4416 case '7': 4417 case '8': 4418 case '9': 4419 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4420 *arg += len; 4421 if (evaluate) 4422 { 4423 rettv->v_type = VAR_NUMBER; 4424 rettv->vval.v_number = n; 4425 } 4426 break; 4427 4428 /* 4429 * String constant: "string". 4430 */ 4431 case '"': ret = get_string_tv(arg, rettv, evaluate); 4432 break; 4433 4434 /* 4435 * Literal string constant: 'str''ing'. 4436 */ 4437 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4438 break; 4439 4440 /* 4441 * List: [expr, expr] 4442 */ 4443 case '[': ret = get_list_tv(arg, rettv, evaluate); 4444 break; 4445 4446 /* 4447 * Dictionary: {key: val, key: val} 4448 */ 4449 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4450 break; 4451 4452 /* 4453 * Option value: &name 4454 */ 4455 case '&': ret = get_option_tv(arg, rettv, evaluate); 4456 break; 4457 4458 /* 4459 * Environment variable: $VAR. 4460 */ 4461 case '$': ret = get_env_tv(arg, rettv, evaluate); 4462 break; 4463 4464 /* 4465 * Register contents: @r. 4466 */ 4467 case '@': ++*arg; 4468 if (evaluate) 4469 { 4470 rettv->v_type = VAR_STRING; 4471 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4472 } 4473 if (**arg != NUL) 4474 ++*arg; 4475 break; 4476 4477 /* 4478 * nested expression: (expression). 4479 */ 4480 case '(': *arg = skipwhite(*arg + 1); 4481 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4482 if (**arg == ')') 4483 ++*arg; 4484 else if (ret == OK) 4485 { 4486 EMSG(_("E110: Missing ')'")); 4487 clear_tv(rettv); 4488 ret = FAIL; 4489 } 4490 break; 4491 4492 default: ret = NOTDONE; 4493 break; 4494 } 4495 4496 if (ret == NOTDONE) 4497 { 4498 /* 4499 * Must be a variable or function name. 4500 * Can also be a curly-braces kind of name: {expr}. 4501 */ 4502 s = *arg; 4503 len = get_name_len(arg, &alias, evaluate, TRUE); 4504 if (alias != NULL) 4505 s = alias; 4506 4507 if (len <= 0) 4508 ret = FAIL; 4509 else 4510 { 4511 if (**arg == '(') /* recursive! */ 4512 { 4513 /* If "s" is the name of a variable of type VAR_FUNC 4514 * use its contents. */ 4515 s = deref_func_name(s, &len); 4516 4517 /* Invoke the function. */ 4518 ret = get_func_tv(s, len, rettv, arg, 4519 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4520 &len, evaluate, NULL); 4521 /* Stop the expression evaluation when immediately 4522 * aborting on error, or when an interrupt occurred or 4523 * an exception was thrown but not caught. */ 4524 if (aborting()) 4525 { 4526 if (ret == OK) 4527 clear_tv(rettv); 4528 ret = FAIL; 4529 } 4530 } 4531 else if (evaluate) 4532 ret = get_var_tv(s, len, rettv, TRUE); 4533 else 4534 ret = OK; 4535 } 4536 4537 if (alias != NULL) 4538 vim_free(alias); 4539 } 4540 4541 *arg = skipwhite(*arg); 4542 4543 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4544 * expr(expr). */ 4545 if (ret == OK) 4546 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4547 4548 /* 4549 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4550 */ 4551 if (ret == OK && evaluate && end_leader > start_leader) 4552 { 4553 int error = FALSE; 4554 4555 val = get_tv_number_chk(rettv, &error); 4556 if (error) 4557 { 4558 clear_tv(rettv); 4559 ret = FAIL; 4560 } 4561 else 4562 { 4563 while (end_leader > start_leader) 4564 { 4565 --end_leader; 4566 if (*end_leader == '!') 4567 val = !val; 4568 else if (*end_leader == '-') 4569 val = -val; 4570 } 4571 clear_tv(rettv); 4572 rettv->v_type = VAR_NUMBER; 4573 rettv->vval.v_number = val; 4574 } 4575 } 4576 4577 return ret; 4578 } 4579 4580 /* 4581 * Evaluate an "[expr]" or "[expr:expr]" index. 4582 * "*arg" points to the '['. 4583 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4584 */ 4585 static int 4586 eval_index(arg, rettv, evaluate, verbose) 4587 char_u **arg; 4588 typval_T *rettv; 4589 int evaluate; 4590 int verbose; /* give error messages */ 4591 { 4592 int empty1 = FALSE, empty2 = FALSE; 4593 typval_T var1, var2; 4594 long n1, n2 = 0; 4595 long len = -1; 4596 int range = FALSE; 4597 char_u *s; 4598 char_u *key = NULL; 4599 4600 if (rettv->v_type == VAR_FUNC) 4601 { 4602 if (verbose) 4603 EMSG(_("E695: Cannot index a Funcref")); 4604 return FAIL; 4605 } 4606 4607 if (**arg == '.') 4608 { 4609 /* 4610 * dict.name 4611 */ 4612 key = *arg + 1; 4613 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4614 ; 4615 if (len == 0) 4616 return FAIL; 4617 *arg = skipwhite(key + len); 4618 } 4619 else 4620 { 4621 /* 4622 * something[idx] 4623 * 4624 * Get the (first) variable from inside the []. 4625 */ 4626 *arg = skipwhite(*arg + 1); 4627 if (**arg == ':') 4628 empty1 = TRUE; 4629 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4630 return FAIL; 4631 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4632 { 4633 /* not a number or string */ 4634 clear_tv(&var1); 4635 return FAIL; 4636 } 4637 4638 /* 4639 * Get the second variable from inside the [:]. 4640 */ 4641 if (**arg == ':') 4642 { 4643 range = TRUE; 4644 *arg = skipwhite(*arg + 1); 4645 if (**arg == ']') 4646 empty2 = TRUE; 4647 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4648 { 4649 if (!empty1) 4650 clear_tv(&var1); 4651 return FAIL; 4652 } 4653 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4654 { 4655 /* not a number or string */ 4656 if (!empty1) 4657 clear_tv(&var1); 4658 clear_tv(&var2); 4659 return FAIL; 4660 } 4661 } 4662 4663 /* Check for the ']'. */ 4664 if (**arg != ']') 4665 { 4666 if (verbose) 4667 EMSG(_(e_missbrac)); 4668 clear_tv(&var1); 4669 if (range) 4670 clear_tv(&var2); 4671 return FAIL; 4672 } 4673 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4674 } 4675 4676 if (evaluate) 4677 { 4678 n1 = 0; 4679 if (!empty1 && rettv->v_type != VAR_DICT) 4680 { 4681 n1 = get_tv_number(&var1); 4682 clear_tv(&var1); 4683 } 4684 if (range) 4685 { 4686 if (empty2) 4687 n2 = -1; 4688 else 4689 { 4690 n2 = get_tv_number(&var2); 4691 clear_tv(&var2); 4692 } 4693 } 4694 4695 switch (rettv->v_type) 4696 { 4697 case VAR_NUMBER: 4698 case VAR_STRING: 4699 s = get_tv_string(rettv); 4700 len = (long)STRLEN(s); 4701 if (range) 4702 { 4703 /* The resulting variable is a substring. If the indexes 4704 * are out of range the result is empty. */ 4705 if (n1 < 0) 4706 { 4707 n1 = len + n1; 4708 if (n1 < 0) 4709 n1 = 0; 4710 } 4711 if (n2 < 0) 4712 n2 = len + n2; 4713 else if (n2 >= len) 4714 n2 = len; 4715 if (n1 >= len || n2 < 0 || n1 > n2) 4716 s = NULL; 4717 else 4718 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4719 } 4720 else 4721 { 4722 /* The resulting variable is a string of a single 4723 * character. If the index is too big or negative the 4724 * result is empty. */ 4725 if (n1 >= len || n1 < 0) 4726 s = NULL; 4727 else 4728 s = vim_strnsave(s + n1, 1); 4729 } 4730 clear_tv(rettv); 4731 rettv->v_type = VAR_STRING; 4732 rettv->vval.v_string = s; 4733 break; 4734 4735 case VAR_LIST: 4736 len = list_len(rettv->vval.v_list); 4737 if (n1 < 0) 4738 n1 = len + n1; 4739 if (!empty1 && (n1 < 0 || n1 >= len)) 4740 { 4741 if (verbose) 4742 EMSGN(_(e_listidx), n1); 4743 return FAIL; 4744 } 4745 if (range) 4746 { 4747 list_T *l; 4748 listitem_T *item; 4749 4750 if (n2 < 0) 4751 n2 = len + n2; 4752 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4753 { 4754 if (verbose) 4755 EMSGN(_(e_listidx), n2); 4756 return FAIL; 4757 } 4758 l = list_alloc(); 4759 if (l == NULL) 4760 return FAIL; 4761 for (item = list_find(rettv->vval.v_list, n1); 4762 n1 <= n2; ++n1) 4763 { 4764 if (list_append_tv(l, &item->li_tv) == FAIL) 4765 { 4766 list_free(l); 4767 return FAIL; 4768 } 4769 item = item->li_next; 4770 } 4771 clear_tv(rettv); 4772 rettv->v_type = VAR_LIST; 4773 rettv->vval.v_list = l; 4774 ++l->lv_refcount; 4775 } 4776 else 4777 { 4778 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4779 &var1); 4780 clear_tv(rettv); 4781 *rettv = var1; 4782 } 4783 break; 4784 4785 case VAR_DICT: 4786 if (range) 4787 { 4788 if (verbose) 4789 EMSG(_(e_dictrange)); 4790 if (len == -1) 4791 clear_tv(&var1); 4792 return FAIL; 4793 } 4794 { 4795 dictitem_T *item; 4796 4797 if (len == -1) 4798 { 4799 key = get_tv_string(&var1); 4800 if (*key == NUL) 4801 { 4802 if (verbose) 4803 EMSG(_(e_emptykey)); 4804 clear_tv(&var1); 4805 return FAIL; 4806 } 4807 } 4808 4809 item = dict_find(rettv->vval.v_dict, key, (int)len); 4810 4811 if (item == NULL && verbose) 4812 EMSG2(_(e_dictkey), key); 4813 if (len == -1) 4814 clear_tv(&var1); 4815 if (item == NULL) 4816 return FAIL; 4817 4818 copy_tv(&item->di_tv, &var1); 4819 clear_tv(rettv); 4820 *rettv = var1; 4821 } 4822 break; 4823 } 4824 } 4825 4826 return OK; 4827 } 4828 4829 /* 4830 * Get an option value. 4831 * "arg" points to the '&' or '+' before the option name. 4832 * "arg" is advanced to character after the option name. 4833 * Return OK or FAIL. 4834 */ 4835 static int 4836 get_option_tv(arg, rettv, evaluate) 4837 char_u **arg; 4838 typval_T *rettv; /* when NULL, only check if option exists */ 4839 int evaluate; 4840 { 4841 char_u *option_end; 4842 long numval; 4843 char_u *stringval; 4844 int opt_type; 4845 int c; 4846 int working = (**arg == '+'); /* has("+option") */ 4847 int ret = OK; 4848 int opt_flags; 4849 4850 /* 4851 * Isolate the option name and find its value. 4852 */ 4853 option_end = find_option_end(arg, &opt_flags); 4854 if (option_end == NULL) 4855 { 4856 if (rettv != NULL) 4857 EMSG2(_("E112: Option name missing: %s"), *arg); 4858 return FAIL; 4859 } 4860 4861 if (!evaluate) 4862 { 4863 *arg = option_end; 4864 return OK; 4865 } 4866 4867 c = *option_end; 4868 *option_end = NUL; 4869 opt_type = get_option_value(*arg, &numval, 4870 rettv == NULL ? NULL : &stringval, opt_flags); 4871 4872 if (opt_type == -3) /* invalid name */ 4873 { 4874 if (rettv != NULL) 4875 EMSG2(_("E113: Unknown option: %s"), *arg); 4876 ret = FAIL; 4877 } 4878 else if (rettv != NULL) 4879 { 4880 if (opt_type == -2) /* hidden string option */ 4881 { 4882 rettv->v_type = VAR_STRING; 4883 rettv->vval.v_string = NULL; 4884 } 4885 else if (opt_type == -1) /* hidden number option */ 4886 { 4887 rettv->v_type = VAR_NUMBER; 4888 rettv->vval.v_number = 0; 4889 } 4890 else if (opt_type == 1) /* number option */ 4891 { 4892 rettv->v_type = VAR_NUMBER; 4893 rettv->vval.v_number = numval; 4894 } 4895 else /* string option */ 4896 { 4897 rettv->v_type = VAR_STRING; 4898 rettv->vval.v_string = stringval; 4899 } 4900 } 4901 else if (working && (opt_type == -2 || opt_type == -1)) 4902 ret = FAIL; 4903 4904 *option_end = c; /* put back for error messages */ 4905 *arg = option_end; 4906 4907 return ret; 4908 } 4909 4910 /* 4911 * Allocate a variable for a string constant. 4912 * Return OK or FAIL. 4913 */ 4914 static int 4915 get_string_tv(arg, rettv, evaluate) 4916 char_u **arg; 4917 typval_T *rettv; 4918 int evaluate; 4919 { 4920 char_u *p; 4921 char_u *name; 4922 int extra = 0; 4923 4924 /* 4925 * Find the end of the string, skipping backslashed characters. 4926 */ 4927 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4928 { 4929 if (*p == '\\' && p[1] != NUL) 4930 { 4931 ++p; 4932 /* A "\<x>" form occupies at least 4 characters, and produces up 4933 * to 6 characters: reserve space for 2 extra */ 4934 if (*p == '<') 4935 extra += 2; 4936 } 4937 } 4938 4939 if (*p != '"') 4940 { 4941 EMSG2(_("E114: Missing quote: %s"), *arg); 4942 return FAIL; 4943 } 4944 4945 /* If only parsing, set *arg and return here */ 4946 if (!evaluate) 4947 { 4948 *arg = p + 1; 4949 return OK; 4950 } 4951 4952 /* 4953 * Copy the string into allocated memory, handling backslashed 4954 * characters. 4955 */ 4956 name = alloc((unsigned)(p - *arg + extra)); 4957 if (name == NULL) 4958 return FAIL; 4959 rettv->v_type = VAR_STRING; 4960 rettv->vval.v_string = name; 4961 4962 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4963 { 4964 if (*p == '\\') 4965 { 4966 switch (*++p) 4967 { 4968 case 'b': *name++ = BS; ++p; break; 4969 case 'e': *name++ = ESC; ++p; break; 4970 case 'f': *name++ = FF; ++p; break; 4971 case 'n': *name++ = NL; ++p; break; 4972 case 'r': *name++ = CAR; ++p; break; 4973 case 't': *name++ = TAB; ++p; break; 4974 4975 case 'X': /* hex: "\x1", "\x12" */ 4976 case 'x': 4977 case 'u': /* Unicode: "\u0023" */ 4978 case 'U': 4979 if (vim_isxdigit(p[1])) 4980 { 4981 int n, nr; 4982 int c = toupper(*p); 4983 4984 if (c == 'X') 4985 n = 2; 4986 else 4987 n = 4; 4988 nr = 0; 4989 while (--n >= 0 && vim_isxdigit(p[1])) 4990 { 4991 ++p; 4992 nr = (nr << 4) + hex2nr(*p); 4993 } 4994 ++p; 4995 #ifdef FEAT_MBYTE 4996 /* For "\u" store the number according to 4997 * 'encoding'. */ 4998 if (c != 'X') 4999 name += (*mb_char2bytes)(nr, name); 5000 else 5001 #endif 5002 *name++ = nr; 5003 } 5004 break; 5005 5006 /* octal: "\1", "\12", "\123" */ 5007 case '0': 5008 case '1': 5009 case '2': 5010 case '3': 5011 case '4': 5012 case '5': 5013 case '6': 5014 case '7': *name = *p++ - '0'; 5015 if (*p >= '0' && *p <= '7') 5016 { 5017 *name = (*name << 3) + *p++ - '0'; 5018 if (*p >= '0' && *p <= '7') 5019 *name = (*name << 3) + *p++ - '0'; 5020 } 5021 ++name; 5022 break; 5023 5024 /* Special key, e.g.: "\<C-W>" */ 5025 case '<': extra = trans_special(&p, name, TRUE); 5026 if (extra != 0) 5027 { 5028 name += extra; 5029 break; 5030 } 5031 /* FALLTHROUGH */ 5032 5033 default: MB_COPY_CHAR(p, name); 5034 break; 5035 } 5036 } 5037 else 5038 MB_COPY_CHAR(p, name); 5039 5040 } 5041 *name = NUL; 5042 *arg = p + 1; 5043 5044 return OK; 5045 } 5046 5047 /* 5048 * Allocate a variable for a 'str''ing' constant. 5049 * Return OK or FAIL. 5050 */ 5051 static int 5052 get_lit_string_tv(arg, rettv, evaluate) 5053 char_u **arg; 5054 typval_T *rettv; 5055 int evaluate; 5056 { 5057 char_u *p; 5058 char_u *str; 5059 int reduce = 0; 5060 5061 /* 5062 * Find the end of the string, skipping ''. 5063 */ 5064 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5065 { 5066 if (*p == '\'') 5067 { 5068 if (p[1] != '\'') 5069 break; 5070 ++reduce; 5071 ++p; 5072 } 5073 } 5074 5075 if (*p != '\'') 5076 { 5077 EMSG2(_("E115: Missing quote: %s"), *arg); 5078 return FAIL; 5079 } 5080 5081 /* If only parsing return after setting "*arg" */ 5082 if (!evaluate) 5083 { 5084 *arg = p + 1; 5085 return OK; 5086 } 5087 5088 /* 5089 * Copy the string into allocated memory, handling '' to ' reduction. 5090 */ 5091 str = alloc((unsigned)((p - *arg) - reduce)); 5092 if (str == NULL) 5093 return FAIL; 5094 rettv->v_type = VAR_STRING; 5095 rettv->vval.v_string = str; 5096 5097 for (p = *arg + 1; *p != NUL; ) 5098 { 5099 if (*p == '\'') 5100 { 5101 if (p[1] != '\'') 5102 break; 5103 ++p; 5104 } 5105 MB_COPY_CHAR(p, str); 5106 } 5107 *str = NUL; 5108 *arg = p + 1; 5109 5110 return OK; 5111 } 5112 5113 /* 5114 * Allocate a variable for a List and fill it from "*arg". 5115 * Return OK or FAIL. 5116 */ 5117 static int 5118 get_list_tv(arg, rettv, evaluate) 5119 char_u **arg; 5120 typval_T *rettv; 5121 int evaluate; 5122 { 5123 list_T *l = NULL; 5124 typval_T tv; 5125 listitem_T *item; 5126 5127 if (evaluate) 5128 { 5129 l = list_alloc(); 5130 if (l == NULL) 5131 return FAIL; 5132 } 5133 5134 *arg = skipwhite(*arg + 1); 5135 while (**arg != ']' && **arg != NUL) 5136 { 5137 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5138 goto failret; 5139 if (evaluate) 5140 { 5141 item = listitem_alloc(); 5142 if (item != NULL) 5143 { 5144 item->li_tv = tv; 5145 item->li_tv.v_lock = 0; 5146 list_append(l, item); 5147 } 5148 else 5149 clear_tv(&tv); 5150 } 5151 5152 if (**arg == ']') 5153 break; 5154 if (**arg != ',') 5155 { 5156 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5157 goto failret; 5158 } 5159 *arg = skipwhite(*arg + 1); 5160 } 5161 5162 if (**arg != ']') 5163 { 5164 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5165 failret: 5166 if (evaluate) 5167 list_free(l); 5168 return FAIL; 5169 } 5170 5171 *arg = skipwhite(*arg + 1); 5172 if (evaluate) 5173 { 5174 rettv->v_type = VAR_LIST; 5175 rettv->vval.v_list = l; 5176 ++l->lv_refcount; 5177 } 5178 5179 return OK; 5180 } 5181 5182 /* 5183 * Allocate an empty header for a list. 5184 * Caller should take care of the reference count. 5185 */ 5186 static list_T * 5187 list_alloc() 5188 { 5189 list_T *l; 5190 5191 l = (list_T *)alloc_clear(sizeof(list_T)); 5192 if (l != NULL) 5193 { 5194 /* Prepend the list to the list of lists for garbage collection. */ 5195 if (first_list != NULL) 5196 first_list->lv_used_prev = l; 5197 l->lv_used_prev = NULL; 5198 l->lv_used_next = first_list; 5199 first_list = l; 5200 } 5201 return l; 5202 } 5203 5204 /* 5205 * Unreference a list: decrement the reference count and free it when it 5206 * becomes zero. 5207 */ 5208 void 5209 list_unref(l) 5210 list_T *l; 5211 { 5212 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5213 list_free(l); 5214 } 5215 5216 /* 5217 * Free a list, including all items it points to. 5218 * Ignores the reference count. 5219 */ 5220 static void 5221 list_free(l) 5222 list_T *l; 5223 { 5224 listitem_T *item; 5225 5226 /* Avoid that recursive reference to the list frees us again. */ 5227 l->lv_refcount = DEL_REFCOUNT; 5228 5229 /* Remove the list from the list of lists for garbage collection. */ 5230 if (l->lv_used_prev == NULL) 5231 first_list = l->lv_used_next; 5232 else 5233 l->lv_used_prev->lv_used_next = l->lv_used_next; 5234 if (l->lv_used_next != NULL) 5235 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5236 5237 for (item = l->lv_first; item != NULL; item = l->lv_first) 5238 { 5239 /* Remove the item before deleting it. */ 5240 l->lv_first = item->li_next; 5241 listitem_free(item); 5242 } 5243 vim_free(l); 5244 } 5245 5246 /* 5247 * Allocate a list item. 5248 */ 5249 static listitem_T * 5250 listitem_alloc() 5251 { 5252 return (listitem_T *)alloc(sizeof(listitem_T)); 5253 } 5254 5255 /* 5256 * Free a list item. Also clears the value. Does not notify watchers. 5257 */ 5258 static void 5259 listitem_free(item) 5260 listitem_T *item; 5261 { 5262 clear_tv(&item->li_tv); 5263 vim_free(item); 5264 } 5265 5266 /* 5267 * Remove a list item from a List and free it. Also clears the value. 5268 */ 5269 static void 5270 listitem_remove(l, item) 5271 list_T *l; 5272 listitem_T *item; 5273 { 5274 list_remove(l, item, item); 5275 listitem_free(item); 5276 } 5277 5278 /* 5279 * Get the number of items in a list. 5280 */ 5281 static long 5282 list_len(l) 5283 list_T *l; 5284 { 5285 if (l == NULL) 5286 return 0L; 5287 return l->lv_len; 5288 } 5289 5290 /* 5291 * Return TRUE when two lists have exactly the same values. 5292 */ 5293 static int 5294 list_equal(l1, l2, ic) 5295 list_T *l1; 5296 list_T *l2; 5297 int ic; /* ignore case for strings */ 5298 { 5299 listitem_T *item1, *item2; 5300 5301 if (list_len(l1) != list_len(l2)) 5302 return FALSE; 5303 5304 for (item1 = l1->lv_first, item2 = l2->lv_first; 5305 item1 != NULL && item2 != NULL; 5306 item1 = item1->li_next, item2 = item2->li_next) 5307 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5308 return FALSE; 5309 return item1 == NULL && item2 == NULL; 5310 } 5311 5312 /* 5313 * Return TRUE when two dictionaries have exactly the same key/values. 5314 */ 5315 static int 5316 dict_equal(d1, d2, ic) 5317 dict_T *d1; 5318 dict_T *d2; 5319 int ic; /* ignore case for strings */ 5320 { 5321 hashitem_T *hi; 5322 dictitem_T *item2; 5323 int todo; 5324 5325 if (dict_len(d1) != dict_len(d2)) 5326 return FALSE; 5327 5328 todo = d1->dv_hashtab.ht_used; 5329 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5330 { 5331 if (!HASHITEM_EMPTY(hi)) 5332 { 5333 item2 = dict_find(d2, hi->hi_key, -1); 5334 if (item2 == NULL) 5335 return FALSE; 5336 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5337 return FALSE; 5338 --todo; 5339 } 5340 } 5341 return TRUE; 5342 } 5343 5344 /* 5345 * Return TRUE if "tv1" and "tv2" have the same value. 5346 * Compares the items just like "==" would compare them, but strings and 5347 * numbers are different. 5348 */ 5349 static int 5350 tv_equal(tv1, tv2, ic) 5351 typval_T *tv1; 5352 typval_T *tv2; 5353 int ic; /* ignore case */ 5354 { 5355 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5356 char_u *s1, *s2; 5357 5358 if (tv1->v_type != tv2->v_type) 5359 return FALSE; 5360 5361 switch (tv1->v_type) 5362 { 5363 case VAR_LIST: 5364 /* recursive! */ 5365 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5366 5367 case VAR_DICT: 5368 /* recursive! */ 5369 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5370 5371 case VAR_FUNC: 5372 return (tv1->vval.v_string != NULL 5373 && tv2->vval.v_string != NULL 5374 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5375 5376 case VAR_NUMBER: 5377 return tv1->vval.v_number == tv2->vval.v_number; 5378 5379 case VAR_STRING: 5380 s1 = get_tv_string_buf(tv1, buf1); 5381 s2 = get_tv_string_buf(tv2, buf2); 5382 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5383 } 5384 5385 EMSG2(_(e_intern2), "tv_equal()"); 5386 return TRUE; 5387 } 5388 5389 /* 5390 * Locate item with index "n" in list "l" and return it. 5391 * A negative index is counted from the end; -1 is the last item. 5392 * Returns NULL when "n" is out of range. 5393 */ 5394 static listitem_T * 5395 list_find(l, n) 5396 list_T *l; 5397 long n; 5398 { 5399 listitem_T *item; 5400 long idx; 5401 5402 if (l == NULL) 5403 return NULL; 5404 5405 /* Negative index is relative to the end. */ 5406 if (n < 0) 5407 n = l->lv_len + n; 5408 5409 /* Check for index out of range. */ 5410 if (n < 0 || n >= l->lv_len) 5411 return NULL; 5412 5413 /* When there is a cached index may start search from there. */ 5414 if (l->lv_idx_item != NULL) 5415 { 5416 if (n < l->lv_idx / 2) 5417 { 5418 /* closest to the start of the list */ 5419 item = l->lv_first; 5420 idx = 0; 5421 } 5422 else if (n > (l->lv_idx + l->lv_len) / 2) 5423 { 5424 /* closest to the end of the list */ 5425 item = l->lv_last; 5426 idx = l->lv_len - 1; 5427 } 5428 else 5429 { 5430 /* closest to the cached index */ 5431 item = l->lv_idx_item; 5432 idx = l->lv_idx; 5433 } 5434 } 5435 else 5436 { 5437 if (n < l->lv_len / 2) 5438 { 5439 /* closest to the start of the list */ 5440 item = l->lv_first; 5441 idx = 0; 5442 } 5443 else 5444 { 5445 /* closest to the end of the list */ 5446 item = l->lv_last; 5447 idx = l->lv_len - 1; 5448 } 5449 } 5450 5451 while (n > idx) 5452 { 5453 /* search forward */ 5454 item = item->li_next; 5455 ++idx; 5456 } 5457 while (n < idx) 5458 { 5459 /* search backward */ 5460 item = item->li_prev; 5461 --idx; 5462 } 5463 5464 /* cache the used index */ 5465 l->lv_idx = idx; 5466 l->lv_idx_item = item; 5467 5468 return item; 5469 } 5470 5471 /* 5472 * Locate "item" list "l" and return its index. 5473 * Returns -1 when "item" is not in the list. 5474 */ 5475 static long 5476 list_idx_of_item(l, item) 5477 list_T *l; 5478 listitem_T *item; 5479 { 5480 long idx = 0; 5481 listitem_T *li; 5482 5483 if (l == NULL) 5484 return -1; 5485 idx = 0; 5486 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5487 ++idx; 5488 if (li == NULL) 5489 return -1; 5490 return idx; 5491 } 5492 5493 /* 5494 * Append item "item" to the end of list "l". 5495 */ 5496 static void 5497 list_append(l, item) 5498 list_T *l; 5499 listitem_T *item; 5500 { 5501 if (l->lv_last == NULL) 5502 { 5503 /* empty list */ 5504 l->lv_first = item; 5505 l->lv_last = item; 5506 item->li_prev = NULL; 5507 } 5508 else 5509 { 5510 l->lv_last->li_next = item; 5511 item->li_prev = l->lv_last; 5512 l->lv_last = item; 5513 } 5514 ++l->lv_len; 5515 item->li_next = NULL; 5516 } 5517 5518 /* 5519 * Append typval_T "tv" to the end of list "l". 5520 * Return FAIL when out of memory. 5521 */ 5522 static int 5523 list_append_tv(l, tv) 5524 list_T *l; 5525 typval_T *tv; 5526 { 5527 listitem_T *li = listitem_alloc(); 5528 5529 if (li == NULL) 5530 return FAIL; 5531 copy_tv(tv, &li->li_tv); 5532 list_append(l, li); 5533 return OK; 5534 } 5535 5536 /* 5537 * Add a dictionary to a list. Used by getqflist(). 5538 * Return FAIL when out of memory. 5539 */ 5540 int 5541 list_append_dict(list, dict) 5542 list_T *list; 5543 dict_T *dict; 5544 { 5545 listitem_T *li = listitem_alloc(); 5546 5547 if (li == NULL) 5548 return FAIL; 5549 li->li_tv.v_type = VAR_DICT; 5550 li->li_tv.v_lock = 0; 5551 li->li_tv.vval.v_dict = dict; 5552 list_append(list, li); 5553 ++dict->dv_refcount; 5554 return OK; 5555 } 5556 5557 /* 5558 * Make a copy of "str" and append it as an item to list "l". 5559 * Returns FAIL when out of memory. 5560 */ 5561 static int 5562 list_append_string(l, str) 5563 list_T *l; 5564 char_u *str; 5565 { 5566 listitem_T *li = listitem_alloc(); 5567 5568 if (li == NULL) 5569 return FAIL; 5570 list_append(l, li); 5571 li->li_tv.v_type = VAR_STRING; 5572 li->li_tv.v_lock = 0; 5573 if ((li->li_tv.vval.v_string = vim_strsave(str)) == NULL) 5574 return FAIL; 5575 return OK; 5576 } 5577 5578 /* 5579 * Insert typval_T "tv" in list "l" before "item". 5580 * If "item" is NULL append at the end. 5581 * Return FAIL when out of memory. 5582 */ 5583 static int 5584 list_insert_tv(l, tv, item) 5585 list_T *l; 5586 typval_T *tv; 5587 listitem_T *item; 5588 { 5589 listitem_T *ni = listitem_alloc(); 5590 5591 if (ni == NULL) 5592 return FAIL; 5593 copy_tv(tv, &ni->li_tv); 5594 if (item == NULL) 5595 /* Append new item at end of list. */ 5596 list_append(l, ni); 5597 else 5598 { 5599 /* Insert new item before existing item. */ 5600 ni->li_prev = item->li_prev; 5601 ni->li_next = item; 5602 if (item->li_prev == NULL) 5603 { 5604 l->lv_first = ni; 5605 ++l->lv_idx; 5606 } 5607 else 5608 { 5609 item->li_prev->li_next = ni; 5610 l->lv_idx_item = NULL; 5611 } 5612 item->li_prev = ni; 5613 ++l->lv_len; 5614 } 5615 return OK; 5616 } 5617 5618 /* 5619 * Extend "l1" with "l2". 5620 * If "bef" is NULL append at the end, otherwise insert before this item. 5621 * Returns FAIL when out of memory. 5622 */ 5623 static int 5624 list_extend(l1, l2, bef) 5625 list_T *l1; 5626 list_T *l2; 5627 listitem_T *bef; 5628 { 5629 listitem_T *item; 5630 5631 for (item = l2->lv_first; item != NULL; item = item->li_next) 5632 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5633 return FAIL; 5634 return OK; 5635 } 5636 5637 /* 5638 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5639 * Return FAIL when out of memory. 5640 */ 5641 static int 5642 list_concat(l1, l2, tv) 5643 list_T *l1; 5644 list_T *l2; 5645 typval_T *tv; 5646 { 5647 list_T *l; 5648 5649 /* make a copy of the first list. */ 5650 l = list_copy(l1, FALSE, 0); 5651 if (l == NULL) 5652 return FAIL; 5653 tv->v_type = VAR_LIST; 5654 tv->vval.v_list = l; 5655 5656 /* append all items from the second list */ 5657 return list_extend(l, l2, NULL); 5658 } 5659 5660 /* 5661 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5662 * The refcount of the new list is set to 1. 5663 * See item_copy() for "copyID". 5664 * Returns NULL when out of memory. 5665 */ 5666 static list_T * 5667 list_copy(orig, deep, copyID) 5668 list_T *orig; 5669 int deep; 5670 int copyID; 5671 { 5672 list_T *copy; 5673 listitem_T *item; 5674 listitem_T *ni; 5675 5676 if (orig == NULL) 5677 return NULL; 5678 5679 copy = list_alloc(); 5680 if (copy != NULL) 5681 { 5682 if (copyID != 0) 5683 { 5684 /* Do this before adding the items, because one of the items may 5685 * refer back to this list. */ 5686 orig->lv_copyID = copyID; 5687 orig->lv_copylist = copy; 5688 } 5689 for (item = orig->lv_first; item != NULL && !got_int; 5690 item = item->li_next) 5691 { 5692 ni = listitem_alloc(); 5693 if (ni == NULL) 5694 break; 5695 if (deep) 5696 { 5697 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5698 { 5699 vim_free(ni); 5700 break; 5701 } 5702 } 5703 else 5704 copy_tv(&item->li_tv, &ni->li_tv); 5705 list_append(copy, ni); 5706 } 5707 ++copy->lv_refcount; 5708 if (item != NULL) 5709 { 5710 list_unref(copy); 5711 copy = NULL; 5712 } 5713 } 5714 5715 return copy; 5716 } 5717 5718 /* 5719 * Remove items "item" to "item2" from list "l". 5720 * Does not free the listitem or the value! 5721 */ 5722 static void 5723 list_remove(l, item, item2) 5724 list_T *l; 5725 listitem_T *item; 5726 listitem_T *item2; 5727 { 5728 listitem_T *ip; 5729 5730 /* notify watchers */ 5731 for (ip = item; ip != NULL; ip = ip->li_next) 5732 { 5733 --l->lv_len; 5734 list_fix_watch(l, ip); 5735 if (ip == item2) 5736 break; 5737 } 5738 5739 if (item2->li_next == NULL) 5740 l->lv_last = item->li_prev; 5741 else 5742 item2->li_next->li_prev = item->li_prev; 5743 if (item->li_prev == NULL) 5744 l->lv_first = item2->li_next; 5745 else 5746 item->li_prev->li_next = item2->li_next; 5747 l->lv_idx_item = NULL; 5748 } 5749 5750 /* 5751 * Return an allocated string with the string representation of a list. 5752 * May return NULL. 5753 */ 5754 static char_u * 5755 list2string(tv) 5756 typval_T *tv; 5757 { 5758 garray_T ga; 5759 5760 if (tv->vval.v_list == NULL) 5761 return NULL; 5762 ga_init2(&ga, (int)sizeof(char), 80); 5763 ga_append(&ga, '['); 5764 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5765 { 5766 vim_free(ga.ga_data); 5767 return NULL; 5768 } 5769 ga_append(&ga, ']'); 5770 ga_append(&ga, NUL); 5771 return (char_u *)ga.ga_data; 5772 } 5773 5774 /* 5775 * Join list "l" into a string in "*gap", using separator "sep". 5776 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5777 * Return FAIL or OK. 5778 */ 5779 static int 5780 list_join(gap, l, sep, echo) 5781 garray_T *gap; 5782 list_T *l; 5783 char_u *sep; 5784 int echo; 5785 { 5786 int first = TRUE; 5787 char_u *tofree; 5788 char_u numbuf[NUMBUFLEN]; 5789 listitem_T *item; 5790 char_u *s; 5791 5792 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5793 { 5794 if (first) 5795 first = FALSE; 5796 else 5797 ga_concat(gap, sep); 5798 5799 if (echo) 5800 s = echo_string(&item->li_tv, &tofree, numbuf); 5801 else 5802 s = tv2string(&item->li_tv, &tofree, numbuf); 5803 if (s != NULL) 5804 ga_concat(gap, s); 5805 vim_free(tofree); 5806 if (s == NULL) 5807 return FAIL; 5808 } 5809 return OK; 5810 } 5811 5812 /* 5813 * Garbage collection for lists and dictionaries. 5814 * 5815 * We use reference counts to be able to free most items right away when they 5816 * are no longer used. But for composite items it's possible that it becomes 5817 * unused while the reference count is > 0: When there is a recursive 5818 * reference. Example: 5819 * :let l = [1, 2, 3] 5820 * :let d = {9: l} 5821 * :let l[1] = d 5822 * 5823 * Since this is quite unusual we handle this with garbage collection: every 5824 * once in a while find out which lists and dicts are not referenced from any 5825 * variable. 5826 * 5827 * Here is a good reference text about garbage collection (refers to Python 5828 * but it applies to all reference-counting mechanisms): 5829 * http://python.ca/nas/python/gc/ 5830 */ 5831 5832 /* 5833 * Do garbage collection for lists and dicts. 5834 * Return TRUE if some memory was freed. 5835 */ 5836 int 5837 garbage_collect() 5838 { 5839 dict_T *dd; 5840 list_T *ll; 5841 int copyID = ++current_copyID; 5842 buf_T *buf; 5843 win_T *wp; 5844 int i; 5845 funccall_T *fc; 5846 int did_free = FALSE; 5847 5848 /* 5849 * 1. Go through all accessible variables and mark all lists and dicts 5850 * with copyID. 5851 */ 5852 /* script-local variables */ 5853 for (i = 1; i <= ga_scripts.ga_len; ++i) 5854 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5855 5856 /* buffer-local variables */ 5857 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5858 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5859 5860 /* window-local variables */ 5861 FOR_ALL_WINDOWS(wp) 5862 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5863 5864 /* global variables */ 5865 set_ref_in_ht(&globvarht, copyID); 5866 5867 /* function-local variables */ 5868 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5869 { 5870 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5871 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5872 } 5873 5874 /* 5875 * 2. Go through the list of dicts and free items without the copyID. 5876 */ 5877 for (dd = first_dict; dd != NULL; ) 5878 if (dd->dv_copyID != copyID) 5879 { 5880 dict_free(dd); 5881 did_free = TRUE; 5882 5883 /* restart, next dict may also have been freed */ 5884 dd = first_dict; 5885 } 5886 else 5887 dd = dd->dv_used_next; 5888 5889 /* 5890 * 3. Go through the list of lists and free items without the copyID. 5891 * But don't free a list that has a watcher (used in a for loop), these 5892 * are not referenced anywhere. 5893 */ 5894 for (ll = first_list; ll != NULL; ) 5895 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 5896 { 5897 list_free(ll); 5898 did_free = TRUE; 5899 5900 /* restart, next list may also have been freed */ 5901 ll = first_list; 5902 } 5903 else 5904 ll = ll->lv_used_next; 5905 5906 return did_free; 5907 } 5908 5909 /* 5910 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5911 */ 5912 static void 5913 set_ref_in_ht(ht, copyID) 5914 hashtab_T *ht; 5915 int copyID; 5916 { 5917 int todo; 5918 hashitem_T *hi; 5919 5920 todo = ht->ht_used; 5921 for (hi = ht->ht_array; todo > 0; ++hi) 5922 if (!HASHITEM_EMPTY(hi)) 5923 { 5924 --todo; 5925 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5926 } 5927 } 5928 5929 /* 5930 * Mark all lists and dicts referenced through list "l" with "copyID". 5931 */ 5932 static void 5933 set_ref_in_list(l, copyID) 5934 list_T *l; 5935 int copyID; 5936 { 5937 listitem_T *li; 5938 5939 for (li = l->lv_first; li != NULL; li = li->li_next) 5940 set_ref_in_item(&li->li_tv, copyID); 5941 } 5942 5943 /* 5944 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5945 */ 5946 static void 5947 set_ref_in_item(tv, copyID) 5948 typval_T *tv; 5949 int copyID; 5950 { 5951 dict_T *dd; 5952 list_T *ll; 5953 5954 switch (tv->v_type) 5955 { 5956 case VAR_DICT: 5957 dd = tv->vval.v_dict; 5958 if (dd->dv_copyID != copyID) 5959 { 5960 /* Didn't see this dict yet. */ 5961 dd->dv_copyID = copyID; 5962 set_ref_in_ht(&dd->dv_hashtab, copyID); 5963 } 5964 break; 5965 5966 case VAR_LIST: 5967 ll = tv->vval.v_list; 5968 if (ll->lv_copyID != copyID) 5969 { 5970 /* Didn't see this list yet. */ 5971 ll->lv_copyID = copyID; 5972 set_ref_in_list(ll, copyID); 5973 } 5974 break; 5975 } 5976 return; 5977 } 5978 5979 /* 5980 * Allocate an empty header for a dictionary. 5981 */ 5982 dict_T * 5983 dict_alloc() 5984 { 5985 dict_T *d; 5986 5987 d = (dict_T *)alloc(sizeof(dict_T)); 5988 if (d != NULL) 5989 { 5990 /* Add the list to the hashtable for garbage collection. */ 5991 if (first_dict != NULL) 5992 first_dict->dv_used_prev = d; 5993 d->dv_used_next = first_dict; 5994 d->dv_used_prev = NULL; 5995 5996 hash_init(&d->dv_hashtab); 5997 d->dv_lock = 0; 5998 d->dv_refcount = 0; 5999 d->dv_copyID = 0; 6000 } 6001 return d; 6002 } 6003 6004 /* 6005 * Unreference a Dictionary: decrement the reference count and free it when it 6006 * becomes zero. 6007 */ 6008 static void 6009 dict_unref(d) 6010 dict_T *d; 6011 { 6012 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6013 dict_free(d); 6014 } 6015 6016 /* 6017 * Free a Dictionary, including all items it contains. 6018 * Ignores the reference count. 6019 */ 6020 static void 6021 dict_free(d) 6022 dict_T *d; 6023 { 6024 int todo; 6025 hashitem_T *hi; 6026 dictitem_T *di; 6027 6028 /* Avoid that recursive reference to the dict frees us again. */ 6029 d->dv_refcount = DEL_REFCOUNT; 6030 6031 /* Remove the dict from the list of dicts for garbage collection. */ 6032 if (d->dv_used_prev == NULL) 6033 first_dict = d->dv_used_next; 6034 else 6035 d->dv_used_prev->dv_used_next = d->dv_used_next; 6036 if (d->dv_used_next != NULL) 6037 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6038 6039 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6040 hash_lock(&d->dv_hashtab); 6041 todo = d->dv_hashtab.ht_used; 6042 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6043 { 6044 if (!HASHITEM_EMPTY(hi)) 6045 { 6046 /* Remove the item before deleting it, just in case there is 6047 * something recursive causing trouble. */ 6048 di = HI2DI(hi); 6049 hash_remove(&d->dv_hashtab, hi); 6050 dictitem_free(di); 6051 --todo; 6052 } 6053 } 6054 hash_clear(&d->dv_hashtab); 6055 vim_free(d); 6056 } 6057 6058 /* 6059 * Allocate a Dictionary item. 6060 * The "key" is copied to the new item. 6061 * Note that the value of the item "di_tv" still needs to be initialized! 6062 * Returns NULL when out of memory. 6063 */ 6064 static dictitem_T * 6065 dictitem_alloc(key) 6066 char_u *key; 6067 { 6068 dictitem_T *di; 6069 6070 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6071 if (di != NULL) 6072 { 6073 STRCPY(di->di_key, key); 6074 di->di_flags = 0; 6075 } 6076 return di; 6077 } 6078 6079 /* 6080 * Make a copy of a Dictionary item. 6081 */ 6082 static dictitem_T * 6083 dictitem_copy(org) 6084 dictitem_T *org; 6085 { 6086 dictitem_T *di; 6087 6088 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6089 if (di != NULL) 6090 { 6091 STRCPY(di->di_key, org->di_key); 6092 di->di_flags = 0; 6093 copy_tv(&org->di_tv, &di->di_tv); 6094 } 6095 return di; 6096 } 6097 6098 /* 6099 * Remove item "item" from Dictionary "dict" and free it. 6100 */ 6101 static void 6102 dictitem_remove(dict, item) 6103 dict_T *dict; 6104 dictitem_T *item; 6105 { 6106 hashitem_T *hi; 6107 6108 hi = hash_find(&dict->dv_hashtab, item->di_key); 6109 if (HASHITEM_EMPTY(hi)) 6110 EMSG2(_(e_intern2), "dictitem_remove()"); 6111 else 6112 hash_remove(&dict->dv_hashtab, hi); 6113 dictitem_free(item); 6114 } 6115 6116 /* 6117 * Free a dict item. Also clears the value. 6118 */ 6119 static void 6120 dictitem_free(item) 6121 dictitem_T *item; 6122 { 6123 clear_tv(&item->di_tv); 6124 vim_free(item); 6125 } 6126 6127 /* 6128 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6129 * The refcount of the new dict is set to 1. 6130 * See item_copy() for "copyID". 6131 * Returns NULL when out of memory. 6132 */ 6133 static dict_T * 6134 dict_copy(orig, deep, copyID) 6135 dict_T *orig; 6136 int deep; 6137 int copyID; 6138 { 6139 dict_T *copy; 6140 dictitem_T *di; 6141 int todo; 6142 hashitem_T *hi; 6143 6144 if (orig == NULL) 6145 return NULL; 6146 6147 copy = dict_alloc(); 6148 if (copy != NULL) 6149 { 6150 if (copyID != 0) 6151 { 6152 orig->dv_copyID = copyID; 6153 orig->dv_copydict = copy; 6154 } 6155 todo = orig->dv_hashtab.ht_used; 6156 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6157 { 6158 if (!HASHITEM_EMPTY(hi)) 6159 { 6160 --todo; 6161 6162 di = dictitem_alloc(hi->hi_key); 6163 if (di == NULL) 6164 break; 6165 if (deep) 6166 { 6167 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6168 copyID) == FAIL) 6169 { 6170 vim_free(di); 6171 break; 6172 } 6173 } 6174 else 6175 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6176 if (dict_add(copy, di) == FAIL) 6177 { 6178 dictitem_free(di); 6179 break; 6180 } 6181 } 6182 } 6183 6184 ++copy->dv_refcount; 6185 if (todo > 0) 6186 { 6187 dict_unref(copy); 6188 copy = NULL; 6189 } 6190 } 6191 6192 return copy; 6193 } 6194 6195 /* 6196 * Add item "item" to Dictionary "d". 6197 * Returns FAIL when out of memory and when key already existed. 6198 */ 6199 static int 6200 dict_add(d, item) 6201 dict_T *d; 6202 dictitem_T *item; 6203 { 6204 return hash_add(&d->dv_hashtab, item->di_key); 6205 } 6206 6207 /* 6208 * Add a number or string entry to dictionary "d". 6209 * When "str" is NULL use number "nr", otherwise use "str". 6210 * Returns FAIL when out of memory and when key already exists. 6211 */ 6212 int 6213 dict_add_nr_str(d, key, nr, str) 6214 dict_T *d; 6215 char *key; 6216 long nr; 6217 char_u *str; 6218 { 6219 dictitem_T *item; 6220 6221 item = dictitem_alloc((char_u *)key); 6222 if (item == NULL) 6223 return FAIL; 6224 item->di_tv.v_lock = 0; 6225 if (str == NULL) 6226 { 6227 item->di_tv.v_type = VAR_NUMBER; 6228 item->di_tv.vval.v_number = nr; 6229 } 6230 else 6231 { 6232 item->di_tv.v_type = VAR_STRING; 6233 item->di_tv.vval.v_string = vim_strsave(str); 6234 } 6235 if (dict_add(d, item) == FAIL) 6236 { 6237 dictitem_free(item); 6238 return FAIL; 6239 } 6240 return OK; 6241 } 6242 6243 /* 6244 * Get the number of items in a Dictionary. 6245 */ 6246 static long 6247 dict_len(d) 6248 dict_T *d; 6249 { 6250 if (d == NULL) 6251 return 0L; 6252 return d->dv_hashtab.ht_used; 6253 } 6254 6255 /* 6256 * Find item "key[len]" in Dictionary "d". 6257 * If "len" is negative use strlen(key). 6258 * Returns NULL when not found. 6259 */ 6260 static dictitem_T * 6261 dict_find(d, key, len) 6262 dict_T *d; 6263 char_u *key; 6264 int len; 6265 { 6266 #define AKEYLEN 200 6267 char_u buf[AKEYLEN]; 6268 char_u *akey; 6269 char_u *tofree = NULL; 6270 hashitem_T *hi; 6271 6272 if (len < 0) 6273 akey = key; 6274 else if (len >= AKEYLEN) 6275 { 6276 tofree = akey = vim_strnsave(key, len); 6277 if (akey == NULL) 6278 return NULL; 6279 } 6280 else 6281 { 6282 /* Avoid a malloc/free by using buf[]. */ 6283 vim_strncpy(buf, key, len); 6284 akey = buf; 6285 } 6286 6287 hi = hash_find(&d->dv_hashtab, akey); 6288 vim_free(tofree); 6289 if (HASHITEM_EMPTY(hi)) 6290 return NULL; 6291 return HI2DI(hi); 6292 } 6293 6294 /* 6295 * Get a string item from a dictionary in allocated memory. 6296 * Returns NULL if the entry doesn't exist or out of memory. 6297 */ 6298 char_u * 6299 get_dict_string(d, key) 6300 dict_T *d; 6301 char_u *key; 6302 { 6303 dictitem_T *di; 6304 6305 di = dict_find(d, key, -1); 6306 if (di == NULL) 6307 return NULL; 6308 return vim_strsave(get_tv_string(&di->di_tv)); 6309 } 6310 6311 /* 6312 * Get a number item from a dictionary. 6313 * Returns 0 if the entry doesn't exist or out of memory. 6314 */ 6315 long 6316 get_dict_number(d, key) 6317 dict_T *d; 6318 char_u *key; 6319 { 6320 dictitem_T *di; 6321 6322 di = dict_find(d, key, -1); 6323 if (di == NULL) 6324 return 0; 6325 return get_tv_number(&di->di_tv); 6326 } 6327 6328 /* 6329 * Return an allocated string with the string representation of a Dictionary. 6330 * May return NULL. 6331 */ 6332 static char_u * 6333 dict2string(tv) 6334 typval_T *tv; 6335 { 6336 garray_T ga; 6337 int first = TRUE; 6338 char_u *tofree; 6339 char_u numbuf[NUMBUFLEN]; 6340 hashitem_T *hi; 6341 char_u *s; 6342 dict_T *d; 6343 int todo; 6344 6345 if ((d = tv->vval.v_dict) == NULL) 6346 return NULL; 6347 ga_init2(&ga, (int)sizeof(char), 80); 6348 ga_append(&ga, '{'); 6349 6350 todo = d->dv_hashtab.ht_used; 6351 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6352 { 6353 if (!HASHITEM_EMPTY(hi)) 6354 { 6355 --todo; 6356 6357 if (first) 6358 first = FALSE; 6359 else 6360 ga_concat(&ga, (char_u *)", "); 6361 6362 tofree = string_quote(hi->hi_key, FALSE); 6363 if (tofree != NULL) 6364 { 6365 ga_concat(&ga, tofree); 6366 vim_free(tofree); 6367 } 6368 ga_concat(&ga, (char_u *)": "); 6369 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6370 if (s != NULL) 6371 ga_concat(&ga, s); 6372 vim_free(tofree); 6373 if (s == NULL) 6374 break; 6375 } 6376 } 6377 if (todo > 0) 6378 { 6379 vim_free(ga.ga_data); 6380 return NULL; 6381 } 6382 6383 ga_append(&ga, '}'); 6384 ga_append(&ga, NUL); 6385 return (char_u *)ga.ga_data; 6386 } 6387 6388 /* 6389 * Allocate a variable for a Dictionary and fill it from "*arg". 6390 * Return OK or FAIL. Returns NOTDONE for {expr}. 6391 */ 6392 static int 6393 get_dict_tv(arg, rettv, evaluate) 6394 char_u **arg; 6395 typval_T *rettv; 6396 int evaluate; 6397 { 6398 dict_T *d = NULL; 6399 typval_T tvkey; 6400 typval_T tv; 6401 char_u *key; 6402 dictitem_T *item; 6403 char_u *start = skipwhite(*arg + 1); 6404 char_u buf[NUMBUFLEN]; 6405 6406 /* 6407 * First check if it's not a curly-braces thing: {expr}. 6408 * Must do this without evaluating, otherwise a function may be called 6409 * twice. Unfortunately this means we need to call eval1() twice for the 6410 * first item. 6411 * But {} is an empty Dictionary. 6412 */ 6413 if (*start != '}') 6414 { 6415 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6416 return FAIL; 6417 if (*start == '}') 6418 return NOTDONE; 6419 } 6420 6421 if (evaluate) 6422 { 6423 d = dict_alloc(); 6424 if (d == NULL) 6425 return FAIL; 6426 } 6427 tvkey.v_type = VAR_UNKNOWN; 6428 tv.v_type = VAR_UNKNOWN; 6429 6430 *arg = skipwhite(*arg + 1); 6431 while (**arg != '}' && **arg != NUL) 6432 { 6433 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6434 goto failret; 6435 if (**arg != ':') 6436 { 6437 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6438 clear_tv(&tvkey); 6439 goto failret; 6440 } 6441 key = get_tv_string_buf_chk(&tvkey, buf); 6442 if (key == NULL || *key == NUL) 6443 { 6444 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6445 if (key != NULL) 6446 EMSG(_(e_emptykey)); 6447 clear_tv(&tvkey); 6448 goto failret; 6449 } 6450 6451 *arg = skipwhite(*arg + 1); 6452 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6453 { 6454 clear_tv(&tvkey); 6455 goto failret; 6456 } 6457 if (evaluate) 6458 { 6459 item = dict_find(d, key, -1); 6460 if (item != NULL) 6461 { 6462 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6463 clear_tv(&tvkey); 6464 clear_tv(&tv); 6465 goto failret; 6466 } 6467 item = dictitem_alloc(key); 6468 clear_tv(&tvkey); 6469 if (item != NULL) 6470 { 6471 item->di_tv = tv; 6472 item->di_tv.v_lock = 0; 6473 if (dict_add(d, item) == FAIL) 6474 dictitem_free(item); 6475 } 6476 } 6477 6478 if (**arg == '}') 6479 break; 6480 if (**arg != ',') 6481 { 6482 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6483 goto failret; 6484 } 6485 *arg = skipwhite(*arg + 1); 6486 } 6487 6488 if (**arg != '}') 6489 { 6490 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6491 failret: 6492 if (evaluate) 6493 dict_free(d); 6494 return FAIL; 6495 } 6496 6497 *arg = skipwhite(*arg + 1); 6498 if (evaluate) 6499 { 6500 rettv->v_type = VAR_DICT; 6501 rettv->vval.v_dict = d; 6502 ++d->dv_refcount; 6503 } 6504 6505 return OK; 6506 } 6507 6508 /* 6509 * Return a string with the string representation of a variable. 6510 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6511 * "numbuf" is used for a number. 6512 * Does not put quotes around strings, as ":echo" displays values. 6513 * May return NULL; 6514 */ 6515 static char_u * 6516 echo_string(tv, tofree, numbuf) 6517 typval_T *tv; 6518 char_u **tofree; 6519 char_u *numbuf; 6520 { 6521 static int recurse = 0; 6522 char_u *r = NULL; 6523 6524 if (recurse >= DICT_MAXNEST) 6525 { 6526 EMSG(_("E724: variable nested too deep for displaying")); 6527 *tofree = NULL; 6528 return NULL; 6529 } 6530 ++recurse; 6531 6532 switch (tv->v_type) 6533 { 6534 case VAR_FUNC: 6535 *tofree = NULL; 6536 r = tv->vval.v_string; 6537 break; 6538 case VAR_LIST: 6539 *tofree = list2string(tv); 6540 r = *tofree; 6541 break; 6542 case VAR_DICT: 6543 *tofree = dict2string(tv); 6544 r = *tofree; 6545 break; 6546 case VAR_STRING: 6547 case VAR_NUMBER: 6548 *tofree = NULL; 6549 r = get_tv_string_buf(tv, numbuf); 6550 break; 6551 default: 6552 EMSG2(_(e_intern2), "echo_string()"); 6553 *tofree = NULL; 6554 } 6555 6556 --recurse; 6557 return r; 6558 } 6559 6560 /* 6561 * Return a string with the string representation of a variable. 6562 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6563 * "numbuf" is used for a number. 6564 * Puts quotes around strings, so that they can be parsed back by eval(). 6565 * May return NULL; 6566 */ 6567 static char_u * 6568 tv2string(tv, tofree, numbuf) 6569 typval_T *tv; 6570 char_u **tofree; 6571 char_u *numbuf; 6572 { 6573 switch (tv->v_type) 6574 { 6575 case VAR_FUNC: 6576 *tofree = string_quote(tv->vval.v_string, TRUE); 6577 return *tofree; 6578 case VAR_STRING: 6579 *tofree = string_quote(tv->vval.v_string, FALSE); 6580 return *tofree; 6581 case VAR_NUMBER: 6582 case VAR_LIST: 6583 case VAR_DICT: 6584 break; 6585 default: 6586 EMSG2(_(e_intern2), "tv2string()"); 6587 } 6588 return echo_string(tv, tofree, numbuf); 6589 } 6590 6591 /* 6592 * Return string "str" in ' quotes, doubling ' characters. 6593 * If "str" is NULL an empty string is assumed. 6594 * If "function" is TRUE make it function('string'). 6595 */ 6596 static char_u * 6597 string_quote(str, function) 6598 char_u *str; 6599 int function; 6600 { 6601 unsigned len; 6602 char_u *p, *r, *s; 6603 6604 len = (function ? 13 : 3); 6605 if (str != NULL) 6606 { 6607 len += STRLEN(str); 6608 for (p = str; *p != NUL; mb_ptr_adv(p)) 6609 if (*p == '\'') 6610 ++len; 6611 } 6612 s = r = alloc(len); 6613 if (r != NULL) 6614 { 6615 if (function) 6616 { 6617 STRCPY(r, "function('"); 6618 r += 10; 6619 } 6620 else 6621 *r++ = '\''; 6622 if (str != NULL) 6623 for (p = str; *p != NUL; ) 6624 { 6625 if (*p == '\'') 6626 *r++ = '\''; 6627 MB_COPY_CHAR(p, r); 6628 } 6629 *r++ = '\''; 6630 if (function) 6631 *r++ = ')'; 6632 *r++ = NUL; 6633 } 6634 return s; 6635 } 6636 6637 /* 6638 * Get the value of an environment variable. 6639 * "arg" is pointing to the '$'. It is advanced to after the name. 6640 * If the environment variable was not set, silently assume it is empty. 6641 * Always return OK. 6642 */ 6643 static int 6644 get_env_tv(arg, rettv, evaluate) 6645 char_u **arg; 6646 typval_T *rettv; 6647 int evaluate; 6648 { 6649 char_u *string = NULL; 6650 int len; 6651 int cc; 6652 char_u *name; 6653 int mustfree = FALSE; 6654 6655 ++*arg; 6656 name = *arg; 6657 len = get_env_len(arg); 6658 if (evaluate) 6659 { 6660 if (len != 0) 6661 { 6662 cc = name[len]; 6663 name[len] = NUL; 6664 /* first try vim_getenv(), fast for normal environment vars */ 6665 string = vim_getenv(name, &mustfree); 6666 if (string != NULL && *string != NUL) 6667 { 6668 if (!mustfree) 6669 string = vim_strsave(string); 6670 } 6671 else 6672 { 6673 if (mustfree) 6674 vim_free(string); 6675 6676 /* next try expanding things like $VIM and ${HOME} */ 6677 string = expand_env_save(name - 1); 6678 if (string != NULL && *string == '$') 6679 { 6680 vim_free(string); 6681 string = NULL; 6682 } 6683 } 6684 name[len] = cc; 6685 } 6686 rettv->v_type = VAR_STRING; 6687 rettv->vval.v_string = string; 6688 } 6689 6690 return OK; 6691 } 6692 6693 /* 6694 * Array with names and number of arguments of all internal functions 6695 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6696 */ 6697 static struct fst 6698 { 6699 char *f_name; /* function name */ 6700 char f_min_argc; /* minimal number of arguments */ 6701 char f_max_argc; /* maximal number of arguments */ 6702 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6703 /* implemenation of function */ 6704 } functions[] = 6705 { 6706 {"add", 2, 2, f_add}, 6707 {"append", 2, 2, f_append}, 6708 {"argc", 0, 0, f_argc}, 6709 {"argidx", 0, 0, f_argidx}, 6710 {"argv", 1, 1, f_argv}, 6711 {"browse", 4, 4, f_browse}, 6712 {"browsedir", 2, 2, f_browsedir}, 6713 {"bufexists", 1, 1, f_bufexists}, 6714 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6715 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6716 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6717 {"buflisted", 1, 1, f_buflisted}, 6718 {"bufloaded", 1, 1, f_bufloaded}, 6719 {"bufname", 1, 1, f_bufname}, 6720 {"bufnr", 1, 1, f_bufnr}, 6721 {"bufwinnr", 1, 1, f_bufwinnr}, 6722 {"byte2line", 1, 1, f_byte2line}, 6723 {"byteidx", 2, 2, f_byteidx}, 6724 {"call", 2, 3, f_call}, 6725 {"char2nr", 1, 1, f_char2nr}, 6726 {"cindent", 1, 1, f_cindent}, 6727 {"col", 1, 1, f_col}, 6728 #if defined(FEAT_INS_EXPAND) 6729 {"complete_add", 1, 1, f_complete_add}, 6730 {"complete_check", 0, 0, f_complete_check}, 6731 #endif 6732 {"confirm", 1, 4, f_confirm}, 6733 {"copy", 1, 1, f_copy}, 6734 {"count", 2, 4, f_count}, 6735 {"cscope_connection",0,3, f_cscope_connection}, 6736 {"cursor", 2, 2, f_cursor}, 6737 {"deepcopy", 1, 2, f_deepcopy}, 6738 {"delete", 1, 1, f_delete}, 6739 {"did_filetype", 0, 0, f_did_filetype}, 6740 {"diff_filler", 1, 1, f_diff_filler}, 6741 {"diff_hlID", 2, 2, f_diff_hlID}, 6742 {"empty", 1, 1, f_empty}, 6743 {"escape", 2, 2, f_escape}, 6744 {"eval", 1, 1, f_eval}, 6745 {"eventhandler", 0, 0, f_eventhandler}, 6746 {"executable", 1, 1, f_executable}, 6747 {"exists", 1, 1, f_exists}, 6748 {"expand", 1, 2, f_expand}, 6749 {"extend", 2, 3, f_extend}, 6750 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6751 {"filereadable", 1, 1, f_filereadable}, 6752 {"filewritable", 1, 1, f_filewritable}, 6753 {"filter", 2, 2, f_filter}, 6754 {"finddir", 1, 3, f_finddir}, 6755 {"findfile", 1, 3, f_findfile}, 6756 {"fnamemodify", 2, 2, f_fnamemodify}, 6757 {"foldclosed", 1, 1, f_foldclosed}, 6758 {"foldclosedend", 1, 1, f_foldclosedend}, 6759 {"foldlevel", 1, 1, f_foldlevel}, 6760 {"foldtext", 0, 0, f_foldtext}, 6761 {"foldtextresult", 1, 1, f_foldtextresult}, 6762 {"foreground", 0, 0, f_foreground}, 6763 {"function", 1, 1, f_function}, 6764 {"garbagecollect", 0, 0, f_garbagecollect}, 6765 {"get", 2, 3, f_get}, 6766 {"getbufline", 2, 3, f_getbufline}, 6767 {"getbufvar", 2, 2, f_getbufvar}, 6768 {"getchar", 0, 1, f_getchar}, 6769 {"getcharmod", 0, 0, f_getcharmod}, 6770 {"getcmdline", 0, 0, f_getcmdline}, 6771 {"getcmdpos", 0, 0, f_getcmdpos}, 6772 {"getcwd", 0, 0, f_getcwd}, 6773 {"getfontname", 0, 1, f_getfontname}, 6774 {"getfperm", 1, 1, f_getfperm}, 6775 {"getfsize", 1, 1, f_getfsize}, 6776 {"getftime", 1, 1, f_getftime}, 6777 {"getftype", 1, 1, f_getftype}, 6778 {"getline", 1, 2, f_getline}, 6779 {"getqflist", 0, 0, f_getqflist}, 6780 {"getreg", 0, 2, f_getreg}, 6781 {"getregtype", 0, 1, f_getregtype}, 6782 {"getwinposx", 0, 0, f_getwinposx}, 6783 {"getwinposy", 0, 0, f_getwinposy}, 6784 {"getwinvar", 2, 2, f_getwinvar}, 6785 {"glob", 1, 1, f_glob}, 6786 {"globpath", 2, 2, f_globpath}, 6787 {"has", 1, 1, f_has}, 6788 {"has_key", 2, 2, f_has_key}, 6789 {"hasmapto", 1, 2, f_hasmapto}, 6790 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6791 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6792 {"histadd", 2, 2, f_histadd}, 6793 {"histdel", 1, 2, f_histdel}, 6794 {"histget", 1, 2, f_histget}, 6795 {"histnr", 1, 1, f_histnr}, 6796 {"hlID", 1, 1, f_hlID}, 6797 {"hlexists", 1, 1, f_hlexists}, 6798 {"hostname", 0, 0, f_hostname}, 6799 {"iconv", 3, 3, f_iconv}, 6800 {"indent", 1, 1, f_indent}, 6801 {"index", 2, 4, f_index}, 6802 {"input", 1, 2, f_input}, 6803 {"inputdialog", 1, 3, f_inputdialog}, 6804 {"inputlist", 1, 1, f_inputlist}, 6805 {"inputrestore", 0, 0, f_inputrestore}, 6806 {"inputsave", 0, 0, f_inputsave}, 6807 {"inputsecret", 1, 2, f_inputsecret}, 6808 {"insert", 2, 3, f_insert}, 6809 {"isdirectory", 1, 1, f_isdirectory}, 6810 {"islocked", 1, 1, f_islocked}, 6811 {"items", 1, 1, f_items}, 6812 {"join", 1, 2, f_join}, 6813 {"keys", 1, 1, f_keys}, 6814 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6815 {"len", 1, 1, f_len}, 6816 {"libcall", 3, 3, f_libcall}, 6817 {"libcallnr", 3, 3, f_libcallnr}, 6818 {"line", 1, 1, f_line}, 6819 {"line2byte", 1, 1, f_line2byte}, 6820 {"lispindent", 1, 1, f_lispindent}, 6821 {"localtime", 0, 0, f_localtime}, 6822 {"map", 2, 2, f_map}, 6823 {"maparg", 1, 2, f_maparg}, 6824 {"mapcheck", 1, 2, f_mapcheck}, 6825 {"match", 2, 4, f_match}, 6826 {"matchend", 2, 4, f_matchend}, 6827 {"matchlist", 2, 4, f_matchlist}, 6828 {"matchstr", 2, 4, f_matchstr}, 6829 {"max", 1, 1, f_max}, 6830 {"min", 1, 1, f_min}, 6831 #ifdef vim_mkdir 6832 {"mkdir", 1, 3, f_mkdir}, 6833 #endif 6834 {"mode", 0, 0, f_mode}, 6835 {"nextnonblank", 1, 1, f_nextnonblank}, 6836 {"nr2char", 1, 1, f_nr2char}, 6837 {"prevnonblank", 1, 1, f_prevnonblank}, 6838 {"printf", 2, 19, f_printf}, 6839 {"range", 1, 3, f_range}, 6840 {"readfile", 1, 3, f_readfile}, 6841 {"remote_expr", 2, 3, f_remote_expr}, 6842 {"remote_foreground", 1, 1, f_remote_foreground}, 6843 {"remote_peek", 1, 2, f_remote_peek}, 6844 {"remote_read", 1, 1, f_remote_read}, 6845 {"remote_send", 2, 3, f_remote_send}, 6846 {"remove", 2, 3, f_remove}, 6847 {"rename", 2, 2, f_rename}, 6848 {"repeat", 2, 2, f_repeat}, 6849 {"resolve", 1, 1, f_resolve}, 6850 {"reverse", 1, 1, f_reverse}, 6851 {"search", 1, 2, f_search}, 6852 {"searchdecl", 1, 2, f_searchdecl}, 6853 {"searchpair", 3, 5, f_searchpair}, 6854 {"server2client", 2, 2, f_server2client}, 6855 {"serverlist", 0, 0, f_serverlist}, 6856 {"setbufvar", 3, 3, f_setbufvar}, 6857 {"setcmdpos", 1, 1, f_setcmdpos}, 6858 {"setline", 2, 2, f_setline}, 6859 {"setqflist", 1, 2, f_setqflist}, 6860 {"setreg", 2, 3, f_setreg}, 6861 {"setwinvar", 3, 3, f_setwinvar}, 6862 {"simplify", 1, 1, f_simplify}, 6863 {"sort", 1, 2, f_sort}, 6864 {"soundfold", 1, 1, f_soundfold}, 6865 {"spellbadword", 0, 0, f_spellbadword}, 6866 {"spellsuggest", 1, 2, f_spellsuggest}, 6867 {"split", 1, 3, f_split}, 6868 #ifdef HAVE_STRFTIME 6869 {"strftime", 1, 2, f_strftime}, 6870 #endif 6871 {"stridx", 2, 3, f_stridx}, 6872 {"string", 1, 1, f_string}, 6873 {"strlen", 1, 1, f_strlen}, 6874 {"strpart", 2, 3, f_strpart}, 6875 {"strridx", 2, 3, f_strridx}, 6876 {"strtrans", 1, 1, f_strtrans}, 6877 {"submatch", 1, 1, f_submatch}, 6878 {"substitute", 4, 4, f_substitute}, 6879 {"synID", 3, 3, f_synID}, 6880 {"synIDattr", 2, 3, f_synIDattr}, 6881 {"synIDtrans", 1, 1, f_synIDtrans}, 6882 {"system", 1, 2, f_system}, 6883 {"tagfiles", 0, 0, f_tagfiles}, 6884 {"taglist", 1, 1, f_taglist}, 6885 {"tempname", 0, 0, f_tempname}, 6886 {"test", 1, 1, f_test}, 6887 {"tolower", 1, 1, f_tolower}, 6888 {"toupper", 1, 1, f_toupper}, 6889 {"tr", 3, 3, f_tr}, 6890 {"type", 1, 1, f_type}, 6891 {"values", 1, 1, f_values}, 6892 {"virtcol", 1, 1, f_virtcol}, 6893 {"visualmode", 0, 1, f_visualmode}, 6894 {"winbufnr", 1, 1, f_winbufnr}, 6895 {"wincol", 0, 0, f_wincol}, 6896 {"winheight", 1, 1, f_winheight}, 6897 {"winline", 0, 0, f_winline}, 6898 {"winnr", 0, 1, f_winnr}, 6899 {"winrestcmd", 0, 0, f_winrestcmd}, 6900 {"winwidth", 1, 1, f_winwidth}, 6901 {"writefile", 2, 3, f_writefile}, 6902 }; 6903 6904 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6905 6906 /* 6907 * Function given to ExpandGeneric() to obtain the list of internal 6908 * or user defined function names. 6909 */ 6910 char_u * 6911 get_function_name(xp, idx) 6912 expand_T *xp; 6913 int idx; 6914 { 6915 static int intidx = -1; 6916 char_u *name; 6917 6918 if (idx == 0) 6919 intidx = -1; 6920 if (intidx < 0) 6921 { 6922 name = get_user_func_name(xp, idx); 6923 if (name != NULL) 6924 return name; 6925 } 6926 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6927 { 6928 STRCPY(IObuff, functions[intidx].f_name); 6929 STRCAT(IObuff, "("); 6930 if (functions[intidx].f_max_argc == 0) 6931 STRCAT(IObuff, ")"); 6932 return IObuff; 6933 } 6934 6935 return NULL; 6936 } 6937 6938 /* 6939 * Function given to ExpandGeneric() to obtain the list of internal or 6940 * user defined variable or function names. 6941 */ 6942 /*ARGSUSED*/ 6943 char_u * 6944 get_expr_name(xp, idx) 6945 expand_T *xp; 6946 int idx; 6947 { 6948 static int intidx = -1; 6949 char_u *name; 6950 6951 if (idx == 0) 6952 intidx = -1; 6953 if (intidx < 0) 6954 { 6955 name = get_function_name(xp, idx); 6956 if (name != NULL) 6957 return name; 6958 } 6959 return get_user_var_name(xp, ++intidx); 6960 } 6961 6962 #endif /* FEAT_CMDL_COMPL */ 6963 6964 /* 6965 * Find internal function in table above. 6966 * Return index, or -1 if not found 6967 */ 6968 static int 6969 find_internal_func(name) 6970 char_u *name; /* name of the function */ 6971 { 6972 int first = 0; 6973 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 6974 int cmp; 6975 int x; 6976 6977 /* 6978 * Find the function name in the table. Binary search. 6979 */ 6980 while (first <= last) 6981 { 6982 x = first + ((unsigned)(last - first) >> 1); 6983 cmp = STRCMP(name, functions[x].f_name); 6984 if (cmp < 0) 6985 last = x - 1; 6986 else if (cmp > 0) 6987 first = x + 1; 6988 else 6989 return x; 6990 } 6991 return -1; 6992 } 6993 6994 /* 6995 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 6996 * name it contains, otherwise return "name". 6997 */ 6998 static char_u * 6999 deref_func_name(name, lenp) 7000 char_u *name; 7001 int *lenp; 7002 { 7003 dictitem_T *v; 7004 int cc; 7005 7006 cc = name[*lenp]; 7007 name[*lenp] = NUL; 7008 v = find_var(name, NULL); 7009 name[*lenp] = cc; 7010 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7011 { 7012 if (v->di_tv.vval.v_string == NULL) 7013 { 7014 *lenp = 0; 7015 return (char_u *)""; /* just in case */ 7016 } 7017 *lenp = STRLEN(v->di_tv.vval.v_string); 7018 return v->di_tv.vval.v_string; 7019 } 7020 7021 return name; 7022 } 7023 7024 /* 7025 * Allocate a variable for the result of a function. 7026 * Return OK or FAIL. 7027 */ 7028 static int 7029 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7030 evaluate, selfdict) 7031 char_u *name; /* name of the function */ 7032 int len; /* length of "name" */ 7033 typval_T *rettv; 7034 char_u **arg; /* argument, pointing to the '(' */ 7035 linenr_T firstline; /* first line of range */ 7036 linenr_T lastline; /* last line of range */ 7037 int *doesrange; /* return: function handled range */ 7038 int evaluate; 7039 dict_T *selfdict; /* Dictionary for "self" */ 7040 { 7041 char_u *argp; 7042 int ret = OK; 7043 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7044 int argcount = 0; /* number of arguments found */ 7045 7046 /* 7047 * Get the arguments. 7048 */ 7049 argp = *arg; 7050 while (argcount < MAX_FUNC_ARGS) 7051 { 7052 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7053 if (*argp == ')' || *argp == ',' || *argp == NUL) 7054 break; 7055 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7056 { 7057 ret = FAIL; 7058 break; 7059 } 7060 ++argcount; 7061 if (*argp != ',') 7062 break; 7063 } 7064 if (*argp == ')') 7065 ++argp; 7066 else 7067 ret = FAIL; 7068 7069 if (ret == OK) 7070 ret = call_func(name, len, rettv, argcount, argvars, 7071 firstline, lastline, doesrange, evaluate, selfdict); 7072 else if (!aborting()) 7073 { 7074 if (argcount == MAX_FUNC_ARGS) 7075 emsg_funcname("E740: Too many arguments for function %s", name); 7076 else 7077 emsg_funcname("E116: Invalid arguments for function %s", name); 7078 } 7079 7080 while (--argcount >= 0) 7081 clear_tv(&argvars[argcount]); 7082 7083 *arg = skipwhite(argp); 7084 return ret; 7085 } 7086 7087 7088 /* 7089 * Call a function with its resolved parameters 7090 * Return OK or FAIL. 7091 */ 7092 static int 7093 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7094 doesrange, evaluate, selfdict) 7095 char_u *name; /* name of the function */ 7096 int len; /* length of "name" */ 7097 typval_T *rettv; /* return value goes here */ 7098 int argcount; /* number of "argvars" */ 7099 typval_T *argvars; /* vars for arguments */ 7100 linenr_T firstline; /* first line of range */ 7101 linenr_T lastline; /* last line of range */ 7102 int *doesrange; /* return: function handled range */ 7103 int evaluate; 7104 dict_T *selfdict; /* Dictionary for "self" */ 7105 { 7106 int ret = FAIL; 7107 #define ERROR_UNKNOWN 0 7108 #define ERROR_TOOMANY 1 7109 #define ERROR_TOOFEW 2 7110 #define ERROR_SCRIPT 3 7111 #define ERROR_DICT 4 7112 #define ERROR_NONE 5 7113 #define ERROR_OTHER 6 7114 int error = ERROR_NONE; 7115 int i; 7116 int llen; 7117 ufunc_T *fp; 7118 int cc; 7119 #define FLEN_FIXED 40 7120 char_u fname_buf[FLEN_FIXED + 1]; 7121 char_u *fname; 7122 7123 /* 7124 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7125 * Change <SNR>123_name() to K_SNR 123_name(). 7126 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7127 */ 7128 cc = name[len]; 7129 name[len] = NUL; 7130 llen = eval_fname_script(name); 7131 if (llen > 0) 7132 { 7133 fname_buf[0] = K_SPECIAL; 7134 fname_buf[1] = KS_EXTRA; 7135 fname_buf[2] = (int)KE_SNR; 7136 i = 3; 7137 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7138 { 7139 if (current_SID <= 0) 7140 error = ERROR_SCRIPT; 7141 else 7142 { 7143 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7144 i = (int)STRLEN(fname_buf); 7145 } 7146 } 7147 if (i + STRLEN(name + llen) < FLEN_FIXED) 7148 { 7149 STRCPY(fname_buf + i, name + llen); 7150 fname = fname_buf; 7151 } 7152 else 7153 { 7154 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7155 if (fname == NULL) 7156 error = ERROR_OTHER; 7157 else 7158 { 7159 mch_memmove(fname, fname_buf, (size_t)i); 7160 STRCPY(fname + i, name + llen); 7161 } 7162 } 7163 } 7164 else 7165 fname = name; 7166 7167 *doesrange = FALSE; 7168 7169 7170 /* execute the function if no errors detected and executing */ 7171 if (evaluate && error == ERROR_NONE) 7172 { 7173 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7174 error = ERROR_UNKNOWN; 7175 7176 if (!builtin_function(fname)) 7177 { 7178 /* 7179 * User defined function. 7180 */ 7181 fp = find_func(fname); 7182 7183 #ifdef FEAT_AUTOCMD 7184 /* Trigger FuncUndefined event, may load the function. */ 7185 if (fp == NULL 7186 && apply_autocmds(EVENT_FUNCUNDEFINED, 7187 fname, fname, TRUE, NULL) 7188 && !aborting()) 7189 { 7190 /* executed an autocommand, search for the function again */ 7191 fp = find_func(fname); 7192 } 7193 #endif 7194 /* Try loading a package. */ 7195 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7196 { 7197 /* loaded a package, search for the function again */ 7198 fp = find_func(fname); 7199 } 7200 7201 if (fp != NULL) 7202 { 7203 if (fp->uf_flags & FC_RANGE) 7204 *doesrange = TRUE; 7205 if (argcount < fp->uf_args.ga_len) 7206 error = ERROR_TOOFEW; 7207 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7208 error = ERROR_TOOMANY; 7209 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7210 error = ERROR_DICT; 7211 else 7212 { 7213 /* 7214 * Call the user function. 7215 * Save and restore search patterns, script variables and 7216 * redo buffer. 7217 */ 7218 save_search_patterns(); 7219 saveRedobuff(); 7220 ++fp->uf_calls; 7221 call_user_func(fp, argcount, argvars, rettv, 7222 firstline, lastline, 7223 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7224 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7225 && fp->uf_refcount <= 0) 7226 /* Function was unreferenced while being used, free it 7227 * now. */ 7228 func_free(fp); 7229 restoreRedobuff(); 7230 restore_search_patterns(); 7231 error = ERROR_NONE; 7232 } 7233 } 7234 } 7235 else 7236 { 7237 /* 7238 * Find the function name in the table, call its implementation. 7239 */ 7240 i = find_internal_func(fname); 7241 if (i >= 0) 7242 { 7243 if (argcount < functions[i].f_min_argc) 7244 error = ERROR_TOOFEW; 7245 else if (argcount > functions[i].f_max_argc) 7246 error = ERROR_TOOMANY; 7247 else 7248 { 7249 argvars[argcount].v_type = VAR_UNKNOWN; 7250 functions[i].f_func(argvars, rettv); 7251 error = ERROR_NONE; 7252 } 7253 } 7254 } 7255 /* 7256 * The function call (or "FuncUndefined" autocommand sequence) might 7257 * have been aborted by an error, an interrupt, or an explicitly thrown 7258 * exception that has not been caught so far. This situation can be 7259 * tested for by calling aborting(). For an error in an internal 7260 * function or for the "E132" error in call_user_func(), however, the 7261 * throw point at which the "force_abort" flag (temporarily reset by 7262 * emsg()) is normally updated has not been reached yet. We need to 7263 * update that flag first to make aborting() reliable. 7264 */ 7265 update_force_abort(); 7266 } 7267 if (error == ERROR_NONE) 7268 ret = OK; 7269 7270 /* 7271 * Report an error unless the argument evaluation or function call has been 7272 * cancelled due to an aborting error, an interrupt, or an exception. 7273 */ 7274 if (!aborting()) 7275 { 7276 switch (error) 7277 { 7278 case ERROR_UNKNOWN: 7279 emsg_funcname("E117: Unknown function: %s", name); 7280 break; 7281 case ERROR_TOOMANY: 7282 emsg_funcname(e_toomanyarg, name); 7283 break; 7284 case ERROR_TOOFEW: 7285 emsg_funcname("E119: Not enough arguments for function: %s", 7286 name); 7287 break; 7288 case ERROR_SCRIPT: 7289 emsg_funcname("E120: Using <SID> not in a script context: %s", 7290 name); 7291 break; 7292 case ERROR_DICT: 7293 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7294 name); 7295 break; 7296 } 7297 } 7298 7299 name[len] = cc; 7300 if (fname != name && fname != fname_buf) 7301 vim_free(fname); 7302 7303 return ret; 7304 } 7305 7306 /* 7307 * Give an error message with a function name. Handle <SNR> things. 7308 */ 7309 static void 7310 emsg_funcname(msg, name) 7311 char *msg; 7312 char_u *name; 7313 { 7314 char_u *p; 7315 7316 if (*name == K_SPECIAL) 7317 p = concat_str((char_u *)"<SNR>", name + 3); 7318 else 7319 p = name; 7320 EMSG2(_(msg), p); 7321 if (p != name) 7322 vim_free(p); 7323 } 7324 7325 /********************************************* 7326 * Implementation of the built-in functions 7327 */ 7328 7329 /* 7330 * "add(list, item)" function 7331 */ 7332 static void 7333 f_add(argvars, rettv) 7334 typval_T *argvars; 7335 typval_T *rettv; 7336 { 7337 list_T *l; 7338 7339 rettv->vval.v_number = 1; /* Default: Failed */ 7340 if (argvars[0].v_type == VAR_LIST) 7341 { 7342 if ((l = argvars[0].vval.v_list) != NULL 7343 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7344 && list_append_tv(l, &argvars[1]) == OK) 7345 copy_tv(&argvars[0], rettv); 7346 } 7347 else 7348 EMSG(_(e_listreq)); 7349 } 7350 7351 /* 7352 * "append(lnum, string/list)" function 7353 */ 7354 static void 7355 f_append(argvars, rettv) 7356 typval_T *argvars; 7357 typval_T *rettv; 7358 { 7359 long lnum; 7360 char_u *line; 7361 list_T *l = NULL; 7362 listitem_T *li = NULL; 7363 typval_T *tv; 7364 long added = 0; 7365 7366 lnum = get_tv_lnum(argvars); 7367 if (lnum >= 0 7368 && lnum <= curbuf->b_ml.ml_line_count 7369 && u_save(lnum, lnum + 1) == OK) 7370 { 7371 if (argvars[1].v_type == VAR_LIST) 7372 { 7373 l = argvars[1].vval.v_list; 7374 if (l == NULL) 7375 return; 7376 li = l->lv_first; 7377 } 7378 rettv->vval.v_number = 0; /* Default: Success */ 7379 for (;;) 7380 { 7381 if (l == NULL) 7382 tv = &argvars[1]; /* append a string */ 7383 else if (li == NULL) 7384 break; /* end of list */ 7385 else 7386 tv = &li->li_tv; /* append item from list */ 7387 line = get_tv_string_chk(tv); 7388 if (line == NULL) /* type error */ 7389 { 7390 rettv->vval.v_number = 1; /* Failed */ 7391 break; 7392 } 7393 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7394 ++added; 7395 if (l == NULL) 7396 break; 7397 li = li->li_next; 7398 } 7399 7400 appended_lines_mark(lnum, added); 7401 if (curwin->w_cursor.lnum > lnum) 7402 curwin->w_cursor.lnum += added; 7403 } 7404 else 7405 rettv->vval.v_number = 1; /* Failed */ 7406 } 7407 7408 /* 7409 * "argc()" function 7410 */ 7411 /* ARGSUSED */ 7412 static void 7413 f_argc(argvars, rettv) 7414 typval_T *argvars; 7415 typval_T *rettv; 7416 { 7417 rettv->vval.v_number = ARGCOUNT; 7418 } 7419 7420 /* 7421 * "argidx()" function 7422 */ 7423 /* ARGSUSED */ 7424 static void 7425 f_argidx(argvars, rettv) 7426 typval_T *argvars; 7427 typval_T *rettv; 7428 { 7429 rettv->vval.v_number = curwin->w_arg_idx; 7430 } 7431 7432 /* 7433 * "argv(nr)" function 7434 */ 7435 static void 7436 f_argv(argvars, rettv) 7437 typval_T *argvars; 7438 typval_T *rettv; 7439 { 7440 int idx; 7441 7442 idx = get_tv_number_chk(&argvars[0], NULL); 7443 if (idx >= 0 && idx < ARGCOUNT) 7444 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7445 else 7446 rettv->vval.v_string = NULL; 7447 rettv->v_type = VAR_STRING; 7448 } 7449 7450 /* 7451 * "browse(save, title, initdir, default)" function 7452 */ 7453 /* ARGSUSED */ 7454 static void 7455 f_browse(argvars, rettv) 7456 typval_T *argvars; 7457 typval_T *rettv; 7458 { 7459 #ifdef FEAT_BROWSE 7460 int save; 7461 char_u *title; 7462 char_u *initdir; 7463 char_u *defname; 7464 char_u buf[NUMBUFLEN]; 7465 char_u buf2[NUMBUFLEN]; 7466 int error = FALSE; 7467 7468 save = get_tv_number_chk(&argvars[0], &error); 7469 title = get_tv_string_chk(&argvars[1]); 7470 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7471 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7472 7473 if (error || title == NULL || initdir == NULL || defname == NULL) 7474 rettv->vval.v_string = NULL; 7475 else 7476 rettv->vval.v_string = 7477 do_browse(save ? BROWSE_SAVE : 0, 7478 title, defname, NULL, initdir, NULL, curbuf); 7479 #else 7480 rettv->vval.v_string = NULL; 7481 #endif 7482 rettv->v_type = VAR_STRING; 7483 } 7484 7485 /* 7486 * "browsedir(title, initdir)" function 7487 */ 7488 /* ARGSUSED */ 7489 static void 7490 f_browsedir(argvars, rettv) 7491 typval_T *argvars; 7492 typval_T *rettv; 7493 { 7494 #ifdef FEAT_BROWSE 7495 char_u *title; 7496 char_u *initdir; 7497 char_u buf[NUMBUFLEN]; 7498 7499 title = get_tv_string_chk(&argvars[0]); 7500 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7501 7502 if (title == NULL || initdir == NULL) 7503 rettv->vval.v_string = NULL; 7504 else 7505 rettv->vval.v_string = do_browse(BROWSE_DIR, 7506 title, NULL, NULL, initdir, NULL, curbuf); 7507 #else 7508 rettv->vval.v_string = NULL; 7509 #endif 7510 rettv->v_type = VAR_STRING; 7511 } 7512 7513 static buf_T *find_buffer __ARGS((typval_T *avar)); 7514 7515 /* 7516 * Find a buffer by number or exact name. 7517 */ 7518 static buf_T * 7519 find_buffer(avar) 7520 typval_T *avar; 7521 { 7522 buf_T *buf = NULL; 7523 7524 if (avar->v_type == VAR_NUMBER) 7525 buf = buflist_findnr((int)avar->vval.v_number); 7526 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7527 { 7528 buf = buflist_findname_exp(avar->vval.v_string); 7529 if (buf == NULL) 7530 { 7531 /* No full path name match, try a match with a URL or a "nofile" 7532 * buffer, these don't use the full path. */ 7533 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7534 if (buf->b_fname != NULL 7535 && (path_with_url(buf->b_fname) 7536 #ifdef FEAT_QUICKFIX 7537 || bt_nofile(buf) 7538 #endif 7539 ) 7540 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7541 break; 7542 } 7543 } 7544 return buf; 7545 } 7546 7547 /* 7548 * "bufexists(expr)" function 7549 */ 7550 static void 7551 f_bufexists(argvars, rettv) 7552 typval_T *argvars; 7553 typval_T *rettv; 7554 { 7555 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7556 } 7557 7558 /* 7559 * "buflisted(expr)" function 7560 */ 7561 static void 7562 f_buflisted(argvars, rettv) 7563 typval_T *argvars; 7564 typval_T *rettv; 7565 { 7566 buf_T *buf; 7567 7568 buf = find_buffer(&argvars[0]); 7569 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7570 } 7571 7572 /* 7573 * "bufloaded(expr)" function 7574 */ 7575 static void 7576 f_bufloaded(argvars, rettv) 7577 typval_T *argvars; 7578 typval_T *rettv; 7579 { 7580 buf_T *buf; 7581 7582 buf = find_buffer(&argvars[0]); 7583 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7584 } 7585 7586 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7587 7588 /* 7589 * Get buffer by number or pattern. 7590 */ 7591 static buf_T * 7592 get_buf_tv(tv) 7593 typval_T *tv; 7594 { 7595 char_u *name = tv->vval.v_string; 7596 int save_magic; 7597 char_u *save_cpo; 7598 buf_T *buf; 7599 7600 if (tv->v_type == VAR_NUMBER) 7601 return buflist_findnr((int)tv->vval.v_number); 7602 if (tv->v_type != VAR_STRING) 7603 return NULL; 7604 if (name == NULL || *name == NUL) 7605 return curbuf; 7606 if (name[0] == '$' && name[1] == NUL) 7607 return lastbuf; 7608 7609 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7610 save_magic = p_magic; 7611 p_magic = TRUE; 7612 save_cpo = p_cpo; 7613 p_cpo = (char_u *)""; 7614 7615 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7616 TRUE, FALSE)); 7617 7618 p_magic = save_magic; 7619 p_cpo = save_cpo; 7620 7621 /* If not found, try expanding the name, like done for bufexists(). */ 7622 if (buf == NULL) 7623 buf = find_buffer(tv); 7624 7625 return buf; 7626 } 7627 7628 /* 7629 * "bufname(expr)" function 7630 */ 7631 static void 7632 f_bufname(argvars, rettv) 7633 typval_T *argvars; 7634 typval_T *rettv; 7635 { 7636 buf_T *buf; 7637 7638 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7639 ++emsg_off; 7640 buf = get_buf_tv(&argvars[0]); 7641 rettv->v_type = VAR_STRING; 7642 if (buf != NULL && buf->b_fname != NULL) 7643 rettv->vval.v_string = vim_strsave(buf->b_fname); 7644 else 7645 rettv->vval.v_string = NULL; 7646 --emsg_off; 7647 } 7648 7649 /* 7650 * "bufnr(expr)" function 7651 */ 7652 static void 7653 f_bufnr(argvars, rettv) 7654 typval_T *argvars; 7655 typval_T *rettv; 7656 { 7657 buf_T *buf; 7658 7659 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7660 ++emsg_off; 7661 buf = get_buf_tv(&argvars[0]); 7662 if (buf != NULL) 7663 rettv->vval.v_number = buf->b_fnum; 7664 else 7665 rettv->vval.v_number = -1; 7666 --emsg_off; 7667 } 7668 7669 /* 7670 * "bufwinnr(nr)" function 7671 */ 7672 static void 7673 f_bufwinnr(argvars, rettv) 7674 typval_T *argvars; 7675 typval_T *rettv; 7676 { 7677 #ifdef FEAT_WINDOWS 7678 win_T *wp; 7679 int winnr = 0; 7680 #endif 7681 buf_T *buf; 7682 7683 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7684 ++emsg_off; 7685 buf = get_buf_tv(&argvars[0]); 7686 #ifdef FEAT_WINDOWS 7687 for (wp = firstwin; wp; wp = wp->w_next) 7688 { 7689 ++winnr; 7690 if (wp->w_buffer == buf) 7691 break; 7692 } 7693 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7694 #else 7695 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7696 #endif 7697 --emsg_off; 7698 } 7699 7700 /* 7701 * "byte2line(byte)" function 7702 */ 7703 /*ARGSUSED*/ 7704 static void 7705 f_byte2line(argvars, rettv) 7706 typval_T *argvars; 7707 typval_T *rettv; 7708 { 7709 #ifndef FEAT_BYTEOFF 7710 rettv->vval.v_number = -1; 7711 #else 7712 long boff = 0; 7713 7714 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7715 if (boff < 0) 7716 rettv->vval.v_number = -1; 7717 else 7718 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7719 (linenr_T)0, &boff); 7720 #endif 7721 } 7722 7723 /* 7724 * "byteidx()" function 7725 */ 7726 /*ARGSUSED*/ 7727 static void 7728 f_byteidx(argvars, rettv) 7729 typval_T *argvars; 7730 typval_T *rettv; 7731 { 7732 #ifdef FEAT_MBYTE 7733 char_u *t; 7734 #endif 7735 char_u *str; 7736 long idx; 7737 7738 str = get_tv_string_chk(&argvars[0]); 7739 idx = get_tv_number_chk(&argvars[1], NULL); 7740 rettv->vval.v_number = -1; 7741 if (str == NULL || idx < 0) 7742 return; 7743 7744 #ifdef FEAT_MBYTE 7745 t = str; 7746 for ( ; idx > 0; idx--) 7747 { 7748 if (*t == NUL) /* EOL reached */ 7749 return; 7750 t += (*mb_ptr2len)(t); 7751 } 7752 rettv->vval.v_number = t - str; 7753 #else 7754 if (idx <= STRLEN(str)) 7755 rettv->vval.v_number = idx; 7756 #endif 7757 } 7758 7759 /* 7760 * "call(func, arglist)" function 7761 */ 7762 static void 7763 f_call(argvars, rettv) 7764 typval_T *argvars; 7765 typval_T *rettv; 7766 { 7767 char_u *func; 7768 typval_T argv[MAX_FUNC_ARGS]; 7769 int argc = 0; 7770 listitem_T *item; 7771 int dummy; 7772 dict_T *selfdict = NULL; 7773 7774 rettv->vval.v_number = 0; 7775 if (argvars[1].v_type != VAR_LIST) 7776 { 7777 EMSG(_(e_listreq)); 7778 return; 7779 } 7780 if (argvars[1].vval.v_list == NULL) 7781 return; 7782 7783 if (argvars[0].v_type == VAR_FUNC) 7784 func = argvars[0].vval.v_string; 7785 else 7786 func = get_tv_string(&argvars[0]); 7787 if (*func == NUL) 7788 return; /* type error or empty name */ 7789 7790 if (argvars[2].v_type != VAR_UNKNOWN) 7791 { 7792 if (argvars[2].v_type != VAR_DICT) 7793 { 7794 EMSG(_(e_dictreq)); 7795 return; 7796 } 7797 selfdict = argvars[2].vval.v_dict; 7798 } 7799 7800 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7801 item = item->li_next) 7802 { 7803 if (argc == MAX_FUNC_ARGS) 7804 { 7805 EMSG(_("E699: Too many arguments")); 7806 break; 7807 } 7808 /* Make a copy of each argument. This is needed to be able to set 7809 * v_lock to VAR_FIXED in the copy without changing the original list. 7810 */ 7811 copy_tv(&item->li_tv, &argv[argc++]); 7812 } 7813 7814 if (item == NULL) 7815 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7816 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7817 &dummy, TRUE, selfdict); 7818 7819 /* Free the arguments. */ 7820 while (argc > 0) 7821 clear_tv(&argv[--argc]); 7822 } 7823 7824 /* 7825 * "char2nr(string)" function 7826 */ 7827 static void 7828 f_char2nr(argvars, rettv) 7829 typval_T *argvars; 7830 typval_T *rettv; 7831 { 7832 #ifdef FEAT_MBYTE 7833 if (has_mbyte) 7834 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7835 else 7836 #endif 7837 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7838 } 7839 7840 /* 7841 * "cindent(lnum)" function 7842 */ 7843 static void 7844 f_cindent(argvars, rettv) 7845 typval_T *argvars; 7846 typval_T *rettv; 7847 { 7848 #ifdef FEAT_CINDENT 7849 pos_T pos; 7850 linenr_T lnum; 7851 7852 pos = curwin->w_cursor; 7853 lnum = get_tv_lnum(argvars); 7854 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7855 { 7856 curwin->w_cursor.lnum = lnum; 7857 rettv->vval.v_number = get_c_indent(); 7858 curwin->w_cursor = pos; 7859 } 7860 else 7861 #endif 7862 rettv->vval.v_number = -1; 7863 } 7864 7865 /* 7866 * "col(string)" function 7867 */ 7868 static void 7869 f_col(argvars, rettv) 7870 typval_T *argvars; 7871 typval_T *rettv; 7872 { 7873 colnr_T col = 0; 7874 pos_T *fp; 7875 7876 fp = var2fpos(&argvars[0], FALSE); 7877 if (fp != NULL) 7878 { 7879 if (fp->col == MAXCOL) 7880 { 7881 /* '> can be MAXCOL, get the length of the line then */ 7882 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7883 col = STRLEN(ml_get(fp->lnum)) + 1; 7884 else 7885 col = MAXCOL; 7886 } 7887 else 7888 { 7889 col = fp->col + 1; 7890 #ifdef FEAT_VIRTUALEDIT 7891 /* col(".") when the cursor is on the NUL at the end of the line 7892 * because of "coladd" can be seen as an extra column. */ 7893 if (virtual_active() && fp == &curwin->w_cursor) 7894 { 7895 char_u *p = ml_get_cursor(); 7896 7897 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7898 curwin->w_virtcol - curwin->w_cursor.coladd)) 7899 { 7900 # ifdef FEAT_MBYTE 7901 int l; 7902 7903 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 7904 col += l; 7905 # else 7906 if (*p != NUL && p[1] == NUL) 7907 ++col; 7908 # endif 7909 } 7910 } 7911 #endif 7912 } 7913 } 7914 rettv->vval.v_number = col; 7915 } 7916 7917 #if defined(FEAT_INS_EXPAND) 7918 /* 7919 * "complete_add()" function 7920 */ 7921 /*ARGSUSED*/ 7922 static void 7923 f_complete_add(argvars, rettv) 7924 typval_T *argvars; 7925 typval_T *rettv; 7926 { 7927 char_u *s; 7928 7929 s = get_tv_string_chk(&argvars[0]); 7930 if (s != NULL) 7931 rettv->vval.v_number = ins_compl_add(s, -1, NULL, FORWARD, 0); 7932 } 7933 7934 /* 7935 * "complete_check()" function 7936 */ 7937 /*ARGSUSED*/ 7938 static void 7939 f_complete_check(argvars, rettv) 7940 typval_T *argvars; 7941 typval_T *rettv; 7942 { 7943 int saved = RedrawingDisabled; 7944 7945 RedrawingDisabled = 0; 7946 ins_compl_check_keys(0); 7947 rettv->vval.v_number = compl_interrupted; 7948 RedrawingDisabled = saved; 7949 } 7950 #endif 7951 7952 /* 7953 * "confirm(message, buttons[, default [, type]])" function 7954 */ 7955 /*ARGSUSED*/ 7956 static void 7957 f_confirm(argvars, rettv) 7958 typval_T *argvars; 7959 typval_T *rettv; 7960 { 7961 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7962 char_u *message; 7963 char_u *buttons = NULL; 7964 char_u buf[NUMBUFLEN]; 7965 char_u buf2[NUMBUFLEN]; 7966 int def = 1; 7967 int type = VIM_GENERIC; 7968 char_u *typestr; 7969 int error = FALSE; 7970 7971 message = get_tv_string_chk(&argvars[0]); 7972 if (message == NULL) 7973 error = TRUE; 7974 if (argvars[1].v_type != VAR_UNKNOWN) 7975 { 7976 buttons = get_tv_string_buf_chk(&argvars[1], buf); 7977 if (buttons == NULL) 7978 error = TRUE; 7979 if (argvars[2].v_type != VAR_UNKNOWN) 7980 { 7981 def = get_tv_number_chk(&argvars[2], &error); 7982 if (argvars[3].v_type != VAR_UNKNOWN) 7983 { 7984 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 7985 if (typestr == NULL) 7986 error = TRUE; 7987 else 7988 { 7989 switch (TOUPPER_ASC(*typestr)) 7990 { 7991 case 'E': type = VIM_ERROR; break; 7992 case 'Q': type = VIM_QUESTION; break; 7993 case 'I': type = VIM_INFO; break; 7994 case 'W': type = VIM_WARNING; break; 7995 case 'G': type = VIM_GENERIC; break; 7996 } 7997 } 7998 } 7999 } 8000 } 8001 8002 if (buttons == NULL || *buttons == NUL) 8003 buttons = (char_u *)_("&Ok"); 8004 8005 if (error) 8006 rettv->vval.v_number = 0; 8007 else 8008 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8009 def, NULL); 8010 #else 8011 rettv->vval.v_number = 0; 8012 #endif 8013 } 8014 8015 /* 8016 * "copy()" function 8017 */ 8018 static void 8019 f_copy(argvars, rettv) 8020 typval_T *argvars; 8021 typval_T *rettv; 8022 { 8023 item_copy(&argvars[0], rettv, FALSE, 0); 8024 } 8025 8026 /* 8027 * "count()" function 8028 */ 8029 static void 8030 f_count(argvars, rettv) 8031 typval_T *argvars; 8032 typval_T *rettv; 8033 { 8034 long n = 0; 8035 int ic = FALSE; 8036 8037 if (argvars[0].v_type == VAR_LIST) 8038 { 8039 listitem_T *li; 8040 list_T *l; 8041 long idx; 8042 8043 if ((l = argvars[0].vval.v_list) != NULL) 8044 { 8045 li = l->lv_first; 8046 if (argvars[2].v_type != VAR_UNKNOWN) 8047 { 8048 int error = FALSE; 8049 8050 ic = get_tv_number_chk(&argvars[2], &error); 8051 if (argvars[3].v_type != VAR_UNKNOWN) 8052 { 8053 idx = get_tv_number_chk(&argvars[3], &error); 8054 if (!error) 8055 { 8056 li = list_find(l, idx); 8057 if (li == NULL) 8058 EMSGN(_(e_listidx), idx); 8059 } 8060 } 8061 if (error) 8062 li = NULL; 8063 } 8064 8065 for ( ; li != NULL; li = li->li_next) 8066 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8067 ++n; 8068 } 8069 } 8070 else if (argvars[0].v_type == VAR_DICT) 8071 { 8072 int todo; 8073 dict_T *d; 8074 hashitem_T *hi; 8075 8076 if ((d = argvars[0].vval.v_dict) != NULL) 8077 { 8078 int error = FALSE; 8079 8080 if (argvars[2].v_type != VAR_UNKNOWN) 8081 { 8082 ic = get_tv_number_chk(&argvars[2], &error); 8083 if (argvars[3].v_type != VAR_UNKNOWN) 8084 EMSG(_(e_invarg)); 8085 } 8086 8087 todo = error ? 0 : d->dv_hashtab.ht_used; 8088 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8089 { 8090 if (!HASHITEM_EMPTY(hi)) 8091 { 8092 --todo; 8093 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8094 ++n; 8095 } 8096 } 8097 } 8098 } 8099 else 8100 EMSG2(_(e_listdictarg), "count()"); 8101 rettv->vval.v_number = n; 8102 } 8103 8104 /* 8105 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8106 * 8107 * Checks the existence of a cscope connection. 8108 */ 8109 /*ARGSUSED*/ 8110 static void 8111 f_cscope_connection(argvars, rettv) 8112 typval_T *argvars; 8113 typval_T *rettv; 8114 { 8115 #ifdef FEAT_CSCOPE 8116 int num = 0; 8117 char_u *dbpath = NULL; 8118 char_u *prepend = NULL; 8119 char_u buf[NUMBUFLEN]; 8120 8121 if (argvars[0].v_type != VAR_UNKNOWN 8122 && argvars[1].v_type != VAR_UNKNOWN) 8123 { 8124 num = (int)get_tv_number(&argvars[0]); 8125 dbpath = get_tv_string(&argvars[1]); 8126 if (argvars[2].v_type != VAR_UNKNOWN) 8127 prepend = get_tv_string_buf(&argvars[2], buf); 8128 } 8129 8130 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8131 #else 8132 rettv->vval.v_number = 0; 8133 #endif 8134 } 8135 8136 /* 8137 * "cursor(lnum, col)" function 8138 * 8139 * Moves the cursor to the specified line and column 8140 */ 8141 /*ARGSUSED*/ 8142 static void 8143 f_cursor(argvars, rettv) 8144 typval_T *argvars; 8145 typval_T *rettv; 8146 { 8147 long line, col; 8148 8149 line = get_tv_lnum(argvars); 8150 col = get_tv_number_chk(&argvars[1], NULL); 8151 if (line < 0 || col < 0) 8152 return; /* type error; errmsg already given */ 8153 if (line > 0) 8154 curwin->w_cursor.lnum = line; 8155 if (col > 0) 8156 curwin->w_cursor.col = col - 1; 8157 #ifdef FEAT_VIRTUALEDIT 8158 curwin->w_cursor.coladd = 0; 8159 #endif 8160 8161 /* Make sure the cursor is in a valid position. */ 8162 check_cursor(); 8163 #ifdef FEAT_MBYTE 8164 /* Correct cursor for multi-byte character. */ 8165 if (has_mbyte) 8166 mb_adjust_cursor(); 8167 #endif 8168 8169 curwin->w_set_curswant = TRUE; 8170 } 8171 8172 /* 8173 * "deepcopy()" function 8174 */ 8175 static void 8176 f_deepcopy(argvars, rettv) 8177 typval_T *argvars; 8178 typval_T *rettv; 8179 { 8180 int noref = 0; 8181 8182 if (argvars[1].v_type != VAR_UNKNOWN) 8183 noref = get_tv_number_chk(&argvars[1], NULL); 8184 if (noref < 0 || noref > 1) 8185 EMSG(_(e_invarg)); 8186 else 8187 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8188 } 8189 8190 /* 8191 * "delete()" function 8192 */ 8193 static void 8194 f_delete(argvars, rettv) 8195 typval_T *argvars; 8196 typval_T *rettv; 8197 { 8198 if (check_restricted() || check_secure()) 8199 rettv->vval.v_number = -1; 8200 else 8201 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8202 } 8203 8204 /* 8205 * "did_filetype()" function 8206 */ 8207 /*ARGSUSED*/ 8208 static void 8209 f_did_filetype(argvars, rettv) 8210 typval_T *argvars; 8211 typval_T *rettv; 8212 { 8213 #ifdef FEAT_AUTOCMD 8214 rettv->vval.v_number = did_filetype; 8215 #else 8216 rettv->vval.v_number = 0; 8217 #endif 8218 } 8219 8220 /* 8221 * "diff_filler()" function 8222 */ 8223 /*ARGSUSED*/ 8224 static void 8225 f_diff_filler(argvars, rettv) 8226 typval_T *argvars; 8227 typval_T *rettv; 8228 { 8229 #ifdef FEAT_DIFF 8230 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8231 #endif 8232 } 8233 8234 /* 8235 * "diff_hlID()" function 8236 */ 8237 /*ARGSUSED*/ 8238 static void 8239 f_diff_hlID(argvars, rettv) 8240 typval_T *argvars; 8241 typval_T *rettv; 8242 { 8243 #ifdef FEAT_DIFF 8244 linenr_T lnum = get_tv_lnum(argvars); 8245 static linenr_T prev_lnum = 0; 8246 static int changedtick = 0; 8247 static int fnum = 0; 8248 static int change_start = 0; 8249 static int change_end = 0; 8250 static enum hlf_value hlID = 0; 8251 int filler_lines; 8252 int col; 8253 8254 if (lnum < 0) /* ignore type error in {lnum} arg */ 8255 lnum = 0; 8256 if (lnum != prev_lnum 8257 || changedtick != curbuf->b_changedtick 8258 || fnum != curbuf->b_fnum) 8259 { 8260 /* New line, buffer, change: need to get the values. */ 8261 filler_lines = diff_check(curwin, lnum); 8262 if (filler_lines < 0) 8263 { 8264 if (filler_lines == -1) 8265 { 8266 change_start = MAXCOL; 8267 change_end = -1; 8268 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8269 hlID = HLF_ADD; /* added line */ 8270 else 8271 hlID = HLF_CHD; /* changed line */ 8272 } 8273 else 8274 hlID = HLF_ADD; /* added line */ 8275 } 8276 else 8277 hlID = (enum hlf_value)0; 8278 prev_lnum = lnum; 8279 changedtick = curbuf->b_changedtick; 8280 fnum = curbuf->b_fnum; 8281 } 8282 8283 if (hlID == HLF_CHD || hlID == HLF_TXD) 8284 { 8285 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8286 if (col >= change_start && col <= change_end) 8287 hlID = HLF_TXD; /* changed text */ 8288 else 8289 hlID = HLF_CHD; /* changed line */ 8290 } 8291 rettv->vval.v_number = hlID == (enum hlf_value)0 ? 0 : (int)hlID; 8292 #endif 8293 } 8294 8295 /* 8296 * "empty({expr})" function 8297 */ 8298 static void 8299 f_empty(argvars, rettv) 8300 typval_T *argvars; 8301 typval_T *rettv; 8302 { 8303 int n; 8304 8305 switch (argvars[0].v_type) 8306 { 8307 case VAR_STRING: 8308 case VAR_FUNC: 8309 n = argvars[0].vval.v_string == NULL 8310 || *argvars[0].vval.v_string == NUL; 8311 break; 8312 case VAR_NUMBER: 8313 n = argvars[0].vval.v_number == 0; 8314 break; 8315 case VAR_LIST: 8316 n = argvars[0].vval.v_list == NULL 8317 || argvars[0].vval.v_list->lv_first == NULL; 8318 break; 8319 case VAR_DICT: 8320 n = argvars[0].vval.v_dict == NULL 8321 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8322 break; 8323 default: 8324 EMSG2(_(e_intern2), "f_empty()"); 8325 n = 0; 8326 } 8327 8328 rettv->vval.v_number = n; 8329 } 8330 8331 /* 8332 * "escape({string}, {chars})" function 8333 */ 8334 static void 8335 f_escape(argvars, rettv) 8336 typval_T *argvars; 8337 typval_T *rettv; 8338 { 8339 char_u buf[NUMBUFLEN]; 8340 8341 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8342 get_tv_string_buf(&argvars[1], buf)); 8343 rettv->v_type = VAR_STRING; 8344 } 8345 8346 /* 8347 * "eval()" function 8348 */ 8349 /*ARGSUSED*/ 8350 static void 8351 f_eval(argvars, rettv) 8352 typval_T *argvars; 8353 typval_T *rettv; 8354 { 8355 char_u *s; 8356 8357 s = get_tv_string_chk(&argvars[0]); 8358 if (s != NULL) 8359 s = skipwhite(s); 8360 8361 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8362 { 8363 rettv->v_type = VAR_NUMBER; 8364 rettv->vval.v_number = 0; 8365 } 8366 else if (*s != NUL) 8367 EMSG(_(e_trailing)); 8368 } 8369 8370 /* 8371 * "eventhandler()" function 8372 */ 8373 /*ARGSUSED*/ 8374 static void 8375 f_eventhandler(argvars, rettv) 8376 typval_T *argvars; 8377 typval_T *rettv; 8378 { 8379 rettv->vval.v_number = vgetc_busy; 8380 } 8381 8382 /* 8383 * "executable()" function 8384 */ 8385 static void 8386 f_executable(argvars, rettv) 8387 typval_T *argvars; 8388 typval_T *rettv; 8389 { 8390 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8391 } 8392 8393 /* 8394 * "exists()" function 8395 */ 8396 static void 8397 f_exists(argvars, rettv) 8398 typval_T *argvars; 8399 typval_T *rettv; 8400 { 8401 char_u *p; 8402 char_u *name; 8403 int n = FALSE; 8404 int len = 0; 8405 8406 p = get_tv_string(&argvars[0]); 8407 if (*p == '$') /* environment variable */ 8408 { 8409 /* first try "normal" environment variables (fast) */ 8410 if (mch_getenv(p + 1) != NULL) 8411 n = TRUE; 8412 else 8413 { 8414 /* try expanding things like $VIM and ${HOME} */ 8415 p = expand_env_save(p); 8416 if (p != NULL && *p != '$') 8417 n = TRUE; 8418 vim_free(p); 8419 } 8420 } 8421 else if (*p == '&' || *p == '+') /* option */ 8422 n = (get_option_tv(&p, NULL, TRUE) == OK); 8423 else if (*p == '*') /* internal or user defined function */ 8424 { 8425 n = function_exists(p + 1); 8426 } 8427 else if (*p == ':') 8428 { 8429 n = cmd_exists(p + 1); 8430 } 8431 else if (*p == '#') 8432 { 8433 #ifdef FEAT_AUTOCMD 8434 name = p + 1; 8435 p = vim_strchr(name, '#'); 8436 if (p != NULL) 8437 n = au_exists(name, p, p + 1); 8438 else 8439 n = au_exists(name, name + STRLEN(name), NULL); 8440 #endif 8441 } 8442 else /* internal variable */ 8443 { 8444 char_u *tofree; 8445 typval_T tv; 8446 8447 /* get_name_len() takes care of expanding curly braces */ 8448 name = p; 8449 len = get_name_len(&p, &tofree, TRUE, FALSE); 8450 if (len > 0) 8451 { 8452 if (tofree != NULL) 8453 name = tofree; 8454 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8455 if (n) 8456 { 8457 /* handle d.key, l[idx], f(expr) */ 8458 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8459 if (n) 8460 clear_tv(&tv); 8461 } 8462 } 8463 8464 vim_free(tofree); 8465 } 8466 8467 rettv->vval.v_number = n; 8468 } 8469 8470 /* 8471 * "expand()" function 8472 */ 8473 static void 8474 f_expand(argvars, rettv) 8475 typval_T *argvars; 8476 typval_T *rettv; 8477 { 8478 char_u *s; 8479 int len; 8480 char_u *errormsg; 8481 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8482 expand_T xpc; 8483 int error = FALSE; 8484 8485 rettv->v_type = VAR_STRING; 8486 s = get_tv_string(&argvars[0]); 8487 if (*s == '%' || *s == '#' || *s == '<') 8488 { 8489 ++emsg_off; 8490 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8491 --emsg_off; 8492 } 8493 else 8494 { 8495 /* When the optional second argument is non-zero, don't remove matches 8496 * for 'suffixes' and 'wildignore' */ 8497 if (argvars[1].v_type != VAR_UNKNOWN 8498 && get_tv_number_chk(&argvars[1], &error)) 8499 flags |= WILD_KEEP_ALL; 8500 if (!error) 8501 { 8502 ExpandInit(&xpc); 8503 xpc.xp_context = EXPAND_FILES; 8504 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8505 ExpandCleanup(&xpc); 8506 } 8507 else 8508 rettv->vval.v_string = NULL; 8509 } 8510 } 8511 8512 /* 8513 * "extend(list, list [, idx])" function 8514 * "extend(dict, dict [, action])" function 8515 */ 8516 static void 8517 f_extend(argvars, rettv) 8518 typval_T *argvars; 8519 typval_T *rettv; 8520 { 8521 rettv->vval.v_number = 0; 8522 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8523 { 8524 list_T *l1, *l2; 8525 listitem_T *item; 8526 long before; 8527 int error = FALSE; 8528 8529 l1 = argvars[0].vval.v_list; 8530 l2 = argvars[1].vval.v_list; 8531 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8532 && l2 != NULL) 8533 { 8534 if (argvars[2].v_type != VAR_UNKNOWN) 8535 { 8536 before = get_tv_number_chk(&argvars[2], &error); 8537 if (error) 8538 return; /* type error; errmsg already given */ 8539 8540 if (before == l1->lv_len) 8541 item = NULL; 8542 else 8543 { 8544 item = list_find(l1, before); 8545 if (item == NULL) 8546 { 8547 EMSGN(_(e_listidx), before); 8548 return; 8549 } 8550 } 8551 } 8552 else 8553 item = NULL; 8554 list_extend(l1, l2, item); 8555 8556 copy_tv(&argvars[0], rettv); 8557 } 8558 } 8559 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8560 { 8561 dict_T *d1, *d2; 8562 dictitem_T *di1; 8563 char_u *action; 8564 int i; 8565 hashitem_T *hi2; 8566 int todo; 8567 8568 d1 = argvars[0].vval.v_dict; 8569 d2 = argvars[1].vval.v_dict; 8570 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8571 && d2 != NULL) 8572 { 8573 /* Check the third argument. */ 8574 if (argvars[2].v_type != VAR_UNKNOWN) 8575 { 8576 static char *(av[]) = {"keep", "force", "error"}; 8577 8578 action = get_tv_string_chk(&argvars[2]); 8579 if (action == NULL) 8580 return; /* type error; errmsg already given */ 8581 for (i = 0; i < 3; ++i) 8582 if (STRCMP(action, av[i]) == 0) 8583 break; 8584 if (i == 3) 8585 { 8586 EMSGN(_(e_invarg2), action); 8587 return; 8588 } 8589 } 8590 else 8591 action = (char_u *)"force"; 8592 8593 /* Go over all entries in the second dict and add them to the 8594 * first dict. */ 8595 todo = d2->dv_hashtab.ht_used; 8596 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8597 { 8598 if (!HASHITEM_EMPTY(hi2)) 8599 { 8600 --todo; 8601 di1 = dict_find(d1, hi2->hi_key, -1); 8602 if (di1 == NULL) 8603 { 8604 di1 = dictitem_copy(HI2DI(hi2)); 8605 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8606 dictitem_free(di1); 8607 } 8608 else if (*action == 'e') 8609 { 8610 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8611 break; 8612 } 8613 else if (*action == 'f') 8614 { 8615 clear_tv(&di1->di_tv); 8616 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8617 } 8618 } 8619 } 8620 8621 copy_tv(&argvars[0], rettv); 8622 } 8623 } 8624 else 8625 EMSG2(_(e_listdictarg), "extend()"); 8626 } 8627 8628 /* 8629 * "filereadable()" function 8630 */ 8631 static void 8632 f_filereadable(argvars, rettv) 8633 typval_T *argvars; 8634 typval_T *rettv; 8635 { 8636 FILE *fd; 8637 char_u *p; 8638 int n; 8639 8640 p = get_tv_string(&argvars[0]); 8641 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8642 { 8643 n = TRUE; 8644 fclose(fd); 8645 } 8646 else 8647 n = FALSE; 8648 8649 rettv->vval.v_number = n; 8650 } 8651 8652 /* 8653 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8654 * rights to write into. 8655 */ 8656 static void 8657 f_filewritable(argvars, rettv) 8658 typval_T *argvars; 8659 typval_T *rettv; 8660 { 8661 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8662 } 8663 8664 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8665 8666 static void 8667 findfilendir(argvars, rettv, dir) 8668 typval_T *argvars; 8669 typval_T *rettv; 8670 int dir; 8671 { 8672 #ifdef FEAT_SEARCHPATH 8673 char_u *fname; 8674 char_u *fresult = NULL; 8675 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8676 char_u *p; 8677 char_u pathbuf[NUMBUFLEN]; 8678 int count = 1; 8679 int first = TRUE; 8680 8681 fname = get_tv_string(&argvars[0]); 8682 8683 if (argvars[1].v_type != VAR_UNKNOWN) 8684 { 8685 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8686 if (p == NULL) 8687 count = -1; /* error */ 8688 else 8689 { 8690 if (*p != NUL) 8691 path = p; 8692 8693 if (argvars[2].v_type != VAR_UNKNOWN) 8694 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8695 } 8696 } 8697 8698 if (*fname != NUL && count >= 0) 8699 { 8700 do 8701 { 8702 vim_free(fresult); 8703 fresult = find_file_in_path_option(first ? fname : NULL, 8704 first ? (int)STRLEN(fname) : 0, 8705 0, first, path, dir, NULL); 8706 first = FALSE; 8707 } while (--count > 0 && fresult != NULL); 8708 } 8709 8710 rettv->vval.v_string = fresult; 8711 #else 8712 rettv->vval.v_string = NULL; 8713 #endif 8714 rettv->v_type = VAR_STRING; 8715 } 8716 8717 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8718 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8719 8720 /* 8721 * Implementation of map() and filter(). 8722 */ 8723 static void 8724 filter_map(argvars, rettv, map) 8725 typval_T *argvars; 8726 typval_T *rettv; 8727 int map; 8728 { 8729 char_u buf[NUMBUFLEN]; 8730 char_u *expr; 8731 listitem_T *li, *nli; 8732 list_T *l = NULL; 8733 dictitem_T *di; 8734 hashtab_T *ht; 8735 hashitem_T *hi; 8736 dict_T *d = NULL; 8737 typval_T save_val; 8738 typval_T save_key; 8739 int rem; 8740 int todo; 8741 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8742 8743 8744 rettv->vval.v_number = 0; 8745 if (argvars[0].v_type == VAR_LIST) 8746 { 8747 if ((l = argvars[0].vval.v_list) == NULL 8748 || (map && tv_check_lock(l->lv_lock, msg))) 8749 return; 8750 } 8751 else if (argvars[0].v_type == VAR_DICT) 8752 { 8753 if ((d = argvars[0].vval.v_dict) == NULL 8754 || (map && tv_check_lock(d->dv_lock, msg))) 8755 return; 8756 } 8757 else 8758 { 8759 EMSG2(_(e_listdictarg), msg); 8760 return; 8761 } 8762 8763 expr = get_tv_string_buf_chk(&argvars[1], buf); 8764 /* On type errors, the preceding call has already displayed an error 8765 * message. Avoid a misleading error message for an empty string that 8766 * was not passed as argument. */ 8767 if (expr != NULL) 8768 { 8769 prepare_vimvar(VV_VAL, &save_val); 8770 expr = skipwhite(expr); 8771 8772 if (argvars[0].v_type == VAR_DICT) 8773 { 8774 prepare_vimvar(VV_KEY, &save_key); 8775 vimvars[VV_KEY].vv_type = VAR_STRING; 8776 8777 ht = &d->dv_hashtab; 8778 hash_lock(ht); 8779 todo = ht->ht_used; 8780 for (hi = ht->ht_array; todo > 0; ++hi) 8781 { 8782 if (!HASHITEM_EMPTY(hi)) 8783 { 8784 --todo; 8785 di = HI2DI(hi); 8786 if (tv_check_lock(di->di_tv.v_lock, msg)) 8787 break; 8788 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8789 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8790 break; 8791 if (!map && rem) 8792 dictitem_remove(d, di); 8793 clear_tv(&vimvars[VV_KEY].vv_tv); 8794 } 8795 } 8796 hash_unlock(ht); 8797 8798 restore_vimvar(VV_KEY, &save_key); 8799 } 8800 else 8801 { 8802 for (li = l->lv_first; li != NULL; li = nli) 8803 { 8804 if (tv_check_lock(li->li_tv.v_lock, msg)) 8805 break; 8806 nli = li->li_next; 8807 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8808 break; 8809 if (!map && rem) 8810 listitem_remove(l, li); 8811 } 8812 } 8813 8814 restore_vimvar(VV_VAL, &save_val); 8815 } 8816 8817 copy_tv(&argvars[0], rettv); 8818 } 8819 8820 static int 8821 filter_map_one(tv, expr, map, remp) 8822 typval_T *tv; 8823 char_u *expr; 8824 int map; 8825 int *remp; 8826 { 8827 typval_T rettv; 8828 char_u *s; 8829 8830 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8831 s = expr; 8832 if (eval1(&s, &rettv, TRUE) == FAIL) 8833 return FAIL; 8834 if (*s != NUL) /* check for trailing chars after expr */ 8835 { 8836 EMSG2(_(e_invexpr2), s); 8837 return FAIL; 8838 } 8839 if (map) 8840 { 8841 /* map(): replace the list item value */ 8842 clear_tv(tv); 8843 *tv = rettv; 8844 } 8845 else 8846 { 8847 int error = FALSE; 8848 8849 /* filter(): when expr is zero remove the item */ 8850 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8851 clear_tv(&rettv); 8852 /* On type error, nothing has been removed; return FAIL to stop the 8853 * loop. The error message was given by get_tv_number_chk(). */ 8854 if (error) 8855 return FAIL; 8856 } 8857 clear_tv(&vimvars[VV_VAL].vv_tv); 8858 return OK; 8859 } 8860 8861 /* 8862 * "filter()" function 8863 */ 8864 static void 8865 f_filter(argvars, rettv) 8866 typval_T *argvars; 8867 typval_T *rettv; 8868 { 8869 filter_map(argvars, rettv, FALSE); 8870 } 8871 8872 /* 8873 * "finddir({fname}[, {path}[, {count}]])" function 8874 */ 8875 static void 8876 f_finddir(argvars, rettv) 8877 typval_T *argvars; 8878 typval_T *rettv; 8879 { 8880 findfilendir(argvars, rettv, TRUE); 8881 } 8882 8883 /* 8884 * "findfile({fname}[, {path}[, {count}]])" function 8885 */ 8886 static void 8887 f_findfile(argvars, rettv) 8888 typval_T *argvars; 8889 typval_T *rettv; 8890 { 8891 findfilendir(argvars, rettv, FALSE); 8892 } 8893 8894 /* 8895 * "fnamemodify({fname}, {mods})" function 8896 */ 8897 static void 8898 f_fnamemodify(argvars, rettv) 8899 typval_T *argvars; 8900 typval_T *rettv; 8901 { 8902 char_u *fname; 8903 char_u *mods; 8904 int usedlen = 0; 8905 int len; 8906 char_u *fbuf = NULL; 8907 char_u buf[NUMBUFLEN]; 8908 8909 fname = get_tv_string_chk(&argvars[0]); 8910 mods = get_tv_string_buf_chk(&argvars[1], buf); 8911 if (fname == NULL || mods == NULL) 8912 fname = NULL; 8913 else 8914 { 8915 len = (int)STRLEN(fname); 8916 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8917 } 8918 8919 rettv->v_type = VAR_STRING; 8920 if (fname == NULL) 8921 rettv->vval.v_string = NULL; 8922 else 8923 rettv->vval.v_string = vim_strnsave(fname, len); 8924 vim_free(fbuf); 8925 } 8926 8927 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8928 8929 /* 8930 * "foldclosed()" function 8931 */ 8932 static void 8933 foldclosed_both(argvars, rettv, end) 8934 typval_T *argvars; 8935 typval_T *rettv; 8936 int end; 8937 { 8938 #ifdef FEAT_FOLDING 8939 linenr_T lnum; 8940 linenr_T first, last; 8941 8942 lnum = get_tv_lnum(argvars); 8943 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8944 { 8945 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8946 { 8947 if (end) 8948 rettv->vval.v_number = (varnumber_T)last; 8949 else 8950 rettv->vval.v_number = (varnumber_T)first; 8951 return; 8952 } 8953 } 8954 #endif 8955 rettv->vval.v_number = -1; 8956 } 8957 8958 /* 8959 * "foldclosed()" function 8960 */ 8961 static void 8962 f_foldclosed(argvars, rettv) 8963 typval_T *argvars; 8964 typval_T *rettv; 8965 { 8966 foldclosed_both(argvars, rettv, FALSE); 8967 } 8968 8969 /* 8970 * "foldclosedend()" function 8971 */ 8972 static void 8973 f_foldclosedend(argvars, rettv) 8974 typval_T *argvars; 8975 typval_T *rettv; 8976 { 8977 foldclosed_both(argvars, rettv, TRUE); 8978 } 8979 8980 /* 8981 * "foldlevel()" function 8982 */ 8983 static void 8984 f_foldlevel(argvars, rettv) 8985 typval_T *argvars; 8986 typval_T *rettv; 8987 { 8988 #ifdef FEAT_FOLDING 8989 linenr_T lnum; 8990 8991 lnum = get_tv_lnum(argvars); 8992 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8993 rettv->vval.v_number = foldLevel(lnum); 8994 else 8995 #endif 8996 rettv->vval.v_number = 0; 8997 } 8998 8999 /* 9000 * "foldtext()" function 9001 */ 9002 /*ARGSUSED*/ 9003 static void 9004 f_foldtext(argvars, rettv) 9005 typval_T *argvars; 9006 typval_T *rettv; 9007 { 9008 #ifdef FEAT_FOLDING 9009 linenr_T lnum; 9010 char_u *s; 9011 char_u *r; 9012 int len; 9013 char *txt; 9014 #endif 9015 9016 rettv->v_type = VAR_STRING; 9017 rettv->vval.v_string = NULL; 9018 #ifdef FEAT_FOLDING 9019 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9020 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9021 <= curbuf->b_ml.ml_line_count 9022 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9023 { 9024 /* Find first non-empty line in the fold. */ 9025 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9026 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9027 { 9028 if (!linewhite(lnum)) 9029 break; 9030 ++lnum; 9031 } 9032 9033 /* Find interesting text in this line. */ 9034 s = skipwhite(ml_get(lnum)); 9035 /* skip C comment-start */ 9036 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9037 { 9038 s = skipwhite(s + 2); 9039 if (*skipwhite(s) == NUL 9040 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9041 { 9042 s = skipwhite(ml_get(lnum + 1)); 9043 if (*s == '*') 9044 s = skipwhite(s + 1); 9045 } 9046 } 9047 txt = _("+-%s%3ld lines: "); 9048 r = alloc((unsigned)(STRLEN(txt) 9049 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9050 + 20 /* for %3ld */ 9051 + STRLEN(s))); /* concatenated */ 9052 if (r != NULL) 9053 { 9054 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9055 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9056 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9057 len = (int)STRLEN(r); 9058 STRCAT(r, s); 9059 /* remove 'foldmarker' and 'commentstring' */ 9060 foldtext_cleanup(r + len); 9061 rettv->vval.v_string = r; 9062 } 9063 } 9064 #endif 9065 } 9066 9067 /* 9068 * "foldtextresult(lnum)" function 9069 */ 9070 /*ARGSUSED*/ 9071 static void 9072 f_foldtextresult(argvars, rettv) 9073 typval_T *argvars; 9074 typval_T *rettv; 9075 { 9076 #ifdef FEAT_FOLDING 9077 linenr_T lnum; 9078 char_u *text; 9079 char_u buf[51]; 9080 foldinfo_T foldinfo; 9081 int fold_count; 9082 #endif 9083 9084 rettv->v_type = VAR_STRING; 9085 rettv->vval.v_string = NULL; 9086 #ifdef FEAT_FOLDING 9087 lnum = get_tv_lnum(argvars); 9088 /* treat illegal types and illegal string values for {lnum} the same */ 9089 if (lnum < 0) 9090 lnum = 0; 9091 fold_count = foldedCount(curwin, lnum, &foldinfo); 9092 if (fold_count > 0) 9093 { 9094 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9095 &foldinfo, buf); 9096 if (text == buf) 9097 text = vim_strsave(text); 9098 rettv->vval.v_string = text; 9099 } 9100 #endif 9101 } 9102 9103 /* 9104 * "foreground()" function 9105 */ 9106 /*ARGSUSED*/ 9107 static void 9108 f_foreground(argvars, rettv) 9109 typval_T *argvars; 9110 typval_T *rettv; 9111 { 9112 rettv->vval.v_number = 0; 9113 #ifdef FEAT_GUI 9114 if (gui.in_use) 9115 gui_mch_set_foreground(); 9116 #else 9117 # ifdef WIN32 9118 win32_set_foreground(); 9119 # endif 9120 #endif 9121 } 9122 9123 /* 9124 * "function()" function 9125 */ 9126 /*ARGSUSED*/ 9127 static void 9128 f_function(argvars, rettv) 9129 typval_T *argvars; 9130 typval_T *rettv; 9131 { 9132 char_u *s; 9133 9134 rettv->vval.v_number = 0; 9135 s = get_tv_string(&argvars[0]); 9136 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9137 EMSG2(_(e_invarg2), s); 9138 else if (!function_exists(s)) 9139 EMSG2(_("E700: Unknown function: %s"), s); 9140 else 9141 { 9142 rettv->vval.v_string = vim_strsave(s); 9143 rettv->v_type = VAR_FUNC; 9144 } 9145 } 9146 9147 /* 9148 * "garbagecollect()" function 9149 */ 9150 /*ARGSUSED*/ 9151 static void 9152 f_garbagecollect(argvars, rettv) 9153 typval_T *argvars; 9154 typval_T *rettv; 9155 { 9156 garbage_collect(); 9157 } 9158 9159 /* 9160 * "get()" function 9161 */ 9162 static void 9163 f_get(argvars, rettv) 9164 typval_T *argvars; 9165 typval_T *rettv; 9166 { 9167 listitem_T *li; 9168 list_T *l; 9169 dictitem_T *di; 9170 dict_T *d; 9171 typval_T *tv = NULL; 9172 9173 if (argvars[0].v_type == VAR_LIST) 9174 { 9175 if ((l = argvars[0].vval.v_list) != NULL) 9176 { 9177 int error = FALSE; 9178 9179 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9180 if (!error && li != NULL) 9181 tv = &li->li_tv; 9182 } 9183 } 9184 else if (argvars[0].v_type == VAR_DICT) 9185 { 9186 if ((d = argvars[0].vval.v_dict) != NULL) 9187 { 9188 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9189 if (di != NULL) 9190 tv = &di->di_tv; 9191 } 9192 } 9193 else 9194 EMSG2(_(e_listdictarg), "get()"); 9195 9196 if (tv == NULL) 9197 { 9198 if (argvars[2].v_type == VAR_UNKNOWN) 9199 rettv->vval.v_number = 0; 9200 else 9201 copy_tv(&argvars[2], rettv); 9202 } 9203 else 9204 copy_tv(tv, rettv); 9205 } 9206 9207 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9208 9209 /* 9210 * Get line or list of lines from buffer "buf" into "rettv". 9211 * Return a range (from start to end) of lines in rettv from the specified 9212 * buffer. 9213 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9214 */ 9215 static void 9216 get_buffer_lines(buf, start, end, retlist, rettv) 9217 buf_T *buf; 9218 linenr_T start; 9219 linenr_T end; 9220 int retlist; 9221 typval_T *rettv; 9222 { 9223 char_u *p; 9224 list_T *l = NULL; 9225 9226 if (retlist) 9227 { 9228 l = list_alloc(); 9229 if (l == NULL) 9230 return; 9231 9232 rettv->vval.v_list = l; 9233 rettv->v_type = VAR_LIST; 9234 ++l->lv_refcount; 9235 } 9236 else 9237 rettv->vval.v_number = 0; 9238 9239 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9240 return; 9241 9242 if (!retlist) 9243 { 9244 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9245 p = ml_get_buf(buf, start, FALSE); 9246 else 9247 p = (char_u *)""; 9248 9249 rettv->v_type = VAR_STRING; 9250 rettv->vval.v_string = vim_strsave(p); 9251 } 9252 else 9253 { 9254 if (end < start) 9255 return; 9256 9257 if (start < 1) 9258 start = 1; 9259 if (end > buf->b_ml.ml_line_count) 9260 end = buf->b_ml.ml_line_count; 9261 while (start <= end) 9262 if (list_append_string(l, ml_get_buf(buf, start++, FALSE)) == FAIL) 9263 break; 9264 } 9265 } 9266 9267 /* 9268 * "getbufline()" function 9269 */ 9270 static void 9271 f_getbufline(argvars, rettv) 9272 typval_T *argvars; 9273 typval_T *rettv; 9274 { 9275 linenr_T lnum; 9276 linenr_T end; 9277 buf_T *buf; 9278 9279 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9280 ++emsg_off; 9281 buf = get_buf_tv(&argvars[0]); 9282 --emsg_off; 9283 9284 lnum = get_tv_lnum_buf(&argvars[1], buf); 9285 if (argvars[2].v_type == VAR_UNKNOWN) 9286 end = lnum; 9287 else 9288 end = get_tv_lnum_buf(&argvars[2], buf); 9289 9290 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9291 } 9292 9293 /* 9294 * "getbufvar()" function 9295 */ 9296 static void 9297 f_getbufvar(argvars, rettv) 9298 typval_T *argvars; 9299 typval_T *rettv; 9300 { 9301 buf_T *buf; 9302 buf_T *save_curbuf; 9303 char_u *varname; 9304 dictitem_T *v; 9305 9306 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9307 varname = get_tv_string_chk(&argvars[1]); 9308 ++emsg_off; 9309 buf = get_buf_tv(&argvars[0]); 9310 9311 rettv->v_type = VAR_STRING; 9312 rettv->vval.v_string = NULL; 9313 9314 if (buf != NULL && varname != NULL) 9315 { 9316 if (*varname == '&') /* buffer-local-option */ 9317 { 9318 /* set curbuf to be our buf, temporarily */ 9319 save_curbuf = curbuf; 9320 curbuf = buf; 9321 9322 get_option_tv(&varname, rettv, TRUE); 9323 9324 /* restore previous notion of curbuf */ 9325 curbuf = save_curbuf; 9326 } 9327 else 9328 { 9329 if (*varname == NUL) 9330 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9331 * scope prefix before the NUL byte is required by 9332 * find_var_in_ht(). */ 9333 varname = (char_u *)"b:" + 2; 9334 /* look up the variable */ 9335 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9336 if (v != NULL) 9337 copy_tv(&v->di_tv, rettv); 9338 } 9339 } 9340 9341 --emsg_off; 9342 } 9343 9344 /* 9345 * "getchar()" function 9346 */ 9347 static void 9348 f_getchar(argvars, rettv) 9349 typval_T *argvars; 9350 typval_T *rettv; 9351 { 9352 varnumber_T n; 9353 int error = FALSE; 9354 9355 ++no_mapping; 9356 ++allow_keys; 9357 if (argvars[0].v_type == VAR_UNKNOWN) 9358 /* getchar(): blocking wait. */ 9359 n = safe_vgetc(); 9360 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9361 /* getchar(1): only check if char avail */ 9362 n = vpeekc(); 9363 else if (error || vpeekc() == NUL) 9364 /* illegal argument or getchar(0) and no char avail: return zero */ 9365 n = 0; 9366 else 9367 /* getchar(0) and char avail: return char */ 9368 n = safe_vgetc(); 9369 --no_mapping; 9370 --allow_keys; 9371 9372 rettv->vval.v_number = n; 9373 if (IS_SPECIAL(n) || mod_mask != 0) 9374 { 9375 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9376 int i = 0; 9377 9378 /* Turn a special key into three bytes, plus modifier. */ 9379 if (mod_mask != 0) 9380 { 9381 temp[i++] = K_SPECIAL; 9382 temp[i++] = KS_MODIFIER; 9383 temp[i++] = mod_mask; 9384 } 9385 if (IS_SPECIAL(n)) 9386 { 9387 temp[i++] = K_SPECIAL; 9388 temp[i++] = K_SECOND(n); 9389 temp[i++] = K_THIRD(n); 9390 } 9391 #ifdef FEAT_MBYTE 9392 else if (has_mbyte) 9393 i += (*mb_char2bytes)(n, temp + i); 9394 #endif 9395 else 9396 temp[i++] = n; 9397 temp[i++] = NUL; 9398 rettv->v_type = VAR_STRING; 9399 rettv->vval.v_string = vim_strsave(temp); 9400 } 9401 } 9402 9403 /* 9404 * "getcharmod()" function 9405 */ 9406 /*ARGSUSED*/ 9407 static void 9408 f_getcharmod(argvars, rettv) 9409 typval_T *argvars; 9410 typval_T *rettv; 9411 { 9412 rettv->vval.v_number = mod_mask; 9413 } 9414 9415 /* 9416 * "getcmdline()" function 9417 */ 9418 /*ARGSUSED*/ 9419 static void 9420 f_getcmdline(argvars, rettv) 9421 typval_T *argvars; 9422 typval_T *rettv; 9423 { 9424 rettv->v_type = VAR_STRING; 9425 rettv->vval.v_string = get_cmdline_str(); 9426 } 9427 9428 /* 9429 * "getcmdpos()" function 9430 */ 9431 /*ARGSUSED*/ 9432 static void 9433 f_getcmdpos(argvars, rettv) 9434 typval_T *argvars; 9435 typval_T *rettv; 9436 { 9437 rettv->vval.v_number = get_cmdline_pos() + 1; 9438 } 9439 9440 /* 9441 * "getcwd()" function 9442 */ 9443 /*ARGSUSED*/ 9444 static void 9445 f_getcwd(argvars, rettv) 9446 typval_T *argvars; 9447 typval_T *rettv; 9448 { 9449 char_u cwd[MAXPATHL]; 9450 9451 rettv->v_type = VAR_STRING; 9452 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9453 rettv->vval.v_string = NULL; 9454 else 9455 { 9456 rettv->vval.v_string = vim_strsave(cwd); 9457 #ifdef BACKSLASH_IN_FILENAME 9458 if (rettv->vval.v_string != NULL) 9459 slash_adjust(rettv->vval.v_string); 9460 #endif 9461 } 9462 } 9463 9464 /* 9465 * "getfontname()" function 9466 */ 9467 /*ARGSUSED*/ 9468 static void 9469 f_getfontname(argvars, rettv) 9470 typval_T *argvars; 9471 typval_T *rettv; 9472 { 9473 rettv->v_type = VAR_STRING; 9474 rettv->vval.v_string = NULL; 9475 #ifdef FEAT_GUI 9476 if (gui.in_use) 9477 { 9478 GuiFont font; 9479 char_u *name = NULL; 9480 9481 if (argvars[0].v_type == VAR_UNKNOWN) 9482 { 9483 /* Get the "Normal" font. Either the name saved by 9484 * hl_set_font_name() or from the font ID. */ 9485 font = gui.norm_font; 9486 name = hl_get_font_name(); 9487 } 9488 else 9489 { 9490 name = get_tv_string(&argvars[0]); 9491 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9492 return; 9493 font = gui_mch_get_font(name, FALSE); 9494 if (font == NOFONT) 9495 return; /* Invalid font name, return empty string. */ 9496 } 9497 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9498 if (argvars[0].v_type != VAR_UNKNOWN) 9499 gui_mch_free_font(font); 9500 } 9501 #endif 9502 } 9503 9504 /* 9505 * "getfperm({fname})" function 9506 */ 9507 static void 9508 f_getfperm(argvars, rettv) 9509 typval_T *argvars; 9510 typval_T *rettv; 9511 { 9512 char_u *fname; 9513 struct stat st; 9514 char_u *perm = NULL; 9515 char_u flags[] = "rwx"; 9516 int i; 9517 9518 fname = get_tv_string(&argvars[0]); 9519 9520 rettv->v_type = VAR_STRING; 9521 if (mch_stat((char *)fname, &st) >= 0) 9522 { 9523 perm = vim_strsave((char_u *)"---------"); 9524 if (perm != NULL) 9525 { 9526 for (i = 0; i < 9; i++) 9527 { 9528 if (st.st_mode & (1 << (8 - i))) 9529 perm[i] = flags[i % 3]; 9530 } 9531 } 9532 } 9533 rettv->vval.v_string = perm; 9534 } 9535 9536 /* 9537 * "getfsize({fname})" function 9538 */ 9539 static void 9540 f_getfsize(argvars, rettv) 9541 typval_T *argvars; 9542 typval_T *rettv; 9543 { 9544 char_u *fname; 9545 struct stat st; 9546 9547 fname = get_tv_string(&argvars[0]); 9548 9549 rettv->v_type = VAR_NUMBER; 9550 9551 if (mch_stat((char *)fname, &st) >= 0) 9552 { 9553 if (mch_isdir(fname)) 9554 rettv->vval.v_number = 0; 9555 else 9556 rettv->vval.v_number = (varnumber_T)st.st_size; 9557 } 9558 else 9559 rettv->vval.v_number = -1; 9560 } 9561 9562 /* 9563 * "getftime({fname})" function 9564 */ 9565 static void 9566 f_getftime(argvars, rettv) 9567 typval_T *argvars; 9568 typval_T *rettv; 9569 { 9570 char_u *fname; 9571 struct stat st; 9572 9573 fname = get_tv_string(&argvars[0]); 9574 9575 if (mch_stat((char *)fname, &st) >= 0) 9576 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9577 else 9578 rettv->vval.v_number = -1; 9579 } 9580 9581 /* 9582 * "getftype({fname})" function 9583 */ 9584 static void 9585 f_getftype(argvars, rettv) 9586 typval_T *argvars; 9587 typval_T *rettv; 9588 { 9589 char_u *fname; 9590 struct stat st; 9591 char_u *type = NULL; 9592 char *t; 9593 9594 fname = get_tv_string(&argvars[0]); 9595 9596 rettv->v_type = VAR_STRING; 9597 if (mch_lstat((char *)fname, &st) >= 0) 9598 { 9599 #ifdef S_ISREG 9600 if (S_ISREG(st.st_mode)) 9601 t = "file"; 9602 else if (S_ISDIR(st.st_mode)) 9603 t = "dir"; 9604 # ifdef S_ISLNK 9605 else if (S_ISLNK(st.st_mode)) 9606 t = "link"; 9607 # endif 9608 # ifdef S_ISBLK 9609 else if (S_ISBLK(st.st_mode)) 9610 t = "bdev"; 9611 # endif 9612 # ifdef S_ISCHR 9613 else if (S_ISCHR(st.st_mode)) 9614 t = "cdev"; 9615 # endif 9616 # ifdef S_ISFIFO 9617 else if (S_ISFIFO(st.st_mode)) 9618 t = "fifo"; 9619 # endif 9620 # ifdef S_ISSOCK 9621 else if (S_ISSOCK(st.st_mode)) 9622 t = "fifo"; 9623 # endif 9624 else 9625 t = "other"; 9626 #else 9627 # ifdef S_IFMT 9628 switch (st.st_mode & S_IFMT) 9629 { 9630 case S_IFREG: t = "file"; break; 9631 case S_IFDIR: t = "dir"; break; 9632 # ifdef S_IFLNK 9633 case S_IFLNK: t = "link"; break; 9634 # endif 9635 # ifdef S_IFBLK 9636 case S_IFBLK: t = "bdev"; break; 9637 # endif 9638 # ifdef S_IFCHR 9639 case S_IFCHR: t = "cdev"; break; 9640 # endif 9641 # ifdef S_IFIFO 9642 case S_IFIFO: t = "fifo"; break; 9643 # endif 9644 # ifdef S_IFSOCK 9645 case S_IFSOCK: t = "socket"; break; 9646 # endif 9647 default: t = "other"; 9648 } 9649 # else 9650 if (mch_isdir(fname)) 9651 t = "dir"; 9652 else 9653 t = "file"; 9654 # endif 9655 #endif 9656 type = vim_strsave((char_u *)t); 9657 } 9658 rettv->vval.v_string = type; 9659 } 9660 9661 /* 9662 * "getline(lnum, [end])" function 9663 */ 9664 static void 9665 f_getline(argvars, rettv) 9666 typval_T *argvars; 9667 typval_T *rettv; 9668 { 9669 linenr_T lnum; 9670 linenr_T end; 9671 int retlist; 9672 9673 lnum = get_tv_lnum(argvars); 9674 if (argvars[1].v_type == VAR_UNKNOWN) 9675 { 9676 end = 0; 9677 retlist = FALSE; 9678 } 9679 else 9680 { 9681 end = get_tv_lnum(&argvars[1]); 9682 retlist = TRUE; 9683 } 9684 9685 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9686 } 9687 9688 /* 9689 * "getqflist()" function 9690 */ 9691 /*ARGSUSED*/ 9692 static void 9693 f_getqflist(argvars, rettv) 9694 typval_T *argvars; 9695 typval_T *rettv; 9696 { 9697 #ifdef FEAT_QUICKFIX 9698 list_T *l; 9699 #endif 9700 9701 rettv->vval.v_number = FALSE; 9702 #ifdef FEAT_QUICKFIX 9703 l = list_alloc(); 9704 if (l != NULL) 9705 { 9706 rettv->vval.v_list = l; 9707 rettv->v_type = VAR_LIST; 9708 ++l->lv_refcount; 9709 (void)get_errorlist(l); 9710 } 9711 #endif 9712 } 9713 9714 /* 9715 * "getreg()" function 9716 */ 9717 static void 9718 f_getreg(argvars, rettv) 9719 typval_T *argvars; 9720 typval_T *rettv; 9721 { 9722 char_u *strregname; 9723 int regname; 9724 int arg2 = FALSE; 9725 int error = FALSE; 9726 9727 if (argvars[0].v_type != VAR_UNKNOWN) 9728 { 9729 strregname = get_tv_string_chk(&argvars[0]); 9730 error = strregname == NULL; 9731 if (argvars[1].v_type != VAR_UNKNOWN) 9732 arg2 = get_tv_number_chk(&argvars[1], &error); 9733 } 9734 else 9735 strregname = vimvars[VV_REG].vv_str; 9736 regname = (strregname == NULL ? '"' : *strregname); 9737 if (regname == 0) 9738 regname = '"'; 9739 9740 rettv->v_type = VAR_STRING; 9741 rettv->vval.v_string = error ? NULL : 9742 get_reg_contents(regname, TRUE, arg2); 9743 } 9744 9745 /* 9746 * "getregtype()" function 9747 */ 9748 static void 9749 f_getregtype(argvars, rettv) 9750 typval_T *argvars; 9751 typval_T *rettv; 9752 { 9753 char_u *strregname; 9754 int regname; 9755 char_u buf[NUMBUFLEN + 2]; 9756 long reglen = 0; 9757 9758 if (argvars[0].v_type != VAR_UNKNOWN) 9759 { 9760 strregname = get_tv_string_chk(&argvars[0]); 9761 if (strregname == NULL) /* type error; errmsg already given */ 9762 { 9763 rettv->v_type = VAR_STRING; 9764 rettv->vval.v_string = NULL; 9765 return; 9766 } 9767 } 9768 else 9769 /* Default to v:register */ 9770 strregname = vimvars[VV_REG].vv_str; 9771 9772 regname = (strregname == NULL ? '"' : *strregname); 9773 if (regname == 0) 9774 regname = '"'; 9775 9776 buf[0] = NUL; 9777 buf[1] = NUL; 9778 switch (get_reg_type(regname, ®len)) 9779 { 9780 case MLINE: buf[0] = 'V'; break; 9781 case MCHAR: buf[0] = 'v'; break; 9782 #ifdef FEAT_VISUAL 9783 case MBLOCK: 9784 buf[0] = Ctrl_V; 9785 sprintf((char *)buf + 1, "%ld", reglen + 1); 9786 break; 9787 #endif 9788 } 9789 rettv->v_type = VAR_STRING; 9790 rettv->vval.v_string = vim_strsave(buf); 9791 } 9792 9793 /* 9794 * "getwinposx()" function 9795 */ 9796 /*ARGSUSED*/ 9797 static void 9798 f_getwinposx(argvars, rettv) 9799 typval_T *argvars; 9800 typval_T *rettv; 9801 { 9802 rettv->vval.v_number = -1; 9803 #ifdef FEAT_GUI 9804 if (gui.in_use) 9805 { 9806 int x, y; 9807 9808 if (gui_mch_get_winpos(&x, &y) == OK) 9809 rettv->vval.v_number = x; 9810 } 9811 #endif 9812 } 9813 9814 /* 9815 * "getwinposy()" function 9816 */ 9817 /*ARGSUSED*/ 9818 static void 9819 f_getwinposy(argvars, rettv) 9820 typval_T *argvars; 9821 typval_T *rettv; 9822 { 9823 rettv->vval.v_number = -1; 9824 #ifdef FEAT_GUI 9825 if (gui.in_use) 9826 { 9827 int x, y; 9828 9829 if (gui_mch_get_winpos(&x, &y) == OK) 9830 rettv->vval.v_number = y; 9831 } 9832 #endif 9833 } 9834 9835 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9836 9837 static win_T * 9838 find_win_by_nr(vp) 9839 typval_T *vp; 9840 { 9841 #ifdef FEAT_WINDOWS 9842 win_T *wp; 9843 #endif 9844 int nr; 9845 9846 nr = get_tv_number_chk(vp, NULL); 9847 9848 #ifdef FEAT_WINDOWS 9849 if (nr < 0) 9850 return NULL; 9851 if (nr == 0) 9852 return curwin; 9853 9854 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9855 if (--nr <= 0) 9856 break; 9857 return wp; 9858 #else 9859 if (nr == 0 || nr == 1) 9860 return curwin; 9861 return NULL; 9862 #endif 9863 } 9864 9865 /* 9866 * "getwinvar()" function 9867 */ 9868 static void 9869 f_getwinvar(argvars, rettv) 9870 typval_T *argvars; 9871 typval_T *rettv; 9872 { 9873 win_T *win, *oldcurwin; 9874 char_u *varname; 9875 dictitem_T *v; 9876 9877 win = find_win_by_nr(&argvars[0]); 9878 varname = get_tv_string_chk(&argvars[1]); 9879 ++emsg_off; 9880 9881 rettv->v_type = VAR_STRING; 9882 rettv->vval.v_string = NULL; 9883 9884 if (win != NULL && varname != NULL) 9885 { 9886 if (*varname == '&') /* window-local-option */ 9887 { 9888 /* Set curwin to be our win, temporarily. Also set curbuf, so 9889 * that we can get buffer-local options. */ 9890 oldcurwin = curwin; 9891 curwin = win; 9892 curbuf = win->w_buffer; 9893 9894 get_option_tv(&varname, rettv, 1); 9895 9896 /* restore previous notion of curwin */ 9897 curwin = oldcurwin; 9898 curbuf = curwin->w_buffer; 9899 } 9900 else 9901 { 9902 if (*varname == NUL) 9903 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9904 * scope prefix before the NUL byte is required by 9905 * find_var_in_ht(). */ 9906 varname = (char_u *)"w:" + 2; 9907 /* look up the variable */ 9908 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9909 if (v != NULL) 9910 copy_tv(&v->di_tv, rettv); 9911 } 9912 } 9913 9914 --emsg_off; 9915 } 9916 9917 /* 9918 * "glob()" function 9919 */ 9920 static void 9921 f_glob(argvars, rettv) 9922 typval_T *argvars; 9923 typval_T *rettv; 9924 { 9925 expand_T xpc; 9926 9927 ExpandInit(&xpc); 9928 xpc.xp_context = EXPAND_FILES; 9929 rettv->v_type = VAR_STRING; 9930 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9931 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9932 ExpandCleanup(&xpc); 9933 } 9934 9935 /* 9936 * "globpath()" function 9937 */ 9938 static void 9939 f_globpath(argvars, rettv) 9940 typval_T *argvars; 9941 typval_T *rettv; 9942 { 9943 char_u buf1[NUMBUFLEN]; 9944 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9945 9946 rettv->v_type = VAR_STRING; 9947 if (file == NULL) 9948 rettv->vval.v_string = NULL; 9949 else 9950 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9951 } 9952 9953 /* 9954 * "has()" function 9955 */ 9956 static void 9957 f_has(argvars, rettv) 9958 typval_T *argvars; 9959 typval_T *rettv; 9960 { 9961 int i; 9962 char_u *name; 9963 int n = FALSE; 9964 static char *(has_list[]) = 9965 { 9966 #ifdef AMIGA 9967 "amiga", 9968 # ifdef FEAT_ARP 9969 "arp", 9970 # endif 9971 #endif 9972 #ifdef __BEOS__ 9973 "beos", 9974 #endif 9975 #ifdef MSDOS 9976 # ifdef DJGPP 9977 "dos32", 9978 # else 9979 "dos16", 9980 # endif 9981 #endif 9982 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 9983 "mac", 9984 #endif 9985 #if defined(MACOS_X_UNIX) 9986 "macunix", 9987 #endif 9988 #ifdef OS2 9989 "os2", 9990 #endif 9991 #ifdef __QNX__ 9992 "qnx", 9993 #endif 9994 #ifdef RISCOS 9995 "riscos", 9996 #endif 9997 #ifdef UNIX 9998 "unix", 9999 #endif 10000 #ifdef VMS 10001 "vms", 10002 #endif 10003 #ifdef WIN16 10004 "win16", 10005 #endif 10006 #ifdef WIN32 10007 "win32", 10008 #endif 10009 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10010 "win32unix", 10011 #endif 10012 #ifdef WIN64 10013 "win64", 10014 #endif 10015 #ifdef EBCDIC 10016 "ebcdic", 10017 #endif 10018 #ifndef CASE_INSENSITIVE_FILENAME 10019 "fname_case", 10020 #endif 10021 #ifdef FEAT_ARABIC 10022 "arabic", 10023 #endif 10024 #ifdef FEAT_AUTOCMD 10025 "autocmd", 10026 #endif 10027 #ifdef FEAT_BEVAL 10028 "balloon_eval", 10029 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10030 "balloon_multiline", 10031 # endif 10032 #endif 10033 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10034 "builtin_terms", 10035 # ifdef ALL_BUILTIN_TCAPS 10036 "all_builtin_terms", 10037 # endif 10038 #endif 10039 #ifdef FEAT_BYTEOFF 10040 "byte_offset", 10041 #endif 10042 #ifdef FEAT_CINDENT 10043 "cindent", 10044 #endif 10045 #ifdef FEAT_CLIENTSERVER 10046 "clientserver", 10047 #endif 10048 #ifdef FEAT_CLIPBOARD 10049 "clipboard", 10050 #endif 10051 #ifdef FEAT_CMDL_COMPL 10052 "cmdline_compl", 10053 #endif 10054 #ifdef FEAT_CMDHIST 10055 "cmdline_hist", 10056 #endif 10057 #ifdef FEAT_COMMENTS 10058 "comments", 10059 #endif 10060 #ifdef FEAT_CRYPT 10061 "cryptv", 10062 #endif 10063 #ifdef FEAT_CSCOPE 10064 "cscope", 10065 #endif 10066 #ifdef CURSOR_SHAPE 10067 "cursorshape", 10068 #endif 10069 #ifdef DEBUG 10070 "debug", 10071 #endif 10072 #ifdef FEAT_CON_DIALOG 10073 "dialog_con", 10074 #endif 10075 #ifdef FEAT_GUI_DIALOG 10076 "dialog_gui", 10077 #endif 10078 #ifdef FEAT_DIFF 10079 "diff", 10080 #endif 10081 #ifdef FEAT_DIGRAPHS 10082 "digraphs", 10083 #endif 10084 #ifdef FEAT_DND 10085 "dnd", 10086 #endif 10087 #ifdef FEAT_EMACS_TAGS 10088 "emacs_tags", 10089 #endif 10090 "eval", /* always present, of course! */ 10091 #ifdef FEAT_EX_EXTRA 10092 "ex_extra", 10093 #endif 10094 #ifdef FEAT_SEARCH_EXTRA 10095 "extra_search", 10096 #endif 10097 #ifdef FEAT_FKMAP 10098 "farsi", 10099 #endif 10100 #ifdef FEAT_SEARCHPATH 10101 "file_in_path", 10102 #endif 10103 #if defined(UNIX) && !defined(USE_SYSTEM) 10104 "filterpipe", 10105 #endif 10106 #ifdef FEAT_FIND_ID 10107 "find_in_path", 10108 #endif 10109 #ifdef FEAT_FOLDING 10110 "folding", 10111 #endif 10112 #ifdef FEAT_FOOTER 10113 "footer", 10114 #endif 10115 #if !defined(USE_SYSTEM) && defined(UNIX) 10116 "fork", 10117 #endif 10118 #ifdef FEAT_GETTEXT 10119 "gettext", 10120 #endif 10121 #ifdef FEAT_GUI 10122 "gui", 10123 #endif 10124 #ifdef FEAT_GUI_ATHENA 10125 # ifdef FEAT_GUI_NEXTAW 10126 "gui_neXtaw", 10127 # else 10128 "gui_athena", 10129 # endif 10130 #endif 10131 #ifdef FEAT_GUI_KDE 10132 "gui_kde", 10133 #endif 10134 #ifdef FEAT_GUI_GTK 10135 "gui_gtk", 10136 # ifdef HAVE_GTK2 10137 "gui_gtk2", 10138 # endif 10139 #endif 10140 #ifdef FEAT_GUI_MAC 10141 "gui_mac", 10142 #endif 10143 #ifdef FEAT_GUI_MOTIF 10144 "gui_motif", 10145 #endif 10146 #ifdef FEAT_GUI_PHOTON 10147 "gui_photon", 10148 #endif 10149 #ifdef FEAT_GUI_W16 10150 "gui_win16", 10151 #endif 10152 #ifdef FEAT_GUI_W32 10153 "gui_win32", 10154 #endif 10155 #ifdef FEAT_HANGULIN 10156 "hangul_input", 10157 #endif 10158 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10159 "iconv", 10160 #endif 10161 #ifdef FEAT_INS_EXPAND 10162 "insert_expand", 10163 #endif 10164 #ifdef FEAT_JUMPLIST 10165 "jumplist", 10166 #endif 10167 #ifdef FEAT_KEYMAP 10168 "keymap", 10169 #endif 10170 #ifdef FEAT_LANGMAP 10171 "langmap", 10172 #endif 10173 #ifdef FEAT_LIBCALL 10174 "libcall", 10175 #endif 10176 #ifdef FEAT_LINEBREAK 10177 "linebreak", 10178 #endif 10179 #ifdef FEAT_LISP 10180 "lispindent", 10181 #endif 10182 #ifdef FEAT_LISTCMDS 10183 "listcmds", 10184 #endif 10185 #ifdef FEAT_LOCALMAP 10186 "localmap", 10187 #endif 10188 #ifdef FEAT_MENU 10189 "menu", 10190 #endif 10191 #ifdef FEAT_SESSION 10192 "mksession", 10193 #endif 10194 #ifdef FEAT_MODIFY_FNAME 10195 "modify_fname", 10196 #endif 10197 #ifdef FEAT_MOUSE 10198 "mouse", 10199 #endif 10200 #ifdef FEAT_MOUSESHAPE 10201 "mouseshape", 10202 #endif 10203 #if defined(UNIX) || defined(VMS) 10204 # ifdef FEAT_MOUSE_DEC 10205 "mouse_dec", 10206 # endif 10207 # ifdef FEAT_MOUSE_GPM 10208 "mouse_gpm", 10209 # endif 10210 # ifdef FEAT_MOUSE_JSB 10211 "mouse_jsbterm", 10212 # endif 10213 # ifdef FEAT_MOUSE_NET 10214 "mouse_netterm", 10215 # endif 10216 # ifdef FEAT_MOUSE_PTERM 10217 "mouse_pterm", 10218 # endif 10219 # ifdef FEAT_MOUSE_XTERM 10220 "mouse_xterm", 10221 # endif 10222 #endif 10223 #ifdef FEAT_MBYTE 10224 "multi_byte", 10225 #endif 10226 #ifdef FEAT_MBYTE_IME 10227 "multi_byte_ime", 10228 #endif 10229 #ifdef FEAT_MULTI_LANG 10230 "multi_lang", 10231 #endif 10232 #ifdef FEAT_MZSCHEME 10233 #ifndef DYNAMIC_MZSCHEME 10234 "mzscheme", 10235 #endif 10236 #endif 10237 #ifdef FEAT_OLE 10238 "ole", 10239 #endif 10240 #ifdef FEAT_OSFILETYPE 10241 "osfiletype", 10242 #endif 10243 #ifdef FEAT_PATH_EXTRA 10244 "path_extra", 10245 #endif 10246 #ifdef FEAT_PERL 10247 #ifndef DYNAMIC_PERL 10248 "perl", 10249 #endif 10250 #endif 10251 #ifdef FEAT_PYTHON 10252 #ifndef DYNAMIC_PYTHON 10253 "python", 10254 #endif 10255 #endif 10256 #ifdef FEAT_POSTSCRIPT 10257 "postscript", 10258 #endif 10259 #ifdef FEAT_PRINTER 10260 "printer", 10261 #endif 10262 #ifdef FEAT_PROFILE 10263 "profile", 10264 #endif 10265 #ifdef FEAT_QUICKFIX 10266 "quickfix", 10267 #endif 10268 #ifdef FEAT_RIGHTLEFT 10269 "rightleft", 10270 #endif 10271 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10272 "ruby", 10273 #endif 10274 #ifdef FEAT_SCROLLBIND 10275 "scrollbind", 10276 #endif 10277 #ifdef FEAT_CMDL_INFO 10278 "showcmd", 10279 "cmdline_info", 10280 #endif 10281 #ifdef FEAT_SIGNS 10282 "signs", 10283 #endif 10284 #ifdef FEAT_SMARTINDENT 10285 "smartindent", 10286 #endif 10287 #ifdef FEAT_SNIFF 10288 "sniff", 10289 #endif 10290 #ifdef FEAT_STL_OPT 10291 "statusline", 10292 #endif 10293 #ifdef FEAT_SUN_WORKSHOP 10294 "sun_workshop", 10295 #endif 10296 #ifdef FEAT_NETBEANS_INTG 10297 "netbeans_intg", 10298 #endif 10299 #ifdef FEAT_SYN_HL 10300 "spell", 10301 #endif 10302 #ifdef FEAT_SYN_HL 10303 "syntax", 10304 #endif 10305 #if defined(USE_SYSTEM) || !defined(UNIX) 10306 "system", 10307 #endif 10308 #ifdef FEAT_TAG_BINS 10309 "tag_binary", 10310 #endif 10311 #ifdef FEAT_TAG_OLDSTATIC 10312 "tag_old_static", 10313 #endif 10314 #ifdef FEAT_TAG_ANYWHITE 10315 "tag_any_white", 10316 #endif 10317 #ifdef FEAT_TCL 10318 # ifndef DYNAMIC_TCL 10319 "tcl", 10320 # endif 10321 #endif 10322 #ifdef TERMINFO 10323 "terminfo", 10324 #endif 10325 #ifdef FEAT_TERMRESPONSE 10326 "termresponse", 10327 #endif 10328 #ifdef FEAT_TEXTOBJ 10329 "textobjects", 10330 #endif 10331 #ifdef HAVE_TGETENT 10332 "tgetent", 10333 #endif 10334 #ifdef FEAT_TITLE 10335 "title", 10336 #endif 10337 #ifdef FEAT_TOOLBAR 10338 "toolbar", 10339 #endif 10340 #ifdef FEAT_USR_CMDS 10341 "user-commands", /* was accidentally included in 5.4 */ 10342 "user_commands", 10343 #endif 10344 #ifdef FEAT_VIMINFO 10345 "viminfo", 10346 #endif 10347 #ifdef FEAT_VERTSPLIT 10348 "vertsplit", 10349 #endif 10350 #ifdef FEAT_VIRTUALEDIT 10351 "virtualedit", 10352 #endif 10353 #ifdef FEAT_VISUAL 10354 "visual", 10355 #endif 10356 #ifdef FEAT_VISUALEXTRA 10357 "visualextra", 10358 #endif 10359 #ifdef FEAT_VREPLACE 10360 "vreplace", 10361 #endif 10362 #ifdef FEAT_WILDIGN 10363 "wildignore", 10364 #endif 10365 #ifdef FEAT_WILDMENU 10366 "wildmenu", 10367 #endif 10368 #ifdef FEAT_WINDOWS 10369 "windows", 10370 #endif 10371 #ifdef FEAT_WAK 10372 "winaltkeys", 10373 #endif 10374 #ifdef FEAT_WRITEBACKUP 10375 "writebackup", 10376 #endif 10377 #ifdef FEAT_XIM 10378 "xim", 10379 #endif 10380 #ifdef FEAT_XFONTSET 10381 "xfontset", 10382 #endif 10383 #ifdef USE_XSMP 10384 "xsmp", 10385 #endif 10386 #ifdef USE_XSMP_INTERACT 10387 "xsmp_interact", 10388 #endif 10389 #ifdef FEAT_XCLIPBOARD 10390 "xterm_clipboard", 10391 #endif 10392 #ifdef FEAT_XTERM_SAVE 10393 "xterm_save", 10394 #endif 10395 #if defined(UNIX) && defined(FEAT_X11) 10396 "X11", 10397 #endif 10398 NULL 10399 }; 10400 10401 name = get_tv_string(&argvars[0]); 10402 for (i = 0; has_list[i] != NULL; ++i) 10403 if (STRICMP(name, has_list[i]) == 0) 10404 { 10405 n = TRUE; 10406 break; 10407 } 10408 10409 if (n == FALSE) 10410 { 10411 if (STRNICMP(name, "patch", 5) == 0) 10412 n = has_patch(atoi((char *)name + 5)); 10413 else if (STRICMP(name, "vim_starting") == 0) 10414 n = (starting != 0); 10415 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10416 else if (STRICMP(name, "balloon_multiline") == 0) 10417 n = multiline_balloon_available(); 10418 #endif 10419 #ifdef DYNAMIC_TCL 10420 else if (STRICMP(name, "tcl") == 0) 10421 n = tcl_enabled(FALSE); 10422 #endif 10423 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10424 else if (STRICMP(name, "iconv") == 0) 10425 n = iconv_enabled(FALSE); 10426 #endif 10427 #ifdef DYNAMIC_MZSCHEME 10428 else if (STRICMP(name, "mzscheme") == 0) 10429 n = mzscheme_enabled(FALSE); 10430 #endif 10431 #ifdef DYNAMIC_RUBY 10432 else if (STRICMP(name, "ruby") == 0) 10433 n = ruby_enabled(FALSE); 10434 #endif 10435 #ifdef DYNAMIC_PYTHON 10436 else if (STRICMP(name, "python") == 0) 10437 n = python_enabled(FALSE); 10438 #endif 10439 #ifdef DYNAMIC_PERL 10440 else if (STRICMP(name, "perl") == 0) 10441 n = perl_enabled(FALSE); 10442 #endif 10443 #ifdef FEAT_GUI 10444 else if (STRICMP(name, "gui_running") == 0) 10445 n = (gui.in_use || gui.starting); 10446 # ifdef FEAT_GUI_W32 10447 else if (STRICMP(name, "gui_win32s") == 0) 10448 n = gui_is_win32s(); 10449 # endif 10450 # ifdef FEAT_BROWSE 10451 else if (STRICMP(name, "browse") == 0) 10452 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10453 # endif 10454 #endif 10455 #ifdef FEAT_SYN_HL 10456 else if (STRICMP(name, "syntax_items") == 0) 10457 n = syntax_present(curbuf); 10458 #endif 10459 #if defined(WIN3264) 10460 else if (STRICMP(name, "win95") == 0) 10461 n = mch_windows95(); 10462 #endif 10463 #ifdef FEAT_NETBEANS_INTG 10464 else if (STRICMP(name, "netbeans_enabled") == 0) 10465 n = usingNetbeans; 10466 #endif 10467 } 10468 10469 rettv->vval.v_number = n; 10470 } 10471 10472 /* 10473 * "has_key()" function 10474 */ 10475 static void 10476 f_has_key(argvars, rettv) 10477 typval_T *argvars; 10478 typval_T *rettv; 10479 { 10480 rettv->vval.v_number = 0; 10481 if (argvars[0].v_type != VAR_DICT) 10482 { 10483 EMSG(_(e_dictreq)); 10484 return; 10485 } 10486 if (argvars[0].vval.v_dict == NULL) 10487 return; 10488 10489 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10490 get_tv_string(&argvars[1]), -1) != NULL; 10491 } 10492 10493 /* 10494 * "hasmapto()" function 10495 */ 10496 static void 10497 f_hasmapto(argvars, rettv) 10498 typval_T *argvars; 10499 typval_T *rettv; 10500 { 10501 char_u *name; 10502 char_u *mode; 10503 char_u buf[NUMBUFLEN]; 10504 10505 name = get_tv_string(&argvars[0]); 10506 if (argvars[1].v_type == VAR_UNKNOWN) 10507 mode = (char_u *)"nvo"; 10508 else 10509 mode = get_tv_string_buf(&argvars[1], buf); 10510 10511 if (map_to_exists(name, mode)) 10512 rettv->vval.v_number = TRUE; 10513 else 10514 rettv->vval.v_number = FALSE; 10515 } 10516 10517 /* 10518 * "histadd()" function 10519 */ 10520 /*ARGSUSED*/ 10521 static void 10522 f_histadd(argvars, rettv) 10523 typval_T *argvars; 10524 typval_T *rettv; 10525 { 10526 #ifdef FEAT_CMDHIST 10527 int histype; 10528 char_u *str; 10529 char_u buf[NUMBUFLEN]; 10530 #endif 10531 10532 rettv->vval.v_number = FALSE; 10533 if (check_restricted() || check_secure()) 10534 return; 10535 #ifdef FEAT_CMDHIST 10536 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10537 histype = str != NULL ? get_histtype(str) : -1; 10538 if (histype >= 0) 10539 { 10540 str = get_tv_string_buf(&argvars[1], buf); 10541 if (*str != NUL) 10542 { 10543 add_to_history(histype, str, FALSE, NUL); 10544 rettv->vval.v_number = TRUE; 10545 return; 10546 } 10547 } 10548 #endif 10549 } 10550 10551 /* 10552 * "histdel()" function 10553 */ 10554 /*ARGSUSED*/ 10555 static void 10556 f_histdel(argvars, rettv) 10557 typval_T *argvars; 10558 typval_T *rettv; 10559 { 10560 #ifdef FEAT_CMDHIST 10561 int n; 10562 char_u buf[NUMBUFLEN]; 10563 char_u *str; 10564 10565 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10566 if (str == NULL) 10567 n = 0; 10568 else if (argvars[1].v_type == VAR_UNKNOWN) 10569 /* only one argument: clear entire history */ 10570 n = clr_history(get_histtype(str)); 10571 else if (argvars[1].v_type == VAR_NUMBER) 10572 /* index given: remove that entry */ 10573 n = del_history_idx(get_histtype(str), 10574 (int)get_tv_number(&argvars[1])); 10575 else 10576 /* string given: remove all matching entries */ 10577 n = del_history_entry(get_histtype(str), 10578 get_tv_string_buf(&argvars[1], buf)); 10579 rettv->vval.v_number = n; 10580 #else 10581 rettv->vval.v_number = 0; 10582 #endif 10583 } 10584 10585 /* 10586 * "histget()" function 10587 */ 10588 /*ARGSUSED*/ 10589 static void 10590 f_histget(argvars, rettv) 10591 typval_T *argvars; 10592 typval_T *rettv; 10593 { 10594 #ifdef FEAT_CMDHIST 10595 int type; 10596 int idx; 10597 char_u *str; 10598 10599 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10600 if (str == NULL) 10601 rettv->vval.v_string = NULL; 10602 else 10603 { 10604 type = get_histtype(str); 10605 if (argvars[1].v_type == VAR_UNKNOWN) 10606 idx = get_history_idx(type); 10607 else 10608 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10609 /* -1 on type error */ 10610 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10611 } 10612 #else 10613 rettv->vval.v_string = NULL; 10614 #endif 10615 rettv->v_type = VAR_STRING; 10616 } 10617 10618 /* 10619 * "histnr()" function 10620 */ 10621 /*ARGSUSED*/ 10622 static void 10623 f_histnr(argvars, rettv) 10624 typval_T *argvars; 10625 typval_T *rettv; 10626 { 10627 int i; 10628 10629 #ifdef FEAT_CMDHIST 10630 char_u *history = get_tv_string_chk(&argvars[0]); 10631 10632 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10633 if (i >= HIST_CMD && i < HIST_COUNT) 10634 i = get_history_idx(i); 10635 else 10636 #endif 10637 i = -1; 10638 rettv->vval.v_number = i; 10639 } 10640 10641 /* 10642 * "highlightID(name)" function 10643 */ 10644 static void 10645 f_hlID(argvars, rettv) 10646 typval_T *argvars; 10647 typval_T *rettv; 10648 { 10649 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10650 } 10651 10652 /* 10653 * "highlight_exists()" function 10654 */ 10655 static void 10656 f_hlexists(argvars, rettv) 10657 typval_T *argvars; 10658 typval_T *rettv; 10659 { 10660 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10661 } 10662 10663 /* 10664 * "hostname()" function 10665 */ 10666 /*ARGSUSED*/ 10667 static void 10668 f_hostname(argvars, rettv) 10669 typval_T *argvars; 10670 typval_T *rettv; 10671 { 10672 char_u hostname[256]; 10673 10674 mch_get_host_name(hostname, 256); 10675 rettv->v_type = VAR_STRING; 10676 rettv->vval.v_string = vim_strsave(hostname); 10677 } 10678 10679 /* 10680 * iconv() function 10681 */ 10682 /*ARGSUSED*/ 10683 static void 10684 f_iconv(argvars, rettv) 10685 typval_T *argvars; 10686 typval_T *rettv; 10687 { 10688 #ifdef FEAT_MBYTE 10689 char_u buf1[NUMBUFLEN]; 10690 char_u buf2[NUMBUFLEN]; 10691 char_u *from, *to, *str; 10692 vimconv_T vimconv; 10693 #endif 10694 10695 rettv->v_type = VAR_STRING; 10696 rettv->vval.v_string = NULL; 10697 10698 #ifdef FEAT_MBYTE 10699 str = get_tv_string(&argvars[0]); 10700 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10701 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10702 vimconv.vc_type = CONV_NONE; 10703 convert_setup(&vimconv, from, to); 10704 10705 /* If the encodings are equal, no conversion needed. */ 10706 if (vimconv.vc_type == CONV_NONE) 10707 rettv->vval.v_string = vim_strsave(str); 10708 else 10709 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10710 10711 convert_setup(&vimconv, NULL, NULL); 10712 vim_free(from); 10713 vim_free(to); 10714 #endif 10715 } 10716 10717 /* 10718 * "indent()" function 10719 */ 10720 static void 10721 f_indent(argvars, rettv) 10722 typval_T *argvars; 10723 typval_T *rettv; 10724 { 10725 linenr_T lnum; 10726 10727 lnum = get_tv_lnum(argvars); 10728 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10729 rettv->vval.v_number = get_indent_lnum(lnum); 10730 else 10731 rettv->vval.v_number = -1; 10732 } 10733 10734 /* 10735 * "index()" function 10736 */ 10737 static void 10738 f_index(argvars, rettv) 10739 typval_T *argvars; 10740 typval_T *rettv; 10741 { 10742 list_T *l; 10743 listitem_T *item; 10744 long idx = 0; 10745 int ic = FALSE; 10746 10747 rettv->vval.v_number = -1; 10748 if (argvars[0].v_type != VAR_LIST) 10749 { 10750 EMSG(_(e_listreq)); 10751 return; 10752 } 10753 l = argvars[0].vval.v_list; 10754 if (l != NULL) 10755 { 10756 item = l->lv_first; 10757 if (argvars[2].v_type != VAR_UNKNOWN) 10758 { 10759 int error = FALSE; 10760 10761 /* Start at specified item. Use the cached index that list_find() 10762 * sets, so that a negative number also works. */ 10763 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10764 idx = l->lv_idx; 10765 if (argvars[3].v_type != VAR_UNKNOWN) 10766 ic = get_tv_number_chk(&argvars[3], &error); 10767 if (error) 10768 item = NULL; 10769 } 10770 10771 for ( ; item != NULL; item = item->li_next, ++idx) 10772 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10773 { 10774 rettv->vval.v_number = idx; 10775 break; 10776 } 10777 } 10778 } 10779 10780 static int inputsecret_flag = 0; 10781 10782 /* 10783 * "input()" function 10784 * Also handles inputsecret() when inputsecret is set. 10785 */ 10786 static void 10787 f_input(argvars, rettv) 10788 typval_T *argvars; 10789 typval_T *rettv; 10790 { 10791 char_u *prompt = get_tv_string_chk(&argvars[0]); 10792 char_u *p = NULL; 10793 int c; 10794 char_u buf[NUMBUFLEN]; 10795 int cmd_silent_save = cmd_silent; 10796 char_u *defstr = (char_u *)""; 10797 10798 rettv->v_type = VAR_STRING; 10799 10800 #ifdef NO_CONSOLE_INPUT 10801 /* While starting up, there is no place to enter text. */ 10802 if (no_console_input()) 10803 { 10804 rettv->vval.v_string = NULL; 10805 return; 10806 } 10807 #endif 10808 10809 cmd_silent = FALSE; /* Want to see the prompt. */ 10810 if (prompt != NULL) 10811 { 10812 /* Only the part of the message after the last NL is considered as 10813 * prompt for the command line */ 10814 p = vim_strrchr(prompt, '\n'); 10815 if (p == NULL) 10816 p = prompt; 10817 else 10818 { 10819 ++p; 10820 c = *p; 10821 *p = NUL; 10822 msg_start(); 10823 msg_clr_eos(); 10824 msg_puts_attr(prompt, echo_attr); 10825 msg_didout = FALSE; 10826 msg_starthere(); 10827 *p = c; 10828 } 10829 cmdline_row = msg_row; 10830 10831 if (argvars[1].v_type != VAR_UNKNOWN) 10832 { 10833 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10834 if (defstr != NULL) 10835 stuffReadbuffSpec(defstr); 10836 } 10837 10838 if (defstr != NULL) 10839 rettv->vval.v_string = 10840 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr); 10841 10842 /* since the user typed this, no need to wait for return */ 10843 need_wait_return = FALSE; 10844 msg_didout = FALSE; 10845 } 10846 cmd_silent = cmd_silent_save; 10847 } 10848 10849 /* 10850 * "inputdialog()" function 10851 */ 10852 static void 10853 f_inputdialog(argvars, rettv) 10854 typval_T *argvars; 10855 typval_T *rettv; 10856 { 10857 #if defined(FEAT_GUI_TEXTDIALOG) 10858 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10859 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10860 { 10861 char_u *message; 10862 char_u buf[NUMBUFLEN]; 10863 char_u *defstr = (char_u *)""; 10864 10865 message = get_tv_string_chk(&argvars[0]); 10866 if (argvars[1].v_type != VAR_UNKNOWN 10867 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10868 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10869 else 10870 IObuff[0] = NUL; 10871 if (message != NULL && defstr != NULL 10872 && do_dialog(VIM_QUESTION, NULL, message, 10873 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10874 rettv->vval.v_string = vim_strsave(IObuff); 10875 else 10876 { 10877 if (message != NULL && defstr != NULL 10878 && argvars[1].v_type != VAR_UNKNOWN 10879 && argvars[2].v_type != VAR_UNKNOWN) 10880 rettv->vval.v_string = vim_strsave( 10881 get_tv_string_buf(&argvars[2], buf)); 10882 else 10883 rettv->vval.v_string = NULL; 10884 } 10885 rettv->v_type = VAR_STRING; 10886 } 10887 else 10888 #endif 10889 f_input(argvars, rettv); 10890 } 10891 10892 /* 10893 * "inputlist()" function 10894 */ 10895 static void 10896 f_inputlist(argvars, rettv) 10897 typval_T *argvars; 10898 typval_T *rettv; 10899 { 10900 listitem_T *li; 10901 int selected; 10902 int mouse_used; 10903 10904 rettv->vval.v_number = 0; 10905 #ifdef NO_CONSOLE_INPUT 10906 /* While starting up, there is no place to enter text. */ 10907 if (no_console_input()) 10908 return; 10909 #endif 10910 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 10911 { 10912 EMSG2(_(e_listarg), "inputlist()"); 10913 return; 10914 } 10915 10916 msg_start(); 10917 lines_left = Rows; /* avoid more prompt */ 10918 msg_scroll = TRUE; 10919 msg_clr_eos(); 10920 10921 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 10922 { 10923 msg_puts(get_tv_string(&li->li_tv)); 10924 msg_putchar('\n'); 10925 } 10926 10927 /* Ask for choice. */ 10928 selected = prompt_for_number(&mouse_used); 10929 if (mouse_used) 10930 selected -= lines_left; 10931 10932 rettv->vval.v_number = selected; 10933 } 10934 10935 10936 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 10937 10938 /* 10939 * "inputrestore()" function 10940 */ 10941 /*ARGSUSED*/ 10942 static void 10943 f_inputrestore(argvars, rettv) 10944 typval_T *argvars; 10945 typval_T *rettv; 10946 { 10947 if (ga_userinput.ga_len > 0) 10948 { 10949 --ga_userinput.ga_len; 10950 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 10951 + ga_userinput.ga_len); 10952 rettv->vval.v_number = 0; /* OK */ 10953 } 10954 else if (p_verbose > 1) 10955 { 10956 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 10957 rettv->vval.v_number = 1; /* Failed */ 10958 } 10959 } 10960 10961 /* 10962 * "inputsave()" function 10963 */ 10964 /*ARGSUSED*/ 10965 static void 10966 f_inputsave(argvars, rettv) 10967 typval_T *argvars; 10968 typval_T *rettv; 10969 { 10970 /* Add an entry to the stack of typehead storage. */ 10971 if (ga_grow(&ga_userinput, 1) == OK) 10972 { 10973 save_typeahead((tasave_T *)(ga_userinput.ga_data) 10974 + ga_userinput.ga_len); 10975 ++ga_userinput.ga_len; 10976 rettv->vval.v_number = 0; /* OK */ 10977 } 10978 else 10979 rettv->vval.v_number = 1; /* Failed */ 10980 } 10981 10982 /* 10983 * "inputsecret()" function 10984 */ 10985 static void 10986 f_inputsecret(argvars, rettv) 10987 typval_T *argvars; 10988 typval_T *rettv; 10989 { 10990 ++cmdline_star; 10991 ++inputsecret_flag; 10992 f_input(argvars, rettv); 10993 --cmdline_star; 10994 --inputsecret_flag; 10995 } 10996 10997 /* 10998 * "insert()" function 10999 */ 11000 static void 11001 f_insert(argvars, rettv) 11002 typval_T *argvars; 11003 typval_T *rettv; 11004 { 11005 long before = 0; 11006 listitem_T *item; 11007 list_T *l; 11008 int error = FALSE; 11009 11010 rettv->vval.v_number = 0; 11011 if (argvars[0].v_type != VAR_LIST) 11012 EMSG2(_(e_listarg), "insert()"); 11013 else if ((l = argvars[0].vval.v_list) != NULL 11014 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11015 { 11016 if (argvars[2].v_type != VAR_UNKNOWN) 11017 before = get_tv_number_chk(&argvars[2], &error); 11018 if (error) 11019 return; /* type error; errmsg already given */ 11020 11021 if (before == l->lv_len) 11022 item = NULL; 11023 else 11024 { 11025 item = list_find(l, before); 11026 if (item == NULL) 11027 { 11028 EMSGN(_(e_listidx), before); 11029 l = NULL; 11030 } 11031 } 11032 if (l != NULL) 11033 { 11034 list_insert_tv(l, &argvars[1], item); 11035 copy_tv(&argvars[0], rettv); 11036 } 11037 } 11038 } 11039 11040 /* 11041 * "isdirectory()" function 11042 */ 11043 static void 11044 f_isdirectory(argvars, rettv) 11045 typval_T *argvars; 11046 typval_T *rettv; 11047 { 11048 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11049 } 11050 11051 /* 11052 * "islocked()" function 11053 */ 11054 static void 11055 f_islocked(argvars, rettv) 11056 typval_T *argvars; 11057 typval_T *rettv; 11058 { 11059 lval_T lv; 11060 char_u *end; 11061 dictitem_T *di; 11062 11063 rettv->vval.v_number = -1; 11064 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11065 FNE_CHECK_START); 11066 if (end != NULL && lv.ll_name != NULL) 11067 { 11068 if (*end != NUL) 11069 EMSG(_(e_trailing)); 11070 else 11071 { 11072 if (lv.ll_tv == NULL) 11073 { 11074 if (check_changedtick(lv.ll_name)) 11075 rettv->vval.v_number = 1; /* always locked */ 11076 else 11077 { 11078 di = find_var(lv.ll_name, NULL); 11079 if (di != NULL) 11080 { 11081 /* Consider a variable locked when: 11082 * 1. the variable itself is locked 11083 * 2. the value of the variable is locked. 11084 * 3. the List or Dict value is locked. 11085 */ 11086 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11087 || tv_islocked(&di->di_tv)); 11088 } 11089 } 11090 } 11091 else if (lv.ll_range) 11092 EMSG(_("E745: Range not allowed")); 11093 else if (lv.ll_newkey != NULL) 11094 EMSG2(_(e_dictkey), lv.ll_newkey); 11095 else if (lv.ll_list != NULL) 11096 /* List item. */ 11097 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11098 else 11099 /* Dictionary item. */ 11100 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11101 } 11102 } 11103 11104 clear_lval(&lv); 11105 } 11106 11107 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11108 11109 /* 11110 * Turn a dict into a list: 11111 * "what" == 0: list of keys 11112 * "what" == 1: list of values 11113 * "what" == 2: list of items 11114 */ 11115 static void 11116 dict_list(argvars, rettv, what) 11117 typval_T *argvars; 11118 typval_T *rettv; 11119 int what; 11120 { 11121 list_T *l; 11122 list_T *l2; 11123 dictitem_T *di; 11124 hashitem_T *hi; 11125 listitem_T *li; 11126 listitem_T *li2; 11127 dict_T *d; 11128 int todo; 11129 11130 rettv->vval.v_number = 0; 11131 if (argvars[0].v_type != VAR_DICT) 11132 { 11133 EMSG(_(e_dictreq)); 11134 return; 11135 } 11136 if ((d = argvars[0].vval.v_dict) == NULL) 11137 return; 11138 11139 l = list_alloc(); 11140 if (l == NULL) 11141 return; 11142 rettv->v_type = VAR_LIST; 11143 rettv->vval.v_list = l; 11144 ++l->lv_refcount; 11145 11146 todo = d->dv_hashtab.ht_used; 11147 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11148 { 11149 if (!HASHITEM_EMPTY(hi)) 11150 { 11151 --todo; 11152 di = HI2DI(hi); 11153 11154 li = listitem_alloc(); 11155 if (li == NULL) 11156 break; 11157 list_append(l, li); 11158 11159 if (what == 0) 11160 { 11161 /* keys() */ 11162 li->li_tv.v_type = VAR_STRING; 11163 li->li_tv.v_lock = 0; 11164 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11165 } 11166 else if (what == 1) 11167 { 11168 /* values() */ 11169 copy_tv(&di->di_tv, &li->li_tv); 11170 } 11171 else 11172 { 11173 /* items() */ 11174 l2 = list_alloc(); 11175 li->li_tv.v_type = VAR_LIST; 11176 li->li_tv.v_lock = 0; 11177 li->li_tv.vval.v_list = l2; 11178 if (l2 == NULL) 11179 break; 11180 ++l2->lv_refcount; 11181 11182 li2 = listitem_alloc(); 11183 if (li2 == NULL) 11184 break; 11185 list_append(l2, li2); 11186 li2->li_tv.v_type = VAR_STRING; 11187 li2->li_tv.v_lock = 0; 11188 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11189 11190 li2 = listitem_alloc(); 11191 if (li2 == NULL) 11192 break; 11193 list_append(l2, li2); 11194 copy_tv(&di->di_tv, &li2->li_tv); 11195 } 11196 } 11197 } 11198 } 11199 11200 /* 11201 * "items(dict)" function 11202 */ 11203 static void 11204 f_items(argvars, rettv) 11205 typval_T *argvars; 11206 typval_T *rettv; 11207 { 11208 dict_list(argvars, rettv, 2); 11209 } 11210 11211 /* 11212 * "join()" function 11213 */ 11214 static void 11215 f_join(argvars, rettv) 11216 typval_T *argvars; 11217 typval_T *rettv; 11218 { 11219 garray_T ga; 11220 char_u *sep; 11221 11222 rettv->vval.v_number = 0; 11223 if (argvars[0].v_type != VAR_LIST) 11224 { 11225 EMSG(_(e_listreq)); 11226 return; 11227 } 11228 if (argvars[0].vval.v_list == NULL) 11229 return; 11230 if (argvars[1].v_type == VAR_UNKNOWN) 11231 sep = (char_u *)" "; 11232 else 11233 sep = get_tv_string_chk(&argvars[1]); 11234 11235 rettv->v_type = VAR_STRING; 11236 11237 if (sep != NULL) 11238 { 11239 ga_init2(&ga, (int)sizeof(char), 80); 11240 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11241 ga_append(&ga, NUL); 11242 rettv->vval.v_string = (char_u *)ga.ga_data; 11243 } 11244 else 11245 rettv->vval.v_string = NULL; 11246 } 11247 11248 /* 11249 * "keys()" function 11250 */ 11251 static void 11252 f_keys(argvars, rettv) 11253 typval_T *argvars; 11254 typval_T *rettv; 11255 { 11256 dict_list(argvars, rettv, 0); 11257 } 11258 11259 /* 11260 * "last_buffer_nr()" function. 11261 */ 11262 /*ARGSUSED*/ 11263 static void 11264 f_last_buffer_nr(argvars, rettv) 11265 typval_T *argvars; 11266 typval_T *rettv; 11267 { 11268 int n = 0; 11269 buf_T *buf; 11270 11271 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11272 if (n < buf->b_fnum) 11273 n = buf->b_fnum; 11274 11275 rettv->vval.v_number = n; 11276 } 11277 11278 /* 11279 * "len()" function 11280 */ 11281 static void 11282 f_len(argvars, rettv) 11283 typval_T *argvars; 11284 typval_T *rettv; 11285 { 11286 switch (argvars[0].v_type) 11287 { 11288 case VAR_STRING: 11289 case VAR_NUMBER: 11290 rettv->vval.v_number = (varnumber_T)STRLEN( 11291 get_tv_string(&argvars[0])); 11292 break; 11293 case VAR_LIST: 11294 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11295 break; 11296 case VAR_DICT: 11297 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11298 break; 11299 default: 11300 EMSG(_("E701: Invalid type for len()")); 11301 break; 11302 } 11303 } 11304 11305 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11306 11307 static void 11308 libcall_common(argvars, rettv, type) 11309 typval_T *argvars; 11310 typval_T *rettv; 11311 int type; 11312 { 11313 #ifdef FEAT_LIBCALL 11314 char_u *string_in; 11315 char_u **string_result; 11316 int nr_result; 11317 #endif 11318 11319 rettv->v_type = type; 11320 if (type == VAR_NUMBER) 11321 rettv->vval.v_number = 0; 11322 else 11323 rettv->vval.v_string = NULL; 11324 11325 if (check_restricted() || check_secure()) 11326 return; 11327 11328 #ifdef FEAT_LIBCALL 11329 /* The first two args must be strings, otherwise its meaningless */ 11330 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11331 { 11332 string_in = NULL; 11333 if (argvars[2].v_type == VAR_STRING) 11334 string_in = argvars[2].vval.v_string; 11335 if (type == VAR_NUMBER) 11336 string_result = NULL; 11337 else 11338 string_result = &rettv->vval.v_string; 11339 if (mch_libcall(argvars[0].vval.v_string, 11340 argvars[1].vval.v_string, 11341 string_in, 11342 argvars[2].vval.v_number, 11343 string_result, 11344 &nr_result) == OK 11345 && type == VAR_NUMBER) 11346 rettv->vval.v_number = nr_result; 11347 } 11348 #endif 11349 } 11350 11351 /* 11352 * "libcall()" function 11353 */ 11354 static void 11355 f_libcall(argvars, rettv) 11356 typval_T *argvars; 11357 typval_T *rettv; 11358 { 11359 libcall_common(argvars, rettv, VAR_STRING); 11360 } 11361 11362 /* 11363 * "libcallnr()" function 11364 */ 11365 static void 11366 f_libcallnr(argvars, rettv) 11367 typval_T *argvars; 11368 typval_T *rettv; 11369 { 11370 libcall_common(argvars, rettv, VAR_NUMBER); 11371 } 11372 11373 /* 11374 * "line(string)" function 11375 */ 11376 static void 11377 f_line(argvars, rettv) 11378 typval_T *argvars; 11379 typval_T *rettv; 11380 { 11381 linenr_T lnum = 0; 11382 pos_T *fp; 11383 11384 fp = var2fpos(&argvars[0], TRUE); 11385 if (fp != NULL) 11386 lnum = fp->lnum; 11387 rettv->vval.v_number = lnum; 11388 } 11389 11390 /* 11391 * "line2byte(lnum)" function 11392 */ 11393 /*ARGSUSED*/ 11394 static void 11395 f_line2byte(argvars, rettv) 11396 typval_T *argvars; 11397 typval_T *rettv; 11398 { 11399 #ifndef FEAT_BYTEOFF 11400 rettv->vval.v_number = -1; 11401 #else 11402 linenr_T lnum; 11403 11404 lnum = get_tv_lnum(argvars); 11405 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11406 rettv->vval.v_number = -1; 11407 else 11408 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11409 if (rettv->vval.v_number >= 0) 11410 ++rettv->vval.v_number; 11411 #endif 11412 } 11413 11414 /* 11415 * "lispindent(lnum)" function 11416 */ 11417 static void 11418 f_lispindent(argvars, rettv) 11419 typval_T *argvars; 11420 typval_T *rettv; 11421 { 11422 #ifdef FEAT_LISP 11423 pos_T pos; 11424 linenr_T lnum; 11425 11426 pos = curwin->w_cursor; 11427 lnum = get_tv_lnum(argvars); 11428 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11429 { 11430 curwin->w_cursor.lnum = lnum; 11431 rettv->vval.v_number = get_lisp_indent(); 11432 curwin->w_cursor = pos; 11433 } 11434 else 11435 #endif 11436 rettv->vval.v_number = -1; 11437 } 11438 11439 /* 11440 * "localtime()" function 11441 */ 11442 /*ARGSUSED*/ 11443 static void 11444 f_localtime(argvars, rettv) 11445 typval_T *argvars; 11446 typval_T *rettv; 11447 { 11448 rettv->vval.v_number = (varnumber_T)time(NULL); 11449 } 11450 11451 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11452 11453 static void 11454 get_maparg(argvars, rettv, exact) 11455 typval_T *argvars; 11456 typval_T *rettv; 11457 int exact; 11458 { 11459 char_u *keys; 11460 char_u *which; 11461 char_u buf[NUMBUFLEN]; 11462 char_u *keys_buf = NULL; 11463 char_u *rhs; 11464 int mode; 11465 garray_T ga; 11466 11467 /* return empty string for failure */ 11468 rettv->v_type = VAR_STRING; 11469 rettv->vval.v_string = NULL; 11470 11471 keys = get_tv_string(&argvars[0]); 11472 if (*keys == NUL) 11473 return; 11474 11475 if (argvars[1].v_type != VAR_UNKNOWN) 11476 which = get_tv_string_buf_chk(&argvars[1], buf); 11477 else 11478 which = (char_u *)""; 11479 if (which == NULL) 11480 return; 11481 11482 mode = get_map_mode(&which, 0); 11483 11484 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11485 rhs = check_map(keys, mode, exact, FALSE); 11486 vim_free(keys_buf); 11487 if (rhs != NULL) 11488 { 11489 ga_init(&ga); 11490 ga.ga_itemsize = 1; 11491 ga.ga_growsize = 40; 11492 11493 while (*rhs != NUL) 11494 ga_concat(&ga, str2special(&rhs, FALSE)); 11495 11496 ga_append(&ga, NUL); 11497 rettv->vval.v_string = (char_u *)ga.ga_data; 11498 } 11499 } 11500 11501 /* 11502 * "map()" function 11503 */ 11504 static void 11505 f_map(argvars, rettv) 11506 typval_T *argvars; 11507 typval_T *rettv; 11508 { 11509 filter_map(argvars, rettv, TRUE); 11510 } 11511 11512 /* 11513 * "maparg()" function 11514 */ 11515 static void 11516 f_maparg(argvars, rettv) 11517 typval_T *argvars; 11518 typval_T *rettv; 11519 { 11520 get_maparg(argvars, rettv, TRUE); 11521 } 11522 11523 /* 11524 * "mapcheck()" function 11525 */ 11526 static void 11527 f_mapcheck(argvars, rettv) 11528 typval_T *argvars; 11529 typval_T *rettv; 11530 { 11531 get_maparg(argvars, rettv, FALSE); 11532 } 11533 11534 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11535 11536 static void 11537 find_some_match(argvars, rettv, type) 11538 typval_T *argvars; 11539 typval_T *rettv; 11540 int type; 11541 { 11542 char_u *str = NULL; 11543 char_u *expr = NULL; 11544 char_u *pat; 11545 regmatch_T regmatch; 11546 char_u patbuf[NUMBUFLEN]; 11547 char_u strbuf[NUMBUFLEN]; 11548 char_u *save_cpo; 11549 long start = 0; 11550 long nth = 1; 11551 int match = 0; 11552 list_T *l = NULL; 11553 listitem_T *li = NULL; 11554 long idx = 0; 11555 char_u *tofree = NULL; 11556 11557 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11558 save_cpo = p_cpo; 11559 p_cpo = (char_u *)""; 11560 11561 rettv->vval.v_number = -1; 11562 if (type == 3) 11563 { 11564 /* return empty list when there are no matches */ 11565 if ((rettv->vval.v_list = list_alloc()) == NULL) 11566 goto theend; 11567 rettv->v_type = VAR_LIST; 11568 ++rettv->vval.v_list->lv_refcount; 11569 } 11570 else if (type == 2) 11571 { 11572 rettv->v_type = VAR_STRING; 11573 rettv->vval.v_string = NULL; 11574 } 11575 11576 if (argvars[0].v_type == VAR_LIST) 11577 { 11578 if ((l = argvars[0].vval.v_list) == NULL) 11579 goto theend; 11580 li = l->lv_first; 11581 } 11582 else 11583 expr = str = get_tv_string(&argvars[0]); 11584 11585 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11586 if (pat == NULL) 11587 goto theend; 11588 11589 if (argvars[2].v_type != VAR_UNKNOWN) 11590 { 11591 int error = FALSE; 11592 11593 start = get_tv_number_chk(&argvars[2], &error); 11594 if (error) 11595 goto theend; 11596 if (l != NULL) 11597 { 11598 li = list_find(l, start); 11599 if (li == NULL) 11600 goto theend; 11601 idx = l->lv_idx; /* use the cached index */ 11602 } 11603 else 11604 { 11605 if (start < 0) 11606 start = 0; 11607 if (start > (long)STRLEN(str)) 11608 goto theend; 11609 str += start; 11610 } 11611 11612 if (argvars[3].v_type != VAR_UNKNOWN) 11613 nth = get_tv_number_chk(&argvars[3], &error); 11614 if (error) 11615 goto theend; 11616 } 11617 11618 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11619 if (regmatch.regprog != NULL) 11620 { 11621 regmatch.rm_ic = p_ic; 11622 11623 for (;;) 11624 { 11625 if (l != NULL) 11626 { 11627 if (li == NULL) 11628 { 11629 match = FALSE; 11630 break; 11631 } 11632 vim_free(tofree); 11633 str = echo_string(&li->li_tv, &tofree, strbuf); 11634 if (str == NULL) 11635 break; 11636 } 11637 11638 match = vim_regexec_nl(®match, str, (colnr_T)0); 11639 11640 if (match && --nth <= 0) 11641 break; 11642 if (l == NULL && !match) 11643 break; 11644 11645 /* Advance to just after the match. */ 11646 if (l != NULL) 11647 { 11648 li = li->li_next; 11649 ++idx; 11650 } 11651 else 11652 { 11653 #ifdef FEAT_MBYTE 11654 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11655 #else 11656 str = regmatch.startp[0] + 1; 11657 #endif 11658 } 11659 } 11660 11661 if (match) 11662 { 11663 if (type == 3) 11664 { 11665 int i; 11666 11667 /* return list with matched string and submatches */ 11668 for (i = 0; i < NSUBEXP; ++i) 11669 { 11670 if (regmatch.endp[i] == NULL) 11671 break; 11672 li = listitem_alloc(); 11673 if (li == NULL) 11674 break; 11675 li->li_tv.v_type = VAR_STRING; 11676 li->li_tv.v_lock = 0; 11677 li->li_tv.vval.v_string = vim_strnsave(regmatch.startp[i], 11678 (int)(regmatch.endp[i] - regmatch.startp[i])); 11679 list_append(rettv->vval.v_list, li); 11680 } 11681 } 11682 else if (type == 2) 11683 { 11684 /* return matched string */ 11685 if (l != NULL) 11686 copy_tv(&li->li_tv, rettv); 11687 else 11688 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11689 (int)(regmatch.endp[0] - regmatch.startp[0])); 11690 } 11691 else if (l != NULL) 11692 rettv->vval.v_number = idx; 11693 else 11694 { 11695 if (type != 0) 11696 rettv->vval.v_number = 11697 (varnumber_T)(regmatch.startp[0] - str); 11698 else 11699 rettv->vval.v_number = 11700 (varnumber_T)(regmatch.endp[0] - str); 11701 rettv->vval.v_number += str - expr; 11702 } 11703 } 11704 vim_free(regmatch.regprog); 11705 } 11706 11707 theend: 11708 vim_free(tofree); 11709 p_cpo = save_cpo; 11710 } 11711 11712 /* 11713 * "match()" function 11714 */ 11715 static void 11716 f_match(argvars, rettv) 11717 typval_T *argvars; 11718 typval_T *rettv; 11719 { 11720 find_some_match(argvars, rettv, 1); 11721 } 11722 11723 /* 11724 * "matchend()" function 11725 */ 11726 static void 11727 f_matchend(argvars, rettv) 11728 typval_T *argvars; 11729 typval_T *rettv; 11730 { 11731 find_some_match(argvars, rettv, 0); 11732 } 11733 11734 /* 11735 * "matchlist()" function 11736 */ 11737 static void 11738 f_matchlist(argvars, rettv) 11739 typval_T *argvars; 11740 typval_T *rettv; 11741 { 11742 find_some_match(argvars, rettv, 3); 11743 } 11744 11745 /* 11746 * "matchstr()" function 11747 */ 11748 static void 11749 f_matchstr(argvars, rettv) 11750 typval_T *argvars; 11751 typval_T *rettv; 11752 { 11753 find_some_match(argvars, rettv, 2); 11754 } 11755 11756 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11757 11758 static void 11759 max_min(argvars, rettv, domax) 11760 typval_T *argvars; 11761 typval_T *rettv; 11762 int domax; 11763 { 11764 long n = 0; 11765 long i; 11766 int error = FALSE; 11767 11768 if (argvars[0].v_type == VAR_LIST) 11769 { 11770 list_T *l; 11771 listitem_T *li; 11772 11773 l = argvars[0].vval.v_list; 11774 if (l != NULL) 11775 { 11776 li = l->lv_first; 11777 if (li != NULL) 11778 { 11779 n = get_tv_number_chk(&li->li_tv, &error); 11780 for (;;) 11781 { 11782 li = li->li_next; 11783 if (li == NULL) 11784 break; 11785 i = get_tv_number_chk(&li->li_tv, &error); 11786 if (domax ? i > n : i < n) 11787 n = i; 11788 } 11789 } 11790 } 11791 } 11792 else if (argvars[0].v_type == VAR_DICT) 11793 { 11794 dict_T *d; 11795 int first = TRUE; 11796 hashitem_T *hi; 11797 int todo; 11798 11799 d = argvars[0].vval.v_dict; 11800 if (d != NULL) 11801 { 11802 todo = d->dv_hashtab.ht_used; 11803 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11804 { 11805 if (!HASHITEM_EMPTY(hi)) 11806 { 11807 --todo; 11808 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11809 if (first) 11810 { 11811 n = i; 11812 first = FALSE; 11813 } 11814 else if (domax ? i > n : i < n) 11815 n = i; 11816 } 11817 } 11818 } 11819 } 11820 else 11821 EMSG(_(e_listdictarg)); 11822 rettv->vval.v_number = error ? 0 : n; 11823 } 11824 11825 /* 11826 * "max()" function 11827 */ 11828 static void 11829 f_max(argvars, rettv) 11830 typval_T *argvars; 11831 typval_T *rettv; 11832 { 11833 max_min(argvars, rettv, TRUE); 11834 } 11835 11836 /* 11837 * "min()" function 11838 */ 11839 static void 11840 f_min(argvars, rettv) 11841 typval_T *argvars; 11842 typval_T *rettv; 11843 { 11844 max_min(argvars, rettv, FALSE); 11845 } 11846 11847 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11848 11849 /* 11850 * Create the directory in which "dir" is located, and higher levels when 11851 * needed. 11852 */ 11853 static int 11854 mkdir_recurse(dir, prot) 11855 char_u *dir; 11856 int prot; 11857 { 11858 char_u *p; 11859 char_u *updir; 11860 int r = FAIL; 11861 11862 /* Get end of directory name in "dir". 11863 * We're done when it's "/" or "c:/". */ 11864 p = gettail_sep(dir); 11865 if (p <= get_past_head(dir)) 11866 return OK; 11867 11868 /* If the directory exists we're done. Otherwise: create it.*/ 11869 updir = vim_strnsave(dir, (int)(p - dir)); 11870 if (updir == NULL) 11871 return FAIL; 11872 if (mch_isdir(updir)) 11873 r = OK; 11874 else if (mkdir_recurse(updir, prot) == OK) 11875 r = vim_mkdir_emsg(updir, prot); 11876 vim_free(updir); 11877 return r; 11878 } 11879 11880 #ifdef vim_mkdir 11881 /* 11882 * "mkdir()" function 11883 */ 11884 static void 11885 f_mkdir(argvars, rettv) 11886 typval_T *argvars; 11887 typval_T *rettv; 11888 { 11889 char_u *dir; 11890 char_u buf[NUMBUFLEN]; 11891 int prot = 0755; 11892 11893 rettv->vval.v_number = FAIL; 11894 if (check_restricted() || check_secure()) 11895 return; 11896 11897 dir = get_tv_string_buf(&argvars[0], buf); 11898 if (argvars[1].v_type != VAR_UNKNOWN) 11899 { 11900 if (argvars[2].v_type != VAR_UNKNOWN) 11901 prot = get_tv_number_chk(&argvars[2], NULL); 11902 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11903 mkdir_recurse(dir, prot); 11904 } 11905 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11906 } 11907 #endif 11908 11909 /* 11910 * "mode()" function 11911 */ 11912 /*ARGSUSED*/ 11913 static void 11914 f_mode(argvars, rettv) 11915 typval_T *argvars; 11916 typval_T *rettv; 11917 { 11918 char_u buf[2]; 11919 11920 #ifdef FEAT_VISUAL 11921 if (VIsual_active) 11922 { 11923 if (VIsual_select) 11924 buf[0] = VIsual_mode + 's' - 'v'; 11925 else 11926 buf[0] = VIsual_mode; 11927 } 11928 else 11929 #endif 11930 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11931 buf[0] = 'r'; 11932 else if (State & INSERT) 11933 { 11934 if (State & REPLACE_FLAG) 11935 buf[0] = 'R'; 11936 else 11937 buf[0] = 'i'; 11938 } 11939 else if (State & CMDLINE) 11940 buf[0] = 'c'; 11941 else 11942 buf[0] = 'n'; 11943 11944 buf[1] = NUL; 11945 rettv->vval.v_string = vim_strsave(buf); 11946 rettv->v_type = VAR_STRING; 11947 } 11948 11949 /* 11950 * "nextnonblank()" function 11951 */ 11952 static void 11953 f_nextnonblank(argvars, rettv) 11954 typval_T *argvars; 11955 typval_T *rettv; 11956 { 11957 linenr_T lnum; 11958 11959 for (lnum = get_tv_lnum(argvars); ; ++lnum) 11960 { 11961 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 11962 { 11963 lnum = 0; 11964 break; 11965 } 11966 if (*skipwhite(ml_get(lnum)) != NUL) 11967 break; 11968 } 11969 rettv->vval.v_number = lnum; 11970 } 11971 11972 /* 11973 * "nr2char()" function 11974 */ 11975 static void 11976 f_nr2char(argvars, rettv) 11977 typval_T *argvars; 11978 typval_T *rettv; 11979 { 11980 char_u buf[NUMBUFLEN]; 11981 11982 #ifdef FEAT_MBYTE 11983 if (has_mbyte) 11984 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 11985 else 11986 #endif 11987 { 11988 buf[0] = (char_u)get_tv_number(&argvars[0]); 11989 buf[1] = NUL; 11990 } 11991 rettv->v_type = VAR_STRING; 11992 rettv->vval.v_string = vim_strsave(buf); 11993 } 11994 11995 /* 11996 * "prevnonblank()" function 11997 */ 11998 static void 11999 f_prevnonblank(argvars, rettv) 12000 typval_T *argvars; 12001 typval_T *rettv; 12002 { 12003 linenr_T lnum; 12004 12005 lnum = get_tv_lnum(argvars); 12006 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12007 lnum = 0; 12008 else 12009 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12010 --lnum; 12011 rettv->vval.v_number = lnum; 12012 } 12013 12014 #ifdef HAVE_STDARG_H 12015 /* This dummy va_list is here because: 12016 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12017 * - locally in the function results in a "used before set" warning 12018 * - using va_start() to initialize it gives "function with fixed args" error */ 12019 static va_list ap; 12020 #endif 12021 12022 /* 12023 * "printf()" function 12024 */ 12025 static void 12026 f_printf(argvars, rettv) 12027 typval_T *argvars; 12028 typval_T *rettv; 12029 { 12030 rettv->v_type = VAR_STRING; 12031 rettv->vval.v_string = NULL; 12032 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12033 { 12034 char_u buf[NUMBUFLEN]; 12035 int len; 12036 char_u *s; 12037 int saved_did_emsg = did_emsg; 12038 char *fmt; 12039 12040 /* Get the required length, allocate the buffer and do it for real. */ 12041 did_emsg = FALSE; 12042 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12043 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12044 if (!did_emsg) 12045 { 12046 s = alloc(len + 1); 12047 if (s != NULL) 12048 { 12049 rettv->vval.v_string = s; 12050 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12051 } 12052 } 12053 did_emsg |= saved_did_emsg; 12054 } 12055 #endif 12056 } 12057 12058 /* 12059 * "range()" function 12060 */ 12061 static void 12062 f_range(argvars, rettv) 12063 typval_T *argvars; 12064 typval_T *rettv; 12065 { 12066 long start; 12067 long end; 12068 long stride = 1; 12069 long i; 12070 list_T *l; 12071 listitem_T *li; 12072 int error = FALSE; 12073 12074 start = get_tv_number_chk(&argvars[0], &error); 12075 if (argvars[1].v_type == VAR_UNKNOWN) 12076 { 12077 end = start - 1; 12078 start = 0; 12079 } 12080 else 12081 { 12082 end = get_tv_number_chk(&argvars[1], &error); 12083 if (argvars[2].v_type != VAR_UNKNOWN) 12084 stride = get_tv_number_chk(&argvars[2], &error); 12085 } 12086 12087 rettv->vval.v_number = 0; 12088 if (error) 12089 return; /* type error; errmsg already given */ 12090 if (stride == 0) 12091 EMSG(_("E726: Stride is zero")); 12092 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12093 EMSG(_("E727: Start past end")); 12094 else 12095 { 12096 l = list_alloc(); 12097 if (l != NULL) 12098 { 12099 rettv->v_type = VAR_LIST; 12100 rettv->vval.v_list = l; 12101 ++l->lv_refcount; 12102 12103 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12104 { 12105 li = listitem_alloc(); 12106 if (li == NULL) 12107 break; 12108 li->li_tv.v_type = VAR_NUMBER; 12109 li->li_tv.v_lock = 0; 12110 li->li_tv.vval.v_number = i; 12111 list_append(l, li); 12112 } 12113 } 12114 } 12115 } 12116 12117 /* 12118 * "readfile()" function 12119 */ 12120 static void 12121 f_readfile(argvars, rettv) 12122 typval_T *argvars; 12123 typval_T *rettv; 12124 { 12125 int binary = FALSE; 12126 char_u *fname; 12127 FILE *fd; 12128 list_T *l; 12129 listitem_T *li; 12130 #define FREAD_SIZE 200 /* optimized for text lines */ 12131 char_u buf[FREAD_SIZE]; 12132 int readlen; /* size of last fread() */ 12133 int buflen; /* nr of valid chars in buf[] */ 12134 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12135 int tolist; /* first byte in buf[] still to be put in list */ 12136 int chop; /* how many CR to chop off */ 12137 char_u *prev = NULL; /* previously read bytes, if any */ 12138 int prevlen = 0; /* length of "prev" if not NULL */ 12139 char_u *s; 12140 int len; 12141 long maxline = MAXLNUM; 12142 long cnt = 0; 12143 12144 if (argvars[1].v_type != VAR_UNKNOWN) 12145 { 12146 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12147 binary = TRUE; 12148 if (argvars[2].v_type != VAR_UNKNOWN) 12149 maxline = get_tv_number(&argvars[2]); 12150 } 12151 12152 l = list_alloc(); 12153 if (l == NULL) 12154 return; 12155 rettv->v_type = VAR_LIST; 12156 rettv->vval.v_list = l; 12157 l->lv_refcount = 1; 12158 12159 /* Always open the file in binary mode, library functions have a mind of 12160 * their own about CR-LF conversion. */ 12161 fname = get_tv_string(&argvars[0]); 12162 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12163 { 12164 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12165 return; 12166 } 12167 12168 filtd = 0; 12169 while (cnt < maxline || maxline < 0) 12170 { 12171 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12172 buflen = filtd + readlen; 12173 tolist = 0; 12174 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12175 { 12176 if (buf[filtd] == '\n' || readlen <= 0) 12177 { 12178 /* Only when in binary mode add an empty list item when the 12179 * last line ends in a '\n'. */ 12180 if (!binary && readlen == 0 && filtd == 0) 12181 break; 12182 12183 /* Found end-of-line or end-of-file: add a text line to the 12184 * list. */ 12185 chop = 0; 12186 if (!binary) 12187 while (filtd - chop - 1 >= tolist 12188 && buf[filtd - chop - 1] == '\r') 12189 ++chop; 12190 len = filtd - tolist - chop; 12191 if (prev == NULL) 12192 s = vim_strnsave(buf + tolist, len); 12193 else 12194 { 12195 s = alloc((unsigned)(prevlen + len + 1)); 12196 if (s != NULL) 12197 { 12198 mch_memmove(s, prev, prevlen); 12199 vim_free(prev); 12200 prev = NULL; 12201 mch_memmove(s + prevlen, buf + tolist, len); 12202 s[prevlen + len] = NUL; 12203 } 12204 } 12205 tolist = filtd + 1; 12206 12207 li = listitem_alloc(); 12208 if (li == NULL) 12209 { 12210 vim_free(s); 12211 break; 12212 } 12213 li->li_tv.v_type = VAR_STRING; 12214 li->li_tv.v_lock = 0; 12215 li->li_tv.vval.v_string = s; 12216 list_append(l, li); 12217 12218 if (++cnt >= maxline && maxline >= 0) 12219 break; 12220 if (readlen <= 0) 12221 break; 12222 } 12223 else if (buf[filtd] == NUL) 12224 buf[filtd] = '\n'; 12225 } 12226 if (readlen <= 0) 12227 break; 12228 12229 if (tolist == 0) 12230 { 12231 /* "buf" is full, need to move text to an allocated buffer */ 12232 if (prev == NULL) 12233 { 12234 prev = vim_strnsave(buf, buflen); 12235 prevlen = buflen; 12236 } 12237 else 12238 { 12239 s = alloc((unsigned)(prevlen + buflen)); 12240 if (s != NULL) 12241 { 12242 mch_memmove(s, prev, prevlen); 12243 mch_memmove(s + prevlen, buf, buflen); 12244 vim_free(prev); 12245 prev = s; 12246 prevlen += buflen; 12247 } 12248 } 12249 filtd = 0; 12250 } 12251 else 12252 { 12253 mch_memmove(buf, buf + tolist, buflen - tolist); 12254 filtd -= tolist; 12255 } 12256 } 12257 12258 /* 12259 * For a negative line count use only the lines at the end of the file, 12260 * free the rest. 12261 */ 12262 if (maxline < 0) 12263 while (cnt > -maxline) 12264 { 12265 listitem_remove(l, l->lv_first); 12266 --cnt; 12267 } 12268 12269 vim_free(prev); 12270 fclose(fd); 12271 } 12272 12273 12274 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12275 static void make_connection __ARGS((void)); 12276 static int check_connection __ARGS((void)); 12277 12278 static void 12279 make_connection() 12280 { 12281 if (X_DISPLAY == NULL 12282 # ifdef FEAT_GUI 12283 && !gui.in_use 12284 # endif 12285 ) 12286 { 12287 x_force_connect = TRUE; 12288 setup_term_clip(); 12289 x_force_connect = FALSE; 12290 } 12291 } 12292 12293 static int 12294 check_connection() 12295 { 12296 make_connection(); 12297 if (X_DISPLAY == NULL) 12298 { 12299 EMSG(_("E240: No connection to Vim server")); 12300 return FAIL; 12301 } 12302 return OK; 12303 } 12304 #endif 12305 12306 #ifdef FEAT_CLIENTSERVER 12307 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12308 12309 static void 12310 remote_common(argvars, rettv, expr) 12311 typval_T *argvars; 12312 typval_T *rettv; 12313 int expr; 12314 { 12315 char_u *server_name; 12316 char_u *keys; 12317 char_u *r = NULL; 12318 char_u buf[NUMBUFLEN]; 12319 # ifdef WIN32 12320 HWND w; 12321 # else 12322 Window w; 12323 # endif 12324 12325 if (check_restricted() || check_secure()) 12326 return; 12327 12328 # ifdef FEAT_X11 12329 if (check_connection() == FAIL) 12330 return; 12331 # endif 12332 12333 server_name = get_tv_string_chk(&argvars[0]); 12334 if (server_name == NULL) 12335 return; /* type error; errmsg already given */ 12336 keys = get_tv_string_buf(&argvars[1], buf); 12337 # ifdef WIN32 12338 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12339 # else 12340 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12341 < 0) 12342 # endif 12343 { 12344 if (r != NULL) 12345 EMSG(r); /* sending worked but evaluation failed */ 12346 else 12347 EMSG2(_("E241: Unable to send to %s"), server_name); 12348 return; 12349 } 12350 12351 rettv->vval.v_string = r; 12352 12353 if (argvars[2].v_type != VAR_UNKNOWN) 12354 { 12355 dictitem_T v; 12356 char_u str[30]; 12357 char_u *idvar; 12358 12359 sprintf((char *)str, "0x%x", (unsigned int)w); 12360 v.di_tv.v_type = VAR_STRING; 12361 v.di_tv.vval.v_string = vim_strsave(str); 12362 idvar = get_tv_string_chk(&argvars[2]); 12363 if (idvar != NULL) 12364 set_var(idvar, &v.di_tv, FALSE); 12365 vim_free(v.di_tv.vval.v_string); 12366 } 12367 } 12368 #endif 12369 12370 /* 12371 * "remote_expr()" function 12372 */ 12373 /*ARGSUSED*/ 12374 static void 12375 f_remote_expr(argvars, rettv) 12376 typval_T *argvars; 12377 typval_T *rettv; 12378 { 12379 rettv->v_type = VAR_STRING; 12380 rettv->vval.v_string = NULL; 12381 #ifdef FEAT_CLIENTSERVER 12382 remote_common(argvars, rettv, TRUE); 12383 #endif 12384 } 12385 12386 /* 12387 * "remote_foreground()" function 12388 */ 12389 /*ARGSUSED*/ 12390 static void 12391 f_remote_foreground(argvars, rettv) 12392 typval_T *argvars; 12393 typval_T *rettv; 12394 { 12395 rettv->vval.v_number = 0; 12396 #ifdef FEAT_CLIENTSERVER 12397 # ifdef WIN32 12398 /* On Win32 it's done in this application. */ 12399 { 12400 char_u *server_name = get_tv_string_chk(&argvars[0]); 12401 12402 if (server_name != NULL) 12403 serverForeground(server_name); 12404 } 12405 # else 12406 /* Send a foreground() expression to the server. */ 12407 argvars[1].v_type = VAR_STRING; 12408 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12409 argvars[2].v_type = VAR_UNKNOWN; 12410 remote_common(argvars, rettv, TRUE); 12411 vim_free(argvars[1].vval.v_string); 12412 # endif 12413 #endif 12414 } 12415 12416 /*ARGSUSED*/ 12417 static void 12418 f_remote_peek(argvars, rettv) 12419 typval_T *argvars; 12420 typval_T *rettv; 12421 { 12422 #ifdef FEAT_CLIENTSERVER 12423 dictitem_T v; 12424 char_u *s = NULL; 12425 # ifdef WIN32 12426 int n = 0; 12427 # endif 12428 char_u *serverid; 12429 12430 if (check_restricted() || check_secure()) 12431 { 12432 rettv->vval.v_number = -1; 12433 return; 12434 } 12435 serverid = get_tv_string_chk(&argvars[0]); 12436 if (serverid == NULL) 12437 { 12438 rettv->vval.v_number = -1; 12439 return; /* type error; errmsg already given */ 12440 } 12441 # ifdef WIN32 12442 sscanf(serverid, "%x", &n); 12443 if (n == 0) 12444 rettv->vval.v_number = -1; 12445 else 12446 { 12447 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12448 rettv->vval.v_number = (s != NULL); 12449 } 12450 # else 12451 rettv->vval.v_number = 0; 12452 if (check_connection() == FAIL) 12453 return; 12454 12455 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12456 serverStrToWin(serverid), &s); 12457 # endif 12458 12459 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12460 { 12461 char_u *retvar; 12462 12463 v.di_tv.v_type = VAR_STRING; 12464 v.di_tv.vval.v_string = vim_strsave(s); 12465 retvar = get_tv_string_chk(&argvars[1]); 12466 if (retvar != NULL) 12467 set_var(retvar, &v.di_tv, FALSE); 12468 vim_free(v.di_tv.vval.v_string); 12469 } 12470 #else 12471 rettv->vval.v_number = -1; 12472 #endif 12473 } 12474 12475 /*ARGSUSED*/ 12476 static void 12477 f_remote_read(argvars, rettv) 12478 typval_T *argvars; 12479 typval_T *rettv; 12480 { 12481 char_u *r = NULL; 12482 12483 #ifdef FEAT_CLIENTSERVER 12484 char_u *serverid = get_tv_string_chk(&argvars[0]); 12485 12486 if (serverid != NULL && !check_restricted() && !check_secure()) 12487 { 12488 # ifdef WIN32 12489 /* The server's HWND is encoded in the 'id' parameter */ 12490 int n = 0; 12491 12492 sscanf(serverid, "%x", &n); 12493 if (n != 0) 12494 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12495 if (r == NULL) 12496 # else 12497 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12498 serverStrToWin(serverid), &r, FALSE) < 0) 12499 # endif 12500 EMSG(_("E277: Unable to read a server reply")); 12501 } 12502 #endif 12503 rettv->v_type = VAR_STRING; 12504 rettv->vval.v_string = r; 12505 } 12506 12507 /* 12508 * "remote_send()" function 12509 */ 12510 /*ARGSUSED*/ 12511 static void 12512 f_remote_send(argvars, rettv) 12513 typval_T *argvars; 12514 typval_T *rettv; 12515 { 12516 rettv->v_type = VAR_STRING; 12517 rettv->vval.v_string = NULL; 12518 #ifdef FEAT_CLIENTSERVER 12519 remote_common(argvars, rettv, FALSE); 12520 #endif 12521 } 12522 12523 /* 12524 * "remove()" function 12525 */ 12526 static void 12527 f_remove(argvars, rettv) 12528 typval_T *argvars; 12529 typval_T *rettv; 12530 { 12531 list_T *l; 12532 listitem_T *item, *item2; 12533 listitem_T *li; 12534 long idx; 12535 long end; 12536 char_u *key; 12537 dict_T *d; 12538 dictitem_T *di; 12539 12540 rettv->vval.v_number = 0; 12541 if (argvars[0].v_type == VAR_DICT) 12542 { 12543 if (argvars[2].v_type != VAR_UNKNOWN) 12544 EMSG2(_(e_toomanyarg), "remove()"); 12545 else if ((d = argvars[0].vval.v_dict) != NULL 12546 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12547 { 12548 key = get_tv_string_chk(&argvars[1]); 12549 if (key != NULL) 12550 { 12551 di = dict_find(d, key, -1); 12552 if (di == NULL) 12553 EMSG2(_(e_dictkey), key); 12554 else 12555 { 12556 *rettv = di->di_tv; 12557 init_tv(&di->di_tv); 12558 dictitem_remove(d, di); 12559 } 12560 } 12561 } 12562 } 12563 else if (argvars[0].v_type != VAR_LIST) 12564 EMSG2(_(e_listdictarg), "remove()"); 12565 else if ((l = argvars[0].vval.v_list) != NULL 12566 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12567 { 12568 int error = FALSE; 12569 12570 idx = get_tv_number_chk(&argvars[1], &error); 12571 if (error) 12572 ; /* type error: do nothing, errmsg already given */ 12573 else if ((item = list_find(l, idx)) == NULL) 12574 EMSGN(_(e_listidx), idx); 12575 else 12576 { 12577 if (argvars[2].v_type == VAR_UNKNOWN) 12578 { 12579 /* Remove one item, return its value. */ 12580 list_remove(l, item, item); 12581 *rettv = item->li_tv; 12582 vim_free(item); 12583 } 12584 else 12585 { 12586 /* Remove range of items, return list with values. */ 12587 end = get_tv_number_chk(&argvars[2], &error); 12588 if (error) 12589 ; /* type error: do nothing */ 12590 else if ((item2 = list_find(l, end)) == NULL) 12591 EMSGN(_(e_listidx), end); 12592 else 12593 { 12594 int cnt = 0; 12595 12596 for (li = item; li != NULL; li = li->li_next) 12597 { 12598 ++cnt; 12599 if (li == item2) 12600 break; 12601 } 12602 if (li == NULL) /* didn't find "item2" after "item" */ 12603 EMSG(_(e_invrange)); 12604 else 12605 { 12606 list_remove(l, item, item2); 12607 l = list_alloc(); 12608 if (l != NULL) 12609 { 12610 rettv->v_type = VAR_LIST; 12611 rettv->vval.v_list = l; 12612 l->lv_first = item; 12613 l->lv_last = item2; 12614 l->lv_refcount = 1; 12615 item->li_prev = NULL; 12616 item2->li_next = NULL; 12617 l->lv_len = cnt; 12618 } 12619 } 12620 } 12621 } 12622 } 12623 } 12624 } 12625 12626 /* 12627 * "rename({from}, {to})" function 12628 */ 12629 static void 12630 f_rename(argvars, rettv) 12631 typval_T *argvars; 12632 typval_T *rettv; 12633 { 12634 char_u buf[NUMBUFLEN]; 12635 12636 if (check_restricted() || check_secure()) 12637 rettv->vval.v_number = -1; 12638 else 12639 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12640 get_tv_string_buf(&argvars[1], buf)); 12641 } 12642 12643 /* 12644 * "repeat()" function 12645 */ 12646 /*ARGSUSED*/ 12647 static void 12648 f_repeat(argvars, rettv) 12649 typval_T *argvars; 12650 typval_T *rettv; 12651 { 12652 char_u *p; 12653 int n; 12654 int slen; 12655 int len; 12656 char_u *r; 12657 int i; 12658 list_T *l; 12659 12660 n = get_tv_number(&argvars[1]); 12661 if (argvars[0].v_type == VAR_LIST) 12662 { 12663 l = list_alloc(); 12664 if (l != NULL && argvars[0].vval.v_list != NULL) 12665 { 12666 l->lv_refcount = 1; 12667 while (n-- > 0) 12668 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12669 break; 12670 } 12671 rettv->v_type = VAR_LIST; 12672 rettv->vval.v_list = l; 12673 } 12674 else 12675 { 12676 p = get_tv_string(&argvars[0]); 12677 rettv->v_type = VAR_STRING; 12678 rettv->vval.v_string = NULL; 12679 12680 slen = (int)STRLEN(p); 12681 len = slen * n; 12682 if (len <= 0) 12683 return; 12684 12685 r = alloc(len + 1); 12686 if (r != NULL) 12687 { 12688 for (i = 0; i < n; i++) 12689 mch_memmove(r + i * slen, p, (size_t)slen); 12690 r[len] = NUL; 12691 } 12692 12693 rettv->vval.v_string = r; 12694 } 12695 } 12696 12697 /* 12698 * "resolve()" function 12699 */ 12700 static void 12701 f_resolve(argvars, rettv) 12702 typval_T *argvars; 12703 typval_T *rettv; 12704 { 12705 char_u *p; 12706 12707 p = get_tv_string(&argvars[0]); 12708 #ifdef FEAT_SHORTCUT 12709 { 12710 char_u *v = NULL; 12711 12712 v = mch_resolve_shortcut(p); 12713 if (v != NULL) 12714 rettv->vval.v_string = v; 12715 else 12716 rettv->vval.v_string = vim_strsave(p); 12717 } 12718 #else 12719 # ifdef HAVE_READLINK 12720 { 12721 char_u buf[MAXPATHL + 1]; 12722 char_u *cpy; 12723 int len; 12724 char_u *remain = NULL; 12725 char_u *q; 12726 int is_relative_to_current = FALSE; 12727 int has_trailing_pathsep = FALSE; 12728 int limit = 100; 12729 12730 p = vim_strsave(p); 12731 12732 if (p[0] == '.' && (vim_ispathsep(p[1]) 12733 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12734 is_relative_to_current = TRUE; 12735 12736 len = STRLEN(p); 12737 if (len > 0 && after_pathsep(p, p + len)) 12738 has_trailing_pathsep = TRUE; 12739 12740 q = getnextcomp(p); 12741 if (*q != NUL) 12742 { 12743 /* Separate the first path component in "p", and keep the 12744 * remainder (beginning with the path separator). */ 12745 remain = vim_strsave(q - 1); 12746 q[-1] = NUL; 12747 } 12748 12749 for (;;) 12750 { 12751 for (;;) 12752 { 12753 len = readlink((char *)p, (char *)buf, MAXPATHL); 12754 if (len <= 0) 12755 break; 12756 buf[len] = NUL; 12757 12758 if (limit-- == 0) 12759 { 12760 vim_free(p); 12761 vim_free(remain); 12762 EMSG(_("E655: Too many symbolic links (cycle?)")); 12763 rettv->vval.v_string = NULL; 12764 goto fail; 12765 } 12766 12767 /* Ensure that the result will have a trailing path separator 12768 * if the argument has one. */ 12769 if (remain == NULL && has_trailing_pathsep) 12770 add_pathsep(buf); 12771 12772 /* Separate the first path component in the link value and 12773 * concatenate the remainders. */ 12774 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12775 if (*q != NUL) 12776 { 12777 if (remain == NULL) 12778 remain = vim_strsave(q - 1); 12779 else 12780 { 12781 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12782 if (cpy != NULL) 12783 { 12784 STRCAT(cpy, remain); 12785 vim_free(remain); 12786 remain = cpy; 12787 } 12788 } 12789 q[-1] = NUL; 12790 } 12791 12792 q = gettail(p); 12793 if (q > p && *q == NUL) 12794 { 12795 /* Ignore trailing path separator. */ 12796 q[-1] = NUL; 12797 q = gettail(p); 12798 } 12799 if (q > p && !mch_isFullName(buf)) 12800 { 12801 /* symlink is relative to directory of argument */ 12802 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12803 if (cpy != NULL) 12804 { 12805 STRCPY(cpy, p); 12806 STRCPY(gettail(cpy), buf); 12807 vim_free(p); 12808 p = cpy; 12809 } 12810 } 12811 else 12812 { 12813 vim_free(p); 12814 p = vim_strsave(buf); 12815 } 12816 } 12817 12818 if (remain == NULL) 12819 break; 12820 12821 /* Append the first path component of "remain" to "p". */ 12822 q = getnextcomp(remain + 1); 12823 len = q - remain - (*q != NUL); 12824 cpy = vim_strnsave(p, STRLEN(p) + len); 12825 if (cpy != NULL) 12826 { 12827 STRNCAT(cpy, remain, len); 12828 vim_free(p); 12829 p = cpy; 12830 } 12831 /* Shorten "remain". */ 12832 if (*q != NUL) 12833 STRCPY(remain, q - 1); 12834 else 12835 { 12836 vim_free(remain); 12837 remain = NULL; 12838 } 12839 } 12840 12841 /* If the result is a relative path name, make it explicitly relative to 12842 * the current directory if and only if the argument had this form. */ 12843 if (!vim_ispathsep(*p)) 12844 { 12845 if (is_relative_to_current 12846 && *p != NUL 12847 && !(p[0] == '.' 12848 && (p[1] == NUL 12849 || vim_ispathsep(p[1]) 12850 || (p[1] == '.' 12851 && (p[2] == NUL 12852 || vim_ispathsep(p[2])))))) 12853 { 12854 /* Prepend "./". */ 12855 cpy = concat_str((char_u *)"./", p); 12856 if (cpy != NULL) 12857 { 12858 vim_free(p); 12859 p = cpy; 12860 } 12861 } 12862 else if (!is_relative_to_current) 12863 { 12864 /* Strip leading "./". */ 12865 q = p; 12866 while (q[0] == '.' && vim_ispathsep(q[1])) 12867 q += 2; 12868 if (q > p) 12869 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12870 } 12871 } 12872 12873 /* Ensure that the result will have no trailing path separator 12874 * if the argument had none. But keep "/" or "//". */ 12875 if (!has_trailing_pathsep) 12876 { 12877 q = p + STRLEN(p); 12878 if (after_pathsep(p, q)) 12879 *gettail_sep(p) = NUL; 12880 } 12881 12882 rettv->vval.v_string = p; 12883 } 12884 # else 12885 rettv->vval.v_string = vim_strsave(p); 12886 # endif 12887 #endif 12888 12889 simplify_filename(rettv->vval.v_string); 12890 12891 #ifdef HAVE_READLINK 12892 fail: 12893 #endif 12894 rettv->v_type = VAR_STRING; 12895 } 12896 12897 /* 12898 * "reverse({list})" function 12899 */ 12900 static void 12901 f_reverse(argvars, rettv) 12902 typval_T *argvars; 12903 typval_T *rettv; 12904 { 12905 list_T *l; 12906 listitem_T *li, *ni; 12907 12908 rettv->vval.v_number = 0; 12909 if (argvars[0].v_type != VAR_LIST) 12910 EMSG2(_(e_listarg), "reverse()"); 12911 else if ((l = argvars[0].vval.v_list) != NULL 12912 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12913 { 12914 li = l->lv_last; 12915 l->lv_first = l->lv_last = NULL; 12916 l->lv_len = 0; 12917 while (li != NULL) 12918 { 12919 ni = li->li_prev; 12920 list_append(l, li); 12921 li = ni; 12922 } 12923 rettv->vval.v_list = l; 12924 rettv->v_type = VAR_LIST; 12925 ++l->lv_refcount; 12926 } 12927 } 12928 12929 #define SP_NOMOVE 1 /* don't move cursor */ 12930 #define SP_REPEAT 2 /* repeat to find outer pair */ 12931 #define SP_RETCOUNT 4 /* return matchcount */ 12932 #define SP_SETPCMARK 8 /* set previous context mark */ 12933 12934 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12935 12936 /* 12937 * Get flags for a search function. 12938 * Possibly sets "p_ws". 12939 * Returns BACKWARD, FORWARD or zero (for an error). 12940 */ 12941 static int 12942 get_search_arg(varp, flagsp) 12943 typval_T *varp; 12944 int *flagsp; 12945 { 12946 int dir = FORWARD; 12947 char_u *flags; 12948 char_u nbuf[NUMBUFLEN]; 12949 int mask; 12950 12951 if (varp->v_type != VAR_UNKNOWN) 12952 { 12953 flags = get_tv_string_buf_chk(varp, nbuf); 12954 if (flags == NULL) 12955 return 0; /* type error; errmsg already given */ 12956 while (*flags != NUL) 12957 { 12958 switch (*flags) 12959 { 12960 case 'b': dir = BACKWARD; break; 12961 case 'w': p_ws = TRUE; break; 12962 case 'W': p_ws = FALSE; break; 12963 default: mask = 0; 12964 if (flagsp != NULL) 12965 switch (*flags) 12966 { 12967 case 'n': mask = SP_NOMOVE; break; 12968 case 'r': mask = SP_REPEAT; break; 12969 case 'm': mask = SP_RETCOUNT; break; 12970 case 's': mask = SP_SETPCMARK; break; 12971 } 12972 if (mask == 0) 12973 { 12974 EMSG2(_(e_invarg2), flags); 12975 dir = 0; 12976 } 12977 else 12978 *flagsp |= mask; 12979 } 12980 if (dir == 0) 12981 break; 12982 ++flags; 12983 } 12984 } 12985 return dir; 12986 } 12987 12988 /* 12989 * "search()" function 12990 */ 12991 static void 12992 f_search(argvars, rettv) 12993 typval_T *argvars; 12994 typval_T *rettv; 12995 { 12996 char_u *pat; 12997 pos_T pos; 12998 pos_T save_cursor; 12999 int save_p_ws = p_ws; 13000 int dir; 13001 int flags = 0; 13002 13003 rettv->vval.v_number = 0; /* default: FAIL */ 13004 13005 pat = get_tv_string(&argvars[0]); 13006 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 13007 if (dir == 0) 13008 goto theend; 13009 /* 13010 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 13011 * Check to make sure only those flags are set. 13012 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13013 * flags cannot be set. Check for that condition also. 13014 */ 13015 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 13016 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13017 { 13018 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13019 goto theend; 13020 } 13021 13022 pos = save_cursor = curwin->w_cursor; 13023 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 13024 SEARCH_KEEP, RE_SEARCH) != FAIL) 13025 { 13026 rettv->vval.v_number = pos.lnum; 13027 if (flags & SP_SETPCMARK) 13028 setpcmark(); 13029 curwin->w_cursor = pos; 13030 /* "/$" will put the cursor after the end of the line, may need to 13031 * correct that here */ 13032 check_cursor(); 13033 } 13034 13035 /* If 'n' flag is used: restore cursor position. */ 13036 if (flags & SP_NOMOVE) 13037 curwin->w_cursor = save_cursor; 13038 theend: 13039 p_ws = save_p_ws; 13040 } 13041 13042 /* 13043 * "searchdecl()" function 13044 */ 13045 static void 13046 f_searchdecl(argvars, rettv) 13047 typval_T *argvars; 13048 typval_T *rettv; 13049 { 13050 int locally = 1; 13051 int error = FALSE; 13052 char_u *name; 13053 13054 rettv->vval.v_number = 1; /* default: FAIL */ 13055 13056 name = get_tv_string_chk(&argvars[0]); 13057 if (argvars[1].v_type != VAR_UNKNOWN) 13058 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13059 if (!error && name != NULL) 13060 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13061 locally, SEARCH_KEEP) == FAIL; 13062 } 13063 13064 /* 13065 * "searchpair()" function 13066 */ 13067 static void 13068 f_searchpair(argvars, rettv) 13069 typval_T *argvars; 13070 typval_T *rettv; 13071 { 13072 char_u *spat, *mpat, *epat; 13073 char_u *skip; 13074 int save_p_ws = p_ws; 13075 int dir; 13076 int flags = 0; 13077 char_u nbuf1[NUMBUFLEN]; 13078 char_u nbuf2[NUMBUFLEN]; 13079 char_u nbuf3[NUMBUFLEN]; 13080 13081 rettv->vval.v_number = 0; /* default: FAIL */ 13082 13083 /* Get the three pattern arguments: start, middle, end. */ 13084 spat = get_tv_string_chk(&argvars[0]); 13085 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13086 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13087 if (spat == NULL || mpat == NULL || epat == NULL) 13088 goto theend; /* type error */ 13089 13090 /* Handle the optional fourth argument: flags */ 13091 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13092 if (dir == 0) 13093 goto theend; 13094 /* 13095 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13096 */ 13097 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13098 { 13099 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13100 goto theend; 13101 } 13102 13103 /* Optional fifth argument: skip expresion */ 13104 if (argvars[3].v_type == VAR_UNKNOWN 13105 || argvars[4].v_type == VAR_UNKNOWN) 13106 skip = (char_u *)""; 13107 else 13108 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13109 if (skip == NULL) 13110 goto theend; /* type error */ 13111 13112 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13113 13114 theend: 13115 p_ws = save_p_ws; 13116 } 13117 13118 /* 13119 * Search for a start/middle/end thing. 13120 * Used by searchpair(), see its documentation for the details. 13121 * Returns 0 or -1 for no match, 13122 */ 13123 long 13124 do_searchpair(spat, mpat, epat, dir, skip, flags) 13125 char_u *spat; /* start pattern */ 13126 char_u *mpat; /* middle pattern */ 13127 char_u *epat; /* end pattern */ 13128 int dir; /* BACKWARD or FORWARD */ 13129 char_u *skip; /* skip expression */ 13130 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13131 { 13132 char_u *save_cpo; 13133 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13134 long retval = 0; 13135 pos_T pos; 13136 pos_T firstpos; 13137 pos_T foundpos; 13138 pos_T save_cursor; 13139 pos_T save_pos; 13140 int n; 13141 int r; 13142 int nest = 1; 13143 int err; 13144 13145 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13146 save_cpo = p_cpo; 13147 p_cpo = (char_u *)""; 13148 13149 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13150 * start/middle/end (pat3, for the top pair). */ 13151 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13152 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13153 if (pat2 == NULL || pat3 == NULL) 13154 goto theend; 13155 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13156 if (*mpat == NUL) 13157 STRCPY(pat3, pat2); 13158 else 13159 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13160 spat, epat, mpat); 13161 13162 save_cursor = curwin->w_cursor; 13163 pos = curwin->w_cursor; 13164 firstpos.lnum = 0; 13165 foundpos.lnum = 0; 13166 pat = pat3; 13167 for (;;) 13168 { 13169 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13170 SEARCH_KEEP, RE_SEARCH); 13171 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13172 /* didn't find it or found the first match again: FAIL */ 13173 break; 13174 13175 if (firstpos.lnum == 0) 13176 firstpos = pos; 13177 if (equalpos(pos, foundpos)) 13178 { 13179 /* Found the same position again. Can happen with a pattern that 13180 * has "\zs" at the end and searching backwards. Advance one 13181 * character and try again. */ 13182 if (dir == BACKWARD) 13183 decl(&pos); 13184 else 13185 incl(&pos); 13186 } 13187 foundpos = pos; 13188 13189 /* If the skip pattern matches, ignore this match. */ 13190 if (*skip != NUL) 13191 { 13192 save_pos = curwin->w_cursor; 13193 curwin->w_cursor = pos; 13194 r = eval_to_bool(skip, &err, NULL, FALSE); 13195 curwin->w_cursor = save_pos; 13196 if (err) 13197 { 13198 /* Evaluating {skip} caused an error, break here. */ 13199 curwin->w_cursor = save_cursor; 13200 retval = -1; 13201 break; 13202 } 13203 if (r) 13204 continue; 13205 } 13206 13207 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13208 { 13209 /* Found end when searching backwards or start when searching 13210 * forward: nested pair. */ 13211 ++nest; 13212 pat = pat2; /* nested, don't search for middle */ 13213 } 13214 else 13215 { 13216 /* Found end when searching forward or start when searching 13217 * backward: end of (nested) pair; or found middle in outer pair. */ 13218 if (--nest == 1) 13219 pat = pat3; /* outer level, search for middle */ 13220 } 13221 13222 if (nest == 0) 13223 { 13224 /* Found the match: return matchcount or line number. */ 13225 if (flags & SP_RETCOUNT) 13226 ++retval; 13227 else 13228 retval = pos.lnum; 13229 if (flags & SP_SETPCMARK) 13230 setpcmark(); 13231 curwin->w_cursor = pos; 13232 if (!(flags & SP_REPEAT)) 13233 break; 13234 nest = 1; /* search for next unmatched */ 13235 } 13236 } 13237 13238 /* If 'n' flag is used or search failed: restore cursor position. */ 13239 if ((flags & SP_NOMOVE) || retval == 0) 13240 curwin->w_cursor = save_cursor; 13241 13242 theend: 13243 vim_free(pat2); 13244 vim_free(pat3); 13245 p_cpo = save_cpo; 13246 13247 return retval; 13248 } 13249 13250 /*ARGSUSED*/ 13251 static void 13252 f_server2client(argvars, rettv) 13253 typval_T *argvars; 13254 typval_T *rettv; 13255 { 13256 #ifdef FEAT_CLIENTSERVER 13257 char_u buf[NUMBUFLEN]; 13258 char_u *server = get_tv_string_chk(&argvars[0]); 13259 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13260 13261 rettv->vval.v_number = -1; 13262 if (server == NULL || reply == NULL) 13263 return; 13264 if (check_restricted() || check_secure()) 13265 return; 13266 # ifdef FEAT_X11 13267 if (check_connection() == FAIL) 13268 return; 13269 # endif 13270 13271 if (serverSendReply(server, reply) < 0) 13272 { 13273 EMSG(_("E258: Unable to send to client")); 13274 return; 13275 } 13276 rettv->vval.v_number = 0; 13277 #else 13278 rettv->vval.v_number = -1; 13279 #endif 13280 } 13281 13282 /*ARGSUSED*/ 13283 static void 13284 f_serverlist(argvars, rettv) 13285 typval_T *argvars; 13286 typval_T *rettv; 13287 { 13288 char_u *r = NULL; 13289 13290 #ifdef FEAT_CLIENTSERVER 13291 # ifdef WIN32 13292 r = serverGetVimNames(); 13293 # else 13294 make_connection(); 13295 if (X_DISPLAY != NULL) 13296 r = serverGetVimNames(X_DISPLAY); 13297 # endif 13298 #endif 13299 rettv->v_type = VAR_STRING; 13300 rettv->vval.v_string = r; 13301 } 13302 13303 /* 13304 * "setbufvar()" function 13305 */ 13306 /*ARGSUSED*/ 13307 static void 13308 f_setbufvar(argvars, rettv) 13309 typval_T *argvars; 13310 typval_T *rettv; 13311 { 13312 buf_T *buf; 13313 #ifdef FEAT_AUTOCMD 13314 aco_save_T aco; 13315 #else 13316 buf_T *save_curbuf; 13317 #endif 13318 char_u *varname, *bufvarname; 13319 typval_T *varp; 13320 char_u nbuf[NUMBUFLEN]; 13321 13322 rettv->vval.v_number = 0; 13323 13324 if (check_restricted() || check_secure()) 13325 return; 13326 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13327 varname = get_tv_string_chk(&argvars[1]); 13328 buf = get_buf_tv(&argvars[0]); 13329 varp = &argvars[2]; 13330 13331 if (buf != NULL && varname != NULL && varp != NULL) 13332 { 13333 /* set curbuf to be our buf, temporarily */ 13334 #ifdef FEAT_AUTOCMD 13335 aucmd_prepbuf(&aco, buf); 13336 #else 13337 save_curbuf = curbuf; 13338 curbuf = buf; 13339 #endif 13340 13341 if (*varname == '&') 13342 { 13343 long numval; 13344 char_u *strval; 13345 int error = FALSE; 13346 13347 ++varname; 13348 numval = get_tv_number_chk(varp, &error); 13349 strval = get_tv_string_buf_chk(varp, nbuf); 13350 if (!error && strval != NULL) 13351 set_option_value(varname, numval, strval, OPT_LOCAL); 13352 } 13353 else 13354 { 13355 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13356 if (bufvarname != NULL) 13357 { 13358 STRCPY(bufvarname, "b:"); 13359 STRCPY(bufvarname + 2, varname); 13360 set_var(bufvarname, varp, TRUE); 13361 vim_free(bufvarname); 13362 } 13363 } 13364 13365 /* reset notion of buffer */ 13366 #ifdef FEAT_AUTOCMD 13367 aucmd_restbuf(&aco); 13368 #else 13369 curbuf = save_curbuf; 13370 #endif 13371 } 13372 } 13373 13374 /* 13375 * "setcmdpos()" function 13376 */ 13377 static void 13378 f_setcmdpos(argvars, rettv) 13379 typval_T *argvars; 13380 typval_T *rettv; 13381 { 13382 int pos = (int)get_tv_number(&argvars[0]) - 1; 13383 13384 if (pos >= 0) 13385 rettv->vval.v_number = set_cmdline_pos(pos); 13386 } 13387 13388 /* 13389 * "setline()" function 13390 */ 13391 static void 13392 f_setline(argvars, rettv) 13393 typval_T *argvars; 13394 typval_T *rettv; 13395 { 13396 linenr_T lnum; 13397 char_u *line = NULL; 13398 list_T *l = NULL; 13399 listitem_T *li = NULL; 13400 long added = 0; 13401 linenr_T lcount = curbuf->b_ml.ml_line_count; 13402 13403 lnum = get_tv_lnum(&argvars[0]); 13404 if (argvars[1].v_type == VAR_LIST) 13405 { 13406 l = argvars[1].vval.v_list; 13407 li = l->lv_first; 13408 } 13409 else 13410 line = get_tv_string_chk(&argvars[1]); 13411 13412 rettv->vval.v_number = 0; /* OK */ 13413 for (;;) 13414 { 13415 if (l != NULL) 13416 { 13417 /* list argument, get next string */ 13418 if (li == NULL) 13419 break; 13420 line = get_tv_string_chk(&li->li_tv); 13421 li = li->li_next; 13422 } 13423 13424 rettv->vval.v_number = 1; /* FAIL */ 13425 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13426 break; 13427 if (lnum <= curbuf->b_ml.ml_line_count) 13428 { 13429 /* existing line, replace it */ 13430 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13431 { 13432 changed_bytes(lnum, 0); 13433 check_cursor_col(); 13434 rettv->vval.v_number = 0; /* OK */ 13435 } 13436 } 13437 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13438 { 13439 /* lnum is one past the last line, append the line */ 13440 ++added; 13441 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13442 rettv->vval.v_number = 0; /* OK */ 13443 } 13444 13445 if (l == NULL) /* only one string argument */ 13446 break; 13447 ++lnum; 13448 } 13449 13450 if (added > 0) 13451 appended_lines_mark(lcount, added); 13452 } 13453 13454 /* 13455 * "setqflist()" function 13456 */ 13457 /*ARGSUSED*/ 13458 static void 13459 f_setqflist(argvars, rettv) 13460 typval_T *argvars; 13461 typval_T *rettv; 13462 { 13463 char_u *act; 13464 int action = ' '; 13465 13466 rettv->vval.v_number = -1; 13467 13468 #ifdef FEAT_QUICKFIX 13469 if (argvars[0].v_type != VAR_LIST) 13470 EMSG(_(e_listreq)); 13471 else 13472 { 13473 list_T *l = argvars[0].vval.v_list; 13474 13475 if (argvars[1].v_type == VAR_STRING) 13476 { 13477 act = get_tv_string_chk(&argvars[1]); 13478 if (act == NULL) 13479 return; /* type error; errmsg already given */ 13480 if (*act == 'a' || *act == 'r') 13481 action = *act; 13482 } 13483 13484 if (l != NULL && set_errorlist(l, action) == OK) 13485 rettv->vval.v_number = 0; 13486 } 13487 #endif 13488 } 13489 13490 /* 13491 * "setreg()" function 13492 */ 13493 static void 13494 f_setreg(argvars, rettv) 13495 typval_T *argvars; 13496 typval_T *rettv; 13497 { 13498 int regname; 13499 char_u *strregname; 13500 char_u *stropt; 13501 char_u *strval; 13502 int append; 13503 char_u yank_type; 13504 long block_len; 13505 13506 block_len = -1; 13507 yank_type = MAUTO; 13508 append = FALSE; 13509 13510 strregname = get_tv_string_chk(argvars); 13511 rettv->vval.v_number = 1; /* FAIL is default */ 13512 13513 if (strregname == NULL) 13514 return; /* type error; errmsg already given */ 13515 regname = *strregname; 13516 if (regname == 0 || regname == '@') 13517 regname = '"'; 13518 else if (regname == '=') 13519 return; 13520 13521 if (argvars[2].v_type != VAR_UNKNOWN) 13522 { 13523 stropt = get_tv_string_chk(&argvars[2]); 13524 if (stropt == NULL) 13525 return; /* type error */ 13526 for (; *stropt != NUL; ++stropt) 13527 switch (*stropt) 13528 { 13529 case 'a': case 'A': /* append */ 13530 append = TRUE; 13531 break; 13532 case 'v': case 'c': /* character-wise selection */ 13533 yank_type = MCHAR; 13534 break; 13535 case 'V': case 'l': /* line-wise selection */ 13536 yank_type = MLINE; 13537 break; 13538 #ifdef FEAT_VISUAL 13539 case 'b': case Ctrl_V: /* block-wise selection */ 13540 yank_type = MBLOCK; 13541 if (VIM_ISDIGIT(stropt[1])) 13542 { 13543 ++stropt; 13544 block_len = getdigits(&stropt) - 1; 13545 --stropt; 13546 } 13547 break; 13548 #endif 13549 } 13550 } 13551 13552 strval = get_tv_string_chk(&argvars[1]); 13553 if (strval != NULL) 13554 write_reg_contents_ex(regname, strval, -1, 13555 append, yank_type, block_len); 13556 rettv->vval.v_number = 0; 13557 } 13558 13559 13560 /* 13561 * "setwinvar(expr)" function 13562 */ 13563 /*ARGSUSED*/ 13564 static void 13565 f_setwinvar(argvars, rettv) 13566 typval_T *argvars; 13567 typval_T *rettv; 13568 { 13569 win_T *win; 13570 #ifdef FEAT_WINDOWS 13571 win_T *save_curwin; 13572 #endif 13573 char_u *varname, *winvarname; 13574 typval_T *varp; 13575 char_u nbuf[NUMBUFLEN]; 13576 13577 rettv->vval.v_number = 0; 13578 13579 if (check_restricted() || check_secure()) 13580 return; 13581 win = find_win_by_nr(&argvars[0]); 13582 varname = get_tv_string_chk(&argvars[1]); 13583 varp = &argvars[2]; 13584 13585 if (win != NULL && varname != NULL && varp != NULL) 13586 { 13587 #ifdef FEAT_WINDOWS 13588 /* set curwin to be our win, temporarily */ 13589 save_curwin = curwin; 13590 curwin = win; 13591 curbuf = curwin->w_buffer; 13592 #endif 13593 13594 if (*varname == '&') 13595 { 13596 long numval; 13597 char_u *strval; 13598 int error = FALSE; 13599 13600 ++varname; 13601 numval = get_tv_number_chk(varp, &error); 13602 strval = get_tv_string_buf_chk(varp, nbuf); 13603 if (!error && strval != NULL) 13604 set_option_value(varname, numval, strval, OPT_LOCAL); 13605 } 13606 else 13607 { 13608 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13609 if (winvarname != NULL) 13610 { 13611 STRCPY(winvarname, "w:"); 13612 STRCPY(winvarname + 2, varname); 13613 set_var(winvarname, varp, TRUE); 13614 vim_free(winvarname); 13615 } 13616 } 13617 13618 #ifdef FEAT_WINDOWS 13619 /* Restore current window, if it's still valid (autocomands can make 13620 * it invalid). */ 13621 if (win_valid(save_curwin)) 13622 { 13623 curwin = save_curwin; 13624 curbuf = curwin->w_buffer; 13625 } 13626 #endif 13627 } 13628 } 13629 13630 /* 13631 * "simplify()" function 13632 */ 13633 static void 13634 f_simplify(argvars, rettv) 13635 typval_T *argvars; 13636 typval_T *rettv; 13637 { 13638 char_u *p; 13639 13640 p = get_tv_string(&argvars[0]); 13641 rettv->vval.v_string = vim_strsave(p); 13642 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13643 rettv->v_type = VAR_STRING; 13644 } 13645 13646 static int 13647 #ifdef __BORLANDC__ 13648 _RTLENTRYF 13649 #endif 13650 item_compare __ARGS((const void *s1, const void *s2)); 13651 static int 13652 #ifdef __BORLANDC__ 13653 _RTLENTRYF 13654 #endif 13655 item_compare2 __ARGS((const void *s1, const void *s2)); 13656 13657 static int item_compare_ic; 13658 static char_u *item_compare_func; 13659 static int item_compare_func_err; 13660 #define ITEM_COMPARE_FAIL 999 13661 13662 /* 13663 * Compare functions for f_sort() below. 13664 */ 13665 static int 13666 #ifdef __BORLANDC__ 13667 _RTLENTRYF 13668 #endif 13669 item_compare(s1, s2) 13670 const void *s1; 13671 const void *s2; 13672 { 13673 char_u *p1, *p2; 13674 char_u *tofree1, *tofree2; 13675 int res; 13676 char_u numbuf1[NUMBUFLEN]; 13677 char_u numbuf2[NUMBUFLEN]; 13678 13679 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13680 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13681 if (item_compare_ic) 13682 res = STRICMP(p1, p2); 13683 else 13684 res = STRCMP(p1, p2); 13685 vim_free(tofree1); 13686 vim_free(tofree2); 13687 return res; 13688 } 13689 13690 static int 13691 #ifdef __BORLANDC__ 13692 _RTLENTRYF 13693 #endif 13694 item_compare2(s1, s2) 13695 const void *s1; 13696 const void *s2; 13697 { 13698 int res; 13699 typval_T rettv; 13700 typval_T argv[2]; 13701 int dummy; 13702 13703 /* shortcut after failure in previous call; compare all items equal */ 13704 if (item_compare_func_err) 13705 return 0; 13706 13707 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13708 * in the copy without changing the original list items. */ 13709 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13710 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13711 13712 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13713 res = call_func(item_compare_func, STRLEN(item_compare_func), 13714 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13715 clear_tv(&argv[0]); 13716 clear_tv(&argv[1]); 13717 13718 if (res == FAIL) 13719 res = ITEM_COMPARE_FAIL; 13720 else 13721 /* return value has wrong type */ 13722 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13723 if (item_compare_func_err) 13724 res = ITEM_COMPARE_FAIL; 13725 clear_tv(&rettv); 13726 return res; 13727 } 13728 13729 /* 13730 * "sort({list})" function 13731 */ 13732 static void 13733 f_sort(argvars, rettv) 13734 typval_T *argvars; 13735 typval_T *rettv; 13736 { 13737 list_T *l; 13738 listitem_T *li; 13739 listitem_T **ptrs; 13740 long len; 13741 long i; 13742 13743 rettv->vval.v_number = 0; 13744 if (argvars[0].v_type != VAR_LIST) 13745 EMSG2(_(e_listarg), "sort()"); 13746 else 13747 { 13748 l = argvars[0].vval.v_list; 13749 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13750 return; 13751 rettv->vval.v_list = l; 13752 rettv->v_type = VAR_LIST; 13753 ++l->lv_refcount; 13754 13755 len = list_len(l); 13756 if (len <= 1) 13757 return; /* short list sorts pretty quickly */ 13758 13759 item_compare_ic = FALSE; 13760 item_compare_func = NULL; 13761 if (argvars[1].v_type != VAR_UNKNOWN) 13762 { 13763 if (argvars[1].v_type == VAR_FUNC) 13764 item_compare_func = argvars[1].vval.v_string; 13765 else 13766 { 13767 int error = FALSE; 13768 13769 i = get_tv_number_chk(&argvars[1], &error); 13770 if (error) 13771 return; /* type error; errmsg already given */ 13772 if (i == 1) 13773 item_compare_ic = TRUE; 13774 else 13775 item_compare_func = get_tv_string(&argvars[1]); 13776 } 13777 } 13778 13779 /* Make an array with each entry pointing to an item in the List. */ 13780 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13781 if (ptrs == NULL) 13782 return; 13783 i = 0; 13784 for (li = l->lv_first; li != NULL; li = li->li_next) 13785 ptrs[i++] = li; 13786 13787 item_compare_func_err = FALSE; 13788 /* test the compare function */ 13789 if (item_compare_func != NULL 13790 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13791 == ITEM_COMPARE_FAIL) 13792 EMSG(_("E702: Sort compare function failed")); 13793 else 13794 { 13795 /* Sort the array with item pointers. */ 13796 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13797 item_compare_func == NULL ? item_compare : item_compare2); 13798 13799 if (!item_compare_func_err) 13800 { 13801 /* Clear the List and append the items in the sorted order. */ 13802 l->lv_first = l->lv_last = NULL; 13803 l->lv_len = 0; 13804 for (i = 0; i < len; ++i) 13805 list_append(l, ptrs[i]); 13806 } 13807 } 13808 13809 vim_free(ptrs); 13810 } 13811 } 13812 13813 /* 13814 * "soundfold({word})" function 13815 */ 13816 static void 13817 f_soundfold(argvars, rettv) 13818 typval_T *argvars; 13819 typval_T *rettv; 13820 { 13821 char_u *s; 13822 13823 rettv->v_type = VAR_STRING; 13824 s = get_tv_string(&argvars[0]); 13825 #ifdef FEAT_SYN_HL 13826 rettv->vval.v_string = eval_soundfold(s); 13827 #else 13828 rettv->vval.v_string = vim_strsave(s); 13829 #endif 13830 } 13831 13832 /* 13833 * "spellbadword()" function 13834 */ 13835 /* ARGSUSED */ 13836 static void 13837 f_spellbadword(argvars, rettv) 13838 typval_T *argvars; 13839 typval_T *rettv; 13840 { 13841 int len; 13842 13843 rettv->vval.v_string = NULL; 13844 rettv->v_type = VAR_STRING; 13845 13846 #ifdef FEAT_SYN_HL 13847 /* Find the start and length of the badly spelled word. */ 13848 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL); 13849 if (len != 0) 13850 rettv->vval.v_string = vim_strnsave(ml_get_cursor(), len); 13851 #endif 13852 } 13853 13854 /* 13855 * "spellsuggest()" function 13856 */ 13857 static void 13858 f_spellsuggest(argvars, rettv) 13859 typval_T *argvars; 13860 typval_T *rettv; 13861 { 13862 char_u *str; 13863 int maxcount; 13864 garray_T ga; 13865 list_T *l; 13866 listitem_T *li; 13867 int i; 13868 13869 l = list_alloc(); 13870 if (l == NULL) 13871 return; 13872 rettv->v_type = VAR_LIST; 13873 rettv->vval.v_list = l; 13874 ++l->lv_refcount; 13875 13876 #ifdef FEAT_SYN_HL 13877 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13878 { 13879 str = get_tv_string(&argvars[0]); 13880 if (argvars[1].v_type != VAR_UNKNOWN) 13881 { 13882 maxcount = get_tv_number(&argvars[1]); 13883 if (maxcount <= 0) 13884 return; 13885 } 13886 else 13887 maxcount = 25; 13888 13889 spell_suggest_list(&ga, str, maxcount, FALSE); 13890 13891 for (i = 0; i < ga.ga_len; ++i) 13892 { 13893 str = ((char_u **)ga.ga_data)[i]; 13894 13895 li = listitem_alloc(); 13896 if (li == NULL) 13897 vim_free(str); 13898 else 13899 { 13900 li->li_tv.v_type = VAR_STRING; 13901 li->li_tv.v_lock = 0; 13902 li->li_tv.vval.v_string = str; 13903 list_append(l, li); 13904 } 13905 } 13906 ga_clear(&ga); 13907 } 13908 #endif 13909 } 13910 13911 static void 13912 f_split(argvars, rettv) 13913 typval_T *argvars; 13914 typval_T *rettv; 13915 { 13916 char_u *str; 13917 char_u *end; 13918 char_u *pat = NULL; 13919 regmatch_T regmatch; 13920 char_u patbuf[NUMBUFLEN]; 13921 char_u *save_cpo; 13922 int match; 13923 listitem_T *ni; 13924 list_T *l; 13925 colnr_T col = 0; 13926 int keepempty = FALSE; 13927 int typeerr = FALSE; 13928 13929 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13930 save_cpo = p_cpo; 13931 p_cpo = (char_u *)""; 13932 13933 str = get_tv_string(&argvars[0]); 13934 if (argvars[1].v_type != VAR_UNKNOWN) 13935 { 13936 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13937 if (pat == NULL) 13938 typeerr = TRUE; 13939 if (argvars[2].v_type != VAR_UNKNOWN) 13940 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 13941 } 13942 if (pat == NULL || *pat == NUL) 13943 pat = (char_u *)"[\\x01- ]\\+"; 13944 13945 l = list_alloc(); 13946 if (l == NULL) 13947 return; 13948 rettv->v_type = VAR_LIST; 13949 rettv->vval.v_list = l; 13950 ++l->lv_refcount; 13951 if (typeerr) 13952 return; 13953 13954 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13955 if (regmatch.regprog != NULL) 13956 { 13957 regmatch.rm_ic = FALSE; 13958 while (*str != NUL || keepempty) 13959 { 13960 if (*str == NUL) 13961 match = FALSE; /* empty item at the end */ 13962 else 13963 match = vim_regexec_nl(®match, str, col); 13964 if (match) 13965 end = regmatch.startp[0]; 13966 else 13967 end = str + STRLEN(str); 13968 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 13969 && match && end < regmatch.endp[0])) 13970 { 13971 ni = listitem_alloc(); 13972 if (ni == NULL) 13973 break; 13974 ni->li_tv.v_type = VAR_STRING; 13975 ni->li_tv.v_lock = 0; 13976 ni->li_tv.vval.v_string = vim_strnsave(str, end - str); 13977 list_append(l, ni); 13978 } 13979 if (!match) 13980 break; 13981 /* Advance to just after the match. */ 13982 if (regmatch.endp[0] > str) 13983 col = 0; 13984 else 13985 { 13986 /* Don't get stuck at the same match. */ 13987 #ifdef FEAT_MBYTE 13988 col = (*mb_ptr2len)(regmatch.endp[0]); 13989 #else 13990 col = 1; 13991 #endif 13992 } 13993 str = regmatch.endp[0]; 13994 } 13995 13996 vim_free(regmatch.regprog); 13997 } 13998 13999 p_cpo = save_cpo; 14000 } 14001 14002 #ifdef HAVE_STRFTIME 14003 /* 14004 * "strftime({format}[, {time}])" function 14005 */ 14006 static void 14007 f_strftime(argvars, rettv) 14008 typval_T *argvars; 14009 typval_T *rettv; 14010 { 14011 char_u result_buf[256]; 14012 struct tm *curtime; 14013 time_t seconds; 14014 char_u *p; 14015 14016 rettv->v_type = VAR_STRING; 14017 14018 p = get_tv_string(&argvars[0]); 14019 if (argvars[1].v_type == VAR_UNKNOWN) 14020 seconds = time(NULL); 14021 else 14022 seconds = (time_t)get_tv_number(&argvars[1]); 14023 curtime = localtime(&seconds); 14024 /* MSVC returns NULL for an invalid value of seconds. */ 14025 if (curtime == NULL) 14026 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 14027 else 14028 { 14029 # ifdef FEAT_MBYTE 14030 vimconv_T conv; 14031 char_u *enc; 14032 14033 conv.vc_type = CONV_NONE; 14034 enc = enc_locale(); 14035 convert_setup(&conv, p_enc, enc); 14036 if (conv.vc_type != CONV_NONE) 14037 p = string_convert(&conv, p, NULL); 14038 # endif 14039 if (p != NULL) 14040 (void)strftime((char *)result_buf, sizeof(result_buf), 14041 (char *)p, curtime); 14042 else 14043 result_buf[0] = NUL; 14044 14045 # ifdef FEAT_MBYTE 14046 if (conv.vc_type != CONV_NONE) 14047 vim_free(p); 14048 convert_setup(&conv, enc, p_enc); 14049 if (conv.vc_type != CONV_NONE) 14050 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 14051 else 14052 # endif 14053 rettv->vval.v_string = vim_strsave(result_buf); 14054 14055 # ifdef FEAT_MBYTE 14056 /* Release conversion descriptors */ 14057 convert_setup(&conv, NULL, NULL); 14058 vim_free(enc); 14059 # endif 14060 } 14061 } 14062 #endif 14063 14064 /* 14065 * "stridx()" function 14066 */ 14067 static void 14068 f_stridx(argvars, rettv) 14069 typval_T *argvars; 14070 typval_T *rettv; 14071 { 14072 char_u buf[NUMBUFLEN]; 14073 char_u *needle; 14074 char_u *haystack; 14075 char_u *save_haystack; 14076 char_u *pos; 14077 int start_idx; 14078 14079 needle = get_tv_string_chk(&argvars[1]); 14080 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 14081 rettv->vval.v_number = -1; 14082 if (needle == NULL || haystack == NULL) 14083 return; /* type error; errmsg already given */ 14084 14085 if (argvars[2].v_type != VAR_UNKNOWN) 14086 { 14087 int error = FALSE; 14088 14089 start_idx = get_tv_number_chk(&argvars[2], &error); 14090 if (error || start_idx >= (int)STRLEN(haystack)) 14091 return; 14092 if (start_idx >= 0) 14093 haystack += start_idx; 14094 } 14095 14096 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14097 if (pos != NULL) 14098 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14099 } 14100 14101 /* 14102 * "string()" function 14103 */ 14104 static void 14105 f_string(argvars, rettv) 14106 typval_T *argvars; 14107 typval_T *rettv; 14108 { 14109 char_u *tofree; 14110 char_u numbuf[NUMBUFLEN]; 14111 14112 rettv->v_type = VAR_STRING; 14113 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14114 if (tofree == NULL) 14115 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14116 } 14117 14118 /* 14119 * "strlen()" function 14120 */ 14121 static void 14122 f_strlen(argvars, rettv) 14123 typval_T *argvars; 14124 typval_T *rettv; 14125 { 14126 rettv->vval.v_number = (varnumber_T)(STRLEN( 14127 get_tv_string(&argvars[0]))); 14128 } 14129 14130 /* 14131 * "strpart()" function 14132 */ 14133 static void 14134 f_strpart(argvars, rettv) 14135 typval_T *argvars; 14136 typval_T *rettv; 14137 { 14138 char_u *p; 14139 int n; 14140 int len; 14141 int slen; 14142 int error = FALSE; 14143 14144 p = get_tv_string(&argvars[0]); 14145 slen = (int)STRLEN(p); 14146 14147 n = get_tv_number_chk(&argvars[1], &error); 14148 if (error) 14149 len = 0; 14150 else if (argvars[2].v_type != VAR_UNKNOWN) 14151 len = get_tv_number(&argvars[2]); 14152 else 14153 len = slen - n; /* default len: all bytes that are available. */ 14154 14155 /* 14156 * Only return the overlap between the specified part and the actual 14157 * string. 14158 */ 14159 if (n < 0) 14160 { 14161 len += n; 14162 n = 0; 14163 } 14164 else if (n > slen) 14165 n = slen; 14166 if (len < 0) 14167 len = 0; 14168 else if (n + len > slen) 14169 len = slen - n; 14170 14171 rettv->v_type = VAR_STRING; 14172 rettv->vval.v_string = vim_strnsave(p + n, len); 14173 } 14174 14175 /* 14176 * "strridx()" function 14177 */ 14178 static void 14179 f_strridx(argvars, rettv) 14180 typval_T *argvars; 14181 typval_T *rettv; 14182 { 14183 char_u buf[NUMBUFLEN]; 14184 char_u *needle; 14185 char_u *haystack; 14186 char_u *rest; 14187 char_u *lastmatch = NULL; 14188 int haystack_len, end_idx; 14189 14190 needle = get_tv_string_chk(&argvars[1]); 14191 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14192 haystack_len = STRLEN(haystack); 14193 14194 rettv->vval.v_number = -1; 14195 if (needle == NULL || haystack == NULL) 14196 return; /* type error; errmsg already given */ 14197 if (argvars[2].v_type != VAR_UNKNOWN) 14198 { 14199 /* Third argument: upper limit for index */ 14200 end_idx = get_tv_number_chk(&argvars[2], NULL); 14201 if (end_idx < 0) 14202 return; /* can never find a match */ 14203 } 14204 else 14205 end_idx = haystack_len; 14206 14207 if (*needle == NUL) 14208 { 14209 /* Empty string matches past the end. */ 14210 lastmatch = haystack + end_idx; 14211 } 14212 else 14213 { 14214 for (rest = haystack; *rest != '\0'; ++rest) 14215 { 14216 rest = (char_u *)strstr((char *)rest, (char *)needle); 14217 if (rest == NULL || rest > haystack + end_idx) 14218 break; 14219 lastmatch = rest; 14220 } 14221 } 14222 14223 if (lastmatch == NULL) 14224 rettv->vval.v_number = -1; 14225 else 14226 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14227 } 14228 14229 /* 14230 * "strtrans()" function 14231 */ 14232 static void 14233 f_strtrans(argvars, rettv) 14234 typval_T *argvars; 14235 typval_T *rettv; 14236 { 14237 rettv->v_type = VAR_STRING; 14238 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14239 } 14240 14241 /* 14242 * "submatch()" function 14243 */ 14244 static void 14245 f_submatch(argvars, rettv) 14246 typval_T *argvars; 14247 typval_T *rettv; 14248 { 14249 rettv->v_type = VAR_STRING; 14250 rettv->vval.v_string = 14251 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14252 } 14253 14254 /* 14255 * "substitute()" function 14256 */ 14257 static void 14258 f_substitute(argvars, rettv) 14259 typval_T *argvars; 14260 typval_T *rettv; 14261 { 14262 char_u patbuf[NUMBUFLEN]; 14263 char_u subbuf[NUMBUFLEN]; 14264 char_u flagsbuf[NUMBUFLEN]; 14265 14266 char_u *str = get_tv_string_chk(&argvars[0]); 14267 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14268 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14269 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14270 14271 rettv->v_type = VAR_STRING; 14272 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14273 rettv->vval.v_string = NULL; 14274 else 14275 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14276 } 14277 14278 /* 14279 * "synID(lnum, col, trans)" function 14280 */ 14281 /*ARGSUSED*/ 14282 static void 14283 f_synID(argvars, rettv) 14284 typval_T *argvars; 14285 typval_T *rettv; 14286 { 14287 int id = 0; 14288 #ifdef FEAT_SYN_HL 14289 long lnum; 14290 long col; 14291 int trans; 14292 int transerr = FALSE; 14293 14294 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14295 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14296 trans = get_tv_number_chk(&argvars[2], &transerr); 14297 14298 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14299 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14300 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14301 #endif 14302 14303 rettv->vval.v_number = id; 14304 } 14305 14306 /* 14307 * "synIDattr(id, what [, mode])" function 14308 */ 14309 /*ARGSUSED*/ 14310 static void 14311 f_synIDattr(argvars, rettv) 14312 typval_T *argvars; 14313 typval_T *rettv; 14314 { 14315 char_u *p = NULL; 14316 #ifdef FEAT_SYN_HL 14317 int id; 14318 char_u *what; 14319 char_u *mode; 14320 char_u modebuf[NUMBUFLEN]; 14321 int modec; 14322 14323 id = get_tv_number(&argvars[0]); 14324 what = get_tv_string(&argvars[1]); 14325 if (argvars[2].v_type != VAR_UNKNOWN) 14326 { 14327 mode = get_tv_string_buf(&argvars[2], modebuf); 14328 modec = TOLOWER_ASC(mode[0]); 14329 if (modec != 't' && modec != 'c' 14330 #ifdef FEAT_GUI 14331 && modec != 'g' 14332 #endif 14333 ) 14334 modec = 0; /* replace invalid with current */ 14335 } 14336 else 14337 { 14338 #ifdef FEAT_GUI 14339 if (gui.in_use) 14340 modec = 'g'; 14341 else 14342 #endif 14343 if (t_colors > 1) 14344 modec = 'c'; 14345 else 14346 modec = 't'; 14347 } 14348 14349 14350 switch (TOLOWER_ASC(what[0])) 14351 { 14352 case 'b': 14353 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14354 p = highlight_color(id, what, modec); 14355 else /* bold */ 14356 p = highlight_has_attr(id, HL_BOLD, modec); 14357 break; 14358 14359 case 'f': /* fg[#] */ 14360 p = highlight_color(id, what, modec); 14361 break; 14362 14363 case 'i': 14364 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14365 p = highlight_has_attr(id, HL_INVERSE, modec); 14366 else /* italic */ 14367 p = highlight_has_attr(id, HL_ITALIC, modec); 14368 break; 14369 14370 case 'n': /* name */ 14371 p = get_highlight_name(NULL, id - 1); 14372 break; 14373 14374 case 'r': /* reverse */ 14375 p = highlight_has_attr(id, HL_INVERSE, modec); 14376 break; 14377 14378 case 's': /* standout */ 14379 p = highlight_has_attr(id, HL_STANDOUT, modec); 14380 break; 14381 14382 case 'u': 14383 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14384 /* underline */ 14385 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14386 else 14387 /* undercurl */ 14388 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14389 break; 14390 } 14391 14392 if (p != NULL) 14393 p = vim_strsave(p); 14394 #endif 14395 rettv->v_type = VAR_STRING; 14396 rettv->vval.v_string = p; 14397 } 14398 14399 /* 14400 * "synIDtrans(id)" function 14401 */ 14402 /*ARGSUSED*/ 14403 static void 14404 f_synIDtrans(argvars, rettv) 14405 typval_T *argvars; 14406 typval_T *rettv; 14407 { 14408 int id; 14409 14410 #ifdef FEAT_SYN_HL 14411 id = get_tv_number(&argvars[0]); 14412 14413 if (id > 0) 14414 id = syn_get_final_id(id); 14415 else 14416 #endif 14417 id = 0; 14418 14419 rettv->vval.v_number = id; 14420 } 14421 14422 /* 14423 * "system()" function 14424 */ 14425 static void 14426 f_system(argvars, rettv) 14427 typval_T *argvars; 14428 typval_T *rettv; 14429 { 14430 char_u *res = NULL; 14431 char_u *p; 14432 char_u *infile = NULL; 14433 char_u buf[NUMBUFLEN]; 14434 int err = FALSE; 14435 FILE *fd; 14436 14437 if (argvars[1].v_type != VAR_UNKNOWN) 14438 { 14439 /* 14440 * Write the string to a temp file, to be used for input of the shell 14441 * command. 14442 */ 14443 if ((infile = vim_tempname('i')) == NULL) 14444 { 14445 EMSG(_(e_notmp)); 14446 return; 14447 } 14448 14449 fd = mch_fopen((char *)infile, WRITEBIN); 14450 if (fd == NULL) 14451 { 14452 EMSG2(_(e_notopen), infile); 14453 goto done; 14454 } 14455 p = get_tv_string_buf_chk(&argvars[1], buf); 14456 if (p == NULL) 14457 goto done; /* type error; errmsg already given */ 14458 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14459 err = TRUE; 14460 if (fclose(fd) != 0) 14461 err = TRUE; 14462 if (err) 14463 { 14464 EMSG(_("E677: Error writing temp file")); 14465 goto done; 14466 } 14467 } 14468 14469 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14470 14471 #ifdef USE_CR 14472 /* translate <CR> into <NL> */ 14473 if (res != NULL) 14474 { 14475 char_u *s; 14476 14477 for (s = res; *s; ++s) 14478 { 14479 if (*s == CAR) 14480 *s = NL; 14481 } 14482 } 14483 #else 14484 # ifdef USE_CRNL 14485 /* translate <CR><NL> into <NL> */ 14486 if (res != NULL) 14487 { 14488 char_u *s, *d; 14489 14490 d = res; 14491 for (s = res; *s; ++s) 14492 { 14493 if (s[0] == CAR && s[1] == NL) 14494 ++s; 14495 *d++ = *s; 14496 } 14497 *d = NUL; 14498 } 14499 # endif 14500 #endif 14501 14502 done: 14503 if (infile != NULL) 14504 { 14505 mch_remove(infile); 14506 vim_free(infile); 14507 } 14508 rettv->v_type = VAR_STRING; 14509 rettv->vval.v_string = res; 14510 } 14511 14512 /* 14513 * "tagfiles()" function 14514 */ 14515 /*ARGSUSED*/ 14516 static void 14517 f_tagfiles(argvars, rettv) 14518 typval_T *argvars; 14519 typval_T *rettv; 14520 { 14521 char_u fname[MAXPATHL + 1]; 14522 list_T *l; 14523 14524 l = list_alloc(); 14525 if (l == NULL) 14526 { 14527 rettv->vval.v_number = 0; 14528 return; 14529 } 14530 rettv->vval.v_list = l; 14531 rettv->v_type = VAR_LIST; 14532 ++l->lv_refcount; 14533 14534 get_tagfname(TRUE, NULL); 14535 for (;;) 14536 if (get_tagfname(FALSE, fname) == FAIL 14537 || list_append_string(l, fname) == FAIL) 14538 break; 14539 } 14540 14541 /* 14542 * "taglist()" function 14543 */ 14544 static void 14545 f_taglist(argvars, rettv) 14546 typval_T *argvars; 14547 typval_T *rettv; 14548 { 14549 char_u *tag_pattern; 14550 list_T *l; 14551 14552 tag_pattern = get_tv_string(&argvars[0]); 14553 14554 rettv->vval.v_number = FALSE; 14555 if (*tag_pattern == NUL) 14556 return; 14557 14558 l = list_alloc(); 14559 if (l != NULL) 14560 { 14561 if (get_tags(l, tag_pattern) != FAIL) 14562 { 14563 rettv->vval.v_list = l; 14564 rettv->v_type = VAR_LIST; 14565 ++l->lv_refcount; 14566 } 14567 else 14568 list_free(l); 14569 } 14570 } 14571 14572 /* 14573 * "tempname()" function 14574 */ 14575 /*ARGSUSED*/ 14576 static void 14577 f_tempname(argvars, rettv) 14578 typval_T *argvars; 14579 typval_T *rettv; 14580 { 14581 static int x = 'A'; 14582 14583 rettv->v_type = VAR_STRING; 14584 rettv->vval.v_string = vim_tempname(x); 14585 14586 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14587 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14588 do 14589 { 14590 if (x == 'Z') 14591 x = '0'; 14592 else if (x == '9') 14593 x = 'A'; 14594 else 14595 { 14596 #ifdef EBCDIC 14597 if (x == 'I') 14598 x = 'J'; 14599 else if (x == 'R') 14600 x = 'S'; 14601 else 14602 #endif 14603 ++x; 14604 } 14605 } while (x == 'I' || x == 'O'); 14606 } 14607 14608 /* 14609 * "test(list)" function: Just checking the walls... 14610 */ 14611 /*ARGSUSED*/ 14612 static void 14613 f_test(argvars, rettv) 14614 typval_T *argvars; 14615 typval_T *rettv; 14616 { 14617 /* Used for unit testing. Change the code below to your liking. */ 14618 #if 0 14619 listitem_T *li; 14620 list_T *l; 14621 char_u *bad, *good; 14622 14623 if (argvars[0].v_type != VAR_LIST) 14624 return; 14625 l = argvars[0].vval.v_list; 14626 if (l == NULL) 14627 return; 14628 li = l->lv_first; 14629 if (li == NULL) 14630 return; 14631 bad = get_tv_string(&li->li_tv); 14632 li = li->li_next; 14633 if (li == NULL) 14634 return; 14635 good = get_tv_string(&li->li_tv); 14636 rettv->vval.v_number = test_edit_score(bad, good); 14637 #endif 14638 } 14639 14640 /* 14641 * "tolower(string)" function 14642 */ 14643 static void 14644 f_tolower(argvars, rettv) 14645 typval_T *argvars; 14646 typval_T *rettv; 14647 { 14648 char_u *p; 14649 14650 p = vim_strsave(get_tv_string(&argvars[0])); 14651 rettv->v_type = VAR_STRING; 14652 rettv->vval.v_string = p; 14653 14654 if (p != NULL) 14655 while (*p != NUL) 14656 { 14657 #ifdef FEAT_MBYTE 14658 int l; 14659 14660 if (enc_utf8) 14661 { 14662 int c, lc; 14663 14664 c = utf_ptr2char(p); 14665 lc = utf_tolower(c); 14666 l = utf_ptr2len(p); 14667 /* TODO: reallocate string when byte count changes. */ 14668 if (utf_char2len(lc) == l) 14669 utf_char2bytes(lc, p); 14670 p += l; 14671 } 14672 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14673 p += l; /* skip multi-byte character */ 14674 else 14675 #endif 14676 { 14677 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14678 ++p; 14679 } 14680 } 14681 } 14682 14683 /* 14684 * "toupper(string)" function 14685 */ 14686 static void 14687 f_toupper(argvars, rettv) 14688 typval_T *argvars; 14689 typval_T *rettv; 14690 { 14691 rettv->v_type = VAR_STRING; 14692 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14693 } 14694 14695 /* 14696 * "tr(string, fromstr, tostr)" function 14697 */ 14698 static void 14699 f_tr(argvars, rettv) 14700 typval_T *argvars; 14701 typval_T *rettv; 14702 { 14703 char_u *instr; 14704 char_u *fromstr; 14705 char_u *tostr; 14706 char_u *p; 14707 #ifdef FEAT_MBYTE 14708 int inlen; 14709 int fromlen; 14710 int tolen; 14711 int idx; 14712 char_u *cpstr; 14713 int cplen; 14714 int first = TRUE; 14715 #endif 14716 char_u buf[NUMBUFLEN]; 14717 char_u buf2[NUMBUFLEN]; 14718 garray_T ga; 14719 14720 instr = get_tv_string(&argvars[0]); 14721 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14722 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14723 14724 /* Default return value: empty string. */ 14725 rettv->v_type = VAR_STRING; 14726 rettv->vval.v_string = NULL; 14727 if (fromstr == NULL || tostr == NULL) 14728 return; /* type error; errmsg already given */ 14729 ga_init2(&ga, (int)sizeof(char), 80); 14730 14731 #ifdef FEAT_MBYTE 14732 if (!has_mbyte) 14733 #endif 14734 /* not multi-byte: fromstr and tostr must be the same length */ 14735 if (STRLEN(fromstr) != STRLEN(tostr)) 14736 { 14737 #ifdef FEAT_MBYTE 14738 error: 14739 #endif 14740 EMSG2(_(e_invarg2), fromstr); 14741 ga_clear(&ga); 14742 return; 14743 } 14744 14745 /* fromstr and tostr have to contain the same number of chars */ 14746 while (*instr != NUL) 14747 { 14748 #ifdef FEAT_MBYTE 14749 if (has_mbyte) 14750 { 14751 inlen = (*mb_ptr2len)(instr); 14752 cpstr = instr; 14753 cplen = inlen; 14754 idx = 0; 14755 for (p = fromstr; *p != NUL; p += fromlen) 14756 { 14757 fromlen = (*mb_ptr2len)(p); 14758 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14759 { 14760 for (p = tostr; *p != NUL; p += tolen) 14761 { 14762 tolen = (*mb_ptr2len)(p); 14763 if (idx-- == 0) 14764 { 14765 cplen = tolen; 14766 cpstr = p; 14767 break; 14768 } 14769 } 14770 if (*p == NUL) /* tostr is shorter than fromstr */ 14771 goto error; 14772 break; 14773 } 14774 ++idx; 14775 } 14776 14777 if (first && cpstr == instr) 14778 { 14779 /* Check that fromstr and tostr have the same number of 14780 * (multi-byte) characters. Done only once when a character 14781 * of instr doesn't appear in fromstr. */ 14782 first = FALSE; 14783 for (p = tostr; *p != NUL; p += tolen) 14784 { 14785 tolen = (*mb_ptr2len)(p); 14786 --idx; 14787 } 14788 if (idx != 0) 14789 goto error; 14790 } 14791 14792 ga_grow(&ga, cplen); 14793 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14794 ga.ga_len += cplen; 14795 14796 instr += inlen; 14797 } 14798 else 14799 #endif 14800 { 14801 /* When not using multi-byte chars we can do it faster. */ 14802 p = vim_strchr(fromstr, *instr); 14803 if (p != NULL) 14804 ga_append(&ga, tostr[p - fromstr]); 14805 else 14806 ga_append(&ga, *instr); 14807 ++instr; 14808 } 14809 } 14810 14811 rettv->vval.v_string = ga.ga_data; 14812 } 14813 14814 /* 14815 * "type(expr)" function 14816 */ 14817 static void 14818 f_type(argvars, rettv) 14819 typval_T *argvars; 14820 typval_T *rettv; 14821 { 14822 int n; 14823 14824 switch (argvars[0].v_type) 14825 { 14826 case VAR_NUMBER: n = 0; break; 14827 case VAR_STRING: n = 1; break; 14828 case VAR_FUNC: n = 2; break; 14829 case VAR_LIST: n = 3; break; 14830 case VAR_DICT: n = 4; break; 14831 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14832 } 14833 rettv->vval.v_number = n; 14834 } 14835 14836 /* 14837 * "values(dict)" function 14838 */ 14839 static void 14840 f_values(argvars, rettv) 14841 typval_T *argvars; 14842 typval_T *rettv; 14843 { 14844 dict_list(argvars, rettv, 1); 14845 } 14846 14847 /* 14848 * "virtcol(string)" function 14849 */ 14850 static void 14851 f_virtcol(argvars, rettv) 14852 typval_T *argvars; 14853 typval_T *rettv; 14854 { 14855 colnr_T vcol = 0; 14856 pos_T *fp; 14857 14858 fp = var2fpos(&argvars[0], FALSE); 14859 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14860 { 14861 getvvcol(curwin, fp, NULL, NULL, &vcol); 14862 ++vcol; 14863 } 14864 14865 rettv->vval.v_number = vcol; 14866 } 14867 14868 /* 14869 * "visualmode()" function 14870 */ 14871 /*ARGSUSED*/ 14872 static void 14873 f_visualmode(argvars, rettv) 14874 typval_T *argvars; 14875 typval_T *rettv; 14876 { 14877 #ifdef FEAT_VISUAL 14878 char_u str[2]; 14879 14880 rettv->v_type = VAR_STRING; 14881 str[0] = curbuf->b_visual_mode_eval; 14882 str[1] = NUL; 14883 rettv->vval.v_string = vim_strsave(str); 14884 14885 /* A non-zero number or non-empty string argument: reset mode. */ 14886 if ((argvars[0].v_type == VAR_NUMBER 14887 && argvars[0].vval.v_number != 0) 14888 || (argvars[0].v_type == VAR_STRING 14889 && *get_tv_string(&argvars[0]) != NUL)) 14890 curbuf->b_visual_mode_eval = NUL; 14891 #else 14892 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14893 #endif 14894 } 14895 14896 /* 14897 * "winbufnr(nr)" function 14898 */ 14899 static void 14900 f_winbufnr(argvars, rettv) 14901 typval_T *argvars; 14902 typval_T *rettv; 14903 { 14904 win_T *wp; 14905 14906 wp = find_win_by_nr(&argvars[0]); 14907 if (wp == NULL) 14908 rettv->vval.v_number = -1; 14909 else 14910 rettv->vval.v_number = wp->w_buffer->b_fnum; 14911 } 14912 14913 /* 14914 * "wincol()" function 14915 */ 14916 /*ARGSUSED*/ 14917 static void 14918 f_wincol(argvars, rettv) 14919 typval_T *argvars; 14920 typval_T *rettv; 14921 { 14922 validate_cursor(); 14923 rettv->vval.v_number = curwin->w_wcol + 1; 14924 } 14925 14926 /* 14927 * "winheight(nr)" function 14928 */ 14929 static void 14930 f_winheight(argvars, rettv) 14931 typval_T *argvars; 14932 typval_T *rettv; 14933 { 14934 win_T *wp; 14935 14936 wp = find_win_by_nr(&argvars[0]); 14937 if (wp == NULL) 14938 rettv->vval.v_number = -1; 14939 else 14940 rettv->vval.v_number = wp->w_height; 14941 } 14942 14943 /* 14944 * "winline()" function 14945 */ 14946 /*ARGSUSED*/ 14947 static void 14948 f_winline(argvars, rettv) 14949 typval_T *argvars; 14950 typval_T *rettv; 14951 { 14952 validate_cursor(); 14953 rettv->vval.v_number = curwin->w_wrow + 1; 14954 } 14955 14956 /* 14957 * "winnr()" function 14958 */ 14959 /* ARGSUSED */ 14960 static void 14961 f_winnr(argvars, rettv) 14962 typval_T *argvars; 14963 typval_T *rettv; 14964 { 14965 int nr = 1; 14966 #ifdef FEAT_WINDOWS 14967 win_T *wp; 14968 win_T *twin = curwin; 14969 char_u *arg; 14970 14971 if (argvars[0].v_type != VAR_UNKNOWN) 14972 { 14973 arg = get_tv_string_chk(&argvars[0]); 14974 if (arg == NULL) 14975 nr = 0; /* type error; errmsg already given */ 14976 else if (STRCMP(arg, "$") == 0) 14977 twin = lastwin; 14978 else if (STRCMP(arg, "#") == 0) 14979 { 14980 twin = prevwin; 14981 if (prevwin == NULL) 14982 nr = 0; 14983 } 14984 else 14985 { 14986 EMSG2(_(e_invexpr2), arg); 14987 nr = 0; 14988 } 14989 } 14990 14991 if (nr > 0) 14992 for (wp = firstwin; wp != twin; wp = wp->w_next) 14993 ++nr; 14994 #endif 14995 rettv->vval.v_number = nr; 14996 } 14997 14998 /* 14999 * "winrestcmd()" function 15000 */ 15001 /* ARGSUSED */ 15002 static void 15003 f_winrestcmd(argvars, rettv) 15004 typval_T *argvars; 15005 typval_T *rettv; 15006 { 15007 #ifdef FEAT_WINDOWS 15008 win_T *wp; 15009 int winnr = 1; 15010 garray_T ga; 15011 char_u buf[50]; 15012 15013 ga_init2(&ga, (int)sizeof(char), 70); 15014 for (wp = firstwin; wp != NULL; wp = wp->w_next) 15015 { 15016 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 15017 ga_concat(&ga, buf); 15018 # ifdef FEAT_VERTSPLIT 15019 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 15020 ga_concat(&ga, buf); 15021 # endif 15022 ++winnr; 15023 } 15024 ga_append(&ga, NUL); 15025 15026 rettv->vval.v_string = ga.ga_data; 15027 #else 15028 rettv->vval.v_string = NULL; 15029 #endif 15030 rettv->v_type = VAR_STRING; 15031 } 15032 15033 /* 15034 * "winwidth(nr)" function 15035 */ 15036 static void 15037 f_winwidth(argvars, rettv) 15038 typval_T *argvars; 15039 typval_T *rettv; 15040 { 15041 win_T *wp; 15042 15043 wp = find_win_by_nr(&argvars[0]); 15044 if (wp == NULL) 15045 rettv->vval.v_number = -1; 15046 else 15047 #ifdef FEAT_VERTSPLIT 15048 rettv->vval.v_number = wp->w_width; 15049 #else 15050 rettv->vval.v_number = Columns; 15051 #endif 15052 } 15053 15054 /* 15055 * "writefile()" function 15056 */ 15057 static void 15058 f_writefile(argvars, rettv) 15059 typval_T *argvars; 15060 typval_T *rettv; 15061 { 15062 int binary = FALSE; 15063 char_u *fname; 15064 FILE *fd; 15065 listitem_T *li; 15066 char_u *s; 15067 int ret = 0; 15068 int c; 15069 15070 if (argvars[0].v_type != VAR_LIST) 15071 { 15072 EMSG2(_(e_listarg), "writefile()"); 15073 return; 15074 } 15075 if (argvars[0].vval.v_list == NULL) 15076 return; 15077 15078 if (argvars[2].v_type != VAR_UNKNOWN 15079 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 15080 binary = TRUE; 15081 15082 /* Always open the file in binary mode, library functions have a mind of 15083 * their own about CR-LF conversion. */ 15084 fname = get_tv_string(&argvars[1]); 15085 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 15086 { 15087 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 15088 ret = -1; 15089 } 15090 else 15091 { 15092 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 15093 li = li->li_next) 15094 { 15095 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 15096 { 15097 if (*s == '\n') 15098 c = putc(NUL, fd); 15099 else 15100 c = putc(*s, fd); 15101 if (c == EOF) 15102 { 15103 ret = -1; 15104 break; 15105 } 15106 } 15107 if (!binary || li->li_next != NULL) 15108 if (putc('\n', fd) == EOF) 15109 { 15110 ret = -1; 15111 break; 15112 } 15113 if (ret < 0) 15114 { 15115 EMSG(_(e_write)); 15116 break; 15117 } 15118 } 15119 fclose(fd); 15120 } 15121 15122 rettv->vval.v_number = ret; 15123 } 15124 15125 /* 15126 * Translate a String variable into a position. 15127 */ 15128 static pos_T * 15129 var2fpos(varp, lnum) 15130 typval_T *varp; 15131 int lnum; /* TRUE when $ is last line */ 15132 { 15133 char_u *name; 15134 static pos_T pos; 15135 pos_T *pp; 15136 15137 name = get_tv_string_chk(varp); 15138 if (name == NULL) 15139 return NULL; 15140 if (name[0] == '.') /* cursor */ 15141 return &curwin->w_cursor; 15142 if (name[0] == '\'') /* mark */ 15143 { 15144 pp = getmark(name[1], FALSE); 15145 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15146 return NULL; 15147 return pp; 15148 } 15149 if (name[0] == '$') /* last column or line */ 15150 { 15151 if (lnum) 15152 { 15153 pos.lnum = curbuf->b_ml.ml_line_count; 15154 pos.col = 0; 15155 } 15156 else 15157 { 15158 pos.lnum = curwin->w_cursor.lnum; 15159 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15160 } 15161 return &pos; 15162 } 15163 return NULL; 15164 } 15165 15166 /* 15167 * Get the length of an environment variable name. 15168 * Advance "arg" to the first character after the name. 15169 * Return 0 for error. 15170 */ 15171 static int 15172 get_env_len(arg) 15173 char_u **arg; 15174 { 15175 char_u *p; 15176 int len; 15177 15178 for (p = *arg; vim_isIDc(*p); ++p) 15179 ; 15180 if (p == *arg) /* no name found */ 15181 return 0; 15182 15183 len = (int)(p - *arg); 15184 *arg = p; 15185 return len; 15186 } 15187 15188 /* 15189 * Get the length of the name of a function or internal variable. 15190 * "arg" is advanced to the first non-white character after the name. 15191 * Return 0 if something is wrong. 15192 */ 15193 static int 15194 get_id_len(arg) 15195 char_u **arg; 15196 { 15197 char_u *p; 15198 int len; 15199 15200 /* Find the end of the name. */ 15201 for (p = *arg; eval_isnamec(*p); ++p) 15202 ; 15203 if (p == *arg) /* no name found */ 15204 return 0; 15205 15206 len = (int)(p - *arg); 15207 *arg = skipwhite(p); 15208 15209 return len; 15210 } 15211 15212 /* 15213 * Get the length of the name of a variable or function. 15214 * Only the name is recognized, does not handle ".key" or "[idx]". 15215 * "arg" is advanced to the first non-white character after the name. 15216 * Return -1 if curly braces expansion failed. 15217 * Return 0 if something else is wrong. 15218 * If the name contains 'magic' {}'s, expand them and return the 15219 * expanded name in an allocated string via 'alias' - caller must free. 15220 */ 15221 static int 15222 get_name_len(arg, alias, evaluate, verbose) 15223 char_u **arg; 15224 char_u **alias; 15225 int evaluate; 15226 int verbose; 15227 { 15228 int len; 15229 char_u *p; 15230 char_u *expr_start; 15231 char_u *expr_end; 15232 15233 *alias = NULL; /* default to no alias */ 15234 15235 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15236 && (*arg)[2] == (int)KE_SNR) 15237 { 15238 /* hard coded <SNR>, already translated */ 15239 *arg += 3; 15240 return get_id_len(arg) + 3; 15241 } 15242 len = eval_fname_script(*arg); 15243 if (len > 0) 15244 { 15245 /* literal "<SID>", "s:" or "<SNR>" */ 15246 *arg += len; 15247 } 15248 15249 /* 15250 * Find the end of the name; check for {} construction. 15251 */ 15252 p = find_name_end(*arg, &expr_start, &expr_end, 15253 len > 0 ? 0 : FNE_CHECK_START); 15254 if (expr_start != NULL) 15255 { 15256 char_u *temp_string; 15257 15258 if (!evaluate) 15259 { 15260 len += (int)(p - *arg); 15261 *arg = skipwhite(p); 15262 return len; 15263 } 15264 15265 /* 15266 * Include any <SID> etc in the expanded string: 15267 * Thus the -len here. 15268 */ 15269 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15270 if (temp_string == NULL) 15271 return -1; 15272 *alias = temp_string; 15273 *arg = skipwhite(p); 15274 return (int)STRLEN(temp_string); 15275 } 15276 15277 len += get_id_len(arg); 15278 if (len == 0 && verbose) 15279 EMSG2(_(e_invexpr2), *arg); 15280 15281 return len; 15282 } 15283 15284 /* 15285 * Find the end of a variable or function name, taking care of magic braces. 15286 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15287 * start and end of the first magic braces item. 15288 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15289 * Return a pointer to just after the name. Equal to "arg" if there is no 15290 * valid name. 15291 */ 15292 static char_u * 15293 find_name_end(arg, expr_start, expr_end, flags) 15294 char_u *arg; 15295 char_u **expr_start; 15296 char_u **expr_end; 15297 int flags; 15298 { 15299 int mb_nest = 0; 15300 int br_nest = 0; 15301 char_u *p; 15302 15303 if (expr_start != NULL) 15304 { 15305 *expr_start = NULL; 15306 *expr_end = NULL; 15307 } 15308 15309 /* Quick check for valid starting character. */ 15310 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15311 return arg; 15312 15313 for (p = arg; *p != NUL 15314 && (eval_isnamec(*p) 15315 || *p == '{' 15316 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15317 || mb_nest != 0 15318 || br_nest != 0); mb_ptr_adv(p)) 15319 { 15320 if (*p == '\'') 15321 { 15322 /* skip over 'string' to avoid counting [ and ] inside it. */ 15323 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15324 ; 15325 if (*p == NUL) 15326 break; 15327 } 15328 else if (*p == '"') 15329 { 15330 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15331 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15332 if (*p == '\\' && p[1] != NUL) 15333 ++p; 15334 if (*p == NUL) 15335 break; 15336 } 15337 15338 if (mb_nest == 0) 15339 { 15340 if (*p == '[') 15341 ++br_nest; 15342 else if (*p == ']') 15343 --br_nest; 15344 } 15345 15346 if (br_nest == 0) 15347 { 15348 if (*p == '{') 15349 { 15350 mb_nest++; 15351 if (expr_start != NULL && *expr_start == NULL) 15352 *expr_start = p; 15353 } 15354 else if (*p == '}') 15355 { 15356 mb_nest--; 15357 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15358 *expr_end = p; 15359 } 15360 } 15361 } 15362 15363 return p; 15364 } 15365 15366 /* 15367 * Expands out the 'magic' {}'s in a variable/function name. 15368 * Note that this can call itself recursively, to deal with 15369 * constructs like foo{bar}{baz}{bam} 15370 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15371 * "in_start" ^ 15372 * "expr_start" ^ 15373 * "expr_end" ^ 15374 * "in_end" ^ 15375 * 15376 * Returns a new allocated string, which the caller must free. 15377 * Returns NULL for failure. 15378 */ 15379 static char_u * 15380 make_expanded_name(in_start, expr_start, expr_end, in_end) 15381 char_u *in_start; 15382 char_u *expr_start; 15383 char_u *expr_end; 15384 char_u *in_end; 15385 { 15386 char_u c1; 15387 char_u *retval = NULL; 15388 char_u *temp_result; 15389 char_u *nextcmd = NULL; 15390 15391 if (expr_end == NULL || in_end == NULL) 15392 return NULL; 15393 *expr_start = NUL; 15394 *expr_end = NUL; 15395 c1 = *in_end; 15396 *in_end = NUL; 15397 15398 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15399 if (temp_result != NULL && nextcmd == NULL) 15400 { 15401 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15402 + (in_end - expr_end) + 1)); 15403 if (retval != NULL) 15404 { 15405 STRCPY(retval, in_start); 15406 STRCAT(retval, temp_result); 15407 STRCAT(retval, expr_end + 1); 15408 } 15409 } 15410 vim_free(temp_result); 15411 15412 *in_end = c1; /* put char back for error messages */ 15413 *expr_start = '{'; 15414 *expr_end = '}'; 15415 15416 if (retval != NULL) 15417 { 15418 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15419 if (expr_start != NULL) 15420 { 15421 /* Further expansion! */ 15422 temp_result = make_expanded_name(retval, expr_start, 15423 expr_end, temp_result); 15424 vim_free(retval); 15425 retval = temp_result; 15426 } 15427 } 15428 15429 return retval; 15430 } 15431 15432 /* 15433 * Return TRUE if character "c" can be used in a variable or function name. 15434 * Does not include '{' or '}' for magic braces. 15435 */ 15436 static int 15437 eval_isnamec(c) 15438 int c; 15439 { 15440 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15441 } 15442 15443 /* 15444 * Return TRUE if character "c" can be used as the first character in a 15445 * variable or function name (excluding '{' and '}'). 15446 */ 15447 static int 15448 eval_isnamec1(c) 15449 int c; 15450 { 15451 return (ASCII_ISALPHA(c) || c == '_'); 15452 } 15453 15454 /* 15455 * Set number v: variable to "val". 15456 */ 15457 void 15458 set_vim_var_nr(idx, val) 15459 int idx; 15460 long val; 15461 { 15462 vimvars[idx].vv_nr = val; 15463 } 15464 15465 /* 15466 * Get number v: variable value. 15467 */ 15468 long 15469 get_vim_var_nr(idx) 15470 int idx; 15471 { 15472 return vimvars[idx].vv_nr; 15473 } 15474 15475 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15476 /* 15477 * Get string v: variable value. Uses a static buffer, can only be used once. 15478 */ 15479 char_u * 15480 get_vim_var_str(idx) 15481 int idx; 15482 { 15483 return get_tv_string(&vimvars[idx].vv_tv); 15484 } 15485 #endif 15486 15487 /* 15488 * Set v:count, v:count1 and v:prevcount. 15489 */ 15490 void 15491 set_vcount(count, count1) 15492 long count; 15493 long count1; 15494 { 15495 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15496 vimvars[VV_COUNT].vv_nr = count; 15497 vimvars[VV_COUNT1].vv_nr = count1; 15498 } 15499 15500 /* 15501 * Set string v: variable to a copy of "val". 15502 */ 15503 void 15504 set_vim_var_string(idx, val, len) 15505 int idx; 15506 char_u *val; 15507 int len; /* length of "val" to use or -1 (whole string) */ 15508 { 15509 /* Need to do this (at least) once, since we can't initialize a union. 15510 * Will always be invoked when "v:progname" is set. */ 15511 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15512 15513 vim_free(vimvars[idx].vv_str); 15514 if (val == NULL) 15515 vimvars[idx].vv_str = NULL; 15516 else if (len == -1) 15517 vimvars[idx].vv_str = vim_strsave(val); 15518 else 15519 vimvars[idx].vv_str = vim_strnsave(val, len); 15520 } 15521 15522 /* 15523 * Set v:register if needed. 15524 */ 15525 void 15526 set_reg_var(c) 15527 int c; 15528 { 15529 char_u regname; 15530 15531 if (c == 0 || c == ' ') 15532 regname = '"'; 15533 else 15534 regname = c; 15535 /* Avoid free/alloc when the value is already right. */ 15536 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15537 set_vim_var_string(VV_REG, ®name, 1); 15538 } 15539 15540 /* 15541 * Get or set v:exception. If "oldval" == NULL, return the current value. 15542 * Otherwise, restore the value to "oldval" and return NULL. 15543 * Must always be called in pairs to save and restore v:exception! Does not 15544 * take care of memory allocations. 15545 */ 15546 char_u * 15547 v_exception(oldval) 15548 char_u *oldval; 15549 { 15550 if (oldval == NULL) 15551 return vimvars[VV_EXCEPTION].vv_str; 15552 15553 vimvars[VV_EXCEPTION].vv_str = oldval; 15554 return NULL; 15555 } 15556 15557 /* 15558 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15559 * Otherwise, restore the value to "oldval" and return NULL. 15560 * Must always be called in pairs to save and restore v:throwpoint! Does not 15561 * take care of memory allocations. 15562 */ 15563 char_u * 15564 v_throwpoint(oldval) 15565 char_u *oldval; 15566 { 15567 if (oldval == NULL) 15568 return vimvars[VV_THROWPOINT].vv_str; 15569 15570 vimvars[VV_THROWPOINT].vv_str = oldval; 15571 return NULL; 15572 } 15573 15574 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15575 /* 15576 * Set v:cmdarg. 15577 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15578 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15579 * Must always be called in pairs! 15580 */ 15581 char_u * 15582 set_cmdarg(eap, oldarg) 15583 exarg_T *eap; 15584 char_u *oldarg; 15585 { 15586 char_u *oldval; 15587 char_u *newval; 15588 unsigned len; 15589 15590 oldval = vimvars[VV_CMDARG].vv_str; 15591 if (eap == NULL) 15592 { 15593 vim_free(oldval); 15594 vimvars[VV_CMDARG].vv_str = oldarg; 15595 return NULL; 15596 } 15597 15598 if (eap->force_bin == FORCE_BIN) 15599 len = 6; 15600 else if (eap->force_bin == FORCE_NOBIN) 15601 len = 8; 15602 else 15603 len = 0; 15604 if (eap->force_ff != 0) 15605 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15606 # ifdef FEAT_MBYTE 15607 if (eap->force_enc != 0) 15608 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15609 # endif 15610 15611 newval = alloc(len + 1); 15612 if (newval == NULL) 15613 return NULL; 15614 15615 if (eap->force_bin == FORCE_BIN) 15616 sprintf((char *)newval, " ++bin"); 15617 else if (eap->force_bin == FORCE_NOBIN) 15618 sprintf((char *)newval, " ++nobin"); 15619 else 15620 *newval = NUL; 15621 if (eap->force_ff != 0) 15622 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15623 eap->cmd + eap->force_ff); 15624 # ifdef FEAT_MBYTE 15625 if (eap->force_enc != 0) 15626 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15627 eap->cmd + eap->force_enc); 15628 # endif 15629 vimvars[VV_CMDARG].vv_str = newval; 15630 return oldval; 15631 } 15632 #endif 15633 15634 /* 15635 * Get the value of internal variable "name". 15636 * Return OK or FAIL. 15637 */ 15638 static int 15639 get_var_tv(name, len, rettv, verbose) 15640 char_u *name; 15641 int len; /* length of "name" */ 15642 typval_T *rettv; /* NULL when only checking existence */ 15643 int verbose; /* may give error message */ 15644 { 15645 int ret = OK; 15646 typval_T *tv = NULL; 15647 typval_T atv; 15648 dictitem_T *v; 15649 int cc; 15650 15651 /* truncate the name, so that we can use strcmp() */ 15652 cc = name[len]; 15653 name[len] = NUL; 15654 15655 /* 15656 * Check for "b:changedtick". 15657 */ 15658 if (STRCMP(name, "b:changedtick") == 0) 15659 { 15660 atv.v_type = VAR_NUMBER; 15661 atv.vval.v_number = curbuf->b_changedtick; 15662 tv = &atv; 15663 } 15664 15665 /* 15666 * Check for user-defined variables. 15667 */ 15668 else 15669 { 15670 v = find_var(name, NULL); 15671 if (v != NULL) 15672 tv = &v->di_tv; 15673 } 15674 15675 if (tv == NULL) 15676 { 15677 if (rettv != NULL && verbose) 15678 EMSG2(_(e_undefvar), name); 15679 ret = FAIL; 15680 } 15681 else if (rettv != NULL) 15682 copy_tv(tv, rettv); 15683 15684 name[len] = cc; 15685 15686 return ret; 15687 } 15688 15689 /* 15690 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15691 * Also handle function call with Funcref variable: func(expr) 15692 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15693 */ 15694 static int 15695 handle_subscript(arg, rettv, evaluate, verbose) 15696 char_u **arg; 15697 typval_T *rettv; 15698 int evaluate; /* do more than finding the end */ 15699 int verbose; /* give error messages */ 15700 { 15701 int ret = OK; 15702 dict_T *selfdict = NULL; 15703 char_u *s; 15704 int len; 15705 typval_T functv; 15706 15707 while (ret == OK 15708 && (**arg == '[' 15709 || (**arg == '.' && rettv->v_type == VAR_DICT) 15710 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15711 && !vim_iswhite(*(*arg - 1))) 15712 { 15713 if (**arg == '(') 15714 { 15715 /* need to copy the funcref so that we can clear rettv */ 15716 functv = *rettv; 15717 rettv->v_type = VAR_UNKNOWN; 15718 15719 /* Invoke the function. Recursive! */ 15720 s = functv.vval.v_string; 15721 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15722 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15723 &len, evaluate, selfdict); 15724 15725 /* Clear the funcref afterwards, so that deleting it while 15726 * evaluating the arguments is possible (see test55). */ 15727 clear_tv(&functv); 15728 15729 /* Stop the expression evaluation when immediately aborting on 15730 * error, or when an interrupt occurred or an exception was thrown 15731 * but not caught. */ 15732 if (aborting()) 15733 { 15734 if (ret == OK) 15735 clear_tv(rettv); 15736 ret = FAIL; 15737 } 15738 dict_unref(selfdict); 15739 selfdict = NULL; 15740 } 15741 else /* **arg == '[' || **arg == '.' */ 15742 { 15743 dict_unref(selfdict); 15744 if (rettv->v_type == VAR_DICT) 15745 { 15746 selfdict = rettv->vval.v_dict; 15747 if (selfdict != NULL) 15748 ++selfdict->dv_refcount; 15749 } 15750 else 15751 selfdict = NULL; 15752 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15753 { 15754 clear_tv(rettv); 15755 ret = FAIL; 15756 } 15757 } 15758 } 15759 dict_unref(selfdict); 15760 return ret; 15761 } 15762 15763 /* 15764 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15765 * value). 15766 */ 15767 static typval_T * 15768 alloc_tv() 15769 { 15770 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15771 } 15772 15773 /* 15774 * Allocate memory for a variable type-value, and assign a string to it. 15775 * The string "s" must have been allocated, it is consumed. 15776 * Return NULL for out of memory, the variable otherwise. 15777 */ 15778 static typval_T * 15779 alloc_string_tv(s) 15780 char_u *s; 15781 { 15782 typval_T *rettv; 15783 15784 rettv = alloc_tv(); 15785 if (rettv != NULL) 15786 { 15787 rettv->v_type = VAR_STRING; 15788 rettv->vval.v_string = s; 15789 } 15790 else 15791 vim_free(s); 15792 return rettv; 15793 } 15794 15795 /* 15796 * Free the memory for a variable type-value. 15797 */ 15798 static void 15799 free_tv(varp) 15800 typval_T *varp; 15801 { 15802 if (varp != NULL) 15803 { 15804 switch (varp->v_type) 15805 { 15806 case VAR_FUNC: 15807 func_unref(varp->vval.v_string); 15808 /*FALLTHROUGH*/ 15809 case VAR_STRING: 15810 vim_free(varp->vval.v_string); 15811 break; 15812 case VAR_LIST: 15813 list_unref(varp->vval.v_list); 15814 break; 15815 case VAR_DICT: 15816 dict_unref(varp->vval.v_dict); 15817 break; 15818 case VAR_NUMBER: 15819 case VAR_UNKNOWN: 15820 break; 15821 default: 15822 EMSG2(_(e_intern2), "free_tv()"); 15823 break; 15824 } 15825 vim_free(varp); 15826 } 15827 } 15828 15829 /* 15830 * Free the memory for a variable value and set the value to NULL or 0. 15831 */ 15832 void 15833 clear_tv(varp) 15834 typval_T *varp; 15835 { 15836 if (varp != NULL) 15837 { 15838 switch (varp->v_type) 15839 { 15840 case VAR_FUNC: 15841 func_unref(varp->vval.v_string); 15842 /*FALLTHROUGH*/ 15843 case VAR_STRING: 15844 vim_free(varp->vval.v_string); 15845 varp->vval.v_string = NULL; 15846 break; 15847 case VAR_LIST: 15848 list_unref(varp->vval.v_list); 15849 varp->vval.v_list = NULL; 15850 break; 15851 case VAR_DICT: 15852 dict_unref(varp->vval.v_dict); 15853 varp->vval.v_dict = NULL; 15854 break; 15855 case VAR_NUMBER: 15856 varp->vval.v_number = 0; 15857 break; 15858 case VAR_UNKNOWN: 15859 break; 15860 default: 15861 EMSG2(_(e_intern2), "clear_tv()"); 15862 } 15863 varp->v_lock = 0; 15864 } 15865 } 15866 15867 /* 15868 * Set the value of a variable to NULL without freeing items. 15869 */ 15870 static void 15871 init_tv(varp) 15872 typval_T *varp; 15873 { 15874 if (varp != NULL) 15875 vim_memset(varp, 0, sizeof(typval_T)); 15876 } 15877 15878 /* 15879 * Get the number value of a variable. 15880 * If it is a String variable, uses vim_str2nr(). 15881 * For incompatible types, return 0. 15882 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15883 * caller of incompatible types: it sets *denote to TRUE if "denote" 15884 * is not NULL or returns -1 otherwise. 15885 */ 15886 static long 15887 get_tv_number(varp) 15888 typval_T *varp; 15889 { 15890 int error = FALSE; 15891 15892 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15893 } 15894 15895 long 15896 get_tv_number_chk(varp, denote) 15897 typval_T *varp; 15898 int *denote; 15899 { 15900 long n = 0L; 15901 15902 switch (varp->v_type) 15903 { 15904 case VAR_NUMBER: 15905 return (long)(varp->vval.v_number); 15906 case VAR_FUNC: 15907 EMSG(_("E703: Using a Funcref as a number")); 15908 break; 15909 case VAR_STRING: 15910 if (varp->vval.v_string != NULL) 15911 vim_str2nr(varp->vval.v_string, NULL, NULL, 15912 TRUE, TRUE, &n, NULL); 15913 return n; 15914 case VAR_LIST: 15915 EMSG(_("E745: Using a List as a number")); 15916 break; 15917 case VAR_DICT: 15918 EMSG(_("E728: Using a Dictionary as a number")); 15919 break; 15920 default: 15921 EMSG2(_(e_intern2), "get_tv_number()"); 15922 break; 15923 } 15924 if (denote == NULL) /* useful for values that must be unsigned */ 15925 n = -1; 15926 else 15927 *denote = TRUE; 15928 return n; 15929 } 15930 15931 /* 15932 * Get the lnum from the first argument. 15933 * Also accepts ".", "$", etc., but that only works for the current buffer. 15934 * Returns -1 on error. 15935 */ 15936 static linenr_T 15937 get_tv_lnum(argvars) 15938 typval_T *argvars; 15939 { 15940 typval_T rettv; 15941 linenr_T lnum; 15942 15943 lnum = get_tv_number_chk(&argvars[0], NULL); 15944 if (lnum == 0) /* no valid number, try using line() */ 15945 { 15946 rettv.v_type = VAR_NUMBER; 15947 f_line(argvars, &rettv); 15948 lnum = rettv.vval.v_number; 15949 clear_tv(&rettv); 15950 } 15951 return lnum; 15952 } 15953 15954 /* 15955 * Get the lnum from the first argument. 15956 * Also accepts "$", then "buf" is used. 15957 * Returns 0 on error. 15958 */ 15959 static linenr_T 15960 get_tv_lnum_buf(argvars, buf) 15961 typval_T *argvars; 15962 buf_T *buf; 15963 { 15964 if (argvars[0].v_type == VAR_STRING 15965 && argvars[0].vval.v_string != NULL 15966 && argvars[0].vval.v_string[0] == '$' 15967 && buf != NULL) 15968 return buf->b_ml.ml_line_count; 15969 return get_tv_number_chk(&argvars[0], NULL); 15970 } 15971 15972 /* 15973 * Get the string value of a variable. 15974 * If it is a Number variable, the number is converted into a string. 15975 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 15976 * get_tv_string_buf() uses a given buffer. 15977 * If the String variable has never been set, return an empty string. 15978 * Never returns NULL; 15979 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 15980 * NULL on error. 15981 */ 15982 static char_u * 15983 get_tv_string(varp) 15984 typval_T *varp; 15985 { 15986 static char_u mybuf[NUMBUFLEN]; 15987 15988 return get_tv_string_buf(varp, mybuf); 15989 } 15990 15991 static char_u * 15992 get_tv_string_buf(varp, buf) 15993 typval_T *varp; 15994 char_u *buf; 15995 { 15996 char_u *res = get_tv_string_buf_chk(varp, buf); 15997 15998 return res != NULL ? res : (char_u *)""; 15999 } 16000 16001 char_u * 16002 get_tv_string_chk(varp) 16003 typval_T *varp; 16004 { 16005 static char_u mybuf[NUMBUFLEN]; 16006 16007 return get_tv_string_buf_chk(varp, mybuf); 16008 } 16009 16010 static char_u * 16011 get_tv_string_buf_chk(varp, buf) 16012 typval_T *varp; 16013 char_u *buf; 16014 { 16015 switch (varp->v_type) 16016 { 16017 case VAR_NUMBER: 16018 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 16019 return buf; 16020 case VAR_FUNC: 16021 EMSG(_("E729: using Funcref as a String")); 16022 break; 16023 case VAR_LIST: 16024 EMSG(_("E730: using List as a String")); 16025 break; 16026 case VAR_DICT: 16027 EMSG(_("E731: using Dictionary as a String")); 16028 break; 16029 case VAR_STRING: 16030 if (varp->vval.v_string != NULL) 16031 return varp->vval.v_string; 16032 return (char_u *)""; 16033 default: 16034 EMSG2(_(e_intern2), "get_tv_string_buf()"); 16035 break; 16036 } 16037 return NULL; 16038 } 16039 16040 /* 16041 * Find variable "name" in the list of variables. 16042 * Return a pointer to it if found, NULL if not found. 16043 * Careful: "a:0" variables don't have a name. 16044 * When "htp" is not NULL we are writing to the variable, set "htp" to the 16045 * hashtab_T used. 16046 */ 16047 static dictitem_T * 16048 find_var(name, htp) 16049 char_u *name; 16050 hashtab_T **htp; 16051 { 16052 char_u *varname; 16053 hashtab_T *ht; 16054 16055 ht = find_var_ht(name, &varname); 16056 if (htp != NULL) 16057 *htp = ht; 16058 if (ht == NULL) 16059 return NULL; 16060 return find_var_in_ht(ht, varname, htp != NULL); 16061 } 16062 16063 /* 16064 * Find variable "varname" in hashtab "ht". 16065 * Returns NULL if not found. 16066 */ 16067 static dictitem_T * 16068 find_var_in_ht(ht, varname, writing) 16069 hashtab_T *ht; 16070 char_u *varname; 16071 int writing; 16072 { 16073 hashitem_T *hi; 16074 16075 if (*varname == NUL) 16076 { 16077 /* Must be something like "s:", otherwise "ht" would be NULL. */ 16078 switch (varname[-2]) 16079 { 16080 case 's': return &SCRIPT_SV(current_SID).sv_var; 16081 case 'g': return &globvars_var; 16082 case 'v': return &vimvars_var; 16083 case 'b': return &curbuf->b_bufvar; 16084 case 'w': return &curwin->w_winvar; 16085 case 'l': return current_funccal == NULL 16086 ? NULL : ¤t_funccal->l_vars_var; 16087 case 'a': return current_funccal == NULL 16088 ? NULL : ¤t_funccal->l_avars_var; 16089 } 16090 return NULL; 16091 } 16092 16093 hi = hash_find(ht, varname); 16094 if (HASHITEM_EMPTY(hi)) 16095 { 16096 /* For global variables we may try auto-loading the script. If it 16097 * worked find the variable again. Don't auto-load a script if it was 16098 * loaded already, otherwise it would be loaded every time when 16099 * checking if a function name is a Funcref variable. */ 16100 if (ht == &globvarht && !writing 16101 && script_autoload(varname, FALSE) && !aborting()) 16102 hi = hash_find(ht, varname); 16103 if (HASHITEM_EMPTY(hi)) 16104 return NULL; 16105 } 16106 return HI2DI(hi); 16107 } 16108 16109 /* 16110 * Find the hashtab used for a variable name. 16111 * Set "varname" to the start of name without ':'. 16112 */ 16113 static hashtab_T * 16114 find_var_ht(name, varname) 16115 char_u *name; 16116 char_u **varname; 16117 { 16118 hashitem_T *hi; 16119 16120 if (name[1] != ':') 16121 { 16122 /* The name must not start with a colon or #. */ 16123 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16124 return NULL; 16125 *varname = name; 16126 16127 /* "version" is "v:version" in all scopes */ 16128 hi = hash_find(&compat_hashtab, name); 16129 if (!HASHITEM_EMPTY(hi)) 16130 return &compat_hashtab; 16131 16132 if (current_funccal == NULL) 16133 return &globvarht; /* global variable */ 16134 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16135 } 16136 *varname = name + 2; 16137 if (*name == 'g') /* global variable */ 16138 return &globvarht; 16139 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16140 */ 16141 if (vim_strchr(name + 2, ':') != NULL 16142 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16143 return NULL; 16144 if (*name == 'b') /* buffer variable */ 16145 return &curbuf->b_vars.dv_hashtab; 16146 if (*name == 'w') /* window variable */ 16147 return &curwin->w_vars.dv_hashtab; 16148 if (*name == 'v') /* v: variable */ 16149 return &vimvarht; 16150 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16151 return ¤t_funccal->l_avars.dv_hashtab; 16152 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16153 return ¤t_funccal->l_vars.dv_hashtab; 16154 if (*name == 's' /* script variable */ 16155 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16156 return &SCRIPT_VARS(current_SID); 16157 return NULL; 16158 } 16159 16160 /* 16161 * Get the string value of a (global/local) variable. 16162 * Returns NULL when it doesn't exist. 16163 */ 16164 char_u * 16165 get_var_value(name) 16166 char_u *name; 16167 { 16168 dictitem_T *v; 16169 16170 v = find_var(name, NULL); 16171 if (v == NULL) 16172 return NULL; 16173 return get_tv_string(&v->di_tv); 16174 } 16175 16176 /* 16177 * Allocate a new hashtab for a sourced script. It will be used while 16178 * sourcing this script and when executing functions defined in the script. 16179 */ 16180 void 16181 new_script_vars(id) 16182 scid_T id; 16183 { 16184 int i; 16185 hashtab_T *ht; 16186 scriptvar_T *sv; 16187 16188 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16189 { 16190 /* Re-allocating ga_data means that an ht_array pointing to 16191 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16192 * at its init value. Also reset "v_dict", it's always the same. */ 16193 for (i = 1; i <= ga_scripts.ga_len; ++i) 16194 { 16195 ht = &SCRIPT_VARS(i); 16196 if (ht->ht_mask == HT_INIT_SIZE - 1) 16197 ht->ht_array = ht->ht_smallarray; 16198 sv = &SCRIPT_SV(i); 16199 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16200 } 16201 16202 while (ga_scripts.ga_len < id) 16203 { 16204 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16205 init_var_dict(&sv->sv_dict, &sv->sv_var); 16206 ++ga_scripts.ga_len; 16207 } 16208 } 16209 } 16210 16211 /* 16212 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16213 * point to it. 16214 */ 16215 void 16216 init_var_dict(dict, dict_var) 16217 dict_T *dict; 16218 dictitem_T *dict_var; 16219 { 16220 hash_init(&dict->dv_hashtab); 16221 dict->dv_refcount = 99999; 16222 dict_var->di_tv.vval.v_dict = dict; 16223 dict_var->di_tv.v_type = VAR_DICT; 16224 dict_var->di_tv.v_lock = VAR_FIXED; 16225 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16226 dict_var->di_key[0] = NUL; 16227 } 16228 16229 /* 16230 * Clean up a list of internal variables. 16231 * Frees all allocated variables and the value they contain. 16232 * Clears hashtab "ht", does not free it. 16233 */ 16234 void 16235 vars_clear(ht) 16236 hashtab_T *ht; 16237 { 16238 vars_clear_ext(ht, TRUE); 16239 } 16240 16241 /* 16242 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16243 */ 16244 static void 16245 vars_clear_ext(ht, free_val) 16246 hashtab_T *ht; 16247 int free_val; 16248 { 16249 int todo; 16250 hashitem_T *hi; 16251 dictitem_T *v; 16252 16253 hash_lock(ht); 16254 todo = ht->ht_used; 16255 for (hi = ht->ht_array; todo > 0; ++hi) 16256 { 16257 if (!HASHITEM_EMPTY(hi)) 16258 { 16259 --todo; 16260 16261 /* Free the variable. Don't remove it from the hashtab, 16262 * ht_array might change then. hash_clear() takes care of it 16263 * later. */ 16264 v = HI2DI(hi); 16265 if (free_val) 16266 clear_tv(&v->di_tv); 16267 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16268 vim_free(v); 16269 } 16270 } 16271 hash_clear(ht); 16272 ht->ht_used = 0; 16273 } 16274 16275 /* 16276 * Delete a variable from hashtab "ht" at item "hi". 16277 * Clear the variable value and free the dictitem. 16278 */ 16279 static void 16280 delete_var(ht, hi) 16281 hashtab_T *ht; 16282 hashitem_T *hi; 16283 { 16284 dictitem_T *di = HI2DI(hi); 16285 16286 hash_remove(ht, hi); 16287 clear_tv(&di->di_tv); 16288 vim_free(di); 16289 } 16290 16291 /* 16292 * List the value of one internal variable. 16293 */ 16294 static void 16295 list_one_var(v, prefix) 16296 dictitem_T *v; 16297 char_u *prefix; 16298 { 16299 char_u *tofree; 16300 char_u *s; 16301 char_u numbuf[NUMBUFLEN]; 16302 16303 s = echo_string(&v->di_tv, &tofree, numbuf); 16304 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16305 s == NULL ? (char_u *)"" : s); 16306 vim_free(tofree); 16307 } 16308 16309 static void 16310 list_one_var_a(prefix, name, type, string) 16311 char_u *prefix; 16312 char_u *name; 16313 int type; 16314 char_u *string; 16315 { 16316 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16317 if (name != NULL) /* "a:" vars don't have a name stored */ 16318 msg_puts(name); 16319 msg_putchar(' '); 16320 msg_advance(22); 16321 if (type == VAR_NUMBER) 16322 msg_putchar('#'); 16323 else if (type == VAR_FUNC) 16324 msg_putchar('*'); 16325 else if (type == VAR_LIST) 16326 { 16327 msg_putchar('['); 16328 if (*string == '[') 16329 ++string; 16330 } 16331 else if (type == VAR_DICT) 16332 { 16333 msg_putchar('{'); 16334 if (*string == '{') 16335 ++string; 16336 } 16337 else 16338 msg_putchar(' '); 16339 16340 msg_outtrans(string); 16341 16342 if (type == VAR_FUNC) 16343 msg_puts((char_u *)"()"); 16344 } 16345 16346 /* 16347 * Set variable "name" to value in "tv". 16348 * If the variable already exists, the value is updated. 16349 * Otherwise the variable is created. 16350 */ 16351 static void 16352 set_var(name, tv, copy) 16353 char_u *name; 16354 typval_T *tv; 16355 int copy; /* make copy of value in "tv" */ 16356 { 16357 dictitem_T *v; 16358 char_u *varname; 16359 hashtab_T *ht; 16360 char_u *p; 16361 16362 if (tv->v_type == VAR_FUNC) 16363 { 16364 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16365 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16366 ? name[2] : name[0])) 16367 { 16368 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16369 return; 16370 } 16371 if (function_exists(name)) 16372 { 16373 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16374 name); 16375 return; 16376 } 16377 } 16378 16379 ht = find_var_ht(name, &varname); 16380 if (ht == NULL || *varname == NUL) 16381 { 16382 EMSG2(_(e_illvar), name); 16383 return; 16384 } 16385 16386 v = find_var_in_ht(ht, varname, TRUE); 16387 if (v != NULL) 16388 { 16389 /* existing variable, need to clear the value */ 16390 if (var_check_ro(v->di_flags, name) 16391 || tv_check_lock(v->di_tv.v_lock, name)) 16392 return; 16393 if (v->di_tv.v_type != tv->v_type 16394 && !((v->di_tv.v_type == VAR_STRING 16395 || v->di_tv.v_type == VAR_NUMBER) 16396 && (tv->v_type == VAR_STRING 16397 || tv->v_type == VAR_NUMBER))) 16398 { 16399 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16400 return; 16401 } 16402 16403 /* 16404 * Handle setting internal v: variables separately: we don't change 16405 * the type. 16406 */ 16407 if (ht == &vimvarht) 16408 { 16409 if (v->di_tv.v_type == VAR_STRING) 16410 { 16411 vim_free(v->di_tv.vval.v_string); 16412 if (copy || tv->v_type != VAR_STRING) 16413 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16414 else 16415 { 16416 /* Take over the string to avoid an extra alloc/free. */ 16417 v->di_tv.vval.v_string = tv->vval.v_string; 16418 tv->vval.v_string = NULL; 16419 } 16420 } 16421 else if (v->di_tv.v_type != VAR_NUMBER) 16422 EMSG2(_(e_intern2), "set_var()"); 16423 else 16424 v->di_tv.vval.v_number = get_tv_number(tv); 16425 return; 16426 } 16427 16428 clear_tv(&v->di_tv); 16429 } 16430 else /* add a new variable */ 16431 { 16432 /* Make sure the variable name is valid. */ 16433 for (p = varname; *p != NUL; ++p) 16434 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16435 { 16436 EMSG2(_(e_illvar), varname); 16437 return; 16438 } 16439 16440 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16441 + STRLEN(varname))); 16442 if (v == NULL) 16443 return; 16444 STRCPY(v->di_key, varname); 16445 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16446 { 16447 vim_free(v); 16448 return; 16449 } 16450 v->di_flags = 0; 16451 } 16452 16453 if (copy || tv->v_type == VAR_NUMBER) 16454 copy_tv(tv, &v->di_tv); 16455 else 16456 { 16457 v->di_tv = *tv; 16458 v->di_tv.v_lock = 0; 16459 init_tv(tv); 16460 } 16461 } 16462 16463 /* 16464 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16465 * Also give an error message. 16466 */ 16467 static int 16468 var_check_ro(flags, name) 16469 int flags; 16470 char_u *name; 16471 { 16472 if (flags & DI_FLAGS_RO) 16473 { 16474 EMSG2(_(e_readonlyvar), name); 16475 return TRUE; 16476 } 16477 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16478 { 16479 EMSG2(_(e_readonlysbx), name); 16480 return TRUE; 16481 } 16482 return FALSE; 16483 } 16484 16485 /* 16486 * Return TRUE if typeval "tv" is set to be locked (immutable). 16487 * Also give an error message, using "name". 16488 */ 16489 static int 16490 tv_check_lock(lock, name) 16491 int lock; 16492 char_u *name; 16493 { 16494 if (lock & VAR_LOCKED) 16495 { 16496 EMSG2(_("E741: Value is locked: %s"), 16497 name == NULL ? (char_u *)_("Unknown") : name); 16498 return TRUE; 16499 } 16500 if (lock & VAR_FIXED) 16501 { 16502 EMSG2(_("E742: Cannot change value of %s"), 16503 name == NULL ? (char_u *)_("Unknown") : name); 16504 return TRUE; 16505 } 16506 return FALSE; 16507 } 16508 16509 /* 16510 * Copy the values from typval_T "from" to typval_T "to". 16511 * When needed allocates string or increases reference count. 16512 * Does not make a copy of a list or dict but copies the reference! 16513 */ 16514 static void 16515 copy_tv(from, to) 16516 typval_T *from; 16517 typval_T *to; 16518 { 16519 to->v_type = from->v_type; 16520 to->v_lock = 0; 16521 switch (from->v_type) 16522 { 16523 case VAR_NUMBER: 16524 to->vval.v_number = from->vval.v_number; 16525 break; 16526 case VAR_STRING: 16527 case VAR_FUNC: 16528 if (from->vval.v_string == NULL) 16529 to->vval.v_string = NULL; 16530 else 16531 { 16532 to->vval.v_string = vim_strsave(from->vval.v_string); 16533 if (from->v_type == VAR_FUNC) 16534 func_ref(to->vval.v_string); 16535 } 16536 break; 16537 case VAR_LIST: 16538 if (from->vval.v_list == NULL) 16539 to->vval.v_list = NULL; 16540 else 16541 { 16542 to->vval.v_list = from->vval.v_list; 16543 ++to->vval.v_list->lv_refcount; 16544 } 16545 break; 16546 case VAR_DICT: 16547 if (from->vval.v_dict == NULL) 16548 to->vval.v_dict = NULL; 16549 else 16550 { 16551 to->vval.v_dict = from->vval.v_dict; 16552 ++to->vval.v_dict->dv_refcount; 16553 } 16554 break; 16555 default: 16556 EMSG2(_(e_intern2), "copy_tv()"); 16557 break; 16558 } 16559 } 16560 16561 /* 16562 * Make a copy of an item. 16563 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16564 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16565 * reference to an already copied list/dict can be used. 16566 * Returns FAIL or OK. 16567 */ 16568 static int 16569 item_copy(from, to, deep, copyID) 16570 typval_T *from; 16571 typval_T *to; 16572 int deep; 16573 int copyID; 16574 { 16575 static int recurse = 0; 16576 int ret = OK; 16577 16578 if (recurse >= DICT_MAXNEST) 16579 { 16580 EMSG(_("E698: variable nested too deep for making a copy")); 16581 return FAIL; 16582 } 16583 ++recurse; 16584 16585 switch (from->v_type) 16586 { 16587 case VAR_NUMBER: 16588 case VAR_STRING: 16589 case VAR_FUNC: 16590 copy_tv(from, to); 16591 break; 16592 case VAR_LIST: 16593 to->v_type = VAR_LIST; 16594 to->v_lock = 0; 16595 if (from->vval.v_list == NULL) 16596 to->vval.v_list = NULL; 16597 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16598 { 16599 /* use the copy made earlier */ 16600 to->vval.v_list = from->vval.v_list->lv_copylist; 16601 ++to->vval.v_list->lv_refcount; 16602 } 16603 else 16604 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16605 if (to->vval.v_list == NULL) 16606 ret = FAIL; 16607 break; 16608 case VAR_DICT: 16609 to->v_type = VAR_DICT; 16610 to->v_lock = 0; 16611 if (from->vval.v_dict == NULL) 16612 to->vval.v_dict = NULL; 16613 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16614 { 16615 /* use the copy made earlier */ 16616 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16617 ++to->vval.v_dict->dv_refcount; 16618 } 16619 else 16620 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16621 if (to->vval.v_dict == NULL) 16622 ret = FAIL; 16623 break; 16624 default: 16625 EMSG2(_(e_intern2), "item_copy()"); 16626 ret = FAIL; 16627 } 16628 --recurse; 16629 return ret; 16630 } 16631 16632 /* 16633 * ":echo expr1 ..." print each argument separated with a space, add a 16634 * newline at the end. 16635 * ":echon expr1 ..." print each argument plain. 16636 */ 16637 void 16638 ex_echo(eap) 16639 exarg_T *eap; 16640 { 16641 char_u *arg = eap->arg; 16642 typval_T rettv; 16643 char_u *tofree; 16644 char_u *p; 16645 int needclr = TRUE; 16646 int atstart = TRUE; 16647 char_u numbuf[NUMBUFLEN]; 16648 16649 if (eap->skip) 16650 ++emsg_skip; 16651 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16652 { 16653 p = arg; 16654 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16655 { 16656 /* 16657 * Report the invalid expression unless the expression evaluation 16658 * has been cancelled due to an aborting error, an interrupt, or an 16659 * exception. 16660 */ 16661 if (!aborting()) 16662 EMSG2(_(e_invexpr2), p); 16663 break; 16664 } 16665 if (!eap->skip) 16666 { 16667 if (atstart) 16668 { 16669 atstart = FALSE; 16670 /* Call msg_start() after eval1(), evaluating the expression 16671 * may cause a message to appear. */ 16672 if (eap->cmdidx == CMD_echo) 16673 msg_start(); 16674 } 16675 else if (eap->cmdidx == CMD_echo) 16676 msg_puts_attr((char_u *)" ", echo_attr); 16677 p = echo_string(&rettv, &tofree, numbuf); 16678 if (p != NULL) 16679 for ( ; *p != NUL && !got_int; ++p) 16680 { 16681 if (*p == '\n' || *p == '\r' || *p == TAB) 16682 { 16683 if (*p != TAB && needclr) 16684 { 16685 /* remove any text still there from the command */ 16686 msg_clr_eos(); 16687 needclr = FALSE; 16688 } 16689 msg_putchar_attr(*p, echo_attr); 16690 } 16691 else 16692 { 16693 #ifdef FEAT_MBYTE 16694 if (has_mbyte) 16695 { 16696 int i = (*mb_ptr2len)(p); 16697 16698 (void)msg_outtrans_len_attr(p, i, echo_attr); 16699 p += i - 1; 16700 } 16701 else 16702 #endif 16703 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16704 } 16705 } 16706 vim_free(tofree); 16707 } 16708 clear_tv(&rettv); 16709 arg = skipwhite(arg); 16710 } 16711 eap->nextcmd = check_nextcmd(arg); 16712 16713 if (eap->skip) 16714 --emsg_skip; 16715 else 16716 { 16717 /* remove text that may still be there from the command */ 16718 if (needclr) 16719 msg_clr_eos(); 16720 if (eap->cmdidx == CMD_echo) 16721 msg_end(); 16722 } 16723 } 16724 16725 /* 16726 * ":echohl {name}". 16727 */ 16728 void 16729 ex_echohl(eap) 16730 exarg_T *eap; 16731 { 16732 int id; 16733 16734 id = syn_name2id(eap->arg); 16735 if (id == 0) 16736 echo_attr = 0; 16737 else 16738 echo_attr = syn_id2attr(id); 16739 } 16740 16741 /* 16742 * ":execute expr1 ..." execute the result of an expression. 16743 * ":echomsg expr1 ..." Print a message 16744 * ":echoerr expr1 ..." Print an error 16745 * Each gets spaces around each argument and a newline at the end for 16746 * echo commands 16747 */ 16748 void 16749 ex_execute(eap) 16750 exarg_T *eap; 16751 { 16752 char_u *arg = eap->arg; 16753 typval_T rettv; 16754 int ret = OK; 16755 char_u *p; 16756 garray_T ga; 16757 int len; 16758 int save_did_emsg; 16759 16760 ga_init2(&ga, 1, 80); 16761 16762 if (eap->skip) 16763 ++emsg_skip; 16764 while (*arg != NUL && *arg != '|' && *arg != '\n') 16765 { 16766 p = arg; 16767 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16768 { 16769 /* 16770 * Report the invalid expression unless the expression evaluation 16771 * has been cancelled due to an aborting error, an interrupt, or an 16772 * exception. 16773 */ 16774 if (!aborting()) 16775 EMSG2(_(e_invexpr2), p); 16776 ret = FAIL; 16777 break; 16778 } 16779 16780 if (!eap->skip) 16781 { 16782 p = get_tv_string(&rettv); 16783 len = (int)STRLEN(p); 16784 if (ga_grow(&ga, len + 2) == FAIL) 16785 { 16786 clear_tv(&rettv); 16787 ret = FAIL; 16788 break; 16789 } 16790 if (ga.ga_len) 16791 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16792 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16793 ga.ga_len += len; 16794 } 16795 16796 clear_tv(&rettv); 16797 arg = skipwhite(arg); 16798 } 16799 16800 if (ret != FAIL && ga.ga_data != NULL) 16801 { 16802 if (eap->cmdidx == CMD_echomsg) 16803 MSG_ATTR(ga.ga_data, echo_attr); 16804 else if (eap->cmdidx == CMD_echoerr) 16805 { 16806 /* We don't want to abort following commands, restore did_emsg. */ 16807 save_did_emsg = did_emsg; 16808 EMSG((char_u *)ga.ga_data); 16809 if (!force_abort) 16810 did_emsg = save_did_emsg; 16811 } 16812 else if (eap->cmdidx == CMD_execute) 16813 do_cmdline((char_u *)ga.ga_data, 16814 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16815 } 16816 16817 ga_clear(&ga); 16818 16819 if (eap->skip) 16820 --emsg_skip; 16821 16822 eap->nextcmd = check_nextcmd(arg); 16823 } 16824 16825 /* 16826 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16827 * "arg" points to the "&" or '+' when called, to "option" when returning. 16828 * Returns NULL when no option name found. Otherwise pointer to the char 16829 * after the option name. 16830 */ 16831 static char_u * 16832 find_option_end(arg, opt_flags) 16833 char_u **arg; 16834 int *opt_flags; 16835 { 16836 char_u *p = *arg; 16837 16838 ++p; 16839 if (*p == 'g' && p[1] == ':') 16840 { 16841 *opt_flags = OPT_GLOBAL; 16842 p += 2; 16843 } 16844 else if (*p == 'l' && p[1] == ':') 16845 { 16846 *opt_flags = OPT_LOCAL; 16847 p += 2; 16848 } 16849 else 16850 *opt_flags = 0; 16851 16852 if (!ASCII_ISALPHA(*p)) 16853 return NULL; 16854 *arg = p; 16855 16856 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16857 p += 4; /* termcap option */ 16858 else 16859 while (ASCII_ISALPHA(*p)) 16860 ++p; 16861 return p; 16862 } 16863 16864 /* 16865 * ":function" 16866 */ 16867 void 16868 ex_function(eap) 16869 exarg_T *eap; 16870 { 16871 char_u *theline; 16872 int j; 16873 int c; 16874 int saved_did_emsg; 16875 char_u *name = NULL; 16876 char_u *p; 16877 char_u *arg; 16878 garray_T newargs; 16879 garray_T newlines; 16880 int varargs = FALSE; 16881 int mustend = FALSE; 16882 int flags = 0; 16883 ufunc_T *fp; 16884 int indent; 16885 int nesting; 16886 char_u *skip_until = NULL; 16887 dictitem_T *v; 16888 funcdict_T fudi; 16889 static int func_nr = 0; /* number for nameless function */ 16890 int paren; 16891 hashtab_T *ht; 16892 int todo; 16893 hashitem_T *hi; 16894 16895 /* 16896 * ":function" without argument: list functions. 16897 */ 16898 if (ends_excmd(*eap->arg)) 16899 { 16900 if (!eap->skip) 16901 { 16902 todo = func_hashtab.ht_used; 16903 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16904 { 16905 if (!HASHITEM_EMPTY(hi)) 16906 { 16907 --todo; 16908 fp = HI2UF(hi); 16909 if (!isdigit(*fp->uf_name)) 16910 list_func_head(fp, FALSE); 16911 } 16912 } 16913 } 16914 eap->nextcmd = check_nextcmd(eap->arg); 16915 return; 16916 } 16917 16918 /* 16919 * ":function /pat": list functions matching pattern. 16920 */ 16921 if (*eap->arg == '/') 16922 { 16923 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 16924 if (!eap->skip) 16925 { 16926 regmatch_T regmatch; 16927 16928 c = *p; 16929 *p = NUL; 16930 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 16931 *p = c; 16932 if (regmatch.regprog != NULL) 16933 { 16934 regmatch.rm_ic = p_ic; 16935 16936 todo = func_hashtab.ht_used; 16937 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16938 { 16939 if (!HASHITEM_EMPTY(hi)) 16940 { 16941 --todo; 16942 fp = HI2UF(hi); 16943 if (!isdigit(*fp->uf_name) 16944 && vim_regexec(®match, fp->uf_name, 0)) 16945 list_func_head(fp, FALSE); 16946 } 16947 } 16948 } 16949 } 16950 if (*p == '/') 16951 ++p; 16952 eap->nextcmd = check_nextcmd(p); 16953 return; 16954 } 16955 16956 /* 16957 * Get the function name. There are these situations: 16958 * func normal function name 16959 * "name" == func, "fudi.fd_dict" == NULL 16960 * dict.func new dictionary entry 16961 * "name" == NULL, "fudi.fd_dict" set, 16962 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 16963 * dict.func existing dict entry with a Funcref 16964 * "name" == func, "fudi.fd_dict" set, 16965 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16966 * dict.func existing dict entry that's not a Funcref 16967 * "name" == NULL, "fudi.fd_dict" set, 16968 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16969 */ 16970 p = eap->arg; 16971 name = trans_function_name(&p, eap->skip, 0, &fudi); 16972 paren = (vim_strchr(p, '(') != NULL); 16973 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 16974 { 16975 /* 16976 * Return on an invalid expression in braces, unless the expression 16977 * evaluation has been cancelled due to an aborting error, an 16978 * interrupt, or an exception. 16979 */ 16980 if (!aborting()) 16981 { 16982 if (!eap->skip && fudi.fd_newkey != NULL) 16983 EMSG2(_(e_dictkey), fudi.fd_newkey); 16984 vim_free(fudi.fd_newkey); 16985 return; 16986 } 16987 else 16988 eap->skip = TRUE; 16989 } 16990 /* An error in a function call during evaluation of an expression in magic 16991 * braces should not cause the function not to be defined. */ 16992 saved_did_emsg = did_emsg; 16993 did_emsg = FALSE; 16994 16995 /* 16996 * ":function func" with only function name: list function. 16997 */ 16998 if (!paren) 16999 { 17000 if (!ends_excmd(*skipwhite(p))) 17001 { 17002 EMSG(_(e_trailing)); 17003 goto ret_free; 17004 } 17005 eap->nextcmd = check_nextcmd(p); 17006 if (eap->nextcmd != NULL) 17007 *p = NUL; 17008 if (!eap->skip && !got_int) 17009 { 17010 fp = find_func(name); 17011 if (fp != NULL) 17012 { 17013 list_func_head(fp, TRUE); 17014 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 17015 { 17016 msg_putchar('\n'); 17017 msg_outnum((long)(j + 1)); 17018 if (j < 9) 17019 msg_putchar(' '); 17020 if (j < 99) 17021 msg_putchar(' '); 17022 msg_prt_line(FUNCLINE(fp, j), FALSE); 17023 out_flush(); /* show a line at a time */ 17024 ui_breakcheck(); 17025 } 17026 if (!got_int) 17027 { 17028 msg_putchar('\n'); 17029 msg_puts((char_u *)" endfunction"); 17030 } 17031 } 17032 else 17033 emsg_funcname("E123: Undefined function: %s", name); 17034 } 17035 goto ret_free; 17036 } 17037 17038 /* 17039 * ":function name(arg1, arg2)" Define function. 17040 */ 17041 p = skipwhite(p); 17042 if (*p != '(') 17043 { 17044 if (!eap->skip) 17045 { 17046 EMSG2(_("E124: Missing '(': %s"), eap->arg); 17047 goto ret_free; 17048 } 17049 /* attempt to continue by skipping some text */ 17050 if (vim_strchr(p, '(') != NULL) 17051 p = vim_strchr(p, '('); 17052 } 17053 p = skipwhite(p + 1); 17054 17055 ga_init2(&newargs, (int)sizeof(char_u *), 3); 17056 ga_init2(&newlines, (int)sizeof(char_u *), 3); 17057 17058 if (!eap->skip) 17059 { 17060 /* Check the name of the function. */ 17061 if (name != NULL) 17062 arg = name; 17063 else 17064 arg = fudi.fd_newkey; 17065 if (arg != NULL) 17066 { 17067 if (*arg == K_SPECIAL) 17068 j = 3; 17069 else 17070 j = 0; 17071 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 17072 : eval_isnamec(arg[j]))) 17073 ++j; 17074 if (arg[j] != NUL) 17075 emsg_funcname(_(e_invarg2), arg); 17076 } 17077 } 17078 17079 /* 17080 * Isolate the arguments: "arg1, arg2, ...)" 17081 */ 17082 while (*p != ')') 17083 { 17084 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 17085 { 17086 varargs = TRUE; 17087 p += 3; 17088 mustend = TRUE; 17089 } 17090 else 17091 { 17092 arg = p; 17093 while (ASCII_ISALNUM(*p) || *p == '_') 17094 ++p; 17095 if (arg == p || isdigit(*arg) 17096 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 17097 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 17098 { 17099 if (!eap->skip) 17100 EMSG2(_("E125: Illegal argument: %s"), arg); 17101 break; 17102 } 17103 if (ga_grow(&newargs, 1) == FAIL) 17104 goto erret; 17105 c = *p; 17106 *p = NUL; 17107 arg = vim_strsave(arg); 17108 if (arg == NULL) 17109 goto erret; 17110 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 17111 *p = c; 17112 newargs.ga_len++; 17113 if (*p == ',') 17114 ++p; 17115 else 17116 mustend = TRUE; 17117 } 17118 p = skipwhite(p); 17119 if (mustend && *p != ')') 17120 { 17121 if (!eap->skip) 17122 EMSG2(_(e_invarg2), eap->arg); 17123 break; 17124 } 17125 } 17126 ++p; /* skip the ')' */ 17127 17128 /* find extra arguments "range", "dict" and "abort" */ 17129 for (;;) 17130 { 17131 p = skipwhite(p); 17132 if (STRNCMP(p, "range", 5) == 0) 17133 { 17134 flags |= FC_RANGE; 17135 p += 5; 17136 } 17137 else if (STRNCMP(p, "dict", 4) == 0) 17138 { 17139 flags |= FC_DICT; 17140 p += 4; 17141 } 17142 else if (STRNCMP(p, "abort", 5) == 0) 17143 { 17144 flags |= FC_ABORT; 17145 p += 5; 17146 } 17147 else 17148 break; 17149 } 17150 17151 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 17152 EMSG(_(e_trailing)); 17153 17154 /* 17155 * Read the body of the function, until ":endfunction" is found. 17156 */ 17157 if (KeyTyped) 17158 { 17159 /* Check if the function already exists, don't let the user type the 17160 * whole function before telling him it doesn't work! For a script we 17161 * need to skip the body to be able to find what follows. */ 17162 if (!eap->skip && !eap->forceit) 17163 { 17164 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 17165 EMSG(_(e_funcdict)); 17166 else if (name != NULL && find_func(name) != NULL) 17167 emsg_funcname(e_funcexts, name); 17168 } 17169 17170 if (!eap->skip && did_emsg) 17171 goto erret; 17172 17173 msg_putchar('\n'); /* don't overwrite the function name */ 17174 cmdline_row = msg_row; 17175 } 17176 17177 indent = 2; 17178 nesting = 0; 17179 for (;;) 17180 { 17181 msg_scroll = TRUE; 17182 need_wait_return = FALSE; 17183 if (eap->getline == NULL) 17184 theline = getcmdline(':', 0L, indent); 17185 else 17186 theline = eap->getline(':', eap->cookie, indent); 17187 if (KeyTyped) 17188 lines_left = Rows - 1; 17189 if (theline == NULL) 17190 { 17191 EMSG(_("E126: Missing :endfunction")); 17192 goto erret; 17193 } 17194 17195 if (skip_until != NULL) 17196 { 17197 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17198 * don't check for ":endfunc". */ 17199 if (STRCMP(theline, skip_until) == 0) 17200 { 17201 vim_free(skip_until); 17202 skip_until = NULL; 17203 } 17204 } 17205 else 17206 { 17207 /* skip ':' and blanks*/ 17208 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17209 ; 17210 17211 /* Check for "endfunction". */ 17212 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17213 { 17214 vim_free(theline); 17215 break; 17216 } 17217 17218 /* Increase indent inside "if", "while", "for" and "try", decrease 17219 * at "end". */ 17220 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17221 indent -= 2; 17222 else if (STRNCMP(p, "if", 2) == 0 17223 || STRNCMP(p, "wh", 2) == 0 17224 || STRNCMP(p, "for", 3) == 0 17225 || STRNCMP(p, "try", 3) == 0) 17226 indent += 2; 17227 17228 /* Check for defining a function inside this function. */ 17229 if (checkforcmd(&p, "function", 2)) 17230 { 17231 if (*p == '!') 17232 p = skipwhite(p + 1); 17233 p += eval_fname_script(p); 17234 if (ASCII_ISALPHA(*p)) 17235 { 17236 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17237 if (*skipwhite(p) == '(') 17238 { 17239 ++nesting; 17240 indent += 2; 17241 } 17242 } 17243 } 17244 17245 /* Check for ":append" or ":insert". */ 17246 p = skip_range(p, NULL); 17247 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17248 || (p[0] == 'i' 17249 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17250 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17251 skip_until = vim_strsave((char_u *)"."); 17252 17253 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17254 arg = skipwhite(skiptowhite(p)); 17255 if (arg[0] == '<' && arg[1] =='<' 17256 && ((p[0] == 'p' && p[1] == 'y' 17257 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17258 || (p[0] == 'p' && p[1] == 'e' 17259 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17260 || (p[0] == 't' && p[1] == 'c' 17261 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17262 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17263 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17264 || (p[0] == 'm' && p[1] == 'z' 17265 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17266 )) 17267 { 17268 /* ":python <<" continues until a dot, like ":append" */ 17269 p = skipwhite(arg + 2); 17270 if (*p == NUL) 17271 skip_until = vim_strsave((char_u *)"."); 17272 else 17273 skip_until = vim_strsave(p); 17274 } 17275 } 17276 17277 /* Add the line to the function. */ 17278 if (ga_grow(&newlines, 1) == FAIL) 17279 { 17280 vim_free(theline); 17281 goto erret; 17282 } 17283 17284 /* Copy the line to newly allocated memory. get_one_sourceline() 17285 * allocates 250 bytes per line, this saves 80% on average. The cost 17286 * is an extra alloc/free. */ 17287 p = vim_strsave(theline); 17288 if (p != NULL) 17289 { 17290 vim_free(theline); 17291 theline = p; 17292 } 17293 17294 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17295 newlines.ga_len++; 17296 } 17297 17298 /* Don't define the function when skipping commands or when an error was 17299 * detected. */ 17300 if (eap->skip || did_emsg) 17301 goto erret; 17302 17303 /* 17304 * If there are no errors, add the function 17305 */ 17306 if (fudi.fd_dict == NULL) 17307 { 17308 v = find_var(name, &ht); 17309 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17310 { 17311 emsg_funcname("E707: Function name conflicts with variable: %s", 17312 name); 17313 goto erret; 17314 } 17315 17316 fp = find_func(name); 17317 if (fp != NULL) 17318 { 17319 if (!eap->forceit) 17320 { 17321 emsg_funcname(e_funcexts, name); 17322 goto erret; 17323 } 17324 if (fp->uf_calls > 0) 17325 { 17326 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17327 name); 17328 goto erret; 17329 } 17330 /* redefine existing function */ 17331 ga_clear_strings(&(fp->uf_args)); 17332 ga_clear_strings(&(fp->uf_lines)); 17333 vim_free(name); 17334 name = NULL; 17335 } 17336 } 17337 else 17338 { 17339 char numbuf[20]; 17340 17341 fp = NULL; 17342 if (fudi.fd_newkey == NULL && !eap->forceit) 17343 { 17344 EMSG(_(e_funcdict)); 17345 goto erret; 17346 } 17347 if (fudi.fd_di == NULL) 17348 { 17349 /* Can't add a function to a locked dictionary */ 17350 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17351 goto erret; 17352 } 17353 /* Can't change an existing function if it is locked */ 17354 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17355 goto erret; 17356 17357 /* Give the function a sequential number. Can only be used with a 17358 * Funcref! */ 17359 vim_free(name); 17360 sprintf(numbuf, "%d", ++func_nr); 17361 name = vim_strsave((char_u *)numbuf); 17362 if (name == NULL) 17363 goto erret; 17364 } 17365 17366 if (fp == NULL) 17367 { 17368 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17369 { 17370 int slen, plen; 17371 char_u *scriptname; 17372 17373 /* Check that the autoload name matches the script name. */ 17374 j = FAIL; 17375 if (sourcing_name != NULL) 17376 { 17377 scriptname = autoload_name(name); 17378 if (scriptname != NULL) 17379 { 17380 p = vim_strchr(scriptname, '/'); 17381 plen = STRLEN(p); 17382 slen = STRLEN(sourcing_name); 17383 if (slen > plen && fnamecmp(p, 17384 sourcing_name + slen - plen) == 0) 17385 j = OK; 17386 vim_free(scriptname); 17387 } 17388 } 17389 if (j == FAIL) 17390 { 17391 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17392 goto erret; 17393 } 17394 } 17395 17396 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17397 if (fp == NULL) 17398 goto erret; 17399 17400 if (fudi.fd_dict != NULL) 17401 { 17402 if (fudi.fd_di == NULL) 17403 { 17404 /* add new dict entry */ 17405 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17406 if (fudi.fd_di == NULL) 17407 { 17408 vim_free(fp); 17409 goto erret; 17410 } 17411 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17412 { 17413 vim_free(fudi.fd_di); 17414 goto erret; 17415 } 17416 } 17417 else 17418 /* overwrite existing dict entry */ 17419 clear_tv(&fudi.fd_di->di_tv); 17420 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17421 fudi.fd_di->di_tv.v_lock = 0; 17422 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17423 fp->uf_refcount = 1; 17424 } 17425 17426 /* insert the new function in the function list */ 17427 STRCPY(fp->uf_name, name); 17428 hash_add(&func_hashtab, UF2HIKEY(fp)); 17429 } 17430 fp->uf_args = newargs; 17431 fp->uf_lines = newlines; 17432 #ifdef FEAT_PROFILE 17433 fp->uf_tml_count = NULL; 17434 fp->uf_tml_total = NULL; 17435 fp->uf_tml_self = NULL; 17436 fp->uf_profiling = FALSE; 17437 if (prof_def_func()) 17438 func_do_profile(fp); 17439 #endif 17440 fp->uf_varargs = varargs; 17441 fp->uf_flags = flags; 17442 fp->uf_calls = 0; 17443 fp->uf_script_ID = current_SID; 17444 goto ret_free; 17445 17446 erret: 17447 ga_clear_strings(&newargs); 17448 ga_clear_strings(&newlines); 17449 ret_free: 17450 vim_free(skip_until); 17451 vim_free(fudi.fd_newkey); 17452 vim_free(name); 17453 did_emsg |= saved_did_emsg; 17454 } 17455 17456 /* 17457 * Get a function name, translating "<SID>" and "<SNR>". 17458 * Also handles a Funcref in a List or Dictionary. 17459 * Returns the function name in allocated memory, or NULL for failure. 17460 * flags: 17461 * TFN_INT: internal function name OK 17462 * TFN_QUIET: be quiet 17463 * Advances "pp" to just after the function name (if no error). 17464 */ 17465 static char_u * 17466 trans_function_name(pp, skip, flags, fdp) 17467 char_u **pp; 17468 int skip; /* only find the end, don't evaluate */ 17469 int flags; 17470 funcdict_T *fdp; /* return: info about dictionary used */ 17471 { 17472 char_u *name = NULL; 17473 char_u *start; 17474 char_u *end; 17475 int lead; 17476 char_u sid_buf[20]; 17477 int len; 17478 lval_T lv; 17479 17480 if (fdp != NULL) 17481 vim_memset(fdp, 0, sizeof(funcdict_T)); 17482 start = *pp; 17483 17484 /* Check for hard coded <SNR>: already translated function ID (from a user 17485 * command). */ 17486 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17487 && (*pp)[2] == (int)KE_SNR) 17488 { 17489 *pp += 3; 17490 len = get_id_len(pp) + 3; 17491 return vim_strnsave(start, len); 17492 } 17493 17494 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17495 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17496 lead = eval_fname_script(start); 17497 if (lead > 2) 17498 start += lead; 17499 17500 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17501 lead > 2 ? 0 : FNE_CHECK_START); 17502 if (end == start) 17503 { 17504 if (!skip) 17505 EMSG(_("E129: Function name required")); 17506 goto theend; 17507 } 17508 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17509 { 17510 /* 17511 * Report an invalid expression in braces, unless the expression 17512 * evaluation has been cancelled due to an aborting error, an 17513 * interrupt, or an exception. 17514 */ 17515 if (!aborting()) 17516 { 17517 if (end != NULL) 17518 EMSG2(_(e_invarg2), start); 17519 } 17520 else 17521 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17522 goto theend; 17523 } 17524 17525 if (lv.ll_tv != NULL) 17526 { 17527 if (fdp != NULL) 17528 { 17529 fdp->fd_dict = lv.ll_dict; 17530 fdp->fd_newkey = lv.ll_newkey; 17531 lv.ll_newkey = NULL; 17532 fdp->fd_di = lv.ll_di; 17533 } 17534 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17535 { 17536 name = vim_strsave(lv.ll_tv->vval.v_string); 17537 *pp = end; 17538 } 17539 else 17540 { 17541 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17542 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17543 EMSG(_(e_funcref)); 17544 else 17545 *pp = end; 17546 name = NULL; 17547 } 17548 goto theend; 17549 } 17550 17551 if (lv.ll_name == NULL) 17552 { 17553 /* Error found, but continue after the function name. */ 17554 *pp = end; 17555 goto theend; 17556 } 17557 17558 if (lv.ll_exp_name != NULL) 17559 len = STRLEN(lv.ll_exp_name); 17560 else 17561 { 17562 if (lead == 2) /* skip over "s:" */ 17563 lv.ll_name += 2; 17564 len = (int)(end - lv.ll_name); 17565 } 17566 17567 /* 17568 * Copy the function name to allocated memory. 17569 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17570 * Accept <SNR>123_name() outside a script. 17571 */ 17572 if (skip) 17573 lead = 0; /* do nothing */ 17574 else if (lead > 0) 17575 { 17576 lead = 3; 17577 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17578 { 17579 if (current_SID <= 0) 17580 { 17581 EMSG(_(e_usingsid)); 17582 goto theend; 17583 } 17584 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17585 lead += (int)STRLEN(sid_buf); 17586 } 17587 } 17588 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17589 { 17590 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17591 goto theend; 17592 } 17593 name = alloc((unsigned)(len + lead + 1)); 17594 if (name != NULL) 17595 { 17596 if (lead > 0) 17597 { 17598 name[0] = K_SPECIAL; 17599 name[1] = KS_EXTRA; 17600 name[2] = (int)KE_SNR; 17601 if (lead > 3) /* If it's "<SID>" */ 17602 STRCPY(name + 3, sid_buf); 17603 } 17604 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17605 name[len + lead] = NUL; 17606 } 17607 *pp = end; 17608 17609 theend: 17610 clear_lval(&lv); 17611 return name; 17612 } 17613 17614 /* 17615 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17616 * Return 2 if "p" starts with "s:". 17617 * Return 0 otherwise. 17618 */ 17619 static int 17620 eval_fname_script(p) 17621 char_u *p; 17622 { 17623 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17624 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17625 return 5; 17626 if (p[0] == 's' && p[1] == ':') 17627 return 2; 17628 return 0; 17629 } 17630 17631 /* 17632 * Return TRUE if "p" starts with "<SID>" or "s:". 17633 * Only works if eval_fname_script() returned non-zero for "p"! 17634 */ 17635 static int 17636 eval_fname_sid(p) 17637 char_u *p; 17638 { 17639 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17640 } 17641 17642 /* 17643 * List the head of the function: "name(arg1, arg2)". 17644 */ 17645 static void 17646 list_func_head(fp, indent) 17647 ufunc_T *fp; 17648 int indent; 17649 { 17650 int j; 17651 17652 msg_start(); 17653 if (indent) 17654 MSG_PUTS(" "); 17655 MSG_PUTS("function "); 17656 if (fp->uf_name[0] == K_SPECIAL) 17657 { 17658 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17659 msg_puts(fp->uf_name + 3); 17660 } 17661 else 17662 msg_puts(fp->uf_name); 17663 msg_putchar('('); 17664 for (j = 0; j < fp->uf_args.ga_len; ++j) 17665 { 17666 if (j) 17667 MSG_PUTS(", "); 17668 msg_puts(FUNCARG(fp, j)); 17669 } 17670 if (fp->uf_varargs) 17671 { 17672 if (j) 17673 MSG_PUTS(", "); 17674 MSG_PUTS("..."); 17675 } 17676 msg_putchar(')'); 17677 msg_clr_eos(); 17678 #ifdef FEAT_EVAL 17679 if (p_verbose > 0) 17680 last_set_msg(fp->uf_script_ID); 17681 #endif 17682 } 17683 17684 /* 17685 * Find a function by name, return pointer to it in ufuncs. 17686 * Return NULL for unknown function. 17687 */ 17688 static ufunc_T * 17689 find_func(name) 17690 char_u *name; 17691 { 17692 hashitem_T *hi; 17693 17694 hi = hash_find(&func_hashtab, name); 17695 if (!HASHITEM_EMPTY(hi)) 17696 return HI2UF(hi); 17697 return NULL; 17698 } 17699 17700 #if defined(EXITFREE) || defined(PROTO) 17701 void 17702 free_all_functions() 17703 { 17704 hashitem_T *hi; 17705 17706 /* Need to start all over every time, because func_free() may change the 17707 * hash table. */ 17708 while (func_hashtab.ht_used > 0) 17709 for (hi = func_hashtab.ht_array; ; ++hi) 17710 if (!HASHITEM_EMPTY(hi)) 17711 { 17712 func_free(HI2UF(hi)); 17713 break; 17714 } 17715 } 17716 #endif 17717 17718 /* 17719 * Return TRUE if a function "name" exists. 17720 */ 17721 static int 17722 function_exists(name) 17723 char_u *name; 17724 { 17725 char_u *p = name; 17726 int n = FALSE; 17727 17728 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17729 if (p != NULL) 17730 { 17731 if (builtin_function(p)) 17732 n = (find_internal_func(p) >= 0); 17733 else 17734 n = (find_func(p) != NULL); 17735 vim_free(p); 17736 } 17737 return n; 17738 } 17739 17740 /* 17741 * Return TRUE if "name" looks like a builtin function name: starts with a 17742 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17743 */ 17744 static int 17745 builtin_function(name) 17746 char_u *name; 17747 { 17748 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17749 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17750 } 17751 17752 #if defined(FEAT_PROFILE) || defined(PROTO) 17753 /* 17754 * Start profiling function "fp". 17755 */ 17756 static void 17757 func_do_profile(fp) 17758 ufunc_T *fp; 17759 { 17760 fp->uf_tm_count = 0; 17761 profile_zero(&fp->uf_tm_self); 17762 profile_zero(&fp->uf_tm_total); 17763 if (fp->uf_tml_count == NULL) 17764 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17765 (sizeof(int) * fp->uf_lines.ga_len)); 17766 if (fp->uf_tml_total == NULL) 17767 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17768 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17769 if (fp->uf_tml_self == NULL) 17770 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17771 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17772 fp->uf_tml_idx = -1; 17773 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17774 || fp->uf_tml_self == NULL) 17775 return; /* out of memory */ 17776 17777 fp->uf_profiling = TRUE; 17778 } 17779 17780 /* 17781 * Dump the profiling results for all functions in file "fd". 17782 */ 17783 void 17784 func_dump_profile(fd) 17785 FILE *fd; 17786 { 17787 hashitem_T *hi; 17788 int todo; 17789 ufunc_T *fp; 17790 int i; 17791 ufunc_T **sorttab; 17792 int st_len = 0; 17793 17794 todo = func_hashtab.ht_used; 17795 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17796 17797 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17798 { 17799 if (!HASHITEM_EMPTY(hi)) 17800 { 17801 --todo; 17802 fp = HI2UF(hi); 17803 if (fp->uf_profiling) 17804 { 17805 if (sorttab != NULL) 17806 sorttab[st_len++] = fp; 17807 17808 if (fp->uf_name[0] == K_SPECIAL) 17809 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17810 else 17811 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17812 if (fp->uf_tm_count == 1) 17813 fprintf(fd, "Called 1 time\n"); 17814 else 17815 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17816 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17817 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17818 fprintf(fd, "\n"); 17819 fprintf(fd, "count total (s) self (s)\n"); 17820 17821 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17822 { 17823 prof_func_line(fd, fp->uf_tml_count[i], 17824 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17825 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17826 } 17827 fprintf(fd, "\n"); 17828 } 17829 } 17830 } 17831 17832 if (sorttab != NULL && st_len > 0) 17833 { 17834 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17835 prof_total_cmp); 17836 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17837 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17838 prof_self_cmp); 17839 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17840 } 17841 } 17842 17843 static void 17844 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17845 FILE *fd; 17846 ufunc_T **sorttab; 17847 int st_len; 17848 char *title; 17849 int prefer_self; /* when equal print only self time */ 17850 { 17851 int i; 17852 ufunc_T *fp; 17853 17854 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17855 fprintf(fd, "count total (s) self (s) function\n"); 17856 for (i = 0; i < 20 && i < st_len; ++i) 17857 { 17858 fp = sorttab[i]; 17859 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17860 prefer_self); 17861 if (fp->uf_name[0] == K_SPECIAL) 17862 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17863 else 17864 fprintf(fd, " %s()\n", fp->uf_name); 17865 } 17866 fprintf(fd, "\n"); 17867 } 17868 17869 /* 17870 * Print the count and times for one function or function line. 17871 */ 17872 static void 17873 prof_func_line(fd, count, total, self, prefer_self) 17874 FILE *fd; 17875 int count; 17876 proftime_T *total; 17877 proftime_T *self; 17878 int prefer_self; /* when equal print only self time */ 17879 { 17880 if (count > 0) 17881 { 17882 fprintf(fd, "%5d ", count); 17883 if (prefer_self && profile_equal(total, self)) 17884 fprintf(fd, " "); 17885 else 17886 fprintf(fd, "%s ", profile_msg(total)); 17887 if (!prefer_self && profile_equal(total, self)) 17888 fprintf(fd, " "); 17889 else 17890 fprintf(fd, "%s ", profile_msg(self)); 17891 } 17892 else 17893 fprintf(fd, " "); 17894 } 17895 17896 /* 17897 * Compare function for total time sorting. 17898 */ 17899 static int 17900 #ifdef __BORLANDC__ 17901 _RTLENTRYF 17902 #endif 17903 prof_total_cmp(s1, s2) 17904 const void *s1; 17905 const void *s2; 17906 { 17907 ufunc_T *p1, *p2; 17908 17909 p1 = *(ufunc_T **)s1; 17910 p2 = *(ufunc_T **)s2; 17911 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 17912 } 17913 17914 /* 17915 * Compare function for self time sorting. 17916 */ 17917 static int 17918 #ifdef __BORLANDC__ 17919 _RTLENTRYF 17920 #endif 17921 prof_self_cmp(s1, s2) 17922 const void *s1; 17923 const void *s2; 17924 { 17925 ufunc_T *p1, *p2; 17926 17927 p1 = *(ufunc_T **)s1; 17928 p2 = *(ufunc_T **)s2; 17929 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 17930 } 17931 17932 #endif 17933 17934 /* The names of packages that once were loaded is remembered. */ 17935 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 17936 17937 /* 17938 * If "name" has a package name try autoloading the script for it. 17939 * Return TRUE if a package was loaded. 17940 */ 17941 static int 17942 script_autoload(name, reload) 17943 char_u *name; 17944 int reload; /* load script again when already loaded */ 17945 { 17946 char_u *p; 17947 char_u *scriptname, *tofree; 17948 int ret = FALSE; 17949 int i; 17950 17951 /* If there is no '#' after name[0] there is no package name. */ 17952 p = vim_strchr(name, AUTOLOAD_CHAR); 17953 if (p == NULL || p == name) 17954 return FALSE; 17955 17956 tofree = scriptname = autoload_name(name); 17957 17958 /* Find the name in the list of previously loaded package names. Skip 17959 * "autoload/", it's always the same. */ 17960 for (i = 0; i < ga_loaded.ga_len; ++i) 17961 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 17962 break; 17963 if (!reload && i < ga_loaded.ga_len) 17964 ret = FALSE; /* was loaded already */ 17965 else 17966 { 17967 /* Remember the name if it wasn't loaded already. */ 17968 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 17969 { 17970 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 17971 tofree = NULL; 17972 } 17973 17974 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 17975 if (source_runtime(scriptname, FALSE) == OK) 17976 ret = TRUE; 17977 } 17978 17979 vim_free(tofree); 17980 return ret; 17981 } 17982 17983 /* 17984 * Return the autoload script name for a function or variable name. 17985 * Returns NULL when out of memory. 17986 */ 17987 static char_u * 17988 autoload_name(name) 17989 char_u *name; 17990 { 17991 char_u *p; 17992 char_u *scriptname; 17993 17994 /* Get the script file name: replace '#' with '/', append ".vim". */ 17995 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 17996 if (scriptname == NULL) 17997 return FALSE; 17998 STRCPY(scriptname, "autoload/"); 17999 STRCAT(scriptname, name); 18000 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 18001 STRCAT(scriptname, ".vim"); 18002 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 18003 *p = '/'; 18004 return scriptname; 18005 } 18006 18007 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 18008 18009 /* 18010 * Function given to ExpandGeneric() to obtain the list of user defined 18011 * function names. 18012 */ 18013 char_u * 18014 get_user_func_name(xp, idx) 18015 expand_T *xp; 18016 int idx; 18017 { 18018 static long_u done; 18019 static hashitem_T *hi; 18020 ufunc_T *fp; 18021 18022 if (idx == 0) 18023 { 18024 done = 0; 18025 hi = func_hashtab.ht_array; 18026 } 18027 if (done < func_hashtab.ht_used) 18028 { 18029 if (done++ > 0) 18030 ++hi; 18031 while (HASHITEM_EMPTY(hi)) 18032 ++hi; 18033 fp = HI2UF(hi); 18034 18035 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 18036 return fp->uf_name; /* prevents overflow */ 18037 18038 cat_func_name(IObuff, fp); 18039 if (xp->xp_context != EXPAND_USER_FUNC) 18040 { 18041 STRCAT(IObuff, "("); 18042 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 18043 STRCAT(IObuff, ")"); 18044 } 18045 return IObuff; 18046 } 18047 return NULL; 18048 } 18049 18050 #endif /* FEAT_CMDL_COMPL */ 18051 18052 /* 18053 * Copy the function name of "fp" to buffer "buf". 18054 * "buf" must be able to hold the function name plus three bytes. 18055 * Takes care of script-local function names. 18056 */ 18057 static void 18058 cat_func_name(buf, fp) 18059 char_u *buf; 18060 ufunc_T *fp; 18061 { 18062 if (fp->uf_name[0] == K_SPECIAL) 18063 { 18064 STRCPY(buf, "<SNR>"); 18065 STRCAT(buf, fp->uf_name + 3); 18066 } 18067 else 18068 STRCPY(buf, fp->uf_name); 18069 } 18070 18071 /* 18072 * ":delfunction {name}" 18073 */ 18074 void 18075 ex_delfunction(eap) 18076 exarg_T *eap; 18077 { 18078 ufunc_T *fp = NULL; 18079 char_u *p; 18080 char_u *name; 18081 funcdict_T fudi; 18082 18083 p = eap->arg; 18084 name = trans_function_name(&p, eap->skip, 0, &fudi); 18085 vim_free(fudi.fd_newkey); 18086 if (name == NULL) 18087 { 18088 if (fudi.fd_dict != NULL && !eap->skip) 18089 EMSG(_(e_funcref)); 18090 return; 18091 } 18092 if (!ends_excmd(*skipwhite(p))) 18093 { 18094 vim_free(name); 18095 EMSG(_(e_trailing)); 18096 return; 18097 } 18098 eap->nextcmd = check_nextcmd(p); 18099 if (eap->nextcmd != NULL) 18100 *p = NUL; 18101 18102 if (!eap->skip) 18103 fp = find_func(name); 18104 vim_free(name); 18105 18106 if (!eap->skip) 18107 { 18108 if (fp == NULL) 18109 { 18110 EMSG2(_(e_nofunc), eap->arg); 18111 return; 18112 } 18113 if (fp->uf_calls > 0) 18114 { 18115 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 18116 return; 18117 } 18118 18119 if (fudi.fd_dict != NULL) 18120 { 18121 /* Delete the dict item that refers to the function, it will 18122 * invoke func_unref() and possibly delete the function. */ 18123 dictitem_remove(fudi.fd_dict, fudi.fd_di); 18124 } 18125 else 18126 func_free(fp); 18127 } 18128 } 18129 18130 /* 18131 * Free a function and remove it from the list of functions. 18132 */ 18133 static void 18134 func_free(fp) 18135 ufunc_T *fp; 18136 { 18137 hashitem_T *hi; 18138 18139 /* clear this function */ 18140 ga_clear_strings(&(fp->uf_args)); 18141 ga_clear_strings(&(fp->uf_lines)); 18142 #ifdef FEAT_PROFILE 18143 vim_free(fp->uf_tml_count); 18144 vim_free(fp->uf_tml_total); 18145 vim_free(fp->uf_tml_self); 18146 #endif 18147 18148 /* remove the function from the function hashtable */ 18149 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 18150 if (HASHITEM_EMPTY(hi)) 18151 EMSG2(_(e_intern2), "func_free()"); 18152 else 18153 hash_remove(&func_hashtab, hi); 18154 18155 vim_free(fp); 18156 } 18157 18158 /* 18159 * Unreference a Function: decrement the reference count and free it when it 18160 * becomes zero. Only for numbered functions. 18161 */ 18162 static void 18163 func_unref(name) 18164 char_u *name; 18165 { 18166 ufunc_T *fp; 18167 18168 if (name != NULL && isdigit(*name)) 18169 { 18170 fp = find_func(name); 18171 if (fp == NULL) 18172 EMSG2(_(e_intern2), "func_unref()"); 18173 else if (--fp->uf_refcount <= 0) 18174 { 18175 /* Only delete it when it's not being used. Otherwise it's done 18176 * when "uf_calls" becomes zero. */ 18177 if (fp->uf_calls == 0) 18178 func_free(fp); 18179 } 18180 } 18181 } 18182 18183 /* 18184 * Count a reference to a Function. 18185 */ 18186 static void 18187 func_ref(name) 18188 char_u *name; 18189 { 18190 ufunc_T *fp; 18191 18192 if (name != NULL && isdigit(*name)) 18193 { 18194 fp = find_func(name); 18195 if (fp == NULL) 18196 EMSG2(_(e_intern2), "func_ref()"); 18197 else 18198 ++fp->uf_refcount; 18199 } 18200 } 18201 18202 /* 18203 * Call a user function. 18204 */ 18205 static void 18206 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18207 ufunc_T *fp; /* pointer to function */ 18208 int argcount; /* nr of args */ 18209 typval_T *argvars; /* arguments */ 18210 typval_T *rettv; /* return value */ 18211 linenr_T firstline; /* first line of range */ 18212 linenr_T lastline; /* last line of range */ 18213 dict_T *selfdict; /* Dictionary for "self" */ 18214 { 18215 char_u *save_sourcing_name; 18216 linenr_T save_sourcing_lnum; 18217 scid_T save_current_SID; 18218 funccall_T fc; 18219 int save_did_emsg; 18220 static int depth = 0; 18221 dictitem_T *v; 18222 int fixvar_idx = 0; /* index in fixvar[] */ 18223 int i; 18224 int ai; 18225 char_u numbuf[NUMBUFLEN]; 18226 char_u *name; 18227 #ifdef FEAT_PROFILE 18228 proftime_T wait_start; 18229 #endif 18230 18231 /* If depth of calling is getting too high, don't execute the function */ 18232 if (depth >= p_mfd) 18233 { 18234 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18235 rettv->v_type = VAR_NUMBER; 18236 rettv->vval.v_number = -1; 18237 return; 18238 } 18239 ++depth; 18240 18241 line_breakcheck(); /* check for CTRL-C hit */ 18242 18243 fc.caller = current_funccal; 18244 current_funccal = &fc; 18245 fc.func = fp; 18246 fc.rettv = rettv; 18247 rettv->vval.v_number = 0; 18248 fc.linenr = 0; 18249 fc.returned = FALSE; 18250 fc.level = ex_nesting_level; 18251 /* Check if this function has a breakpoint. */ 18252 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18253 fc.dbg_tick = debug_tick; 18254 18255 /* 18256 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18257 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18258 * each argument variable and saves a lot of time. 18259 */ 18260 /* 18261 * Init l: variables. 18262 */ 18263 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18264 if (selfdict != NULL) 18265 { 18266 /* Set l:self to "selfdict". */ 18267 v = &fc.fixvar[fixvar_idx++].var; 18268 STRCPY(v->di_key, "self"); 18269 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18270 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18271 v->di_tv.v_type = VAR_DICT; 18272 v->di_tv.v_lock = 0; 18273 v->di_tv.vval.v_dict = selfdict; 18274 ++selfdict->dv_refcount; 18275 } 18276 18277 /* 18278 * Init a: variables. 18279 * Set a:0 to "argcount". 18280 * Set a:000 to a list with room for the "..." arguments. 18281 */ 18282 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18283 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18284 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18285 v = &fc.fixvar[fixvar_idx++].var; 18286 STRCPY(v->di_key, "000"); 18287 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18288 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18289 v->di_tv.v_type = VAR_LIST; 18290 v->di_tv.v_lock = VAR_FIXED; 18291 v->di_tv.vval.v_list = &fc.l_varlist; 18292 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18293 fc.l_varlist.lv_refcount = 99999; 18294 18295 /* 18296 * Set a:firstline to "firstline" and a:lastline to "lastline". 18297 * Set a:name to named arguments. 18298 * Set a:N to the "..." arguments. 18299 */ 18300 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18301 (varnumber_T)firstline); 18302 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18303 (varnumber_T)lastline); 18304 for (i = 0; i < argcount; ++i) 18305 { 18306 ai = i - fp->uf_args.ga_len; 18307 if (ai < 0) 18308 /* named argument a:name */ 18309 name = FUNCARG(fp, i); 18310 else 18311 { 18312 /* "..." argument a:1, a:2, etc. */ 18313 sprintf((char *)numbuf, "%d", ai + 1); 18314 name = numbuf; 18315 } 18316 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18317 { 18318 v = &fc.fixvar[fixvar_idx++].var; 18319 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18320 } 18321 else 18322 { 18323 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18324 + STRLEN(name))); 18325 if (v == NULL) 18326 break; 18327 v->di_flags = DI_FLAGS_RO; 18328 } 18329 STRCPY(v->di_key, name); 18330 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18331 18332 /* Note: the values are copied directly to avoid alloc/free. 18333 * "argvars" must have VAR_FIXED for v_lock. */ 18334 v->di_tv = argvars[i]; 18335 v->di_tv.v_lock = VAR_FIXED; 18336 18337 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18338 { 18339 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18340 fc.l_listitems[ai].li_tv = argvars[i]; 18341 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18342 } 18343 } 18344 18345 /* Don't redraw while executing the function. */ 18346 ++RedrawingDisabled; 18347 save_sourcing_name = sourcing_name; 18348 save_sourcing_lnum = sourcing_lnum; 18349 sourcing_lnum = 1; 18350 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18351 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18352 if (sourcing_name != NULL) 18353 { 18354 if (save_sourcing_name != NULL 18355 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18356 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18357 else 18358 STRCPY(sourcing_name, "function "); 18359 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18360 18361 if (p_verbose >= 12) 18362 { 18363 ++no_wait_return; 18364 verbose_enter_scroll(); 18365 18366 smsg((char_u *)_("calling %s"), sourcing_name); 18367 if (p_verbose >= 14) 18368 { 18369 char_u buf[MSG_BUF_LEN]; 18370 char_u numbuf[NUMBUFLEN]; 18371 char_u *tofree; 18372 18373 msg_puts((char_u *)"("); 18374 for (i = 0; i < argcount; ++i) 18375 { 18376 if (i > 0) 18377 msg_puts((char_u *)", "); 18378 if (argvars[i].v_type == VAR_NUMBER) 18379 msg_outnum((long)argvars[i].vval.v_number); 18380 else 18381 { 18382 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18383 buf, MSG_BUF_CLEN); 18384 msg_puts(buf); 18385 vim_free(tofree); 18386 } 18387 } 18388 msg_puts((char_u *)")"); 18389 } 18390 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18391 18392 verbose_leave_scroll(); 18393 --no_wait_return; 18394 } 18395 } 18396 #ifdef FEAT_PROFILE 18397 if (do_profiling) 18398 { 18399 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18400 func_do_profile(fp); 18401 if (fp->uf_profiling 18402 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18403 { 18404 ++fp->uf_tm_count; 18405 profile_start(&fp->uf_tm_start); 18406 profile_zero(&fp->uf_tm_children); 18407 } 18408 script_prof_save(&wait_start); 18409 } 18410 #endif 18411 18412 save_current_SID = current_SID; 18413 current_SID = fp->uf_script_ID; 18414 save_did_emsg = did_emsg; 18415 did_emsg = FALSE; 18416 18417 /* call do_cmdline() to execute the lines */ 18418 do_cmdline(NULL, get_func_line, (void *)&fc, 18419 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18420 18421 --RedrawingDisabled; 18422 18423 /* when the function was aborted because of an error, return -1 */ 18424 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18425 { 18426 clear_tv(rettv); 18427 rettv->v_type = VAR_NUMBER; 18428 rettv->vval.v_number = -1; 18429 } 18430 18431 #ifdef FEAT_PROFILE 18432 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18433 { 18434 profile_end(&fp->uf_tm_start); 18435 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18436 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18437 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18438 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18439 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18440 { 18441 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18442 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18443 } 18444 } 18445 #endif 18446 18447 /* when being verbose, mention the return value */ 18448 if (p_verbose >= 12) 18449 { 18450 ++no_wait_return; 18451 verbose_enter_scroll(); 18452 18453 if (aborting()) 18454 smsg((char_u *)_("%s aborted"), sourcing_name); 18455 else if (fc.rettv->v_type == VAR_NUMBER) 18456 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18457 (long)fc.rettv->vval.v_number); 18458 else 18459 { 18460 char_u buf[MSG_BUF_LEN]; 18461 char_u numbuf[NUMBUFLEN]; 18462 char_u *tofree; 18463 18464 /* The value may be very long. Skip the middle part, so that we 18465 * have some idea how it starts and ends. smsg() would always 18466 * truncate it at the end. */ 18467 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18468 buf, MSG_BUF_CLEN); 18469 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18470 vim_free(tofree); 18471 } 18472 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18473 18474 verbose_leave_scroll(); 18475 --no_wait_return; 18476 } 18477 18478 vim_free(sourcing_name); 18479 sourcing_name = save_sourcing_name; 18480 sourcing_lnum = save_sourcing_lnum; 18481 current_SID = save_current_SID; 18482 #ifdef FEAT_PROFILE 18483 if (do_profiling) 18484 script_prof_restore(&wait_start); 18485 #endif 18486 18487 if (p_verbose >= 12 && sourcing_name != NULL) 18488 { 18489 ++no_wait_return; 18490 verbose_enter_scroll(); 18491 18492 smsg((char_u *)_("continuing in %s"), sourcing_name); 18493 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18494 18495 verbose_leave_scroll(); 18496 --no_wait_return; 18497 } 18498 18499 did_emsg |= save_did_emsg; 18500 current_funccal = fc.caller; 18501 18502 /* The a: variables typevals were not alloced, only free the allocated 18503 * variables. */ 18504 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18505 18506 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18507 --depth; 18508 } 18509 18510 /* 18511 * Add a number variable "name" to dict "dp" with value "nr". 18512 */ 18513 static void 18514 add_nr_var(dp, v, name, nr) 18515 dict_T *dp; 18516 dictitem_T *v; 18517 char *name; 18518 varnumber_T nr; 18519 { 18520 STRCPY(v->di_key, name); 18521 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18522 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18523 v->di_tv.v_type = VAR_NUMBER; 18524 v->di_tv.v_lock = VAR_FIXED; 18525 v->di_tv.vval.v_number = nr; 18526 } 18527 18528 /* 18529 * ":return [expr]" 18530 */ 18531 void 18532 ex_return(eap) 18533 exarg_T *eap; 18534 { 18535 char_u *arg = eap->arg; 18536 typval_T rettv; 18537 int returning = FALSE; 18538 18539 if (current_funccal == NULL) 18540 { 18541 EMSG(_("E133: :return not inside a function")); 18542 return; 18543 } 18544 18545 if (eap->skip) 18546 ++emsg_skip; 18547 18548 eap->nextcmd = NULL; 18549 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18550 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18551 { 18552 if (!eap->skip) 18553 returning = do_return(eap, FALSE, TRUE, &rettv); 18554 else 18555 clear_tv(&rettv); 18556 } 18557 /* It's safer to return also on error. */ 18558 else if (!eap->skip) 18559 { 18560 /* 18561 * Return unless the expression evaluation has been cancelled due to an 18562 * aborting error, an interrupt, or an exception. 18563 */ 18564 if (!aborting()) 18565 returning = do_return(eap, FALSE, TRUE, NULL); 18566 } 18567 18568 /* When skipping or the return gets pending, advance to the next command 18569 * in this line (!returning). Otherwise, ignore the rest of the line. 18570 * Following lines will be ignored by get_func_line(). */ 18571 if (returning) 18572 eap->nextcmd = NULL; 18573 else if (eap->nextcmd == NULL) /* no argument */ 18574 eap->nextcmd = check_nextcmd(arg); 18575 18576 if (eap->skip) 18577 --emsg_skip; 18578 } 18579 18580 /* 18581 * Return from a function. Possibly makes the return pending. Also called 18582 * for a pending return at the ":endtry" or after returning from an extra 18583 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18584 * when called due to a ":return" command. "rettv" may point to a typval_T 18585 * with the return rettv. Returns TRUE when the return can be carried out, 18586 * FALSE when the return gets pending. 18587 */ 18588 int 18589 do_return(eap, reanimate, is_cmd, rettv) 18590 exarg_T *eap; 18591 int reanimate; 18592 int is_cmd; 18593 void *rettv; 18594 { 18595 int idx; 18596 struct condstack *cstack = eap->cstack; 18597 18598 if (reanimate) 18599 /* Undo the return. */ 18600 current_funccal->returned = FALSE; 18601 18602 /* 18603 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18604 * not in its finally clause (which then is to be executed next) is found. 18605 * In this case, make the ":return" pending for execution at the ":endtry". 18606 * Otherwise, return normally. 18607 */ 18608 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18609 if (idx >= 0) 18610 { 18611 cstack->cs_pending[idx] = CSTP_RETURN; 18612 18613 if (!is_cmd && !reanimate) 18614 /* A pending return again gets pending. "rettv" points to an 18615 * allocated variable with the rettv of the original ":return"'s 18616 * argument if present or is NULL else. */ 18617 cstack->cs_rettv[idx] = rettv; 18618 else 18619 { 18620 /* When undoing a return in order to make it pending, get the stored 18621 * return rettv. */ 18622 if (reanimate) 18623 rettv = current_funccal->rettv; 18624 18625 if (rettv != NULL) 18626 { 18627 /* Store the value of the pending return. */ 18628 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18629 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18630 else 18631 EMSG(_(e_outofmem)); 18632 } 18633 else 18634 cstack->cs_rettv[idx] = NULL; 18635 18636 if (reanimate) 18637 { 18638 /* The pending return value could be overwritten by a ":return" 18639 * without argument in a finally clause; reset the default 18640 * return value. */ 18641 current_funccal->rettv->v_type = VAR_NUMBER; 18642 current_funccal->rettv->vval.v_number = 0; 18643 } 18644 } 18645 report_make_pending(CSTP_RETURN, rettv); 18646 } 18647 else 18648 { 18649 current_funccal->returned = TRUE; 18650 18651 /* If the return is carried out now, store the return value. For 18652 * a return immediately after reanimation, the value is already 18653 * there. */ 18654 if (!reanimate && rettv != NULL) 18655 { 18656 clear_tv(current_funccal->rettv); 18657 *current_funccal->rettv = *(typval_T *)rettv; 18658 if (!is_cmd) 18659 vim_free(rettv); 18660 } 18661 } 18662 18663 return idx < 0; 18664 } 18665 18666 /* 18667 * Free the variable with a pending return value. 18668 */ 18669 void 18670 discard_pending_return(rettv) 18671 void *rettv; 18672 { 18673 free_tv((typval_T *)rettv); 18674 } 18675 18676 /* 18677 * Generate a return command for producing the value of "rettv". The result 18678 * is an allocated string. Used by report_pending() for verbose messages. 18679 */ 18680 char_u * 18681 get_return_cmd(rettv) 18682 void *rettv; 18683 { 18684 char_u *s = NULL; 18685 char_u *tofree = NULL; 18686 char_u numbuf[NUMBUFLEN]; 18687 18688 if (rettv != NULL) 18689 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18690 if (s == NULL) 18691 s = (char_u *)""; 18692 18693 STRCPY(IObuff, ":return "); 18694 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18695 if (STRLEN(s) + 8 >= IOSIZE) 18696 STRCPY(IObuff + IOSIZE - 4, "..."); 18697 vim_free(tofree); 18698 return vim_strsave(IObuff); 18699 } 18700 18701 /* 18702 * Get next function line. 18703 * Called by do_cmdline() to get the next line. 18704 * Returns allocated string, or NULL for end of function. 18705 */ 18706 /* ARGSUSED */ 18707 char_u * 18708 get_func_line(c, cookie, indent) 18709 int c; /* not used */ 18710 void *cookie; 18711 int indent; /* not used */ 18712 { 18713 funccall_T *fcp = (funccall_T *)cookie; 18714 ufunc_T *fp = fcp->func; 18715 char_u *retval; 18716 garray_T *gap; /* growarray with function lines */ 18717 18718 /* If breakpoints have been added/deleted need to check for it. */ 18719 if (fcp->dbg_tick != debug_tick) 18720 { 18721 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18722 sourcing_lnum); 18723 fcp->dbg_tick = debug_tick; 18724 } 18725 #ifdef FEAT_PROFILE 18726 if (do_profiling) 18727 func_line_end(cookie); 18728 #endif 18729 18730 gap = &fp->uf_lines; 18731 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18732 retval = NULL; 18733 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18734 retval = NULL; 18735 else 18736 { 18737 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18738 sourcing_lnum = fcp->linenr; 18739 #ifdef FEAT_PROFILE 18740 if (do_profiling) 18741 func_line_start(cookie); 18742 #endif 18743 } 18744 18745 /* Did we encounter a breakpoint? */ 18746 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18747 { 18748 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18749 /* Find next breakpoint. */ 18750 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18751 sourcing_lnum); 18752 fcp->dbg_tick = debug_tick; 18753 } 18754 18755 return retval; 18756 } 18757 18758 #if defined(FEAT_PROFILE) || defined(PROTO) 18759 /* 18760 * Called when starting to read a function line. 18761 * "sourcing_lnum" must be correct! 18762 * When skipping lines it may not actually be executed, but we won't find out 18763 * until later and we need to store the time now. 18764 */ 18765 void 18766 func_line_start(cookie) 18767 void *cookie; 18768 { 18769 funccall_T *fcp = (funccall_T *)cookie; 18770 ufunc_T *fp = fcp->func; 18771 18772 if (fp->uf_profiling && sourcing_lnum >= 1 18773 && sourcing_lnum <= fp->uf_lines.ga_len) 18774 { 18775 fp->uf_tml_idx = sourcing_lnum - 1; 18776 fp->uf_tml_execed = FALSE; 18777 profile_start(&fp->uf_tml_start); 18778 profile_zero(&fp->uf_tml_children); 18779 profile_get_wait(&fp->uf_tml_wait); 18780 } 18781 } 18782 18783 /* 18784 * Called when actually executing a function line. 18785 */ 18786 void 18787 func_line_exec(cookie) 18788 void *cookie; 18789 { 18790 funccall_T *fcp = (funccall_T *)cookie; 18791 ufunc_T *fp = fcp->func; 18792 18793 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18794 fp->uf_tml_execed = TRUE; 18795 } 18796 18797 /* 18798 * Called when done with a function line. 18799 */ 18800 void 18801 func_line_end(cookie) 18802 void *cookie; 18803 { 18804 funccall_T *fcp = (funccall_T *)cookie; 18805 ufunc_T *fp = fcp->func; 18806 18807 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18808 { 18809 if (fp->uf_tml_execed) 18810 { 18811 ++fp->uf_tml_count[fp->uf_tml_idx]; 18812 profile_end(&fp->uf_tml_start); 18813 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18814 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18815 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18816 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18817 } 18818 fp->uf_tml_idx = -1; 18819 } 18820 } 18821 #endif 18822 18823 /* 18824 * Return TRUE if the currently active function should be ended, because a 18825 * return was encountered or an error occured. Used inside a ":while". 18826 */ 18827 int 18828 func_has_ended(cookie) 18829 void *cookie; 18830 { 18831 funccall_T *fcp = (funccall_T *)cookie; 18832 18833 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18834 * an error inside a try conditional. */ 18835 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18836 || fcp->returned); 18837 } 18838 18839 /* 18840 * return TRUE if cookie indicates a function which "abort"s on errors. 18841 */ 18842 int 18843 func_has_abort(cookie) 18844 void *cookie; 18845 { 18846 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18847 } 18848 18849 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18850 typedef enum 18851 { 18852 VAR_FLAVOUR_DEFAULT, 18853 VAR_FLAVOUR_SESSION, 18854 VAR_FLAVOUR_VIMINFO 18855 } var_flavour_T; 18856 18857 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18858 18859 static var_flavour_T 18860 var_flavour(varname) 18861 char_u *varname; 18862 { 18863 char_u *p = varname; 18864 18865 if (ASCII_ISUPPER(*p)) 18866 { 18867 while (*(++p)) 18868 if (ASCII_ISLOWER(*p)) 18869 return VAR_FLAVOUR_SESSION; 18870 return VAR_FLAVOUR_VIMINFO; 18871 } 18872 else 18873 return VAR_FLAVOUR_DEFAULT; 18874 } 18875 #endif 18876 18877 #if defined(FEAT_VIMINFO) || defined(PROTO) 18878 /* 18879 * Restore global vars that start with a capital from the viminfo file 18880 */ 18881 int 18882 read_viminfo_varlist(virp, writing) 18883 vir_T *virp; 18884 int writing; 18885 { 18886 char_u *tab; 18887 int is_string = FALSE; 18888 typval_T tv; 18889 18890 if (!writing && (find_viminfo_parameter('!') != NULL)) 18891 { 18892 tab = vim_strchr(virp->vir_line + 1, '\t'); 18893 if (tab != NULL) 18894 { 18895 *tab++ = '\0'; /* isolate the variable name */ 18896 if (*tab == 'S') /* string var */ 18897 is_string = TRUE; 18898 18899 tab = vim_strchr(tab, '\t'); 18900 if (tab != NULL) 18901 { 18902 if (is_string) 18903 { 18904 tv.v_type = VAR_STRING; 18905 tv.vval.v_string = viminfo_readstring(virp, 18906 (int)(tab - virp->vir_line + 1), TRUE); 18907 } 18908 else 18909 { 18910 tv.v_type = VAR_NUMBER; 18911 tv.vval.v_number = atol((char *)tab + 1); 18912 } 18913 set_var(virp->vir_line + 1, &tv, FALSE); 18914 if (is_string) 18915 vim_free(tv.vval.v_string); 18916 } 18917 } 18918 } 18919 18920 return viminfo_readline(virp); 18921 } 18922 18923 /* 18924 * Write global vars that start with a capital to the viminfo file 18925 */ 18926 void 18927 write_viminfo_varlist(fp) 18928 FILE *fp; 18929 { 18930 hashitem_T *hi; 18931 dictitem_T *this_var; 18932 int todo; 18933 char *s; 18934 char_u *p; 18935 char_u *tofree; 18936 char_u numbuf[NUMBUFLEN]; 18937 18938 if (find_viminfo_parameter('!') == NULL) 18939 return; 18940 18941 fprintf(fp, _("\n# global variables:\n")); 18942 18943 todo = globvarht.ht_used; 18944 for (hi = globvarht.ht_array; todo > 0; ++hi) 18945 { 18946 if (!HASHITEM_EMPTY(hi)) 18947 { 18948 --todo; 18949 this_var = HI2DI(hi); 18950 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 18951 { 18952 switch (this_var->di_tv.v_type) 18953 { 18954 case VAR_STRING: s = "STR"; break; 18955 case VAR_NUMBER: s = "NUM"; break; 18956 default: continue; 18957 } 18958 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 18959 p = echo_string(&this_var->di_tv, &tofree, numbuf); 18960 if (p != NULL) 18961 viminfo_writestring(fp, p); 18962 vim_free(tofree); 18963 } 18964 } 18965 } 18966 } 18967 #endif 18968 18969 #if defined(FEAT_SESSION) || defined(PROTO) 18970 int 18971 store_session_globals(fd) 18972 FILE *fd; 18973 { 18974 hashitem_T *hi; 18975 dictitem_T *this_var; 18976 int todo; 18977 char_u *p, *t; 18978 18979 todo = globvarht.ht_used; 18980 for (hi = globvarht.ht_array; todo > 0; ++hi) 18981 { 18982 if (!HASHITEM_EMPTY(hi)) 18983 { 18984 --todo; 18985 this_var = HI2DI(hi); 18986 if ((this_var->di_tv.v_type == VAR_NUMBER 18987 || this_var->di_tv.v_type == VAR_STRING) 18988 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 18989 { 18990 /* Escape special characters with a backslash. Turn a LF and 18991 * CR into \n and \r. */ 18992 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 18993 (char_u *)"\\\"\n\r"); 18994 if (p == NULL) /* out of memory */ 18995 break; 18996 for (t = p; *t != NUL; ++t) 18997 if (*t == '\n') 18998 *t = 'n'; 18999 else if (*t == '\r') 19000 *t = 'r'; 19001 if ((fprintf(fd, "let %s = %c%s%c", 19002 this_var->di_key, 19003 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19004 : ' ', 19005 p, 19006 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19007 : ' ') < 0) 19008 || put_eol(fd) == FAIL) 19009 { 19010 vim_free(p); 19011 return FAIL; 19012 } 19013 vim_free(p); 19014 } 19015 } 19016 } 19017 return OK; 19018 } 19019 #endif 19020 19021 /* 19022 * Display script name where an item was last set. 19023 * Should only be invoked when 'verbose' is non-zero. 19024 */ 19025 void 19026 last_set_msg(scriptID) 19027 scid_T scriptID; 19028 { 19029 char_u *p; 19030 19031 if (scriptID != 0) 19032 { 19033 p = home_replace_save(NULL, get_scriptname(scriptID)); 19034 if (p != NULL) 19035 { 19036 verbose_enter(); 19037 MSG_PUTS(_("\n\tLast set from ")); 19038 MSG_PUTS(p); 19039 vim_free(p); 19040 verbose_leave(); 19041 } 19042 } 19043 } 19044 19045 #endif /* FEAT_EVAL */ 19046 19047 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 19048 19049 19050 #ifdef WIN3264 19051 /* 19052 * Functions for ":8" filename modifier: get 8.3 version of a filename. 19053 */ 19054 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19055 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 19056 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19057 19058 /* 19059 * Get the short pathname of a file. 19060 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 19061 */ 19062 static int 19063 get_short_pathname(fnamep, bufp, fnamelen) 19064 char_u **fnamep; 19065 char_u **bufp; 19066 int *fnamelen; 19067 { 19068 int l,len; 19069 char_u *newbuf; 19070 19071 len = *fnamelen; 19072 19073 l = GetShortPathName(*fnamep, *fnamep, len); 19074 if (l > len - 1) 19075 { 19076 /* If that doesn't work (not enough space), then save the string 19077 * and try again with a new buffer big enough 19078 */ 19079 newbuf = vim_strnsave(*fnamep, l); 19080 if (newbuf == NULL) 19081 return 0; 19082 19083 vim_free(*bufp); 19084 *fnamep = *bufp = newbuf; 19085 19086 l = GetShortPathName(*fnamep,*fnamep,l+1); 19087 19088 /* Really should always succeed, as the buffer is big enough */ 19089 } 19090 19091 *fnamelen = l; 19092 return 1; 19093 } 19094 19095 /* 19096 * Create a short path name. Returns the length of the buffer it needs. 19097 * Doesn't copy over the end of the buffer passed in. 19098 */ 19099 static int 19100 shortpath_for_invalid_fname(fname, bufp, fnamelen) 19101 char_u **fname; 19102 char_u **bufp; 19103 int *fnamelen; 19104 { 19105 char_u *s, *p, *pbuf2, *pbuf3; 19106 char_u ch; 19107 int len, len2, plen, slen; 19108 19109 /* Make a copy */ 19110 len2 = *fnamelen; 19111 pbuf2 = vim_strnsave(*fname, len2); 19112 pbuf3 = NULL; 19113 19114 s = pbuf2 + len2 - 1; /* Find the end */ 19115 slen = 1; 19116 plen = len2; 19117 19118 if (after_pathsep(pbuf2, s + 1)) 19119 { 19120 --s; 19121 ++slen; 19122 --plen; 19123 } 19124 19125 do 19126 { 19127 /* Go back one path-seperator */ 19128 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 19129 { 19130 --s; 19131 ++slen; 19132 --plen; 19133 } 19134 if (s <= pbuf2) 19135 break; 19136 19137 /* Remeber the character that is about to be blatted */ 19138 ch = *s; 19139 *s = 0; /* get_short_pathname requires a null-terminated string */ 19140 19141 /* Try it in situ */ 19142 p = pbuf2; 19143 if (!get_short_pathname(&p, &pbuf3, &plen)) 19144 { 19145 vim_free(pbuf2); 19146 return -1; 19147 } 19148 *s = ch; /* Preserve the string */ 19149 } while (plen == 0); 19150 19151 if (plen > 0) 19152 { 19153 /* Remeber the length of the new string. */ 19154 *fnamelen = len = plen + slen; 19155 vim_free(*bufp); 19156 if (len > len2) 19157 { 19158 /* If there's not enough space in the currently allocated string, 19159 * then copy it to a buffer big enough. 19160 */ 19161 *fname= *bufp = vim_strnsave(p, len); 19162 if (*fname == NULL) 19163 return -1; 19164 } 19165 else 19166 { 19167 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 19168 *fname = *bufp = pbuf2; 19169 if (p != pbuf2) 19170 strncpy(*fname, p, plen); 19171 pbuf2 = NULL; 19172 } 19173 /* Concat the next bit */ 19174 strncpy(*fname + plen, s, slen); 19175 (*fname)[len] = '\0'; 19176 } 19177 vim_free(pbuf3); 19178 vim_free(pbuf2); 19179 return 0; 19180 } 19181 19182 /* 19183 * Get a pathname for a partial path. 19184 */ 19185 static int 19186 shortpath_for_partial(fnamep, bufp, fnamelen) 19187 char_u **fnamep; 19188 char_u **bufp; 19189 int *fnamelen; 19190 { 19191 int sepcount, len, tflen; 19192 char_u *p; 19193 char_u *pbuf, *tfname; 19194 int hasTilde; 19195 19196 /* Count up the path seperators from the RHS.. so we know which part 19197 * of the path to return. 19198 */ 19199 sepcount = 0; 19200 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19201 if (vim_ispathsep(*p)) 19202 ++sepcount; 19203 19204 /* Need full path first (use expand_env() to remove a "~/") */ 19205 hasTilde = (**fnamep == '~'); 19206 if (hasTilde) 19207 pbuf = tfname = expand_env_save(*fnamep); 19208 else 19209 pbuf = tfname = FullName_save(*fnamep, FALSE); 19210 19211 len = tflen = STRLEN(tfname); 19212 19213 if (!get_short_pathname(&tfname, &pbuf, &len)) 19214 return -1; 19215 19216 if (len == 0) 19217 { 19218 /* Don't have a valid filename, so shorten the rest of the 19219 * path if we can. This CAN give us invalid 8.3 filenames, but 19220 * there's not a lot of point in guessing what it might be. 19221 */ 19222 len = tflen; 19223 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19224 return -1; 19225 } 19226 19227 /* Count the paths backward to find the beginning of the desired string. */ 19228 for (p = tfname + len - 1; p >= tfname; --p) 19229 { 19230 #ifdef FEAT_MBYTE 19231 if (has_mbyte) 19232 p -= mb_head_off(tfname, p); 19233 #endif 19234 if (vim_ispathsep(*p)) 19235 { 19236 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19237 break; 19238 else 19239 sepcount --; 19240 } 19241 } 19242 if (hasTilde) 19243 { 19244 --p; 19245 if (p >= tfname) 19246 *p = '~'; 19247 else 19248 return -1; 19249 } 19250 else 19251 ++p; 19252 19253 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19254 vim_free(*bufp); 19255 *fnamelen = (int)STRLEN(p); 19256 *bufp = pbuf; 19257 *fnamep = p; 19258 19259 return 0; 19260 } 19261 #endif /* WIN3264 */ 19262 19263 /* 19264 * Adjust a filename, according to a string of modifiers. 19265 * *fnamep must be NUL terminated when called. When returning, the length is 19266 * determined by *fnamelen. 19267 * Returns valid flags. 19268 * When there is an error, *fnamep is set to NULL. 19269 */ 19270 int 19271 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19272 char_u *src; /* string with modifiers */ 19273 int *usedlen; /* characters after src that are used */ 19274 char_u **fnamep; /* file name so far */ 19275 char_u **bufp; /* buffer for allocated file name or NULL */ 19276 int *fnamelen; /* length of fnamep */ 19277 { 19278 int valid = 0; 19279 char_u *tail; 19280 char_u *s, *p, *pbuf; 19281 char_u dirname[MAXPATHL]; 19282 int c; 19283 int has_fullname = 0; 19284 #ifdef WIN3264 19285 int has_shortname = 0; 19286 #endif 19287 19288 repeat: 19289 /* ":p" - full path/file_name */ 19290 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19291 { 19292 has_fullname = 1; 19293 19294 valid |= VALID_PATH; 19295 *usedlen += 2; 19296 19297 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19298 if ((*fnamep)[0] == '~' 19299 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19300 && ((*fnamep)[1] == '/' 19301 # ifdef BACKSLASH_IN_FILENAME 19302 || (*fnamep)[1] == '\\' 19303 # endif 19304 || (*fnamep)[1] == NUL) 19305 19306 #endif 19307 ) 19308 { 19309 *fnamep = expand_env_save(*fnamep); 19310 vim_free(*bufp); /* free any allocated file name */ 19311 *bufp = *fnamep; 19312 if (*fnamep == NULL) 19313 return -1; 19314 } 19315 19316 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19317 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19318 { 19319 if (vim_ispathsep(*p) 19320 && p[1] == '.' 19321 && (p[2] == NUL 19322 || vim_ispathsep(p[2]) 19323 || (p[2] == '.' 19324 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19325 break; 19326 } 19327 19328 /* FullName_save() is slow, don't use it when not needed. */ 19329 if (*p != NUL || !vim_isAbsName(*fnamep)) 19330 { 19331 *fnamep = FullName_save(*fnamep, *p != NUL); 19332 vim_free(*bufp); /* free any allocated file name */ 19333 *bufp = *fnamep; 19334 if (*fnamep == NULL) 19335 return -1; 19336 } 19337 19338 /* Append a path separator to a directory. */ 19339 if (mch_isdir(*fnamep)) 19340 { 19341 /* Make room for one or two extra characters. */ 19342 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19343 vim_free(*bufp); /* free any allocated file name */ 19344 *bufp = *fnamep; 19345 if (*fnamep == NULL) 19346 return -1; 19347 add_pathsep(*fnamep); 19348 } 19349 } 19350 19351 /* ":." - path relative to the current directory */ 19352 /* ":~" - path relative to the home directory */ 19353 /* ":8" - shortname path - postponed till after */ 19354 while (src[*usedlen] == ':' 19355 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19356 { 19357 *usedlen += 2; 19358 if (c == '8') 19359 { 19360 #ifdef WIN3264 19361 has_shortname = 1; /* Postpone this. */ 19362 #endif 19363 continue; 19364 } 19365 pbuf = NULL; 19366 /* Need full path first (use expand_env() to remove a "~/") */ 19367 if (!has_fullname) 19368 { 19369 if (c == '.' && **fnamep == '~') 19370 p = pbuf = expand_env_save(*fnamep); 19371 else 19372 p = pbuf = FullName_save(*fnamep, FALSE); 19373 } 19374 else 19375 p = *fnamep; 19376 19377 has_fullname = 0; 19378 19379 if (p != NULL) 19380 { 19381 if (c == '.') 19382 { 19383 mch_dirname(dirname, MAXPATHL); 19384 s = shorten_fname(p, dirname); 19385 if (s != NULL) 19386 { 19387 *fnamep = s; 19388 if (pbuf != NULL) 19389 { 19390 vim_free(*bufp); /* free any allocated file name */ 19391 *bufp = pbuf; 19392 pbuf = NULL; 19393 } 19394 } 19395 } 19396 else 19397 { 19398 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19399 /* Only replace it when it starts with '~' */ 19400 if (*dirname == '~') 19401 { 19402 s = vim_strsave(dirname); 19403 if (s != NULL) 19404 { 19405 *fnamep = s; 19406 vim_free(*bufp); 19407 *bufp = s; 19408 } 19409 } 19410 } 19411 vim_free(pbuf); 19412 } 19413 } 19414 19415 tail = gettail(*fnamep); 19416 *fnamelen = (int)STRLEN(*fnamep); 19417 19418 /* ":h" - head, remove "/file_name", can be repeated */ 19419 /* Don't remove the first "/" or "c:\" */ 19420 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19421 { 19422 valid |= VALID_HEAD; 19423 *usedlen += 2; 19424 s = get_past_head(*fnamep); 19425 while (tail > s && after_pathsep(s, tail)) 19426 --tail; 19427 *fnamelen = (int)(tail - *fnamep); 19428 #ifdef VMS 19429 if (*fnamelen > 0) 19430 *fnamelen += 1; /* the path separator is part of the path */ 19431 #endif 19432 while (tail > s && !after_pathsep(s, tail)) 19433 mb_ptr_back(*fnamep, tail); 19434 } 19435 19436 /* ":8" - shortname */ 19437 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19438 { 19439 *usedlen += 2; 19440 #ifdef WIN3264 19441 has_shortname = 1; 19442 #endif 19443 } 19444 19445 #ifdef WIN3264 19446 /* Check shortname after we have done 'heads' and before we do 'tails' 19447 */ 19448 if (has_shortname) 19449 { 19450 pbuf = NULL; 19451 /* Copy the string if it is shortened by :h */ 19452 if (*fnamelen < (int)STRLEN(*fnamep)) 19453 { 19454 p = vim_strnsave(*fnamep, *fnamelen); 19455 if (p == 0) 19456 return -1; 19457 vim_free(*bufp); 19458 *bufp = *fnamep = p; 19459 } 19460 19461 /* Split into two implementations - makes it easier. First is where 19462 * there isn't a full name already, second is where there is. 19463 */ 19464 if (!has_fullname && !vim_isAbsName(*fnamep)) 19465 { 19466 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19467 return -1; 19468 } 19469 else 19470 { 19471 int l; 19472 19473 /* Simple case, already have the full-name 19474 * Nearly always shorter, so try first time. */ 19475 l = *fnamelen; 19476 if (!get_short_pathname(fnamep, bufp, &l)) 19477 return -1; 19478 19479 if (l == 0) 19480 { 19481 /* Couldn't find the filename.. search the paths. 19482 */ 19483 l = *fnamelen; 19484 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19485 return -1; 19486 } 19487 *fnamelen = l; 19488 } 19489 } 19490 #endif /* WIN3264 */ 19491 19492 /* ":t" - tail, just the basename */ 19493 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19494 { 19495 *usedlen += 2; 19496 *fnamelen -= (int)(tail - *fnamep); 19497 *fnamep = tail; 19498 } 19499 19500 /* ":e" - extension, can be repeated */ 19501 /* ":r" - root, without extension, can be repeated */ 19502 while (src[*usedlen] == ':' 19503 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19504 { 19505 /* find a '.' in the tail: 19506 * - for second :e: before the current fname 19507 * - otherwise: The last '.' 19508 */ 19509 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19510 s = *fnamep - 2; 19511 else 19512 s = *fnamep + *fnamelen - 1; 19513 for ( ; s > tail; --s) 19514 if (s[0] == '.') 19515 break; 19516 if (src[*usedlen + 1] == 'e') /* :e */ 19517 { 19518 if (s > tail) 19519 { 19520 *fnamelen += (int)(*fnamep - (s + 1)); 19521 *fnamep = s + 1; 19522 #ifdef VMS 19523 /* cut version from the extension */ 19524 s = *fnamep + *fnamelen - 1; 19525 for ( ; s > *fnamep; --s) 19526 if (s[0] == ';') 19527 break; 19528 if (s > *fnamep) 19529 *fnamelen = s - *fnamep; 19530 #endif 19531 } 19532 else if (*fnamep <= tail) 19533 *fnamelen = 0; 19534 } 19535 else /* :r */ 19536 { 19537 if (s > tail) /* remove one extension */ 19538 *fnamelen = (int)(s - *fnamep); 19539 } 19540 *usedlen += 2; 19541 } 19542 19543 /* ":s?pat?foo?" - substitute */ 19544 /* ":gs?pat?foo?" - global substitute */ 19545 if (src[*usedlen] == ':' 19546 && (src[*usedlen + 1] == 's' 19547 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19548 { 19549 char_u *str; 19550 char_u *pat; 19551 char_u *sub; 19552 int sep; 19553 char_u *flags; 19554 int didit = FALSE; 19555 19556 flags = (char_u *)""; 19557 s = src + *usedlen + 2; 19558 if (src[*usedlen + 1] == 'g') 19559 { 19560 flags = (char_u *)"g"; 19561 ++s; 19562 } 19563 19564 sep = *s++; 19565 if (sep) 19566 { 19567 /* find end of pattern */ 19568 p = vim_strchr(s, sep); 19569 if (p != NULL) 19570 { 19571 pat = vim_strnsave(s, (int)(p - s)); 19572 if (pat != NULL) 19573 { 19574 s = p + 1; 19575 /* find end of substitution */ 19576 p = vim_strchr(s, sep); 19577 if (p != NULL) 19578 { 19579 sub = vim_strnsave(s, (int)(p - s)); 19580 str = vim_strnsave(*fnamep, *fnamelen); 19581 if (sub != NULL && str != NULL) 19582 { 19583 *usedlen = (int)(p + 1 - src); 19584 s = do_string_sub(str, pat, sub, flags); 19585 if (s != NULL) 19586 { 19587 *fnamep = s; 19588 *fnamelen = (int)STRLEN(s); 19589 vim_free(*bufp); 19590 *bufp = s; 19591 didit = TRUE; 19592 } 19593 } 19594 vim_free(sub); 19595 vim_free(str); 19596 } 19597 vim_free(pat); 19598 } 19599 } 19600 /* after using ":s", repeat all the modifiers */ 19601 if (didit) 19602 goto repeat; 19603 } 19604 } 19605 19606 return valid; 19607 } 19608 19609 /* 19610 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19611 * "flags" can be "g" to do a global substitute. 19612 * Returns an allocated string, NULL for error. 19613 */ 19614 char_u * 19615 do_string_sub(str, pat, sub, flags) 19616 char_u *str; 19617 char_u *pat; 19618 char_u *sub; 19619 char_u *flags; 19620 { 19621 int sublen; 19622 regmatch_T regmatch; 19623 int i; 19624 int do_all; 19625 char_u *tail; 19626 garray_T ga; 19627 char_u *ret; 19628 char_u *save_cpo; 19629 19630 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19631 save_cpo = p_cpo; 19632 p_cpo = (char_u *)""; 19633 19634 ga_init2(&ga, 1, 200); 19635 19636 do_all = (flags[0] == 'g'); 19637 19638 regmatch.rm_ic = p_ic; 19639 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19640 if (regmatch.regprog != NULL) 19641 { 19642 tail = str; 19643 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19644 { 19645 /* 19646 * Get some space for a temporary buffer to do the substitution 19647 * into. It will contain: 19648 * - The text up to where the match is. 19649 * - The substituted text. 19650 * - The text after the match. 19651 */ 19652 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19653 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19654 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19655 { 19656 ga_clear(&ga); 19657 break; 19658 } 19659 19660 /* copy the text up to where the match is */ 19661 i = (int)(regmatch.startp[0] - tail); 19662 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19663 /* add the substituted text */ 19664 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19665 + ga.ga_len + i, TRUE, TRUE, FALSE); 19666 ga.ga_len += i + sublen - 1; 19667 /* avoid getting stuck on a match with an empty string */ 19668 if (tail == regmatch.endp[0]) 19669 { 19670 if (*tail == NUL) 19671 break; 19672 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19673 ++ga.ga_len; 19674 } 19675 else 19676 { 19677 tail = regmatch.endp[0]; 19678 if (*tail == NUL) 19679 break; 19680 } 19681 if (!do_all) 19682 break; 19683 } 19684 19685 if (ga.ga_data != NULL) 19686 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19687 19688 vim_free(regmatch.regprog); 19689 } 19690 19691 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19692 ga_clear(&ga); 19693 p_cpo = save_cpo; 19694 19695 return ret; 19696 } 19697 19698 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19699