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_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 413 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 414 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 415 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 416 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 417 static char_u *list2string __ARGS((typval_T *tv)); 418 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); 419 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 420 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 421 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 422 static void dict_unref __ARGS((dict_T *d)); 423 static void dict_free __ARGS((dict_T *d)); 424 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 425 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 426 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 427 static void dictitem_free __ARGS((dictitem_T *item)); 428 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 429 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 430 static long dict_len __ARGS((dict_T *d)); 431 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 432 static char_u *dict2string __ARGS((typval_T *tv)); 433 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 434 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 435 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 436 static char_u *string_quote __ARGS((char_u *str, int function)); 437 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 438 static int find_internal_func __ARGS((char_u *name)); 439 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 440 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)); 441 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)); 442 static void emsg_funcname __ARGS((char *msg, char_u *name)); 443 444 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 445 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 446 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 447 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 448 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 449 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 450 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 463 #if defined(FEAT_INS_EXPAND) 464 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 466 #endif 467 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 468 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 469 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 472 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 562 #ifdef vim_mkdir 563 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 564 #endif 565 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 598 #ifdef HAVE_STRFTIME 599 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 600 #endif 601 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 631 632 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 633 static int get_env_len __ARGS((char_u **arg)); 634 static int get_id_len __ARGS((char_u **arg)); 635 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 636 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 637 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 638 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 639 valid character */ 640 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 641 static int eval_isnamec __ARGS((int c)); 642 static int eval_isnamec1 __ARGS((int c)); 643 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 644 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 645 static typval_T *alloc_tv __ARGS((void)); 646 static typval_T *alloc_string_tv __ARGS((char_u *string)); 647 static void free_tv __ARGS((typval_T *varp)); 648 static void init_tv __ARGS((typval_T *varp)); 649 static long get_tv_number __ARGS((typval_T *varp)); 650 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 651 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 652 static char_u *get_tv_string __ARGS((typval_T *varp)); 653 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 654 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 655 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 656 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 657 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 658 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 659 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 660 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 661 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 662 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 663 static int var_check_ro __ARGS((int flags, char_u *name)); 664 static int tv_check_lock __ARGS((int lock, char_u *name)); 665 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 666 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 667 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 668 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 669 static int eval_fname_script __ARGS((char_u *p)); 670 static int eval_fname_sid __ARGS((char_u *p)); 671 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 672 static ufunc_T *find_func __ARGS((char_u *name)); 673 static int function_exists __ARGS((char_u *name)); 674 static int builtin_function __ARGS((char_u *name)); 675 #ifdef FEAT_PROFILE 676 static void func_do_profile __ARGS((ufunc_T *fp)); 677 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 678 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 679 static int 680 # ifdef __BORLANDC__ 681 _RTLENTRYF 682 # endif 683 prof_total_cmp __ARGS((const void *s1, const void *s2)); 684 static int 685 # ifdef __BORLANDC__ 686 _RTLENTRYF 687 # endif 688 prof_self_cmp __ARGS((const void *s1, const void *s2)); 689 #endif 690 static int script_autoload __ARGS((char_u *name, int reload)); 691 static char_u *autoload_name __ARGS((char_u *name)); 692 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 693 static void func_free __ARGS((ufunc_T *fp)); 694 static void func_unref __ARGS((char_u *name)); 695 static void func_ref __ARGS((char_u *name)); 696 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)); 697 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 698 699 /* Character used as separated in autoload function/variable names. */ 700 #define AUTOLOAD_CHAR '#' 701 702 /* 703 * Initialize the global and v: variables. 704 */ 705 void 706 eval_init() 707 { 708 int i; 709 struct vimvar *p; 710 711 init_var_dict(&globvardict, &globvars_var); 712 init_var_dict(&vimvardict, &vimvars_var); 713 hash_init(&compat_hashtab); 714 hash_init(&func_hashtab); 715 716 for (i = 0; i < VV_LEN; ++i) 717 { 718 p = &vimvars[i]; 719 STRCPY(p->vv_di.di_key, p->vv_name); 720 if (p->vv_flags & VV_RO) 721 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 722 else if (p->vv_flags & VV_RO_SBX) 723 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 724 else 725 p->vv_di.di_flags = DI_FLAGS_FIX; 726 727 /* add to v: scope dict, unless the value is not always available */ 728 if (p->vv_type != VAR_UNKNOWN) 729 hash_add(&vimvarht, p->vv_di.di_key); 730 if (p->vv_flags & VV_COMPAT) 731 /* add to compat scope dict */ 732 hash_add(&compat_hashtab, p->vv_di.di_key); 733 } 734 } 735 736 #if defined(EXITFREE) || defined(PROTO) 737 void 738 eval_clear() 739 { 740 int i; 741 struct vimvar *p; 742 743 for (i = 0; i < VV_LEN; ++i) 744 { 745 p = &vimvars[i]; 746 if (p->vv_di.di_tv.v_type == VAR_STRING) 747 { 748 vim_free(p->vv_di.di_tv.vval.v_string); 749 p->vv_di.di_tv.vval.v_string = NULL; 750 } 751 } 752 hash_clear(&vimvarht); 753 hash_clear(&compat_hashtab); 754 755 /* script-local variables */ 756 for (i = 1; i <= ga_scripts.ga_len; ++i) 757 vars_clear(&SCRIPT_VARS(i)); 758 ga_clear(&ga_scripts); 759 free_scriptnames(); 760 761 /* global variables */ 762 vars_clear(&globvarht); 763 764 /* functions */ 765 free_all_functions(); 766 hash_clear(&func_hashtab); 767 768 /* unreferenced lists and dicts */ 769 (void)garbage_collect(); 770 } 771 #endif 772 773 /* 774 * Return the name of the executed function. 775 */ 776 char_u * 777 func_name(cookie) 778 void *cookie; 779 { 780 return ((funccall_T *)cookie)->func->uf_name; 781 } 782 783 /* 784 * Return the address holding the next breakpoint line for a funccall cookie. 785 */ 786 linenr_T * 787 func_breakpoint(cookie) 788 void *cookie; 789 { 790 return &((funccall_T *)cookie)->breakpoint; 791 } 792 793 /* 794 * Return the address holding the debug tick for a funccall cookie. 795 */ 796 int * 797 func_dbg_tick(cookie) 798 void *cookie; 799 { 800 return &((funccall_T *)cookie)->dbg_tick; 801 } 802 803 /* 804 * Return the nesting level for a funccall cookie. 805 */ 806 int 807 func_level(cookie) 808 void *cookie; 809 { 810 return ((funccall_T *)cookie)->level; 811 } 812 813 /* pointer to funccal for currently active function */ 814 funccall_T *current_funccal = NULL; 815 816 /* 817 * Return TRUE when a function was ended by a ":return" command. 818 */ 819 int 820 current_func_returned() 821 { 822 return current_funccal->returned; 823 } 824 825 826 /* 827 * Set an internal variable to a string value. Creates the variable if it does 828 * not already exist. 829 */ 830 void 831 set_internal_string_var(name, value) 832 char_u *name; 833 char_u *value; 834 { 835 char_u *val; 836 typval_T *tvp; 837 838 val = vim_strsave(value); 839 if (val != NULL) 840 { 841 tvp = alloc_string_tv(val); 842 if (tvp != NULL) 843 { 844 set_var(name, tvp, FALSE); 845 free_tv(tvp); 846 } 847 } 848 } 849 850 static lval_T *redir_lval = NULL; 851 static char_u *redir_endp = NULL; 852 static char_u *redir_varname = NULL; 853 854 /* 855 * Start recording command output to a variable 856 * Returns OK if successfully completed the setup. FAIL otherwise. 857 */ 858 int 859 var_redir_start(name, append) 860 char_u *name; 861 int append; /* append to an existing variable */ 862 { 863 int save_emsg; 864 int err; 865 typval_T tv; 866 867 /* Make sure a valid variable name is specified */ 868 if (!eval_isnamec1(*name)) 869 { 870 EMSG(_(e_invarg)); 871 return FAIL; 872 } 873 874 redir_varname = vim_strsave(name); 875 if (redir_varname == NULL) 876 return FAIL; 877 878 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 879 if (redir_lval == NULL) 880 { 881 var_redir_stop(); 882 return FAIL; 883 } 884 885 /* Parse the variable name (can be a dict or list entry). */ 886 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 887 FNE_CHECK_START); 888 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 889 { 890 if (redir_endp != NULL && *redir_endp != NUL) 891 /* Trailing characters are present after the variable name */ 892 EMSG(_(e_trailing)); 893 else 894 EMSG(_(e_invarg)); 895 var_redir_stop(); 896 return FAIL; 897 } 898 899 /* check if we can write to the variable: set it to or append an empty 900 * string */ 901 save_emsg = did_emsg; 902 did_emsg = FALSE; 903 tv.v_type = VAR_STRING; 904 tv.vval.v_string = (char_u *)""; 905 if (append) 906 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 907 else 908 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 909 err = did_emsg; 910 did_emsg += save_emsg; 911 if (err) 912 { 913 var_redir_stop(); 914 return FAIL; 915 } 916 if (redir_lval->ll_newkey != NULL) 917 { 918 /* Dictionary item was created, don't do it again. */ 919 vim_free(redir_lval->ll_newkey); 920 redir_lval->ll_newkey = NULL; 921 } 922 923 return OK; 924 } 925 926 /* 927 * Append "value[len]" to the variable set by var_redir_start(). 928 */ 929 void 930 var_redir_str(value, len) 931 char_u *value; 932 int len; 933 { 934 char_u *val; 935 typval_T tv; 936 int save_emsg; 937 int err; 938 939 if (redir_lval == NULL) 940 return; 941 942 if (len == -1) 943 /* Append the entire string */ 944 val = vim_strsave(value); 945 else 946 /* Append only the specified number of characters */ 947 val = vim_strnsave(value, len); 948 if (val == NULL) 949 return; 950 951 tv.v_type = VAR_STRING; 952 tv.vval.v_string = val; 953 954 save_emsg = did_emsg; 955 did_emsg = FALSE; 956 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 957 err = did_emsg; 958 did_emsg += save_emsg; 959 if (err) 960 var_redir_stop(); 961 962 vim_free(tv.vval.v_string); 963 } 964 965 /* 966 * Stop redirecting command output to a variable. 967 */ 968 void 969 var_redir_stop() 970 { 971 if (redir_lval != NULL) 972 { 973 clear_lval(redir_lval); 974 vim_free(redir_lval); 975 redir_lval = NULL; 976 } 977 vim_free(redir_varname); 978 redir_varname = NULL; 979 } 980 981 # if defined(FEAT_MBYTE) || defined(PROTO) 982 int 983 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 984 char_u *enc_from; 985 char_u *enc_to; 986 char_u *fname_from; 987 char_u *fname_to; 988 { 989 int err = FALSE; 990 991 set_vim_var_string(VV_CC_FROM, enc_from, -1); 992 set_vim_var_string(VV_CC_TO, enc_to, -1); 993 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 994 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 995 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 996 err = TRUE; 997 set_vim_var_string(VV_CC_FROM, NULL, -1); 998 set_vim_var_string(VV_CC_TO, NULL, -1); 999 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1000 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1001 1002 if (err) 1003 return FAIL; 1004 return OK; 1005 } 1006 # endif 1007 1008 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1009 int 1010 eval_printexpr(fname, args) 1011 char_u *fname; 1012 char_u *args; 1013 { 1014 int err = FALSE; 1015 1016 set_vim_var_string(VV_FNAME_IN, fname, -1); 1017 set_vim_var_string(VV_CMDARG, args, -1); 1018 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1019 err = TRUE; 1020 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1021 set_vim_var_string(VV_CMDARG, NULL, -1); 1022 1023 if (err) 1024 { 1025 mch_remove(fname); 1026 return FAIL; 1027 } 1028 return OK; 1029 } 1030 # endif 1031 1032 # if defined(FEAT_DIFF) || defined(PROTO) 1033 void 1034 eval_diff(origfile, newfile, outfile) 1035 char_u *origfile; 1036 char_u *newfile; 1037 char_u *outfile; 1038 { 1039 int err = FALSE; 1040 1041 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1042 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1043 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1044 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1045 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1046 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1047 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1048 } 1049 1050 void 1051 eval_patch(origfile, difffile, outfile) 1052 char_u *origfile; 1053 char_u *difffile; 1054 char_u *outfile; 1055 { 1056 int err; 1057 1058 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1059 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1060 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1061 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1062 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1063 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1064 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1065 } 1066 # endif 1067 1068 /* 1069 * Top level evaluation function, returning a boolean. 1070 * Sets "error" to TRUE if there was an error. 1071 * Return TRUE or FALSE. 1072 */ 1073 int 1074 eval_to_bool(arg, error, nextcmd, skip) 1075 char_u *arg; 1076 int *error; 1077 char_u **nextcmd; 1078 int skip; /* only parse, don't execute */ 1079 { 1080 typval_T tv; 1081 int retval = FALSE; 1082 1083 if (skip) 1084 ++emsg_skip; 1085 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1086 *error = TRUE; 1087 else 1088 { 1089 *error = FALSE; 1090 if (!skip) 1091 { 1092 retval = (get_tv_number_chk(&tv, error) != 0); 1093 clear_tv(&tv); 1094 } 1095 } 1096 if (skip) 1097 --emsg_skip; 1098 1099 return retval; 1100 } 1101 1102 /* 1103 * Top level evaluation function, returning a string. If "skip" is TRUE, 1104 * only parsing to "nextcmd" is done, without reporting errors. Return 1105 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1106 */ 1107 char_u * 1108 eval_to_string_skip(arg, nextcmd, skip) 1109 char_u *arg; 1110 char_u **nextcmd; 1111 int skip; /* only parse, don't execute */ 1112 { 1113 typval_T tv; 1114 char_u *retval; 1115 1116 if (skip) 1117 ++emsg_skip; 1118 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1119 retval = NULL; 1120 else 1121 { 1122 retval = vim_strsave(get_tv_string(&tv)); 1123 clear_tv(&tv); 1124 } 1125 if (skip) 1126 --emsg_skip; 1127 1128 return retval; 1129 } 1130 1131 /* 1132 * Skip over an expression at "*pp". 1133 * Return FAIL for an error, OK otherwise. 1134 */ 1135 int 1136 skip_expr(pp) 1137 char_u **pp; 1138 { 1139 typval_T rettv; 1140 1141 *pp = skipwhite(*pp); 1142 return eval1(pp, &rettv, FALSE); 1143 } 1144 1145 /* 1146 * Top level evaluation function, returning a string. 1147 * Return pointer to allocated memory, or NULL for failure. 1148 */ 1149 char_u * 1150 eval_to_string(arg, nextcmd) 1151 char_u *arg; 1152 char_u **nextcmd; 1153 { 1154 typval_T tv; 1155 char_u *retval; 1156 1157 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1158 retval = NULL; 1159 else 1160 { 1161 retval = vim_strsave(get_tv_string(&tv)); 1162 clear_tv(&tv); 1163 } 1164 1165 return retval; 1166 } 1167 1168 /* 1169 * Call eval_to_string() with "sandbox" set and not using local variables. 1170 */ 1171 char_u * 1172 eval_to_string_safe(arg, nextcmd) 1173 char_u *arg; 1174 char_u **nextcmd; 1175 { 1176 char_u *retval; 1177 void *save_funccalp; 1178 1179 save_funccalp = save_funccal(); 1180 ++sandbox; 1181 retval = eval_to_string(arg, nextcmd); 1182 --sandbox; 1183 restore_funccal(save_funccalp); 1184 return retval; 1185 } 1186 1187 /* 1188 * Top level evaluation function, returning a number. 1189 * Evaluates "expr" silently. 1190 * Returns -1 for an error. 1191 */ 1192 int 1193 eval_to_number(expr) 1194 char_u *expr; 1195 { 1196 typval_T rettv; 1197 int retval; 1198 char_u *p = skipwhite(expr); 1199 1200 ++emsg_off; 1201 1202 if (eval1(&p, &rettv, TRUE) == FAIL) 1203 retval = -1; 1204 else 1205 { 1206 retval = get_tv_number_chk(&rettv, NULL); 1207 clear_tv(&rettv); 1208 } 1209 --emsg_off; 1210 1211 return retval; 1212 } 1213 1214 /* 1215 * Prepare v: variable "idx" to be used. 1216 * Save the current typeval in "save_tv". 1217 * When not used yet add the variable to the v: hashtable. 1218 */ 1219 static void 1220 prepare_vimvar(idx, save_tv) 1221 int idx; 1222 typval_T *save_tv; 1223 { 1224 *save_tv = vimvars[idx].vv_tv; 1225 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1226 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1227 } 1228 1229 /* 1230 * Restore v: variable "idx" to typeval "save_tv". 1231 * When no longer defined, remove the variable from the v: hashtable. 1232 */ 1233 static void 1234 restore_vimvar(idx, save_tv) 1235 int idx; 1236 typval_T *save_tv; 1237 { 1238 hashitem_T *hi; 1239 1240 clear_tv(&vimvars[idx].vv_tv); 1241 vimvars[idx].vv_tv = *save_tv; 1242 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1243 { 1244 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1245 if (HASHITEM_EMPTY(hi)) 1246 EMSG2(_(e_intern2), "restore_vimvar()"); 1247 else 1248 hash_remove(&vimvarht, hi); 1249 } 1250 } 1251 1252 #if defined(FEAT_SYN_HL) || defined(PROTO) 1253 /* 1254 * Evaluate an expression to a list with suggestions. 1255 * For the "expr:" part of 'spellsuggest'. 1256 */ 1257 list_T * 1258 eval_spell_expr(badword, expr) 1259 char_u *badword; 1260 char_u *expr; 1261 { 1262 typval_T save_val; 1263 typval_T rettv; 1264 list_T *list = NULL; 1265 char_u *p = skipwhite(expr); 1266 1267 /* Set "v:val" to the bad word. */ 1268 prepare_vimvar(VV_VAL, &save_val); 1269 vimvars[VV_VAL].vv_type = VAR_STRING; 1270 vimvars[VV_VAL].vv_str = badword; 1271 if (p_verbose == 0) 1272 ++emsg_off; 1273 1274 if (eval1(&p, &rettv, TRUE) == OK) 1275 { 1276 if (rettv.v_type != VAR_LIST) 1277 clear_tv(&rettv); 1278 else 1279 list = rettv.vval.v_list; 1280 } 1281 1282 if (p_verbose == 0) 1283 --emsg_off; 1284 vimvars[VV_VAL].vv_str = NULL; 1285 restore_vimvar(VV_VAL, &save_val); 1286 1287 return list; 1288 } 1289 1290 /* 1291 * "list" is supposed to contain two items: a word and a number. Return the 1292 * word in "pp" and the number as the return value. 1293 * Return -1 if anything isn't right. 1294 * Used to get the good word and score from the eval_spell_expr() result. 1295 */ 1296 int 1297 get_spellword(list, pp) 1298 list_T *list; 1299 char_u **pp; 1300 { 1301 listitem_T *li; 1302 1303 li = list->lv_first; 1304 if (li == NULL) 1305 return -1; 1306 *pp = get_tv_string(&li->li_tv); 1307 1308 li = li->li_next; 1309 if (li == NULL) 1310 return -1; 1311 return get_tv_number(&li->li_tv); 1312 } 1313 #endif 1314 1315 /* 1316 * Top level evaluation function, 1317 */ 1318 typval_T * 1319 eval_expr(arg, nextcmd) 1320 char_u *arg; 1321 char_u **nextcmd; 1322 { 1323 typval_T *tv; 1324 1325 tv = (typval_T *)alloc(sizeof(typval_T)); 1326 if (!tv) 1327 return NULL; 1328 1329 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1330 { 1331 vim_free(tv); 1332 return NULL; 1333 } 1334 1335 return tv; 1336 } 1337 1338 1339 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1340 /* 1341 * Call some vimL function and return the result in "*rettv". 1342 * Uses argv[argc] for the function arguments. 1343 * Returns OK or FAIL. 1344 */ 1345 static int 1346 call_vim_function(func, argc, argv, safe, rettv) 1347 char_u *func; 1348 int argc; 1349 char_u **argv; 1350 int safe; /* use the sandbox */ 1351 typval_T *rettv; 1352 { 1353 typval_T *argvars; 1354 long n; 1355 int len; 1356 int i; 1357 int doesrange; 1358 void *save_funccalp = NULL; 1359 int ret; 1360 1361 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1362 if (argvars == NULL) 1363 return FAIL; 1364 1365 for (i = 0; i < argc; i++) 1366 { 1367 /* Pass a NULL or empty argument as an empty string */ 1368 if (argv[i] == NULL || *argv[i] == NUL) 1369 { 1370 argvars[i].v_type = VAR_STRING; 1371 argvars[i].vval.v_string = (char_u *)""; 1372 continue; 1373 } 1374 1375 /* Recognize a number argument, the others must be strings. */ 1376 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1377 if (len != 0 && len == (int)STRLEN(argv[i])) 1378 { 1379 argvars[i].v_type = VAR_NUMBER; 1380 argvars[i].vval.v_number = n; 1381 } 1382 else 1383 { 1384 argvars[i].v_type = VAR_STRING; 1385 argvars[i].vval.v_string = argv[i]; 1386 } 1387 } 1388 1389 if (safe) 1390 { 1391 save_funccalp = save_funccal(); 1392 ++sandbox; 1393 } 1394 1395 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1396 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1397 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1398 &doesrange, TRUE, NULL); 1399 if (safe) 1400 { 1401 --sandbox; 1402 restore_funccal(save_funccalp); 1403 } 1404 vim_free(argvars); 1405 1406 if (ret == FAIL) 1407 clear_tv(rettv); 1408 1409 return ret; 1410 } 1411 1412 /* 1413 * Call vimL function "func" and return the result as a string. 1414 * Returns NULL when calling the function fails. 1415 * Uses argv[argc] for the function arguments. 1416 */ 1417 void * 1418 call_func_retstr(func, argc, argv, safe) 1419 char_u *func; 1420 int argc; 1421 char_u **argv; 1422 int safe; /* use the sandbox */ 1423 { 1424 typval_T rettv; 1425 char_u *retval; 1426 1427 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1428 return NULL; 1429 1430 retval = vim_strsave(get_tv_string(&rettv)); 1431 clear_tv(&rettv); 1432 return retval; 1433 } 1434 1435 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1436 /* 1437 * Call vimL function "func" and return the result as a number. 1438 * Returns -1 when calling the function fails. 1439 * Uses argv[argc] for the function arguments. 1440 */ 1441 long 1442 call_func_retnr(func, argc, argv, safe) 1443 char_u *func; 1444 int argc; 1445 char_u **argv; 1446 int safe; /* use the sandbox */ 1447 { 1448 typval_T rettv; 1449 long retval; 1450 1451 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1452 return -1; 1453 1454 retval = get_tv_number_chk(&rettv, NULL); 1455 clear_tv(&rettv); 1456 return retval; 1457 } 1458 #endif 1459 1460 /* 1461 * Call vimL function "func" and return the result as a list 1462 * Uses argv[argc] for the function arguments. 1463 */ 1464 void * 1465 call_func_retlist(func, argc, argv, safe) 1466 char_u *func; 1467 int argc; 1468 char_u **argv; 1469 int safe; /* use the sandbox */ 1470 { 1471 typval_T rettv; 1472 1473 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1474 return NULL; 1475 1476 if (rettv.v_type != VAR_LIST) 1477 { 1478 clear_tv(&rettv); 1479 return NULL; 1480 } 1481 1482 return rettv.vval.v_list; 1483 } 1484 1485 #endif 1486 1487 /* 1488 * Save the current function call pointer, and set it to NULL. 1489 * Used when executing autocommands and for ":source". 1490 */ 1491 void * 1492 save_funccal() 1493 { 1494 funccall_T *fc = current_funccal; 1495 1496 current_funccal = NULL; 1497 return (void *)fc; 1498 } 1499 1500 void 1501 restore_funccal(vfc) 1502 void *vfc; 1503 { 1504 funccall_T *fc = (funccall_T *)vfc; 1505 1506 current_funccal = fc; 1507 } 1508 1509 #if defined(FEAT_PROFILE) || defined(PROTO) 1510 /* 1511 * Prepare profiling for entering a child or something else that is not 1512 * counted for the script/function itself. 1513 * Should always be called in pair with prof_child_exit(). 1514 */ 1515 void 1516 prof_child_enter(tm) 1517 proftime_T *tm; /* place to store waittime */ 1518 { 1519 funccall_T *fc = current_funccal; 1520 1521 if (fc != NULL && fc->func->uf_profiling) 1522 profile_start(&fc->prof_child); 1523 script_prof_save(tm); 1524 } 1525 1526 /* 1527 * Take care of time spent in a child. 1528 * Should always be called after prof_child_enter(). 1529 */ 1530 void 1531 prof_child_exit(tm) 1532 proftime_T *tm; /* where waittime was stored */ 1533 { 1534 funccall_T *fc = current_funccal; 1535 1536 if (fc != NULL && fc->func->uf_profiling) 1537 { 1538 profile_end(&fc->prof_child); 1539 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1540 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1541 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1542 } 1543 script_prof_restore(tm); 1544 } 1545 #endif 1546 1547 1548 #ifdef FEAT_FOLDING 1549 /* 1550 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1551 * it in "*cp". Doesn't give error messages. 1552 */ 1553 int 1554 eval_foldexpr(arg, cp) 1555 char_u *arg; 1556 int *cp; 1557 { 1558 typval_T tv; 1559 int retval; 1560 char_u *s; 1561 1562 ++emsg_off; 1563 ++sandbox; 1564 *cp = NUL; 1565 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1566 retval = 0; 1567 else 1568 { 1569 /* If the result is a number, just return the number. */ 1570 if (tv.v_type == VAR_NUMBER) 1571 retval = tv.vval.v_number; 1572 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1573 retval = 0; 1574 else 1575 { 1576 /* If the result is a string, check if there is a non-digit before 1577 * the number. */ 1578 s = tv.vval.v_string; 1579 if (!VIM_ISDIGIT(*s) && *s != '-') 1580 *cp = *s++; 1581 retval = atol((char *)s); 1582 } 1583 clear_tv(&tv); 1584 } 1585 --emsg_off; 1586 --sandbox; 1587 1588 return retval; 1589 } 1590 #endif 1591 1592 /* 1593 * ":let" list all variable values 1594 * ":let var1 var2" list variable values 1595 * ":let var = expr" assignment command. 1596 * ":let var += expr" assignment command. 1597 * ":let var -= expr" assignment command. 1598 * ":let var .= expr" assignment command. 1599 * ":let [var1, var2] = expr" unpack list. 1600 */ 1601 void 1602 ex_let(eap) 1603 exarg_T *eap; 1604 { 1605 char_u *arg = eap->arg; 1606 char_u *expr = NULL; 1607 typval_T rettv; 1608 int i; 1609 int var_count = 0; 1610 int semicolon = 0; 1611 char_u op[2]; 1612 1613 expr = skip_var_list(arg, &var_count, &semicolon); 1614 if (expr == NULL) 1615 return; 1616 expr = vim_strchr(expr, '='); 1617 if (expr == NULL) 1618 { 1619 /* 1620 * ":let" without "=": list variables 1621 */ 1622 if (*arg == '[') 1623 EMSG(_(e_invarg)); 1624 else if (!ends_excmd(*arg)) 1625 /* ":let var1 var2" */ 1626 arg = list_arg_vars(eap, arg); 1627 else if (!eap->skip) 1628 { 1629 /* ":let" */ 1630 list_glob_vars(); 1631 list_buf_vars(); 1632 list_win_vars(); 1633 list_vim_vars(); 1634 } 1635 eap->nextcmd = check_nextcmd(arg); 1636 } 1637 else 1638 { 1639 op[0] = '='; 1640 op[1] = NUL; 1641 if (expr > arg) 1642 { 1643 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1644 op[0] = expr[-1]; /* +=, -= or .= */ 1645 } 1646 expr = skipwhite(expr + 1); 1647 1648 if (eap->skip) 1649 ++emsg_skip; 1650 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1651 if (eap->skip) 1652 { 1653 if (i != FAIL) 1654 clear_tv(&rettv); 1655 --emsg_skip; 1656 } 1657 else if (i != FAIL) 1658 { 1659 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1660 op); 1661 clear_tv(&rettv); 1662 } 1663 } 1664 } 1665 1666 /* 1667 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1668 * Handles both "var" with any type and "[var, var; var]" with a list type. 1669 * When "nextchars" is not NULL it points to a string with characters that 1670 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1671 * or concatenate. 1672 * Returns OK or FAIL; 1673 */ 1674 static int 1675 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1676 char_u *arg_start; 1677 typval_T *tv; 1678 int copy; /* copy values from "tv", don't move */ 1679 int semicolon; /* from skip_var_list() */ 1680 int var_count; /* from skip_var_list() */ 1681 char_u *nextchars; 1682 { 1683 char_u *arg = arg_start; 1684 list_T *l; 1685 int i; 1686 listitem_T *item; 1687 typval_T ltv; 1688 1689 if (*arg != '[') 1690 { 1691 /* 1692 * ":let var = expr" or ":for var in list" 1693 */ 1694 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1695 return FAIL; 1696 return OK; 1697 } 1698 1699 /* 1700 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1701 */ 1702 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1703 { 1704 EMSG(_(e_listreq)); 1705 return FAIL; 1706 } 1707 1708 i = list_len(l); 1709 if (semicolon == 0 && var_count < i) 1710 { 1711 EMSG(_("E687: Less targets than List items")); 1712 return FAIL; 1713 } 1714 if (var_count - semicolon > i) 1715 { 1716 EMSG(_("E688: More targets than List items")); 1717 return FAIL; 1718 } 1719 1720 item = l->lv_first; 1721 while (*arg != ']') 1722 { 1723 arg = skipwhite(arg + 1); 1724 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1725 item = item->li_next; 1726 if (arg == NULL) 1727 return FAIL; 1728 1729 arg = skipwhite(arg); 1730 if (*arg == ';') 1731 { 1732 /* Put the rest of the list (may be empty) in the var after ';'. 1733 * Create a new list for this. */ 1734 l = list_alloc(); 1735 if (l == NULL) 1736 return FAIL; 1737 while (item != NULL) 1738 { 1739 list_append_tv(l, &item->li_tv); 1740 item = item->li_next; 1741 } 1742 1743 ltv.v_type = VAR_LIST; 1744 ltv.v_lock = 0; 1745 ltv.vval.v_list = l; 1746 l->lv_refcount = 1; 1747 1748 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1749 (char_u *)"]", nextchars); 1750 clear_tv(<v); 1751 if (arg == NULL) 1752 return FAIL; 1753 break; 1754 } 1755 else if (*arg != ',' && *arg != ']') 1756 { 1757 EMSG2(_(e_intern2), "ex_let_vars()"); 1758 return FAIL; 1759 } 1760 } 1761 1762 return OK; 1763 } 1764 1765 /* 1766 * Skip over assignable variable "var" or list of variables "[var, var]". 1767 * Used for ":let varvar = expr" and ":for varvar in expr". 1768 * For "[var, var]" increment "*var_count" for each variable. 1769 * for "[var, var; var]" set "semicolon". 1770 * Return NULL for an error. 1771 */ 1772 static char_u * 1773 skip_var_list(arg, var_count, semicolon) 1774 char_u *arg; 1775 int *var_count; 1776 int *semicolon; 1777 { 1778 char_u *p, *s; 1779 1780 if (*arg == '[') 1781 { 1782 /* "[var, var]": find the matching ']'. */ 1783 p = arg; 1784 for (;;) 1785 { 1786 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1787 s = skip_var_one(p); 1788 if (s == p) 1789 { 1790 EMSG2(_(e_invarg2), p); 1791 return NULL; 1792 } 1793 ++*var_count; 1794 1795 p = skipwhite(s); 1796 if (*p == ']') 1797 break; 1798 else if (*p == ';') 1799 { 1800 if (*semicolon == 1) 1801 { 1802 EMSG(_("Double ; in list of variables")); 1803 return NULL; 1804 } 1805 *semicolon = 1; 1806 } 1807 else if (*p != ',') 1808 { 1809 EMSG2(_(e_invarg2), p); 1810 return NULL; 1811 } 1812 } 1813 return p + 1; 1814 } 1815 else 1816 return skip_var_one(arg); 1817 } 1818 1819 /* 1820 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1821 * l[idx]. 1822 */ 1823 static char_u * 1824 skip_var_one(arg) 1825 char_u *arg; 1826 { 1827 if (*arg == '@' && arg[1] != NUL) 1828 return arg + 2; 1829 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1830 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1831 } 1832 1833 /* 1834 * List variables for hashtab "ht" with prefix "prefix". 1835 * If "empty" is TRUE also list NULL strings as empty strings. 1836 */ 1837 static void 1838 list_hashtable_vars(ht, prefix, empty) 1839 hashtab_T *ht; 1840 char_u *prefix; 1841 int empty; 1842 { 1843 hashitem_T *hi; 1844 dictitem_T *di; 1845 int todo; 1846 1847 todo = ht->ht_used; 1848 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1849 { 1850 if (!HASHITEM_EMPTY(hi)) 1851 { 1852 --todo; 1853 di = HI2DI(hi); 1854 if (empty || di->di_tv.v_type != VAR_STRING 1855 || di->di_tv.vval.v_string != NULL) 1856 list_one_var(di, prefix); 1857 } 1858 } 1859 } 1860 1861 /* 1862 * List global variables. 1863 */ 1864 static void 1865 list_glob_vars() 1866 { 1867 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1868 } 1869 1870 /* 1871 * List buffer variables. 1872 */ 1873 static void 1874 list_buf_vars() 1875 { 1876 char_u numbuf[NUMBUFLEN]; 1877 1878 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1879 1880 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1881 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1882 } 1883 1884 /* 1885 * List window variables. 1886 */ 1887 static void 1888 list_win_vars() 1889 { 1890 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1891 } 1892 1893 /* 1894 * List Vim variables. 1895 */ 1896 static void 1897 list_vim_vars() 1898 { 1899 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1900 } 1901 1902 /* 1903 * List variables in "arg". 1904 */ 1905 static char_u * 1906 list_arg_vars(eap, arg) 1907 exarg_T *eap; 1908 char_u *arg; 1909 { 1910 int error = FALSE; 1911 int len; 1912 char_u *name; 1913 char_u *name_start; 1914 char_u *arg_subsc; 1915 char_u *tofree; 1916 typval_T tv; 1917 1918 while (!ends_excmd(*arg) && !got_int) 1919 { 1920 if (error || eap->skip) 1921 { 1922 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1923 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1924 { 1925 emsg_severe = TRUE; 1926 EMSG(_(e_trailing)); 1927 break; 1928 } 1929 } 1930 else 1931 { 1932 /* get_name_len() takes care of expanding curly braces */ 1933 name_start = name = arg; 1934 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1935 if (len <= 0) 1936 { 1937 /* This is mainly to keep test 49 working: when expanding 1938 * curly braces fails overrule the exception error message. */ 1939 if (len < 0 && !aborting()) 1940 { 1941 emsg_severe = TRUE; 1942 EMSG2(_(e_invarg2), arg); 1943 break; 1944 } 1945 error = TRUE; 1946 } 1947 else 1948 { 1949 if (tofree != NULL) 1950 name = tofree; 1951 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1952 error = TRUE; 1953 else 1954 { 1955 /* handle d.key, l[idx], f(expr) */ 1956 arg_subsc = arg; 1957 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1958 error = TRUE; 1959 else 1960 { 1961 if (arg == arg_subsc && len == 2 && name[1] == ':') 1962 { 1963 switch (*name) 1964 { 1965 case 'g': list_glob_vars(); break; 1966 case 'b': list_buf_vars(); break; 1967 case 'w': list_win_vars(); break; 1968 case 'v': list_vim_vars(); break; 1969 default: 1970 EMSG2(_("E738: Can't list variables for %s"), name); 1971 } 1972 } 1973 else 1974 { 1975 char_u numbuf[NUMBUFLEN]; 1976 char_u *tf; 1977 int c; 1978 char_u *s; 1979 1980 s = echo_string(&tv, &tf, numbuf); 1981 c = *arg; 1982 *arg = NUL; 1983 list_one_var_a((char_u *)"", 1984 arg == arg_subsc ? name : name_start, 1985 tv.v_type, s == NULL ? (char_u *)"" : s); 1986 *arg = c; 1987 vim_free(tf); 1988 } 1989 clear_tv(&tv); 1990 } 1991 } 1992 } 1993 1994 vim_free(tofree); 1995 } 1996 1997 arg = skipwhite(arg); 1998 } 1999 2000 return arg; 2001 } 2002 2003 /* 2004 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2005 * Returns a pointer to the char just after the var name. 2006 * Returns NULL if there is an error. 2007 */ 2008 static char_u * 2009 ex_let_one(arg, tv, copy, endchars, op) 2010 char_u *arg; /* points to variable name */ 2011 typval_T *tv; /* value to assign to variable */ 2012 int copy; /* copy value from "tv" */ 2013 char_u *endchars; /* valid chars after variable name or NULL */ 2014 char_u *op; /* "+", "-", "." or NULL*/ 2015 { 2016 int c1; 2017 char_u *name; 2018 char_u *p; 2019 char_u *arg_end = NULL; 2020 int len; 2021 int opt_flags; 2022 char_u *tofree = NULL; 2023 2024 /* 2025 * ":let $VAR = expr": Set environment variable. 2026 */ 2027 if (*arg == '$') 2028 { 2029 /* Find the end of the name. */ 2030 ++arg; 2031 name = arg; 2032 len = get_env_len(&arg); 2033 if (len == 0) 2034 EMSG2(_(e_invarg2), name - 1); 2035 else 2036 { 2037 if (op != NULL && (*op == '+' || *op == '-')) 2038 EMSG2(_(e_letwrong), op); 2039 else if (endchars != NULL 2040 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2041 EMSG(_(e_letunexp)); 2042 else 2043 { 2044 c1 = name[len]; 2045 name[len] = NUL; 2046 p = get_tv_string_chk(tv); 2047 if (p != NULL && op != NULL && *op == '.') 2048 { 2049 int mustfree = FALSE; 2050 char_u *s = vim_getenv(name, &mustfree); 2051 2052 if (s != NULL) 2053 { 2054 p = tofree = concat_str(s, p); 2055 if (mustfree) 2056 vim_free(s); 2057 } 2058 } 2059 if (p != NULL) 2060 { 2061 vim_setenv(name, p); 2062 if (STRICMP(name, "HOME") == 0) 2063 init_homedir(); 2064 else if (didset_vim && STRICMP(name, "VIM") == 0) 2065 didset_vim = FALSE; 2066 else if (didset_vimruntime 2067 && STRICMP(name, "VIMRUNTIME") == 0) 2068 didset_vimruntime = FALSE; 2069 arg_end = arg; 2070 } 2071 name[len] = c1; 2072 vim_free(tofree); 2073 } 2074 } 2075 } 2076 2077 /* 2078 * ":let &option = expr": Set option value. 2079 * ":let &l:option = expr": Set local option value. 2080 * ":let &g:option = expr": Set global option value. 2081 */ 2082 else if (*arg == '&') 2083 { 2084 /* Find the end of the name. */ 2085 p = find_option_end(&arg, &opt_flags); 2086 if (p == NULL || (endchars != NULL 2087 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2088 EMSG(_(e_letunexp)); 2089 else 2090 { 2091 long n; 2092 int opt_type; 2093 long numval; 2094 char_u *stringval = NULL; 2095 char_u *s; 2096 2097 c1 = *p; 2098 *p = NUL; 2099 2100 n = get_tv_number(tv); 2101 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2102 if (s != NULL && op != NULL && *op != '=') 2103 { 2104 opt_type = get_option_value(arg, &numval, 2105 &stringval, opt_flags); 2106 if ((opt_type == 1 && *op == '.') 2107 || (opt_type == 0 && *op != '.')) 2108 EMSG2(_(e_letwrong), op); 2109 else 2110 { 2111 if (opt_type == 1) /* number */ 2112 { 2113 if (*op == '+') 2114 n = numval + n; 2115 else 2116 n = numval - n; 2117 } 2118 else if (opt_type == 0 && stringval != NULL) /* string */ 2119 { 2120 s = concat_str(stringval, s); 2121 vim_free(stringval); 2122 stringval = s; 2123 } 2124 } 2125 } 2126 if (s != NULL) 2127 { 2128 set_option_value(arg, n, s, opt_flags); 2129 arg_end = p; 2130 } 2131 *p = c1; 2132 vim_free(stringval); 2133 } 2134 } 2135 2136 /* 2137 * ":let @r = expr": Set register contents. 2138 */ 2139 else if (*arg == '@') 2140 { 2141 ++arg; 2142 if (op != NULL && (*op == '+' || *op == '-')) 2143 EMSG2(_(e_letwrong), op); 2144 else if (endchars != NULL 2145 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2146 EMSG(_(e_letunexp)); 2147 else 2148 { 2149 char_u *tofree = NULL; 2150 char_u *s; 2151 2152 p = get_tv_string_chk(tv); 2153 if (p != NULL && op != NULL && *op == '.') 2154 { 2155 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2156 if (s != NULL) 2157 { 2158 p = tofree = concat_str(s, p); 2159 vim_free(s); 2160 } 2161 } 2162 if (p != NULL) 2163 { 2164 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2165 arg_end = arg + 1; 2166 } 2167 vim_free(tofree); 2168 } 2169 } 2170 2171 /* 2172 * ":let var = expr": Set internal variable. 2173 * ":let {expr} = expr": Idem, name made with curly braces 2174 */ 2175 else if (eval_isnamec1(*arg) || *arg == '{') 2176 { 2177 lval_T lv; 2178 2179 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2180 if (p != NULL && lv.ll_name != NULL) 2181 { 2182 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2183 EMSG(_(e_letunexp)); 2184 else 2185 { 2186 set_var_lval(&lv, p, tv, copy, op); 2187 arg_end = p; 2188 } 2189 } 2190 clear_lval(&lv); 2191 } 2192 2193 else 2194 EMSG2(_(e_invarg2), arg); 2195 2196 return arg_end; 2197 } 2198 2199 /* 2200 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2201 */ 2202 static int 2203 check_changedtick(arg) 2204 char_u *arg; 2205 { 2206 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2207 { 2208 EMSG2(_(e_readonlyvar), arg); 2209 return TRUE; 2210 } 2211 return FALSE; 2212 } 2213 2214 /* 2215 * Get an lval: variable, Dict item or List item that can be assigned a value 2216 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2217 * "name.key", "name.key[expr]" etc. 2218 * Indexing only works if "name" is an existing List or Dictionary. 2219 * "name" points to the start of the name. 2220 * If "rettv" is not NULL it points to the value to be assigned. 2221 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2222 * wrong; must end in space or cmd separator. 2223 * 2224 * Returns a pointer to just after the name, including indexes. 2225 * When an evaluation error occurs "lp->ll_name" is NULL; 2226 * Returns NULL for a parsing error. Still need to free items in "lp"! 2227 */ 2228 static char_u * 2229 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2230 char_u *name; 2231 typval_T *rettv; 2232 lval_T *lp; 2233 int unlet; 2234 int skip; 2235 int quiet; /* don't give error messages */ 2236 int fne_flags; /* flags for find_name_end() */ 2237 { 2238 char_u *p; 2239 char_u *expr_start, *expr_end; 2240 int cc; 2241 dictitem_T *v; 2242 typval_T var1; 2243 typval_T var2; 2244 int empty1 = FALSE; 2245 listitem_T *ni; 2246 char_u *key = NULL; 2247 int len; 2248 hashtab_T *ht; 2249 2250 /* Clear everything in "lp". */ 2251 vim_memset(lp, 0, sizeof(lval_T)); 2252 2253 if (skip) 2254 { 2255 /* When skipping just find the end of the name. */ 2256 lp->ll_name = name; 2257 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2258 } 2259 2260 /* Find the end of the name. */ 2261 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2262 if (expr_start != NULL) 2263 { 2264 /* Don't expand the name when we already know there is an error. */ 2265 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2266 && *p != '[' && *p != '.') 2267 { 2268 EMSG(_(e_trailing)); 2269 return NULL; 2270 } 2271 2272 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2273 if (lp->ll_exp_name == NULL) 2274 { 2275 /* Report an invalid expression in braces, unless the 2276 * expression evaluation has been cancelled due to an 2277 * aborting error, an interrupt, or an exception. */ 2278 if (!aborting() && !quiet) 2279 { 2280 emsg_severe = TRUE; 2281 EMSG2(_(e_invarg2), name); 2282 return NULL; 2283 } 2284 } 2285 lp->ll_name = lp->ll_exp_name; 2286 } 2287 else 2288 lp->ll_name = name; 2289 2290 /* Without [idx] or .key we are done. */ 2291 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2292 return p; 2293 2294 cc = *p; 2295 *p = NUL; 2296 v = find_var(lp->ll_name, &ht); 2297 if (v == NULL && !quiet) 2298 EMSG2(_(e_undefvar), lp->ll_name); 2299 *p = cc; 2300 if (v == NULL) 2301 return NULL; 2302 2303 /* 2304 * Loop until no more [idx] or .key is following. 2305 */ 2306 lp->ll_tv = &v->di_tv; 2307 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2308 { 2309 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2310 && !(lp->ll_tv->v_type == VAR_DICT 2311 && lp->ll_tv->vval.v_dict != NULL)) 2312 { 2313 if (!quiet) 2314 EMSG(_("E689: Can only index a List or Dictionary")); 2315 return NULL; 2316 } 2317 if (lp->ll_range) 2318 { 2319 if (!quiet) 2320 EMSG(_("E708: [:] must come last")); 2321 return NULL; 2322 } 2323 2324 len = -1; 2325 if (*p == '.') 2326 { 2327 key = p + 1; 2328 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2329 ; 2330 if (len == 0) 2331 { 2332 if (!quiet) 2333 EMSG(_(e_emptykey)); 2334 return NULL; 2335 } 2336 p = key + len; 2337 } 2338 else 2339 { 2340 /* Get the index [expr] or the first index [expr: ]. */ 2341 p = skipwhite(p + 1); 2342 if (*p == ':') 2343 empty1 = TRUE; 2344 else 2345 { 2346 empty1 = FALSE; 2347 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2348 return NULL; 2349 if (get_tv_string_chk(&var1) == NULL) 2350 { 2351 /* not a number or string */ 2352 clear_tv(&var1); 2353 return NULL; 2354 } 2355 } 2356 2357 /* Optionally get the second index [ :expr]. */ 2358 if (*p == ':') 2359 { 2360 if (lp->ll_tv->v_type == VAR_DICT) 2361 { 2362 if (!quiet) 2363 EMSG(_(e_dictrange)); 2364 if (!empty1) 2365 clear_tv(&var1); 2366 return NULL; 2367 } 2368 if (rettv != NULL && (rettv->v_type != VAR_LIST 2369 || rettv->vval.v_list == NULL)) 2370 { 2371 if (!quiet) 2372 EMSG(_("E709: [:] requires a List value")); 2373 if (!empty1) 2374 clear_tv(&var1); 2375 return NULL; 2376 } 2377 p = skipwhite(p + 1); 2378 if (*p == ']') 2379 lp->ll_empty2 = TRUE; 2380 else 2381 { 2382 lp->ll_empty2 = FALSE; 2383 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2384 { 2385 if (!empty1) 2386 clear_tv(&var1); 2387 return NULL; 2388 } 2389 if (get_tv_string_chk(&var2) == NULL) 2390 { 2391 /* not a number or string */ 2392 if (!empty1) 2393 clear_tv(&var1); 2394 clear_tv(&var2); 2395 return NULL; 2396 } 2397 } 2398 lp->ll_range = TRUE; 2399 } 2400 else 2401 lp->ll_range = FALSE; 2402 2403 if (*p != ']') 2404 { 2405 if (!quiet) 2406 EMSG(_(e_missbrac)); 2407 if (!empty1) 2408 clear_tv(&var1); 2409 if (lp->ll_range && !lp->ll_empty2) 2410 clear_tv(&var2); 2411 return NULL; 2412 } 2413 2414 /* Skip to past ']'. */ 2415 ++p; 2416 } 2417 2418 if (lp->ll_tv->v_type == VAR_DICT) 2419 { 2420 if (len == -1) 2421 { 2422 /* "[key]": get key from "var1" */ 2423 key = get_tv_string(&var1); /* is number or string */ 2424 if (*key == NUL) 2425 { 2426 if (!quiet) 2427 EMSG(_(e_emptykey)); 2428 clear_tv(&var1); 2429 return NULL; 2430 } 2431 } 2432 lp->ll_list = NULL; 2433 lp->ll_dict = lp->ll_tv->vval.v_dict; 2434 lp->ll_di = dict_find(lp->ll_dict, key, len); 2435 if (lp->ll_di == NULL) 2436 { 2437 /* Key does not exist in dict: may need to add it. */ 2438 if (*p == '[' || *p == '.' || unlet) 2439 { 2440 if (!quiet) 2441 EMSG2(_(e_dictkey), key); 2442 if (len == -1) 2443 clear_tv(&var1); 2444 return NULL; 2445 } 2446 if (len == -1) 2447 lp->ll_newkey = vim_strsave(key); 2448 else 2449 lp->ll_newkey = vim_strnsave(key, len); 2450 if (len == -1) 2451 clear_tv(&var1); 2452 if (lp->ll_newkey == NULL) 2453 p = NULL; 2454 break; 2455 } 2456 if (len == -1) 2457 clear_tv(&var1); 2458 lp->ll_tv = &lp->ll_di->di_tv; 2459 } 2460 else 2461 { 2462 /* 2463 * Get the number and item for the only or first index of the List. 2464 */ 2465 if (empty1) 2466 lp->ll_n1 = 0; 2467 else 2468 { 2469 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2470 clear_tv(&var1); 2471 } 2472 lp->ll_dict = NULL; 2473 lp->ll_list = lp->ll_tv->vval.v_list; 2474 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2475 if (lp->ll_li == NULL) 2476 { 2477 if (!quiet) 2478 EMSGN(_(e_listidx), lp->ll_n1); 2479 if (lp->ll_range && !lp->ll_empty2) 2480 clear_tv(&var2); 2481 return NULL; 2482 } 2483 2484 /* 2485 * May need to find the item or absolute index for the second 2486 * index of a range. 2487 * When no index given: "lp->ll_empty2" is TRUE. 2488 * Otherwise "lp->ll_n2" is set to the second index. 2489 */ 2490 if (lp->ll_range && !lp->ll_empty2) 2491 { 2492 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2493 clear_tv(&var2); 2494 if (lp->ll_n2 < 0) 2495 { 2496 ni = list_find(lp->ll_list, lp->ll_n2); 2497 if (ni == NULL) 2498 { 2499 if (!quiet) 2500 EMSGN(_(e_listidx), lp->ll_n2); 2501 return NULL; 2502 } 2503 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2504 } 2505 2506 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2507 if (lp->ll_n1 < 0) 2508 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2509 if (lp->ll_n2 < lp->ll_n1) 2510 { 2511 if (!quiet) 2512 EMSGN(_(e_listidx), lp->ll_n2); 2513 return NULL; 2514 } 2515 } 2516 2517 lp->ll_tv = &lp->ll_li->li_tv; 2518 } 2519 } 2520 2521 return p; 2522 } 2523 2524 /* 2525 * Clear lval "lp" that was filled by get_lval(). 2526 */ 2527 static void 2528 clear_lval(lp) 2529 lval_T *lp; 2530 { 2531 vim_free(lp->ll_exp_name); 2532 vim_free(lp->ll_newkey); 2533 } 2534 2535 /* 2536 * Set a variable that was parsed by get_lval() to "rettv". 2537 * "endp" points to just after the parsed name. 2538 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2539 */ 2540 static void 2541 set_var_lval(lp, endp, rettv, copy, op) 2542 lval_T *lp; 2543 char_u *endp; 2544 typval_T *rettv; 2545 int copy; 2546 char_u *op; 2547 { 2548 int cc; 2549 listitem_T *ni; 2550 listitem_T *ri; 2551 dictitem_T *di; 2552 2553 if (lp->ll_tv == NULL) 2554 { 2555 if (!check_changedtick(lp->ll_name)) 2556 { 2557 cc = *endp; 2558 *endp = NUL; 2559 if (op != NULL && *op != '=') 2560 { 2561 typval_T tv; 2562 2563 /* handle +=, -= and .= */ 2564 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2565 &tv, TRUE) == OK) 2566 { 2567 if (tv_op(&tv, rettv, op) == OK) 2568 set_var(lp->ll_name, &tv, FALSE); 2569 clear_tv(&tv); 2570 } 2571 } 2572 else 2573 set_var(lp->ll_name, rettv, copy); 2574 *endp = cc; 2575 } 2576 } 2577 else if (tv_check_lock(lp->ll_newkey == NULL 2578 ? lp->ll_tv->v_lock 2579 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2580 ; 2581 else if (lp->ll_range) 2582 { 2583 /* 2584 * Assign the List values to the list items. 2585 */ 2586 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2587 { 2588 if (op != NULL && *op != '=') 2589 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2590 else 2591 { 2592 clear_tv(&lp->ll_li->li_tv); 2593 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2594 } 2595 ri = ri->li_next; 2596 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2597 break; 2598 if (lp->ll_li->li_next == NULL) 2599 { 2600 /* Need to add an empty item. */ 2601 ni = listitem_alloc(); 2602 if (ni == NULL) 2603 { 2604 ri = NULL; 2605 break; 2606 } 2607 ni->li_tv.v_type = VAR_NUMBER; 2608 ni->li_tv.v_lock = 0; 2609 ni->li_tv.vval.v_number = 0; 2610 list_append(lp->ll_list, ni); 2611 } 2612 lp->ll_li = lp->ll_li->li_next; 2613 ++lp->ll_n1; 2614 } 2615 if (ri != NULL) 2616 EMSG(_("E710: List value has more items than target")); 2617 else if (lp->ll_empty2 2618 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2619 : lp->ll_n1 != lp->ll_n2) 2620 EMSG(_("E711: List value has not enough items")); 2621 } 2622 else 2623 { 2624 /* 2625 * Assign to a List or Dictionary item. 2626 */ 2627 if (lp->ll_newkey != NULL) 2628 { 2629 if (op != NULL && *op != '=') 2630 { 2631 EMSG2(_(e_letwrong), op); 2632 return; 2633 } 2634 2635 /* Need to add an item to the Dictionary. */ 2636 di = dictitem_alloc(lp->ll_newkey); 2637 if (di == NULL) 2638 return; 2639 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2640 { 2641 vim_free(di); 2642 return; 2643 } 2644 lp->ll_tv = &di->di_tv; 2645 } 2646 else if (op != NULL && *op != '=') 2647 { 2648 tv_op(lp->ll_tv, rettv, op); 2649 return; 2650 } 2651 else 2652 clear_tv(lp->ll_tv); 2653 2654 /* 2655 * Assign the value to the variable or list item. 2656 */ 2657 if (copy) 2658 copy_tv(rettv, lp->ll_tv); 2659 else 2660 { 2661 *lp->ll_tv = *rettv; 2662 lp->ll_tv->v_lock = 0; 2663 init_tv(rettv); 2664 } 2665 } 2666 } 2667 2668 /* 2669 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2670 * Returns OK or FAIL. 2671 */ 2672 static int 2673 tv_op(tv1, tv2, op) 2674 typval_T *tv1; 2675 typval_T *tv2; 2676 char_u *op; 2677 { 2678 long n; 2679 char_u numbuf[NUMBUFLEN]; 2680 char_u *s; 2681 2682 /* Can't do anything with a Funcref or a Dict on the right. */ 2683 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2684 { 2685 switch (tv1->v_type) 2686 { 2687 case VAR_DICT: 2688 case VAR_FUNC: 2689 break; 2690 2691 case VAR_LIST: 2692 if (*op != '+' || tv2->v_type != VAR_LIST) 2693 break; 2694 /* List += List */ 2695 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2696 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2697 return OK; 2698 2699 case VAR_NUMBER: 2700 case VAR_STRING: 2701 if (tv2->v_type == VAR_LIST) 2702 break; 2703 if (*op == '+' || *op == '-') 2704 { 2705 /* nr += nr or nr -= nr*/ 2706 n = get_tv_number(tv1); 2707 if (*op == '+') 2708 n += get_tv_number(tv2); 2709 else 2710 n -= get_tv_number(tv2); 2711 clear_tv(tv1); 2712 tv1->v_type = VAR_NUMBER; 2713 tv1->vval.v_number = n; 2714 } 2715 else 2716 { 2717 /* str .= str */ 2718 s = get_tv_string(tv1); 2719 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2720 clear_tv(tv1); 2721 tv1->v_type = VAR_STRING; 2722 tv1->vval.v_string = s; 2723 } 2724 return OK; 2725 } 2726 } 2727 2728 EMSG2(_(e_letwrong), op); 2729 return FAIL; 2730 } 2731 2732 /* 2733 * Add a watcher to a list. 2734 */ 2735 static void 2736 list_add_watch(l, lw) 2737 list_T *l; 2738 listwatch_T *lw; 2739 { 2740 lw->lw_next = l->lv_watch; 2741 l->lv_watch = lw; 2742 } 2743 2744 /* 2745 * Remove a watcher from a list. 2746 * No warning when it isn't found... 2747 */ 2748 static void 2749 list_rem_watch(l, lwrem) 2750 list_T *l; 2751 listwatch_T *lwrem; 2752 { 2753 listwatch_T *lw, **lwp; 2754 2755 lwp = &l->lv_watch; 2756 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2757 { 2758 if (lw == lwrem) 2759 { 2760 *lwp = lw->lw_next; 2761 break; 2762 } 2763 lwp = &lw->lw_next; 2764 } 2765 } 2766 2767 /* 2768 * Just before removing an item from a list: advance watchers to the next 2769 * item. 2770 */ 2771 static void 2772 list_fix_watch(l, item) 2773 list_T *l; 2774 listitem_T *item; 2775 { 2776 listwatch_T *lw; 2777 2778 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2779 if (lw->lw_item == item) 2780 lw->lw_item = item->li_next; 2781 } 2782 2783 /* 2784 * Evaluate the expression used in a ":for var in expr" command. 2785 * "arg" points to "var". 2786 * Set "*errp" to TRUE for an error, FALSE otherwise; 2787 * Return a pointer that holds the info. Null when there is an error. 2788 */ 2789 void * 2790 eval_for_line(arg, errp, nextcmdp, skip) 2791 char_u *arg; 2792 int *errp; 2793 char_u **nextcmdp; 2794 int skip; 2795 { 2796 forinfo_T *fi; 2797 char_u *expr; 2798 typval_T tv; 2799 list_T *l; 2800 2801 *errp = TRUE; /* default: there is an error */ 2802 2803 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2804 if (fi == NULL) 2805 return NULL; 2806 2807 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2808 if (expr == NULL) 2809 return fi; 2810 2811 expr = skipwhite(expr); 2812 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2813 { 2814 EMSG(_("E690: Missing \"in\" after :for")); 2815 return fi; 2816 } 2817 2818 if (skip) 2819 ++emsg_skip; 2820 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2821 { 2822 *errp = FALSE; 2823 if (!skip) 2824 { 2825 l = tv.vval.v_list; 2826 if (tv.v_type != VAR_LIST || l == NULL) 2827 { 2828 EMSG(_(e_listreq)); 2829 clear_tv(&tv); 2830 } 2831 else 2832 { 2833 fi->fi_list = l; 2834 list_add_watch(l, &fi->fi_lw); 2835 fi->fi_lw.lw_item = l->lv_first; 2836 } 2837 } 2838 } 2839 if (skip) 2840 --emsg_skip; 2841 2842 return fi; 2843 } 2844 2845 /* 2846 * Use the first item in a ":for" list. Advance to the next. 2847 * Assign the values to the variable (list). "arg" points to the first one. 2848 * Return TRUE when a valid item was found, FALSE when at end of list or 2849 * something wrong. 2850 */ 2851 int 2852 next_for_item(fi_void, arg) 2853 void *fi_void; 2854 char_u *arg; 2855 { 2856 forinfo_T *fi = (forinfo_T *)fi_void; 2857 int result; 2858 listitem_T *item; 2859 2860 item = fi->fi_lw.lw_item; 2861 if (item == NULL) 2862 result = FALSE; 2863 else 2864 { 2865 fi->fi_lw.lw_item = item->li_next; 2866 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2867 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2868 } 2869 return result; 2870 } 2871 2872 /* 2873 * Free the structure used to store info used by ":for". 2874 */ 2875 void 2876 free_for_info(fi_void) 2877 void *fi_void; 2878 { 2879 forinfo_T *fi = (forinfo_T *)fi_void; 2880 2881 if (fi != NULL && fi->fi_list != NULL) 2882 { 2883 list_rem_watch(fi->fi_list, &fi->fi_lw); 2884 list_unref(fi->fi_list); 2885 } 2886 vim_free(fi); 2887 } 2888 2889 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2890 2891 void 2892 set_context_for_expression(xp, arg, cmdidx) 2893 expand_T *xp; 2894 char_u *arg; 2895 cmdidx_T cmdidx; 2896 { 2897 int got_eq = FALSE; 2898 int c; 2899 char_u *p; 2900 2901 if (cmdidx == CMD_let) 2902 { 2903 xp->xp_context = EXPAND_USER_VARS; 2904 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2905 { 2906 /* ":let var1 var2 ...": find last space. */ 2907 for (p = arg + STRLEN(arg); p >= arg; ) 2908 { 2909 xp->xp_pattern = p; 2910 mb_ptr_back(arg, p); 2911 if (vim_iswhite(*p)) 2912 break; 2913 } 2914 return; 2915 } 2916 } 2917 else 2918 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2919 : EXPAND_EXPRESSION; 2920 while ((xp->xp_pattern = vim_strpbrk(arg, 2921 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2922 { 2923 c = *xp->xp_pattern; 2924 if (c == '&') 2925 { 2926 c = xp->xp_pattern[1]; 2927 if (c == '&') 2928 { 2929 ++xp->xp_pattern; 2930 xp->xp_context = cmdidx != CMD_let || got_eq 2931 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2932 } 2933 else if (c != ' ') 2934 { 2935 xp->xp_context = EXPAND_SETTINGS; 2936 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2937 xp->xp_pattern += 2; 2938 2939 } 2940 } 2941 else if (c == '$') 2942 { 2943 /* environment variable */ 2944 xp->xp_context = EXPAND_ENV_VARS; 2945 } 2946 else if (c == '=') 2947 { 2948 got_eq = TRUE; 2949 xp->xp_context = EXPAND_EXPRESSION; 2950 } 2951 else if (c == '<' 2952 && xp->xp_context == EXPAND_FUNCTIONS 2953 && vim_strchr(xp->xp_pattern, '(') == NULL) 2954 { 2955 /* Function name can start with "<SNR>" */ 2956 break; 2957 } 2958 else if (cmdidx != CMD_let || got_eq) 2959 { 2960 if (c == '"') /* string */ 2961 { 2962 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2963 if (c == '\\' && xp->xp_pattern[1] != NUL) 2964 ++xp->xp_pattern; 2965 xp->xp_context = EXPAND_NOTHING; 2966 } 2967 else if (c == '\'') /* literal string */ 2968 { 2969 /* Trick: '' is like stopping and starting a literal string. */ 2970 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2971 /* skip */ ; 2972 xp->xp_context = EXPAND_NOTHING; 2973 } 2974 else if (c == '|') 2975 { 2976 if (xp->xp_pattern[1] == '|') 2977 { 2978 ++xp->xp_pattern; 2979 xp->xp_context = EXPAND_EXPRESSION; 2980 } 2981 else 2982 xp->xp_context = EXPAND_COMMANDS; 2983 } 2984 else 2985 xp->xp_context = EXPAND_EXPRESSION; 2986 } 2987 else 2988 /* Doesn't look like something valid, expand as an expression 2989 * anyway. */ 2990 xp->xp_context = EXPAND_EXPRESSION; 2991 arg = xp->xp_pattern; 2992 if (*arg != NUL) 2993 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 2994 /* skip */ ; 2995 } 2996 xp->xp_pattern = arg; 2997 } 2998 2999 #endif /* FEAT_CMDL_COMPL */ 3000 3001 /* 3002 * ":1,25call func(arg1, arg2)" function call. 3003 */ 3004 void 3005 ex_call(eap) 3006 exarg_T *eap; 3007 { 3008 char_u *arg = eap->arg; 3009 char_u *startarg; 3010 char_u *name; 3011 char_u *tofree; 3012 int len; 3013 typval_T rettv; 3014 linenr_T lnum; 3015 int doesrange; 3016 int failed = FALSE; 3017 funcdict_T fudi; 3018 3019 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3020 vim_free(fudi.fd_newkey); 3021 if (tofree == NULL) 3022 return; 3023 3024 /* Increase refcount on dictionary, it could get deleted when evaluating 3025 * the arguments. */ 3026 if (fudi.fd_dict != NULL) 3027 ++fudi.fd_dict->dv_refcount; 3028 3029 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3030 len = STRLEN(tofree); 3031 name = deref_func_name(tofree, &len); 3032 3033 /* Skip white space to allow ":call func ()". Not good, but required for 3034 * backward compatibility. */ 3035 startarg = skipwhite(arg); 3036 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3037 3038 if (*startarg != '(') 3039 { 3040 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3041 goto end; 3042 } 3043 3044 /* 3045 * When skipping, evaluate the function once, to find the end of the 3046 * arguments. 3047 * When the function takes a range, this is discovered after the first 3048 * call, and the loop is broken. 3049 */ 3050 if (eap->skip) 3051 { 3052 ++emsg_skip; 3053 lnum = eap->line2; /* do it once, also with an invalid range */ 3054 } 3055 else 3056 lnum = eap->line1; 3057 for ( ; lnum <= eap->line2; ++lnum) 3058 { 3059 if (!eap->skip && eap->addr_count > 0) 3060 { 3061 curwin->w_cursor.lnum = lnum; 3062 curwin->w_cursor.col = 0; 3063 } 3064 arg = startarg; 3065 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3066 eap->line1, eap->line2, &doesrange, 3067 !eap->skip, fudi.fd_dict) == FAIL) 3068 { 3069 failed = TRUE; 3070 break; 3071 } 3072 clear_tv(&rettv); 3073 if (doesrange || eap->skip) 3074 break; 3075 /* Stop when immediately aborting on error, or when an interrupt 3076 * occurred or an exception was thrown but not caught. 3077 * get_func_tv() returned OK, so that the check for trailing 3078 * characters below is executed. */ 3079 if (aborting()) 3080 break; 3081 } 3082 if (eap->skip) 3083 --emsg_skip; 3084 3085 if (!failed) 3086 { 3087 /* Check for trailing illegal characters and a following command. */ 3088 if (!ends_excmd(*arg)) 3089 { 3090 emsg_severe = TRUE; 3091 EMSG(_(e_trailing)); 3092 } 3093 else 3094 eap->nextcmd = check_nextcmd(arg); 3095 } 3096 3097 end: 3098 dict_unref(fudi.fd_dict); 3099 vim_free(tofree); 3100 } 3101 3102 /* 3103 * ":unlet[!] var1 ... " command. 3104 */ 3105 void 3106 ex_unlet(eap) 3107 exarg_T *eap; 3108 { 3109 ex_unletlock(eap, eap->arg, 0); 3110 } 3111 3112 /* 3113 * ":lockvar" and ":unlockvar" commands 3114 */ 3115 void 3116 ex_lockvar(eap) 3117 exarg_T *eap; 3118 { 3119 char_u *arg = eap->arg; 3120 int deep = 2; 3121 3122 if (eap->forceit) 3123 deep = -1; 3124 else if (vim_isdigit(*arg)) 3125 { 3126 deep = getdigits(&arg); 3127 arg = skipwhite(arg); 3128 } 3129 3130 ex_unletlock(eap, arg, deep); 3131 } 3132 3133 /* 3134 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3135 */ 3136 static void 3137 ex_unletlock(eap, argstart, deep) 3138 exarg_T *eap; 3139 char_u *argstart; 3140 int deep; 3141 { 3142 char_u *arg = argstart; 3143 char_u *name_end; 3144 int error = FALSE; 3145 lval_T lv; 3146 3147 do 3148 { 3149 /* Parse the name and find the end. */ 3150 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3151 FNE_CHECK_START); 3152 if (lv.ll_name == NULL) 3153 error = TRUE; /* error but continue parsing */ 3154 if (name_end == NULL || (!vim_iswhite(*name_end) 3155 && !ends_excmd(*name_end))) 3156 { 3157 if (name_end != NULL) 3158 { 3159 emsg_severe = TRUE; 3160 EMSG(_(e_trailing)); 3161 } 3162 if (!(eap->skip || error)) 3163 clear_lval(&lv); 3164 break; 3165 } 3166 3167 if (!error && !eap->skip) 3168 { 3169 if (eap->cmdidx == CMD_unlet) 3170 { 3171 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3172 error = TRUE; 3173 } 3174 else 3175 { 3176 if (do_lock_var(&lv, name_end, deep, 3177 eap->cmdidx == CMD_lockvar) == FAIL) 3178 error = TRUE; 3179 } 3180 } 3181 3182 if (!eap->skip) 3183 clear_lval(&lv); 3184 3185 arg = skipwhite(name_end); 3186 } while (!ends_excmd(*arg)); 3187 3188 eap->nextcmd = check_nextcmd(arg); 3189 } 3190 3191 static int 3192 do_unlet_var(lp, name_end, forceit) 3193 lval_T *lp; 3194 char_u *name_end; 3195 int forceit; 3196 { 3197 int ret = OK; 3198 int cc; 3199 3200 if (lp->ll_tv == NULL) 3201 { 3202 cc = *name_end; 3203 *name_end = NUL; 3204 3205 /* Normal name or expanded name. */ 3206 if (check_changedtick(lp->ll_name)) 3207 ret = FAIL; 3208 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3209 ret = FAIL; 3210 *name_end = cc; 3211 } 3212 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3213 return FAIL; 3214 else if (lp->ll_range) 3215 { 3216 listitem_T *li; 3217 3218 /* Delete a range of List items. */ 3219 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3220 { 3221 li = lp->ll_li->li_next; 3222 listitem_remove(lp->ll_list, lp->ll_li); 3223 lp->ll_li = li; 3224 ++lp->ll_n1; 3225 } 3226 } 3227 else 3228 { 3229 if (lp->ll_list != NULL) 3230 /* unlet a List item. */ 3231 listitem_remove(lp->ll_list, lp->ll_li); 3232 else 3233 /* unlet a Dictionary item. */ 3234 dictitem_remove(lp->ll_dict, lp->ll_di); 3235 } 3236 3237 return ret; 3238 } 3239 3240 /* 3241 * "unlet" a variable. Return OK if it existed, FAIL if not. 3242 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3243 */ 3244 int 3245 do_unlet(name, forceit) 3246 char_u *name; 3247 int forceit; 3248 { 3249 hashtab_T *ht; 3250 hashitem_T *hi; 3251 char_u *varname; 3252 3253 ht = find_var_ht(name, &varname); 3254 if (ht != NULL && *varname != NUL) 3255 { 3256 hi = hash_find(ht, varname); 3257 if (!HASHITEM_EMPTY(hi)) 3258 { 3259 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3260 return FAIL; 3261 delete_var(ht, hi); 3262 return OK; 3263 } 3264 } 3265 if (forceit) 3266 return OK; 3267 EMSG2(_("E108: No such variable: \"%s\""), name); 3268 return FAIL; 3269 } 3270 3271 /* 3272 * Lock or unlock variable indicated by "lp". 3273 * "deep" is the levels to go (-1 for unlimited); 3274 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3275 */ 3276 static int 3277 do_lock_var(lp, name_end, deep, lock) 3278 lval_T *lp; 3279 char_u *name_end; 3280 int deep; 3281 int lock; 3282 { 3283 int ret = OK; 3284 int cc; 3285 dictitem_T *di; 3286 3287 if (deep == 0) /* nothing to do */ 3288 return OK; 3289 3290 if (lp->ll_tv == NULL) 3291 { 3292 cc = *name_end; 3293 *name_end = NUL; 3294 3295 /* Normal name or expanded name. */ 3296 if (check_changedtick(lp->ll_name)) 3297 ret = FAIL; 3298 else 3299 { 3300 di = find_var(lp->ll_name, NULL); 3301 if (di == NULL) 3302 ret = FAIL; 3303 else 3304 { 3305 if (lock) 3306 di->di_flags |= DI_FLAGS_LOCK; 3307 else 3308 di->di_flags &= ~DI_FLAGS_LOCK; 3309 item_lock(&di->di_tv, deep, lock); 3310 } 3311 } 3312 *name_end = cc; 3313 } 3314 else if (lp->ll_range) 3315 { 3316 listitem_T *li = lp->ll_li; 3317 3318 /* (un)lock a range of List items. */ 3319 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3320 { 3321 item_lock(&li->li_tv, deep, lock); 3322 li = li->li_next; 3323 ++lp->ll_n1; 3324 } 3325 } 3326 else if (lp->ll_list != NULL) 3327 /* (un)lock a List item. */ 3328 item_lock(&lp->ll_li->li_tv, deep, lock); 3329 else 3330 /* un(lock) a Dictionary item. */ 3331 item_lock(&lp->ll_di->di_tv, deep, lock); 3332 3333 return ret; 3334 } 3335 3336 /* 3337 * Lock or unlock an item. "deep" is nr of levels to go. 3338 */ 3339 static void 3340 item_lock(tv, deep, lock) 3341 typval_T *tv; 3342 int deep; 3343 int lock; 3344 { 3345 static int recurse = 0; 3346 list_T *l; 3347 listitem_T *li; 3348 dict_T *d; 3349 hashitem_T *hi; 3350 int todo; 3351 3352 if (recurse >= DICT_MAXNEST) 3353 { 3354 EMSG(_("E743: variable nested too deep for (un)lock")); 3355 return; 3356 } 3357 if (deep == 0) 3358 return; 3359 ++recurse; 3360 3361 /* lock/unlock the item itself */ 3362 if (lock) 3363 tv->v_lock |= VAR_LOCKED; 3364 else 3365 tv->v_lock &= ~VAR_LOCKED; 3366 3367 switch (tv->v_type) 3368 { 3369 case VAR_LIST: 3370 if ((l = tv->vval.v_list) != NULL) 3371 { 3372 if (lock) 3373 l->lv_lock |= VAR_LOCKED; 3374 else 3375 l->lv_lock &= ~VAR_LOCKED; 3376 if (deep < 0 || deep > 1) 3377 /* recursive: lock/unlock the items the List contains */ 3378 for (li = l->lv_first; li != NULL; li = li->li_next) 3379 item_lock(&li->li_tv, deep - 1, lock); 3380 } 3381 break; 3382 case VAR_DICT: 3383 if ((d = tv->vval.v_dict) != NULL) 3384 { 3385 if (lock) 3386 d->dv_lock |= VAR_LOCKED; 3387 else 3388 d->dv_lock &= ~VAR_LOCKED; 3389 if (deep < 0 || deep > 1) 3390 { 3391 /* recursive: lock/unlock the items the List contains */ 3392 todo = d->dv_hashtab.ht_used; 3393 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3394 { 3395 if (!HASHITEM_EMPTY(hi)) 3396 { 3397 --todo; 3398 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3399 } 3400 } 3401 } 3402 } 3403 } 3404 --recurse; 3405 } 3406 3407 /* 3408 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3409 * it refers to a List or Dictionary that is locked. 3410 */ 3411 static int 3412 tv_islocked(tv) 3413 typval_T *tv; 3414 { 3415 return (tv->v_lock & VAR_LOCKED) 3416 || (tv->v_type == VAR_LIST 3417 && tv->vval.v_list != NULL 3418 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3419 || (tv->v_type == VAR_DICT 3420 && tv->vval.v_dict != NULL 3421 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3422 } 3423 3424 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3425 /* 3426 * Delete all "menutrans_" variables. 3427 */ 3428 void 3429 del_menutrans_vars() 3430 { 3431 hashitem_T *hi; 3432 int todo; 3433 3434 hash_lock(&globvarht); 3435 todo = globvarht.ht_used; 3436 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3437 { 3438 if (!HASHITEM_EMPTY(hi)) 3439 { 3440 --todo; 3441 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3442 delete_var(&globvarht, hi); 3443 } 3444 } 3445 hash_unlock(&globvarht); 3446 } 3447 #endif 3448 3449 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3450 3451 /* 3452 * Local string buffer for the next two functions to store a variable name 3453 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3454 * get_user_var_name(). 3455 */ 3456 3457 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3458 3459 static char_u *varnamebuf = NULL; 3460 static int varnamebuflen = 0; 3461 3462 /* 3463 * Function to concatenate a prefix and a variable name. 3464 */ 3465 static char_u * 3466 cat_prefix_varname(prefix, name) 3467 int prefix; 3468 char_u *name; 3469 { 3470 int len; 3471 3472 len = (int)STRLEN(name) + 3; 3473 if (len > varnamebuflen) 3474 { 3475 vim_free(varnamebuf); 3476 len += 10; /* some additional space */ 3477 varnamebuf = alloc(len); 3478 if (varnamebuf == NULL) 3479 { 3480 varnamebuflen = 0; 3481 return NULL; 3482 } 3483 varnamebuflen = len; 3484 } 3485 *varnamebuf = prefix; 3486 varnamebuf[1] = ':'; 3487 STRCPY(varnamebuf + 2, name); 3488 return varnamebuf; 3489 } 3490 3491 /* 3492 * Function given to ExpandGeneric() to obtain the list of user defined 3493 * (global/buffer/window/built-in) variable names. 3494 */ 3495 /*ARGSUSED*/ 3496 char_u * 3497 get_user_var_name(xp, idx) 3498 expand_T *xp; 3499 int idx; 3500 { 3501 static long_u gdone; 3502 static long_u bdone; 3503 static long_u wdone; 3504 static int vidx; 3505 static hashitem_T *hi; 3506 hashtab_T *ht; 3507 3508 if (idx == 0) 3509 gdone = bdone = wdone = vidx = 0; 3510 3511 /* Global variables */ 3512 if (gdone < globvarht.ht_used) 3513 { 3514 if (gdone++ == 0) 3515 hi = globvarht.ht_array; 3516 else 3517 ++hi; 3518 while (HASHITEM_EMPTY(hi)) 3519 ++hi; 3520 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3521 return cat_prefix_varname('g', hi->hi_key); 3522 return hi->hi_key; 3523 } 3524 3525 /* b: variables */ 3526 ht = &curbuf->b_vars.dv_hashtab; 3527 if (bdone < ht->ht_used) 3528 { 3529 if (bdone++ == 0) 3530 hi = ht->ht_array; 3531 else 3532 ++hi; 3533 while (HASHITEM_EMPTY(hi)) 3534 ++hi; 3535 return cat_prefix_varname('b', hi->hi_key); 3536 } 3537 if (bdone == ht->ht_used) 3538 { 3539 ++bdone; 3540 return (char_u *)"b:changedtick"; 3541 } 3542 3543 /* w: variables */ 3544 ht = &curwin->w_vars.dv_hashtab; 3545 if (wdone < ht->ht_used) 3546 { 3547 if (wdone++ == 0) 3548 hi = ht->ht_array; 3549 else 3550 ++hi; 3551 while (HASHITEM_EMPTY(hi)) 3552 ++hi; 3553 return cat_prefix_varname('w', hi->hi_key); 3554 } 3555 3556 /* v: variables */ 3557 if (vidx < VV_LEN) 3558 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3559 3560 vim_free(varnamebuf); 3561 varnamebuf = NULL; 3562 varnamebuflen = 0; 3563 return NULL; 3564 } 3565 3566 #endif /* FEAT_CMDL_COMPL */ 3567 3568 /* 3569 * types for expressions. 3570 */ 3571 typedef enum 3572 { 3573 TYPE_UNKNOWN = 0 3574 , TYPE_EQUAL /* == */ 3575 , TYPE_NEQUAL /* != */ 3576 , TYPE_GREATER /* > */ 3577 , TYPE_GEQUAL /* >= */ 3578 , TYPE_SMALLER /* < */ 3579 , TYPE_SEQUAL /* <= */ 3580 , TYPE_MATCH /* =~ */ 3581 , TYPE_NOMATCH /* !~ */ 3582 } exptype_T; 3583 3584 /* 3585 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3586 * executed. The function may return OK, but the rettv will be of type 3587 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3588 */ 3589 3590 /* 3591 * Handle zero level expression. 3592 * This calls eval1() and handles error message and nextcmd. 3593 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3594 * Return OK or FAIL. 3595 */ 3596 static int 3597 eval0(arg, rettv, nextcmd, evaluate) 3598 char_u *arg; 3599 typval_T *rettv; 3600 char_u **nextcmd; 3601 int evaluate; 3602 { 3603 int ret; 3604 char_u *p; 3605 3606 p = skipwhite(arg); 3607 ret = eval1(&p, rettv, evaluate); 3608 if (ret == FAIL || !ends_excmd(*p)) 3609 { 3610 if (ret != FAIL) 3611 clear_tv(rettv); 3612 /* 3613 * Report the invalid expression unless the expression evaluation has 3614 * been cancelled due to an aborting error, an interrupt, or an 3615 * exception. 3616 */ 3617 if (!aborting()) 3618 EMSG2(_(e_invexpr2), arg); 3619 ret = FAIL; 3620 } 3621 if (nextcmd != NULL) 3622 *nextcmd = check_nextcmd(p); 3623 3624 return ret; 3625 } 3626 3627 /* 3628 * Handle top level expression: 3629 * expr1 ? expr0 : expr0 3630 * 3631 * "arg" must point to the first non-white of the expression. 3632 * "arg" is advanced to the next non-white after the recognized expression. 3633 * 3634 * Return OK or FAIL. 3635 */ 3636 static int 3637 eval1(arg, rettv, evaluate) 3638 char_u **arg; 3639 typval_T *rettv; 3640 int evaluate; 3641 { 3642 int result; 3643 typval_T var2; 3644 3645 /* 3646 * Get the first variable. 3647 */ 3648 if (eval2(arg, rettv, evaluate) == FAIL) 3649 return FAIL; 3650 3651 if ((*arg)[0] == '?') 3652 { 3653 result = FALSE; 3654 if (evaluate) 3655 { 3656 int error = FALSE; 3657 3658 if (get_tv_number_chk(rettv, &error) != 0) 3659 result = TRUE; 3660 clear_tv(rettv); 3661 if (error) 3662 return FAIL; 3663 } 3664 3665 /* 3666 * Get the second variable. 3667 */ 3668 *arg = skipwhite(*arg + 1); 3669 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3670 return FAIL; 3671 3672 /* 3673 * Check for the ":". 3674 */ 3675 if ((*arg)[0] != ':') 3676 { 3677 EMSG(_("E109: Missing ':' after '?'")); 3678 if (evaluate && result) 3679 clear_tv(rettv); 3680 return FAIL; 3681 } 3682 3683 /* 3684 * Get the third variable. 3685 */ 3686 *arg = skipwhite(*arg + 1); 3687 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3688 { 3689 if (evaluate && result) 3690 clear_tv(rettv); 3691 return FAIL; 3692 } 3693 if (evaluate && !result) 3694 *rettv = var2; 3695 } 3696 3697 return OK; 3698 } 3699 3700 /* 3701 * Handle first level expression: 3702 * expr2 || expr2 || expr2 logical OR 3703 * 3704 * "arg" must point to the first non-white of the expression. 3705 * "arg" is advanced to the next non-white after the recognized expression. 3706 * 3707 * Return OK or FAIL. 3708 */ 3709 static int 3710 eval2(arg, rettv, evaluate) 3711 char_u **arg; 3712 typval_T *rettv; 3713 int evaluate; 3714 { 3715 typval_T var2; 3716 long result; 3717 int first; 3718 int error = FALSE; 3719 3720 /* 3721 * Get the first variable. 3722 */ 3723 if (eval3(arg, rettv, evaluate) == FAIL) 3724 return FAIL; 3725 3726 /* 3727 * Repeat until there is no following "||". 3728 */ 3729 first = TRUE; 3730 result = FALSE; 3731 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3732 { 3733 if (evaluate && first) 3734 { 3735 if (get_tv_number_chk(rettv, &error) != 0) 3736 result = TRUE; 3737 clear_tv(rettv); 3738 if (error) 3739 return FAIL; 3740 first = FALSE; 3741 } 3742 3743 /* 3744 * Get the second variable. 3745 */ 3746 *arg = skipwhite(*arg + 2); 3747 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3748 return FAIL; 3749 3750 /* 3751 * Compute the result. 3752 */ 3753 if (evaluate && !result) 3754 { 3755 if (get_tv_number_chk(&var2, &error) != 0) 3756 result = TRUE; 3757 clear_tv(&var2); 3758 if (error) 3759 return FAIL; 3760 } 3761 if (evaluate) 3762 { 3763 rettv->v_type = VAR_NUMBER; 3764 rettv->vval.v_number = result; 3765 } 3766 } 3767 3768 return OK; 3769 } 3770 3771 /* 3772 * Handle second level expression: 3773 * expr3 && expr3 && expr3 logical AND 3774 * 3775 * "arg" must point to the first non-white of the expression. 3776 * "arg" is advanced to the next non-white after the recognized expression. 3777 * 3778 * Return OK or FAIL. 3779 */ 3780 static int 3781 eval3(arg, rettv, evaluate) 3782 char_u **arg; 3783 typval_T *rettv; 3784 int evaluate; 3785 { 3786 typval_T var2; 3787 long result; 3788 int first; 3789 int error = FALSE; 3790 3791 /* 3792 * Get the first variable. 3793 */ 3794 if (eval4(arg, rettv, evaluate) == FAIL) 3795 return FAIL; 3796 3797 /* 3798 * Repeat until there is no following "&&". 3799 */ 3800 first = TRUE; 3801 result = TRUE; 3802 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3803 { 3804 if (evaluate && first) 3805 { 3806 if (get_tv_number_chk(rettv, &error) == 0) 3807 result = FALSE; 3808 clear_tv(rettv); 3809 if (error) 3810 return FAIL; 3811 first = FALSE; 3812 } 3813 3814 /* 3815 * Get the second variable. 3816 */ 3817 *arg = skipwhite(*arg + 2); 3818 if (eval4(arg, &var2, evaluate && result) == FAIL) 3819 return FAIL; 3820 3821 /* 3822 * Compute the result. 3823 */ 3824 if (evaluate && result) 3825 { 3826 if (get_tv_number_chk(&var2, &error) == 0) 3827 result = FALSE; 3828 clear_tv(&var2); 3829 if (error) 3830 return FAIL; 3831 } 3832 if (evaluate) 3833 { 3834 rettv->v_type = VAR_NUMBER; 3835 rettv->vval.v_number = result; 3836 } 3837 } 3838 3839 return OK; 3840 } 3841 3842 /* 3843 * Handle third level expression: 3844 * var1 == var2 3845 * var1 =~ var2 3846 * var1 != var2 3847 * var1 !~ var2 3848 * var1 > var2 3849 * var1 >= var2 3850 * var1 < var2 3851 * var1 <= var2 3852 * var1 is var2 3853 * var1 isnot var2 3854 * 3855 * "arg" must point to the first non-white of the expression. 3856 * "arg" is advanced to the next non-white after the recognized expression. 3857 * 3858 * Return OK or FAIL. 3859 */ 3860 static int 3861 eval4(arg, rettv, evaluate) 3862 char_u **arg; 3863 typval_T *rettv; 3864 int evaluate; 3865 { 3866 typval_T var2; 3867 char_u *p; 3868 int i; 3869 exptype_T type = TYPE_UNKNOWN; 3870 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3871 int len = 2; 3872 long n1, n2; 3873 char_u *s1, *s2; 3874 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3875 regmatch_T regmatch; 3876 int ic; 3877 char_u *save_cpo; 3878 3879 /* 3880 * Get the first variable. 3881 */ 3882 if (eval5(arg, rettv, evaluate) == FAIL) 3883 return FAIL; 3884 3885 p = *arg; 3886 switch (p[0]) 3887 { 3888 case '=': if (p[1] == '=') 3889 type = TYPE_EQUAL; 3890 else if (p[1] == '~') 3891 type = TYPE_MATCH; 3892 break; 3893 case '!': if (p[1] == '=') 3894 type = TYPE_NEQUAL; 3895 else if (p[1] == '~') 3896 type = TYPE_NOMATCH; 3897 break; 3898 case '>': if (p[1] != '=') 3899 { 3900 type = TYPE_GREATER; 3901 len = 1; 3902 } 3903 else 3904 type = TYPE_GEQUAL; 3905 break; 3906 case '<': if (p[1] != '=') 3907 { 3908 type = TYPE_SMALLER; 3909 len = 1; 3910 } 3911 else 3912 type = TYPE_SEQUAL; 3913 break; 3914 case 'i': if (p[1] == 's') 3915 { 3916 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3917 len = 5; 3918 if (!vim_isIDc(p[len])) 3919 { 3920 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3921 type_is = TRUE; 3922 } 3923 } 3924 break; 3925 } 3926 3927 /* 3928 * If there is a comparitive operator, use it. 3929 */ 3930 if (type != TYPE_UNKNOWN) 3931 { 3932 /* extra question mark appended: ignore case */ 3933 if (p[len] == '?') 3934 { 3935 ic = TRUE; 3936 ++len; 3937 } 3938 /* extra '#' appended: match case */ 3939 else if (p[len] == '#') 3940 { 3941 ic = FALSE; 3942 ++len; 3943 } 3944 /* nothing appened: use 'ignorecase' */ 3945 else 3946 ic = p_ic; 3947 3948 /* 3949 * Get the second variable. 3950 */ 3951 *arg = skipwhite(p + len); 3952 if (eval5(arg, &var2, evaluate) == FAIL) 3953 { 3954 clear_tv(rettv); 3955 return FAIL; 3956 } 3957 3958 if (evaluate) 3959 { 3960 if (type_is && rettv->v_type != var2.v_type) 3961 { 3962 /* For "is" a different type always means FALSE, for "notis" 3963 * it means TRUE. */ 3964 n1 = (type == TYPE_NEQUAL); 3965 } 3966 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3967 { 3968 if (type_is) 3969 { 3970 n1 = (rettv->v_type == var2.v_type 3971 && rettv->vval.v_list == var2.vval.v_list); 3972 if (type == TYPE_NEQUAL) 3973 n1 = !n1; 3974 } 3975 else if (rettv->v_type != var2.v_type 3976 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3977 { 3978 if (rettv->v_type != var2.v_type) 3979 EMSG(_("E691: Can only compare List with List")); 3980 else 3981 EMSG(_("E692: Invalid operation for Lists")); 3982 clear_tv(rettv); 3983 clear_tv(&var2); 3984 return FAIL; 3985 } 3986 else 3987 { 3988 /* Compare two Lists for being equal or unequal. */ 3989 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3990 if (type == TYPE_NEQUAL) 3991 n1 = !n1; 3992 } 3993 } 3994 3995 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 3996 { 3997 if (type_is) 3998 { 3999 n1 = (rettv->v_type == var2.v_type 4000 && rettv->vval.v_dict == var2.vval.v_dict); 4001 if (type == TYPE_NEQUAL) 4002 n1 = !n1; 4003 } 4004 else if (rettv->v_type != var2.v_type 4005 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4006 { 4007 if (rettv->v_type != var2.v_type) 4008 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4009 else 4010 EMSG(_("E736: Invalid operation for Dictionary")); 4011 clear_tv(rettv); 4012 clear_tv(&var2); 4013 return FAIL; 4014 } 4015 else 4016 { 4017 /* Compare two Dictionaries for being equal or unequal. */ 4018 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4019 if (type == TYPE_NEQUAL) 4020 n1 = !n1; 4021 } 4022 } 4023 4024 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4025 { 4026 if (rettv->v_type != var2.v_type 4027 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4028 { 4029 if (rettv->v_type != var2.v_type) 4030 EMSG(_("E693: Can only compare Funcref with Funcref")); 4031 else 4032 EMSG(_("E694: Invalid operation for Funcrefs")); 4033 clear_tv(rettv); 4034 clear_tv(&var2); 4035 return FAIL; 4036 } 4037 else 4038 { 4039 /* Compare two Funcrefs for being equal or unequal. */ 4040 if (rettv->vval.v_string == NULL 4041 || var2.vval.v_string == NULL) 4042 n1 = FALSE; 4043 else 4044 n1 = STRCMP(rettv->vval.v_string, 4045 var2.vval.v_string) == 0; 4046 if (type == TYPE_NEQUAL) 4047 n1 = !n1; 4048 } 4049 } 4050 4051 /* 4052 * If one of the two variables is a number, compare as a number. 4053 * When using "=~" or "!~", always compare as string. 4054 */ 4055 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4056 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4057 { 4058 n1 = get_tv_number(rettv); 4059 n2 = get_tv_number(&var2); 4060 switch (type) 4061 { 4062 case TYPE_EQUAL: n1 = (n1 == n2); break; 4063 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4064 case TYPE_GREATER: n1 = (n1 > n2); break; 4065 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4066 case TYPE_SMALLER: n1 = (n1 < n2); break; 4067 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4068 case TYPE_UNKNOWN: 4069 case TYPE_MATCH: 4070 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4071 } 4072 } 4073 else 4074 { 4075 s1 = get_tv_string_buf(rettv, buf1); 4076 s2 = get_tv_string_buf(&var2, buf2); 4077 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4078 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4079 else 4080 i = 0; 4081 n1 = FALSE; 4082 switch (type) 4083 { 4084 case TYPE_EQUAL: n1 = (i == 0); break; 4085 case TYPE_NEQUAL: n1 = (i != 0); break; 4086 case TYPE_GREATER: n1 = (i > 0); break; 4087 case TYPE_GEQUAL: n1 = (i >= 0); break; 4088 case TYPE_SMALLER: n1 = (i < 0); break; 4089 case TYPE_SEQUAL: n1 = (i <= 0); break; 4090 4091 case TYPE_MATCH: 4092 case TYPE_NOMATCH: 4093 /* avoid 'l' flag in 'cpoptions' */ 4094 save_cpo = p_cpo; 4095 p_cpo = (char_u *)""; 4096 regmatch.regprog = vim_regcomp(s2, 4097 RE_MAGIC + RE_STRING); 4098 regmatch.rm_ic = ic; 4099 if (regmatch.regprog != NULL) 4100 { 4101 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4102 vim_free(regmatch.regprog); 4103 if (type == TYPE_NOMATCH) 4104 n1 = !n1; 4105 } 4106 p_cpo = save_cpo; 4107 break; 4108 4109 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4110 } 4111 } 4112 clear_tv(rettv); 4113 clear_tv(&var2); 4114 rettv->v_type = VAR_NUMBER; 4115 rettv->vval.v_number = n1; 4116 } 4117 } 4118 4119 return OK; 4120 } 4121 4122 /* 4123 * Handle fourth level expression: 4124 * + number addition 4125 * - number subtraction 4126 * . string concatenation 4127 * 4128 * "arg" must point to the first non-white of the expression. 4129 * "arg" is advanced to the next non-white after the recognized expression. 4130 * 4131 * Return OK or FAIL. 4132 */ 4133 static int 4134 eval5(arg, rettv, evaluate) 4135 char_u **arg; 4136 typval_T *rettv; 4137 int evaluate; 4138 { 4139 typval_T var2; 4140 typval_T var3; 4141 int op; 4142 long n1, n2; 4143 char_u *s1, *s2; 4144 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4145 char_u *p; 4146 4147 /* 4148 * Get the first variable. 4149 */ 4150 if (eval6(arg, rettv, evaluate) == FAIL) 4151 return FAIL; 4152 4153 /* 4154 * Repeat computing, until no '+', '-' or '.' is following. 4155 */ 4156 for (;;) 4157 { 4158 op = **arg; 4159 if (op != '+' && op != '-' && op != '.') 4160 break; 4161 4162 if (op != '+' || rettv->v_type != VAR_LIST) 4163 { 4164 /* For "list + ...", an illegal use of the first operand as 4165 * a number cannot be determined before evaluating the 2nd 4166 * operand: if this is also a list, all is ok. 4167 * For "something . ...", "something - ..." or "non-list + ...", 4168 * we know that the first operand needs to be a string or number 4169 * without evaluating the 2nd operand. So check before to avoid 4170 * side effects after an error. */ 4171 if (evaluate && get_tv_string_chk(rettv) == NULL) 4172 { 4173 clear_tv(rettv); 4174 return FAIL; 4175 } 4176 } 4177 4178 /* 4179 * Get the second variable. 4180 */ 4181 *arg = skipwhite(*arg + 1); 4182 if (eval6(arg, &var2, evaluate) == FAIL) 4183 { 4184 clear_tv(rettv); 4185 return FAIL; 4186 } 4187 4188 if (evaluate) 4189 { 4190 /* 4191 * Compute the result. 4192 */ 4193 if (op == '.') 4194 { 4195 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4196 s2 = get_tv_string_buf_chk(&var2, buf2); 4197 if (s2 == NULL) /* type error ? */ 4198 { 4199 clear_tv(rettv); 4200 clear_tv(&var2); 4201 return FAIL; 4202 } 4203 p = concat_str(s1, s2); 4204 clear_tv(rettv); 4205 rettv->v_type = VAR_STRING; 4206 rettv->vval.v_string = p; 4207 } 4208 else if (op == '+' && rettv->v_type == VAR_LIST 4209 && var2.v_type == VAR_LIST) 4210 { 4211 /* concatenate Lists */ 4212 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4213 &var3) == FAIL) 4214 { 4215 clear_tv(rettv); 4216 clear_tv(&var2); 4217 return FAIL; 4218 } 4219 clear_tv(rettv); 4220 *rettv = var3; 4221 } 4222 else 4223 { 4224 int error = FALSE; 4225 4226 n1 = get_tv_number_chk(rettv, &error); 4227 if (error) 4228 { 4229 /* This can only happen for "list + non-list". 4230 * For "non-list + ..." or "something - ...", we returned 4231 * before evaluating the 2nd operand. */ 4232 clear_tv(rettv); 4233 return FAIL; 4234 } 4235 n2 = get_tv_number_chk(&var2, &error); 4236 if (error) 4237 { 4238 clear_tv(rettv); 4239 clear_tv(&var2); 4240 return FAIL; 4241 } 4242 clear_tv(rettv); 4243 if (op == '+') 4244 n1 = n1 + n2; 4245 else 4246 n1 = n1 - n2; 4247 rettv->v_type = VAR_NUMBER; 4248 rettv->vval.v_number = n1; 4249 } 4250 clear_tv(&var2); 4251 } 4252 } 4253 return OK; 4254 } 4255 4256 /* 4257 * Handle fifth level expression: 4258 * * number multiplication 4259 * / number division 4260 * % number modulo 4261 * 4262 * "arg" must point to the first non-white of the expression. 4263 * "arg" is advanced to the next non-white after the recognized expression. 4264 * 4265 * Return OK or FAIL. 4266 */ 4267 static int 4268 eval6(arg, rettv, evaluate) 4269 char_u **arg; 4270 typval_T *rettv; 4271 int evaluate; 4272 { 4273 typval_T var2; 4274 int op; 4275 long n1, n2; 4276 int error = FALSE; 4277 4278 /* 4279 * Get the first variable. 4280 */ 4281 if (eval7(arg, rettv, evaluate) == FAIL) 4282 return FAIL; 4283 4284 /* 4285 * Repeat computing, until no '*', '/' or '%' is following. 4286 */ 4287 for (;;) 4288 { 4289 op = **arg; 4290 if (op != '*' && op != '/' && op != '%') 4291 break; 4292 4293 if (evaluate) 4294 { 4295 n1 = get_tv_number_chk(rettv, &error); 4296 clear_tv(rettv); 4297 if (error) 4298 return FAIL; 4299 } 4300 else 4301 n1 = 0; 4302 4303 /* 4304 * Get the second variable. 4305 */ 4306 *arg = skipwhite(*arg + 1); 4307 if (eval7(arg, &var2, evaluate) == FAIL) 4308 return FAIL; 4309 4310 if (evaluate) 4311 { 4312 n2 = get_tv_number_chk(&var2, &error); 4313 clear_tv(&var2); 4314 if (error) 4315 return FAIL; 4316 4317 /* 4318 * Compute the result. 4319 */ 4320 if (op == '*') 4321 n1 = n1 * n2; 4322 else if (op == '/') 4323 { 4324 if (n2 == 0) /* give an error message? */ 4325 n1 = 0x7fffffffL; 4326 else 4327 n1 = n1 / n2; 4328 } 4329 else 4330 { 4331 if (n2 == 0) /* give an error message? */ 4332 n1 = 0; 4333 else 4334 n1 = n1 % n2; 4335 } 4336 rettv->v_type = VAR_NUMBER; 4337 rettv->vval.v_number = n1; 4338 } 4339 } 4340 4341 return OK; 4342 } 4343 4344 /* 4345 * Handle sixth level expression: 4346 * number number constant 4347 * "string" string contstant 4348 * 'string' literal string contstant 4349 * &option-name option value 4350 * @r register contents 4351 * identifier variable value 4352 * function() function call 4353 * $VAR environment variable 4354 * (expression) nested expression 4355 * [expr, expr] List 4356 * {key: val, key: val} Dictionary 4357 * 4358 * Also handle: 4359 * ! in front logical NOT 4360 * - in front unary minus 4361 * + in front unary plus (ignored) 4362 * trailing [] subscript in String or List 4363 * trailing .name entry in Dictionary 4364 * 4365 * "arg" must point to the first non-white of the expression. 4366 * "arg" is advanced to the next non-white after the recognized expression. 4367 * 4368 * Return OK or FAIL. 4369 */ 4370 static int 4371 eval7(arg, rettv, evaluate) 4372 char_u **arg; 4373 typval_T *rettv; 4374 int evaluate; 4375 { 4376 long n; 4377 int len; 4378 char_u *s; 4379 int val; 4380 char_u *start_leader, *end_leader; 4381 int ret = OK; 4382 char_u *alias; 4383 4384 /* 4385 * Initialise variable so that clear_tv() can't mistake this for a 4386 * string and free a string that isn't there. 4387 */ 4388 rettv->v_type = VAR_UNKNOWN; 4389 4390 /* 4391 * Skip '!' and '-' characters. They are handled later. 4392 */ 4393 start_leader = *arg; 4394 while (**arg == '!' || **arg == '-' || **arg == '+') 4395 *arg = skipwhite(*arg + 1); 4396 end_leader = *arg; 4397 4398 switch (**arg) 4399 { 4400 /* 4401 * Number constant. 4402 */ 4403 case '0': 4404 case '1': 4405 case '2': 4406 case '3': 4407 case '4': 4408 case '5': 4409 case '6': 4410 case '7': 4411 case '8': 4412 case '9': 4413 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4414 *arg += len; 4415 if (evaluate) 4416 { 4417 rettv->v_type = VAR_NUMBER; 4418 rettv->vval.v_number = n; 4419 } 4420 break; 4421 4422 /* 4423 * String constant: "string". 4424 */ 4425 case '"': ret = get_string_tv(arg, rettv, evaluate); 4426 break; 4427 4428 /* 4429 * Literal string constant: 'str''ing'. 4430 */ 4431 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4432 break; 4433 4434 /* 4435 * List: [expr, expr] 4436 */ 4437 case '[': ret = get_list_tv(arg, rettv, evaluate); 4438 break; 4439 4440 /* 4441 * Dictionary: {key: val, key: val} 4442 */ 4443 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4444 break; 4445 4446 /* 4447 * Option value: &name 4448 */ 4449 case '&': ret = get_option_tv(arg, rettv, evaluate); 4450 break; 4451 4452 /* 4453 * Environment variable: $VAR. 4454 */ 4455 case '$': ret = get_env_tv(arg, rettv, evaluate); 4456 break; 4457 4458 /* 4459 * Register contents: @r. 4460 */ 4461 case '@': ++*arg; 4462 if (evaluate) 4463 { 4464 rettv->v_type = VAR_STRING; 4465 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4466 } 4467 if (**arg != NUL) 4468 ++*arg; 4469 break; 4470 4471 /* 4472 * nested expression: (expression). 4473 */ 4474 case '(': *arg = skipwhite(*arg + 1); 4475 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4476 if (**arg == ')') 4477 ++*arg; 4478 else if (ret == OK) 4479 { 4480 EMSG(_("E110: Missing ')'")); 4481 clear_tv(rettv); 4482 ret = FAIL; 4483 } 4484 break; 4485 4486 default: ret = NOTDONE; 4487 break; 4488 } 4489 4490 if (ret == NOTDONE) 4491 { 4492 /* 4493 * Must be a variable or function name. 4494 * Can also be a curly-braces kind of name: {expr}. 4495 */ 4496 s = *arg; 4497 len = get_name_len(arg, &alias, evaluate, TRUE); 4498 if (alias != NULL) 4499 s = alias; 4500 4501 if (len <= 0) 4502 ret = FAIL; 4503 else 4504 { 4505 if (**arg == '(') /* recursive! */ 4506 { 4507 /* If "s" is the name of a variable of type VAR_FUNC 4508 * use its contents. */ 4509 s = deref_func_name(s, &len); 4510 4511 /* Invoke the function. */ 4512 ret = get_func_tv(s, len, rettv, arg, 4513 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4514 &len, evaluate, NULL); 4515 /* Stop the expression evaluation when immediately 4516 * aborting on error, or when an interrupt occurred or 4517 * an exception was thrown but not caught. */ 4518 if (aborting()) 4519 { 4520 if (ret == OK) 4521 clear_tv(rettv); 4522 ret = FAIL; 4523 } 4524 } 4525 else if (evaluate) 4526 ret = get_var_tv(s, len, rettv, TRUE); 4527 else 4528 ret = OK; 4529 } 4530 4531 if (alias != NULL) 4532 vim_free(alias); 4533 } 4534 4535 *arg = skipwhite(*arg); 4536 4537 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4538 * expr(expr). */ 4539 if (ret == OK) 4540 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4541 4542 /* 4543 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4544 */ 4545 if (ret == OK && evaluate && end_leader > start_leader) 4546 { 4547 int error = FALSE; 4548 4549 val = get_tv_number_chk(rettv, &error); 4550 if (error) 4551 { 4552 clear_tv(rettv); 4553 ret = FAIL; 4554 } 4555 else 4556 { 4557 while (end_leader > start_leader) 4558 { 4559 --end_leader; 4560 if (*end_leader == '!') 4561 val = !val; 4562 else if (*end_leader == '-') 4563 val = -val; 4564 } 4565 clear_tv(rettv); 4566 rettv->v_type = VAR_NUMBER; 4567 rettv->vval.v_number = val; 4568 } 4569 } 4570 4571 return ret; 4572 } 4573 4574 /* 4575 * Evaluate an "[expr]" or "[expr:expr]" index. 4576 * "*arg" points to the '['. 4577 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4578 */ 4579 static int 4580 eval_index(arg, rettv, evaluate, verbose) 4581 char_u **arg; 4582 typval_T *rettv; 4583 int evaluate; 4584 int verbose; /* give error messages */ 4585 { 4586 int empty1 = FALSE, empty2 = FALSE; 4587 typval_T var1, var2; 4588 long n1, n2 = 0; 4589 long len = -1; 4590 int range = FALSE; 4591 char_u *s; 4592 char_u *key = NULL; 4593 4594 if (rettv->v_type == VAR_FUNC) 4595 { 4596 if (verbose) 4597 EMSG(_("E695: Cannot index a Funcref")); 4598 return FAIL; 4599 } 4600 4601 if (**arg == '.') 4602 { 4603 /* 4604 * dict.name 4605 */ 4606 key = *arg + 1; 4607 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4608 ; 4609 if (len == 0) 4610 return FAIL; 4611 *arg = skipwhite(key + len); 4612 } 4613 else 4614 { 4615 /* 4616 * something[idx] 4617 * 4618 * Get the (first) variable from inside the []. 4619 */ 4620 *arg = skipwhite(*arg + 1); 4621 if (**arg == ':') 4622 empty1 = TRUE; 4623 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4624 return FAIL; 4625 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4626 { 4627 /* not a number or string */ 4628 clear_tv(&var1); 4629 return FAIL; 4630 } 4631 4632 /* 4633 * Get the second variable from inside the [:]. 4634 */ 4635 if (**arg == ':') 4636 { 4637 range = TRUE; 4638 *arg = skipwhite(*arg + 1); 4639 if (**arg == ']') 4640 empty2 = TRUE; 4641 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4642 { 4643 if (!empty1) 4644 clear_tv(&var1); 4645 return FAIL; 4646 } 4647 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4648 { 4649 /* not a number or string */ 4650 if (!empty1) 4651 clear_tv(&var1); 4652 clear_tv(&var2); 4653 return FAIL; 4654 } 4655 } 4656 4657 /* Check for the ']'. */ 4658 if (**arg != ']') 4659 { 4660 if (verbose) 4661 EMSG(_(e_missbrac)); 4662 clear_tv(&var1); 4663 if (range) 4664 clear_tv(&var2); 4665 return FAIL; 4666 } 4667 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4668 } 4669 4670 if (evaluate) 4671 { 4672 n1 = 0; 4673 if (!empty1 && rettv->v_type != VAR_DICT) 4674 { 4675 n1 = get_tv_number(&var1); 4676 clear_tv(&var1); 4677 } 4678 if (range) 4679 { 4680 if (empty2) 4681 n2 = -1; 4682 else 4683 { 4684 n2 = get_tv_number(&var2); 4685 clear_tv(&var2); 4686 } 4687 } 4688 4689 switch (rettv->v_type) 4690 { 4691 case VAR_NUMBER: 4692 case VAR_STRING: 4693 s = get_tv_string(rettv); 4694 len = (long)STRLEN(s); 4695 if (range) 4696 { 4697 /* The resulting variable is a substring. If the indexes 4698 * are out of range the result is empty. */ 4699 if (n1 < 0) 4700 { 4701 n1 = len + n1; 4702 if (n1 < 0) 4703 n1 = 0; 4704 } 4705 if (n2 < 0) 4706 n2 = len + n2; 4707 else if (n2 >= len) 4708 n2 = len; 4709 if (n1 >= len || n2 < 0 || n1 > n2) 4710 s = NULL; 4711 else 4712 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4713 } 4714 else 4715 { 4716 /* The resulting variable is a string of a single 4717 * character. If the index is too big or negative the 4718 * result is empty. */ 4719 if (n1 >= len || n1 < 0) 4720 s = NULL; 4721 else 4722 s = vim_strnsave(s + n1, 1); 4723 } 4724 clear_tv(rettv); 4725 rettv->v_type = VAR_STRING; 4726 rettv->vval.v_string = s; 4727 break; 4728 4729 case VAR_LIST: 4730 len = list_len(rettv->vval.v_list); 4731 if (n1 < 0) 4732 n1 = len + n1; 4733 if (!empty1 && (n1 < 0 || n1 >= len)) 4734 { 4735 if (verbose) 4736 EMSGN(_(e_listidx), n1); 4737 return FAIL; 4738 } 4739 if (range) 4740 { 4741 list_T *l; 4742 listitem_T *item; 4743 4744 if (n2 < 0) 4745 n2 = len + n2; 4746 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4747 { 4748 if (verbose) 4749 EMSGN(_(e_listidx), n2); 4750 return FAIL; 4751 } 4752 l = list_alloc(); 4753 if (l == NULL) 4754 return FAIL; 4755 for (item = list_find(rettv->vval.v_list, n1); 4756 n1 <= n2; ++n1) 4757 { 4758 if (list_append_tv(l, &item->li_tv) == FAIL) 4759 { 4760 list_free(l); 4761 return FAIL; 4762 } 4763 item = item->li_next; 4764 } 4765 clear_tv(rettv); 4766 rettv->v_type = VAR_LIST; 4767 rettv->vval.v_list = l; 4768 ++l->lv_refcount; 4769 } 4770 else 4771 { 4772 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4773 &var1); 4774 clear_tv(rettv); 4775 *rettv = var1; 4776 } 4777 break; 4778 4779 case VAR_DICT: 4780 if (range) 4781 { 4782 if (verbose) 4783 EMSG(_(e_dictrange)); 4784 if (len == -1) 4785 clear_tv(&var1); 4786 return FAIL; 4787 } 4788 { 4789 dictitem_T *item; 4790 4791 if (len == -1) 4792 { 4793 key = get_tv_string(&var1); 4794 if (*key == NUL) 4795 { 4796 if (verbose) 4797 EMSG(_(e_emptykey)); 4798 clear_tv(&var1); 4799 return FAIL; 4800 } 4801 } 4802 4803 item = dict_find(rettv->vval.v_dict, key, (int)len); 4804 4805 if (item == NULL && verbose) 4806 EMSG2(_(e_dictkey), key); 4807 if (len == -1) 4808 clear_tv(&var1); 4809 if (item == NULL) 4810 return FAIL; 4811 4812 copy_tv(&item->di_tv, &var1); 4813 clear_tv(rettv); 4814 *rettv = var1; 4815 } 4816 break; 4817 } 4818 } 4819 4820 return OK; 4821 } 4822 4823 /* 4824 * Get an option value. 4825 * "arg" points to the '&' or '+' before the option name. 4826 * "arg" is advanced to character after the option name. 4827 * Return OK or FAIL. 4828 */ 4829 static int 4830 get_option_tv(arg, rettv, evaluate) 4831 char_u **arg; 4832 typval_T *rettv; /* when NULL, only check if option exists */ 4833 int evaluate; 4834 { 4835 char_u *option_end; 4836 long numval; 4837 char_u *stringval; 4838 int opt_type; 4839 int c; 4840 int working = (**arg == '+'); /* has("+option") */ 4841 int ret = OK; 4842 int opt_flags; 4843 4844 /* 4845 * Isolate the option name and find its value. 4846 */ 4847 option_end = find_option_end(arg, &opt_flags); 4848 if (option_end == NULL) 4849 { 4850 if (rettv != NULL) 4851 EMSG2(_("E112: Option name missing: %s"), *arg); 4852 return FAIL; 4853 } 4854 4855 if (!evaluate) 4856 { 4857 *arg = option_end; 4858 return OK; 4859 } 4860 4861 c = *option_end; 4862 *option_end = NUL; 4863 opt_type = get_option_value(*arg, &numval, 4864 rettv == NULL ? NULL : &stringval, opt_flags); 4865 4866 if (opt_type == -3) /* invalid name */ 4867 { 4868 if (rettv != NULL) 4869 EMSG2(_("E113: Unknown option: %s"), *arg); 4870 ret = FAIL; 4871 } 4872 else if (rettv != NULL) 4873 { 4874 if (opt_type == -2) /* hidden string option */ 4875 { 4876 rettv->v_type = VAR_STRING; 4877 rettv->vval.v_string = NULL; 4878 } 4879 else if (opt_type == -1) /* hidden number option */ 4880 { 4881 rettv->v_type = VAR_NUMBER; 4882 rettv->vval.v_number = 0; 4883 } 4884 else if (opt_type == 1) /* number option */ 4885 { 4886 rettv->v_type = VAR_NUMBER; 4887 rettv->vval.v_number = numval; 4888 } 4889 else /* string option */ 4890 { 4891 rettv->v_type = VAR_STRING; 4892 rettv->vval.v_string = stringval; 4893 } 4894 } 4895 else if (working && (opt_type == -2 || opt_type == -1)) 4896 ret = FAIL; 4897 4898 *option_end = c; /* put back for error messages */ 4899 *arg = option_end; 4900 4901 return ret; 4902 } 4903 4904 /* 4905 * Allocate a variable for a string constant. 4906 * Return OK or FAIL. 4907 */ 4908 static int 4909 get_string_tv(arg, rettv, evaluate) 4910 char_u **arg; 4911 typval_T *rettv; 4912 int evaluate; 4913 { 4914 char_u *p; 4915 char_u *name; 4916 int extra = 0; 4917 4918 /* 4919 * Find the end of the string, skipping backslashed characters. 4920 */ 4921 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4922 { 4923 if (*p == '\\' && p[1] != NUL) 4924 { 4925 ++p; 4926 /* A "\<x>" form occupies at least 4 characters, and produces up 4927 * to 6 characters: reserve space for 2 extra */ 4928 if (*p == '<') 4929 extra += 2; 4930 } 4931 } 4932 4933 if (*p != '"') 4934 { 4935 EMSG2(_("E114: Missing quote: %s"), *arg); 4936 return FAIL; 4937 } 4938 4939 /* If only parsing, set *arg and return here */ 4940 if (!evaluate) 4941 { 4942 *arg = p + 1; 4943 return OK; 4944 } 4945 4946 /* 4947 * Copy the string into allocated memory, handling backslashed 4948 * characters. 4949 */ 4950 name = alloc((unsigned)(p - *arg + extra)); 4951 if (name == NULL) 4952 return FAIL; 4953 rettv->v_type = VAR_STRING; 4954 rettv->vval.v_string = name; 4955 4956 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4957 { 4958 if (*p == '\\') 4959 { 4960 switch (*++p) 4961 { 4962 case 'b': *name++ = BS; ++p; break; 4963 case 'e': *name++ = ESC; ++p; break; 4964 case 'f': *name++ = FF; ++p; break; 4965 case 'n': *name++ = NL; ++p; break; 4966 case 'r': *name++ = CAR; ++p; break; 4967 case 't': *name++ = TAB; ++p; break; 4968 4969 case 'X': /* hex: "\x1", "\x12" */ 4970 case 'x': 4971 case 'u': /* Unicode: "\u0023" */ 4972 case 'U': 4973 if (vim_isxdigit(p[1])) 4974 { 4975 int n, nr; 4976 int c = toupper(*p); 4977 4978 if (c == 'X') 4979 n = 2; 4980 else 4981 n = 4; 4982 nr = 0; 4983 while (--n >= 0 && vim_isxdigit(p[1])) 4984 { 4985 ++p; 4986 nr = (nr << 4) + hex2nr(*p); 4987 } 4988 ++p; 4989 #ifdef FEAT_MBYTE 4990 /* For "\u" store the number according to 4991 * 'encoding'. */ 4992 if (c != 'X') 4993 name += (*mb_char2bytes)(nr, name); 4994 else 4995 #endif 4996 *name++ = nr; 4997 } 4998 break; 4999 5000 /* octal: "\1", "\12", "\123" */ 5001 case '0': 5002 case '1': 5003 case '2': 5004 case '3': 5005 case '4': 5006 case '5': 5007 case '6': 5008 case '7': *name = *p++ - '0'; 5009 if (*p >= '0' && *p <= '7') 5010 { 5011 *name = (*name << 3) + *p++ - '0'; 5012 if (*p >= '0' && *p <= '7') 5013 *name = (*name << 3) + *p++ - '0'; 5014 } 5015 ++name; 5016 break; 5017 5018 /* Special key, e.g.: "\<C-W>" */ 5019 case '<': extra = trans_special(&p, name, TRUE); 5020 if (extra != 0) 5021 { 5022 name += extra; 5023 break; 5024 } 5025 /* FALLTHROUGH */ 5026 5027 default: MB_COPY_CHAR(p, name); 5028 break; 5029 } 5030 } 5031 else 5032 MB_COPY_CHAR(p, name); 5033 5034 } 5035 *name = NUL; 5036 *arg = p + 1; 5037 5038 return OK; 5039 } 5040 5041 /* 5042 * Allocate a variable for a 'str''ing' constant. 5043 * Return OK or FAIL. 5044 */ 5045 static int 5046 get_lit_string_tv(arg, rettv, evaluate) 5047 char_u **arg; 5048 typval_T *rettv; 5049 int evaluate; 5050 { 5051 char_u *p; 5052 char_u *str; 5053 int reduce = 0; 5054 5055 /* 5056 * Find the end of the string, skipping ''. 5057 */ 5058 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5059 { 5060 if (*p == '\'') 5061 { 5062 if (p[1] != '\'') 5063 break; 5064 ++reduce; 5065 ++p; 5066 } 5067 } 5068 5069 if (*p != '\'') 5070 { 5071 EMSG2(_("E115: Missing quote: %s"), *arg); 5072 return FAIL; 5073 } 5074 5075 /* If only parsing return after setting "*arg" */ 5076 if (!evaluate) 5077 { 5078 *arg = p + 1; 5079 return OK; 5080 } 5081 5082 /* 5083 * Copy the string into allocated memory, handling '' to ' reduction. 5084 */ 5085 str = alloc((unsigned)((p - *arg) - reduce)); 5086 if (str == NULL) 5087 return FAIL; 5088 rettv->v_type = VAR_STRING; 5089 rettv->vval.v_string = str; 5090 5091 for (p = *arg + 1; *p != NUL; ) 5092 { 5093 if (*p == '\'') 5094 { 5095 if (p[1] != '\'') 5096 break; 5097 ++p; 5098 } 5099 MB_COPY_CHAR(p, str); 5100 } 5101 *str = NUL; 5102 *arg = p + 1; 5103 5104 return OK; 5105 } 5106 5107 /* 5108 * Allocate a variable for a List and fill it from "*arg". 5109 * Return OK or FAIL. 5110 */ 5111 static int 5112 get_list_tv(arg, rettv, evaluate) 5113 char_u **arg; 5114 typval_T *rettv; 5115 int evaluate; 5116 { 5117 list_T *l = NULL; 5118 typval_T tv; 5119 listitem_T *item; 5120 5121 if (evaluate) 5122 { 5123 l = list_alloc(); 5124 if (l == NULL) 5125 return FAIL; 5126 } 5127 5128 *arg = skipwhite(*arg + 1); 5129 while (**arg != ']' && **arg != NUL) 5130 { 5131 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5132 goto failret; 5133 if (evaluate) 5134 { 5135 item = listitem_alloc(); 5136 if (item != NULL) 5137 { 5138 item->li_tv = tv; 5139 item->li_tv.v_lock = 0; 5140 list_append(l, item); 5141 } 5142 else 5143 clear_tv(&tv); 5144 } 5145 5146 if (**arg == ']') 5147 break; 5148 if (**arg != ',') 5149 { 5150 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5151 goto failret; 5152 } 5153 *arg = skipwhite(*arg + 1); 5154 } 5155 5156 if (**arg != ']') 5157 { 5158 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5159 failret: 5160 if (evaluate) 5161 list_free(l); 5162 return FAIL; 5163 } 5164 5165 *arg = skipwhite(*arg + 1); 5166 if (evaluate) 5167 { 5168 rettv->v_type = VAR_LIST; 5169 rettv->vval.v_list = l; 5170 ++l->lv_refcount; 5171 } 5172 5173 return OK; 5174 } 5175 5176 /* 5177 * Allocate an empty header for a list. 5178 */ 5179 static list_T * 5180 list_alloc() 5181 { 5182 list_T *l; 5183 5184 l = (list_T *)alloc_clear(sizeof(list_T)); 5185 if (l != NULL) 5186 { 5187 /* Prepend the list to the list of lists for garbage collection. */ 5188 if (first_list != NULL) 5189 first_list->lv_used_prev = l; 5190 l->lv_used_prev = NULL; 5191 l->lv_used_next = first_list; 5192 first_list = l; 5193 } 5194 return l; 5195 } 5196 5197 /* 5198 * Unreference a list: decrement the reference count and free it when it 5199 * becomes zero. 5200 */ 5201 void 5202 list_unref(l) 5203 list_T *l; 5204 { 5205 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5206 list_free(l); 5207 } 5208 5209 /* 5210 * Free a list, including all items it points to. 5211 * Ignores the reference count. 5212 */ 5213 static void 5214 list_free(l) 5215 list_T *l; 5216 { 5217 listitem_T *item; 5218 5219 /* Avoid that recursive reference to the list frees us again. */ 5220 l->lv_refcount = DEL_REFCOUNT; 5221 5222 /* Remove the list from the list of lists for garbage collection. */ 5223 if (l->lv_used_prev == NULL) 5224 first_list = l->lv_used_next; 5225 else 5226 l->lv_used_prev->lv_used_next = l->lv_used_next; 5227 if (l->lv_used_next != NULL) 5228 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5229 5230 for (item = l->lv_first; item != NULL; item = l->lv_first) 5231 { 5232 /* Remove the item before deleting it. */ 5233 l->lv_first = item->li_next; 5234 listitem_free(item); 5235 } 5236 vim_free(l); 5237 } 5238 5239 /* 5240 * Allocate a list item. 5241 */ 5242 static listitem_T * 5243 listitem_alloc() 5244 { 5245 return (listitem_T *)alloc(sizeof(listitem_T)); 5246 } 5247 5248 /* 5249 * Free a list item. Also clears the value. Does not notify watchers. 5250 */ 5251 static void 5252 listitem_free(item) 5253 listitem_T *item; 5254 { 5255 clear_tv(&item->li_tv); 5256 vim_free(item); 5257 } 5258 5259 /* 5260 * Remove a list item from a List and free it. Also clears the value. 5261 */ 5262 static void 5263 listitem_remove(l, item) 5264 list_T *l; 5265 listitem_T *item; 5266 { 5267 list_remove(l, item, item); 5268 listitem_free(item); 5269 } 5270 5271 /* 5272 * Get the number of items in a list. 5273 */ 5274 static long 5275 list_len(l) 5276 list_T *l; 5277 { 5278 if (l == NULL) 5279 return 0L; 5280 return l->lv_len; 5281 } 5282 5283 /* 5284 * Return TRUE when two lists have exactly the same values. 5285 */ 5286 static int 5287 list_equal(l1, l2, ic) 5288 list_T *l1; 5289 list_T *l2; 5290 int ic; /* ignore case for strings */ 5291 { 5292 listitem_T *item1, *item2; 5293 5294 if (list_len(l1) != list_len(l2)) 5295 return FALSE; 5296 5297 for (item1 = l1->lv_first, item2 = l2->lv_first; 5298 item1 != NULL && item2 != NULL; 5299 item1 = item1->li_next, item2 = item2->li_next) 5300 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5301 return FALSE; 5302 return item1 == NULL && item2 == NULL; 5303 } 5304 5305 /* 5306 * Return TRUE when two dictionaries have exactly the same key/values. 5307 */ 5308 static int 5309 dict_equal(d1, d2, ic) 5310 dict_T *d1; 5311 dict_T *d2; 5312 int ic; /* ignore case for strings */ 5313 { 5314 hashitem_T *hi; 5315 dictitem_T *item2; 5316 int todo; 5317 5318 if (dict_len(d1) != dict_len(d2)) 5319 return FALSE; 5320 5321 todo = d1->dv_hashtab.ht_used; 5322 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5323 { 5324 if (!HASHITEM_EMPTY(hi)) 5325 { 5326 item2 = dict_find(d2, hi->hi_key, -1); 5327 if (item2 == NULL) 5328 return FALSE; 5329 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5330 return FALSE; 5331 --todo; 5332 } 5333 } 5334 return TRUE; 5335 } 5336 5337 /* 5338 * Return TRUE if "tv1" and "tv2" have the same value. 5339 * Compares the items just like "==" would compare them, but strings and 5340 * numbers are different. 5341 */ 5342 static int 5343 tv_equal(tv1, tv2, ic) 5344 typval_T *tv1; 5345 typval_T *tv2; 5346 int ic; /* ignore case */ 5347 { 5348 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5349 char_u *s1, *s2; 5350 5351 if (tv1->v_type != tv2->v_type) 5352 return FALSE; 5353 5354 switch (tv1->v_type) 5355 { 5356 case VAR_LIST: 5357 /* recursive! */ 5358 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5359 5360 case VAR_DICT: 5361 /* recursive! */ 5362 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5363 5364 case VAR_FUNC: 5365 return (tv1->vval.v_string != NULL 5366 && tv2->vval.v_string != NULL 5367 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5368 5369 case VAR_NUMBER: 5370 return tv1->vval.v_number == tv2->vval.v_number; 5371 5372 case VAR_STRING: 5373 s1 = get_tv_string_buf(tv1, buf1); 5374 s2 = get_tv_string_buf(tv2, buf2); 5375 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5376 } 5377 5378 EMSG2(_(e_intern2), "tv_equal()"); 5379 return TRUE; 5380 } 5381 5382 /* 5383 * Locate item with index "n" in list "l" and return it. 5384 * A negative index is counted from the end; -1 is the last item. 5385 * Returns NULL when "n" is out of range. 5386 */ 5387 static listitem_T * 5388 list_find(l, n) 5389 list_T *l; 5390 long n; 5391 { 5392 listitem_T *item; 5393 long idx; 5394 5395 if (l == NULL) 5396 return NULL; 5397 5398 /* Negative index is relative to the end. */ 5399 if (n < 0) 5400 n = l->lv_len + n; 5401 5402 /* Check for index out of range. */ 5403 if (n < 0 || n >= l->lv_len) 5404 return NULL; 5405 5406 /* When there is a cached index may start search from there. */ 5407 if (l->lv_idx_item != NULL) 5408 { 5409 if (n < l->lv_idx / 2) 5410 { 5411 /* closest to the start of the list */ 5412 item = l->lv_first; 5413 idx = 0; 5414 } 5415 else if (n > (l->lv_idx + l->lv_len) / 2) 5416 { 5417 /* closest to the end of the list */ 5418 item = l->lv_last; 5419 idx = l->lv_len - 1; 5420 } 5421 else 5422 { 5423 /* closest to the cached index */ 5424 item = l->lv_idx_item; 5425 idx = l->lv_idx; 5426 } 5427 } 5428 else 5429 { 5430 if (n < l->lv_len / 2) 5431 { 5432 /* closest to the start of the list */ 5433 item = l->lv_first; 5434 idx = 0; 5435 } 5436 else 5437 { 5438 /* closest to the end of the list */ 5439 item = l->lv_last; 5440 idx = l->lv_len - 1; 5441 } 5442 } 5443 5444 while (n > idx) 5445 { 5446 /* search forward */ 5447 item = item->li_next; 5448 ++idx; 5449 } 5450 while (n < idx) 5451 { 5452 /* search backward */ 5453 item = item->li_prev; 5454 --idx; 5455 } 5456 5457 /* cache the used index */ 5458 l->lv_idx = idx; 5459 l->lv_idx_item = item; 5460 5461 return item; 5462 } 5463 5464 /* 5465 * Locate "item" list "l" and return its index. 5466 * Returns -1 when "item" is not in the list. 5467 */ 5468 static long 5469 list_idx_of_item(l, item) 5470 list_T *l; 5471 listitem_T *item; 5472 { 5473 long idx = 0; 5474 listitem_T *li; 5475 5476 if (l == NULL) 5477 return -1; 5478 idx = 0; 5479 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5480 ++idx; 5481 if (li == NULL) 5482 return -1; 5483 return idx; 5484 } 5485 5486 /* 5487 * Append item "item" to the end of list "l". 5488 */ 5489 static void 5490 list_append(l, item) 5491 list_T *l; 5492 listitem_T *item; 5493 { 5494 if (l->lv_last == NULL) 5495 { 5496 /* empty list */ 5497 l->lv_first = item; 5498 l->lv_last = item; 5499 item->li_prev = NULL; 5500 } 5501 else 5502 { 5503 l->lv_last->li_next = item; 5504 item->li_prev = l->lv_last; 5505 l->lv_last = item; 5506 } 5507 ++l->lv_len; 5508 item->li_next = NULL; 5509 } 5510 5511 /* 5512 * Append typval_T "tv" to the end of list "l". 5513 * Return FAIL when out of memory. 5514 */ 5515 static int 5516 list_append_tv(l, tv) 5517 list_T *l; 5518 typval_T *tv; 5519 { 5520 listitem_T *li = listitem_alloc(); 5521 5522 if (li == NULL) 5523 return FAIL; 5524 copy_tv(tv, &li->li_tv); 5525 list_append(l, li); 5526 return OK; 5527 } 5528 5529 /* 5530 * Add a dictionary to a list. Used by getqflist(). 5531 * Return FAIL when out of memory. 5532 */ 5533 int 5534 list_append_dict(list, dict) 5535 list_T *list; 5536 dict_T *dict; 5537 { 5538 listitem_T *li = listitem_alloc(); 5539 5540 if (li == NULL) 5541 return FAIL; 5542 li->li_tv.v_type = VAR_DICT; 5543 li->li_tv.v_lock = 0; 5544 li->li_tv.vval.v_dict = dict; 5545 list_append(list, li); 5546 ++dict->dv_refcount; 5547 return OK; 5548 } 5549 5550 /* 5551 * Insert typval_T "tv" in list "l" before "item". 5552 * If "item" is NULL append at the end. 5553 * Return FAIL when out of memory. 5554 */ 5555 static int 5556 list_insert_tv(l, tv, item) 5557 list_T *l; 5558 typval_T *tv; 5559 listitem_T *item; 5560 { 5561 listitem_T *ni = listitem_alloc(); 5562 5563 if (ni == NULL) 5564 return FAIL; 5565 copy_tv(tv, &ni->li_tv); 5566 if (item == NULL) 5567 /* Append new item at end of list. */ 5568 list_append(l, ni); 5569 else 5570 { 5571 /* Insert new item before existing item. */ 5572 ni->li_prev = item->li_prev; 5573 ni->li_next = item; 5574 if (item->li_prev == NULL) 5575 { 5576 l->lv_first = ni; 5577 ++l->lv_idx; 5578 } 5579 else 5580 { 5581 item->li_prev->li_next = ni; 5582 l->lv_idx_item = NULL; 5583 } 5584 item->li_prev = ni; 5585 ++l->lv_len; 5586 } 5587 return OK; 5588 } 5589 5590 /* 5591 * Extend "l1" with "l2". 5592 * If "bef" is NULL append at the end, otherwise insert before this item. 5593 * Returns FAIL when out of memory. 5594 */ 5595 static int 5596 list_extend(l1, l2, bef) 5597 list_T *l1; 5598 list_T *l2; 5599 listitem_T *bef; 5600 { 5601 listitem_T *item; 5602 5603 for (item = l2->lv_first; item != NULL; item = item->li_next) 5604 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5605 return FAIL; 5606 return OK; 5607 } 5608 5609 /* 5610 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5611 * Return FAIL when out of memory. 5612 */ 5613 static int 5614 list_concat(l1, l2, tv) 5615 list_T *l1; 5616 list_T *l2; 5617 typval_T *tv; 5618 { 5619 list_T *l; 5620 5621 /* make a copy of the first list. */ 5622 l = list_copy(l1, FALSE, 0); 5623 if (l == NULL) 5624 return FAIL; 5625 tv->v_type = VAR_LIST; 5626 tv->vval.v_list = l; 5627 5628 /* append all items from the second list */ 5629 return list_extend(l, l2, NULL); 5630 } 5631 5632 /* 5633 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5634 * The refcount of the new list is set to 1. 5635 * See item_copy() for "copyID". 5636 * Returns NULL when out of memory. 5637 */ 5638 static list_T * 5639 list_copy(orig, deep, copyID) 5640 list_T *orig; 5641 int deep; 5642 int copyID; 5643 { 5644 list_T *copy; 5645 listitem_T *item; 5646 listitem_T *ni; 5647 5648 if (orig == NULL) 5649 return NULL; 5650 5651 copy = list_alloc(); 5652 if (copy != NULL) 5653 { 5654 if (copyID != 0) 5655 { 5656 /* Do this before adding the items, because one of the items may 5657 * refer back to this list. */ 5658 orig->lv_copyID = copyID; 5659 orig->lv_copylist = copy; 5660 } 5661 for (item = orig->lv_first; item != NULL && !got_int; 5662 item = item->li_next) 5663 { 5664 ni = listitem_alloc(); 5665 if (ni == NULL) 5666 break; 5667 if (deep) 5668 { 5669 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5670 { 5671 vim_free(ni); 5672 break; 5673 } 5674 } 5675 else 5676 copy_tv(&item->li_tv, &ni->li_tv); 5677 list_append(copy, ni); 5678 } 5679 ++copy->lv_refcount; 5680 if (item != NULL) 5681 { 5682 list_unref(copy); 5683 copy = NULL; 5684 } 5685 } 5686 5687 return copy; 5688 } 5689 5690 /* 5691 * Remove items "item" to "item2" from list "l". 5692 * Does not free the listitem or the value! 5693 */ 5694 static void 5695 list_remove(l, item, item2) 5696 list_T *l; 5697 listitem_T *item; 5698 listitem_T *item2; 5699 { 5700 listitem_T *ip; 5701 5702 /* notify watchers */ 5703 for (ip = item; ip != NULL; ip = ip->li_next) 5704 { 5705 --l->lv_len; 5706 list_fix_watch(l, ip); 5707 if (ip == item2) 5708 break; 5709 } 5710 5711 if (item2->li_next == NULL) 5712 l->lv_last = item->li_prev; 5713 else 5714 item2->li_next->li_prev = item->li_prev; 5715 if (item->li_prev == NULL) 5716 l->lv_first = item2->li_next; 5717 else 5718 item->li_prev->li_next = item2->li_next; 5719 l->lv_idx_item = NULL; 5720 } 5721 5722 /* 5723 * Return an allocated string with the string representation of a list. 5724 * May return NULL. 5725 */ 5726 static char_u * 5727 list2string(tv) 5728 typval_T *tv; 5729 { 5730 garray_T ga; 5731 5732 if (tv->vval.v_list == NULL) 5733 return NULL; 5734 ga_init2(&ga, (int)sizeof(char), 80); 5735 ga_append(&ga, '['); 5736 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5737 { 5738 vim_free(ga.ga_data); 5739 return NULL; 5740 } 5741 ga_append(&ga, ']'); 5742 ga_append(&ga, NUL); 5743 return (char_u *)ga.ga_data; 5744 } 5745 5746 /* 5747 * Join list "l" into a string in "*gap", using separator "sep". 5748 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5749 * Return FAIL or OK. 5750 */ 5751 static int 5752 list_join(gap, l, sep, echo) 5753 garray_T *gap; 5754 list_T *l; 5755 char_u *sep; 5756 int echo; 5757 { 5758 int first = TRUE; 5759 char_u *tofree; 5760 char_u numbuf[NUMBUFLEN]; 5761 listitem_T *item; 5762 char_u *s; 5763 5764 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5765 { 5766 if (first) 5767 first = FALSE; 5768 else 5769 ga_concat(gap, sep); 5770 5771 if (echo) 5772 s = echo_string(&item->li_tv, &tofree, numbuf); 5773 else 5774 s = tv2string(&item->li_tv, &tofree, numbuf); 5775 if (s != NULL) 5776 ga_concat(gap, s); 5777 vim_free(tofree); 5778 if (s == NULL) 5779 return FAIL; 5780 } 5781 return OK; 5782 } 5783 5784 /* 5785 * Garbage collection for lists and dictionaries. 5786 * 5787 * We use reference counts to be able to free most items right away when they 5788 * are no longer used. But for composite items it's possible that it becomes 5789 * unused while the reference count is > 0: When there is a recursive 5790 * reference. Example: 5791 * :let l = [1, 2, 3] 5792 * :let d = {9: l} 5793 * :let l[1] = d 5794 * 5795 * Since this is quite unusual we handle this with garbage collection: every 5796 * once in a while find out which lists and dicts are not referenced from any 5797 * variable. 5798 * 5799 * Here is a good reference text about garbage collection (refers to Python 5800 * but it applies to all reference-counting mechanisms): 5801 * http://python.ca/nas/python/gc/ 5802 */ 5803 5804 /* 5805 * Do garbage collection for lists and dicts. 5806 * Return TRUE if some memory was freed. 5807 */ 5808 int 5809 garbage_collect() 5810 { 5811 dict_T *dd; 5812 list_T *ll; 5813 int copyID = ++current_copyID; 5814 buf_T *buf; 5815 win_T *wp; 5816 int i; 5817 funccall_T *fc; 5818 int did_free = FALSE; 5819 5820 /* 5821 * 1. Go through all accessible variables and mark all lists and dicts 5822 * with copyID. 5823 */ 5824 /* script-local variables */ 5825 for (i = 1; i <= ga_scripts.ga_len; ++i) 5826 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5827 5828 /* buffer-local variables */ 5829 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5830 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5831 5832 /* window-local variables */ 5833 FOR_ALL_WINDOWS(wp) 5834 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5835 5836 /* global variables */ 5837 set_ref_in_ht(&globvarht, copyID); 5838 5839 /* function-local variables */ 5840 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5841 { 5842 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5843 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5844 } 5845 5846 /* 5847 * 2. Go through the list of dicts and free items without the copyID. 5848 */ 5849 for (dd = first_dict; dd != NULL; ) 5850 if (dd->dv_copyID != copyID) 5851 { 5852 dict_free(dd); 5853 did_free = TRUE; 5854 5855 /* restart, next dict may also have been freed */ 5856 dd = first_dict; 5857 } 5858 else 5859 dd = dd->dv_used_next; 5860 5861 /* 5862 * 3. Go through the list of lists and free items without the copyID. 5863 */ 5864 for (ll = first_list; ll != NULL; ) 5865 if (ll->lv_copyID != copyID) 5866 { 5867 list_free(ll); 5868 did_free = TRUE; 5869 5870 /* restart, next dict may also have been freed */ 5871 ll = first_list; 5872 } 5873 else 5874 ll = ll->lv_used_next; 5875 5876 return did_free; 5877 } 5878 5879 /* 5880 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5881 */ 5882 static void 5883 set_ref_in_ht(ht, copyID) 5884 hashtab_T *ht; 5885 int copyID; 5886 { 5887 int todo; 5888 hashitem_T *hi; 5889 5890 todo = ht->ht_used; 5891 for (hi = ht->ht_array; todo > 0; ++hi) 5892 if (!HASHITEM_EMPTY(hi)) 5893 { 5894 --todo; 5895 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5896 } 5897 } 5898 5899 /* 5900 * Mark all lists and dicts referenced through list "l" with "copyID". 5901 */ 5902 static void 5903 set_ref_in_list(l, copyID) 5904 list_T *l; 5905 int copyID; 5906 { 5907 listitem_T *li; 5908 5909 for (li = l->lv_first; li != NULL; li = li->li_next) 5910 set_ref_in_item(&li->li_tv, copyID); 5911 } 5912 5913 /* 5914 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5915 */ 5916 static void 5917 set_ref_in_item(tv, copyID) 5918 typval_T *tv; 5919 int copyID; 5920 { 5921 dict_T *dd; 5922 list_T *ll; 5923 5924 switch (tv->v_type) 5925 { 5926 case VAR_DICT: 5927 dd = tv->vval.v_dict; 5928 if (dd->dv_copyID != copyID) 5929 { 5930 /* Didn't see this dict yet. */ 5931 dd->dv_copyID = copyID; 5932 set_ref_in_ht(&dd->dv_hashtab, copyID); 5933 } 5934 break; 5935 5936 case VAR_LIST: 5937 ll = tv->vval.v_list; 5938 if (ll->lv_copyID != copyID) 5939 { 5940 /* Didn't see this list yet. */ 5941 ll->lv_copyID = copyID; 5942 set_ref_in_list(ll, copyID); 5943 } 5944 break; 5945 } 5946 return; 5947 } 5948 5949 /* 5950 * Allocate an empty header for a dictionary. 5951 */ 5952 dict_T * 5953 dict_alloc() 5954 { 5955 dict_T *d; 5956 5957 d = (dict_T *)alloc(sizeof(dict_T)); 5958 if (d != NULL) 5959 { 5960 /* Add the list to the hashtable for garbage collection. */ 5961 if (first_dict != NULL) 5962 first_dict->dv_used_prev = d; 5963 d->dv_used_next = first_dict; 5964 d->dv_used_prev = NULL; 5965 5966 hash_init(&d->dv_hashtab); 5967 d->dv_lock = 0; 5968 d->dv_refcount = 0; 5969 d->dv_copyID = 0; 5970 } 5971 return d; 5972 } 5973 5974 /* 5975 * Unreference a Dictionary: decrement the reference count and free it when it 5976 * becomes zero. 5977 */ 5978 static void 5979 dict_unref(d) 5980 dict_T *d; 5981 { 5982 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 5983 dict_free(d); 5984 } 5985 5986 /* 5987 * Free a Dictionary, including all items it contains. 5988 * Ignores the reference count. 5989 */ 5990 static void 5991 dict_free(d) 5992 dict_T *d; 5993 { 5994 int todo; 5995 hashitem_T *hi; 5996 dictitem_T *di; 5997 5998 /* Avoid that recursive reference to the dict frees us again. */ 5999 d->dv_refcount = DEL_REFCOUNT; 6000 6001 /* Remove the dict from the list of dicts for garbage collection. */ 6002 if (d->dv_used_prev == NULL) 6003 first_dict = d->dv_used_next; 6004 else 6005 d->dv_used_prev->dv_used_next = d->dv_used_next; 6006 if (d->dv_used_next != NULL) 6007 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6008 6009 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6010 hash_lock(&d->dv_hashtab); 6011 todo = d->dv_hashtab.ht_used; 6012 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6013 { 6014 if (!HASHITEM_EMPTY(hi)) 6015 { 6016 /* Remove the item before deleting it, just in case there is 6017 * something recursive causing trouble. */ 6018 di = HI2DI(hi); 6019 hash_remove(&d->dv_hashtab, hi); 6020 dictitem_free(di); 6021 --todo; 6022 } 6023 } 6024 hash_clear(&d->dv_hashtab); 6025 vim_free(d); 6026 } 6027 6028 /* 6029 * Allocate a Dictionary item. 6030 * The "key" is copied to the new item. 6031 * Note that the value of the item "di_tv" still needs to be initialized! 6032 * Returns NULL when out of memory. 6033 */ 6034 static dictitem_T * 6035 dictitem_alloc(key) 6036 char_u *key; 6037 { 6038 dictitem_T *di; 6039 6040 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6041 if (di != NULL) 6042 { 6043 STRCPY(di->di_key, key); 6044 di->di_flags = 0; 6045 } 6046 return di; 6047 } 6048 6049 /* 6050 * Make a copy of a Dictionary item. 6051 */ 6052 static dictitem_T * 6053 dictitem_copy(org) 6054 dictitem_T *org; 6055 { 6056 dictitem_T *di; 6057 6058 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6059 if (di != NULL) 6060 { 6061 STRCPY(di->di_key, org->di_key); 6062 di->di_flags = 0; 6063 copy_tv(&org->di_tv, &di->di_tv); 6064 } 6065 return di; 6066 } 6067 6068 /* 6069 * Remove item "item" from Dictionary "dict" and free it. 6070 */ 6071 static void 6072 dictitem_remove(dict, item) 6073 dict_T *dict; 6074 dictitem_T *item; 6075 { 6076 hashitem_T *hi; 6077 6078 hi = hash_find(&dict->dv_hashtab, item->di_key); 6079 if (HASHITEM_EMPTY(hi)) 6080 EMSG2(_(e_intern2), "dictitem_remove()"); 6081 else 6082 hash_remove(&dict->dv_hashtab, hi); 6083 dictitem_free(item); 6084 } 6085 6086 /* 6087 * Free a dict item. Also clears the value. 6088 */ 6089 static void 6090 dictitem_free(item) 6091 dictitem_T *item; 6092 { 6093 clear_tv(&item->di_tv); 6094 vim_free(item); 6095 } 6096 6097 /* 6098 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6099 * The refcount of the new dict is set to 1. 6100 * See item_copy() for "copyID". 6101 * Returns NULL when out of memory. 6102 */ 6103 static dict_T * 6104 dict_copy(orig, deep, copyID) 6105 dict_T *orig; 6106 int deep; 6107 int copyID; 6108 { 6109 dict_T *copy; 6110 dictitem_T *di; 6111 int todo; 6112 hashitem_T *hi; 6113 6114 if (orig == NULL) 6115 return NULL; 6116 6117 copy = dict_alloc(); 6118 if (copy != NULL) 6119 { 6120 if (copyID != 0) 6121 { 6122 orig->dv_copyID = copyID; 6123 orig->dv_copydict = copy; 6124 } 6125 todo = orig->dv_hashtab.ht_used; 6126 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6127 { 6128 if (!HASHITEM_EMPTY(hi)) 6129 { 6130 --todo; 6131 6132 di = dictitem_alloc(hi->hi_key); 6133 if (di == NULL) 6134 break; 6135 if (deep) 6136 { 6137 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6138 copyID) == FAIL) 6139 { 6140 vim_free(di); 6141 break; 6142 } 6143 } 6144 else 6145 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6146 if (dict_add(copy, di) == FAIL) 6147 { 6148 dictitem_free(di); 6149 break; 6150 } 6151 } 6152 } 6153 6154 ++copy->dv_refcount; 6155 if (todo > 0) 6156 { 6157 dict_unref(copy); 6158 copy = NULL; 6159 } 6160 } 6161 6162 return copy; 6163 } 6164 6165 /* 6166 * Add item "item" to Dictionary "d". 6167 * Returns FAIL when out of memory and when key already existed. 6168 */ 6169 static int 6170 dict_add(d, item) 6171 dict_T *d; 6172 dictitem_T *item; 6173 { 6174 return hash_add(&d->dv_hashtab, item->di_key); 6175 } 6176 6177 /* 6178 * Add a number or string entry to dictionary "d". 6179 * When "str" is NULL use number "nr", otherwise use "str". 6180 * Returns FAIL when out of memory and when key already exists. 6181 */ 6182 int 6183 dict_add_nr_str(d, key, nr, str) 6184 dict_T *d; 6185 char *key; 6186 long nr; 6187 char_u *str; 6188 { 6189 dictitem_T *item; 6190 6191 item = dictitem_alloc((char_u *)key); 6192 if (item == NULL) 6193 return FAIL; 6194 item->di_tv.v_lock = 0; 6195 if (str == NULL) 6196 { 6197 item->di_tv.v_type = VAR_NUMBER; 6198 item->di_tv.vval.v_number = nr; 6199 } 6200 else 6201 { 6202 item->di_tv.v_type = VAR_STRING; 6203 item->di_tv.vval.v_string = vim_strsave(str); 6204 } 6205 if (dict_add(d, item) == FAIL) 6206 { 6207 dictitem_free(item); 6208 return FAIL; 6209 } 6210 return OK; 6211 } 6212 6213 /* 6214 * Get the number of items in a Dictionary. 6215 */ 6216 static long 6217 dict_len(d) 6218 dict_T *d; 6219 { 6220 if (d == NULL) 6221 return 0L; 6222 return d->dv_hashtab.ht_used; 6223 } 6224 6225 /* 6226 * Find item "key[len]" in Dictionary "d". 6227 * If "len" is negative use strlen(key). 6228 * Returns NULL when not found. 6229 */ 6230 static dictitem_T * 6231 dict_find(d, key, len) 6232 dict_T *d; 6233 char_u *key; 6234 int len; 6235 { 6236 #define AKEYLEN 200 6237 char_u buf[AKEYLEN]; 6238 char_u *akey; 6239 char_u *tofree = NULL; 6240 hashitem_T *hi; 6241 6242 if (len < 0) 6243 akey = key; 6244 else if (len >= AKEYLEN) 6245 { 6246 tofree = akey = vim_strnsave(key, len); 6247 if (akey == NULL) 6248 return NULL; 6249 } 6250 else 6251 { 6252 /* Avoid a malloc/free by using buf[]. */ 6253 vim_strncpy(buf, key, len); 6254 akey = buf; 6255 } 6256 6257 hi = hash_find(&d->dv_hashtab, akey); 6258 vim_free(tofree); 6259 if (HASHITEM_EMPTY(hi)) 6260 return NULL; 6261 return HI2DI(hi); 6262 } 6263 6264 /* 6265 * Get a string item from a dictionary in allocated memory. 6266 * Returns NULL if the entry doesn't exist or out of memory. 6267 */ 6268 char_u * 6269 get_dict_string(d, key) 6270 dict_T *d; 6271 char_u *key; 6272 { 6273 dictitem_T *di; 6274 6275 di = dict_find(d, key, -1); 6276 if (di == NULL) 6277 return NULL; 6278 return vim_strsave(get_tv_string(&di->di_tv)); 6279 } 6280 6281 /* 6282 * Get a number item from a dictionary. 6283 * Returns 0 if the entry doesn't exist or out of memory. 6284 */ 6285 long 6286 get_dict_number(d, key) 6287 dict_T *d; 6288 char_u *key; 6289 { 6290 dictitem_T *di; 6291 6292 di = dict_find(d, key, -1); 6293 if (di == NULL) 6294 return 0; 6295 return get_tv_number(&di->di_tv); 6296 } 6297 6298 /* 6299 * Return an allocated string with the string representation of a Dictionary. 6300 * May return NULL. 6301 */ 6302 static char_u * 6303 dict2string(tv) 6304 typval_T *tv; 6305 { 6306 garray_T ga; 6307 int first = TRUE; 6308 char_u *tofree; 6309 char_u numbuf[NUMBUFLEN]; 6310 hashitem_T *hi; 6311 char_u *s; 6312 dict_T *d; 6313 int todo; 6314 6315 if ((d = tv->vval.v_dict) == NULL) 6316 return NULL; 6317 ga_init2(&ga, (int)sizeof(char), 80); 6318 ga_append(&ga, '{'); 6319 6320 todo = d->dv_hashtab.ht_used; 6321 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6322 { 6323 if (!HASHITEM_EMPTY(hi)) 6324 { 6325 --todo; 6326 6327 if (first) 6328 first = FALSE; 6329 else 6330 ga_concat(&ga, (char_u *)", "); 6331 6332 tofree = string_quote(hi->hi_key, FALSE); 6333 if (tofree != NULL) 6334 { 6335 ga_concat(&ga, tofree); 6336 vim_free(tofree); 6337 } 6338 ga_concat(&ga, (char_u *)": "); 6339 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6340 if (s != NULL) 6341 ga_concat(&ga, s); 6342 vim_free(tofree); 6343 if (s == NULL) 6344 break; 6345 } 6346 } 6347 if (todo > 0) 6348 { 6349 vim_free(ga.ga_data); 6350 return NULL; 6351 } 6352 6353 ga_append(&ga, '}'); 6354 ga_append(&ga, NUL); 6355 return (char_u *)ga.ga_data; 6356 } 6357 6358 /* 6359 * Allocate a variable for a Dictionary and fill it from "*arg". 6360 * Return OK or FAIL. Returns NOTDONE for {expr}. 6361 */ 6362 static int 6363 get_dict_tv(arg, rettv, evaluate) 6364 char_u **arg; 6365 typval_T *rettv; 6366 int evaluate; 6367 { 6368 dict_T *d = NULL; 6369 typval_T tvkey; 6370 typval_T tv; 6371 char_u *key; 6372 dictitem_T *item; 6373 char_u *start = skipwhite(*arg + 1); 6374 char_u buf[NUMBUFLEN]; 6375 6376 /* 6377 * First check if it's not a curly-braces thing: {expr}. 6378 * Must do this without evaluating, otherwise a function may be called 6379 * twice. Unfortunately this means we need to call eval1() twice for the 6380 * first item. 6381 * But {} is an empty Dictionary. 6382 */ 6383 if (*start != '}') 6384 { 6385 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6386 return FAIL; 6387 if (*start == '}') 6388 return NOTDONE; 6389 } 6390 6391 if (evaluate) 6392 { 6393 d = dict_alloc(); 6394 if (d == NULL) 6395 return FAIL; 6396 } 6397 tvkey.v_type = VAR_UNKNOWN; 6398 tv.v_type = VAR_UNKNOWN; 6399 6400 *arg = skipwhite(*arg + 1); 6401 while (**arg != '}' && **arg != NUL) 6402 { 6403 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6404 goto failret; 6405 if (**arg != ':') 6406 { 6407 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6408 clear_tv(&tvkey); 6409 goto failret; 6410 } 6411 key = get_tv_string_buf_chk(&tvkey, buf); 6412 if (key == NULL || *key == NUL) 6413 { 6414 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6415 if (key != NULL) 6416 EMSG(_(e_emptykey)); 6417 clear_tv(&tvkey); 6418 goto failret; 6419 } 6420 6421 *arg = skipwhite(*arg + 1); 6422 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6423 { 6424 clear_tv(&tvkey); 6425 goto failret; 6426 } 6427 if (evaluate) 6428 { 6429 item = dict_find(d, key, -1); 6430 if (item != NULL) 6431 { 6432 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6433 clear_tv(&tvkey); 6434 clear_tv(&tv); 6435 goto failret; 6436 } 6437 item = dictitem_alloc(key); 6438 clear_tv(&tvkey); 6439 if (item != NULL) 6440 { 6441 item->di_tv = tv; 6442 item->di_tv.v_lock = 0; 6443 if (dict_add(d, item) == FAIL) 6444 dictitem_free(item); 6445 } 6446 } 6447 6448 if (**arg == '}') 6449 break; 6450 if (**arg != ',') 6451 { 6452 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6453 goto failret; 6454 } 6455 *arg = skipwhite(*arg + 1); 6456 } 6457 6458 if (**arg != '}') 6459 { 6460 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6461 failret: 6462 if (evaluate) 6463 dict_free(d); 6464 return FAIL; 6465 } 6466 6467 *arg = skipwhite(*arg + 1); 6468 if (evaluate) 6469 { 6470 rettv->v_type = VAR_DICT; 6471 rettv->vval.v_dict = d; 6472 ++d->dv_refcount; 6473 } 6474 6475 return OK; 6476 } 6477 6478 /* 6479 * Return a string with the string representation of a variable. 6480 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6481 * "numbuf" is used for a number. 6482 * Does not put quotes around strings, as ":echo" displays values. 6483 * May return NULL; 6484 */ 6485 static char_u * 6486 echo_string(tv, tofree, numbuf) 6487 typval_T *tv; 6488 char_u **tofree; 6489 char_u *numbuf; 6490 { 6491 static int recurse = 0; 6492 char_u *r = NULL; 6493 6494 if (recurse >= DICT_MAXNEST) 6495 { 6496 EMSG(_("E724: variable nested too deep for displaying")); 6497 *tofree = NULL; 6498 return NULL; 6499 } 6500 ++recurse; 6501 6502 switch (tv->v_type) 6503 { 6504 case VAR_FUNC: 6505 *tofree = NULL; 6506 r = tv->vval.v_string; 6507 break; 6508 case VAR_LIST: 6509 *tofree = list2string(tv); 6510 r = *tofree; 6511 break; 6512 case VAR_DICT: 6513 *tofree = dict2string(tv); 6514 r = *tofree; 6515 break; 6516 case VAR_STRING: 6517 case VAR_NUMBER: 6518 *tofree = NULL; 6519 r = get_tv_string_buf(tv, numbuf); 6520 break; 6521 default: 6522 EMSG2(_(e_intern2), "echo_string()"); 6523 *tofree = NULL; 6524 } 6525 6526 --recurse; 6527 return r; 6528 } 6529 6530 /* 6531 * Return a string with the string representation of a variable. 6532 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6533 * "numbuf" is used for a number. 6534 * Puts quotes around strings, so that they can be parsed back by eval(). 6535 * May return NULL; 6536 */ 6537 static char_u * 6538 tv2string(tv, tofree, numbuf) 6539 typval_T *tv; 6540 char_u **tofree; 6541 char_u *numbuf; 6542 { 6543 switch (tv->v_type) 6544 { 6545 case VAR_FUNC: 6546 *tofree = string_quote(tv->vval.v_string, TRUE); 6547 return *tofree; 6548 case VAR_STRING: 6549 *tofree = string_quote(tv->vval.v_string, FALSE); 6550 return *tofree; 6551 case VAR_NUMBER: 6552 case VAR_LIST: 6553 case VAR_DICT: 6554 break; 6555 default: 6556 EMSG2(_(e_intern2), "tv2string()"); 6557 } 6558 return echo_string(tv, tofree, numbuf); 6559 } 6560 6561 /* 6562 * Return string "str" in ' quotes, doubling ' characters. 6563 * If "str" is NULL an empty string is assumed. 6564 * If "function" is TRUE make it function('string'). 6565 */ 6566 static char_u * 6567 string_quote(str, function) 6568 char_u *str; 6569 int function; 6570 { 6571 unsigned len; 6572 char_u *p, *r, *s; 6573 6574 len = (function ? 13 : 3); 6575 if (str != NULL) 6576 { 6577 len += STRLEN(str); 6578 for (p = str; *p != NUL; mb_ptr_adv(p)) 6579 if (*p == '\'') 6580 ++len; 6581 } 6582 s = r = alloc(len); 6583 if (r != NULL) 6584 { 6585 if (function) 6586 { 6587 STRCPY(r, "function('"); 6588 r += 10; 6589 } 6590 else 6591 *r++ = '\''; 6592 if (str != NULL) 6593 for (p = str; *p != NUL; ) 6594 { 6595 if (*p == '\'') 6596 *r++ = '\''; 6597 MB_COPY_CHAR(p, r); 6598 } 6599 *r++ = '\''; 6600 if (function) 6601 *r++ = ')'; 6602 *r++ = NUL; 6603 } 6604 return s; 6605 } 6606 6607 /* 6608 * Get the value of an environment variable. 6609 * "arg" is pointing to the '$'. It is advanced to after the name. 6610 * If the environment variable was not set, silently assume it is empty. 6611 * Always return OK. 6612 */ 6613 static int 6614 get_env_tv(arg, rettv, evaluate) 6615 char_u **arg; 6616 typval_T *rettv; 6617 int evaluate; 6618 { 6619 char_u *string = NULL; 6620 int len; 6621 int cc; 6622 char_u *name; 6623 int mustfree = FALSE; 6624 6625 ++*arg; 6626 name = *arg; 6627 len = get_env_len(arg); 6628 if (evaluate) 6629 { 6630 if (len != 0) 6631 { 6632 cc = name[len]; 6633 name[len] = NUL; 6634 /* first try vim_getenv(), fast for normal environment vars */ 6635 string = vim_getenv(name, &mustfree); 6636 if (string != NULL && *string != NUL) 6637 { 6638 if (!mustfree) 6639 string = vim_strsave(string); 6640 } 6641 else 6642 { 6643 if (mustfree) 6644 vim_free(string); 6645 6646 /* next try expanding things like $VIM and ${HOME} */ 6647 string = expand_env_save(name - 1); 6648 if (string != NULL && *string == '$') 6649 { 6650 vim_free(string); 6651 string = NULL; 6652 } 6653 } 6654 name[len] = cc; 6655 } 6656 rettv->v_type = VAR_STRING; 6657 rettv->vval.v_string = string; 6658 } 6659 6660 return OK; 6661 } 6662 6663 /* 6664 * Array with names and number of arguments of all internal functions 6665 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6666 */ 6667 static struct fst 6668 { 6669 char *f_name; /* function name */ 6670 char f_min_argc; /* minimal number of arguments */ 6671 char f_max_argc; /* maximal number of arguments */ 6672 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6673 /* implemenation of function */ 6674 } functions[] = 6675 { 6676 {"add", 2, 2, f_add}, 6677 {"append", 2, 2, f_append}, 6678 {"argc", 0, 0, f_argc}, 6679 {"argidx", 0, 0, f_argidx}, 6680 {"argv", 1, 1, f_argv}, 6681 {"browse", 4, 4, f_browse}, 6682 {"browsedir", 2, 2, f_browsedir}, 6683 {"bufexists", 1, 1, f_bufexists}, 6684 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6685 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6686 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6687 {"buflisted", 1, 1, f_buflisted}, 6688 {"bufloaded", 1, 1, f_bufloaded}, 6689 {"bufname", 1, 1, f_bufname}, 6690 {"bufnr", 1, 1, f_bufnr}, 6691 {"bufwinnr", 1, 1, f_bufwinnr}, 6692 {"byte2line", 1, 1, f_byte2line}, 6693 {"byteidx", 2, 2, f_byteidx}, 6694 {"call", 2, 3, f_call}, 6695 {"char2nr", 1, 1, f_char2nr}, 6696 {"cindent", 1, 1, f_cindent}, 6697 {"col", 1, 1, f_col}, 6698 #if defined(FEAT_INS_EXPAND) 6699 {"complete_add", 1, 1, f_complete_add}, 6700 {"complete_check", 0, 0, f_complete_check}, 6701 #endif 6702 {"confirm", 1, 4, f_confirm}, 6703 {"copy", 1, 1, f_copy}, 6704 {"count", 2, 4, f_count}, 6705 {"cscope_connection",0,3, f_cscope_connection}, 6706 {"cursor", 2, 2, f_cursor}, 6707 {"deepcopy", 1, 2, f_deepcopy}, 6708 {"delete", 1, 1, f_delete}, 6709 {"did_filetype", 0, 0, f_did_filetype}, 6710 {"diff_filler", 1, 1, f_diff_filler}, 6711 {"diff_hlID", 2, 2, f_diff_hlID}, 6712 {"empty", 1, 1, f_empty}, 6713 {"escape", 2, 2, f_escape}, 6714 {"eval", 1, 1, f_eval}, 6715 {"eventhandler", 0, 0, f_eventhandler}, 6716 {"executable", 1, 1, f_executable}, 6717 {"exists", 1, 1, f_exists}, 6718 {"expand", 1, 2, f_expand}, 6719 {"extend", 2, 3, f_extend}, 6720 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6721 {"filereadable", 1, 1, f_filereadable}, 6722 {"filewritable", 1, 1, f_filewritable}, 6723 {"filter", 2, 2, f_filter}, 6724 {"finddir", 1, 3, f_finddir}, 6725 {"findfile", 1, 3, f_findfile}, 6726 {"fnamemodify", 2, 2, f_fnamemodify}, 6727 {"foldclosed", 1, 1, f_foldclosed}, 6728 {"foldclosedend", 1, 1, f_foldclosedend}, 6729 {"foldlevel", 1, 1, f_foldlevel}, 6730 {"foldtext", 0, 0, f_foldtext}, 6731 {"foldtextresult", 1, 1, f_foldtextresult}, 6732 {"foreground", 0, 0, f_foreground}, 6733 {"function", 1, 1, f_function}, 6734 {"garbagecollect", 0, 0, f_garbagecollect}, 6735 {"get", 2, 3, f_get}, 6736 {"getbufline", 2, 3, f_getbufline}, 6737 {"getbufvar", 2, 2, f_getbufvar}, 6738 {"getchar", 0, 1, f_getchar}, 6739 {"getcharmod", 0, 0, f_getcharmod}, 6740 {"getcmdline", 0, 0, f_getcmdline}, 6741 {"getcmdpos", 0, 0, f_getcmdpos}, 6742 {"getcwd", 0, 0, f_getcwd}, 6743 {"getfontname", 0, 1, f_getfontname}, 6744 {"getfperm", 1, 1, f_getfperm}, 6745 {"getfsize", 1, 1, f_getfsize}, 6746 {"getftime", 1, 1, f_getftime}, 6747 {"getftype", 1, 1, f_getftype}, 6748 {"getline", 1, 2, f_getline}, 6749 {"getqflist", 0, 0, f_getqflist}, 6750 {"getreg", 0, 2, f_getreg}, 6751 {"getregtype", 0, 1, f_getregtype}, 6752 {"getwinposx", 0, 0, f_getwinposx}, 6753 {"getwinposy", 0, 0, f_getwinposy}, 6754 {"getwinvar", 2, 2, f_getwinvar}, 6755 {"glob", 1, 1, f_glob}, 6756 {"globpath", 2, 2, f_globpath}, 6757 {"has", 1, 1, f_has}, 6758 {"has_key", 2, 2, f_has_key}, 6759 {"hasmapto", 1, 2, f_hasmapto}, 6760 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6761 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6762 {"histadd", 2, 2, f_histadd}, 6763 {"histdel", 1, 2, f_histdel}, 6764 {"histget", 1, 2, f_histget}, 6765 {"histnr", 1, 1, f_histnr}, 6766 {"hlID", 1, 1, f_hlID}, 6767 {"hlexists", 1, 1, f_hlexists}, 6768 {"hostname", 0, 0, f_hostname}, 6769 {"iconv", 3, 3, f_iconv}, 6770 {"indent", 1, 1, f_indent}, 6771 {"index", 2, 4, f_index}, 6772 {"input", 1, 2, f_input}, 6773 {"inputdialog", 1, 3, f_inputdialog}, 6774 {"inputrestore", 0, 0, f_inputrestore}, 6775 {"inputsave", 0, 0, f_inputsave}, 6776 {"inputsecret", 1, 2, f_inputsecret}, 6777 {"insert", 2, 3, f_insert}, 6778 {"isdirectory", 1, 1, f_isdirectory}, 6779 {"islocked", 1, 1, f_islocked}, 6780 {"items", 1, 1, f_items}, 6781 {"join", 1, 2, f_join}, 6782 {"keys", 1, 1, f_keys}, 6783 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6784 {"len", 1, 1, f_len}, 6785 {"libcall", 3, 3, f_libcall}, 6786 {"libcallnr", 3, 3, f_libcallnr}, 6787 {"line", 1, 1, f_line}, 6788 {"line2byte", 1, 1, f_line2byte}, 6789 {"lispindent", 1, 1, f_lispindent}, 6790 {"localtime", 0, 0, f_localtime}, 6791 {"map", 2, 2, f_map}, 6792 {"maparg", 1, 2, f_maparg}, 6793 {"mapcheck", 1, 2, f_mapcheck}, 6794 {"match", 2, 4, f_match}, 6795 {"matchend", 2, 4, f_matchend}, 6796 {"matchlist", 2, 4, f_matchlist}, 6797 {"matchstr", 2, 4, f_matchstr}, 6798 {"max", 1, 1, f_max}, 6799 {"min", 1, 1, f_min}, 6800 #ifdef vim_mkdir 6801 {"mkdir", 1, 3, f_mkdir}, 6802 #endif 6803 {"mode", 0, 0, f_mode}, 6804 {"nextnonblank", 1, 1, f_nextnonblank}, 6805 {"nr2char", 1, 1, f_nr2char}, 6806 {"prevnonblank", 1, 1, f_prevnonblank}, 6807 {"printf", 2, 19, f_printf}, 6808 {"range", 1, 3, f_range}, 6809 {"readfile", 1, 3, f_readfile}, 6810 {"remote_expr", 2, 3, f_remote_expr}, 6811 {"remote_foreground", 1, 1, f_remote_foreground}, 6812 {"remote_peek", 1, 2, f_remote_peek}, 6813 {"remote_read", 1, 1, f_remote_read}, 6814 {"remote_send", 2, 3, f_remote_send}, 6815 {"remove", 2, 3, f_remove}, 6816 {"rename", 2, 2, f_rename}, 6817 {"repeat", 2, 2, f_repeat}, 6818 {"resolve", 1, 1, f_resolve}, 6819 {"reverse", 1, 1, f_reverse}, 6820 {"search", 1, 2, f_search}, 6821 {"searchpair", 3, 5, f_searchpair}, 6822 {"server2client", 2, 2, f_server2client}, 6823 {"serverlist", 0, 0, f_serverlist}, 6824 {"setbufvar", 3, 3, f_setbufvar}, 6825 {"setcmdpos", 1, 1, f_setcmdpos}, 6826 {"setline", 2, 2, f_setline}, 6827 {"setqflist", 1, 2, f_setqflist}, 6828 {"setreg", 2, 3, f_setreg}, 6829 {"setwinvar", 3, 3, f_setwinvar}, 6830 {"simplify", 1, 1, f_simplify}, 6831 {"sort", 1, 2, f_sort}, 6832 {"soundfold", 1, 1, f_soundfold}, 6833 {"spellbadword", 0, 0, f_spellbadword}, 6834 {"spellsuggest", 1, 2, f_spellsuggest}, 6835 {"split", 1, 3, f_split}, 6836 #ifdef HAVE_STRFTIME 6837 {"strftime", 1, 2, f_strftime}, 6838 #endif 6839 {"stridx", 2, 3, f_stridx}, 6840 {"string", 1, 1, f_string}, 6841 {"strlen", 1, 1, f_strlen}, 6842 {"strpart", 2, 3, f_strpart}, 6843 {"strridx", 2, 3, f_strridx}, 6844 {"strtrans", 1, 1, f_strtrans}, 6845 {"submatch", 1, 1, f_submatch}, 6846 {"substitute", 4, 4, f_substitute}, 6847 {"synID", 3, 3, f_synID}, 6848 {"synIDattr", 2, 3, f_synIDattr}, 6849 {"synIDtrans", 1, 1, f_synIDtrans}, 6850 {"system", 1, 2, f_system}, 6851 {"taglist", 1, 1, f_taglist}, 6852 {"tempname", 0, 0, f_tempname}, 6853 {"test", 1, 1, f_test}, 6854 {"tolower", 1, 1, f_tolower}, 6855 {"toupper", 1, 1, f_toupper}, 6856 {"tr", 3, 3, f_tr}, 6857 {"type", 1, 1, f_type}, 6858 {"values", 1, 1, f_values}, 6859 {"virtcol", 1, 1, f_virtcol}, 6860 {"visualmode", 0, 1, f_visualmode}, 6861 {"winbufnr", 1, 1, f_winbufnr}, 6862 {"wincol", 0, 0, f_wincol}, 6863 {"winheight", 1, 1, f_winheight}, 6864 {"winline", 0, 0, f_winline}, 6865 {"winnr", 0, 1, f_winnr}, 6866 {"winrestcmd", 0, 0, f_winrestcmd}, 6867 {"winwidth", 1, 1, f_winwidth}, 6868 {"writefile", 2, 3, f_writefile}, 6869 }; 6870 6871 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6872 6873 /* 6874 * Function given to ExpandGeneric() to obtain the list of internal 6875 * or user defined function names. 6876 */ 6877 char_u * 6878 get_function_name(xp, idx) 6879 expand_T *xp; 6880 int idx; 6881 { 6882 static int intidx = -1; 6883 char_u *name; 6884 6885 if (idx == 0) 6886 intidx = -1; 6887 if (intidx < 0) 6888 { 6889 name = get_user_func_name(xp, idx); 6890 if (name != NULL) 6891 return name; 6892 } 6893 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6894 { 6895 STRCPY(IObuff, functions[intidx].f_name); 6896 STRCAT(IObuff, "("); 6897 if (functions[intidx].f_max_argc == 0) 6898 STRCAT(IObuff, ")"); 6899 return IObuff; 6900 } 6901 6902 return NULL; 6903 } 6904 6905 /* 6906 * Function given to ExpandGeneric() to obtain the list of internal or 6907 * user defined variable or function names. 6908 */ 6909 /*ARGSUSED*/ 6910 char_u * 6911 get_expr_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_function_name(xp, idx); 6923 if (name != NULL) 6924 return name; 6925 } 6926 return get_user_var_name(xp, ++intidx); 6927 } 6928 6929 #endif /* FEAT_CMDL_COMPL */ 6930 6931 /* 6932 * Find internal function in table above. 6933 * Return index, or -1 if not found 6934 */ 6935 static int 6936 find_internal_func(name) 6937 char_u *name; /* name of the function */ 6938 { 6939 int first = 0; 6940 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 6941 int cmp; 6942 int x; 6943 6944 /* 6945 * Find the function name in the table. Binary search. 6946 */ 6947 while (first <= last) 6948 { 6949 x = first + ((unsigned)(last - first) >> 1); 6950 cmp = STRCMP(name, functions[x].f_name); 6951 if (cmp < 0) 6952 last = x - 1; 6953 else if (cmp > 0) 6954 first = x + 1; 6955 else 6956 return x; 6957 } 6958 return -1; 6959 } 6960 6961 /* 6962 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 6963 * name it contains, otherwise return "name". 6964 */ 6965 static char_u * 6966 deref_func_name(name, lenp) 6967 char_u *name; 6968 int *lenp; 6969 { 6970 dictitem_T *v; 6971 int cc; 6972 6973 cc = name[*lenp]; 6974 name[*lenp] = NUL; 6975 v = find_var(name, NULL); 6976 name[*lenp] = cc; 6977 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 6978 { 6979 if (v->di_tv.vval.v_string == NULL) 6980 { 6981 *lenp = 0; 6982 return (char_u *)""; /* just in case */ 6983 } 6984 *lenp = STRLEN(v->di_tv.vval.v_string); 6985 return v->di_tv.vval.v_string; 6986 } 6987 6988 return name; 6989 } 6990 6991 /* 6992 * Allocate a variable for the result of a function. 6993 * Return OK or FAIL. 6994 */ 6995 static int 6996 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 6997 evaluate, selfdict) 6998 char_u *name; /* name of the function */ 6999 int len; /* length of "name" */ 7000 typval_T *rettv; 7001 char_u **arg; /* argument, pointing to the '(' */ 7002 linenr_T firstline; /* first line of range */ 7003 linenr_T lastline; /* last line of range */ 7004 int *doesrange; /* return: function handled range */ 7005 int evaluate; 7006 dict_T *selfdict; /* Dictionary for "self" */ 7007 { 7008 char_u *argp; 7009 int ret = OK; 7010 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7011 int argcount = 0; /* number of arguments found */ 7012 7013 /* 7014 * Get the arguments. 7015 */ 7016 argp = *arg; 7017 while (argcount < MAX_FUNC_ARGS) 7018 { 7019 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7020 if (*argp == ')' || *argp == ',' || *argp == NUL) 7021 break; 7022 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7023 { 7024 ret = FAIL; 7025 break; 7026 } 7027 ++argcount; 7028 if (*argp != ',') 7029 break; 7030 } 7031 if (*argp == ')') 7032 ++argp; 7033 else 7034 ret = FAIL; 7035 7036 if (ret == OK) 7037 ret = call_func(name, len, rettv, argcount, argvars, 7038 firstline, lastline, doesrange, evaluate, selfdict); 7039 else if (!aborting()) 7040 { 7041 if (argcount == MAX_FUNC_ARGS) 7042 emsg_funcname("E740: Too many arguments for function %s", name); 7043 else 7044 emsg_funcname("E116: Invalid arguments for function %s", name); 7045 } 7046 7047 while (--argcount >= 0) 7048 clear_tv(&argvars[argcount]); 7049 7050 *arg = skipwhite(argp); 7051 return ret; 7052 } 7053 7054 7055 /* 7056 * Call a function with its resolved parameters 7057 * Return OK or FAIL. 7058 */ 7059 static int 7060 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7061 doesrange, evaluate, selfdict) 7062 char_u *name; /* name of the function */ 7063 int len; /* length of "name" */ 7064 typval_T *rettv; /* return value goes here */ 7065 int argcount; /* number of "argvars" */ 7066 typval_T *argvars; /* vars for arguments */ 7067 linenr_T firstline; /* first line of range */ 7068 linenr_T lastline; /* last line of range */ 7069 int *doesrange; /* return: function handled range */ 7070 int evaluate; 7071 dict_T *selfdict; /* Dictionary for "self" */ 7072 { 7073 int ret = FAIL; 7074 #define ERROR_UNKNOWN 0 7075 #define ERROR_TOOMANY 1 7076 #define ERROR_TOOFEW 2 7077 #define ERROR_SCRIPT 3 7078 #define ERROR_DICT 4 7079 #define ERROR_NONE 5 7080 #define ERROR_OTHER 6 7081 int error = ERROR_NONE; 7082 int i; 7083 int llen; 7084 ufunc_T *fp; 7085 int cc; 7086 #define FLEN_FIXED 40 7087 char_u fname_buf[FLEN_FIXED + 1]; 7088 char_u *fname; 7089 7090 /* 7091 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7092 * Change <SNR>123_name() to K_SNR 123_name(). 7093 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7094 */ 7095 cc = name[len]; 7096 name[len] = NUL; 7097 llen = eval_fname_script(name); 7098 if (llen > 0) 7099 { 7100 fname_buf[0] = K_SPECIAL; 7101 fname_buf[1] = KS_EXTRA; 7102 fname_buf[2] = (int)KE_SNR; 7103 i = 3; 7104 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7105 { 7106 if (current_SID <= 0) 7107 error = ERROR_SCRIPT; 7108 else 7109 { 7110 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7111 i = (int)STRLEN(fname_buf); 7112 } 7113 } 7114 if (i + STRLEN(name + llen) < FLEN_FIXED) 7115 { 7116 STRCPY(fname_buf + i, name + llen); 7117 fname = fname_buf; 7118 } 7119 else 7120 { 7121 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7122 if (fname == NULL) 7123 error = ERROR_OTHER; 7124 else 7125 { 7126 mch_memmove(fname, fname_buf, (size_t)i); 7127 STRCPY(fname + i, name + llen); 7128 } 7129 } 7130 } 7131 else 7132 fname = name; 7133 7134 *doesrange = FALSE; 7135 7136 7137 /* execute the function if no errors detected and executing */ 7138 if (evaluate && error == ERROR_NONE) 7139 { 7140 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7141 error = ERROR_UNKNOWN; 7142 7143 if (!builtin_function(fname)) 7144 { 7145 /* 7146 * User defined function. 7147 */ 7148 fp = find_func(fname); 7149 7150 #ifdef FEAT_AUTOCMD 7151 /* Trigger FuncUndefined event, may load the function. */ 7152 if (fp == NULL 7153 && apply_autocmds(EVENT_FUNCUNDEFINED, 7154 fname, fname, TRUE, NULL) 7155 && !aborting()) 7156 { 7157 /* executed an autocommand, search for the function again */ 7158 fp = find_func(fname); 7159 } 7160 #endif 7161 /* Try loading a package. */ 7162 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7163 { 7164 /* loaded a package, search for the function again */ 7165 fp = find_func(fname); 7166 } 7167 7168 if (fp != NULL) 7169 { 7170 if (fp->uf_flags & FC_RANGE) 7171 *doesrange = TRUE; 7172 if (argcount < fp->uf_args.ga_len) 7173 error = ERROR_TOOFEW; 7174 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7175 error = ERROR_TOOMANY; 7176 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7177 error = ERROR_DICT; 7178 else 7179 { 7180 /* 7181 * Call the user function. 7182 * Save and restore search patterns, script variables and 7183 * redo buffer. 7184 */ 7185 save_search_patterns(); 7186 saveRedobuff(); 7187 ++fp->uf_calls; 7188 call_user_func(fp, argcount, argvars, rettv, 7189 firstline, lastline, 7190 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7191 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7192 && fp->uf_refcount <= 0) 7193 /* Function was unreferenced while being used, free it 7194 * now. */ 7195 func_free(fp); 7196 restoreRedobuff(); 7197 restore_search_patterns(); 7198 error = ERROR_NONE; 7199 } 7200 } 7201 } 7202 else 7203 { 7204 /* 7205 * Find the function name in the table, call its implementation. 7206 */ 7207 i = find_internal_func(fname); 7208 if (i >= 0) 7209 { 7210 if (argcount < functions[i].f_min_argc) 7211 error = ERROR_TOOFEW; 7212 else if (argcount > functions[i].f_max_argc) 7213 error = ERROR_TOOMANY; 7214 else 7215 { 7216 argvars[argcount].v_type = VAR_UNKNOWN; 7217 functions[i].f_func(argvars, rettv); 7218 error = ERROR_NONE; 7219 } 7220 } 7221 } 7222 /* 7223 * The function call (or "FuncUndefined" autocommand sequence) might 7224 * have been aborted by an error, an interrupt, or an explicitly thrown 7225 * exception that has not been caught so far. This situation can be 7226 * tested for by calling aborting(). For an error in an internal 7227 * function or for the "E132" error in call_user_func(), however, the 7228 * throw point at which the "force_abort" flag (temporarily reset by 7229 * emsg()) is normally updated has not been reached yet. We need to 7230 * update that flag first to make aborting() reliable. 7231 */ 7232 update_force_abort(); 7233 } 7234 if (error == ERROR_NONE) 7235 ret = OK; 7236 7237 /* 7238 * Report an error unless the argument evaluation or function call has been 7239 * cancelled due to an aborting error, an interrupt, or an exception. 7240 */ 7241 if (!aborting()) 7242 { 7243 switch (error) 7244 { 7245 case ERROR_UNKNOWN: 7246 emsg_funcname("E117: Unknown function: %s", name); 7247 break; 7248 case ERROR_TOOMANY: 7249 emsg_funcname(e_toomanyarg, name); 7250 break; 7251 case ERROR_TOOFEW: 7252 emsg_funcname("E119: Not enough arguments for function: %s", 7253 name); 7254 break; 7255 case ERROR_SCRIPT: 7256 emsg_funcname("E120: Using <SID> not in a script context: %s", 7257 name); 7258 break; 7259 case ERROR_DICT: 7260 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7261 name); 7262 break; 7263 } 7264 } 7265 7266 name[len] = cc; 7267 if (fname != name && fname != fname_buf) 7268 vim_free(fname); 7269 7270 return ret; 7271 } 7272 7273 /* 7274 * Give an error message with a function name. Handle <SNR> things. 7275 */ 7276 static void 7277 emsg_funcname(msg, name) 7278 char *msg; 7279 char_u *name; 7280 { 7281 char_u *p; 7282 7283 if (*name == K_SPECIAL) 7284 p = concat_str((char_u *)"<SNR>", name + 3); 7285 else 7286 p = name; 7287 EMSG2(_(msg), p); 7288 if (p != name) 7289 vim_free(p); 7290 } 7291 7292 /********************************************* 7293 * Implementation of the built-in functions 7294 */ 7295 7296 /* 7297 * "add(list, item)" function 7298 */ 7299 static void 7300 f_add(argvars, rettv) 7301 typval_T *argvars; 7302 typval_T *rettv; 7303 { 7304 list_T *l; 7305 7306 rettv->vval.v_number = 1; /* Default: Failed */ 7307 if (argvars[0].v_type == VAR_LIST) 7308 { 7309 if ((l = argvars[0].vval.v_list) != NULL 7310 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7311 && list_append_tv(l, &argvars[1]) == OK) 7312 copy_tv(&argvars[0], rettv); 7313 } 7314 else 7315 EMSG(_(e_listreq)); 7316 } 7317 7318 /* 7319 * "append(lnum, string/list)" function 7320 */ 7321 static void 7322 f_append(argvars, rettv) 7323 typval_T *argvars; 7324 typval_T *rettv; 7325 { 7326 long lnum; 7327 char_u *line; 7328 list_T *l = NULL; 7329 listitem_T *li = NULL; 7330 typval_T *tv; 7331 long added = 0; 7332 7333 lnum = get_tv_lnum(argvars); 7334 if (lnum >= 0 7335 && lnum <= curbuf->b_ml.ml_line_count 7336 && u_save(lnum, lnum + 1) == OK) 7337 { 7338 if (argvars[1].v_type == VAR_LIST) 7339 { 7340 l = argvars[1].vval.v_list; 7341 if (l == NULL) 7342 return; 7343 li = l->lv_first; 7344 } 7345 rettv->vval.v_number = 0; /* Default: Success */ 7346 for (;;) 7347 { 7348 if (l == NULL) 7349 tv = &argvars[1]; /* append a string */ 7350 else if (li == NULL) 7351 break; /* end of list */ 7352 else 7353 tv = &li->li_tv; /* append item from list */ 7354 line = get_tv_string_chk(tv); 7355 if (line == NULL) /* type error */ 7356 { 7357 rettv->vval.v_number = 1; /* Failed */ 7358 break; 7359 } 7360 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7361 ++added; 7362 if (l == NULL) 7363 break; 7364 li = li->li_next; 7365 } 7366 7367 appended_lines_mark(lnum, added); 7368 if (curwin->w_cursor.lnum > lnum) 7369 curwin->w_cursor.lnum += added; 7370 } 7371 else 7372 rettv->vval.v_number = 1; /* Failed */ 7373 } 7374 7375 /* 7376 * "argc()" function 7377 */ 7378 /* ARGSUSED */ 7379 static void 7380 f_argc(argvars, rettv) 7381 typval_T *argvars; 7382 typval_T *rettv; 7383 { 7384 rettv->vval.v_number = ARGCOUNT; 7385 } 7386 7387 /* 7388 * "argidx()" function 7389 */ 7390 /* ARGSUSED */ 7391 static void 7392 f_argidx(argvars, rettv) 7393 typval_T *argvars; 7394 typval_T *rettv; 7395 { 7396 rettv->vval.v_number = curwin->w_arg_idx; 7397 } 7398 7399 /* 7400 * "argv(nr)" function 7401 */ 7402 static void 7403 f_argv(argvars, rettv) 7404 typval_T *argvars; 7405 typval_T *rettv; 7406 { 7407 int idx; 7408 7409 idx = get_tv_number_chk(&argvars[0], NULL); 7410 if (idx >= 0 && idx < ARGCOUNT) 7411 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7412 else 7413 rettv->vval.v_string = NULL; 7414 rettv->v_type = VAR_STRING; 7415 } 7416 7417 /* 7418 * "browse(save, title, initdir, default)" function 7419 */ 7420 /* ARGSUSED */ 7421 static void 7422 f_browse(argvars, rettv) 7423 typval_T *argvars; 7424 typval_T *rettv; 7425 { 7426 #ifdef FEAT_BROWSE 7427 int save; 7428 char_u *title; 7429 char_u *initdir; 7430 char_u *defname; 7431 char_u buf[NUMBUFLEN]; 7432 char_u buf2[NUMBUFLEN]; 7433 int error = FALSE; 7434 7435 save = get_tv_number_chk(&argvars[0], &error); 7436 title = get_tv_string_chk(&argvars[1]); 7437 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7438 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7439 7440 if (error || title == NULL || initdir == NULL || defname == NULL) 7441 rettv->vval.v_string = NULL; 7442 else 7443 rettv->vval.v_string = 7444 do_browse(save ? BROWSE_SAVE : 0, 7445 title, defname, NULL, initdir, NULL, curbuf); 7446 #else 7447 rettv->vval.v_string = NULL; 7448 #endif 7449 rettv->v_type = VAR_STRING; 7450 } 7451 7452 /* 7453 * "browsedir(title, initdir)" function 7454 */ 7455 /* ARGSUSED */ 7456 static void 7457 f_browsedir(argvars, rettv) 7458 typval_T *argvars; 7459 typval_T *rettv; 7460 { 7461 #ifdef FEAT_BROWSE 7462 char_u *title; 7463 char_u *initdir; 7464 char_u buf[NUMBUFLEN]; 7465 7466 title = get_tv_string_chk(&argvars[0]); 7467 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7468 7469 if (title == NULL || initdir == NULL) 7470 rettv->vval.v_string = NULL; 7471 else 7472 rettv->vval.v_string = do_browse(BROWSE_DIR, 7473 title, NULL, NULL, initdir, NULL, curbuf); 7474 #else 7475 rettv->vval.v_string = NULL; 7476 #endif 7477 rettv->v_type = VAR_STRING; 7478 } 7479 7480 static buf_T *find_buffer __ARGS((typval_T *avar)); 7481 7482 /* 7483 * Find a buffer by number or exact name. 7484 */ 7485 static buf_T * 7486 find_buffer(avar) 7487 typval_T *avar; 7488 { 7489 buf_T *buf = NULL; 7490 7491 if (avar->v_type == VAR_NUMBER) 7492 buf = buflist_findnr((int)avar->vval.v_number); 7493 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7494 { 7495 buf = buflist_findname_exp(avar->vval.v_string); 7496 if (buf == NULL) 7497 { 7498 /* No full path name match, try a match with a URL or a "nofile" 7499 * buffer, these don't use the full path. */ 7500 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7501 if (buf->b_fname != NULL 7502 && (path_with_url(buf->b_fname) 7503 #ifdef FEAT_QUICKFIX 7504 || bt_nofile(buf) 7505 #endif 7506 ) 7507 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7508 break; 7509 } 7510 } 7511 return buf; 7512 } 7513 7514 /* 7515 * "bufexists(expr)" function 7516 */ 7517 static void 7518 f_bufexists(argvars, rettv) 7519 typval_T *argvars; 7520 typval_T *rettv; 7521 { 7522 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7523 } 7524 7525 /* 7526 * "buflisted(expr)" function 7527 */ 7528 static void 7529 f_buflisted(argvars, rettv) 7530 typval_T *argvars; 7531 typval_T *rettv; 7532 { 7533 buf_T *buf; 7534 7535 buf = find_buffer(&argvars[0]); 7536 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7537 } 7538 7539 /* 7540 * "bufloaded(expr)" function 7541 */ 7542 static void 7543 f_bufloaded(argvars, rettv) 7544 typval_T *argvars; 7545 typval_T *rettv; 7546 { 7547 buf_T *buf; 7548 7549 buf = find_buffer(&argvars[0]); 7550 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7551 } 7552 7553 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7554 7555 /* 7556 * Get buffer by number or pattern. 7557 */ 7558 static buf_T * 7559 get_buf_tv(tv) 7560 typval_T *tv; 7561 { 7562 char_u *name = tv->vval.v_string; 7563 int save_magic; 7564 char_u *save_cpo; 7565 buf_T *buf; 7566 7567 if (tv->v_type == VAR_NUMBER) 7568 return buflist_findnr((int)tv->vval.v_number); 7569 if (tv->v_type != VAR_STRING) 7570 return NULL; 7571 if (name == NULL || *name == NUL) 7572 return curbuf; 7573 if (name[0] == '$' && name[1] == NUL) 7574 return lastbuf; 7575 7576 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7577 save_magic = p_magic; 7578 p_magic = TRUE; 7579 save_cpo = p_cpo; 7580 p_cpo = (char_u *)""; 7581 7582 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7583 TRUE, FALSE)); 7584 7585 p_magic = save_magic; 7586 p_cpo = save_cpo; 7587 7588 /* If not found, try expanding the name, like done for bufexists(). */ 7589 if (buf == NULL) 7590 buf = find_buffer(tv); 7591 7592 return buf; 7593 } 7594 7595 /* 7596 * "bufname(expr)" function 7597 */ 7598 static void 7599 f_bufname(argvars, rettv) 7600 typval_T *argvars; 7601 typval_T *rettv; 7602 { 7603 buf_T *buf; 7604 7605 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7606 ++emsg_off; 7607 buf = get_buf_tv(&argvars[0]); 7608 rettv->v_type = VAR_STRING; 7609 if (buf != NULL && buf->b_fname != NULL) 7610 rettv->vval.v_string = vim_strsave(buf->b_fname); 7611 else 7612 rettv->vval.v_string = NULL; 7613 --emsg_off; 7614 } 7615 7616 /* 7617 * "bufnr(expr)" function 7618 */ 7619 static void 7620 f_bufnr(argvars, rettv) 7621 typval_T *argvars; 7622 typval_T *rettv; 7623 { 7624 buf_T *buf; 7625 7626 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7627 ++emsg_off; 7628 buf = get_buf_tv(&argvars[0]); 7629 if (buf != NULL) 7630 rettv->vval.v_number = buf->b_fnum; 7631 else 7632 rettv->vval.v_number = -1; 7633 --emsg_off; 7634 } 7635 7636 /* 7637 * "bufwinnr(nr)" function 7638 */ 7639 static void 7640 f_bufwinnr(argvars, rettv) 7641 typval_T *argvars; 7642 typval_T *rettv; 7643 { 7644 #ifdef FEAT_WINDOWS 7645 win_T *wp; 7646 int winnr = 0; 7647 #endif 7648 buf_T *buf; 7649 7650 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7651 ++emsg_off; 7652 buf = get_buf_tv(&argvars[0]); 7653 #ifdef FEAT_WINDOWS 7654 for (wp = firstwin; wp; wp = wp->w_next) 7655 { 7656 ++winnr; 7657 if (wp->w_buffer == buf) 7658 break; 7659 } 7660 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7661 #else 7662 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7663 #endif 7664 --emsg_off; 7665 } 7666 7667 /* 7668 * "byte2line(byte)" function 7669 */ 7670 /*ARGSUSED*/ 7671 static void 7672 f_byte2line(argvars, rettv) 7673 typval_T *argvars; 7674 typval_T *rettv; 7675 { 7676 #ifndef FEAT_BYTEOFF 7677 rettv->vval.v_number = -1; 7678 #else 7679 long boff = 0; 7680 7681 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7682 if (boff < 0) 7683 rettv->vval.v_number = -1; 7684 else 7685 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7686 (linenr_T)0, &boff); 7687 #endif 7688 } 7689 7690 /* 7691 * "byteidx()" function 7692 */ 7693 /*ARGSUSED*/ 7694 static void 7695 f_byteidx(argvars, rettv) 7696 typval_T *argvars; 7697 typval_T *rettv; 7698 { 7699 #ifdef FEAT_MBYTE 7700 char_u *t; 7701 #endif 7702 char_u *str; 7703 long idx; 7704 7705 str = get_tv_string_chk(&argvars[0]); 7706 idx = get_tv_number_chk(&argvars[1], NULL); 7707 rettv->vval.v_number = -1; 7708 if (str == NULL || idx < 0) 7709 return; 7710 7711 #ifdef FEAT_MBYTE 7712 t = str; 7713 for ( ; idx > 0; idx--) 7714 { 7715 if (*t == NUL) /* EOL reached */ 7716 return; 7717 t += (*mb_ptr2len)(t); 7718 } 7719 rettv->vval.v_number = t - str; 7720 #else 7721 if (idx <= STRLEN(str)) 7722 rettv->vval.v_number = idx; 7723 #endif 7724 } 7725 7726 /* 7727 * "call(func, arglist)" function 7728 */ 7729 static void 7730 f_call(argvars, rettv) 7731 typval_T *argvars; 7732 typval_T *rettv; 7733 { 7734 char_u *func; 7735 typval_T argv[MAX_FUNC_ARGS]; 7736 int argc = 0; 7737 listitem_T *item; 7738 int dummy; 7739 dict_T *selfdict = NULL; 7740 7741 rettv->vval.v_number = 0; 7742 if (argvars[1].v_type != VAR_LIST) 7743 { 7744 EMSG(_(e_listreq)); 7745 return; 7746 } 7747 if (argvars[1].vval.v_list == NULL) 7748 return; 7749 7750 if (argvars[0].v_type == VAR_FUNC) 7751 func = argvars[0].vval.v_string; 7752 else 7753 func = get_tv_string(&argvars[0]); 7754 if (*func == NUL) 7755 return; /* type error or empty name */ 7756 7757 if (argvars[2].v_type != VAR_UNKNOWN) 7758 { 7759 if (argvars[2].v_type != VAR_DICT) 7760 { 7761 EMSG(_(e_dictreq)); 7762 return; 7763 } 7764 selfdict = argvars[2].vval.v_dict; 7765 } 7766 7767 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7768 item = item->li_next) 7769 { 7770 if (argc == MAX_FUNC_ARGS) 7771 { 7772 EMSG(_("E699: Too many arguments")); 7773 break; 7774 } 7775 /* Make a copy of each argument. This is needed to be able to set 7776 * v_lock to VAR_FIXED in the copy without changing the original list. 7777 */ 7778 copy_tv(&item->li_tv, &argv[argc++]); 7779 } 7780 7781 if (item == NULL) 7782 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7783 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7784 &dummy, TRUE, selfdict); 7785 7786 /* Free the arguments. */ 7787 while (argc > 0) 7788 clear_tv(&argv[--argc]); 7789 } 7790 7791 /* 7792 * "char2nr(string)" function 7793 */ 7794 static void 7795 f_char2nr(argvars, rettv) 7796 typval_T *argvars; 7797 typval_T *rettv; 7798 { 7799 #ifdef FEAT_MBYTE 7800 if (has_mbyte) 7801 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7802 else 7803 #endif 7804 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7805 } 7806 7807 /* 7808 * "cindent(lnum)" function 7809 */ 7810 static void 7811 f_cindent(argvars, rettv) 7812 typval_T *argvars; 7813 typval_T *rettv; 7814 { 7815 #ifdef FEAT_CINDENT 7816 pos_T pos; 7817 linenr_T lnum; 7818 7819 pos = curwin->w_cursor; 7820 lnum = get_tv_lnum(argvars); 7821 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7822 { 7823 curwin->w_cursor.lnum = lnum; 7824 rettv->vval.v_number = get_c_indent(); 7825 curwin->w_cursor = pos; 7826 } 7827 else 7828 #endif 7829 rettv->vval.v_number = -1; 7830 } 7831 7832 /* 7833 * "col(string)" function 7834 */ 7835 static void 7836 f_col(argvars, rettv) 7837 typval_T *argvars; 7838 typval_T *rettv; 7839 { 7840 colnr_T col = 0; 7841 pos_T *fp; 7842 7843 fp = var2fpos(&argvars[0], FALSE); 7844 if (fp != NULL) 7845 { 7846 if (fp->col == MAXCOL) 7847 { 7848 /* '> can be MAXCOL, get the length of the line then */ 7849 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7850 col = STRLEN(ml_get(fp->lnum)) + 1; 7851 else 7852 col = MAXCOL; 7853 } 7854 else 7855 { 7856 col = fp->col + 1; 7857 #ifdef FEAT_VIRTUALEDIT 7858 /* col(".") when the cursor is on the NUL at the end of the line 7859 * because of "coladd" can be seen as an extra column. */ 7860 if (virtual_active() && fp == &curwin->w_cursor) 7861 { 7862 char_u *p = ml_get_cursor(); 7863 7864 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7865 curwin->w_virtcol - curwin->w_cursor.coladd)) 7866 { 7867 # ifdef FEAT_MBYTE 7868 int l; 7869 7870 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 7871 col += l; 7872 # else 7873 if (*p != NUL && p[1] == NUL) 7874 ++col; 7875 # endif 7876 } 7877 } 7878 #endif 7879 } 7880 } 7881 rettv->vval.v_number = col; 7882 } 7883 7884 #if defined(FEAT_INS_EXPAND) 7885 /* 7886 * "complete_add()" function 7887 */ 7888 /*ARGSUSED*/ 7889 static void 7890 f_complete_add(argvars, rettv) 7891 typval_T *argvars; 7892 typval_T *rettv; 7893 { 7894 char_u *s; 7895 7896 s = get_tv_string_chk(&argvars[0]); 7897 if (s != NULL) 7898 rettv->vval.v_number = ins_compl_add(s, -1, NULL, FORWARD, 0); 7899 } 7900 7901 /* 7902 * "complete_check()" function 7903 */ 7904 /*ARGSUSED*/ 7905 static void 7906 f_complete_check(argvars, rettv) 7907 typval_T *argvars; 7908 typval_T *rettv; 7909 { 7910 int saved = RedrawingDisabled; 7911 7912 RedrawingDisabled = 0; 7913 ins_compl_check_keys(0); 7914 rettv->vval.v_number = compl_interrupted; 7915 RedrawingDisabled = saved; 7916 } 7917 #endif 7918 7919 /* 7920 * "confirm(message, buttons[, default [, type]])" function 7921 */ 7922 /*ARGSUSED*/ 7923 static void 7924 f_confirm(argvars, rettv) 7925 typval_T *argvars; 7926 typval_T *rettv; 7927 { 7928 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7929 char_u *message; 7930 char_u *buttons = NULL; 7931 char_u buf[NUMBUFLEN]; 7932 char_u buf2[NUMBUFLEN]; 7933 int def = 1; 7934 int type = VIM_GENERIC; 7935 char_u *typestr; 7936 int error = FALSE; 7937 7938 message = get_tv_string_chk(&argvars[0]); 7939 if (message == NULL) 7940 error = TRUE; 7941 if (argvars[1].v_type != VAR_UNKNOWN) 7942 { 7943 buttons = get_tv_string_buf_chk(&argvars[1], buf); 7944 if (buttons == NULL) 7945 error = TRUE; 7946 if (argvars[2].v_type != VAR_UNKNOWN) 7947 { 7948 def = get_tv_number_chk(&argvars[2], &error); 7949 if (argvars[3].v_type != VAR_UNKNOWN) 7950 { 7951 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 7952 if (typestr == NULL) 7953 error = TRUE; 7954 else 7955 { 7956 switch (TOUPPER_ASC(*typestr)) 7957 { 7958 case 'E': type = VIM_ERROR; break; 7959 case 'Q': type = VIM_QUESTION; break; 7960 case 'I': type = VIM_INFO; break; 7961 case 'W': type = VIM_WARNING; break; 7962 case 'G': type = VIM_GENERIC; break; 7963 } 7964 } 7965 } 7966 } 7967 } 7968 7969 if (buttons == NULL || *buttons == NUL) 7970 buttons = (char_u *)_("&Ok"); 7971 7972 if (error) 7973 rettv->vval.v_number = 0; 7974 else 7975 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 7976 def, NULL); 7977 #else 7978 rettv->vval.v_number = 0; 7979 #endif 7980 } 7981 7982 /* 7983 * "copy()" function 7984 */ 7985 static void 7986 f_copy(argvars, rettv) 7987 typval_T *argvars; 7988 typval_T *rettv; 7989 { 7990 item_copy(&argvars[0], rettv, FALSE, 0); 7991 } 7992 7993 /* 7994 * "count()" function 7995 */ 7996 static void 7997 f_count(argvars, rettv) 7998 typval_T *argvars; 7999 typval_T *rettv; 8000 { 8001 long n = 0; 8002 int ic = FALSE; 8003 8004 if (argvars[0].v_type == VAR_LIST) 8005 { 8006 listitem_T *li; 8007 list_T *l; 8008 long idx; 8009 8010 if ((l = argvars[0].vval.v_list) != NULL) 8011 { 8012 li = l->lv_first; 8013 if (argvars[2].v_type != VAR_UNKNOWN) 8014 { 8015 int error = FALSE; 8016 8017 ic = get_tv_number_chk(&argvars[2], &error); 8018 if (argvars[3].v_type != VAR_UNKNOWN) 8019 { 8020 idx = get_tv_number_chk(&argvars[3], &error); 8021 if (!error) 8022 { 8023 li = list_find(l, idx); 8024 if (li == NULL) 8025 EMSGN(_(e_listidx), idx); 8026 } 8027 } 8028 if (error) 8029 li = NULL; 8030 } 8031 8032 for ( ; li != NULL; li = li->li_next) 8033 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8034 ++n; 8035 } 8036 } 8037 else if (argvars[0].v_type == VAR_DICT) 8038 { 8039 int todo; 8040 dict_T *d; 8041 hashitem_T *hi; 8042 8043 if ((d = argvars[0].vval.v_dict) != NULL) 8044 { 8045 int error = FALSE; 8046 8047 if (argvars[2].v_type != VAR_UNKNOWN) 8048 { 8049 ic = get_tv_number_chk(&argvars[2], &error); 8050 if (argvars[3].v_type != VAR_UNKNOWN) 8051 EMSG(_(e_invarg)); 8052 } 8053 8054 todo = error ? 0 : d->dv_hashtab.ht_used; 8055 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8056 { 8057 if (!HASHITEM_EMPTY(hi)) 8058 { 8059 --todo; 8060 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8061 ++n; 8062 } 8063 } 8064 } 8065 } 8066 else 8067 EMSG2(_(e_listdictarg), "count()"); 8068 rettv->vval.v_number = n; 8069 } 8070 8071 /* 8072 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8073 * 8074 * Checks the existence of a cscope connection. 8075 */ 8076 /*ARGSUSED*/ 8077 static void 8078 f_cscope_connection(argvars, rettv) 8079 typval_T *argvars; 8080 typval_T *rettv; 8081 { 8082 #ifdef FEAT_CSCOPE 8083 int num = 0; 8084 char_u *dbpath = NULL; 8085 char_u *prepend = NULL; 8086 char_u buf[NUMBUFLEN]; 8087 8088 if (argvars[0].v_type != VAR_UNKNOWN 8089 && argvars[1].v_type != VAR_UNKNOWN) 8090 { 8091 num = (int)get_tv_number(&argvars[0]); 8092 dbpath = get_tv_string(&argvars[1]); 8093 if (argvars[2].v_type != VAR_UNKNOWN) 8094 prepend = get_tv_string_buf(&argvars[2], buf); 8095 } 8096 8097 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8098 #else 8099 rettv->vval.v_number = 0; 8100 #endif 8101 } 8102 8103 /* 8104 * "cursor(lnum, col)" function 8105 * 8106 * Moves the cursor to the specified line and column 8107 */ 8108 /*ARGSUSED*/ 8109 static void 8110 f_cursor(argvars, rettv) 8111 typval_T *argvars; 8112 typval_T *rettv; 8113 { 8114 long line, col; 8115 8116 line = get_tv_lnum(argvars); 8117 col = get_tv_number_chk(&argvars[1], NULL); 8118 if (line < 0 || col < 0) 8119 return; /* type error; errmsg already given */ 8120 if (line > 0) 8121 curwin->w_cursor.lnum = line; 8122 if (col > 0) 8123 curwin->w_cursor.col = col - 1; 8124 #ifdef FEAT_VIRTUALEDIT 8125 curwin->w_cursor.coladd = 0; 8126 #endif 8127 8128 /* Make sure the cursor is in a valid position. */ 8129 check_cursor(); 8130 #ifdef FEAT_MBYTE 8131 /* Correct cursor for multi-byte character. */ 8132 if (has_mbyte) 8133 mb_adjust_cursor(); 8134 #endif 8135 8136 curwin->w_set_curswant = TRUE; 8137 } 8138 8139 /* 8140 * "deepcopy()" function 8141 */ 8142 static void 8143 f_deepcopy(argvars, rettv) 8144 typval_T *argvars; 8145 typval_T *rettv; 8146 { 8147 int noref = 0; 8148 8149 if (argvars[1].v_type != VAR_UNKNOWN) 8150 noref = get_tv_number_chk(&argvars[1], NULL); 8151 if (noref < 0 || noref > 1) 8152 EMSG(_(e_invarg)); 8153 else 8154 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8155 } 8156 8157 /* 8158 * "delete()" function 8159 */ 8160 static void 8161 f_delete(argvars, rettv) 8162 typval_T *argvars; 8163 typval_T *rettv; 8164 { 8165 if (check_restricted() || check_secure()) 8166 rettv->vval.v_number = -1; 8167 else 8168 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8169 } 8170 8171 /* 8172 * "did_filetype()" function 8173 */ 8174 /*ARGSUSED*/ 8175 static void 8176 f_did_filetype(argvars, rettv) 8177 typval_T *argvars; 8178 typval_T *rettv; 8179 { 8180 #ifdef FEAT_AUTOCMD 8181 rettv->vval.v_number = did_filetype; 8182 #else 8183 rettv->vval.v_number = 0; 8184 #endif 8185 } 8186 8187 /* 8188 * "diff_filler()" function 8189 */ 8190 /*ARGSUSED*/ 8191 static void 8192 f_diff_filler(argvars, rettv) 8193 typval_T *argvars; 8194 typval_T *rettv; 8195 { 8196 #ifdef FEAT_DIFF 8197 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8198 #endif 8199 } 8200 8201 /* 8202 * "diff_hlID()" function 8203 */ 8204 /*ARGSUSED*/ 8205 static void 8206 f_diff_hlID(argvars, rettv) 8207 typval_T *argvars; 8208 typval_T *rettv; 8209 { 8210 #ifdef FEAT_DIFF 8211 linenr_T lnum = get_tv_lnum(argvars); 8212 static linenr_T prev_lnum = 0; 8213 static int changedtick = 0; 8214 static int fnum = 0; 8215 static int change_start = 0; 8216 static int change_end = 0; 8217 static enum hlf_value hlID = 0; 8218 int filler_lines; 8219 int col; 8220 8221 if (lnum < 0) /* ignore type error in {lnum} arg */ 8222 lnum = 0; 8223 if (lnum != prev_lnum 8224 || changedtick != curbuf->b_changedtick 8225 || fnum != curbuf->b_fnum) 8226 { 8227 /* New line, buffer, change: need to get the values. */ 8228 filler_lines = diff_check(curwin, lnum); 8229 if (filler_lines < 0) 8230 { 8231 if (filler_lines == -1) 8232 { 8233 change_start = MAXCOL; 8234 change_end = -1; 8235 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8236 hlID = HLF_ADD; /* added line */ 8237 else 8238 hlID = HLF_CHD; /* changed line */ 8239 } 8240 else 8241 hlID = HLF_ADD; /* added line */ 8242 } 8243 else 8244 hlID = (enum hlf_value)0; 8245 prev_lnum = lnum; 8246 changedtick = curbuf->b_changedtick; 8247 fnum = curbuf->b_fnum; 8248 } 8249 8250 if (hlID == HLF_CHD || hlID == HLF_TXD) 8251 { 8252 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8253 if (col >= change_start && col <= change_end) 8254 hlID = HLF_TXD; /* changed text */ 8255 else 8256 hlID = HLF_CHD; /* changed line */ 8257 } 8258 rettv->vval.v_number = hlID == (enum hlf_value)0 ? 0 : (int)hlID; 8259 #endif 8260 } 8261 8262 /* 8263 * "empty({expr})" function 8264 */ 8265 static void 8266 f_empty(argvars, rettv) 8267 typval_T *argvars; 8268 typval_T *rettv; 8269 { 8270 int n; 8271 8272 switch (argvars[0].v_type) 8273 { 8274 case VAR_STRING: 8275 case VAR_FUNC: 8276 n = argvars[0].vval.v_string == NULL 8277 || *argvars[0].vval.v_string == NUL; 8278 break; 8279 case VAR_NUMBER: 8280 n = argvars[0].vval.v_number == 0; 8281 break; 8282 case VAR_LIST: 8283 n = argvars[0].vval.v_list == NULL 8284 || argvars[0].vval.v_list->lv_first == NULL; 8285 break; 8286 case VAR_DICT: 8287 n = argvars[0].vval.v_dict == NULL 8288 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8289 break; 8290 default: 8291 EMSG2(_(e_intern2), "f_empty()"); 8292 n = 0; 8293 } 8294 8295 rettv->vval.v_number = n; 8296 } 8297 8298 /* 8299 * "escape({string}, {chars})" function 8300 */ 8301 static void 8302 f_escape(argvars, rettv) 8303 typval_T *argvars; 8304 typval_T *rettv; 8305 { 8306 char_u buf[NUMBUFLEN]; 8307 8308 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8309 get_tv_string_buf(&argvars[1], buf)); 8310 rettv->v_type = VAR_STRING; 8311 } 8312 8313 /* 8314 * "eval()" function 8315 */ 8316 /*ARGSUSED*/ 8317 static void 8318 f_eval(argvars, rettv) 8319 typval_T *argvars; 8320 typval_T *rettv; 8321 { 8322 char_u *s; 8323 8324 s = get_tv_string_chk(&argvars[0]); 8325 if (s != NULL) 8326 s = skipwhite(s); 8327 8328 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8329 { 8330 rettv->v_type = VAR_NUMBER; 8331 rettv->vval.v_number = 0; 8332 } 8333 else if (*s != NUL) 8334 EMSG(_(e_trailing)); 8335 } 8336 8337 /* 8338 * "eventhandler()" function 8339 */ 8340 /*ARGSUSED*/ 8341 static void 8342 f_eventhandler(argvars, rettv) 8343 typval_T *argvars; 8344 typval_T *rettv; 8345 { 8346 rettv->vval.v_number = vgetc_busy; 8347 } 8348 8349 /* 8350 * "executable()" function 8351 */ 8352 static void 8353 f_executable(argvars, rettv) 8354 typval_T *argvars; 8355 typval_T *rettv; 8356 { 8357 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8358 } 8359 8360 /* 8361 * "exists()" function 8362 */ 8363 static void 8364 f_exists(argvars, rettv) 8365 typval_T *argvars; 8366 typval_T *rettv; 8367 { 8368 char_u *p; 8369 char_u *name; 8370 int n = FALSE; 8371 int len = 0; 8372 8373 p = get_tv_string(&argvars[0]); 8374 if (*p == '$') /* environment variable */ 8375 { 8376 /* first try "normal" environment variables (fast) */ 8377 if (mch_getenv(p + 1) != NULL) 8378 n = TRUE; 8379 else 8380 { 8381 /* try expanding things like $VIM and ${HOME} */ 8382 p = expand_env_save(p); 8383 if (p != NULL && *p != '$') 8384 n = TRUE; 8385 vim_free(p); 8386 } 8387 } 8388 else if (*p == '&' || *p == '+') /* option */ 8389 n = (get_option_tv(&p, NULL, TRUE) == OK); 8390 else if (*p == '*') /* internal or user defined function */ 8391 { 8392 n = function_exists(p + 1); 8393 } 8394 else if (*p == ':') 8395 { 8396 n = cmd_exists(p + 1); 8397 } 8398 else if (*p == '#') 8399 { 8400 #ifdef FEAT_AUTOCMD 8401 name = p + 1; 8402 p = vim_strchr(name, '#'); 8403 if (p != NULL) 8404 n = au_exists(name, p, p + 1); 8405 else 8406 n = au_exists(name, name + STRLEN(name), NULL); 8407 #endif 8408 } 8409 else /* internal variable */ 8410 { 8411 char_u *tofree; 8412 typval_T tv; 8413 8414 /* get_name_len() takes care of expanding curly braces */ 8415 name = p; 8416 len = get_name_len(&p, &tofree, TRUE, FALSE); 8417 if (len > 0) 8418 { 8419 if (tofree != NULL) 8420 name = tofree; 8421 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8422 if (n) 8423 { 8424 /* handle d.key, l[idx], f(expr) */ 8425 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8426 if (n) 8427 clear_tv(&tv); 8428 } 8429 } 8430 8431 vim_free(tofree); 8432 } 8433 8434 rettv->vval.v_number = n; 8435 } 8436 8437 /* 8438 * "expand()" function 8439 */ 8440 static void 8441 f_expand(argvars, rettv) 8442 typval_T *argvars; 8443 typval_T *rettv; 8444 { 8445 char_u *s; 8446 int len; 8447 char_u *errormsg; 8448 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8449 expand_T xpc; 8450 int error = FALSE; 8451 8452 rettv->v_type = VAR_STRING; 8453 s = get_tv_string(&argvars[0]); 8454 if (*s == '%' || *s == '#' || *s == '<') 8455 { 8456 ++emsg_off; 8457 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8458 --emsg_off; 8459 } 8460 else 8461 { 8462 /* When the optional second argument is non-zero, don't remove matches 8463 * for 'suffixes' and 'wildignore' */ 8464 if (argvars[1].v_type != VAR_UNKNOWN 8465 && get_tv_number_chk(&argvars[1], &error)) 8466 flags |= WILD_KEEP_ALL; 8467 if (!error) 8468 { 8469 ExpandInit(&xpc); 8470 xpc.xp_context = EXPAND_FILES; 8471 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8472 ExpandCleanup(&xpc); 8473 } 8474 else 8475 rettv->vval.v_string = NULL; 8476 } 8477 } 8478 8479 /* 8480 * "extend(list, list [, idx])" function 8481 * "extend(dict, dict [, action])" function 8482 */ 8483 static void 8484 f_extend(argvars, rettv) 8485 typval_T *argvars; 8486 typval_T *rettv; 8487 { 8488 rettv->vval.v_number = 0; 8489 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8490 { 8491 list_T *l1, *l2; 8492 listitem_T *item; 8493 long before; 8494 int error = FALSE; 8495 8496 l1 = argvars[0].vval.v_list; 8497 l2 = argvars[1].vval.v_list; 8498 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8499 && l2 != NULL) 8500 { 8501 if (argvars[2].v_type != VAR_UNKNOWN) 8502 { 8503 before = get_tv_number_chk(&argvars[2], &error); 8504 if (error) 8505 return; /* type error; errmsg already given */ 8506 8507 if (before == l1->lv_len) 8508 item = NULL; 8509 else 8510 { 8511 item = list_find(l1, before); 8512 if (item == NULL) 8513 { 8514 EMSGN(_(e_listidx), before); 8515 return; 8516 } 8517 } 8518 } 8519 else 8520 item = NULL; 8521 list_extend(l1, l2, item); 8522 8523 copy_tv(&argvars[0], rettv); 8524 } 8525 } 8526 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8527 { 8528 dict_T *d1, *d2; 8529 dictitem_T *di1; 8530 char_u *action; 8531 int i; 8532 hashitem_T *hi2; 8533 int todo; 8534 8535 d1 = argvars[0].vval.v_dict; 8536 d2 = argvars[1].vval.v_dict; 8537 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8538 && d2 != NULL) 8539 { 8540 /* Check the third argument. */ 8541 if (argvars[2].v_type != VAR_UNKNOWN) 8542 { 8543 static char *(av[]) = {"keep", "force", "error"}; 8544 8545 action = get_tv_string_chk(&argvars[2]); 8546 if (action == NULL) 8547 return; /* type error; errmsg already given */ 8548 for (i = 0; i < 3; ++i) 8549 if (STRCMP(action, av[i]) == 0) 8550 break; 8551 if (i == 3) 8552 { 8553 EMSGN(_(e_invarg2), action); 8554 return; 8555 } 8556 } 8557 else 8558 action = (char_u *)"force"; 8559 8560 /* Go over all entries in the second dict and add them to the 8561 * first dict. */ 8562 todo = d2->dv_hashtab.ht_used; 8563 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8564 { 8565 if (!HASHITEM_EMPTY(hi2)) 8566 { 8567 --todo; 8568 di1 = dict_find(d1, hi2->hi_key, -1); 8569 if (di1 == NULL) 8570 { 8571 di1 = dictitem_copy(HI2DI(hi2)); 8572 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8573 dictitem_free(di1); 8574 } 8575 else if (*action == 'e') 8576 { 8577 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8578 break; 8579 } 8580 else if (*action == 'f') 8581 { 8582 clear_tv(&di1->di_tv); 8583 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8584 } 8585 } 8586 } 8587 8588 copy_tv(&argvars[0], rettv); 8589 } 8590 } 8591 else 8592 EMSG2(_(e_listdictarg), "extend()"); 8593 } 8594 8595 /* 8596 * "filereadable()" function 8597 */ 8598 static void 8599 f_filereadable(argvars, rettv) 8600 typval_T *argvars; 8601 typval_T *rettv; 8602 { 8603 FILE *fd; 8604 char_u *p; 8605 int n; 8606 8607 p = get_tv_string(&argvars[0]); 8608 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8609 { 8610 n = TRUE; 8611 fclose(fd); 8612 } 8613 else 8614 n = FALSE; 8615 8616 rettv->vval.v_number = n; 8617 } 8618 8619 /* 8620 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8621 * rights to write into. 8622 */ 8623 static void 8624 f_filewritable(argvars, rettv) 8625 typval_T *argvars; 8626 typval_T *rettv; 8627 { 8628 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8629 } 8630 8631 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8632 8633 static void 8634 findfilendir(argvars, rettv, dir) 8635 typval_T *argvars; 8636 typval_T *rettv; 8637 int dir; 8638 { 8639 #ifdef FEAT_SEARCHPATH 8640 char_u *fname; 8641 char_u *fresult = NULL; 8642 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8643 char_u *p; 8644 char_u pathbuf[NUMBUFLEN]; 8645 int count = 1; 8646 int first = TRUE; 8647 8648 fname = get_tv_string(&argvars[0]); 8649 8650 if (argvars[1].v_type != VAR_UNKNOWN) 8651 { 8652 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8653 if (p == NULL) 8654 count = -1; /* error */ 8655 else 8656 { 8657 if (*p != NUL) 8658 path = p; 8659 8660 if (argvars[2].v_type != VAR_UNKNOWN) 8661 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8662 } 8663 } 8664 8665 if (*fname != NUL && count >= 0) 8666 { 8667 do 8668 { 8669 vim_free(fresult); 8670 fresult = find_file_in_path_option(first ? fname : NULL, 8671 first ? (int)STRLEN(fname) : 0, 8672 0, first, path, dir, NULL); 8673 first = FALSE; 8674 } while (--count > 0 && fresult != NULL); 8675 } 8676 8677 rettv->vval.v_string = fresult; 8678 #else 8679 rettv->vval.v_string = NULL; 8680 #endif 8681 rettv->v_type = VAR_STRING; 8682 } 8683 8684 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8685 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8686 8687 /* 8688 * Implementation of map() and filter(). 8689 */ 8690 static void 8691 filter_map(argvars, rettv, map) 8692 typval_T *argvars; 8693 typval_T *rettv; 8694 int map; 8695 { 8696 char_u buf[NUMBUFLEN]; 8697 char_u *expr; 8698 listitem_T *li, *nli; 8699 list_T *l = NULL; 8700 dictitem_T *di; 8701 hashtab_T *ht; 8702 hashitem_T *hi; 8703 dict_T *d = NULL; 8704 typval_T save_val; 8705 typval_T save_key; 8706 int rem; 8707 int todo; 8708 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8709 8710 8711 rettv->vval.v_number = 0; 8712 if (argvars[0].v_type == VAR_LIST) 8713 { 8714 if ((l = argvars[0].vval.v_list) == NULL 8715 || (map && tv_check_lock(l->lv_lock, msg))) 8716 return; 8717 } 8718 else if (argvars[0].v_type == VAR_DICT) 8719 { 8720 if ((d = argvars[0].vval.v_dict) == NULL 8721 || (map && tv_check_lock(d->dv_lock, msg))) 8722 return; 8723 } 8724 else 8725 { 8726 EMSG2(_(e_listdictarg), msg); 8727 return; 8728 } 8729 8730 expr = get_tv_string_buf_chk(&argvars[1], buf); 8731 /* On type errors, the preceding call has already displayed an error 8732 * message. Avoid a misleading error message for an empty string that 8733 * was not passed as argument. */ 8734 if (expr != NULL) 8735 { 8736 prepare_vimvar(VV_VAL, &save_val); 8737 expr = skipwhite(expr); 8738 8739 if (argvars[0].v_type == VAR_DICT) 8740 { 8741 prepare_vimvar(VV_KEY, &save_key); 8742 vimvars[VV_KEY].vv_type = VAR_STRING; 8743 8744 ht = &d->dv_hashtab; 8745 hash_lock(ht); 8746 todo = ht->ht_used; 8747 for (hi = ht->ht_array; todo > 0; ++hi) 8748 { 8749 if (!HASHITEM_EMPTY(hi)) 8750 { 8751 --todo; 8752 di = HI2DI(hi); 8753 if (tv_check_lock(di->di_tv.v_lock, msg)) 8754 break; 8755 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8756 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8757 break; 8758 if (!map && rem) 8759 dictitem_remove(d, di); 8760 clear_tv(&vimvars[VV_KEY].vv_tv); 8761 } 8762 } 8763 hash_unlock(ht); 8764 8765 restore_vimvar(VV_KEY, &save_key); 8766 } 8767 else 8768 { 8769 for (li = l->lv_first; li != NULL; li = nli) 8770 { 8771 if (tv_check_lock(li->li_tv.v_lock, msg)) 8772 break; 8773 nli = li->li_next; 8774 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8775 break; 8776 if (!map && rem) 8777 listitem_remove(l, li); 8778 } 8779 } 8780 8781 restore_vimvar(VV_VAL, &save_val); 8782 } 8783 8784 copy_tv(&argvars[0], rettv); 8785 } 8786 8787 static int 8788 filter_map_one(tv, expr, map, remp) 8789 typval_T *tv; 8790 char_u *expr; 8791 int map; 8792 int *remp; 8793 { 8794 typval_T rettv; 8795 char_u *s; 8796 8797 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8798 s = expr; 8799 if (eval1(&s, &rettv, TRUE) == FAIL) 8800 return FAIL; 8801 if (*s != NUL) /* check for trailing chars after expr */ 8802 { 8803 EMSG2(_(e_invexpr2), s); 8804 return FAIL; 8805 } 8806 if (map) 8807 { 8808 /* map(): replace the list item value */ 8809 clear_tv(tv); 8810 *tv = rettv; 8811 } 8812 else 8813 { 8814 int error = FALSE; 8815 8816 /* filter(): when expr is zero remove the item */ 8817 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8818 clear_tv(&rettv); 8819 /* On type error, nothing has been removed; return FAIL to stop the 8820 * loop. The error message was given by get_tv_number_chk(). */ 8821 if (error) 8822 return FAIL; 8823 } 8824 clear_tv(&vimvars[VV_VAL].vv_tv); 8825 return OK; 8826 } 8827 8828 /* 8829 * "filter()" function 8830 */ 8831 static void 8832 f_filter(argvars, rettv) 8833 typval_T *argvars; 8834 typval_T *rettv; 8835 { 8836 filter_map(argvars, rettv, FALSE); 8837 } 8838 8839 /* 8840 * "finddir({fname}[, {path}[, {count}]])" function 8841 */ 8842 static void 8843 f_finddir(argvars, rettv) 8844 typval_T *argvars; 8845 typval_T *rettv; 8846 { 8847 findfilendir(argvars, rettv, TRUE); 8848 } 8849 8850 /* 8851 * "findfile({fname}[, {path}[, {count}]])" function 8852 */ 8853 static void 8854 f_findfile(argvars, rettv) 8855 typval_T *argvars; 8856 typval_T *rettv; 8857 { 8858 findfilendir(argvars, rettv, FALSE); 8859 } 8860 8861 /* 8862 * "fnamemodify({fname}, {mods})" function 8863 */ 8864 static void 8865 f_fnamemodify(argvars, rettv) 8866 typval_T *argvars; 8867 typval_T *rettv; 8868 { 8869 char_u *fname; 8870 char_u *mods; 8871 int usedlen = 0; 8872 int len; 8873 char_u *fbuf = NULL; 8874 char_u buf[NUMBUFLEN]; 8875 8876 fname = get_tv_string_chk(&argvars[0]); 8877 mods = get_tv_string_buf_chk(&argvars[1], buf); 8878 if (fname == NULL || mods == NULL) 8879 fname = NULL; 8880 else 8881 { 8882 len = (int)STRLEN(fname); 8883 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8884 } 8885 8886 rettv->v_type = VAR_STRING; 8887 if (fname == NULL) 8888 rettv->vval.v_string = NULL; 8889 else 8890 rettv->vval.v_string = vim_strnsave(fname, len); 8891 vim_free(fbuf); 8892 } 8893 8894 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8895 8896 /* 8897 * "foldclosed()" function 8898 */ 8899 static void 8900 foldclosed_both(argvars, rettv, end) 8901 typval_T *argvars; 8902 typval_T *rettv; 8903 int end; 8904 { 8905 #ifdef FEAT_FOLDING 8906 linenr_T lnum; 8907 linenr_T first, last; 8908 8909 lnum = get_tv_lnum(argvars); 8910 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8911 { 8912 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8913 { 8914 if (end) 8915 rettv->vval.v_number = (varnumber_T)last; 8916 else 8917 rettv->vval.v_number = (varnumber_T)first; 8918 return; 8919 } 8920 } 8921 #endif 8922 rettv->vval.v_number = -1; 8923 } 8924 8925 /* 8926 * "foldclosed()" function 8927 */ 8928 static void 8929 f_foldclosed(argvars, rettv) 8930 typval_T *argvars; 8931 typval_T *rettv; 8932 { 8933 foldclosed_both(argvars, rettv, FALSE); 8934 } 8935 8936 /* 8937 * "foldclosedend()" function 8938 */ 8939 static void 8940 f_foldclosedend(argvars, rettv) 8941 typval_T *argvars; 8942 typval_T *rettv; 8943 { 8944 foldclosed_both(argvars, rettv, TRUE); 8945 } 8946 8947 /* 8948 * "foldlevel()" function 8949 */ 8950 static void 8951 f_foldlevel(argvars, rettv) 8952 typval_T *argvars; 8953 typval_T *rettv; 8954 { 8955 #ifdef FEAT_FOLDING 8956 linenr_T lnum; 8957 8958 lnum = get_tv_lnum(argvars); 8959 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8960 rettv->vval.v_number = foldLevel(lnum); 8961 else 8962 #endif 8963 rettv->vval.v_number = 0; 8964 } 8965 8966 /* 8967 * "foldtext()" function 8968 */ 8969 /*ARGSUSED*/ 8970 static void 8971 f_foldtext(argvars, rettv) 8972 typval_T *argvars; 8973 typval_T *rettv; 8974 { 8975 #ifdef FEAT_FOLDING 8976 linenr_T lnum; 8977 char_u *s; 8978 char_u *r; 8979 int len; 8980 char *txt; 8981 #endif 8982 8983 rettv->v_type = VAR_STRING; 8984 rettv->vval.v_string = NULL; 8985 #ifdef FEAT_FOLDING 8986 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 8987 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 8988 <= curbuf->b_ml.ml_line_count 8989 && vimvars[VV_FOLDDASHES].vv_str != NULL) 8990 { 8991 /* Find first non-empty line in the fold. */ 8992 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 8993 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 8994 { 8995 if (!linewhite(lnum)) 8996 break; 8997 ++lnum; 8998 } 8999 9000 /* Find interesting text in this line. */ 9001 s = skipwhite(ml_get(lnum)); 9002 /* skip C comment-start */ 9003 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9004 { 9005 s = skipwhite(s + 2); 9006 if (*skipwhite(s) == NUL 9007 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9008 { 9009 s = skipwhite(ml_get(lnum + 1)); 9010 if (*s == '*') 9011 s = skipwhite(s + 1); 9012 } 9013 } 9014 txt = _("+-%s%3ld lines: "); 9015 r = alloc((unsigned)(STRLEN(txt) 9016 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9017 + 20 /* for %3ld */ 9018 + STRLEN(s))); /* concatenated */ 9019 if (r != NULL) 9020 { 9021 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9022 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9023 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9024 len = (int)STRLEN(r); 9025 STRCAT(r, s); 9026 /* remove 'foldmarker' and 'commentstring' */ 9027 foldtext_cleanup(r + len); 9028 rettv->vval.v_string = r; 9029 } 9030 } 9031 #endif 9032 } 9033 9034 /* 9035 * "foldtextresult(lnum)" function 9036 */ 9037 /*ARGSUSED*/ 9038 static void 9039 f_foldtextresult(argvars, rettv) 9040 typval_T *argvars; 9041 typval_T *rettv; 9042 { 9043 #ifdef FEAT_FOLDING 9044 linenr_T lnum; 9045 char_u *text; 9046 char_u buf[51]; 9047 foldinfo_T foldinfo; 9048 int fold_count; 9049 #endif 9050 9051 rettv->v_type = VAR_STRING; 9052 rettv->vval.v_string = NULL; 9053 #ifdef FEAT_FOLDING 9054 lnum = get_tv_lnum(argvars); 9055 /* treat illegal types and illegal string values for {lnum} the same */ 9056 if (lnum < 0) 9057 lnum = 0; 9058 fold_count = foldedCount(curwin, lnum, &foldinfo); 9059 if (fold_count > 0) 9060 { 9061 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9062 &foldinfo, buf); 9063 if (text == buf) 9064 text = vim_strsave(text); 9065 rettv->vval.v_string = text; 9066 } 9067 #endif 9068 } 9069 9070 /* 9071 * "foreground()" function 9072 */ 9073 /*ARGSUSED*/ 9074 static void 9075 f_foreground(argvars, rettv) 9076 typval_T *argvars; 9077 typval_T *rettv; 9078 { 9079 rettv->vval.v_number = 0; 9080 #ifdef FEAT_GUI 9081 if (gui.in_use) 9082 gui_mch_set_foreground(); 9083 #else 9084 # ifdef WIN32 9085 win32_set_foreground(); 9086 # endif 9087 #endif 9088 } 9089 9090 /* 9091 * "function()" function 9092 */ 9093 /*ARGSUSED*/ 9094 static void 9095 f_function(argvars, rettv) 9096 typval_T *argvars; 9097 typval_T *rettv; 9098 { 9099 char_u *s; 9100 9101 rettv->vval.v_number = 0; 9102 s = get_tv_string(&argvars[0]); 9103 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9104 EMSG2(_(e_invarg2), s); 9105 else if (!function_exists(s)) 9106 EMSG2(_("E700: Unknown function: %s"), s); 9107 else 9108 { 9109 rettv->vval.v_string = vim_strsave(s); 9110 rettv->v_type = VAR_FUNC; 9111 } 9112 } 9113 9114 /* 9115 * "garbagecollect()" function 9116 */ 9117 /*ARGSUSED*/ 9118 static void 9119 f_garbagecollect(argvars, rettv) 9120 typval_T *argvars; 9121 typval_T *rettv; 9122 { 9123 garbage_collect(); 9124 } 9125 9126 /* 9127 * "get()" function 9128 */ 9129 static void 9130 f_get(argvars, rettv) 9131 typval_T *argvars; 9132 typval_T *rettv; 9133 { 9134 listitem_T *li; 9135 list_T *l; 9136 dictitem_T *di; 9137 dict_T *d; 9138 typval_T *tv = NULL; 9139 9140 if (argvars[0].v_type == VAR_LIST) 9141 { 9142 if ((l = argvars[0].vval.v_list) != NULL) 9143 { 9144 int error = FALSE; 9145 9146 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9147 if (!error && li != NULL) 9148 tv = &li->li_tv; 9149 } 9150 } 9151 else if (argvars[0].v_type == VAR_DICT) 9152 { 9153 if ((d = argvars[0].vval.v_dict) != NULL) 9154 { 9155 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9156 if (di != NULL) 9157 tv = &di->di_tv; 9158 } 9159 } 9160 else 9161 EMSG2(_(e_listdictarg), "get()"); 9162 9163 if (tv == NULL) 9164 { 9165 if (argvars[2].v_type == VAR_UNKNOWN) 9166 rettv->vval.v_number = 0; 9167 else 9168 copy_tv(&argvars[2], rettv); 9169 } 9170 else 9171 copy_tv(tv, rettv); 9172 } 9173 9174 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9175 9176 /* 9177 * Get line or list of lines from buffer "buf" into "rettv". 9178 * Return a range (from start to end) of lines in rettv from the specified 9179 * buffer. 9180 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9181 */ 9182 static void 9183 get_buffer_lines(buf, start, end, retlist, rettv) 9184 buf_T *buf; 9185 linenr_T start; 9186 linenr_T end; 9187 int retlist; 9188 typval_T *rettv; 9189 { 9190 char_u *p; 9191 list_T *l = NULL; 9192 listitem_T *li; 9193 9194 if (retlist) 9195 { 9196 l = list_alloc(); 9197 if (l == NULL) 9198 return; 9199 9200 rettv->vval.v_list = l; 9201 rettv->v_type = VAR_LIST; 9202 ++l->lv_refcount; 9203 } 9204 else 9205 rettv->vval.v_number = 0; 9206 9207 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9208 return; 9209 9210 if (!retlist) 9211 { 9212 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9213 p = ml_get_buf(buf, start, FALSE); 9214 else 9215 p = (char_u *)""; 9216 9217 rettv->v_type = VAR_STRING; 9218 rettv->vval.v_string = vim_strsave(p); 9219 } 9220 else 9221 { 9222 if (end < start) 9223 return; 9224 9225 if (start < 1) 9226 start = 1; 9227 if (end > buf->b_ml.ml_line_count) 9228 end = buf->b_ml.ml_line_count; 9229 while (start <= end) 9230 { 9231 li = listitem_alloc(); 9232 if (li == NULL) 9233 break; 9234 list_append(l, li); 9235 li->li_tv.v_type = VAR_STRING; 9236 li->li_tv.v_lock = 0; 9237 li->li_tv.vval.v_string = 9238 vim_strsave(ml_get_buf(buf, start++, FALSE)); 9239 } 9240 } 9241 } 9242 9243 /* 9244 * "getbufline()" function 9245 */ 9246 static void 9247 f_getbufline(argvars, rettv) 9248 typval_T *argvars; 9249 typval_T *rettv; 9250 { 9251 linenr_T lnum; 9252 linenr_T end; 9253 buf_T *buf; 9254 9255 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9256 ++emsg_off; 9257 buf = get_buf_tv(&argvars[0]); 9258 --emsg_off; 9259 9260 lnum = get_tv_lnum_buf(&argvars[1], buf); 9261 if (argvars[2].v_type == VAR_UNKNOWN) 9262 end = lnum; 9263 else 9264 end = get_tv_lnum_buf(&argvars[2], buf); 9265 9266 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9267 } 9268 9269 /* 9270 * "getbufvar()" function 9271 */ 9272 static void 9273 f_getbufvar(argvars, rettv) 9274 typval_T *argvars; 9275 typval_T *rettv; 9276 { 9277 buf_T *buf; 9278 buf_T *save_curbuf; 9279 char_u *varname; 9280 dictitem_T *v; 9281 9282 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9283 varname = get_tv_string_chk(&argvars[1]); 9284 ++emsg_off; 9285 buf = get_buf_tv(&argvars[0]); 9286 9287 rettv->v_type = VAR_STRING; 9288 rettv->vval.v_string = NULL; 9289 9290 if (buf != NULL && varname != NULL) 9291 { 9292 if (*varname == '&') /* buffer-local-option */ 9293 { 9294 /* set curbuf to be our buf, temporarily */ 9295 save_curbuf = curbuf; 9296 curbuf = buf; 9297 9298 get_option_tv(&varname, rettv, TRUE); 9299 9300 /* restore previous notion of curbuf */ 9301 curbuf = save_curbuf; 9302 } 9303 else 9304 { 9305 if (*varname == NUL) 9306 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9307 * scope prefix before the NUL byte is required by 9308 * find_var_in_ht(). */ 9309 varname = (char_u *)"b:" + 2; 9310 /* look up the variable */ 9311 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9312 if (v != NULL) 9313 copy_tv(&v->di_tv, rettv); 9314 } 9315 } 9316 9317 --emsg_off; 9318 } 9319 9320 /* 9321 * "getchar()" function 9322 */ 9323 static void 9324 f_getchar(argvars, rettv) 9325 typval_T *argvars; 9326 typval_T *rettv; 9327 { 9328 varnumber_T n; 9329 int error = FALSE; 9330 9331 ++no_mapping; 9332 ++allow_keys; 9333 if (argvars[0].v_type == VAR_UNKNOWN) 9334 /* getchar(): blocking wait. */ 9335 n = safe_vgetc(); 9336 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9337 /* getchar(1): only check if char avail */ 9338 n = vpeekc(); 9339 else if (error || vpeekc() == NUL) 9340 /* illegal argument or getchar(0) and no char avail: return zero */ 9341 n = 0; 9342 else 9343 /* getchar(0) and char avail: return char */ 9344 n = safe_vgetc(); 9345 --no_mapping; 9346 --allow_keys; 9347 9348 rettv->vval.v_number = n; 9349 if (IS_SPECIAL(n) || mod_mask != 0) 9350 { 9351 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9352 int i = 0; 9353 9354 /* Turn a special key into three bytes, plus modifier. */ 9355 if (mod_mask != 0) 9356 { 9357 temp[i++] = K_SPECIAL; 9358 temp[i++] = KS_MODIFIER; 9359 temp[i++] = mod_mask; 9360 } 9361 if (IS_SPECIAL(n)) 9362 { 9363 temp[i++] = K_SPECIAL; 9364 temp[i++] = K_SECOND(n); 9365 temp[i++] = K_THIRD(n); 9366 } 9367 #ifdef FEAT_MBYTE 9368 else if (has_mbyte) 9369 i += (*mb_char2bytes)(n, temp + i); 9370 #endif 9371 else 9372 temp[i++] = n; 9373 temp[i++] = NUL; 9374 rettv->v_type = VAR_STRING; 9375 rettv->vval.v_string = vim_strsave(temp); 9376 } 9377 } 9378 9379 /* 9380 * "getcharmod()" function 9381 */ 9382 /*ARGSUSED*/ 9383 static void 9384 f_getcharmod(argvars, rettv) 9385 typval_T *argvars; 9386 typval_T *rettv; 9387 { 9388 rettv->vval.v_number = mod_mask; 9389 } 9390 9391 /* 9392 * "getcmdline()" function 9393 */ 9394 /*ARGSUSED*/ 9395 static void 9396 f_getcmdline(argvars, rettv) 9397 typval_T *argvars; 9398 typval_T *rettv; 9399 { 9400 rettv->v_type = VAR_STRING; 9401 rettv->vval.v_string = get_cmdline_str(); 9402 } 9403 9404 /* 9405 * "getcmdpos()" function 9406 */ 9407 /*ARGSUSED*/ 9408 static void 9409 f_getcmdpos(argvars, rettv) 9410 typval_T *argvars; 9411 typval_T *rettv; 9412 { 9413 rettv->vval.v_number = get_cmdline_pos() + 1; 9414 } 9415 9416 /* 9417 * "getcwd()" function 9418 */ 9419 /*ARGSUSED*/ 9420 static void 9421 f_getcwd(argvars, rettv) 9422 typval_T *argvars; 9423 typval_T *rettv; 9424 { 9425 char_u cwd[MAXPATHL]; 9426 9427 rettv->v_type = VAR_STRING; 9428 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9429 rettv->vval.v_string = NULL; 9430 else 9431 { 9432 rettv->vval.v_string = vim_strsave(cwd); 9433 #ifdef BACKSLASH_IN_FILENAME 9434 if (rettv->vval.v_string != NULL) 9435 slash_adjust(rettv->vval.v_string); 9436 #endif 9437 } 9438 } 9439 9440 /* 9441 * "getfontname()" function 9442 */ 9443 /*ARGSUSED*/ 9444 static void 9445 f_getfontname(argvars, rettv) 9446 typval_T *argvars; 9447 typval_T *rettv; 9448 { 9449 rettv->v_type = VAR_STRING; 9450 rettv->vval.v_string = NULL; 9451 #ifdef FEAT_GUI 9452 if (gui.in_use) 9453 { 9454 GuiFont font; 9455 char_u *name = NULL; 9456 9457 if (argvars[0].v_type == VAR_UNKNOWN) 9458 { 9459 /* Get the "Normal" font. Either the name saved by 9460 * hl_set_font_name() or from the font ID. */ 9461 font = gui.norm_font; 9462 name = hl_get_font_name(); 9463 } 9464 else 9465 { 9466 name = get_tv_string(&argvars[0]); 9467 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9468 return; 9469 font = gui_mch_get_font(name, FALSE); 9470 if (font == NOFONT) 9471 return; /* Invalid font name, return empty string. */ 9472 } 9473 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9474 if (argvars[0].v_type != VAR_UNKNOWN) 9475 gui_mch_free_font(font); 9476 } 9477 #endif 9478 } 9479 9480 /* 9481 * "getfperm({fname})" function 9482 */ 9483 static void 9484 f_getfperm(argvars, rettv) 9485 typval_T *argvars; 9486 typval_T *rettv; 9487 { 9488 char_u *fname; 9489 struct stat st; 9490 char_u *perm = NULL; 9491 char_u flags[] = "rwx"; 9492 int i; 9493 9494 fname = get_tv_string(&argvars[0]); 9495 9496 rettv->v_type = VAR_STRING; 9497 if (mch_stat((char *)fname, &st) >= 0) 9498 { 9499 perm = vim_strsave((char_u *)"---------"); 9500 if (perm != NULL) 9501 { 9502 for (i = 0; i < 9; i++) 9503 { 9504 if (st.st_mode & (1 << (8 - i))) 9505 perm[i] = flags[i % 3]; 9506 } 9507 } 9508 } 9509 rettv->vval.v_string = perm; 9510 } 9511 9512 /* 9513 * "getfsize({fname})" function 9514 */ 9515 static void 9516 f_getfsize(argvars, rettv) 9517 typval_T *argvars; 9518 typval_T *rettv; 9519 { 9520 char_u *fname; 9521 struct stat st; 9522 9523 fname = get_tv_string(&argvars[0]); 9524 9525 rettv->v_type = VAR_NUMBER; 9526 9527 if (mch_stat((char *)fname, &st) >= 0) 9528 { 9529 if (mch_isdir(fname)) 9530 rettv->vval.v_number = 0; 9531 else 9532 rettv->vval.v_number = (varnumber_T)st.st_size; 9533 } 9534 else 9535 rettv->vval.v_number = -1; 9536 } 9537 9538 /* 9539 * "getftime({fname})" function 9540 */ 9541 static void 9542 f_getftime(argvars, rettv) 9543 typval_T *argvars; 9544 typval_T *rettv; 9545 { 9546 char_u *fname; 9547 struct stat st; 9548 9549 fname = get_tv_string(&argvars[0]); 9550 9551 if (mch_stat((char *)fname, &st) >= 0) 9552 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9553 else 9554 rettv->vval.v_number = -1; 9555 } 9556 9557 /* 9558 * "getftype({fname})" function 9559 */ 9560 static void 9561 f_getftype(argvars, rettv) 9562 typval_T *argvars; 9563 typval_T *rettv; 9564 { 9565 char_u *fname; 9566 struct stat st; 9567 char_u *type = NULL; 9568 char *t; 9569 9570 fname = get_tv_string(&argvars[0]); 9571 9572 rettv->v_type = VAR_STRING; 9573 if (mch_lstat((char *)fname, &st) >= 0) 9574 { 9575 #ifdef S_ISREG 9576 if (S_ISREG(st.st_mode)) 9577 t = "file"; 9578 else if (S_ISDIR(st.st_mode)) 9579 t = "dir"; 9580 # ifdef S_ISLNK 9581 else if (S_ISLNK(st.st_mode)) 9582 t = "link"; 9583 # endif 9584 # ifdef S_ISBLK 9585 else if (S_ISBLK(st.st_mode)) 9586 t = "bdev"; 9587 # endif 9588 # ifdef S_ISCHR 9589 else if (S_ISCHR(st.st_mode)) 9590 t = "cdev"; 9591 # endif 9592 # ifdef S_ISFIFO 9593 else if (S_ISFIFO(st.st_mode)) 9594 t = "fifo"; 9595 # endif 9596 # ifdef S_ISSOCK 9597 else if (S_ISSOCK(st.st_mode)) 9598 t = "fifo"; 9599 # endif 9600 else 9601 t = "other"; 9602 #else 9603 # ifdef S_IFMT 9604 switch (st.st_mode & S_IFMT) 9605 { 9606 case S_IFREG: t = "file"; break; 9607 case S_IFDIR: t = "dir"; break; 9608 # ifdef S_IFLNK 9609 case S_IFLNK: t = "link"; break; 9610 # endif 9611 # ifdef S_IFBLK 9612 case S_IFBLK: t = "bdev"; break; 9613 # endif 9614 # ifdef S_IFCHR 9615 case S_IFCHR: t = "cdev"; break; 9616 # endif 9617 # ifdef S_IFIFO 9618 case S_IFIFO: t = "fifo"; break; 9619 # endif 9620 # ifdef S_IFSOCK 9621 case S_IFSOCK: t = "socket"; break; 9622 # endif 9623 default: t = "other"; 9624 } 9625 # else 9626 if (mch_isdir(fname)) 9627 t = "dir"; 9628 else 9629 t = "file"; 9630 # endif 9631 #endif 9632 type = vim_strsave((char_u *)t); 9633 } 9634 rettv->vval.v_string = type; 9635 } 9636 9637 /* 9638 * "getline(lnum, [end])" function 9639 */ 9640 static void 9641 f_getline(argvars, rettv) 9642 typval_T *argvars; 9643 typval_T *rettv; 9644 { 9645 linenr_T lnum; 9646 linenr_T end; 9647 int retlist; 9648 9649 lnum = get_tv_lnum(argvars); 9650 if (argvars[1].v_type == VAR_UNKNOWN) 9651 { 9652 end = 0; 9653 retlist = FALSE; 9654 } 9655 else 9656 { 9657 end = get_tv_lnum(&argvars[1]); 9658 retlist = TRUE; 9659 } 9660 9661 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9662 } 9663 9664 /* 9665 * "getqflist()" function 9666 */ 9667 /*ARGSUSED*/ 9668 static void 9669 f_getqflist(argvars, rettv) 9670 typval_T *argvars; 9671 typval_T *rettv; 9672 { 9673 #ifdef FEAT_QUICKFIX 9674 list_T *l; 9675 #endif 9676 9677 rettv->vval.v_number = FALSE; 9678 #ifdef FEAT_QUICKFIX 9679 l = list_alloc(); 9680 if (l != NULL) 9681 { 9682 if (get_errorlist(l) != FAIL) 9683 { 9684 rettv->vval.v_list = l; 9685 rettv->v_type = VAR_LIST; 9686 ++l->lv_refcount; 9687 } 9688 else 9689 list_free(l); 9690 } 9691 #endif 9692 } 9693 9694 /* 9695 * "getreg()" function 9696 */ 9697 static void 9698 f_getreg(argvars, rettv) 9699 typval_T *argvars; 9700 typval_T *rettv; 9701 { 9702 char_u *strregname; 9703 int regname; 9704 int arg2 = FALSE; 9705 int error = FALSE; 9706 9707 if (argvars[0].v_type != VAR_UNKNOWN) 9708 { 9709 strregname = get_tv_string_chk(&argvars[0]); 9710 error = strregname == NULL; 9711 if (argvars[1].v_type != VAR_UNKNOWN) 9712 arg2 = get_tv_number_chk(&argvars[1], &error); 9713 } 9714 else 9715 strregname = vimvars[VV_REG].vv_str; 9716 regname = (strregname == NULL ? '"' : *strregname); 9717 if (regname == 0) 9718 regname = '"'; 9719 9720 rettv->v_type = VAR_STRING; 9721 rettv->vval.v_string = error ? NULL : 9722 get_reg_contents(regname, TRUE, arg2); 9723 } 9724 9725 /* 9726 * "getregtype()" function 9727 */ 9728 static void 9729 f_getregtype(argvars, rettv) 9730 typval_T *argvars; 9731 typval_T *rettv; 9732 { 9733 char_u *strregname; 9734 int regname; 9735 char_u buf[NUMBUFLEN + 2]; 9736 long reglen = 0; 9737 9738 if (argvars[0].v_type != VAR_UNKNOWN) 9739 { 9740 strregname = get_tv_string_chk(&argvars[0]); 9741 if (strregname == NULL) /* type error; errmsg already given */ 9742 { 9743 rettv->v_type = VAR_STRING; 9744 rettv->vval.v_string = NULL; 9745 return; 9746 } 9747 } 9748 else 9749 /* Default to v:register */ 9750 strregname = vimvars[VV_REG].vv_str; 9751 9752 regname = (strregname == NULL ? '"' : *strregname); 9753 if (regname == 0) 9754 regname = '"'; 9755 9756 buf[0] = NUL; 9757 buf[1] = NUL; 9758 switch (get_reg_type(regname, ®len)) 9759 { 9760 case MLINE: buf[0] = 'V'; break; 9761 case MCHAR: buf[0] = 'v'; break; 9762 #ifdef FEAT_VISUAL 9763 case MBLOCK: 9764 buf[0] = Ctrl_V; 9765 sprintf((char *)buf + 1, "%ld", reglen + 1); 9766 break; 9767 #endif 9768 } 9769 rettv->v_type = VAR_STRING; 9770 rettv->vval.v_string = vim_strsave(buf); 9771 } 9772 9773 /* 9774 * "getwinposx()" function 9775 */ 9776 /*ARGSUSED*/ 9777 static void 9778 f_getwinposx(argvars, rettv) 9779 typval_T *argvars; 9780 typval_T *rettv; 9781 { 9782 rettv->vval.v_number = -1; 9783 #ifdef FEAT_GUI 9784 if (gui.in_use) 9785 { 9786 int x, y; 9787 9788 if (gui_mch_get_winpos(&x, &y) == OK) 9789 rettv->vval.v_number = x; 9790 } 9791 #endif 9792 } 9793 9794 /* 9795 * "getwinposy()" function 9796 */ 9797 /*ARGSUSED*/ 9798 static void 9799 f_getwinposy(argvars, rettv) 9800 typval_T *argvars; 9801 typval_T *rettv; 9802 { 9803 rettv->vval.v_number = -1; 9804 #ifdef FEAT_GUI 9805 if (gui.in_use) 9806 { 9807 int x, y; 9808 9809 if (gui_mch_get_winpos(&x, &y) == OK) 9810 rettv->vval.v_number = y; 9811 } 9812 #endif 9813 } 9814 9815 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9816 9817 static win_T * 9818 find_win_by_nr(vp) 9819 typval_T *vp; 9820 { 9821 #ifdef FEAT_WINDOWS 9822 win_T *wp; 9823 #endif 9824 int nr; 9825 9826 nr = get_tv_number_chk(vp, NULL); 9827 9828 #ifdef FEAT_WINDOWS 9829 if (nr < 0) 9830 return NULL; 9831 if (nr == 0) 9832 return curwin; 9833 9834 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9835 if (--nr <= 0) 9836 break; 9837 return wp; 9838 #else 9839 if (nr == 0 || nr == 1) 9840 return curwin; 9841 return NULL; 9842 #endif 9843 } 9844 9845 /* 9846 * "getwinvar()" function 9847 */ 9848 static void 9849 f_getwinvar(argvars, rettv) 9850 typval_T *argvars; 9851 typval_T *rettv; 9852 { 9853 win_T *win, *oldcurwin; 9854 char_u *varname; 9855 dictitem_T *v; 9856 9857 win = find_win_by_nr(&argvars[0]); 9858 varname = get_tv_string_chk(&argvars[1]); 9859 ++emsg_off; 9860 9861 rettv->v_type = VAR_STRING; 9862 rettv->vval.v_string = NULL; 9863 9864 if (win != NULL && varname != NULL) 9865 { 9866 if (*varname == '&') /* window-local-option */ 9867 { 9868 /* Set curwin to be our win, temporarily. Also set curbuf, so 9869 * that we can get buffer-local options. */ 9870 oldcurwin = curwin; 9871 curwin = win; 9872 curbuf = win->w_buffer; 9873 9874 get_option_tv(&varname, rettv, 1); 9875 9876 /* restore previous notion of curwin */ 9877 curwin = oldcurwin; 9878 curbuf = curwin->w_buffer; 9879 } 9880 else 9881 { 9882 if (*varname == NUL) 9883 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9884 * scope prefix before the NUL byte is required by 9885 * find_var_in_ht(). */ 9886 varname = (char_u *)"w:" + 2; 9887 /* look up the variable */ 9888 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9889 if (v != NULL) 9890 copy_tv(&v->di_tv, rettv); 9891 } 9892 } 9893 9894 --emsg_off; 9895 } 9896 9897 /* 9898 * "glob()" function 9899 */ 9900 static void 9901 f_glob(argvars, rettv) 9902 typval_T *argvars; 9903 typval_T *rettv; 9904 { 9905 expand_T xpc; 9906 9907 ExpandInit(&xpc); 9908 xpc.xp_context = EXPAND_FILES; 9909 rettv->v_type = VAR_STRING; 9910 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9911 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9912 ExpandCleanup(&xpc); 9913 } 9914 9915 /* 9916 * "globpath()" function 9917 */ 9918 static void 9919 f_globpath(argvars, rettv) 9920 typval_T *argvars; 9921 typval_T *rettv; 9922 { 9923 char_u buf1[NUMBUFLEN]; 9924 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9925 9926 rettv->v_type = VAR_STRING; 9927 if (file == NULL) 9928 rettv->vval.v_string = NULL; 9929 else 9930 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9931 } 9932 9933 /* 9934 * "has()" function 9935 */ 9936 static void 9937 f_has(argvars, rettv) 9938 typval_T *argvars; 9939 typval_T *rettv; 9940 { 9941 int i; 9942 char_u *name; 9943 int n = FALSE; 9944 static char *(has_list[]) = 9945 { 9946 #ifdef AMIGA 9947 "amiga", 9948 # ifdef FEAT_ARP 9949 "arp", 9950 # endif 9951 #endif 9952 #ifdef __BEOS__ 9953 "beos", 9954 #endif 9955 #ifdef MSDOS 9956 # ifdef DJGPP 9957 "dos32", 9958 # else 9959 "dos16", 9960 # endif 9961 #endif 9962 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 9963 "mac", 9964 #endif 9965 #if defined(MACOS_X_UNIX) 9966 "macunix", 9967 #endif 9968 #ifdef OS2 9969 "os2", 9970 #endif 9971 #ifdef __QNX__ 9972 "qnx", 9973 #endif 9974 #ifdef RISCOS 9975 "riscos", 9976 #endif 9977 #ifdef UNIX 9978 "unix", 9979 #endif 9980 #ifdef VMS 9981 "vms", 9982 #endif 9983 #ifdef WIN16 9984 "win16", 9985 #endif 9986 #ifdef WIN32 9987 "win32", 9988 #endif 9989 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 9990 "win32unix", 9991 #endif 9992 #ifdef WIN64 9993 "win64", 9994 #endif 9995 #ifdef EBCDIC 9996 "ebcdic", 9997 #endif 9998 #ifndef CASE_INSENSITIVE_FILENAME 9999 "fname_case", 10000 #endif 10001 #ifdef FEAT_ARABIC 10002 "arabic", 10003 #endif 10004 #ifdef FEAT_AUTOCMD 10005 "autocmd", 10006 #endif 10007 #ifdef FEAT_BEVAL 10008 "balloon_eval", 10009 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10010 "balloon_multiline", 10011 # endif 10012 #endif 10013 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10014 "builtin_terms", 10015 # ifdef ALL_BUILTIN_TCAPS 10016 "all_builtin_terms", 10017 # endif 10018 #endif 10019 #ifdef FEAT_BYTEOFF 10020 "byte_offset", 10021 #endif 10022 #ifdef FEAT_CINDENT 10023 "cindent", 10024 #endif 10025 #ifdef FEAT_CLIENTSERVER 10026 "clientserver", 10027 #endif 10028 #ifdef FEAT_CLIPBOARD 10029 "clipboard", 10030 #endif 10031 #ifdef FEAT_CMDL_COMPL 10032 "cmdline_compl", 10033 #endif 10034 #ifdef FEAT_CMDHIST 10035 "cmdline_hist", 10036 #endif 10037 #ifdef FEAT_COMMENTS 10038 "comments", 10039 #endif 10040 #ifdef FEAT_CRYPT 10041 "cryptv", 10042 #endif 10043 #ifdef FEAT_CSCOPE 10044 "cscope", 10045 #endif 10046 #ifdef CURSOR_SHAPE 10047 "cursorshape", 10048 #endif 10049 #ifdef DEBUG 10050 "debug", 10051 #endif 10052 #ifdef FEAT_CON_DIALOG 10053 "dialog_con", 10054 #endif 10055 #ifdef FEAT_GUI_DIALOG 10056 "dialog_gui", 10057 #endif 10058 #ifdef FEAT_DIFF 10059 "diff", 10060 #endif 10061 #ifdef FEAT_DIGRAPHS 10062 "digraphs", 10063 #endif 10064 #ifdef FEAT_DND 10065 "dnd", 10066 #endif 10067 #ifdef FEAT_EMACS_TAGS 10068 "emacs_tags", 10069 #endif 10070 "eval", /* always present, of course! */ 10071 #ifdef FEAT_EX_EXTRA 10072 "ex_extra", 10073 #endif 10074 #ifdef FEAT_SEARCH_EXTRA 10075 "extra_search", 10076 #endif 10077 #ifdef FEAT_FKMAP 10078 "farsi", 10079 #endif 10080 #ifdef FEAT_SEARCHPATH 10081 "file_in_path", 10082 #endif 10083 #if defined(UNIX) && !defined(USE_SYSTEM) 10084 "filterpipe", 10085 #endif 10086 #ifdef FEAT_FIND_ID 10087 "find_in_path", 10088 #endif 10089 #ifdef FEAT_FOLDING 10090 "folding", 10091 #endif 10092 #ifdef FEAT_FOOTER 10093 "footer", 10094 #endif 10095 #if !defined(USE_SYSTEM) && defined(UNIX) 10096 "fork", 10097 #endif 10098 #ifdef FEAT_GETTEXT 10099 "gettext", 10100 #endif 10101 #ifdef FEAT_GUI 10102 "gui", 10103 #endif 10104 #ifdef FEAT_GUI_ATHENA 10105 # ifdef FEAT_GUI_NEXTAW 10106 "gui_neXtaw", 10107 # else 10108 "gui_athena", 10109 # endif 10110 #endif 10111 #ifdef FEAT_GUI_KDE 10112 "gui_kde", 10113 #endif 10114 #ifdef FEAT_GUI_GTK 10115 "gui_gtk", 10116 # ifdef HAVE_GTK2 10117 "gui_gtk2", 10118 # endif 10119 #endif 10120 #ifdef FEAT_GUI_MAC 10121 "gui_mac", 10122 #endif 10123 #ifdef FEAT_GUI_MOTIF 10124 "gui_motif", 10125 #endif 10126 #ifdef FEAT_GUI_PHOTON 10127 "gui_photon", 10128 #endif 10129 #ifdef FEAT_GUI_W16 10130 "gui_win16", 10131 #endif 10132 #ifdef FEAT_GUI_W32 10133 "gui_win32", 10134 #endif 10135 #ifdef FEAT_HANGULIN 10136 "hangul_input", 10137 #endif 10138 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10139 "iconv", 10140 #endif 10141 #ifdef FEAT_INS_EXPAND 10142 "insert_expand", 10143 #endif 10144 #ifdef FEAT_JUMPLIST 10145 "jumplist", 10146 #endif 10147 #ifdef FEAT_KEYMAP 10148 "keymap", 10149 #endif 10150 #ifdef FEAT_LANGMAP 10151 "langmap", 10152 #endif 10153 #ifdef FEAT_LIBCALL 10154 "libcall", 10155 #endif 10156 #ifdef FEAT_LINEBREAK 10157 "linebreak", 10158 #endif 10159 #ifdef FEAT_LISP 10160 "lispindent", 10161 #endif 10162 #ifdef FEAT_LISTCMDS 10163 "listcmds", 10164 #endif 10165 #ifdef FEAT_LOCALMAP 10166 "localmap", 10167 #endif 10168 #ifdef FEAT_MENU 10169 "menu", 10170 #endif 10171 #ifdef FEAT_SESSION 10172 "mksession", 10173 #endif 10174 #ifdef FEAT_MODIFY_FNAME 10175 "modify_fname", 10176 #endif 10177 #ifdef FEAT_MOUSE 10178 "mouse", 10179 #endif 10180 #ifdef FEAT_MOUSESHAPE 10181 "mouseshape", 10182 #endif 10183 #if defined(UNIX) || defined(VMS) 10184 # ifdef FEAT_MOUSE_DEC 10185 "mouse_dec", 10186 # endif 10187 # ifdef FEAT_MOUSE_GPM 10188 "mouse_gpm", 10189 # endif 10190 # ifdef FEAT_MOUSE_JSB 10191 "mouse_jsbterm", 10192 # endif 10193 # ifdef FEAT_MOUSE_NET 10194 "mouse_netterm", 10195 # endif 10196 # ifdef FEAT_MOUSE_PTERM 10197 "mouse_pterm", 10198 # endif 10199 # ifdef FEAT_MOUSE_XTERM 10200 "mouse_xterm", 10201 # endif 10202 #endif 10203 #ifdef FEAT_MBYTE 10204 "multi_byte", 10205 #endif 10206 #ifdef FEAT_MBYTE_IME 10207 "multi_byte_ime", 10208 #endif 10209 #ifdef FEAT_MULTI_LANG 10210 "multi_lang", 10211 #endif 10212 #ifdef FEAT_MZSCHEME 10213 #ifndef DYNAMIC_MZSCHEME 10214 "mzscheme", 10215 #endif 10216 #endif 10217 #ifdef FEAT_OLE 10218 "ole", 10219 #endif 10220 #ifdef FEAT_OSFILETYPE 10221 "osfiletype", 10222 #endif 10223 #ifdef FEAT_PATH_EXTRA 10224 "path_extra", 10225 #endif 10226 #ifdef FEAT_PERL 10227 #ifndef DYNAMIC_PERL 10228 "perl", 10229 #endif 10230 #endif 10231 #ifdef FEAT_PYTHON 10232 #ifndef DYNAMIC_PYTHON 10233 "python", 10234 #endif 10235 #endif 10236 #ifdef FEAT_POSTSCRIPT 10237 "postscript", 10238 #endif 10239 #ifdef FEAT_PRINTER 10240 "printer", 10241 #endif 10242 #ifdef FEAT_PROFILE 10243 "profile", 10244 #endif 10245 #ifdef FEAT_QUICKFIX 10246 "quickfix", 10247 #endif 10248 #ifdef FEAT_RIGHTLEFT 10249 "rightleft", 10250 #endif 10251 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10252 "ruby", 10253 #endif 10254 #ifdef FEAT_SCROLLBIND 10255 "scrollbind", 10256 #endif 10257 #ifdef FEAT_CMDL_INFO 10258 "showcmd", 10259 "cmdline_info", 10260 #endif 10261 #ifdef FEAT_SIGNS 10262 "signs", 10263 #endif 10264 #ifdef FEAT_SMARTINDENT 10265 "smartindent", 10266 #endif 10267 #ifdef FEAT_SNIFF 10268 "sniff", 10269 #endif 10270 #ifdef FEAT_STL_OPT 10271 "statusline", 10272 #endif 10273 #ifdef FEAT_SUN_WORKSHOP 10274 "sun_workshop", 10275 #endif 10276 #ifdef FEAT_NETBEANS_INTG 10277 "netbeans_intg", 10278 #endif 10279 #ifdef FEAT_SYN_HL 10280 "spell", 10281 #endif 10282 #ifdef FEAT_SYN_HL 10283 "syntax", 10284 #endif 10285 #if defined(USE_SYSTEM) || !defined(UNIX) 10286 "system", 10287 #endif 10288 #ifdef FEAT_TAG_BINS 10289 "tag_binary", 10290 #endif 10291 #ifdef FEAT_TAG_OLDSTATIC 10292 "tag_old_static", 10293 #endif 10294 #ifdef FEAT_TAG_ANYWHITE 10295 "tag_any_white", 10296 #endif 10297 #ifdef FEAT_TCL 10298 # ifndef DYNAMIC_TCL 10299 "tcl", 10300 # endif 10301 #endif 10302 #ifdef TERMINFO 10303 "terminfo", 10304 #endif 10305 #ifdef FEAT_TERMRESPONSE 10306 "termresponse", 10307 #endif 10308 #ifdef FEAT_TEXTOBJ 10309 "textobjects", 10310 #endif 10311 #ifdef HAVE_TGETENT 10312 "tgetent", 10313 #endif 10314 #ifdef FEAT_TITLE 10315 "title", 10316 #endif 10317 #ifdef FEAT_TOOLBAR 10318 "toolbar", 10319 #endif 10320 #ifdef FEAT_USR_CMDS 10321 "user-commands", /* was accidentally included in 5.4 */ 10322 "user_commands", 10323 #endif 10324 #ifdef FEAT_VIMINFO 10325 "viminfo", 10326 #endif 10327 #ifdef FEAT_VERTSPLIT 10328 "vertsplit", 10329 #endif 10330 #ifdef FEAT_VIRTUALEDIT 10331 "virtualedit", 10332 #endif 10333 #ifdef FEAT_VISUAL 10334 "visual", 10335 #endif 10336 #ifdef FEAT_VISUALEXTRA 10337 "visualextra", 10338 #endif 10339 #ifdef FEAT_VREPLACE 10340 "vreplace", 10341 #endif 10342 #ifdef FEAT_WILDIGN 10343 "wildignore", 10344 #endif 10345 #ifdef FEAT_WILDMENU 10346 "wildmenu", 10347 #endif 10348 #ifdef FEAT_WINDOWS 10349 "windows", 10350 #endif 10351 #ifdef FEAT_WAK 10352 "winaltkeys", 10353 #endif 10354 #ifdef FEAT_WRITEBACKUP 10355 "writebackup", 10356 #endif 10357 #ifdef FEAT_XIM 10358 "xim", 10359 #endif 10360 #ifdef FEAT_XFONTSET 10361 "xfontset", 10362 #endif 10363 #ifdef USE_XSMP 10364 "xsmp", 10365 #endif 10366 #ifdef USE_XSMP_INTERACT 10367 "xsmp_interact", 10368 #endif 10369 #ifdef FEAT_XCLIPBOARD 10370 "xterm_clipboard", 10371 #endif 10372 #ifdef FEAT_XTERM_SAVE 10373 "xterm_save", 10374 #endif 10375 #if defined(UNIX) && defined(FEAT_X11) 10376 "X11", 10377 #endif 10378 NULL 10379 }; 10380 10381 name = get_tv_string(&argvars[0]); 10382 for (i = 0; has_list[i] != NULL; ++i) 10383 if (STRICMP(name, has_list[i]) == 0) 10384 { 10385 n = TRUE; 10386 break; 10387 } 10388 10389 if (n == FALSE) 10390 { 10391 if (STRNICMP(name, "patch", 5) == 0) 10392 n = has_patch(atoi((char *)name + 5)); 10393 else if (STRICMP(name, "vim_starting") == 0) 10394 n = (starting != 0); 10395 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10396 else if (STRICMP(name, "balloon_multiline") == 0) 10397 n = multiline_balloon_available(); 10398 #endif 10399 #ifdef DYNAMIC_TCL 10400 else if (STRICMP(name, "tcl") == 0) 10401 n = tcl_enabled(FALSE); 10402 #endif 10403 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10404 else if (STRICMP(name, "iconv") == 0) 10405 n = iconv_enabled(FALSE); 10406 #endif 10407 #ifdef DYNAMIC_MZSCHEME 10408 else if (STRICMP(name, "mzscheme") == 0) 10409 n = mzscheme_enabled(FALSE); 10410 #endif 10411 #ifdef DYNAMIC_RUBY 10412 else if (STRICMP(name, "ruby") == 0) 10413 n = ruby_enabled(FALSE); 10414 #endif 10415 #ifdef DYNAMIC_PYTHON 10416 else if (STRICMP(name, "python") == 0) 10417 n = python_enabled(FALSE); 10418 #endif 10419 #ifdef DYNAMIC_PERL 10420 else if (STRICMP(name, "perl") == 0) 10421 n = perl_enabled(FALSE); 10422 #endif 10423 #ifdef FEAT_GUI 10424 else if (STRICMP(name, "gui_running") == 0) 10425 n = (gui.in_use || gui.starting); 10426 # ifdef FEAT_GUI_W32 10427 else if (STRICMP(name, "gui_win32s") == 0) 10428 n = gui_is_win32s(); 10429 # endif 10430 # ifdef FEAT_BROWSE 10431 else if (STRICMP(name, "browse") == 0) 10432 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10433 # endif 10434 #endif 10435 #ifdef FEAT_SYN_HL 10436 else if (STRICMP(name, "syntax_items") == 0) 10437 n = syntax_present(curbuf); 10438 #endif 10439 #if defined(WIN3264) 10440 else if (STRICMP(name, "win95") == 0) 10441 n = mch_windows95(); 10442 #endif 10443 #ifdef FEAT_NETBEANS_INTG 10444 else if (STRICMP(name, "netbeans_enabled") == 0) 10445 n = usingNetbeans; 10446 #endif 10447 } 10448 10449 rettv->vval.v_number = n; 10450 } 10451 10452 /* 10453 * "has_key()" function 10454 */ 10455 static void 10456 f_has_key(argvars, rettv) 10457 typval_T *argvars; 10458 typval_T *rettv; 10459 { 10460 rettv->vval.v_number = 0; 10461 if (argvars[0].v_type != VAR_DICT) 10462 { 10463 EMSG(_(e_dictreq)); 10464 return; 10465 } 10466 if (argvars[0].vval.v_dict == NULL) 10467 return; 10468 10469 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10470 get_tv_string(&argvars[1]), -1) != NULL; 10471 } 10472 10473 /* 10474 * "hasmapto()" function 10475 */ 10476 static void 10477 f_hasmapto(argvars, rettv) 10478 typval_T *argvars; 10479 typval_T *rettv; 10480 { 10481 char_u *name; 10482 char_u *mode; 10483 char_u buf[NUMBUFLEN]; 10484 10485 name = get_tv_string(&argvars[0]); 10486 if (argvars[1].v_type == VAR_UNKNOWN) 10487 mode = (char_u *)"nvo"; 10488 else 10489 mode = get_tv_string_buf(&argvars[1], buf); 10490 10491 if (map_to_exists(name, mode)) 10492 rettv->vval.v_number = TRUE; 10493 else 10494 rettv->vval.v_number = FALSE; 10495 } 10496 10497 /* 10498 * "histadd()" function 10499 */ 10500 /*ARGSUSED*/ 10501 static void 10502 f_histadd(argvars, rettv) 10503 typval_T *argvars; 10504 typval_T *rettv; 10505 { 10506 #ifdef FEAT_CMDHIST 10507 int histype; 10508 char_u *str; 10509 char_u buf[NUMBUFLEN]; 10510 #endif 10511 10512 rettv->vval.v_number = FALSE; 10513 if (check_restricted() || check_secure()) 10514 return; 10515 #ifdef FEAT_CMDHIST 10516 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10517 histype = str != NULL ? get_histtype(str) : -1; 10518 if (histype >= 0) 10519 { 10520 str = get_tv_string_buf(&argvars[1], buf); 10521 if (*str != NUL) 10522 { 10523 add_to_history(histype, str, FALSE, NUL); 10524 rettv->vval.v_number = TRUE; 10525 return; 10526 } 10527 } 10528 #endif 10529 } 10530 10531 /* 10532 * "histdel()" function 10533 */ 10534 /*ARGSUSED*/ 10535 static void 10536 f_histdel(argvars, rettv) 10537 typval_T *argvars; 10538 typval_T *rettv; 10539 { 10540 #ifdef FEAT_CMDHIST 10541 int n; 10542 char_u buf[NUMBUFLEN]; 10543 char_u *str; 10544 10545 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10546 if (str == NULL) 10547 n = 0; 10548 else if (argvars[1].v_type == VAR_UNKNOWN) 10549 /* only one argument: clear entire history */ 10550 n = clr_history(get_histtype(str)); 10551 else if (argvars[1].v_type == VAR_NUMBER) 10552 /* index given: remove that entry */ 10553 n = del_history_idx(get_histtype(str), 10554 (int)get_tv_number(&argvars[1])); 10555 else 10556 /* string given: remove all matching entries */ 10557 n = del_history_entry(get_histtype(str), 10558 get_tv_string_buf(&argvars[1], buf)); 10559 rettv->vval.v_number = n; 10560 #else 10561 rettv->vval.v_number = 0; 10562 #endif 10563 } 10564 10565 /* 10566 * "histget()" function 10567 */ 10568 /*ARGSUSED*/ 10569 static void 10570 f_histget(argvars, rettv) 10571 typval_T *argvars; 10572 typval_T *rettv; 10573 { 10574 #ifdef FEAT_CMDHIST 10575 int type; 10576 int idx; 10577 char_u *str; 10578 10579 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10580 if (str == NULL) 10581 rettv->vval.v_string = NULL; 10582 else 10583 { 10584 type = get_histtype(str); 10585 if (argvars[1].v_type == VAR_UNKNOWN) 10586 idx = get_history_idx(type); 10587 else 10588 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10589 /* -1 on type error */ 10590 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10591 } 10592 #else 10593 rettv->vval.v_string = NULL; 10594 #endif 10595 rettv->v_type = VAR_STRING; 10596 } 10597 10598 /* 10599 * "histnr()" function 10600 */ 10601 /*ARGSUSED*/ 10602 static void 10603 f_histnr(argvars, rettv) 10604 typval_T *argvars; 10605 typval_T *rettv; 10606 { 10607 int i; 10608 10609 #ifdef FEAT_CMDHIST 10610 char_u *history = get_tv_string_chk(&argvars[0]); 10611 10612 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10613 if (i >= HIST_CMD && i < HIST_COUNT) 10614 i = get_history_idx(i); 10615 else 10616 #endif 10617 i = -1; 10618 rettv->vval.v_number = i; 10619 } 10620 10621 /* 10622 * "highlightID(name)" function 10623 */ 10624 static void 10625 f_hlID(argvars, rettv) 10626 typval_T *argvars; 10627 typval_T *rettv; 10628 { 10629 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10630 } 10631 10632 /* 10633 * "highlight_exists()" function 10634 */ 10635 static void 10636 f_hlexists(argvars, rettv) 10637 typval_T *argvars; 10638 typval_T *rettv; 10639 { 10640 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10641 } 10642 10643 /* 10644 * "hostname()" function 10645 */ 10646 /*ARGSUSED*/ 10647 static void 10648 f_hostname(argvars, rettv) 10649 typval_T *argvars; 10650 typval_T *rettv; 10651 { 10652 char_u hostname[256]; 10653 10654 mch_get_host_name(hostname, 256); 10655 rettv->v_type = VAR_STRING; 10656 rettv->vval.v_string = vim_strsave(hostname); 10657 } 10658 10659 /* 10660 * iconv() function 10661 */ 10662 /*ARGSUSED*/ 10663 static void 10664 f_iconv(argvars, rettv) 10665 typval_T *argvars; 10666 typval_T *rettv; 10667 { 10668 #ifdef FEAT_MBYTE 10669 char_u buf1[NUMBUFLEN]; 10670 char_u buf2[NUMBUFLEN]; 10671 char_u *from, *to, *str; 10672 vimconv_T vimconv; 10673 #endif 10674 10675 rettv->v_type = VAR_STRING; 10676 rettv->vval.v_string = NULL; 10677 10678 #ifdef FEAT_MBYTE 10679 str = get_tv_string(&argvars[0]); 10680 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10681 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10682 vimconv.vc_type = CONV_NONE; 10683 convert_setup(&vimconv, from, to); 10684 10685 /* If the encodings are equal, no conversion needed. */ 10686 if (vimconv.vc_type == CONV_NONE) 10687 rettv->vval.v_string = vim_strsave(str); 10688 else 10689 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10690 10691 convert_setup(&vimconv, NULL, NULL); 10692 vim_free(from); 10693 vim_free(to); 10694 #endif 10695 } 10696 10697 /* 10698 * "indent()" function 10699 */ 10700 static void 10701 f_indent(argvars, rettv) 10702 typval_T *argvars; 10703 typval_T *rettv; 10704 { 10705 linenr_T lnum; 10706 10707 lnum = get_tv_lnum(argvars); 10708 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10709 rettv->vval.v_number = get_indent_lnum(lnum); 10710 else 10711 rettv->vval.v_number = -1; 10712 } 10713 10714 /* 10715 * "index()" function 10716 */ 10717 static void 10718 f_index(argvars, rettv) 10719 typval_T *argvars; 10720 typval_T *rettv; 10721 { 10722 list_T *l; 10723 listitem_T *item; 10724 long idx = 0; 10725 int ic = FALSE; 10726 10727 rettv->vval.v_number = -1; 10728 if (argvars[0].v_type != VAR_LIST) 10729 { 10730 EMSG(_(e_listreq)); 10731 return; 10732 } 10733 l = argvars[0].vval.v_list; 10734 if (l != NULL) 10735 { 10736 item = l->lv_first; 10737 if (argvars[2].v_type != VAR_UNKNOWN) 10738 { 10739 int error = FALSE; 10740 10741 /* Start at specified item. Use the cached index that list_find() 10742 * sets, so that a negative number also works. */ 10743 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10744 idx = l->lv_idx; 10745 if (argvars[3].v_type != VAR_UNKNOWN) 10746 ic = get_tv_number_chk(&argvars[3], &error); 10747 if (error) 10748 item = NULL; 10749 } 10750 10751 for ( ; item != NULL; item = item->li_next, ++idx) 10752 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10753 { 10754 rettv->vval.v_number = idx; 10755 break; 10756 } 10757 } 10758 } 10759 10760 static int inputsecret_flag = 0; 10761 10762 /* 10763 * "input()" function 10764 * Also handles inputsecret() when inputsecret is set. 10765 */ 10766 static void 10767 f_input(argvars, rettv) 10768 typval_T *argvars; 10769 typval_T *rettv; 10770 { 10771 char_u *prompt = get_tv_string_chk(&argvars[0]); 10772 char_u *p = NULL; 10773 int c; 10774 char_u buf[NUMBUFLEN]; 10775 int cmd_silent_save = cmd_silent; 10776 char_u *defstr = (char_u *)""; 10777 10778 rettv->v_type = VAR_STRING; 10779 10780 #ifdef NO_CONSOLE_INPUT 10781 /* While starting up, there is no place to enter text. */ 10782 if (no_console_input()) 10783 { 10784 rettv->vval.v_string = NULL; 10785 return; 10786 } 10787 #endif 10788 10789 cmd_silent = FALSE; /* Want to see the prompt. */ 10790 if (prompt != NULL) 10791 { 10792 /* Only the part of the message after the last NL is considered as 10793 * prompt for the command line */ 10794 p = vim_strrchr(prompt, '\n'); 10795 if (p == NULL) 10796 p = prompt; 10797 else 10798 { 10799 ++p; 10800 c = *p; 10801 *p = NUL; 10802 msg_start(); 10803 msg_clr_eos(); 10804 msg_puts_attr(prompt, echo_attr); 10805 msg_didout = FALSE; 10806 msg_starthere(); 10807 *p = c; 10808 } 10809 cmdline_row = msg_row; 10810 10811 if (argvars[1].v_type != VAR_UNKNOWN) 10812 { 10813 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10814 if (defstr != NULL) 10815 stuffReadbuffSpec(defstr); 10816 } 10817 10818 if (defstr != NULL) 10819 rettv->vval.v_string = 10820 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr); 10821 10822 /* since the user typed this, no need to wait for return */ 10823 need_wait_return = FALSE; 10824 msg_didout = FALSE; 10825 } 10826 cmd_silent = cmd_silent_save; 10827 } 10828 10829 /* 10830 * "inputdialog()" function 10831 */ 10832 static void 10833 f_inputdialog(argvars, rettv) 10834 typval_T *argvars; 10835 typval_T *rettv; 10836 { 10837 #if defined(FEAT_GUI_TEXTDIALOG) 10838 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10839 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10840 { 10841 char_u *message; 10842 char_u buf[NUMBUFLEN]; 10843 char_u *defstr = (char_u *)""; 10844 10845 message = get_tv_string_chk(&argvars[0]); 10846 if (argvars[1].v_type != VAR_UNKNOWN 10847 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10848 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10849 else 10850 IObuff[0] = NUL; 10851 if (message != NULL && defstr != NULL 10852 && do_dialog(VIM_QUESTION, NULL, message, 10853 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10854 rettv->vval.v_string = vim_strsave(IObuff); 10855 else 10856 { 10857 if (message != NULL && defstr != NULL 10858 && argvars[1].v_type != VAR_UNKNOWN 10859 && argvars[2].v_type != VAR_UNKNOWN) 10860 rettv->vval.v_string = vim_strsave( 10861 get_tv_string_buf(&argvars[2], buf)); 10862 else 10863 rettv->vval.v_string = NULL; 10864 } 10865 rettv->v_type = VAR_STRING; 10866 } 10867 else 10868 #endif 10869 f_input(argvars, rettv); 10870 } 10871 10872 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 10873 10874 /* 10875 * "inputrestore()" function 10876 */ 10877 /*ARGSUSED*/ 10878 static void 10879 f_inputrestore(argvars, rettv) 10880 typval_T *argvars; 10881 typval_T *rettv; 10882 { 10883 if (ga_userinput.ga_len > 0) 10884 { 10885 --ga_userinput.ga_len; 10886 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 10887 + ga_userinput.ga_len); 10888 rettv->vval.v_number = 0; /* OK */ 10889 } 10890 else if (p_verbose > 1) 10891 { 10892 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 10893 rettv->vval.v_number = 1; /* Failed */ 10894 } 10895 } 10896 10897 /* 10898 * "inputsave()" function 10899 */ 10900 /*ARGSUSED*/ 10901 static void 10902 f_inputsave(argvars, rettv) 10903 typval_T *argvars; 10904 typval_T *rettv; 10905 { 10906 /* Add an entry to the stack of typehead storage. */ 10907 if (ga_grow(&ga_userinput, 1) == OK) 10908 { 10909 save_typeahead((tasave_T *)(ga_userinput.ga_data) 10910 + ga_userinput.ga_len); 10911 ++ga_userinput.ga_len; 10912 rettv->vval.v_number = 0; /* OK */ 10913 } 10914 else 10915 rettv->vval.v_number = 1; /* Failed */ 10916 } 10917 10918 /* 10919 * "inputsecret()" function 10920 */ 10921 static void 10922 f_inputsecret(argvars, rettv) 10923 typval_T *argvars; 10924 typval_T *rettv; 10925 { 10926 ++cmdline_star; 10927 ++inputsecret_flag; 10928 f_input(argvars, rettv); 10929 --cmdline_star; 10930 --inputsecret_flag; 10931 } 10932 10933 /* 10934 * "insert()" function 10935 */ 10936 static void 10937 f_insert(argvars, rettv) 10938 typval_T *argvars; 10939 typval_T *rettv; 10940 { 10941 long before = 0; 10942 listitem_T *item; 10943 list_T *l; 10944 int error = FALSE; 10945 10946 rettv->vval.v_number = 0; 10947 if (argvars[0].v_type != VAR_LIST) 10948 EMSG2(_(e_listarg), "insert()"); 10949 else if ((l = argvars[0].vval.v_list) != NULL 10950 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 10951 { 10952 if (argvars[2].v_type != VAR_UNKNOWN) 10953 before = get_tv_number_chk(&argvars[2], &error); 10954 if (error) 10955 return; /* type error; errmsg already given */ 10956 10957 if (before == l->lv_len) 10958 item = NULL; 10959 else 10960 { 10961 item = list_find(l, before); 10962 if (item == NULL) 10963 { 10964 EMSGN(_(e_listidx), before); 10965 l = NULL; 10966 } 10967 } 10968 if (l != NULL) 10969 { 10970 list_insert_tv(l, &argvars[1], item); 10971 copy_tv(&argvars[0], rettv); 10972 } 10973 } 10974 } 10975 10976 /* 10977 * "isdirectory()" function 10978 */ 10979 static void 10980 f_isdirectory(argvars, rettv) 10981 typval_T *argvars; 10982 typval_T *rettv; 10983 { 10984 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 10985 } 10986 10987 /* 10988 * "islocked()" function 10989 */ 10990 static void 10991 f_islocked(argvars, rettv) 10992 typval_T *argvars; 10993 typval_T *rettv; 10994 { 10995 lval_T lv; 10996 char_u *end; 10997 dictitem_T *di; 10998 10999 rettv->vval.v_number = -1; 11000 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11001 FNE_CHECK_START); 11002 if (end != NULL && lv.ll_name != NULL) 11003 { 11004 if (*end != NUL) 11005 EMSG(_(e_trailing)); 11006 else 11007 { 11008 if (lv.ll_tv == NULL) 11009 { 11010 if (check_changedtick(lv.ll_name)) 11011 rettv->vval.v_number = 1; /* always locked */ 11012 else 11013 { 11014 di = find_var(lv.ll_name, NULL); 11015 if (di != NULL) 11016 { 11017 /* Consider a variable locked when: 11018 * 1. the variable itself is locked 11019 * 2. the value of the variable is locked. 11020 * 3. the List or Dict value is locked. 11021 */ 11022 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11023 || tv_islocked(&di->di_tv)); 11024 } 11025 } 11026 } 11027 else if (lv.ll_range) 11028 EMSG(_("E745: Range not allowed")); 11029 else if (lv.ll_newkey != NULL) 11030 EMSG2(_(e_dictkey), lv.ll_newkey); 11031 else if (lv.ll_list != NULL) 11032 /* List item. */ 11033 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11034 else 11035 /* Dictionary item. */ 11036 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11037 } 11038 } 11039 11040 clear_lval(&lv); 11041 } 11042 11043 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11044 11045 /* 11046 * Turn a dict into a list: 11047 * "what" == 0: list of keys 11048 * "what" == 1: list of values 11049 * "what" == 2: list of items 11050 */ 11051 static void 11052 dict_list(argvars, rettv, what) 11053 typval_T *argvars; 11054 typval_T *rettv; 11055 int what; 11056 { 11057 list_T *l; 11058 list_T *l2; 11059 dictitem_T *di; 11060 hashitem_T *hi; 11061 listitem_T *li; 11062 listitem_T *li2; 11063 dict_T *d; 11064 int todo; 11065 11066 rettv->vval.v_number = 0; 11067 if (argvars[0].v_type != VAR_DICT) 11068 { 11069 EMSG(_(e_dictreq)); 11070 return; 11071 } 11072 if ((d = argvars[0].vval.v_dict) == NULL) 11073 return; 11074 11075 l = list_alloc(); 11076 if (l == NULL) 11077 return; 11078 rettv->v_type = VAR_LIST; 11079 rettv->vval.v_list = l; 11080 ++l->lv_refcount; 11081 11082 todo = d->dv_hashtab.ht_used; 11083 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11084 { 11085 if (!HASHITEM_EMPTY(hi)) 11086 { 11087 --todo; 11088 di = HI2DI(hi); 11089 11090 li = listitem_alloc(); 11091 if (li == NULL) 11092 break; 11093 list_append(l, li); 11094 11095 if (what == 0) 11096 { 11097 /* keys() */ 11098 li->li_tv.v_type = VAR_STRING; 11099 li->li_tv.v_lock = 0; 11100 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11101 } 11102 else if (what == 1) 11103 { 11104 /* values() */ 11105 copy_tv(&di->di_tv, &li->li_tv); 11106 } 11107 else 11108 { 11109 /* items() */ 11110 l2 = list_alloc(); 11111 li->li_tv.v_type = VAR_LIST; 11112 li->li_tv.v_lock = 0; 11113 li->li_tv.vval.v_list = l2; 11114 if (l2 == NULL) 11115 break; 11116 ++l2->lv_refcount; 11117 11118 li2 = listitem_alloc(); 11119 if (li2 == NULL) 11120 break; 11121 list_append(l2, li2); 11122 li2->li_tv.v_type = VAR_STRING; 11123 li2->li_tv.v_lock = 0; 11124 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11125 11126 li2 = listitem_alloc(); 11127 if (li2 == NULL) 11128 break; 11129 list_append(l2, li2); 11130 copy_tv(&di->di_tv, &li2->li_tv); 11131 } 11132 } 11133 } 11134 } 11135 11136 /* 11137 * "items(dict)" function 11138 */ 11139 static void 11140 f_items(argvars, rettv) 11141 typval_T *argvars; 11142 typval_T *rettv; 11143 { 11144 dict_list(argvars, rettv, 2); 11145 } 11146 11147 /* 11148 * "join()" function 11149 */ 11150 static void 11151 f_join(argvars, rettv) 11152 typval_T *argvars; 11153 typval_T *rettv; 11154 { 11155 garray_T ga; 11156 char_u *sep; 11157 11158 rettv->vval.v_number = 0; 11159 if (argvars[0].v_type != VAR_LIST) 11160 { 11161 EMSG(_(e_listreq)); 11162 return; 11163 } 11164 if (argvars[0].vval.v_list == NULL) 11165 return; 11166 if (argvars[1].v_type == VAR_UNKNOWN) 11167 sep = (char_u *)" "; 11168 else 11169 sep = get_tv_string_chk(&argvars[1]); 11170 11171 rettv->v_type = VAR_STRING; 11172 11173 if (sep != NULL) 11174 { 11175 ga_init2(&ga, (int)sizeof(char), 80); 11176 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11177 ga_append(&ga, NUL); 11178 rettv->vval.v_string = (char_u *)ga.ga_data; 11179 } 11180 else 11181 rettv->vval.v_string = NULL; 11182 } 11183 11184 /* 11185 * "keys()" function 11186 */ 11187 static void 11188 f_keys(argvars, rettv) 11189 typval_T *argvars; 11190 typval_T *rettv; 11191 { 11192 dict_list(argvars, rettv, 0); 11193 } 11194 11195 /* 11196 * "last_buffer_nr()" function. 11197 */ 11198 /*ARGSUSED*/ 11199 static void 11200 f_last_buffer_nr(argvars, rettv) 11201 typval_T *argvars; 11202 typval_T *rettv; 11203 { 11204 int n = 0; 11205 buf_T *buf; 11206 11207 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11208 if (n < buf->b_fnum) 11209 n = buf->b_fnum; 11210 11211 rettv->vval.v_number = n; 11212 } 11213 11214 /* 11215 * "len()" function 11216 */ 11217 static void 11218 f_len(argvars, rettv) 11219 typval_T *argvars; 11220 typval_T *rettv; 11221 { 11222 switch (argvars[0].v_type) 11223 { 11224 case VAR_STRING: 11225 case VAR_NUMBER: 11226 rettv->vval.v_number = (varnumber_T)STRLEN( 11227 get_tv_string(&argvars[0])); 11228 break; 11229 case VAR_LIST: 11230 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11231 break; 11232 case VAR_DICT: 11233 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11234 break; 11235 default: 11236 EMSG(_("E701: Invalid type for len()")); 11237 break; 11238 } 11239 } 11240 11241 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11242 11243 static void 11244 libcall_common(argvars, rettv, type) 11245 typval_T *argvars; 11246 typval_T *rettv; 11247 int type; 11248 { 11249 #ifdef FEAT_LIBCALL 11250 char_u *string_in; 11251 char_u **string_result; 11252 int nr_result; 11253 #endif 11254 11255 rettv->v_type = type; 11256 if (type == VAR_NUMBER) 11257 rettv->vval.v_number = 0; 11258 else 11259 rettv->vval.v_string = NULL; 11260 11261 if (check_restricted() || check_secure()) 11262 return; 11263 11264 #ifdef FEAT_LIBCALL 11265 /* The first two args must be strings, otherwise its meaningless */ 11266 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11267 { 11268 string_in = NULL; 11269 if (argvars[2].v_type == VAR_STRING) 11270 string_in = argvars[2].vval.v_string; 11271 if (type == VAR_NUMBER) 11272 string_result = NULL; 11273 else 11274 string_result = &rettv->vval.v_string; 11275 if (mch_libcall(argvars[0].vval.v_string, 11276 argvars[1].vval.v_string, 11277 string_in, 11278 argvars[2].vval.v_number, 11279 string_result, 11280 &nr_result) == OK 11281 && type == VAR_NUMBER) 11282 rettv->vval.v_number = nr_result; 11283 } 11284 #endif 11285 } 11286 11287 /* 11288 * "libcall()" function 11289 */ 11290 static void 11291 f_libcall(argvars, rettv) 11292 typval_T *argvars; 11293 typval_T *rettv; 11294 { 11295 libcall_common(argvars, rettv, VAR_STRING); 11296 } 11297 11298 /* 11299 * "libcallnr()" function 11300 */ 11301 static void 11302 f_libcallnr(argvars, rettv) 11303 typval_T *argvars; 11304 typval_T *rettv; 11305 { 11306 libcall_common(argvars, rettv, VAR_NUMBER); 11307 } 11308 11309 /* 11310 * "line(string)" function 11311 */ 11312 static void 11313 f_line(argvars, rettv) 11314 typval_T *argvars; 11315 typval_T *rettv; 11316 { 11317 linenr_T lnum = 0; 11318 pos_T *fp; 11319 11320 fp = var2fpos(&argvars[0], TRUE); 11321 if (fp != NULL) 11322 lnum = fp->lnum; 11323 rettv->vval.v_number = lnum; 11324 } 11325 11326 /* 11327 * "line2byte(lnum)" function 11328 */ 11329 /*ARGSUSED*/ 11330 static void 11331 f_line2byte(argvars, rettv) 11332 typval_T *argvars; 11333 typval_T *rettv; 11334 { 11335 #ifndef FEAT_BYTEOFF 11336 rettv->vval.v_number = -1; 11337 #else 11338 linenr_T lnum; 11339 11340 lnum = get_tv_lnum(argvars); 11341 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11342 rettv->vval.v_number = -1; 11343 else 11344 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11345 if (rettv->vval.v_number >= 0) 11346 ++rettv->vval.v_number; 11347 #endif 11348 } 11349 11350 /* 11351 * "lispindent(lnum)" function 11352 */ 11353 static void 11354 f_lispindent(argvars, rettv) 11355 typval_T *argvars; 11356 typval_T *rettv; 11357 { 11358 #ifdef FEAT_LISP 11359 pos_T pos; 11360 linenr_T lnum; 11361 11362 pos = curwin->w_cursor; 11363 lnum = get_tv_lnum(argvars); 11364 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11365 { 11366 curwin->w_cursor.lnum = lnum; 11367 rettv->vval.v_number = get_lisp_indent(); 11368 curwin->w_cursor = pos; 11369 } 11370 else 11371 #endif 11372 rettv->vval.v_number = -1; 11373 } 11374 11375 /* 11376 * "localtime()" function 11377 */ 11378 /*ARGSUSED*/ 11379 static void 11380 f_localtime(argvars, rettv) 11381 typval_T *argvars; 11382 typval_T *rettv; 11383 { 11384 rettv->vval.v_number = (varnumber_T)time(NULL); 11385 } 11386 11387 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11388 11389 static void 11390 get_maparg(argvars, rettv, exact) 11391 typval_T *argvars; 11392 typval_T *rettv; 11393 int exact; 11394 { 11395 char_u *keys; 11396 char_u *which; 11397 char_u buf[NUMBUFLEN]; 11398 char_u *keys_buf = NULL; 11399 char_u *rhs; 11400 int mode; 11401 garray_T ga; 11402 11403 /* return empty string for failure */ 11404 rettv->v_type = VAR_STRING; 11405 rettv->vval.v_string = NULL; 11406 11407 keys = get_tv_string(&argvars[0]); 11408 if (*keys == NUL) 11409 return; 11410 11411 if (argvars[1].v_type != VAR_UNKNOWN) 11412 which = get_tv_string_buf_chk(&argvars[1], buf); 11413 else 11414 which = (char_u *)""; 11415 if (which == NULL) 11416 return; 11417 11418 mode = get_map_mode(&which, 0); 11419 11420 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11421 rhs = check_map(keys, mode, exact, FALSE); 11422 vim_free(keys_buf); 11423 if (rhs != NULL) 11424 { 11425 ga_init(&ga); 11426 ga.ga_itemsize = 1; 11427 ga.ga_growsize = 40; 11428 11429 while (*rhs != NUL) 11430 ga_concat(&ga, str2special(&rhs, FALSE)); 11431 11432 ga_append(&ga, NUL); 11433 rettv->vval.v_string = (char_u *)ga.ga_data; 11434 } 11435 } 11436 11437 /* 11438 * "map()" function 11439 */ 11440 static void 11441 f_map(argvars, rettv) 11442 typval_T *argvars; 11443 typval_T *rettv; 11444 { 11445 filter_map(argvars, rettv, TRUE); 11446 } 11447 11448 /* 11449 * "maparg()" function 11450 */ 11451 static void 11452 f_maparg(argvars, rettv) 11453 typval_T *argvars; 11454 typval_T *rettv; 11455 { 11456 get_maparg(argvars, rettv, TRUE); 11457 } 11458 11459 /* 11460 * "mapcheck()" function 11461 */ 11462 static void 11463 f_mapcheck(argvars, rettv) 11464 typval_T *argvars; 11465 typval_T *rettv; 11466 { 11467 get_maparg(argvars, rettv, FALSE); 11468 } 11469 11470 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11471 11472 static void 11473 find_some_match(argvars, rettv, type) 11474 typval_T *argvars; 11475 typval_T *rettv; 11476 int type; 11477 { 11478 char_u *str = NULL; 11479 char_u *expr = NULL; 11480 char_u *pat; 11481 regmatch_T regmatch; 11482 char_u patbuf[NUMBUFLEN]; 11483 char_u strbuf[NUMBUFLEN]; 11484 char_u *save_cpo; 11485 long start = 0; 11486 long nth = 1; 11487 int match = 0; 11488 list_T *l = NULL; 11489 listitem_T *li = NULL; 11490 long idx = 0; 11491 char_u *tofree = NULL; 11492 11493 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11494 save_cpo = p_cpo; 11495 p_cpo = (char_u *)""; 11496 11497 rettv->vval.v_number = -1; 11498 if (type == 3) 11499 { 11500 /* return empty list when there are no matches */ 11501 if ((rettv->vval.v_list = list_alloc()) == NULL) 11502 goto theend; 11503 rettv->v_type = VAR_LIST; 11504 ++rettv->vval.v_list->lv_refcount; 11505 } 11506 else if (type == 2) 11507 { 11508 rettv->v_type = VAR_STRING; 11509 rettv->vval.v_string = NULL; 11510 } 11511 11512 if (argvars[0].v_type == VAR_LIST) 11513 { 11514 if ((l = argvars[0].vval.v_list) == NULL) 11515 goto theend; 11516 li = l->lv_first; 11517 } 11518 else 11519 expr = str = get_tv_string(&argvars[0]); 11520 11521 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11522 if (pat == NULL) 11523 goto theend; 11524 11525 if (argvars[2].v_type != VAR_UNKNOWN) 11526 { 11527 int error = FALSE; 11528 11529 start = get_tv_number_chk(&argvars[2], &error); 11530 if (error) 11531 goto theend; 11532 if (l != NULL) 11533 { 11534 li = list_find(l, start); 11535 if (li == NULL) 11536 goto theend; 11537 idx = l->lv_idx; /* use the cached index */ 11538 } 11539 else 11540 { 11541 if (start < 0) 11542 start = 0; 11543 if (start > (long)STRLEN(str)) 11544 goto theend; 11545 str += start; 11546 } 11547 11548 if (argvars[3].v_type != VAR_UNKNOWN) 11549 nth = get_tv_number_chk(&argvars[3], &error); 11550 if (error) 11551 goto theend; 11552 } 11553 11554 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11555 if (regmatch.regprog != NULL) 11556 { 11557 regmatch.rm_ic = p_ic; 11558 11559 for (;;) 11560 { 11561 if (l != NULL) 11562 { 11563 if (li == NULL) 11564 { 11565 match = FALSE; 11566 break; 11567 } 11568 vim_free(tofree); 11569 str = echo_string(&li->li_tv, &tofree, strbuf); 11570 if (str == NULL) 11571 break; 11572 } 11573 11574 match = vim_regexec_nl(®match, str, (colnr_T)0); 11575 11576 if (match && --nth <= 0) 11577 break; 11578 if (l == NULL && !match) 11579 break; 11580 11581 /* Advance to just after the match. */ 11582 if (l != NULL) 11583 { 11584 li = li->li_next; 11585 ++idx; 11586 } 11587 else 11588 { 11589 #ifdef FEAT_MBYTE 11590 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11591 #else 11592 str = regmatch.startp[0] + 1; 11593 #endif 11594 } 11595 } 11596 11597 if (match) 11598 { 11599 if (type == 3) 11600 { 11601 int i; 11602 11603 /* return list with matched string and submatches */ 11604 for (i = 0; i < NSUBEXP; ++i) 11605 { 11606 if (regmatch.endp[i] == NULL) 11607 break; 11608 li = listitem_alloc(); 11609 if (li == NULL) 11610 break; 11611 li->li_tv.v_type = VAR_STRING; 11612 li->li_tv.v_lock = 0; 11613 li->li_tv.vval.v_string = vim_strnsave(regmatch.startp[i], 11614 (int)(regmatch.endp[i] - regmatch.startp[i])); 11615 list_append(rettv->vval.v_list, li); 11616 } 11617 } 11618 else if (type == 2) 11619 { 11620 /* return matched string */ 11621 if (l != NULL) 11622 copy_tv(&li->li_tv, rettv); 11623 else 11624 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11625 (int)(regmatch.endp[0] - regmatch.startp[0])); 11626 } 11627 else if (l != NULL) 11628 rettv->vval.v_number = idx; 11629 else 11630 { 11631 if (type != 0) 11632 rettv->vval.v_number = 11633 (varnumber_T)(regmatch.startp[0] - str); 11634 else 11635 rettv->vval.v_number = 11636 (varnumber_T)(regmatch.endp[0] - str); 11637 rettv->vval.v_number += str - expr; 11638 } 11639 } 11640 vim_free(regmatch.regprog); 11641 } 11642 11643 theend: 11644 vim_free(tofree); 11645 p_cpo = save_cpo; 11646 } 11647 11648 /* 11649 * "match()" function 11650 */ 11651 static void 11652 f_match(argvars, rettv) 11653 typval_T *argvars; 11654 typval_T *rettv; 11655 { 11656 find_some_match(argvars, rettv, 1); 11657 } 11658 11659 /* 11660 * "matchend()" function 11661 */ 11662 static void 11663 f_matchend(argvars, rettv) 11664 typval_T *argvars; 11665 typval_T *rettv; 11666 { 11667 find_some_match(argvars, rettv, 0); 11668 } 11669 11670 /* 11671 * "matchlist()" function 11672 */ 11673 static void 11674 f_matchlist(argvars, rettv) 11675 typval_T *argvars; 11676 typval_T *rettv; 11677 { 11678 find_some_match(argvars, rettv, 3); 11679 } 11680 11681 /* 11682 * "matchstr()" function 11683 */ 11684 static void 11685 f_matchstr(argvars, rettv) 11686 typval_T *argvars; 11687 typval_T *rettv; 11688 { 11689 find_some_match(argvars, rettv, 2); 11690 } 11691 11692 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11693 11694 static void 11695 max_min(argvars, rettv, domax) 11696 typval_T *argvars; 11697 typval_T *rettv; 11698 int domax; 11699 { 11700 long n = 0; 11701 long i; 11702 int error = FALSE; 11703 11704 if (argvars[0].v_type == VAR_LIST) 11705 { 11706 list_T *l; 11707 listitem_T *li; 11708 11709 l = argvars[0].vval.v_list; 11710 if (l != NULL) 11711 { 11712 li = l->lv_first; 11713 if (li != NULL) 11714 { 11715 n = get_tv_number_chk(&li->li_tv, &error); 11716 for (;;) 11717 { 11718 li = li->li_next; 11719 if (li == NULL) 11720 break; 11721 i = get_tv_number_chk(&li->li_tv, &error); 11722 if (domax ? i > n : i < n) 11723 n = i; 11724 } 11725 } 11726 } 11727 } 11728 else if (argvars[0].v_type == VAR_DICT) 11729 { 11730 dict_T *d; 11731 int first = TRUE; 11732 hashitem_T *hi; 11733 int todo; 11734 11735 d = argvars[0].vval.v_dict; 11736 if (d != NULL) 11737 { 11738 todo = d->dv_hashtab.ht_used; 11739 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11740 { 11741 if (!HASHITEM_EMPTY(hi)) 11742 { 11743 --todo; 11744 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11745 if (first) 11746 { 11747 n = i; 11748 first = FALSE; 11749 } 11750 else if (domax ? i > n : i < n) 11751 n = i; 11752 } 11753 } 11754 } 11755 } 11756 else 11757 EMSG(_(e_listdictarg)); 11758 rettv->vval.v_number = error ? 0 : n; 11759 } 11760 11761 /* 11762 * "max()" function 11763 */ 11764 static void 11765 f_max(argvars, rettv) 11766 typval_T *argvars; 11767 typval_T *rettv; 11768 { 11769 max_min(argvars, rettv, TRUE); 11770 } 11771 11772 /* 11773 * "min()" function 11774 */ 11775 static void 11776 f_min(argvars, rettv) 11777 typval_T *argvars; 11778 typval_T *rettv; 11779 { 11780 max_min(argvars, rettv, FALSE); 11781 } 11782 11783 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11784 11785 /* 11786 * Create the directory in which "dir" is located, and higher levels when 11787 * needed. 11788 */ 11789 static int 11790 mkdir_recurse(dir, prot) 11791 char_u *dir; 11792 int prot; 11793 { 11794 char_u *p; 11795 char_u *updir; 11796 int r = FAIL; 11797 11798 /* Get end of directory name in "dir". 11799 * We're done when it's "/" or "c:/". */ 11800 p = gettail_sep(dir); 11801 if (p <= get_past_head(dir)) 11802 return OK; 11803 11804 /* If the directory exists we're done. Otherwise: create it.*/ 11805 updir = vim_strnsave(dir, (int)(p - dir)); 11806 if (updir == NULL) 11807 return FAIL; 11808 if (mch_isdir(updir)) 11809 r = OK; 11810 else if (mkdir_recurse(updir, prot) == OK) 11811 r = vim_mkdir_emsg(updir, prot); 11812 vim_free(updir); 11813 return r; 11814 } 11815 11816 #ifdef vim_mkdir 11817 /* 11818 * "mkdir()" function 11819 */ 11820 static void 11821 f_mkdir(argvars, rettv) 11822 typval_T *argvars; 11823 typval_T *rettv; 11824 { 11825 char_u *dir; 11826 char_u buf[NUMBUFLEN]; 11827 int prot = 0755; 11828 11829 rettv->vval.v_number = FAIL; 11830 if (check_restricted() || check_secure()) 11831 return; 11832 11833 dir = get_tv_string_buf(&argvars[0], buf); 11834 if (argvars[1].v_type != VAR_UNKNOWN) 11835 { 11836 if (argvars[2].v_type != VAR_UNKNOWN) 11837 prot = get_tv_number_chk(&argvars[2], NULL); 11838 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11839 mkdir_recurse(dir, prot); 11840 } 11841 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11842 } 11843 #endif 11844 11845 /* 11846 * "mode()" function 11847 */ 11848 /*ARGSUSED*/ 11849 static void 11850 f_mode(argvars, rettv) 11851 typval_T *argvars; 11852 typval_T *rettv; 11853 { 11854 char_u buf[2]; 11855 11856 #ifdef FEAT_VISUAL 11857 if (VIsual_active) 11858 { 11859 if (VIsual_select) 11860 buf[0] = VIsual_mode + 's' - 'v'; 11861 else 11862 buf[0] = VIsual_mode; 11863 } 11864 else 11865 #endif 11866 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11867 buf[0] = 'r'; 11868 else if (State & INSERT) 11869 { 11870 if (State & REPLACE_FLAG) 11871 buf[0] = 'R'; 11872 else 11873 buf[0] = 'i'; 11874 } 11875 else if (State & CMDLINE) 11876 buf[0] = 'c'; 11877 else 11878 buf[0] = 'n'; 11879 11880 buf[1] = NUL; 11881 rettv->vval.v_string = vim_strsave(buf); 11882 rettv->v_type = VAR_STRING; 11883 } 11884 11885 /* 11886 * "nextnonblank()" function 11887 */ 11888 static void 11889 f_nextnonblank(argvars, rettv) 11890 typval_T *argvars; 11891 typval_T *rettv; 11892 { 11893 linenr_T lnum; 11894 11895 for (lnum = get_tv_lnum(argvars); ; ++lnum) 11896 { 11897 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 11898 { 11899 lnum = 0; 11900 break; 11901 } 11902 if (*skipwhite(ml_get(lnum)) != NUL) 11903 break; 11904 } 11905 rettv->vval.v_number = lnum; 11906 } 11907 11908 /* 11909 * "nr2char()" function 11910 */ 11911 static void 11912 f_nr2char(argvars, rettv) 11913 typval_T *argvars; 11914 typval_T *rettv; 11915 { 11916 char_u buf[NUMBUFLEN]; 11917 11918 #ifdef FEAT_MBYTE 11919 if (has_mbyte) 11920 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 11921 else 11922 #endif 11923 { 11924 buf[0] = (char_u)get_tv_number(&argvars[0]); 11925 buf[1] = NUL; 11926 } 11927 rettv->v_type = VAR_STRING; 11928 rettv->vval.v_string = vim_strsave(buf); 11929 } 11930 11931 /* 11932 * "prevnonblank()" function 11933 */ 11934 static void 11935 f_prevnonblank(argvars, rettv) 11936 typval_T *argvars; 11937 typval_T *rettv; 11938 { 11939 linenr_T lnum; 11940 11941 lnum = get_tv_lnum(argvars); 11942 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 11943 lnum = 0; 11944 else 11945 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 11946 --lnum; 11947 rettv->vval.v_number = lnum; 11948 } 11949 11950 #ifdef HAVE_STDARG_H 11951 /* This dummy va_list is here because: 11952 * - passing a NULL pointer doesn't work when va_list isn't a pointer 11953 * - locally in the function results in a "used before set" warning 11954 * - using va_start() to initialize it gives "function with fixed args" error */ 11955 static va_list ap; 11956 #endif 11957 11958 /* 11959 * "printf()" function 11960 */ 11961 static void 11962 f_printf(argvars, rettv) 11963 typval_T *argvars; 11964 typval_T *rettv; 11965 { 11966 rettv->v_type = VAR_STRING; 11967 rettv->vval.v_string = NULL; 11968 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 11969 { 11970 char_u buf[NUMBUFLEN]; 11971 int len; 11972 char_u *s; 11973 int saved_did_emsg = did_emsg; 11974 char *fmt; 11975 11976 /* Get the required length, allocate the buffer and do it for real. */ 11977 did_emsg = FALSE; 11978 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 11979 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 11980 if (!did_emsg) 11981 { 11982 s = alloc(len + 1); 11983 if (s != NULL) 11984 { 11985 rettv->vval.v_string = s; 11986 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 11987 } 11988 } 11989 did_emsg |= saved_did_emsg; 11990 } 11991 #endif 11992 } 11993 11994 /* 11995 * "range()" function 11996 */ 11997 static void 11998 f_range(argvars, rettv) 11999 typval_T *argvars; 12000 typval_T *rettv; 12001 { 12002 long start; 12003 long end; 12004 long stride = 1; 12005 long i; 12006 list_T *l; 12007 listitem_T *li; 12008 int error = FALSE; 12009 12010 start = get_tv_number_chk(&argvars[0], &error); 12011 if (argvars[1].v_type == VAR_UNKNOWN) 12012 { 12013 end = start - 1; 12014 start = 0; 12015 } 12016 else 12017 { 12018 end = get_tv_number_chk(&argvars[1], &error); 12019 if (argvars[2].v_type != VAR_UNKNOWN) 12020 stride = get_tv_number_chk(&argvars[2], &error); 12021 } 12022 12023 rettv->vval.v_number = 0; 12024 if (error) 12025 return; /* type error; errmsg already given */ 12026 if (stride == 0) 12027 EMSG(_("E726: Stride is zero")); 12028 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12029 EMSG(_("E727: Start past end")); 12030 else 12031 { 12032 l = list_alloc(); 12033 if (l != NULL) 12034 { 12035 rettv->v_type = VAR_LIST; 12036 rettv->vval.v_list = l; 12037 ++l->lv_refcount; 12038 12039 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12040 { 12041 li = listitem_alloc(); 12042 if (li == NULL) 12043 break; 12044 li->li_tv.v_type = VAR_NUMBER; 12045 li->li_tv.v_lock = 0; 12046 li->li_tv.vval.v_number = i; 12047 list_append(l, li); 12048 } 12049 } 12050 } 12051 } 12052 12053 /* 12054 * "readfile()" function 12055 */ 12056 static void 12057 f_readfile(argvars, rettv) 12058 typval_T *argvars; 12059 typval_T *rettv; 12060 { 12061 int binary = FALSE; 12062 char_u *fname; 12063 FILE *fd; 12064 list_T *l; 12065 listitem_T *li; 12066 #define FREAD_SIZE 200 /* optimized for text lines */ 12067 char_u buf[FREAD_SIZE]; 12068 int readlen; /* size of last fread() */ 12069 int buflen; /* nr of valid chars in buf[] */ 12070 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12071 int tolist; /* first byte in buf[] still to be put in list */ 12072 int chop; /* how many CR to chop off */ 12073 char_u *prev = NULL; /* previously read bytes, if any */ 12074 int prevlen = 0; /* length of "prev" if not NULL */ 12075 char_u *s; 12076 int len; 12077 long maxline = MAXLNUM; 12078 long cnt = 0; 12079 12080 if (argvars[1].v_type != VAR_UNKNOWN) 12081 { 12082 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12083 binary = TRUE; 12084 if (argvars[2].v_type != VAR_UNKNOWN) 12085 maxline = get_tv_number(&argvars[2]); 12086 } 12087 12088 l = list_alloc(); 12089 if (l == NULL) 12090 return; 12091 rettv->v_type = VAR_LIST; 12092 rettv->vval.v_list = l; 12093 l->lv_refcount = 1; 12094 12095 /* Always open the file in binary mode, library functions have a mind of 12096 * their own about CR-LF conversion. */ 12097 fname = get_tv_string(&argvars[0]); 12098 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12099 { 12100 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12101 return; 12102 } 12103 12104 filtd = 0; 12105 while (cnt < maxline || maxline < 0) 12106 { 12107 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12108 buflen = filtd + readlen; 12109 tolist = 0; 12110 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12111 { 12112 if (buf[filtd] == '\n' || readlen <= 0) 12113 { 12114 /* Only when in binary mode add an empty list item when the 12115 * last line ends in a '\n'. */ 12116 if (!binary && readlen == 0 && filtd == 0) 12117 break; 12118 12119 /* Found end-of-line or end-of-file: add a text line to the 12120 * list. */ 12121 chop = 0; 12122 if (!binary) 12123 while (filtd - chop - 1 >= tolist 12124 && buf[filtd - chop - 1] == '\r') 12125 ++chop; 12126 len = filtd - tolist - chop; 12127 if (prev == NULL) 12128 s = vim_strnsave(buf + tolist, len); 12129 else 12130 { 12131 s = alloc((unsigned)(prevlen + len + 1)); 12132 if (s != NULL) 12133 { 12134 mch_memmove(s, prev, prevlen); 12135 vim_free(prev); 12136 prev = NULL; 12137 mch_memmove(s + prevlen, buf + tolist, len); 12138 s[prevlen + len] = NUL; 12139 } 12140 } 12141 tolist = filtd + 1; 12142 12143 li = listitem_alloc(); 12144 if (li == NULL) 12145 { 12146 vim_free(s); 12147 break; 12148 } 12149 li->li_tv.v_type = VAR_STRING; 12150 li->li_tv.v_lock = 0; 12151 li->li_tv.vval.v_string = s; 12152 list_append(l, li); 12153 12154 if (++cnt >= maxline && maxline >= 0) 12155 break; 12156 if (readlen <= 0) 12157 break; 12158 } 12159 else if (buf[filtd] == NUL) 12160 buf[filtd] = '\n'; 12161 } 12162 if (readlen <= 0) 12163 break; 12164 12165 if (tolist == 0) 12166 { 12167 /* "buf" is full, need to move text to an allocated buffer */ 12168 if (prev == NULL) 12169 { 12170 prev = vim_strnsave(buf, buflen); 12171 prevlen = buflen; 12172 } 12173 else 12174 { 12175 s = alloc((unsigned)(prevlen + buflen)); 12176 if (s != NULL) 12177 { 12178 mch_memmove(s, prev, prevlen); 12179 mch_memmove(s + prevlen, buf, buflen); 12180 vim_free(prev); 12181 prev = s; 12182 prevlen += buflen; 12183 } 12184 } 12185 filtd = 0; 12186 } 12187 else 12188 { 12189 mch_memmove(buf, buf + tolist, buflen - tolist); 12190 filtd -= tolist; 12191 } 12192 } 12193 12194 /* 12195 * For a negative line count use only the lines at the end of the file, 12196 * free the rest. 12197 */ 12198 if (maxline < 0) 12199 while (cnt > -maxline) 12200 { 12201 listitem_remove(l, l->lv_first); 12202 --cnt; 12203 } 12204 12205 vim_free(prev); 12206 fclose(fd); 12207 } 12208 12209 12210 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12211 static void make_connection __ARGS((void)); 12212 static int check_connection __ARGS((void)); 12213 12214 static void 12215 make_connection() 12216 { 12217 if (X_DISPLAY == NULL 12218 # ifdef FEAT_GUI 12219 && !gui.in_use 12220 # endif 12221 ) 12222 { 12223 x_force_connect = TRUE; 12224 setup_term_clip(); 12225 x_force_connect = FALSE; 12226 } 12227 } 12228 12229 static int 12230 check_connection() 12231 { 12232 make_connection(); 12233 if (X_DISPLAY == NULL) 12234 { 12235 EMSG(_("E240: No connection to Vim server")); 12236 return FAIL; 12237 } 12238 return OK; 12239 } 12240 #endif 12241 12242 #ifdef FEAT_CLIENTSERVER 12243 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12244 12245 static void 12246 remote_common(argvars, rettv, expr) 12247 typval_T *argvars; 12248 typval_T *rettv; 12249 int expr; 12250 { 12251 char_u *server_name; 12252 char_u *keys; 12253 char_u *r = NULL; 12254 char_u buf[NUMBUFLEN]; 12255 # ifdef WIN32 12256 HWND w; 12257 # else 12258 Window w; 12259 # endif 12260 12261 if (check_restricted() || check_secure()) 12262 return; 12263 12264 # ifdef FEAT_X11 12265 if (check_connection() == FAIL) 12266 return; 12267 # endif 12268 12269 server_name = get_tv_string_chk(&argvars[0]); 12270 if (server_name == NULL) 12271 return; /* type error; errmsg already given */ 12272 keys = get_tv_string_buf(&argvars[1], buf); 12273 # ifdef WIN32 12274 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12275 # else 12276 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12277 < 0) 12278 # endif 12279 { 12280 if (r != NULL) 12281 EMSG(r); /* sending worked but evaluation failed */ 12282 else 12283 EMSG2(_("E241: Unable to send to %s"), server_name); 12284 return; 12285 } 12286 12287 rettv->vval.v_string = r; 12288 12289 if (argvars[2].v_type != VAR_UNKNOWN) 12290 { 12291 dictitem_T v; 12292 char_u str[30]; 12293 char_u *idvar; 12294 12295 sprintf((char *)str, "0x%x", (unsigned int)w); 12296 v.di_tv.v_type = VAR_STRING; 12297 v.di_tv.vval.v_string = vim_strsave(str); 12298 idvar = get_tv_string_chk(&argvars[2]); 12299 if (idvar != NULL) 12300 set_var(idvar, &v.di_tv, FALSE); 12301 vim_free(v.di_tv.vval.v_string); 12302 } 12303 } 12304 #endif 12305 12306 /* 12307 * "remote_expr()" function 12308 */ 12309 /*ARGSUSED*/ 12310 static void 12311 f_remote_expr(argvars, rettv) 12312 typval_T *argvars; 12313 typval_T *rettv; 12314 { 12315 rettv->v_type = VAR_STRING; 12316 rettv->vval.v_string = NULL; 12317 #ifdef FEAT_CLIENTSERVER 12318 remote_common(argvars, rettv, TRUE); 12319 #endif 12320 } 12321 12322 /* 12323 * "remote_foreground()" function 12324 */ 12325 /*ARGSUSED*/ 12326 static void 12327 f_remote_foreground(argvars, rettv) 12328 typval_T *argvars; 12329 typval_T *rettv; 12330 { 12331 rettv->vval.v_number = 0; 12332 #ifdef FEAT_CLIENTSERVER 12333 # ifdef WIN32 12334 /* On Win32 it's done in this application. */ 12335 { 12336 char_u *server_name = get_tv_string_chk(&argvars[0]); 12337 12338 if (server_name != NULL) 12339 serverForeground(server_name); 12340 } 12341 # else 12342 /* Send a foreground() expression to the server. */ 12343 argvars[1].v_type = VAR_STRING; 12344 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12345 argvars[2].v_type = VAR_UNKNOWN; 12346 remote_common(argvars, rettv, TRUE); 12347 vim_free(argvars[1].vval.v_string); 12348 # endif 12349 #endif 12350 } 12351 12352 /*ARGSUSED*/ 12353 static void 12354 f_remote_peek(argvars, rettv) 12355 typval_T *argvars; 12356 typval_T *rettv; 12357 { 12358 #ifdef FEAT_CLIENTSERVER 12359 dictitem_T v; 12360 char_u *s = NULL; 12361 # ifdef WIN32 12362 int n = 0; 12363 # endif 12364 char_u *serverid; 12365 12366 if (check_restricted() || check_secure()) 12367 { 12368 rettv->vval.v_number = -1; 12369 return; 12370 } 12371 serverid = get_tv_string_chk(&argvars[0]); 12372 if (serverid == NULL) 12373 { 12374 rettv->vval.v_number = -1; 12375 return; /* type error; errmsg already given */ 12376 } 12377 # ifdef WIN32 12378 sscanf(serverid, "%x", &n); 12379 if (n == 0) 12380 rettv->vval.v_number = -1; 12381 else 12382 { 12383 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12384 rettv->vval.v_number = (s != NULL); 12385 } 12386 # else 12387 rettv->vval.v_number = 0; 12388 if (check_connection() == FAIL) 12389 return; 12390 12391 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12392 serverStrToWin(serverid), &s); 12393 # endif 12394 12395 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12396 { 12397 char_u *retvar; 12398 12399 v.di_tv.v_type = VAR_STRING; 12400 v.di_tv.vval.v_string = vim_strsave(s); 12401 retvar = get_tv_string_chk(&argvars[1]); 12402 if (retvar != NULL) 12403 set_var(retvar, &v.di_tv, FALSE); 12404 vim_free(v.di_tv.vval.v_string); 12405 } 12406 #else 12407 rettv->vval.v_number = -1; 12408 #endif 12409 } 12410 12411 /*ARGSUSED*/ 12412 static void 12413 f_remote_read(argvars, rettv) 12414 typval_T *argvars; 12415 typval_T *rettv; 12416 { 12417 char_u *r = NULL; 12418 12419 #ifdef FEAT_CLIENTSERVER 12420 char_u *serverid = get_tv_string_chk(&argvars[0]); 12421 12422 if (serverid != NULL && !check_restricted() && !check_secure()) 12423 { 12424 # ifdef WIN32 12425 /* The server's HWND is encoded in the 'id' parameter */ 12426 int n = 0; 12427 12428 sscanf(serverid, "%x", &n); 12429 if (n != 0) 12430 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12431 if (r == NULL) 12432 # else 12433 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12434 serverStrToWin(serverid), &r, FALSE) < 0) 12435 # endif 12436 EMSG(_("E277: Unable to read a server reply")); 12437 } 12438 #endif 12439 rettv->v_type = VAR_STRING; 12440 rettv->vval.v_string = r; 12441 } 12442 12443 /* 12444 * "remote_send()" function 12445 */ 12446 /*ARGSUSED*/ 12447 static void 12448 f_remote_send(argvars, rettv) 12449 typval_T *argvars; 12450 typval_T *rettv; 12451 { 12452 rettv->v_type = VAR_STRING; 12453 rettv->vval.v_string = NULL; 12454 #ifdef FEAT_CLIENTSERVER 12455 remote_common(argvars, rettv, FALSE); 12456 #endif 12457 } 12458 12459 /* 12460 * "remove()" function 12461 */ 12462 static void 12463 f_remove(argvars, rettv) 12464 typval_T *argvars; 12465 typval_T *rettv; 12466 { 12467 list_T *l; 12468 listitem_T *item, *item2; 12469 listitem_T *li; 12470 long idx; 12471 long end; 12472 char_u *key; 12473 dict_T *d; 12474 dictitem_T *di; 12475 12476 rettv->vval.v_number = 0; 12477 if (argvars[0].v_type == VAR_DICT) 12478 { 12479 if (argvars[2].v_type != VAR_UNKNOWN) 12480 EMSG2(_(e_toomanyarg), "remove()"); 12481 else if ((d = argvars[0].vval.v_dict) != NULL 12482 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12483 { 12484 key = get_tv_string_chk(&argvars[1]); 12485 if (key != NULL) 12486 { 12487 di = dict_find(d, key, -1); 12488 if (di == NULL) 12489 EMSG2(_(e_dictkey), key); 12490 else 12491 { 12492 *rettv = di->di_tv; 12493 init_tv(&di->di_tv); 12494 dictitem_remove(d, di); 12495 } 12496 } 12497 } 12498 } 12499 else if (argvars[0].v_type != VAR_LIST) 12500 EMSG2(_(e_listdictarg), "remove()"); 12501 else if ((l = argvars[0].vval.v_list) != NULL 12502 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12503 { 12504 int error = FALSE; 12505 12506 idx = get_tv_number_chk(&argvars[1], &error); 12507 if (error) 12508 ; /* type error: do nothing, errmsg already given */ 12509 else if ((item = list_find(l, idx)) == NULL) 12510 EMSGN(_(e_listidx), idx); 12511 else 12512 { 12513 if (argvars[2].v_type == VAR_UNKNOWN) 12514 { 12515 /* Remove one item, return its value. */ 12516 list_remove(l, item, item); 12517 *rettv = item->li_tv; 12518 vim_free(item); 12519 } 12520 else 12521 { 12522 /* Remove range of items, return list with values. */ 12523 end = get_tv_number_chk(&argvars[2], &error); 12524 if (error) 12525 ; /* type error: do nothing */ 12526 else if ((item2 = list_find(l, end)) == NULL) 12527 EMSGN(_(e_listidx), end); 12528 else 12529 { 12530 int cnt = 0; 12531 12532 for (li = item; li != NULL; li = li->li_next) 12533 { 12534 ++cnt; 12535 if (li == item2) 12536 break; 12537 } 12538 if (li == NULL) /* didn't find "item2" after "item" */ 12539 EMSG(_(e_invrange)); 12540 else 12541 { 12542 list_remove(l, item, item2); 12543 l = list_alloc(); 12544 if (l != NULL) 12545 { 12546 rettv->v_type = VAR_LIST; 12547 rettv->vval.v_list = l; 12548 l->lv_first = item; 12549 l->lv_last = item2; 12550 l->lv_refcount = 1; 12551 item->li_prev = NULL; 12552 item2->li_next = NULL; 12553 l->lv_len = cnt; 12554 } 12555 } 12556 } 12557 } 12558 } 12559 } 12560 } 12561 12562 /* 12563 * "rename({from}, {to})" function 12564 */ 12565 static void 12566 f_rename(argvars, rettv) 12567 typval_T *argvars; 12568 typval_T *rettv; 12569 { 12570 char_u buf[NUMBUFLEN]; 12571 12572 if (check_restricted() || check_secure()) 12573 rettv->vval.v_number = -1; 12574 else 12575 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12576 get_tv_string_buf(&argvars[1], buf)); 12577 } 12578 12579 /* 12580 * "repeat()" function 12581 */ 12582 /*ARGSUSED*/ 12583 static void 12584 f_repeat(argvars, rettv) 12585 typval_T *argvars; 12586 typval_T *rettv; 12587 { 12588 char_u *p; 12589 int n; 12590 int slen; 12591 int len; 12592 char_u *r; 12593 int i; 12594 list_T *l; 12595 12596 n = get_tv_number(&argvars[1]); 12597 if (argvars[0].v_type == VAR_LIST) 12598 { 12599 l = list_alloc(); 12600 if (l != NULL && argvars[0].vval.v_list != NULL) 12601 { 12602 l->lv_refcount = 1; 12603 while (n-- > 0) 12604 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12605 break; 12606 } 12607 rettv->v_type = VAR_LIST; 12608 rettv->vval.v_list = l; 12609 } 12610 else 12611 { 12612 p = get_tv_string(&argvars[0]); 12613 rettv->v_type = VAR_STRING; 12614 rettv->vval.v_string = NULL; 12615 12616 slen = (int)STRLEN(p); 12617 len = slen * n; 12618 if (len <= 0) 12619 return; 12620 12621 r = alloc(len + 1); 12622 if (r != NULL) 12623 { 12624 for (i = 0; i < n; i++) 12625 mch_memmove(r + i * slen, p, (size_t)slen); 12626 r[len] = NUL; 12627 } 12628 12629 rettv->vval.v_string = r; 12630 } 12631 } 12632 12633 /* 12634 * "resolve()" function 12635 */ 12636 static void 12637 f_resolve(argvars, rettv) 12638 typval_T *argvars; 12639 typval_T *rettv; 12640 { 12641 char_u *p; 12642 12643 p = get_tv_string(&argvars[0]); 12644 #ifdef FEAT_SHORTCUT 12645 { 12646 char_u *v = NULL; 12647 12648 v = mch_resolve_shortcut(p); 12649 if (v != NULL) 12650 rettv->vval.v_string = v; 12651 else 12652 rettv->vval.v_string = vim_strsave(p); 12653 } 12654 #else 12655 # ifdef HAVE_READLINK 12656 { 12657 char_u buf[MAXPATHL + 1]; 12658 char_u *cpy; 12659 int len; 12660 char_u *remain = NULL; 12661 char_u *q; 12662 int is_relative_to_current = FALSE; 12663 int has_trailing_pathsep = FALSE; 12664 int limit = 100; 12665 12666 p = vim_strsave(p); 12667 12668 if (p[0] == '.' && (vim_ispathsep(p[1]) 12669 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12670 is_relative_to_current = TRUE; 12671 12672 len = STRLEN(p); 12673 if (len > 0 && after_pathsep(p, p + len)) 12674 has_trailing_pathsep = TRUE; 12675 12676 q = getnextcomp(p); 12677 if (*q != NUL) 12678 { 12679 /* Separate the first path component in "p", and keep the 12680 * remainder (beginning with the path separator). */ 12681 remain = vim_strsave(q - 1); 12682 q[-1] = NUL; 12683 } 12684 12685 for (;;) 12686 { 12687 for (;;) 12688 { 12689 len = readlink((char *)p, (char *)buf, MAXPATHL); 12690 if (len <= 0) 12691 break; 12692 buf[len] = NUL; 12693 12694 if (limit-- == 0) 12695 { 12696 vim_free(p); 12697 vim_free(remain); 12698 EMSG(_("E655: Too many symbolic links (cycle?)")); 12699 rettv->vval.v_string = NULL; 12700 goto fail; 12701 } 12702 12703 /* Ensure that the result will have a trailing path separator 12704 * if the argument has one. */ 12705 if (remain == NULL && has_trailing_pathsep) 12706 add_pathsep(buf); 12707 12708 /* Separate the first path component in the link value and 12709 * concatenate the remainders. */ 12710 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12711 if (*q != NUL) 12712 { 12713 if (remain == NULL) 12714 remain = vim_strsave(q - 1); 12715 else 12716 { 12717 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12718 if (cpy != NULL) 12719 { 12720 STRCAT(cpy, remain); 12721 vim_free(remain); 12722 remain = cpy; 12723 } 12724 } 12725 q[-1] = NUL; 12726 } 12727 12728 q = gettail(p); 12729 if (q > p && *q == NUL) 12730 { 12731 /* Ignore trailing path separator. */ 12732 q[-1] = NUL; 12733 q = gettail(p); 12734 } 12735 if (q > p && !mch_isFullName(buf)) 12736 { 12737 /* symlink is relative to directory of argument */ 12738 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12739 if (cpy != NULL) 12740 { 12741 STRCPY(cpy, p); 12742 STRCPY(gettail(cpy), buf); 12743 vim_free(p); 12744 p = cpy; 12745 } 12746 } 12747 else 12748 { 12749 vim_free(p); 12750 p = vim_strsave(buf); 12751 } 12752 } 12753 12754 if (remain == NULL) 12755 break; 12756 12757 /* Append the first path component of "remain" to "p". */ 12758 q = getnextcomp(remain + 1); 12759 len = q - remain - (*q != NUL); 12760 cpy = vim_strnsave(p, STRLEN(p) + len); 12761 if (cpy != NULL) 12762 { 12763 STRNCAT(cpy, remain, len); 12764 vim_free(p); 12765 p = cpy; 12766 } 12767 /* Shorten "remain". */ 12768 if (*q != NUL) 12769 STRCPY(remain, q - 1); 12770 else 12771 { 12772 vim_free(remain); 12773 remain = NULL; 12774 } 12775 } 12776 12777 /* If the result is a relative path name, make it explicitly relative to 12778 * the current directory if and only if the argument had this form. */ 12779 if (!vim_ispathsep(*p)) 12780 { 12781 if (is_relative_to_current 12782 && *p != NUL 12783 && !(p[0] == '.' 12784 && (p[1] == NUL 12785 || vim_ispathsep(p[1]) 12786 || (p[1] == '.' 12787 && (p[2] == NUL 12788 || vim_ispathsep(p[2])))))) 12789 { 12790 /* Prepend "./". */ 12791 cpy = concat_str((char_u *)"./", p); 12792 if (cpy != NULL) 12793 { 12794 vim_free(p); 12795 p = cpy; 12796 } 12797 } 12798 else if (!is_relative_to_current) 12799 { 12800 /* Strip leading "./". */ 12801 q = p; 12802 while (q[0] == '.' && vim_ispathsep(q[1])) 12803 q += 2; 12804 if (q > p) 12805 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12806 } 12807 } 12808 12809 /* Ensure that the result will have no trailing path separator 12810 * if the argument had none. But keep "/" or "//". */ 12811 if (!has_trailing_pathsep) 12812 { 12813 q = p + STRLEN(p); 12814 if (after_pathsep(p, q)) 12815 *gettail_sep(p) = NUL; 12816 } 12817 12818 rettv->vval.v_string = p; 12819 } 12820 # else 12821 rettv->vval.v_string = vim_strsave(p); 12822 # endif 12823 #endif 12824 12825 simplify_filename(rettv->vval.v_string); 12826 12827 #ifdef HAVE_READLINK 12828 fail: 12829 #endif 12830 rettv->v_type = VAR_STRING; 12831 } 12832 12833 /* 12834 * "reverse({list})" function 12835 */ 12836 static void 12837 f_reverse(argvars, rettv) 12838 typval_T *argvars; 12839 typval_T *rettv; 12840 { 12841 list_T *l; 12842 listitem_T *li, *ni; 12843 12844 rettv->vval.v_number = 0; 12845 if (argvars[0].v_type != VAR_LIST) 12846 EMSG2(_(e_listarg), "reverse()"); 12847 else if ((l = argvars[0].vval.v_list) != NULL 12848 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12849 { 12850 li = l->lv_last; 12851 l->lv_first = l->lv_last = NULL; 12852 l->lv_len = 0; 12853 while (li != NULL) 12854 { 12855 ni = li->li_prev; 12856 list_append(l, li); 12857 li = ni; 12858 } 12859 rettv->vval.v_list = l; 12860 rettv->v_type = VAR_LIST; 12861 ++l->lv_refcount; 12862 } 12863 } 12864 12865 #define SP_NOMOVE 1 /* don't move cursor */ 12866 #define SP_REPEAT 2 /* repeat to find outer pair */ 12867 #define SP_RETCOUNT 4 /* return matchcount */ 12868 #define SP_SETPCMARK 8 /* set previous context mark */ 12869 12870 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12871 12872 /* 12873 * Get flags for a search function. 12874 * Possibly sets "p_ws". 12875 * Returns BACKWARD, FORWARD or zero (for an error). 12876 */ 12877 static int 12878 get_search_arg(varp, flagsp) 12879 typval_T *varp; 12880 int *flagsp; 12881 { 12882 int dir = FORWARD; 12883 char_u *flags; 12884 char_u nbuf[NUMBUFLEN]; 12885 int mask; 12886 12887 if (varp->v_type != VAR_UNKNOWN) 12888 { 12889 flags = get_tv_string_buf_chk(varp, nbuf); 12890 if (flags == NULL) 12891 return 0; /* type error; errmsg already given */ 12892 while (*flags != NUL) 12893 { 12894 switch (*flags) 12895 { 12896 case 'b': dir = BACKWARD; break; 12897 case 'w': p_ws = TRUE; break; 12898 case 'W': p_ws = FALSE; break; 12899 default: mask = 0; 12900 if (flagsp != NULL) 12901 switch (*flags) 12902 { 12903 case 'n': mask = SP_NOMOVE; break; 12904 case 'r': mask = SP_REPEAT; break; 12905 case 'm': mask = SP_RETCOUNT; break; 12906 case 's': mask = SP_SETPCMARK; break; 12907 } 12908 if (mask == 0) 12909 { 12910 EMSG2(_(e_invarg2), flags); 12911 dir = 0; 12912 } 12913 else 12914 *flagsp |= mask; 12915 } 12916 if (dir == 0) 12917 break; 12918 ++flags; 12919 } 12920 } 12921 return dir; 12922 } 12923 12924 /* 12925 * "search()" function 12926 */ 12927 static void 12928 f_search(argvars, rettv) 12929 typval_T *argvars; 12930 typval_T *rettv; 12931 { 12932 char_u *pat; 12933 pos_T pos; 12934 pos_T save_cursor; 12935 int save_p_ws = p_ws; 12936 int dir; 12937 int flags = 0; 12938 12939 rettv->vval.v_number = 0; /* default: FAIL */ 12940 12941 pat = get_tv_string(&argvars[0]); 12942 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 12943 if (dir == 0) 12944 goto theend; 12945 /* 12946 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 12947 * Check to make sure only those flags are set. 12948 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 12949 * flags cannot be set. Check for that condition also. 12950 */ 12951 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 12952 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 12953 { 12954 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 12955 goto theend; 12956 } 12957 12958 pos = save_cursor = curwin->w_cursor; 12959 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 12960 SEARCH_KEEP, RE_SEARCH) != FAIL) 12961 { 12962 rettv->vval.v_number = pos.lnum; 12963 if (flags & SP_SETPCMARK) 12964 setpcmark(); 12965 curwin->w_cursor = pos; 12966 /* "/$" will put the cursor after the end of the line, may need to 12967 * correct that here */ 12968 check_cursor(); 12969 } 12970 12971 /* If 'n' flag is used: restore cursor position. */ 12972 if (flags & SP_NOMOVE) 12973 curwin->w_cursor = save_cursor; 12974 theend: 12975 p_ws = save_p_ws; 12976 } 12977 12978 /* 12979 * "searchpair()" function 12980 */ 12981 static void 12982 f_searchpair(argvars, rettv) 12983 typval_T *argvars; 12984 typval_T *rettv; 12985 { 12986 char_u *spat, *mpat, *epat; 12987 char_u *skip; 12988 int save_p_ws = p_ws; 12989 int dir; 12990 int flags = 0; 12991 char_u nbuf1[NUMBUFLEN]; 12992 char_u nbuf2[NUMBUFLEN]; 12993 char_u nbuf3[NUMBUFLEN]; 12994 12995 rettv->vval.v_number = 0; /* default: FAIL */ 12996 12997 /* Get the three pattern arguments: start, middle, end. */ 12998 spat = get_tv_string_chk(&argvars[0]); 12999 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13000 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13001 if (spat == NULL || mpat == NULL || epat == NULL) 13002 goto theend; /* type error */ 13003 13004 /* Handle the optional fourth argument: flags */ 13005 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13006 if (dir == 0) 13007 goto theend; 13008 /* 13009 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13010 */ 13011 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13012 { 13013 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13014 goto theend; 13015 } 13016 13017 /* Optional fifth argument: skip expresion */ 13018 if (argvars[3].v_type == VAR_UNKNOWN 13019 || argvars[4].v_type == VAR_UNKNOWN) 13020 skip = (char_u *)""; 13021 else 13022 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13023 if (skip == NULL) 13024 goto theend; /* type error */ 13025 13026 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13027 13028 theend: 13029 p_ws = save_p_ws; 13030 } 13031 13032 /* 13033 * Search for a start/middle/end thing. 13034 * Used by searchpair(), see its documentation for the details. 13035 * Returns 0 or -1 for no match, 13036 */ 13037 long 13038 do_searchpair(spat, mpat, epat, dir, skip, flags) 13039 char_u *spat; /* start pattern */ 13040 char_u *mpat; /* middle pattern */ 13041 char_u *epat; /* end pattern */ 13042 int dir; /* BACKWARD or FORWARD */ 13043 char_u *skip; /* skip expression */ 13044 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13045 { 13046 char_u *save_cpo; 13047 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13048 long retval = 0; 13049 pos_T pos; 13050 pos_T firstpos; 13051 pos_T foundpos; 13052 pos_T save_cursor; 13053 pos_T save_pos; 13054 int n; 13055 int r; 13056 int nest = 1; 13057 int err; 13058 13059 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13060 save_cpo = p_cpo; 13061 p_cpo = (char_u *)""; 13062 13063 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13064 * start/middle/end (pat3, for the top pair). */ 13065 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13066 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13067 if (pat2 == NULL || pat3 == NULL) 13068 goto theend; 13069 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13070 if (*mpat == NUL) 13071 STRCPY(pat3, pat2); 13072 else 13073 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13074 spat, epat, mpat); 13075 13076 save_cursor = curwin->w_cursor; 13077 pos = curwin->w_cursor; 13078 firstpos.lnum = 0; 13079 foundpos.lnum = 0; 13080 pat = pat3; 13081 for (;;) 13082 { 13083 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13084 SEARCH_KEEP, RE_SEARCH); 13085 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13086 /* didn't find it or found the first match again: FAIL */ 13087 break; 13088 13089 if (firstpos.lnum == 0) 13090 firstpos = pos; 13091 if (equalpos(pos, foundpos)) 13092 { 13093 /* Found the same position again. Can happen with a pattern that 13094 * has "\zs" at the end and searching backwards. Advance one 13095 * character and try again. */ 13096 if (dir == BACKWARD) 13097 decl(&pos); 13098 else 13099 incl(&pos); 13100 } 13101 foundpos = pos; 13102 13103 /* If the skip pattern matches, ignore this match. */ 13104 if (*skip != NUL) 13105 { 13106 save_pos = curwin->w_cursor; 13107 curwin->w_cursor = pos; 13108 r = eval_to_bool(skip, &err, NULL, FALSE); 13109 curwin->w_cursor = save_pos; 13110 if (err) 13111 { 13112 /* Evaluating {skip} caused an error, break here. */ 13113 curwin->w_cursor = save_cursor; 13114 retval = -1; 13115 break; 13116 } 13117 if (r) 13118 continue; 13119 } 13120 13121 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13122 { 13123 /* Found end when searching backwards or start when searching 13124 * forward: nested pair. */ 13125 ++nest; 13126 pat = pat2; /* nested, don't search for middle */ 13127 } 13128 else 13129 { 13130 /* Found end when searching forward or start when searching 13131 * backward: end of (nested) pair; or found middle in outer pair. */ 13132 if (--nest == 1) 13133 pat = pat3; /* outer level, search for middle */ 13134 } 13135 13136 if (nest == 0) 13137 { 13138 /* Found the match: return matchcount or line number. */ 13139 if (flags & SP_RETCOUNT) 13140 ++retval; 13141 else 13142 retval = pos.lnum; 13143 if (flags & SP_SETPCMARK) 13144 setpcmark(); 13145 curwin->w_cursor = pos; 13146 if (!(flags & SP_REPEAT)) 13147 break; 13148 nest = 1; /* search for next unmatched */ 13149 } 13150 } 13151 13152 /* If 'n' flag is used or search failed: restore cursor position. */ 13153 if ((flags & SP_NOMOVE) || retval == 0) 13154 curwin->w_cursor = save_cursor; 13155 13156 theend: 13157 vim_free(pat2); 13158 vim_free(pat3); 13159 p_cpo = save_cpo; 13160 13161 return retval; 13162 } 13163 13164 /*ARGSUSED*/ 13165 static void 13166 f_server2client(argvars, rettv) 13167 typval_T *argvars; 13168 typval_T *rettv; 13169 { 13170 #ifdef FEAT_CLIENTSERVER 13171 char_u buf[NUMBUFLEN]; 13172 char_u *server = get_tv_string_chk(&argvars[0]); 13173 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13174 13175 rettv->vval.v_number = -1; 13176 if (server == NULL || reply == NULL) 13177 return; 13178 if (check_restricted() || check_secure()) 13179 return; 13180 # ifdef FEAT_X11 13181 if (check_connection() == FAIL) 13182 return; 13183 # endif 13184 13185 if (serverSendReply(server, reply) < 0) 13186 { 13187 EMSG(_("E258: Unable to send to client")); 13188 return; 13189 } 13190 rettv->vval.v_number = 0; 13191 #else 13192 rettv->vval.v_number = -1; 13193 #endif 13194 } 13195 13196 /*ARGSUSED*/ 13197 static void 13198 f_serverlist(argvars, rettv) 13199 typval_T *argvars; 13200 typval_T *rettv; 13201 { 13202 char_u *r = NULL; 13203 13204 #ifdef FEAT_CLIENTSERVER 13205 # ifdef WIN32 13206 r = serverGetVimNames(); 13207 # else 13208 make_connection(); 13209 if (X_DISPLAY != NULL) 13210 r = serverGetVimNames(X_DISPLAY); 13211 # endif 13212 #endif 13213 rettv->v_type = VAR_STRING; 13214 rettv->vval.v_string = r; 13215 } 13216 13217 /* 13218 * "setbufvar()" function 13219 */ 13220 /*ARGSUSED*/ 13221 static void 13222 f_setbufvar(argvars, rettv) 13223 typval_T *argvars; 13224 typval_T *rettv; 13225 { 13226 buf_T *buf; 13227 #ifdef FEAT_AUTOCMD 13228 aco_save_T aco; 13229 #else 13230 buf_T *save_curbuf; 13231 #endif 13232 char_u *varname, *bufvarname; 13233 typval_T *varp; 13234 char_u nbuf[NUMBUFLEN]; 13235 13236 rettv->vval.v_number = 0; 13237 13238 if (check_restricted() || check_secure()) 13239 return; 13240 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13241 varname = get_tv_string_chk(&argvars[1]); 13242 buf = get_buf_tv(&argvars[0]); 13243 varp = &argvars[2]; 13244 13245 if (buf != NULL && varname != NULL && varp != NULL) 13246 { 13247 /* set curbuf to be our buf, temporarily */ 13248 #ifdef FEAT_AUTOCMD 13249 aucmd_prepbuf(&aco, buf); 13250 #else 13251 save_curbuf = curbuf; 13252 curbuf = buf; 13253 #endif 13254 13255 if (*varname == '&') 13256 { 13257 long numval; 13258 char_u *strval; 13259 int error = FALSE; 13260 13261 ++varname; 13262 numval = get_tv_number_chk(varp, &error); 13263 strval = get_tv_string_buf_chk(varp, nbuf); 13264 if (!error && strval != NULL) 13265 set_option_value(varname, numval, strval, OPT_LOCAL); 13266 } 13267 else 13268 { 13269 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13270 if (bufvarname != NULL) 13271 { 13272 STRCPY(bufvarname, "b:"); 13273 STRCPY(bufvarname + 2, varname); 13274 set_var(bufvarname, varp, TRUE); 13275 vim_free(bufvarname); 13276 } 13277 } 13278 13279 /* reset notion of buffer */ 13280 #ifdef FEAT_AUTOCMD 13281 aucmd_restbuf(&aco); 13282 #else 13283 curbuf = save_curbuf; 13284 #endif 13285 } 13286 } 13287 13288 /* 13289 * "setcmdpos()" function 13290 */ 13291 static void 13292 f_setcmdpos(argvars, rettv) 13293 typval_T *argvars; 13294 typval_T *rettv; 13295 { 13296 int pos = (int)get_tv_number(&argvars[0]) - 1; 13297 13298 if (pos >= 0) 13299 rettv->vval.v_number = set_cmdline_pos(pos); 13300 } 13301 13302 /* 13303 * "setline()" function 13304 */ 13305 static void 13306 f_setline(argvars, rettv) 13307 typval_T *argvars; 13308 typval_T *rettv; 13309 { 13310 linenr_T lnum; 13311 char_u *line = NULL; 13312 list_T *l = NULL; 13313 listitem_T *li = NULL; 13314 long added = 0; 13315 linenr_T lcount = curbuf->b_ml.ml_line_count; 13316 13317 lnum = get_tv_lnum(&argvars[0]); 13318 if (argvars[1].v_type == VAR_LIST) 13319 { 13320 l = argvars[1].vval.v_list; 13321 li = l->lv_first; 13322 } 13323 else 13324 line = get_tv_string_chk(&argvars[1]); 13325 13326 rettv->vval.v_number = 0; /* OK */ 13327 for (;;) 13328 { 13329 if (l != NULL) 13330 { 13331 /* list argument, get next string */ 13332 if (li == NULL) 13333 break; 13334 line = get_tv_string_chk(&li->li_tv); 13335 li = li->li_next; 13336 } 13337 13338 rettv->vval.v_number = 1; /* FAIL */ 13339 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13340 break; 13341 if (lnum <= curbuf->b_ml.ml_line_count) 13342 { 13343 /* existing line, replace it */ 13344 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13345 { 13346 changed_bytes(lnum, 0); 13347 check_cursor_col(); 13348 rettv->vval.v_number = 0; /* OK */ 13349 } 13350 } 13351 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13352 { 13353 /* lnum is one past the last line, append the line */ 13354 ++added; 13355 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13356 rettv->vval.v_number = 0; /* OK */ 13357 } 13358 13359 if (l == NULL) /* only one string argument */ 13360 break; 13361 ++lnum; 13362 } 13363 13364 if (added > 0) 13365 appended_lines_mark(lcount, added); 13366 } 13367 13368 /* 13369 * "setqflist()" function 13370 */ 13371 /*ARGSUSED*/ 13372 static void 13373 f_setqflist(argvars, rettv) 13374 typval_T *argvars; 13375 typval_T *rettv; 13376 { 13377 char_u *act; 13378 int action = ' '; 13379 13380 rettv->vval.v_number = -1; 13381 13382 #ifdef FEAT_QUICKFIX 13383 if (argvars[0].v_type != VAR_LIST) 13384 EMSG(_(e_listreq)); 13385 else 13386 { 13387 list_T *l = argvars[0].vval.v_list; 13388 13389 if (argvars[1].v_type == VAR_STRING) 13390 { 13391 act = get_tv_string_chk(&argvars[1]); 13392 if (act == NULL) 13393 return; /* type error; errmsg already given */ 13394 if (*act == 'a' || *act == 'r') 13395 action = *act; 13396 } 13397 13398 if (l != NULL && set_errorlist(l, action) == OK) 13399 rettv->vval.v_number = 0; 13400 } 13401 #endif 13402 } 13403 13404 /* 13405 * "setreg()" function 13406 */ 13407 static void 13408 f_setreg(argvars, rettv) 13409 typval_T *argvars; 13410 typval_T *rettv; 13411 { 13412 int regname; 13413 char_u *strregname; 13414 char_u *stropt; 13415 char_u *strval; 13416 int append; 13417 char_u yank_type; 13418 long block_len; 13419 13420 block_len = -1; 13421 yank_type = MAUTO; 13422 append = FALSE; 13423 13424 strregname = get_tv_string_chk(argvars); 13425 rettv->vval.v_number = 1; /* FAIL is default */ 13426 13427 if (strregname == NULL) 13428 return; /* type error; errmsg already given */ 13429 regname = *strregname; 13430 if (regname == 0 || regname == '@') 13431 regname = '"'; 13432 else if (regname == '=') 13433 return; 13434 13435 if (argvars[2].v_type != VAR_UNKNOWN) 13436 { 13437 stropt = get_tv_string_chk(&argvars[2]); 13438 if (stropt == NULL) 13439 return; /* type error */ 13440 for (; *stropt != NUL; ++stropt) 13441 switch (*stropt) 13442 { 13443 case 'a': case 'A': /* append */ 13444 append = TRUE; 13445 break; 13446 case 'v': case 'c': /* character-wise selection */ 13447 yank_type = MCHAR; 13448 break; 13449 case 'V': case 'l': /* line-wise selection */ 13450 yank_type = MLINE; 13451 break; 13452 #ifdef FEAT_VISUAL 13453 case 'b': case Ctrl_V: /* block-wise selection */ 13454 yank_type = MBLOCK; 13455 if (VIM_ISDIGIT(stropt[1])) 13456 { 13457 ++stropt; 13458 block_len = getdigits(&stropt) - 1; 13459 --stropt; 13460 } 13461 break; 13462 #endif 13463 } 13464 } 13465 13466 strval = get_tv_string_chk(&argvars[1]); 13467 if (strval != NULL) 13468 write_reg_contents_ex(regname, strval, -1, 13469 append, yank_type, block_len); 13470 rettv->vval.v_number = 0; 13471 } 13472 13473 13474 /* 13475 * "setwinvar(expr)" function 13476 */ 13477 /*ARGSUSED*/ 13478 static void 13479 f_setwinvar(argvars, rettv) 13480 typval_T *argvars; 13481 typval_T *rettv; 13482 { 13483 win_T *win; 13484 #ifdef FEAT_WINDOWS 13485 win_T *save_curwin; 13486 #endif 13487 char_u *varname, *winvarname; 13488 typval_T *varp; 13489 char_u nbuf[NUMBUFLEN]; 13490 13491 rettv->vval.v_number = 0; 13492 13493 if (check_restricted() || check_secure()) 13494 return; 13495 win = find_win_by_nr(&argvars[0]); 13496 varname = get_tv_string_chk(&argvars[1]); 13497 varp = &argvars[2]; 13498 13499 if (win != NULL && varname != NULL && varp != NULL) 13500 { 13501 #ifdef FEAT_WINDOWS 13502 /* set curwin to be our win, temporarily */ 13503 save_curwin = curwin; 13504 curwin = win; 13505 curbuf = curwin->w_buffer; 13506 #endif 13507 13508 if (*varname == '&') 13509 { 13510 long numval; 13511 char_u *strval; 13512 int error = FALSE; 13513 13514 ++varname; 13515 numval = get_tv_number_chk(varp, &error); 13516 strval = get_tv_string_buf_chk(varp, nbuf); 13517 if (!error && strval != NULL) 13518 set_option_value(varname, numval, strval, OPT_LOCAL); 13519 } 13520 else 13521 { 13522 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13523 if (winvarname != NULL) 13524 { 13525 STRCPY(winvarname, "w:"); 13526 STRCPY(winvarname + 2, varname); 13527 set_var(winvarname, varp, TRUE); 13528 vim_free(winvarname); 13529 } 13530 } 13531 13532 #ifdef FEAT_WINDOWS 13533 /* Restore current window, if it's still valid (autocomands can make 13534 * it invalid). */ 13535 if (win_valid(save_curwin)) 13536 { 13537 curwin = save_curwin; 13538 curbuf = curwin->w_buffer; 13539 } 13540 #endif 13541 } 13542 } 13543 13544 /* 13545 * "simplify()" function 13546 */ 13547 static void 13548 f_simplify(argvars, rettv) 13549 typval_T *argvars; 13550 typval_T *rettv; 13551 { 13552 char_u *p; 13553 13554 p = get_tv_string(&argvars[0]); 13555 rettv->vval.v_string = vim_strsave(p); 13556 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13557 rettv->v_type = VAR_STRING; 13558 } 13559 13560 static int 13561 #ifdef __BORLANDC__ 13562 _RTLENTRYF 13563 #endif 13564 item_compare __ARGS((const void *s1, const void *s2)); 13565 static int 13566 #ifdef __BORLANDC__ 13567 _RTLENTRYF 13568 #endif 13569 item_compare2 __ARGS((const void *s1, const void *s2)); 13570 13571 static int item_compare_ic; 13572 static char_u *item_compare_func; 13573 static int item_compare_func_err; 13574 #define ITEM_COMPARE_FAIL 999 13575 13576 /* 13577 * Compare functions for f_sort() below. 13578 */ 13579 static int 13580 #ifdef __BORLANDC__ 13581 _RTLENTRYF 13582 #endif 13583 item_compare(s1, s2) 13584 const void *s1; 13585 const void *s2; 13586 { 13587 char_u *p1, *p2; 13588 char_u *tofree1, *tofree2; 13589 int res; 13590 char_u numbuf1[NUMBUFLEN]; 13591 char_u numbuf2[NUMBUFLEN]; 13592 13593 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13594 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13595 if (item_compare_ic) 13596 res = STRICMP(p1, p2); 13597 else 13598 res = STRCMP(p1, p2); 13599 vim_free(tofree1); 13600 vim_free(tofree2); 13601 return res; 13602 } 13603 13604 static int 13605 #ifdef __BORLANDC__ 13606 _RTLENTRYF 13607 #endif 13608 item_compare2(s1, s2) 13609 const void *s1; 13610 const void *s2; 13611 { 13612 int res; 13613 typval_T rettv; 13614 typval_T argv[2]; 13615 int dummy; 13616 13617 /* shortcut after failure in previous call; compare all items equal */ 13618 if (item_compare_func_err) 13619 return 0; 13620 13621 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13622 * in the copy without changing the original list items. */ 13623 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13624 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13625 13626 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13627 res = call_func(item_compare_func, STRLEN(item_compare_func), 13628 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13629 clear_tv(&argv[0]); 13630 clear_tv(&argv[1]); 13631 13632 if (res == FAIL) 13633 res = ITEM_COMPARE_FAIL; 13634 else 13635 /* return value has wrong type */ 13636 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13637 if (item_compare_func_err) 13638 res = ITEM_COMPARE_FAIL; 13639 clear_tv(&rettv); 13640 return res; 13641 } 13642 13643 /* 13644 * "sort({list})" function 13645 */ 13646 static void 13647 f_sort(argvars, rettv) 13648 typval_T *argvars; 13649 typval_T *rettv; 13650 { 13651 list_T *l; 13652 listitem_T *li; 13653 listitem_T **ptrs; 13654 long len; 13655 long i; 13656 13657 rettv->vval.v_number = 0; 13658 if (argvars[0].v_type != VAR_LIST) 13659 EMSG2(_(e_listarg), "sort()"); 13660 else 13661 { 13662 l = argvars[0].vval.v_list; 13663 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13664 return; 13665 rettv->vval.v_list = l; 13666 rettv->v_type = VAR_LIST; 13667 ++l->lv_refcount; 13668 13669 len = list_len(l); 13670 if (len <= 1) 13671 return; /* short list sorts pretty quickly */ 13672 13673 item_compare_ic = FALSE; 13674 item_compare_func = NULL; 13675 if (argvars[1].v_type != VAR_UNKNOWN) 13676 { 13677 if (argvars[1].v_type == VAR_FUNC) 13678 item_compare_func = argvars[1].vval.v_string; 13679 else 13680 { 13681 int error = FALSE; 13682 13683 i = get_tv_number_chk(&argvars[1], &error); 13684 if (error) 13685 return; /* type error; errmsg already given */ 13686 if (i == 1) 13687 item_compare_ic = TRUE; 13688 else 13689 item_compare_func = get_tv_string(&argvars[1]); 13690 } 13691 } 13692 13693 /* Make an array with each entry pointing to an item in the List. */ 13694 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13695 if (ptrs == NULL) 13696 return; 13697 i = 0; 13698 for (li = l->lv_first; li != NULL; li = li->li_next) 13699 ptrs[i++] = li; 13700 13701 item_compare_func_err = FALSE; 13702 /* test the compare function */ 13703 if (item_compare_func != NULL 13704 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13705 == ITEM_COMPARE_FAIL) 13706 EMSG(_("E702: Sort compare function failed")); 13707 else 13708 { 13709 /* Sort the array with item pointers. */ 13710 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13711 item_compare_func == NULL ? item_compare : item_compare2); 13712 13713 if (!item_compare_func_err) 13714 { 13715 /* Clear the List and append the items in the sorted order. */ 13716 l->lv_first = l->lv_last = NULL; 13717 l->lv_len = 0; 13718 for (i = 0; i < len; ++i) 13719 list_append(l, ptrs[i]); 13720 } 13721 } 13722 13723 vim_free(ptrs); 13724 } 13725 } 13726 13727 /* 13728 * "soundfold({word})" function 13729 */ 13730 static void 13731 f_soundfold(argvars, rettv) 13732 typval_T *argvars; 13733 typval_T *rettv; 13734 { 13735 char_u *s; 13736 13737 rettv->v_type = VAR_STRING; 13738 s = get_tv_string(&argvars[0]); 13739 #ifdef FEAT_SYN_HL 13740 rettv->vval.v_string = eval_soundfold(s); 13741 #else 13742 rettv->vval.v_string = vim_strsave(s); 13743 #endif 13744 } 13745 13746 /* 13747 * "spellbadword()" function 13748 */ 13749 /* ARGSUSED */ 13750 static void 13751 f_spellbadword(argvars, rettv) 13752 typval_T *argvars; 13753 typval_T *rettv; 13754 { 13755 int len; 13756 13757 rettv->vval.v_string = NULL; 13758 rettv->v_type = VAR_STRING; 13759 13760 #ifdef FEAT_SYN_HL 13761 /* Find the start and length of the badly spelled word. */ 13762 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL); 13763 if (len != 0) 13764 rettv->vval.v_string = vim_strnsave(ml_get_cursor(), len); 13765 #endif 13766 } 13767 13768 /* 13769 * "spellsuggest()" function 13770 */ 13771 static void 13772 f_spellsuggest(argvars, rettv) 13773 typval_T *argvars; 13774 typval_T *rettv; 13775 { 13776 char_u *str; 13777 int maxcount; 13778 garray_T ga; 13779 list_T *l; 13780 listitem_T *li; 13781 int i; 13782 13783 l = list_alloc(); 13784 if (l == NULL) 13785 return; 13786 rettv->v_type = VAR_LIST; 13787 rettv->vval.v_list = l; 13788 ++l->lv_refcount; 13789 13790 #ifdef FEAT_SYN_HL 13791 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13792 { 13793 str = get_tv_string(&argvars[0]); 13794 if (argvars[1].v_type != VAR_UNKNOWN) 13795 { 13796 maxcount = get_tv_number(&argvars[1]); 13797 if (maxcount <= 0) 13798 return; 13799 } 13800 else 13801 maxcount = 25; 13802 13803 spell_suggest_list(&ga, str, maxcount, FALSE); 13804 13805 for (i = 0; i < ga.ga_len; ++i) 13806 { 13807 str = ((char_u **)ga.ga_data)[i]; 13808 13809 li = listitem_alloc(); 13810 if (li == NULL) 13811 vim_free(str); 13812 else 13813 { 13814 li->li_tv.v_type = VAR_STRING; 13815 li->li_tv.v_lock = 0; 13816 li->li_tv.vval.v_string = str; 13817 list_append(l, li); 13818 } 13819 } 13820 ga_clear(&ga); 13821 } 13822 #endif 13823 } 13824 13825 static void 13826 f_split(argvars, rettv) 13827 typval_T *argvars; 13828 typval_T *rettv; 13829 { 13830 char_u *str; 13831 char_u *end; 13832 char_u *pat = NULL; 13833 regmatch_T regmatch; 13834 char_u patbuf[NUMBUFLEN]; 13835 char_u *save_cpo; 13836 int match; 13837 listitem_T *ni; 13838 list_T *l; 13839 colnr_T col = 0; 13840 int keepempty = FALSE; 13841 int typeerr = FALSE; 13842 13843 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13844 save_cpo = p_cpo; 13845 p_cpo = (char_u *)""; 13846 13847 str = get_tv_string(&argvars[0]); 13848 if (argvars[1].v_type != VAR_UNKNOWN) 13849 { 13850 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13851 if (pat == NULL) 13852 typeerr = TRUE; 13853 if (argvars[2].v_type != VAR_UNKNOWN) 13854 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 13855 } 13856 if (pat == NULL || *pat == NUL) 13857 pat = (char_u *)"[\\x01- ]\\+"; 13858 13859 l = list_alloc(); 13860 if (l == NULL) 13861 return; 13862 rettv->v_type = VAR_LIST; 13863 rettv->vval.v_list = l; 13864 ++l->lv_refcount; 13865 if (typeerr) 13866 return; 13867 13868 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13869 if (regmatch.regprog != NULL) 13870 { 13871 regmatch.rm_ic = FALSE; 13872 while (*str != NUL || keepempty) 13873 { 13874 if (*str == NUL) 13875 match = FALSE; /* empty item at the end */ 13876 else 13877 match = vim_regexec_nl(®match, str, col); 13878 if (match) 13879 end = regmatch.startp[0]; 13880 else 13881 end = str + STRLEN(str); 13882 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 13883 && match && end < regmatch.endp[0])) 13884 { 13885 ni = listitem_alloc(); 13886 if (ni == NULL) 13887 break; 13888 ni->li_tv.v_type = VAR_STRING; 13889 ni->li_tv.v_lock = 0; 13890 ni->li_tv.vval.v_string = vim_strnsave(str, end - str); 13891 list_append(l, ni); 13892 } 13893 if (!match) 13894 break; 13895 /* Advance to just after the match. */ 13896 if (regmatch.endp[0] > str) 13897 col = 0; 13898 else 13899 { 13900 /* Don't get stuck at the same match. */ 13901 #ifdef FEAT_MBYTE 13902 col = (*mb_ptr2len)(regmatch.endp[0]); 13903 #else 13904 col = 1; 13905 #endif 13906 } 13907 str = regmatch.endp[0]; 13908 } 13909 13910 vim_free(regmatch.regprog); 13911 } 13912 13913 p_cpo = save_cpo; 13914 } 13915 13916 #ifdef HAVE_STRFTIME 13917 /* 13918 * "strftime({format}[, {time}])" function 13919 */ 13920 static void 13921 f_strftime(argvars, rettv) 13922 typval_T *argvars; 13923 typval_T *rettv; 13924 { 13925 char_u result_buf[256]; 13926 struct tm *curtime; 13927 time_t seconds; 13928 char_u *p; 13929 13930 rettv->v_type = VAR_STRING; 13931 13932 p = get_tv_string(&argvars[0]); 13933 if (argvars[1].v_type == VAR_UNKNOWN) 13934 seconds = time(NULL); 13935 else 13936 seconds = (time_t)get_tv_number(&argvars[1]); 13937 curtime = localtime(&seconds); 13938 /* MSVC returns NULL for an invalid value of seconds. */ 13939 if (curtime == NULL) 13940 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 13941 else 13942 { 13943 # ifdef FEAT_MBYTE 13944 vimconv_T conv; 13945 char_u *enc; 13946 13947 conv.vc_type = CONV_NONE; 13948 enc = enc_locale(); 13949 convert_setup(&conv, p_enc, enc); 13950 if (conv.vc_type != CONV_NONE) 13951 p = string_convert(&conv, p, NULL); 13952 # endif 13953 if (p != NULL) 13954 (void)strftime((char *)result_buf, sizeof(result_buf), 13955 (char *)p, curtime); 13956 else 13957 result_buf[0] = NUL; 13958 13959 # ifdef FEAT_MBYTE 13960 if (conv.vc_type != CONV_NONE) 13961 vim_free(p); 13962 convert_setup(&conv, enc, p_enc); 13963 if (conv.vc_type != CONV_NONE) 13964 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 13965 else 13966 # endif 13967 rettv->vval.v_string = vim_strsave(result_buf); 13968 13969 # ifdef FEAT_MBYTE 13970 /* Release conversion descriptors */ 13971 convert_setup(&conv, NULL, NULL); 13972 vim_free(enc); 13973 # endif 13974 } 13975 } 13976 #endif 13977 13978 /* 13979 * "stridx()" function 13980 */ 13981 static void 13982 f_stridx(argvars, rettv) 13983 typval_T *argvars; 13984 typval_T *rettv; 13985 { 13986 char_u buf[NUMBUFLEN]; 13987 char_u *needle; 13988 char_u *haystack; 13989 char_u *save_haystack; 13990 char_u *pos; 13991 int start_idx; 13992 13993 needle = get_tv_string_chk(&argvars[1]); 13994 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 13995 rettv->vval.v_number = -1; 13996 if (needle == NULL || haystack == NULL) 13997 return; /* type error; errmsg already given */ 13998 13999 if (argvars[2].v_type != VAR_UNKNOWN) 14000 { 14001 int error = FALSE; 14002 14003 start_idx = get_tv_number_chk(&argvars[2], &error); 14004 if (error || start_idx >= (int)STRLEN(haystack)) 14005 return; 14006 if (start_idx >= 0) 14007 haystack += start_idx; 14008 } 14009 14010 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14011 if (pos != NULL) 14012 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14013 } 14014 14015 /* 14016 * "string()" function 14017 */ 14018 static void 14019 f_string(argvars, rettv) 14020 typval_T *argvars; 14021 typval_T *rettv; 14022 { 14023 char_u *tofree; 14024 char_u numbuf[NUMBUFLEN]; 14025 14026 rettv->v_type = VAR_STRING; 14027 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14028 if (tofree == NULL) 14029 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14030 } 14031 14032 /* 14033 * "strlen()" function 14034 */ 14035 static void 14036 f_strlen(argvars, rettv) 14037 typval_T *argvars; 14038 typval_T *rettv; 14039 { 14040 rettv->vval.v_number = (varnumber_T)(STRLEN( 14041 get_tv_string(&argvars[0]))); 14042 } 14043 14044 /* 14045 * "strpart()" function 14046 */ 14047 static void 14048 f_strpart(argvars, rettv) 14049 typval_T *argvars; 14050 typval_T *rettv; 14051 { 14052 char_u *p; 14053 int n; 14054 int len; 14055 int slen; 14056 int error = FALSE; 14057 14058 p = get_tv_string(&argvars[0]); 14059 slen = (int)STRLEN(p); 14060 14061 n = get_tv_number_chk(&argvars[1], &error); 14062 if (error) 14063 len = 0; 14064 else if (argvars[2].v_type != VAR_UNKNOWN) 14065 len = get_tv_number(&argvars[2]); 14066 else 14067 len = slen - n; /* default len: all bytes that are available. */ 14068 14069 /* 14070 * Only return the overlap between the specified part and the actual 14071 * string. 14072 */ 14073 if (n < 0) 14074 { 14075 len += n; 14076 n = 0; 14077 } 14078 else if (n > slen) 14079 n = slen; 14080 if (len < 0) 14081 len = 0; 14082 else if (n + len > slen) 14083 len = slen - n; 14084 14085 rettv->v_type = VAR_STRING; 14086 rettv->vval.v_string = vim_strnsave(p + n, len); 14087 } 14088 14089 /* 14090 * "strridx()" function 14091 */ 14092 static void 14093 f_strridx(argvars, rettv) 14094 typval_T *argvars; 14095 typval_T *rettv; 14096 { 14097 char_u buf[NUMBUFLEN]; 14098 char_u *needle; 14099 char_u *haystack; 14100 char_u *rest; 14101 char_u *lastmatch = NULL; 14102 int haystack_len, end_idx; 14103 14104 needle = get_tv_string_chk(&argvars[1]); 14105 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14106 haystack_len = STRLEN(haystack); 14107 14108 rettv->vval.v_number = -1; 14109 if (needle == NULL || haystack == NULL) 14110 return; /* type error; errmsg already given */ 14111 if (argvars[2].v_type != VAR_UNKNOWN) 14112 { 14113 /* Third argument: upper limit for index */ 14114 end_idx = get_tv_number_chk(&argvars[2], NULL); 14115 if (end_idx < 0) 14116 return; /* can never find a match */ 14117 } 14118 else 14119 end_idx = haystack_len; 14120 14121 if (*needle == NUL) 14122 { 14123 /* Empty string matches past the end. */ 14124 lastmatch = haystack + end_idx; 14125 } 14126 else 14127 { 14128 for (rest = haystack; *rest != '\0'; ++rest) 14129 { 14130 rest = (char_u *)strstr((char *)rest, (char *)needle); 14131 if (rest == NULL || rest > haystack + end_idx) 14132 break; 14133 lastmatch = rest; 14134 } 14135 } 14136 14137 if (lastmatch == NULL) 14138 rettv->vval.v_number = -1; 14139 else 14140 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14141 } 14142 14143 /* 14144 * "strtrans()" function 14145 */ 14146 static void 14147 f_strtrans(argvars, rettv) 14148 typval_T *argvars; 14149 typval_T *rettv; 14150 { 14151 rettv->v_type = VAR_STRING; 14152 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14153 } 14154 14155 /* 14156 * "submatch()" function 14157 */ 14158 static void 14159 f_submatch(argvars, rettv) 14160 typval_T *argvars; 14161 typval_T *rettv; 14162 { 14163 rettv->v_type = VAR_STRING; 14164 rettv->vval.v_string = 14165 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14166 } 14167 14168 /* 14169 * "substitute()" function 14170 */ 14171 static void 14172 f_substitute(argvars, rettv) 14173 typval_T *argvars; 14174 typval_T *rettv; 14175 { 14176 char_u patbuf[NUMBUFLEN]; 14177 char_u subbuf[NUMBUFLEN]; 14178 char_u flagsbuf[NUMBUFLEN]; 14179 14180 char_u *str = get_tv_string_chk(&argvars[0]); 14181 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14182 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14183 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14184 14185 rettv->v_type = VAR_STRING; 14186 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14187 rettv->vval.v_string = NULL; 14188 else 14189 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14190 } 14191 14192 /* 14193 * "synID(lnum, col, trans)" function 14194 */ 14195 /*ARGSUSED*/ 14196 static void 14197 f_synID(argvars, rettv) 14198 typval_T *argvars; 14199 typval_T *rettv; 14200 { 14201 int id = 0; 14202 #ifdef FEAT_SYN_HL 14203 long lnum; 14204 long col; 14205 int trans; 14206 int transerr = FALSE; 14207 14208 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14209 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14210 trans = get_tv_number_chk(&argvars[2], &transerr); 14211 14212 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14213 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14214 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14215 #endif 14216 14217 rettv->vval.v_number = id; 14218 } 14219 14220 /* 14221 * "synIDattr(id, what [, mode])" function 14222 */ 14223 /*ARGSUSED*/ 14224 static void 14225 f_synIDattr(argvars, rettv) 14226 typval_T *argvars; 14227 typval_T *rettv; 14228 { 14229 char_u *p = NULL; 14230 #ifdef FEAT_SYN_HL 14231 int id; 14232 char_u *what; 14233 char_u *mode; 14234 char_u modebuf[NUMBUFLEN]; 14235 int modec; 14236 14237 id = get_tv_number(&argvars[0]); 14238 what = get_tv_string(&argvars[1]); 14239 if (argvars[2].v_type != VAR_UNKNOWN) 14240 { 14241 mode = get_tv_string_buf(&argvars[2], modebuf); 14242 modec = TOLOWER_ASC(mode[0]); 14243 if (modec != 't' && modec != 'c' 14244 #ifdef FEAT_GUI 14245 && modec != 'g' 14246 #endif 14247 ) 14248 modec = 0; /* replace invalid with current */ 14249 } 14250 else 14251 { 14252 #ifdef FEAT_GUI 14253 if (gui.in_use) 14254 modec = 'g'; 14255 else 14256 #endif 14257 if (t_colors > 1) 14258 modec = 'c'; 14259 else 14260 modec = 't'; 14261 } 14262 14263 14264 switch (TOLOWER_ASC(what[0])) 14265 { 14266 case 'b': 14267 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14268 p = highlight_color(id, what, modec); 14269 else /* bold */ 14270 p = highlight_has_attr(id, HL_BOLD, modec); 14271 break; 14272 14273 case 'f': /* fg[#] */ 14274 p = highlight_color(id, what, modec); 14275 break; 14276 14277 case 'i': 14278 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14279 p = highlight_has_attr(id, HL_INVERSE, modec); 14280 else /* italic */ 14281 p = highlight_has_attr(id, HL_ITALIC, modec); 14282 break; 14283 14284 case 'n': /* name */ 14285 p = get_highlight_name(NULL, id - 1); 14286 break; 14287 14288 case 'r': /* reverse */ 14289 p = highlight_has_attr(id, HL_INVERSE, modec); 14290 break; 14291 14292 case 's': /* standout */ 14293 p = highlight_has_attr(id, HL_STANDOUT, modec); 14294 break; 14295 14296 case 'u': 14297 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14298 /* underline */ 14299 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14300 else 14301 /* undercurl */ 14302 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14303 break; 14304 } 14305 14306 if (p != NULL) 14307 p = vim_strsave(p); 14308 #endif 14309 rettv->v_type = VAR_STRING; 14310 rettv->vval.v_string = p; 14311 } 14312 14313 /* 14314 * "synIDtrans(id)" function 14315 */ 14316 /*ARGSUSED*/ 14317 static void 14318 f_synIDtrans(argvars, rettv) 14319 typval_T *argvars; 14320 typval_T *rettv; 14321 { 14322 int id; 14323 14324 #ifdef FEAT_SYN_HL 14325 id = get_tv_number(&argvars[0]); 14326 14327 if (id > 0) 14328 id = syn_get_final_id(id); 14329 else 14330 #endif 14331 id = 0; 14332 14333 rettv->vval.v_number = id; 14334 } 14335 14336 /* 14337 * "system()" function 14338 */ 14339 static void 14340 f_system(argvars, rettv) 14341 typval_T *argvars; 14342 typval_T *rettv; 14343 { 14344 char_u *res = NULL; 14345 char_u *p; 14346 char_u *infile = NULL; 14347 char_u buf[NUMBUFLEN]; 14348 int err = FALSE; 14349 FILE *fd; 14350 14351 if (argvars[1].v_type != VAR_UNKNOWN) 14352 { 14353 /* 14354 * Write the string to a temp file, to be used for input of the shell 14355 * command. 14356 */ 14357 if ((infile = vim_tempname('i')) == NULL) 14358 { 14359 EMSG(_(e_notmp)); 14360 return; 14361 } 14362 14363 fd = mch_fopen((char *)infile, WRITEBIN); 14364 if (fd == NULL) 14365 { 14366 EMSG2(_(e_notopen), infile); 14367 goto done; 14368 } 14369 p = get_tv_string_buf_chk(&argvars[1], buf); 14370 if (p == NULL) 14371 goto done; /* type error; errmsg already given */ 14372 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14373 err = TRUE; 14374 if (fclose(fd) != 0) 14375 err = TRUE; 14376 if (err) 14377 { 14378 EMSG(_("E677: Error writing temp file")); 14379 goto done; 14380 } 14381 } 14382 14383 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14384 14385 #ifdef USE_CR 14386 /* translate <CR> into <NL> */ 14387 if (res != NULL) 14388 { 14389 char_u *s; 14390 14391 for (s = res; *s; ++s) 14392 { 14393 if (*s == CAR) 14394 *s = NL; 14395 } 14396 } 14397 #else 14398 # ifdef USE_CRNL 14399 /* translate <CR><NL> into <NL> */ 14400 if (res != NULL) 14401 { 14402 char_u *s, *d; 14403 14404 d = res; 14405 for (s = res; *s; ++s) 14406 { 14407 if (s[0] == CAR && s[1] == NL) 14408 ++s; 14409 *d++ = *s; 14410 } 14411 *d = NUL; 14412 } 14413 # endif 14414 #endif 14415 14416 done: 14417 if (infile != NULL) 14418 { 14419 mch_remove(infile); 14420 vim_free(infile); 14421 } 14422 rettv->v_type = VAR_STRING; 14423 rettv->vval.v_string = res; 14424 } 14425 14426 /* 14427 * "taglist()" function 14428 */ 14429 static void 14430 f_taglist(argvars, rettv) 14431 typval_T *argvars; 14432 typval_T *rettv; 14433 { 14434 char_u *tag_pattern; 14435 list_T *l; 14436 14437 tag_pattern = get_tv_string(&argvars[0]); 14438 14439 rettv->vval.v_number = FALSE; 14440 if (*tag_pattern == NUL) 14441 return; 14442 14443 l = list_alloc(); 14444 if (l != NULL) 14445 { 14446 if (get_tags(l, tag_pattern) != FAIL) 14447 { 14448 rettv->vval.v_list = l; 14449 rettv->v_type = VAR_LIST; 14450 ++l->lv_refcount; 14451 } 14452 else 14453 list_free(l); 14454 } 14455 } 14456 14457 /* 14458 * "tempname()" function 14459 */ 14460 /*ARGSUSED*/ 14461 static void 14462 f_tempname(argvars, rettv) 14463 typval_T *argvars; 14464 typval_T *rettv; 14465 { 14466 static int x = 'A'; 14467 14468 rettv->v_type = VAR_STRING; 14469 rettv->vval.v_string = vim_tempname(x); 14470 14471 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14472 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14473 do 14474 { 14475 if (x == 'Z') 14476 x = '0'; 14477 else if (x == '9') 14478 x = 'A'; 14479 else 14480 { 14481 #ifdef EBCDIC 14482 if (x == 'I') 14483 x = 'J'; 14484 else if (x == 'R') 14485 x = 'S'; 14486 else 14487 #endif 14488 ++x; 14489 } 14490 } while (x == 'I' || x == 'O'); 14491 } 14492 14493 /* 14494 * "test(list)" function: Just checking the walls... 14495 */ 14496 /*ARGSUSED*/ 14497 static void 14498 f_test(argvars, rettv) 14499 typval_T *argvars; 14500 typval_T *rettv; 14501 { 14502 /* Used for unit testing. Change the code below to your liking. */ 14503 #if 0 14504 listitem_T *li; 14505 list_T *l; 14506 char_u *bad, *good; 14507 14508 if (argvars[0].v_type != VAR_LIST) 14509 return; 14510 l = argvars[0].vval.v_list; 14511 if (l == NULL) 14512 return; 14513 li = l->lv_first; 14514 if (li == NULL) 14515 return; 14516 bad = get_tv_string(&li->li_tv); 14517 li = li->li_next; 14518 if (li == NULL) 14519 return; 14520 good = get_tv_string(&li->li_tv); 14521 rettv->vval.v_number = test_edit_score(bad, good); 14522 #endif 14523 } 14524 14525 /* 14526 * "tolower(string)" function 14527 */ 14528 static void 14529 f_tolower(argvars, rettv) 14530 typval_T *argvars; 14531 typval_T *rettv; 14532 { 14533 char_u *p; 14534 14535 p = vim_strsave(get_tv_string(&argvars[0])); 14536 rettv->v_type = VAR_STRING; 14537 rettv->vval.v_string = p; 14538 14539 if (p != NULL) 14540 while (*p != NUL) 14541 { 14542 #ifdef FEAT_MBYTE 14543 int l; 14544 14545 if (enc_utf8) 14546 { 14547 int c, lc; 14548 14549 c = utf_ptr2char(p); 14550 lc = utf_tolower(c); 14551 l = utf_ptr2len(p); 14552 /* TODO: reallocate string when byte count changes. */ 14553 if (utf_char2len(lc) == l) 14554 utf_char2bytes(lc, p); 14555 p += l; 14556 } 14557 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14558 p += l; /* skip multi-byte character */ 14559 else 14560 #endif 14561 { 14562 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14563 ++p; 14564 } 14565 } 14566 } 14567 14568 /* 14569 * "toupper(string)" function 14570 */ 14571 static void 14572 f_toupper(argvars, rettv) 14573 typval_T *argvars; 14574 typval_T *rettv; 14575 { 14576 rettv->v_type = VAR_STRING; 14577 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14578 } 14579 14580 /* 14581 * "tr(string, fromstr, tostr)" function 14582 */ 14583 static void 14584 f_tr(argvars, rettv) 14585 typval_T *argvars; 14586 typval_T *rettv; 14587 { 14588 char_u *instr; 14589 char_u *fromstr; 14590 char_u *tostr; 14591 char_u *p; 14592 #ifdef FEAT_MBYTE 14593 int inlen; 14594 int fromlen; 14595 int tolen; 14596 int idx; 14597 char_u *cpstr; 14598 int cplen; 14599 int first = TRUE; 14600 #endif 14601 char_u buf[NUMBUFLEN]; 14602 char_u buf2[NUMBUFLEN]; 14603 garray_T ga; 14604 14605 instr = get_tv_string(&argvars[0]); 14606 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14607 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14608 14609 /* Default return value: empty string. */ 14610 rettv->v_type = VAR_STRING; 14611 rettv->vval.v_string = NULL; 14612 if (fromstr == NULL || tostr == NULL) 14613 return; /* type error; errmsg already given */ 14614 ga_init2(&ga, (int)sizeof(char), 80); 14615 14616 #ifdef FEAT_MBYTE 14617 if (!has_mbyte) 14618 #endif 14619 /* not multi-byte: fromstr and tostr must be the same length */ 14620 if (STRLEN(fromstr) != STRLEN(tostr)) 14621 { 14622 #ifdef FEAT_MBYTE 14623 error: 14624 #endif 14625 EMSG2(_(e_invarg2), fromstr); 14626 ga_clear(&ga); 14627 return; 14628 } 14629 14630 /* fromstr and tostr have to contain the same number of chars */ 14631 while (*instr != NUL) 14632 { 14633 #ifdef FEAT_MBYTE 14634 if (has_mbyte) 14635 { 14636 inlen = (*mb_ptr2len)(instr); 14637 cpstr = instr; 14638 cplen = inlen; 14639 idx = 0; 14640 for (p = fromstr; *p != NUL; p += fromlen) 14641 { 14642 fromlen = (*mb_ptr2len)(p); 14643 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14644 { 14645 for (p = tostr; *p != NUL; p += tolen) 14646 { 14647 tolen = (*mb_ptr2len)(p); 14648 if (idx-- == 0) 14649 { 14650 cplen = tolen; 14651 cpstr = p; 14652 break; 14653 } 14654 } 14655 if (*p == NUL) /* tostr is shorter than fromstr */ 14656 goto error; 14657 break; 14658 } 14659 ++idx; 14660 } 14661 14662 if (first && cpstr == instr) 14663 { 14664 /* Check that fromstr and tostr have the same number of 14665 * (multi-byte) characters. Done only once when a character 14666 * of instr doesn't appear in fromstr. */ 14667 first = FALSE; 14668 for (p = tostr; *p != NUL; p += tolen) 14669 { 14670 tolen = (*mb_ptr2len)(p); 14671 --idx; 14672 } 14673 if (idx != 0) 14674 goto error; 14675 } 14676 14677 ga_grow(&ga, cplen); 14678 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14679 ga.ga_len += cplen; 14680 14681 instr += inlen; 14682 } 14683 else 14684 #endif 14685 { 14686 /* When not using multi-byte chars we can do it faster. */ 14687 p = vim_strchr(fromstr, *instr); 14688 if (p != NULL) 14689 ga_append(&ga, tostr[p - fromstr]); 14690 else 14691 ga_append(&ga, *instr); 14692 ++instr; 14693 } 14694 } 14695 14696 rettv->vval.v_string = ga.ga_data; 14697 } 14698 14699 /* 14700 * "type(expr)" function 14701 */ 14702 static void 14703 f_type(argvars, rettv) 14704 typval_T *argvars; 14705 typval_T *rettv; 14706 { 14707 int n; 14708 14709 switch (argvars[0].v_type) 14710 { 14711 case VAR_NUMBER: n = 0; break; 14712 case VAR_STRING: n = 1; break; 14713 case VAR_FUNC: n = 2; break; 14714 case VAR_LIST: n = 3; break; 14715 case VAR_DICT: n = 4; break; 14716 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14717 } 14718 rettv->vval.v_number = n; 14719 } 14720 14721 /* 14722 * "values(dict)" function 14723 */ 14724 static void 14725 f_values(argvars, rettv) 14726 typval_T *argvars; 14727 typval_T *rettv; 14728 { 14729 dict_list(argvars, rettv, 1); 14730 } 14731 14732 /* 14733 * "virtcol(string)" function 14734 */ 14735 static void 14736 f_virtcol(argvars, rettv) 14737 typval_T *argvars; 14738 typval_T *rettv; 14739 { 14740 colnr_T vcol = 0; 14741 pos_T *fp; 14742 14743 fp = var2fpos(&argvars[0], FALSE); 14744 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14745 { 14746 getvvcol(curwin, fp, NULL, NULL, &vcol); 14747 ++vcol; 14748 } 14749 14750 rettv->vval.v_number = vcol; 14751 } 14752 14753 /* 14754 * "visualmode()" function 14755 */ 14756 /*ARGSUSED*/ 14757 static void 14758 f_visualmode(argvars, rettv) 14759 typval_T *argvars; 14760 typval_T *rettv; 14761 { 14762 #ifdef FEAT_VISUAL 14763 char_u str[2]; 14764 14765 rettv->v_type = VAR_STRING; 14766 str[0] = curbuf->b_visual_mode_eval; 14767 str[1] = NUL; 14768 rettv->vval.v_string = vim_strsave(str); 14769 14770 /* A non-zero number or non-empty string argument: reset mode. */ 14771 if ((argvars[0].v_type == VAR_NUMBER 14772 && argvars[0].vval.v_number != 0) 14773 || (argvars[0].v_type == VAR_STRING 14774 && *get_tv_string(&argvars[0]) != NUL)) 14775 curbuf->b_visual_mode_eval = NUL; 14776 #else 14777 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14778 #endif 14779 } 14780 14781 /* 14782 * "winbufnr(nr)" function 14783 */ 14784 static void 14785 f_winbufnr(argvars, rettv) 14786 typval_T *argvars; 14787 typval_T *rettv; 14788 { 14789 win_T *wp; 14790 14791 wp = find_win_by_nr(&argvars[0]); 14792 if (wp == NULL) 14793 rettv->vval.v_number = -1; 14794 else 14795 rettv->vval.v_number = wp->w_buffer->b_fnum; 14796 } 14797 14798 /* 14799 * "wincol()" function 14800 */ 14801 /*ARGSUSED*/ 14802 static void 14803 f_wincol(argvars, rettv) 14804 typval_T *argvars; 14805 typval_T *rettv; 14806 { 14807 validate_cursor(); 14808 rettv->vval.v_number = curwin->w_wcol + 1; 14809 } 14810 14811 /* 14812 * "winheight(nr)" function 14813 */ 14814 static void 14815 f_winheight(argvars, rettv) 14816 typval_T *argvars; 14817 typval_T *rettv; 14818 { 14819 win_T *wp; 14820 14821 wp = find_win_by_nr(&argvars[0]); 14822 if (wp == NULL) 14823 rettv->vval.v_number = -1; 14824 else 14825 rettv->vval.v_number = wp->w_height; 14826 } 14827 14828 /* 14829 * "winline()" function 14830 */ 14831 /*ARGSUSED*/ 14832 static void 14833 f_winline(argvars, rettv) 14834 typval_T *argvars; 14835 typval_T *rettv; 14836 { 14837 validate_cursor(); 14838 rettv->vval.v_number = curwin->w_wrow + 1; 14839 } 14840 14841 /* 14842 * "winnr()" function 14843 */ 14844 /* ARGSUSED */ 14845 static void 14846 f_winnr(argvars, rettv) 14847 typval_T *argvars; 14848 typval_T *rettv; 14849 { 14850 int nr = 1; 14851 #ifdef FEAT_WINDOWS 14852 win_T *wp; 14853 win_T *twin = curwin; 14854 char_u *arg; 14855 14856 if (argvars[0].v_type != VAR_UNKNOWN) 14857 { 14858 arg = get_tv_string_chk(&argvars[0]); 14859 if (arg == NULL) 14860 nr = 0; /* type error; errmsg already given */ 14861 else if (STRCMP(arg, "$") == 0) 14862 twin = lastwin; 14863 else if (STRCMP(arg, "#") == 0) 14864 { 14865 twin = prevwin; 14866 if (prevwin == NULL) 14867 nr = 0; 14868 } 14869 else 14870 { 14871 EMSG2(_(e_invexpr2), arg); 14872 nr = 0; 14873 } 14874 } 14875 14876 if (nr > 0) 14877 for (wp = firstwin; wp != twin; wp = wp->w_next) 14878 ++nr; 14879 #endif 14880 rettv->vval.v_number = nr; 14881 } 14882 14883 /* 14884 * "winrestcmd()" function 14885 */ 14886 /* ARGSUSED */ 14887 static void 14888 f_winrestcmd(argvars, rettv) 14889 typval_T *argvars; 14890 typval_T *rettv; 14891 { 14892 #ifdef FEAT_WINDOWS 14893 win_T *wp; 14894 int winnr = 1; 14895 garray_T ga; 14896 char_u buf[50]; 14897 14898 ga_init2(&ga, (int)sizeof(char), 70); 14899 for (wp = firstwin; wp != NULL; wp = wp->w_next) 14900 { 14901 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 14902 ga_concat(&ga, buf); 14903 # ifdef FEAT_VERTSPLIT 14904 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 14905 ga_concat(&ga, buf); 14906 # endif 14907 ++winnr; 14908 } 14909 ga_append(&ga, NUL); 14910 14911 rettv->vval.v_string = ga.ga_data; 14912 #else 14913 rettv->vval.v_string = NULL; 14914 #endif 14915 rettv->v_type = VAR_STRING; 14916 } 14917 14918 /* 14919 * "winwidth(nr)" function 14920 */ 14921 static void 14922 f_winwidth(argvars, rettv) 14923 typval_T *argvars; 14924 typval_T *rettv; 14925 { 14926 win_T *wp; 14927 14928 wp = find_win_by_nr(&argvars[0]); 14929 if (wp == NULL) 14930 rettv->vval.v_number = -1; 14931 else 14932 #ifdef FEAT_VERTSPLIT 14933 rettv->vval.v_number = wp->w_width; 14934 #else 14935 rettv->vval.v_number = Columns; 14936 #endif 14937 } 14938 14939 /* 14940 * "writefile()" function 14941 */ 14942 static void 14943 f_writefile(argvars, rettv) 14944 typval_T *argvars; 14945 typval_T *rettv; 14946 { 14947 int binary = FALSE; 14948 char_u *fname; 14949 FILE *fd; 14950 listitem_T *li; 14951 char_u *s; 14952 int ret = 0; 14953 int c; 14954 14955 if (argvars[0].v_type != VAR_LIST) 14956 { 14957 EMSG2(_(e_listarg), "writefile()"); 14958 return; 14959 } 14960 if (argvars[0].vval.v_list == NULL) 14961 return; 14962 14963 if (argvars[2].v_type != VAR_UNKNOWN 14964 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 14965 binary = TRUE; 14966 14967 /* Always open the file in binary mode, library functions have a mind of 14968 * their own about CR-LF conversion. */ 14969 fname = get_tv_string(&argvars[1]); 14970 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 14971 { 14972 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 14973 ret = -1; 14974 } 14975 else 14976 { 14977 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 14978 li = li->li_next) 14979 { 14980 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 14981 { 14982 if (*s == '\n') 14983 c = putc(NUL, fd); 14984 else 14985 c = putc(*s, fd); 14986 if (c == EOF) 14987 { 14988 ret = -1; 14989 break; 14990 } 14991 } 14992 if (!binary || li->li_next != NULL) 14993 if (putc('\n', fd) == EOF) 14994 { 14995 ret = -1; 14996 break; 14997 } 14998 if (ret < 0) 14999 { 15000 EMSG(_(e_write)); 15001 break; 15002 } 15003 } 15004 fclose(fd); 15005 } 15006 15007 rettv->vval.v_number = ret; 15008 } 15009 15010 /* 15011 * Translate a String variable into a position. 15012 */ 15013 static pos_T * 15014 var2fpos(varp, lnum) 15015 typval_T *varp; 15016 int lnum; /* TRUE when $ is last line */ 15017 { 15018 char_u *name; 15019 static pos_T pos; 15020 pos_T *pp; 15021 15022 name = get_tv_string_chk(varp); 15023 if (name == NULL) 15024 return NULL; 15025 if (name[0] == '.') /* cursor */ 15026 return &curwin->w_cursor; 15027 if (name[0] == '\'') /* mark */ 15028 { 15029 pp = getmark(name[1], FALSE); 15030 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15031 return NULL; 15032 return pp; 15033 } 15034 if (name[0] == '$') /* last column or line */ 15035 { 15036 if (lnum) 15037 { 15038 pos.lnum = curbuf->b_ml.ml_line_count; 15039 pos.col = 0; 15040 } 15041 else 15042 { 15043 pos.lnum = curwin->w_cursor.lnum; 15044 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15045 } 15046 return &pos; 15047 } 15048 return NULL; 15049 } 15050 15051 /* 15052 * Get the length of an environment variable name. 15053 * Advance "arg" to the first character after the name. 15054 * Return 0 for error. 15055 */ 15056 static int 15057 get_env_len(arg) 15058 char_u **arg; 15059 { 15060 char_u *p; 15061 int len; 15062 15063 for (p = *arg; vim_isIDc(*p); ++p) 15064 ; 15065 if (p == *arg) /* no name found */ 15066 return 0; 15067 15068 len = (int)(p - *arg); 15069 *arg = p; 15070 return len; 15071 } 15072 15073 /* 15074 * Get the length of the name of a function or internal variable. 15075 * "arg" is advanced to the first non-white character after the name. 15076 * Return 0 if something is wrong. 15077 */ 15078 static int 15079 get_id_len(arg) 15080 char_u **arg; 15081 { 15082 char_u *p; 15083 int len; 15084 15085 /* Find the end of the name. */ 15086 for (p = *arg; eval_isnamec(*p); ++p) 15087 ; 15088 if (p == *arg) /* no name found */ 15089 return 0; 15090 15091 len = (int)(p - *arg); 15092 *arg = skipwhite(p); 15093 15094 return len; 15095 } 15096 15097 /* 15098 * Get the length of the name of a variable or function. 15099 * Only the name is recognized, does not handle ".key" or "[idx]". 15100 * "arg" is advanced to the first non-white character after the name. 15101 * Return -1 if curly braces expansion failed. 15102 * Return 0 if something else is wrong. 15103 * If the name contains 'magic' {}'s, expand them and return the 15104 * expanded name in an allocated string via 'alias' - caller must free. 15105 */ 15106 static int 15107 get_name_len(arg, alias, evaluate, verbose) 15108 char_u **arg; 15109 char_u **alias; 15110 int evaluate; 15111 int verbose; 15112 { 15113 int len; 15114 char_u *p; 15115 char_u *expr_start; 15116 char_u *expr_end; 15117 15118 *alias = NULL; /* default to no alias */ 15119 15120 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15121 && (*arg)[2] == (int)KE_SNR) 15122 { 15123 /* hard coded <SNR>, already translated */ 15124 *arg += 3; 15125 return get_id_len(arg) + 3; 15126 } 15127 len = eval_fname_script(*arg); 15128 if (len > 0) 15129 { 15130 /* literal "<SID>", "s:" or "<SNR>" */ 15131 *arg += len; 15132 } 15133 15134 /* 15135 * Find the end of the name; check for {} construction. 15136 */ 15137 p = find_name_end(*arg, &expr_start, &expr_end, 15138 len > 0 ? 0 : FNE_CHECK_START); 15139 if (expr_start != NULL) 15140 { 15141 char_u *temp_string; 15142 15143 if (!evaluate) 15144 { 15145 len += (int)(p - *arg); 15146 *arg = skipwhite(p); 15147 return len; 15148 } 15149 15150 /* 15151 * Include any <SID> etc in the expanded string: 15152 * Thus the -len here. 15153 */ 15154 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15155 if (temp_string == NULL) 15156 return -1; 15157 *alias = temp_string; 15158 *arg = skipwhite(p); 15159 return (int)STRLEN(temp_string); 15160 } 15161 15162 len += get_id_len(arg); 15163 if (len == 0 && verbose) 15164 EMSG2(_(e_invexpr2), *arg); 15165 15166 return len; 15167 } 15168 15169 /* 15170 * Find the end of a variable or function name, taking care of magic braces. 15171 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15172 * start and end of the first magic braces item. 15173 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15174 * Return a pointer to just after the name. Equal to "arg" if there is no 15175 * valid name. 15176 */ 15177 static char_u * 15178 find_name_end(arg, expr_start, expr_end, flags) 15179 char_u *arg; 15180 char_u **expr_start; 15181 char_u **expr_end; 15182 int flags; 15183 { 15184 int mb_nest = 0; 15185 int br_nest = 0; 15186 char_u *p; 15187 15188 if (expr_start != NULL) 15189 { 15190 *expr_start = NULL; 15191 *expr_end = NULL; 15192 } 15193 15194 /* Quick check for valid starting character. */ 15195 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15196 return arg; 15197 15198 for (p = arg; *p != NUL 15199 && (eval_isnamec(*p) 15200 || *p == '{' 15201 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15202 || mb_nest != 0 15203 || br_nest != 0); mb_ptr_adv(p)) 15204 { 15205 if (*p == '\'') 15206 { 15207 /* skip over 'string' to avoid counting [ and ] inside it. */ 15208 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15209 ; 15210 if (*p == NUL) 15211 break; 15212 } 15213 else if (*p == '"') 15214 { 15215 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15216 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15217 if (*p == '\\' && p[1] != NUL) 15218 ++p; 15219 if (*p == NUL) 15220 break; 15221 } 15222 15223 if (mb_nest == 0) 15224 { 15225 if (*p == '[') 15226 ++br_nest; 15227 else if (*p == ']') 15228 --br_nest; 15229 } 15230 15231 if (br_nest == 0) 15232 { 15233 if (*p == '{') 15234 { 15235 mb_nest++; 15236 if (expr_start != NULL && *expr_start == NULL) 15237 *expr_start = p; 15238 } 15239 else if (*p == '}') 15240 { 15241 mb_nest--; 15242 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15243 *expr_end = p; 15244 } 15245 } 15246 } 15247 15248 return p; 15249 } 15250 15251 /* 15252 * Expands out the 'magic' {}'s in a variable/function name. 15253 * Note that this can call itself recursively, to deal with 15254 * constructs like foo{bar}{baz}{bam} 15255 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15256 * "in_start" ^ 15257 * "expr_start" ^ 15258 * "expr_end" ^ 15259 * "in_end" ^ 15260 * 15261 * Returns a new allocated string, which the caller must free. 15262 * Returns NULL for failure. 15263 */ 15264 static char_u * 15265 make_expanded_name(in_start, expr_start, expr_end, in_end) 15266 char_u *in_start; 15267 char_u *expr_start; 15268 char_u *expr_end; 15269 char_u *in_end; 15270 { 15271 char_u c1; 15272 char_u *retval = NULL; 15273 char_u *temp_result; 15274 char_u *nextcmd = NULL; 15275 15276 if (expr_end == NULL || in_end == NULL) 15277 return NULL; 15278 *expr_start = NUL; 15279 *expr_end = NUL; 15280 c1 = *in_end; 15281 *in_end = NUL; 15282 15283 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15284 if (temp_result != NULL && nextcmd == NULL) 15285 { 15286 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15287 + (in_end - expr_end) + 1)); 15288 if (retval != NULL) 15289 { 15290 STRCPY(retval, in_start); 15291 STRCAT(retval, temp_result); 15292 STRCAT(retval, expr_end + 1); 15293 } 15294 } 15295 vim_free(temp_result); 15296 15297 *in_end = c1; /* put char back for error messages */ 15298 *expr_start = '{'; 15299 *expr_end = '}'; 15300 15301 if (retval != NULL) 15302 { 15303 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15304 if (expr_start != NULL) 15305 { 15306 /* Further expansion! */ 15307 temp_result = make_expanded_name(retval, expr_start, 15308 expr_end, temp_result); 15309 vim_free(retval); 15310 retval = temp_result; 15311 } 15312 } 15313 15314 return retval; 15315 } 15316 15317 /* 15318 * Return TRUE if character "c" can be used in a variable or function name. 15319 * Does not include '{' or '}' for magic braces. 15320 */ 15321 static int 15322 eval_isnamec(c) 15323 int c; 15324 { 15325 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15326 } 15327 15328 /* 15329 * Return TRUE if character "c" can be used as the first character in a 15330 * variable or function name (excluding '{' and '}'). 15331 */ 15332 static int 15333 eval_isnamec1(c) 15334 int c; 15335 { 15336 return (ASCII_ISALPHA(c) || c == '_'); 15337 } 15338 15339 /* 15340 * Set number v: variable to "val". 15341 */ 15342 void 15343 set_vim_var_nr(idx, val) 15344 int idx; 15345 long val; 15346 { 15347 vimvars[idx].vv_nr = val; 15348 } 15349 15350 /* 15351 * Get number v: variable value. 15352 */ 15353 long 15354 get_vim_var_nr(idx) 15355 int idx; 15356 { 15357 return vimvars[idx].vv_nr; 15358 } 15359 15360 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15361 /* 15362 * Get string v: variable value. Uses a static buffer, can only be used once. 15363 */ 15364 char_u * 15365 get_vim_var_str(idx) 15366 int idx; 15367 { 15368 return get_tv_string(&vimvars[idx].vv_tv); 15369 } 15370 #endif 15371 15372 /* 15373 * Set v:count, v:count1 and v:prevcount. 15374 */ 15375 void 15376 set_vcount(count, count1) 15377 long count; 15378 long count1; 15379 { 15380 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15381 vimvars[VV_COUNT].vv_nr = count; 15382 vimvars[VV_COUNT1].vv_nr = count1; 15383 } 15384 15385 /* 15386 * Set string v: variable to a copy of "val". 15387 */ 15388 void 15389 set_vim_var_string(idx, val, len) 15390 int idx; 15391 char_u *val; 15392 int len; /* length of "val" to use or -1 (whole string) */ 15393 { 15394 /* Need to do this (at least) once, since we can't initialize a union. 15395 * Will always be invoked when "v:progname" is set. */ 15396 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15397 15398 vim_free(vimvars[idx].vv_str); 15399 if (val == NULL) 15400 vimvars[idx].vv_str = NULL; 15401 else if (len == -1) 15402 vimvars[idx].vv_str = vim_strsave(val); 15403 else 15404 vimvars[idx].vv_str = vim_strnsave(val, len); 15405 } 15406 15407 /* 15408 * Set v:register if needed. 15409 */ 15410 void 15411 set_reg_var(c) 15412 int c; 15413 { 15414 char_u regname; 15415 15416 if (c == 0 || c == ' ') 15417 regname = '"'; 15418 else 15419 regname = c; 15420 /* Avoid free/alloc when the value is already right. */ 15421 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15422 set_vim_var_string(VV_REG, ®name, 1); 15423 } 15424 15425 /* 15426 * Get or set v:exception. If "oldval" == NULL, return the current value. 15427 * Otherwise, restore the value to "oldval" and return NULL. 15428 * Must always be called in pairs to save and restore v:exception! Does not 15429 * take care of memory allocations. 15430 */ 15431 char_u * 15432 v_exception(oldval) 15433 char_u *oldval; 15434 { 15435 if (oldval == NULL) 15436 return vimvars[VV_EXCEPTION].vv_str; 15437 15438 vimvars[VV_EXCEPTION].vv_str = oldval; 15439 return NULL; 15440 } 15441 15442 /* 15443 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15444 * Otherwise, restore the value to "oldval" and return NULL. 15445 * Must always be called in pairs to save and restore v:throwpoint! Does not 15446 * take care of memory allocations. 15447 */ 15448 char_u * 15449 v_throwpoint(oldval) 15450 char_u *oldval; 15451 { 15452 if (oldval == NULL) 15453 return vimvars[VV_THROWPOINT].vv_str; 15454 15455 vimvars[VV_THROWPOINT].vv_str = oldval; 15456 return NULL; 15457 } 15458 15459 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15460 /* 15461 * Set v:cmdarg. 15462 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15463 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15464 * Must always be called in pairs! 15465 */ 15466 char_u * 15467 set_cmdarg(eap, oldarg) 15468 exarg_T *eap; 15469 char_u *oldarg; 15470 { 15471 char_u *oldval; 15472 char_u *newval; 15473 unsigned len; 15474 15475 oldval = vimvars[VV_CMDARG].vv_str; 15476 if (eap == NULL) 15477 { 15478 vim_free(oldval); 15479 vimvars[VV_CMDARG].vv_str = oldarg; 15480 return NULL; 15481 } 15482 15483 if (eap->force_bin == FORCE_BIN) 15484 len = 6; 15485 else if (eap->force_bin == FORCE_NOBIN) 15486 len = 8; 15487 else 15488 len = 0; 15489 if (eap->force_ff != 0) 15490 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15491 # ifdef FEAT_MBYTE 15492 if (eap->force_enc != 0) 15493 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15494 # endif 15495 15496 newval = alloc(len + 1); 15497 if (newval == NULL) 15498 return NULL; 15499 15500 if (eap->force_bin == FORCE_BIN) 15501 sprintf((char *)newval, " ++bin"); 15502 else if (eap->force_bin == FORCE_NOBIN) 15503 sprintf((char *)newval, " ++nobin"); 15504 else 15505 *newval = NUL; 15506 if (eap->force_ff != 0) 15507 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15508 eap->cmd + eap->force_ff); 15509 # ifdef FEAT_MBYTE 15510 if (eap->force_enc != 0) 15511 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15512 eap->cmd + eap->force_enc); 15513 # endif 15514 vimvars[VV_CMDARG].vv_str = newval; 15515 return oldval; 15516 } 15517 #endif 15518 15519 /* 15520 * Get the value of internal variable "name". 15521 * Return OK or FAIL. 15522 */ 15523 static int 15524 get_var_tv(name, len, rettv, verbose) 15525 char_u *name; 15526 int len; /* length of "name" */ 15527 typval_T *rettv; /* NULL when only checking existence */ 15528 int verbose; /* may give error message */ 15529 { 15530 int ret = OK; 15531 typval_T *tv = NULL; 15532 typval_T atv; 15533 dictitem_T *v; 15534 int cc; 15535 15536 /* truncate the name, so that we can use strcmp() */ 15537 cc = name[len]; 15538 name[len] = NUL; 15539 15540 /* 15541 * Check for "b:changedtick". 15542 */ 15543 if (STRCMP(name, "b:changedtick") == 0) 15544 { 15545 atv.v_type = VAR_NUMBER; 15546 atv.vval.v_number = curbuf->b_changedtick; 15547 tv = &atv; 15548 } 15549 15550 /* 15551 * Check for user-defined variables. 15552 */ 15553 else 15554 { 15555 v = find_var(name, NULL); 15556 if (v != NULL) 15557 tv = &v->di_tv; 15558 } 15559 15560 if (tv == NULL) 15561 { 15562 if (rettv != NULL && verbose) 15563 EMSG2(_(e_undefvar), name); 15564 ret = FAIL; 15565 } 15566 else if (rettv != NULL) 15567 copy_tv(tv, rettv); 15568 15569 name[len] = cc; 15570 15571 return ret; 15572 } 15573 15574 /* 15575 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15576 * Also handle function call with Funcref variable: func(expr) 15577 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15578 */ 15579 static int 15580 handle_subscript(arg, rettv, evaluate, verbose) 15581 char_u **arg; 15582 typval_T *rettv; 15583 int evaluate; /* do more than finding the end */ 15584 int verbose; /* give error messages */ 15585 { 15586 int ret = OK; 15587 dict_T *selfdict = NULL; 15588 char_u *s; 15589 int len; 15590 typval_T functv; 15591 15592 while (ret == OK 15593 && (**arg == '[' 15594 || (**arg == '.' && rettv->v_type == VAR_DICT) 15595 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15596 && !vim_iswhite(*(*arg - 1))) 15597 { 15598 if (**arg == '(') 15599 { 15600 /* need to copy the funcref so that we can clear rettv */ 15601 functv = *rettv; 15602 rettv->v_type = VAR_UNKNOWN; 15603 15604 /* Invoke the function. Recursive! */ 15605 s = functv.vval.v_string; 15606 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15607 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15608 &len, evaluate, selfdict); 15609 15610 /* Clear the funcref afterwards, so that deleting it while 15611 * evaluating the arguments is possible (see test55). */ 15612 clear_tv(&functv); 15613 15614 /* Stop the expression evaluation when immediately aborting on 15615 * error, or when an interrupt occurred or an exception was thrown 15616 * but not caught. */ 15617 if (aborting()) 15618 { 15619 if (ret == OK) 15620 clear_tv(rettv); 15621 ret = FAIL; 15622 } 15623 dict_unref(selfdict); 15624 selfdict = NULL; 15625 } 15626 else /* **arg == '[' || **arg == '.' */ 15627 { 15628 dict_unref(selfdict); 15629 if (rettv->v_type == VAR_DICT) 15630 { 15631 selfdict = rettv->vval.v_dict; 15632 if (selfdict != NULL) 15633 ++selfdict->dv_refcount; 15634 } 15635 else 15636 selfdict = NULL; 15637 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15638 { 15639 clear_tv(rettv); 15640 ret = FAIL; 15641 } 15642 } 15643 } 15644 dict_unref(selfdict); 15645 return ret; 15646 } 15647 15648 /* 15649 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15650 * value). 15651 */ 15652 static typval_T * 15653 alloc_tv() 15654 { 15655 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15656 } 15657 15658 /* 15659 * Allocate memory for a variable type-value, and assign a string to it. 15660 * The string "s" must have been allocated, it is consumed. 15661 * Return NULL for out of memory, the variable otherwise. 15662 */ 15663 static typval_T * 15664 alloc_string_tv(s) 15665 char_u *s; 15666 { 15667 typval_T *rettv; 15668 15669 rettv = alloc_tv(); 15670 if (rettv != NULL) 15671 { 15672 rettv->v_type = VAR_STRING; 15673 rettv->vval.v_string = s; 15674 } 15675 else 15676 vim_free(s); 15677 return rettv; 15678 } 15679 15680 /* 15681 * Free the memory for a variable type-value. 15682 */ 15683 static void 15684 free_tv(varp) 15685 typval_T *varp; 15686 { 15687 if (varp != NULL) 15688 { 15689 switch (varp->v_type) 15690 { 15691 case VAR_FUNC: 15692 func_unref(varp->vval.v_string); 15693 /*FALLTHROUGH*/ 15694 case VAR_STRING: 15695 vim_free(varp->vval.v_string); 15696 break; 15697 case VAR_LIST: 15698 list_unref(varp->vval.v_list); 15699 break; 15700 case VAR_DICT: 15701 dict_unref(varp->vval.v_dict); 15702 break; 15703 case VAR_NUMBER: 15704 case VAR_UNKNOWN: 15705 break; 15706 default: 15707 EMSG2(_(e_intern2), "free_tv()"); 15708 break; 15709 } 15710 vim_free(varp); 15711 } 15712 } 15713 15714 /* 15715 * Free the memory for a variable value and set the value to NULL or 0. 15716 */ 15717 void 15718 clear_tv(varp) 15719 typval_T *varp; 15720 { 15721 if (varp != NULL) 15722 { 15723 switch (varp->v_type) 15724 { 15725 case VAR_FUNC: 15726 func_unref(varp->vval.v_string); 15727 /*FALLTHROUGH*/ 15728 case VAR_STRING: 15729 vim_free(varp->vval.v_string); 15730 varp->vval.v_string = NULL; 15731 break; 15732 case VAR_LIST: 15733 list_unref(varp->vval.v_list); 15734 varp->vval.v_list = NULL; 15735 break; 15736 case VAR_DICT: 15737 dict_unref(varp->vval.v_dict); 15738 varp->vval.v_dict = NULL; 15739 break; 15740 case VAR_NUMBER: 15741 varp->vval.v_number = 0; 15742 break; 15743 case VAR_UNKNOWN: 15744 break; 15745 default: 15746 EMSG2(_(e_intern2), "clear_tv()"); 15747 } 15748 varp->v_lock = 0; 15749 } 15750 } 15751 15752 /* 15753 * Set the value of a variable to NULL without freeing items. 15754 */ 15755 static void 15756 init_tv(varp) 15757 typval_T *varp; 15758 { 15759 if (varp != NULL) 15760 vim_memset(varp, 0, sizeof(typval_T)); 15761 } 15762 15763 /* 15764 * Get the number value of a variable. 15765 * If it is a String variable, uses vim_str2nr(). 15766 * For incompatible types, return 0. 15767 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15768 * caller of incompatible types: it sets *denote to TRUE if "denote" 15769 * is not NULL or returns -1 otherwise. 15770 */ 15771 static long 15772 get_tv_number(varp) 15773 typval_T *varp; 15774 { 15775 int error = FALSE; 15776 15777 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15778 } 15779 15780 long 15781 get_tv_number_chk(varp, denote) 15782 typval_T *varp; 15783 int *denote; 15784 { 15785 long n = 0L; 15786 15787 switch (varp->v_type) 15788 { 15789 case VAR_NUMBER: 15790 return (long)(varp->vval.v_number); 15791 case VAR_FUNC: 15792 EMSG(_("E703: Using a Funcref as a number")); 15793 break; 15794 case VAR_STRING: 15795 if (varp->vval.v_string != NULL) 15796 vim_str2nr(varp->vval.v_string, NULL, NULL, 15797 TRUE, TRUE, &n, NULL); 15798 return n; 15799 case VAR_LIST: 15800 EMSG(_("E745: Using a List as a number")); 15801 break; 15802 case VAR_DICT: 15803 EMSG(_("E728: Using a Dictionary as a number")); 15804 break; 15805 default: 15806 EMSG2(_(e_intern2), "get_tv_number()"); 15807 break; 15808 } 15809 if (denote == NULL) /* useful for values that must be unsigned */ 15810 n = -1; 15811 else 15812 *denote = TRUE; 15813 return n; 15814 } 15815 15816 /* 15817 * Get the lnum from the first argument. 15818 * Also accepts ".", "$", etc., but that only works for the current buffer. 15819 * Returns -1 on error. 15820 */ 15821 static linenr_T 15822 get_tv_lnum(argvars) 15823 typval_T *argvars; 15824 { 15825 typval_T rettv; 15826 linenr_T lnum; 15827 15828 lnum = get_tv_number_chk(&argvars[0], NULL); 15829 if (lnum == 0) /* no valid number, try using line() */ 15830 { 15831 rettv.v_type = VAR_NUMBER; 15832 f_line(argvars, &rettv); 15833 lnum = rettv.vval.v_number; 15834 clear_tv(&rettv); 15835 } 15836 return lnum; 15837 } 15838 15839 /* 15840 * Get the lnum from the first argument. 15841 * Also accepts "$", then "buf" is used. 15842 * Returns 0 on error. 15843 */ 15844 static linenr_T 15845 get_tv_lnum_buf(argvars, buf) 15846 typval_T *argvars; 15847 buf_T *buf; 15848 { 15849 if (argvars[0].v_type == VAR_STRING 15850 && argvars[0].vval.v_string != NULL 15851 && argvars[0].vval.v_string[0] == '$' 15852 && buf != NULL) 15853 return buf->b_ml.ml_line_count; 15854 return get_tv_number_chk(&argvars[0], NULL); 15855 } 15856 15857 /* 15858 * Get the string value of a variable. 15859 * If it is a Number variable, the number is converted into a string. 15860 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 15861 * get_tv_string_buf() uses a given buffer. 15862 * If the String variable has never been set, return an empty string. 15863 * Never returns NULL; 15864 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 15865 * NULL on error. 15866 */ 15867 static char_u * 15868 get_tv_string(varp) 15869 typval_T *varp; 15870 { 15871 static char_u mybuf[NUMBUFLEN]; 15872 15873 return get_tv_string_buf(varp, mybuf); 15874 } 15875 15876 static char_u * 15877 get_tv_string_buf(varp, buf) 15878 typval_T *varp; 15879 char_u *buf; 15880 { 15881 char_u *res = get_tv_string_buf_chk(varp, buf); 15882 15883 return res != NULL ? res : (char_u *)""; 15884 } 15885 15886 char_u * 15887 get_tv_string_chk(varp) 15888 typval_T *varp; 15889 { 15890 static char_u mybuf[NUMBUFLEN]; 15891 15892 return get_tv_string_buf_chk(varp, mybuf); 15893 } 15894 15895 static char_u * 15896 get_tv_string_buf_chk(varp, buf) 15897 typval_T *varp; 15898 char_u *buf; 15899 { 15900 switch (varp->v_type) 15901 { 15902 case VAR_NUMBER: 15903 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 15904 return buf; 15905 case VAR_FUNC: 15906 EMSG(_("E729: using Funcref as a String")); 15907 break; 15908 case VAR_LIST: 15909 EMSG(_("E730: using List as a String")); 15910 break; 15911 case VAR_DICT: 15912 EMSG(_("E731: using Dictionary as a String")); 15913 break; 15914 case VAR_STRING: 15915 if (varp->vval.v_string != NULL) 15916 return varp->vval.v_string; 15917 return (char_u *)""; 15918 default: 15919 EMSG2(_(e_intern2), "get_tv_string_buf()"); 15920 break; 15921 } 15922 return NULL; 15923 } 15924 15925 /* 15926 * Find variable "name" in the list of variables. 15927 * Return a pointer to it if found, NULL if not found. 15928 * Careful: "a:0" variables don't have a name. 15929 * When "htp" is not NULL we are writing to the variable, set "htp" to the 15930 * hashtab_T used. 15931 */ 15932 static dictitem_T * 15933 find_var(name, htp) 15934 char_u *name; 15935 hashtab_T **htp; 15936 { 15937 char_u *varname; 15938 hashtab_T *ht; 15939 15940 ht = find_var_ht(name, &varname); 15941 if (htp != NULL) 15942 *htp = ht; 15943 if (ht == NULL) 15944 return NULL; 15945 return find_var_in_ht(ht, varname, htp != NULL); 15946 } 15947 15948 /* 15949 * Find variable "varname" in hashtab "ht". 15950 * Returns NULL if not found. 15951 */ 15952 static dictitem_T * 15953 find_var_in_ht(ht, varname, writing) 15954 hashtab_T *ht; 15955 char_u *varname; 15956 int writing; 15957 { 15958 hashitem_T *hi; 15959 15960 if (*varname == NUL) 15961 { 15962 /* Must be something like "s:", otherwise "ht" would be NULL. */ 15963 switch (varname[-2]) 15964 { 15965 case 's': return &SCRIPT_SV(current_SID).sv_var; 15966 case 'g': return &globvars_var; 15967 case 'v': return &vimvars_var; 15968 case 'b': return &curbuf->b_bufvar; 15969 case 'w': return &curwin->w_winvar; 15970 case 'l': return current_funccal == NULL 15971 ? NULL : ¤t_funccal->l_vars_var; 15972 case 'a': return current_funccal == NULL 15973 ? NULL : ¤t_funccal->l_avars_var; 15974 } 15975 return NULL; 15976 } 15977 15978 hi = hash_find(ht, varname); 15979 if (HASHITEM_EMPTY(hi)) 15980 { 15981 /* For global variables we may try auto-loading the script. If it 15982 * worked find the variable again. Don't auto-load a script if it was 15983 * loaded already, otherwise it would be loaded every time when 15984 * checking if a function name is a Funcref variable. */ 15985 if (ht == &globvarht && !writing 15986 && script_autoload(varname, FALSE) && !aborting()) 15987 hi = hash_find(ht, varname); 15988 if (HASHITEM_EMPTY(hi)) 15989 return NULL; 15990 } 15991 return HI2DI(hi); 15992 } 15993 15994 /* 15995 * Find the hashtab used for a variable name. 15996 * Set "varname" to the start of name without ':'. 15997 */ 15998 static hashtab_T * 15999 find_var_ht(name, varname) 16000 char_u *name; 16001 char_u **varname; 16002 { 16003 hashitem_T *hi; 16004 16005 if (name[1] != ':') 16006 { 16007 /* The name must not start with a colon or #. */ 16008 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16009 return NULL; 16010 *varname = name; 16011 16012 /* "version" is "v:version" in all scopes */ 16013 hi = hash_find(&compat_hashtab, name); 16014 if (!HASHITEM_EMPTY(hi)) 16015 return &compat_hashtab; 16016 16017 if (current_funccal == NULL) 16018 return &globvarht; /* global variable */ 16019 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16020 } 16021 *varname = name + 2; 16022 if (*name == 'g') /* global variable */ 16023 return &globvarht; 16024 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16025 */ 16026 if (vim_strchr(name + 2, ':') != NULL 16027 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16028 return NULL; 16029 if (*name == 'b') /* buffer variable */ 16030 return &curbuf->b_vars.dv_hashtab; 16031 if (*name == 'w') /* window variable */ 16032 return &curwin->w_vars.dv_hashtab; 16033 if (*name == 'v') /* v: variable */ 16034 return &vimvarht; 16035 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16036 return ¤t_funccal->l_avars.dv_hashtab; 16037 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16038 return ¤t_funccal->l_vars.dv_hashtab; 16039 if (*name == 's' /* script variable */ 16040 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16041 return &SCRIPT_VARS(current_SID); 16042 return NULL; 16043 } 16044 16045 /* 16046 * Get the string value of a (global/local) variable. 16047 * Returns NULL when it doesn't exist. 16048 */ 16049 char_u * 16050 get_var_value(name) 16051 char_u *name; 16052 { 16053 dictitem_T *v; 16054 16055 v = find_var(name, NULL); 16056 if (v == NULL) 16057 return NULL; 16058 return get_tv_string(&v->di_tv); 16059 } 16060 16061 /* 16062 * Allocate a new hashtab for a sourced script. It will be used while 16063 * sourcing this script and when executing functions defined in the script. 16064 */ 16065 void 16066 new_script_vars(id) 16067 scid_T id; 16068 { 16069 int i; 16070 hashtab_T *ht; 16071 scriptvar_T *sv; 16072 16073 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16074 { 16075 /* Re-allocating ga_data means that an ht_array pointing to 16076 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16077 * at its init value. Also reset "v_dict", it's always the same. */ 16078 for (i = 1; i <= ga_scripts.ga_len; ++i) 16079 { 16080 ht = &SCRIPT_VARS(i); 16081 if (ht->ht_mask == HT_INIT_SIZE - 1) 16082 ht->ht_array = ht->ht_smallarray; 16083 sv = &SCRIPT_SV(i); 16084 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16085 } 16086 16087 while (ga_scripts.ga_len < id) 16088 { 16089 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16090 init_var_dict(&sv->sv_dict, &sv->sv_var); 16091 ++ga_scripts.ga_len; 16092 } 16093 } 16094 } 16095 16096 /* 16097 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16098 * point to it. 16099 */ 16100 void 16101 init_var_dict(dict, dict_var) 16102 dict_T *dict; 16103 dictitem_T *dict_var; 16104 { 16105 hash_init(&dict->dv_hashtab); 16106 dict->dv_refcount = 99999; 16107 dict_var->di_tv.vval.v_dict = dict; 16108 dict_var->di_tv.v_type = VAR_DICT; 16109 dict_var->di_tv.v_lock = VAR_FIXED; 16110 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16111 dict_var->di_key[0] = NUL; 16112 } 16113 16114 /* 16115 * Clean up a list of internal variables. 16116 * Frees all allocated variables and the value they contain. 16117 * Clears hashtab "ht", does not free it. 16118 */ 16119 void 16120 vars_clear(ht) 16121 hashtab_T *ht; 16122 { 16123 vars_clear_ext(ht, TRUE); 16124 } 16125 16126 /* 16127 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16128 */ 16129 static void 16130 vars_clear_ext(ht, free_val) 16131 hashtab_T *ht; 16132 int free_val; 16133 { 16134 int todo; 16135 hashitem_T *hi; 16136 dictitem_T *v; 16137 16138 hash_lock(ht); 16139 todo = ht->ht_used; 16140 for (hi = ht->ht_array; todo > 0; ++hi) 16141 { 16142 if (!HASHITEM_EMPTY(hi)) 16143 { 16144 --todo; 16145 16146 /* Free the variable. Don't remove it from the hashtab, 16147 * ht_array might change then. hash_clear() takes care of it 16148 * later. */ 16149 v = HI2DI(hi); 16150 if (free_val) 16151 clear_tv(&v->di_tv); 16152 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16153 vim_free(v); 16154 } 16155 } 16156 hash_clear(ht); 16157 ht->ht_used = 0; 16158 } 16159 16160 /* 16161 * Delete a variable from hashtab "ht" at item "hi". 16162 * Clear the variable value and free the dictitem. 16163 */ 16164 static void 16165 delete_var(ht, hi) 16166 hashtab_T *ht; 16167 hashitem_T *hi; 16168 { 16169 dictitem_T *di = HI2DI(hi); 16170 16171 hash_remove(ht, hi); 16172 clear_tv(&di->di_tv); 16173 vim_free(di); 16174 } 16175 16176 /* 16177 * List the value of one internal variable. 16178 */ 16179 static void 16180 list_one_var(v, prefix) 16181 dictitem_T *v; 16182 char_u *prefix; 16183 { 16184 char_u *tofree; 16185 char_u *s; 16186 char_u numbuf[NUMBUFLEN]; 16187 16188 s = echo_string(&v->di_tv, &tofree, numbuf); 16189 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16190 s == NULL ? (char_u *)"" : s); 16191 vim_free(tofree); 16192 } 16193 16194 static void 16195 list_one_var_a(prefix, name, type, string) 16196 char_u *prefix; 16197 char_u *name; 16198 int type; 16199 char_u *string; 16200 { 16201 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16202 if (name != NULL) /* "a:" vars don't have a name stored */ 16203 msg_puts(name); 16204 msg_putchar(' '); 16205 msg_advance(22); 16206 if (type == VAR_NUMBER) 16207 msg_putchar('#'); 16208 else if (type == VAR_FUNC) 16209 msg_putchar('*'); 16210 else if (type == VAR_LIST) 16211 { 16212 msg_putchar('['); 16213 if (*string == '[') 16214 ++string; 16215 } 16216 else if (type == VAR_DICT) 16217 { 16218 msg_putchar('{'); 16219 if (*string == '{') 16220 ++string; 16221 } 16222 else 16223 msg_putchar(' '); 16224 16225 msg_outtrans(string); 16226 16227 if (type == VAR_FUNC) 16228 msg_puts((char_u *)"()"); 16229 } 16230 16231 /* 16232 * Set variable "name" to value in "tv". 16233 * If the variable already exists, the value is updated. 16234 * Otherwise the variable is created. 16235 */ 16236 static void 16237 set_var(name, tv, copy) 16238 char_u *name; 16239 typval_T *tv; 16240 int copy; /* make copy of value in "tv" */ 16241 { 16242 dictitem_T *v; 16243 char_u *varname; 16244 hashtab_T *ht; 16245 char_u *p; 16246 16247 if (tv->v_type == VAR_FUNC) 16248 { 16249 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16250 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16251 ? name[2] : name[0])) 16252 { 16253 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16254 return; 16255 } 16256 if (function_exists(name)) 16257 { 16258 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16259 name); 16260 return; 16261 } 16262 } 16263 16264 ht = find_var_ht(name, &varname); 16265 if (ht == NULL || *varname == NUL) 16266 { 16267 EMSG2(_(e_illvar), name); 16268 return; 16269 } 16270 16271 v = find_var_in_ht(ht, varname, TRUE); 16272 if (v != NULL) 16273 { 16274 /* existing variable, need to clear the value */ 16275 if (var_check_ro(v->di_flags, name) 16276 || tv_check_lock(v->di_tv.v_lock, name)) 16277 return; 16278 if (v->di_tv.v_type != tv->v_type 16279 && !((v->di_tv.v_type == VAR_STRING 16280 || v->di_tv.v_type == VAR_NUMBER) 16281 && (tv->v_type == VAR_STRING 16282 || tv->v_type == VAR_NUMBER))) 16283 { 16284 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16285 return; 16286 } 16287 16288 /* 16289 * Handle setting internal v: variables separately: we don't change 16290 * the type. 16291 */ 16292 if (ht == &vimvarht) 16293 { 16294 if (v->di_tv.v_type == VAR_STRING) 16295 { 16296 vim_free(v->di_tv.vval.v_string); 16297 if (copy || tv->v_type != VAR_STRING) 16298 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16299 else 16300 { 16301 /* Take over the string to avoid an extra alloc/free. */ 16302 v->di_tv.vval.v_string = tv->vval.v_string; 16303 tv->vval.v_string = NULL; 16304 } 16305 } 16306 else if (v->di_tv.v_type != VAR_NUMBER) 16307 EMSG2(_(e_intern2), "set_var()"); 16308 else 16309 v->di_tv.vval.v_number = get_tv_number(tv); 16310 return; 16311 } 16312 16313 clear_tv(&v->di_tv); 16314 } 16315 else /* add a new variable */ 16316 { 16317 /* Make sure the variable name is valid. */ 16318 for (p = varname; *p != NUL; ++p) 16319 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16320 { 16321 EMSG2(_(e_illvar), varname); 16322 return; 16323 } 16324 16325 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16326 + STRLEN(varname))); 16327 if (v == NULL) 16328 return; 16329 STRCPY(v->di_key, varname); 16330 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16331 { 16332 vim_free(v); 16333 return; 16334 } 16335 v->di_flags = 0; 16336 } 16337 16338 if (copy || tv->v_type == VAR_NUMBER) 16339 copy_tv(tv, &v->di_tv); 16340 else 16341 { 16342 v->di_tv = *tv; 16343 v->di_tv.v_lock = 0; 16344 init_tv(tv); 16345 } 16346 } 16347 16348 /* 16349 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16350 * Also give an error message. 16351 */ 16352 static int 16353 var_check_ro(flags, name) 16354 int flags; 16355 char_u *name; 16356 { 16357 if (flags & DI_FLAGS_RO) 16358 { 16359 EMSG2(_(e_readonlyvar), name); 16360 return TRUE; 16361 } 16362 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16363 { 16364 EMSG2(_(e_readonlysbx), name); 16365 return TRUE; 16366 } 16367 return FALSE; 16368 } 16369 16370 /* 16371 * Return TRUE if typeval "tv" is set to be locked (immutable). 16372 * Also give an error message, using "name". 16373 */ 16374 static int 16375 tv_check_lock(lock, name) 16376 int lock; 16377 char_u *name; 16378 { 16379 if (lock & VAR_LOCKED) 16380 { 16381 EMSG2(_("E741: Value is locked: %s"), 16382 name == NULL ? (char_u *)_("Unknown") : name); 16383 return TRUE; 16384 } 16385 if (lock & VAR_FIXED) 16386 { 16387 EMSG2(_("E742: Cannot change value of %s"), 16388 name == NULL ? (char_u *)_("Unknown") : name); 16389 return TRUE; 16390 } 16391 return FALSE; 16392 } 16393 16394 /* 16395 * Copy the values from typval_T "from" to typval_T "to". 16396 * When needed allocates string or increases reference count. 16397 * Does not make a copy of a list or dict but copies the reference! 16398 */ 16399 static void 16400 copy_tv(from, to) 16401 typval_T *from; 16402 typval_T *to; 16403 { 16404 to->v_type = from->v_type; 16405 to->v_lock = 0; 16406 switch (from->v_type) 16407 { 16408 case VAR_NUMBER: 16409 to->vval.v_number = from->vval.v_number; 16410 break; 16411 case VAR_STRING: 16412 case VAR_FUNC: 16413 if (from->vval.v_string == NULL) 16414 to->vval.v_string = NULL; 16415 else 16416 { 16417 to->vval.v_string = vim_strsave(from->vval.v_string); 16418 if (from->v_type == VAR_FUNC) 16419 func_ref(to->vval.v_string); 16420 } 16421 break; 16422 case VAR_LIST: 16423 if (from->vval.v_list == NULL) 16424 to->vval.v_list = NULL; 16425 else 16426 { 16427 to->vval.v_list = from->vval.v_list; 16428 ++to->vval.v_list->lv_refcount; 16429 } 16430 break; 16431 case VAR_DICT: 16432 if (from->vval.v_dict == NULL) 16433 to->vval.v_dict = NULL; 16434 else 16435 { 16436 to->vval.v_dict = from->vval.v_dict; 16437 ++to->vval.v_dict->dv_refcount; 16438 } 16439 break; 16440 default: 16441 EMSG2(_(e_intern2), "copy_tv()"); 16442 break; 16443 } 16444 } 16445 16446 /* 16447 * Make a copy of an item. 16448 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16449 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16450 * reference to an already copied list/dict can be used. 16451 * Returns FAIL or OK. 16452 */ 16453 static int 16454 item_copy(from, to, deep, copyID) 16455 typval_T *from; 16456 typval_T *to; 16457 int deep; 16458 int copyID; 16459 { 16460 static int recurse = 0; 16461 int ret = OK; 16462 16463 if (recurse >= DICT_MAXNEST) 16464 { 16465 EMSG(_("E698: variable nested too deep for making a copy")); 16466 return FAIL; 16467 } 16468 ++recurse; 16469 16470 switch (from->v_type) 16471 { 16472 case VAR_NUMBER: 16473 case VAR_STRING: 16474 case VAR_FUNC: 16475 copy_tv(from, to); 16476 break; 16477 case VAR_LIST: 16478 to->v_type = VAR_LIST; 16479 to->v_lock = 0; 16480 if (from->vval.v_list == NULL) 16481 to->vval.v_list = NULL; 16482 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16483 { 16484 /* use the copy made earlier */ 16485 to->vval.v_list = from->vval.v_list->lv_copylist; 16486 ++to->vval.v_list->lv_refcount; 16487 } 16488 else 16489 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16490 if (to->vval.v_list == NULL) 16491 ret = FAIL; 16492 break; 16493 case VAR_DICT: 16494 to->v_type = VAR_DICT; 16495 to->v_lock = 0; 16496 if (from->vval.v_dict == NULL) 16497 to->vval.v_dict = NULL; 16498 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16499 { 16500 /* use the copy made earlier */ 16501 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16502 ++to->vval.v_dict->dv_refcount; 16503 } 16504 else 16505 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16506 if (to->vval.v_dict == NULL) 16507 ret = FAIL; 16508 break; 16509 default: 16510 EMSG2(_(e_intern2), "item_copy()"); 16511 ret = FAIL; 16512 } 16513 --recurse; 16514 return ret; 16515 } 16516 16517 /* 16518 * ":echo expr1 ..." print each argument separated with a space, add a 16519 * newline at the end. 16520 * ":echon expr1 ..." print each argument plain. 16521 */ 16522 void 16523 ex_echo(eap) 16524 exarg_T *eap; 16525 { 16526 char_u *arg = eap->arg; 16527 typval_T rettv; 16528 char_u *tofree; 16529 char_u *p; 16530 int needclr = TRUE; 16531 int atstart = TRUE; 16532 char_u numbuf[NUMBUFLEN]; 16533 16534 if (eap->skip) 16535 ++emsg_skip; 16536 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16537 { 16538 p = arg; 16539 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16540 { 16541 /* 16542 * Report the invalid expression unless the expression evaluation 16543 * has been cancelled due to an aborting error, an interrupt, or an 16544 * exception. 16545 */ 16546 if (!aborting()) 16547 EMSG2(_(e_invexpr2), p); 16548 break; 16549 } 16550 if (!eap->skip) 16551 { 16552 if (atstart) 16553 { 16554 atstart = FALSE; 16555 /* Call msg_start() after eval1(), evaluating the expression 16556 * may cause a message to appear. */ 16557 if (eap->cmdidx == CMD_echo) 16558 msg_start(); 16559 } 16560 else if (eap->cmdidx == CMD_echo) 16561 msg_puts_attr((char_u *)" ", echo_attr); 16562 p = echo_string(&rettv, &tofree, numbuf); 16563 if (p != NULL) 16564 for ( ; *p != NUL && !got_int; ++p) 16565 { 16566 if (*p == '\n' || *p == '\r' || *p == TAB) 16567 { 16568 if (*p != TAB && needclr) 16569 { 16570 /* remove any text still there from the command */ 16571 msg_clr_eos(); 16572 needclr = FALSE; 16573 } 16574 msg_putchar_attr(*p, echo_attr); 16575 } 16576 else 16577 { 16578 #ifdef FEAT_MBYTE 16579 if (has_mbyte) 16580 { 16581 int i = (*mb_ptr2len)(p); 16582 16583 (void)msg_outtrans_len_attr(p, i, echo_attr); 16584 p += i - 1; 16585 } 16586 else 16587 #endif 16588 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16589 } 16590 } 16591 vim_free(tofree); 16592 } 16593 clear_tv(&rettv); 16594 arg = skipwhite(arg); 16595 } 16596 eap->nextcmd = check_nextcmd(arg); 16597 16598 if (eap->skip) 16599 --emsg_skip; 16600 else 16601 { 16602 /* remove text that may still be there from the command */ 16603 if (needclr) 16604 msg_clr_eos(); 16605 if (eap->cmdidx == CMD_echo) 16606 msg_end(); 16607 } 16608 } 16609 16610 /* 16611 * ":echohl {name}". 16612 */ 16613 void 16614 ex_echohl(eap) 16615 exarg_T *eap; 16616 { 16617 int id; 16618 16619 id = syn_name2id(eap->arg); 16620 if (id == 0) 16621 echo_attr = 0; 16622 else 16623 echo_attr = syn_id2attr(id); 16624 } 16625 16626 /* 16627 * ":execute expr1 ..." execute the result of an expression. 16628 * ":echomsg expr1 ..." Print a message 16629 * ":echoerr expr1 ..." Print an error 16630 * Each gets spaces around each argument and a newline at the end for 16631 * echo commands 16632 */ 16633 void 16634 ex_execute(eap) 16635 exarg_T *eap; 16636 { 16637 char_u *arg = eap->arg; 16638 typval_T rettv; 16639 int ret = OK; 16640 char_u *p; 16641 garray_T ga; 16642 int len; 16643 int save_did_emsg; 16644 16645 ga_init2(&ga, 1, 80); 16646 16647 if (eap->skip) 16648 ++emsg_skip; 16649 while (*arg != NUL && *arg != '|' && *arg != '\n') 16650 { 16651 p = arg; 16652 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16653 { 16654 /* 16655 * Report the invalid expression unless the expression evaluation 16656 * has been cancelled due to an aborting error, an interrupt, or an 16657 * exception. 16658 */ 16659 if (!aborting()) 16660 EMSG2(_(e_invexpr2), p); 16661 ret = FAIL; 16662 break; 16663 } 16664 16665 if (!eap->skip) 16666 { 16667 p = get_tv_string(&rettv); 16668 len = (int)STRLEN(p); 16669 if (ga_grow(&ga, len + 2) == FAIL) 16670 { 16671 clear_tv(&rettv); 16672 ret = FAIL; 16673 break; 16674 } 16675 if (ga.ga_len) 16676 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16677 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16678 ga.ga_len += len; 16679 } 16680 16681 clear_tv(&rettv); 16682 arg = skipwhite(arg); 16683 } 16684 16685 if (ret != FAIL && ga.ga_data != NULL) 16686 { 16687 if (eap->cmdidx == CMD_echomsg) 16688 MSG_ATTR(ga.ga_data, echo_attr); 16689 else if (eap->cmdidx == CMD_echoerr) 16690 { 16691 /* We don't want to abort following commands, restore did_emsg. */ 16692 save_did_emsg = did_emsg; 16693 EMSG((char_u *)ga.ga_data); 16694 if (!force_abort) 16695 did_emsg = save_did_emsg; 16696 } 16697 else if (eap->cmdidx == CMD_execute) 16698 do_cmdline((char_u *)ga.ga_data, 16699 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16700 } 16701 16702 ga_clear(&ga); 16703 16704 if (eap->skip) 16705 --emsg_skip; 16706 16707 eap->nextcmd = check_nextcmd(arg); 16708 } 16709 16710 /* 16711 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16712 * "arg" points to the "&" or '+' when called, to "option" when returning. 16713 * Returns NULL when no option name found. Otherwise pointer to the char 16714 * after the option name. 16715 */ 16716 static char_u * 16717 find_option_end(arg, opt_flags) 16718 char_u **arg; 16719 int *opt_flags; 16720 { 16721 char_u *p = *arg; 16722 16723 ++p; 16724 if (*p == 'g' && p[1] == ':') 16725 { 16726 *opt_flags = OPT_GLOBAL; 16727 p += 2; 16728 } 16729 else if (*p == 'l' && p[1] == ':') 16730 { 16731 *opt_flags = OPT_LOCAL; 16732 p += 2; 16733 } 16734 else 16735 *opt_flags = 0; 16736 16737 if (!ASCII_ISALPHA(*p)) 16738 return NULL; 16739 *arg = p; 16740 16741 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16742 p += 4; /* termcap option */ 16743 else 16744 while (ASCII_ISALPHA(*p)) 16745 ++p; 16746 return p; 16747 } 16748 16749 /* 16750 * ":function" 16751 */ 16752 void 16753 ex_function(eap) 16754 exarg_T *eap; 16755 { 16756 char_u *theline; 16757 int j; 16758 int c; 16759 int saved_did_emsg; 16760 char_u *name = NULL; 16761 char_u *p; 16762 char_u *arg; 16763 garray_T newargs; 16764 garray_T newlines; 16765 int varargs = FALSE; 16766 int mustend = FALSE; 16767 int flags = 0; 16768 ufunc_T *fp; 16769 int indent; 16770 int nesting; 16771 char_u *skip_until = NULL; 16772 dictitem_T *v; 16773 funcdict_T fudi; 16774 static int func_nr = 0; /* number for nameless function */ 16775 int paren; 16776 hashtab_T *ht; 16777 int todo; 16778 hashitem_T *hi; 16779 16780 /* 16781 * ":function" without argument: list functions. 16782 */ 16783 if (ends_excmd(*eap->arg)) 16784 { 16785 if (!eap->skip) 16786 { 16787 todo = func_hashtab.ht_used; 16788 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16789 { 16790 if (!HASHITEM_EMPTY(hi)) 16791 { 16792 --todo; 16793 fp = HI2UF(hi); 16794 if (!isdigit(*fp->uf_name)) 16795 list_func_head(fp, FALSE); 16796 } 16797 } 16798 } 16799 eap->nextcmd = check_nextcmd(eap->arg); 16800 return; 16801 } 16802 16803 /* 16804 * Get the function name. There are these situations: 16805 * func normal function name 16806 * "name" == func, "fudi.fd_dict" == NULL 16807 * dict.func new dictionary entry 16808 * "name" == NULL, "fudi.fd_dict" set, 16809 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 16810 * dict.func existing dict entry with a Funcref 16811 * "name" == func, "fudi.fd_dict" set, 16812 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16813 * dict.func existing dict entry that's not a Funcref 16814 * "name" == NULL, "fudi.fd_dict" set, 16815 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16816 */ 16817 p = eap->arg; 16818 name = trans_function_name(&p, eap->skip, 0, &fudi); 16819 paren = (vim_strchr(p, '(') != NULL); 16820 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 16821 { 16822 /* 16823 * Return on an invalid expression in braces, unless the expression 16824 * evaluation has been cancelled due to an aborting error, an 16825 * interrupt, or an exception. 16826 */ 16827 if (!aborting()) 16828 { 16829 if (!eap->skip && fudi.fd_newkey != NULL) 16830 EMSG2(_(e_dictkey), fudi.fd_newkey); 16831 vim_free(fudi.fd_newkey); 16832 return; 16833 } 16834 else 16835 eap->skip = TRUE; 16836 } 16837 /* An error in a function call during evaluation of an expression in magic 16838 * braces should not cause the function not to be defined. */ 16839 saved_did_emsg = did_emsg; 16840 did_emsg = FALSE; 16841 16842 /* 16843 * ":function func" with only function name: list function. 16844 */ 16845 if (!paren) 16846 { 16847 if (!ends_excmd(*skipwhite(p))) 16848 { 16849 EMSG(_(e_trailing)); 16850 goto ret_free; 16851 } 16852 eap->nextcmd = check_nextcmd(p); 16853 if (eap->nextcmd != NULL) 16854 *p = NUL; 16855 if (!eap->skip && !got_int) 16856 { 16857 fp = find_func(name); 16858 if (fp != NULL) 16859 { 16860 list_func_head(fp, TRUE); 16861 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 16862 { 16863 msg_putchar('\n'); 16864 msg_outnum((long)(j + 1)); 16865 if (j < 9) 16866 msg_putchar(' '); 16867 if (j < 99) 16868 msg_putchar(' '); 16869 msg_prt_line(FUNCLINE(fp, j), FALSE); 16870 out_flush(); /* show a line at a time */ 16871 ui_breakcheck(); 16872 } 16873 if (!got_int) 16874 { 16875 msg_putchar('\n'); 16876 msg_puts((char_u *)" endfunction"); 16877 } 16878 } 16879 else 16880 emsg_funcname("E123: Undefined function: %s", name); 16881 } 16882 goto ret_free; 16883 } 16884 16885 /* 16886 * ":function name(arg1, arg2)" Define function. 16887 */ 16888 p = skipwhite(p); 16889 if (*p != '(') 16890 { 16891 if (!eap->skip) 16892 { 16893 EMSG2(_("E124: Missing '(': %s"), eap->arg); 16894 goto ret_free; 16895 } 16896 /* attempt to continue by skipping some text */ 16897 if (vim_strchr(p, '(') != NULL) 16898 p = vim_strchr(p, '('); 16899 } 16900 p = skipwhite(p + 1); 16901 16902 ga_init2(&newargs, (int)sizeof(char_u *), 3); 16903 ga_init2(&newlines, (int)sizeof(char_u *), 3); 16904 16905 if (!eap->skip) 16906 { 16907 /* Check the name of the function. */ 16908 if (name != NULL) 16909 arg = name; 16910 else 16911 arg = fudi.fd_newkey; 16912 if (arg != NULL) 16913 { 16914 if (*arg == K_SPECIAL) 16915 j = 3; 16916 else 16917 j = 0; 16918 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 16919 : eval_isnamec(arg[j]))) 16920 ++j; 16921 if (arg[j] != NUL) 16922 emsg_funcname(_(e_invarg2), arg); 16923 } 16924 } 16925 16926 /* 16927 * Isolate the arguments: "arg1, arg2, ...)" 16928 */ 16929 while (*p != ')') 16930 { 16931 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 16932 { 16933 varargs = TRUE; 16934 p += 3; 16935 mustend = TRUE; 16936 } 16937 else 16938 { 16939 arg = p; 16940 while (ASCII_ISALNUM(*p) || *p == '_') 16941 ++p; 16942 if (arg == p || isdigit(*arg) 16943 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 16944 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 16945 { 16946 if (!eap->skip) 16947 EMSG2(_("E125: Illegal argument: %s"), arg); 16948 break; 16949 } 16950 if (ga_grow(&newargs, 1) == FAIL) 16951 goto erret; 16952 c = *p; 16953 *p = NUL; 16954 arg = vim_strsave(arg); 16955 if (arg == NULL) 16956 goto erret; 16957 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 16958 *p = c; 16959 newargs.ga_len++; 16960 if (*p == ',') 16961 ++p; 16962 else 16963 mustend = TRUE; 16964 } 16965 p = skipwhite(p); 16966 if (mustend && *p != ')') 16967 { 16968 if (!eap->skip) 16969 EMSG2(_(e_invarg2), eap->arg); 16970 break; 16971 } 16972 } 16973 ++p; /* skip the ')' */ 16974 16975 /* find extra arguments "range", "dict" and "abort" */ 16976 for (;;) 16977 { 16978 p = skipwhite(p); 16979 if (STRNCMP(p, "range", 5) == 0) 16980 { 16981 flags |= FC_RANGE; 16982 p += 5; 16983 } 16984 else if (STRNCMP(p, "dict", 4) == 0) 16985 { 16986 flags |= FC_DICT; 16987 p += 4; 16988 } 16989 else if (STRNCMP(p, "abort", 5) == 0) 16990 { 16991 flags |= FC_ABORT; 16992 p += 5; 16993 } 16994 else 16995 break; 16996 } 16997 16998 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 16999 EMSG(_(e_trailing)); 17000 17001 /* 17002 * Read the body of the function, until ":endfunction" is found. 17003 */ 17004 if (KeyTyped) 17005 { 17006 /* Check if the function already exists, don't let the user type the 17007 * whole function before telling him it doesn't work! For a script we 17008 * need to skip the body to be able to find what follows. */ 17009 if (!eap->skip && !eap->forceit) 17010 { 17011 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 17012 EMSG(_(e_funcdict)); 17013 else if (name != NULL && find_func(name) != NULL) 17014 emsg_funcname(e_funcexts, name); 17015 } 17016 17017 if (!eap->skip && did_emsg) 17018 goto erret; 17019 17020 msg_putchar('\n'); /* don't overwrite the function name */ 17021 cmdline_row = msg_row; 17022 } 17023 17024 indent = 2; 17025 nesting = 0; 17026 for (;;) 17027 { 17028 msg_scroll = TRUE; 17029 need_wait_return = FALSE; 17030 if (eap->getline == NULL) 17031 theline = getcmdline(':', 0L, indent); 17032 else 17033 theline = eap->getline(':', eap->cookie, indent); 17034 if (KeyTyped) 17035 lines_left = Rows - 1; 17036 if (theline == NULL) 17037 { 17038 EMSG(_("E126: Missing :endfunction")); 17039 goto erret; 17040 } 17041 17042 if (skip_until != NULL) 17043 { 17044 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17045 * don't check for ":endfunc". */ 17046 if (STRCMP(theline, skip_until) == 0) 17047 { 17048 vim_free(skip_until); 17049 skip_until = NULL; 17050 } 17051 } 17052 else 17053 { 17054 /* skip ':' and blanks*/ 17055 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17056 ; 17057 17058 /* Check for "endfunction". */ 17059 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17060 { 17061 vim_free(theline); 17062 break; 17063 } 17064 17065 /* Increase indent inside "if", "while", "for" and "try", decrease 17066 * at "end". */ 17067 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17068 indent -= 2; 17069 else if (STRNCMP(p, "if", 2) == 0 17070 || STRNCMP(p, "wh", 2) == 0 17071 || STRNCMP(p, "for", 3) == 0 17072 || STRNCMP(p, "try", 3) == 0) 17073 indent += 2; 17074 17075 /* Check for defining a function inside this function. */ 17076 if (checkforcmd(&p, "function", 2)) 17077 { 17078 if (*p == '!') 17079 p = skipwhite(p + 1); 17080 p += eval_fname_script(p); 17081 if (ASCII_ISALPHA(*p)) 17082 { 17083 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17084 if (*skipwhite(p) == '(') 17085 { 17086 ++nesting; 17087 indent += 2; 17088 } 17089 } 17090 } 17091 17092 /* Check for ":append" or ":insert". */ 17093 p = skip_range(p, NULL); 17094 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17095 || (p[0] == 'i' 17096 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17097 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17098 skip_until = vim_strsave((char_u *)"."); 17099 17100 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17101 arg = skipwhite(skiptowhite(p)); 17102 if (arg[0] == '<' && arg[1] =='<' 17103 && ((p[0] == 'p' && p[1] == 'y' 17104 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17105 || (p[0] == 'p' && p[1] == 'e' 17106 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17107 || (p[0] == 't' && p[1] == 'c' 17108 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17109 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17110 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17111 || (p[0] == 'm' && p[1] == 'z' 17112 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17113 )) 17114 { 17115 /* ":python <<" continues until a dot, like ":append" */ 17116 p = skipwhite(arg + 2); 17117 if (*p == NUL) 17118 skip_until = vim_strsave((char_u *)"."); 17119 else 17120 skip_until = vim_strsave(p); 17121 } 17122 } 17123 17124 /* Add the line to the function. */ 17125 if (ga_grow(&newlines, 1) == FAIL) 17126 { 17127 vim_free(theline); 17128 goto erret; 17129 } 17130 17131 /* Copy the line to newly allocated memory. get_one_sourceline() 17132 * allocates 250 bytes per line, this saves 80% on average. The cost 17133 * is an extra alloc/free. */ 17134 p = vim_strsave(theline); 17135 if (p != NULL) 17136 { 17137 vim_free(theline); 17138 theline = p; 17139 } 17140 17141 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17142 newlines.ga_len++; 17143 } 17144 17145 /* Don't define the function when skipping commands or when an error was 17146 * detected. */ 17147 if (eap->skip || did_emsg) 17148 goto erret; 17149 17150 /* 17151 * If there are no errors, add the function 17152 */ 17153 if (fudi.fd_dict == NULL) 17154 { 17155 v = find_var(name, &ht); 17156 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17157 { 17158 emsg_funcname("E707: Function name conflicts with variable: %s", 17159 name); 17160 goto erret; 17161 } 17162 17163 fp = find_func(name); 17164 if (fp != NULL) 17165 { 17166 if (!eap->forceit) 17167 { 17168 emsg_funcname(e_funcexts, name); 17169 goto erret; 17170 } 17171 if (fp->uf_calls > 0) 17172 { 17173 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17174 name); 17175 goto erret; 17176 } 17177 /* redefine existing function */ 17178 ga_clear_strings(&(fp->uf_args)); 17179 ga_clear_strings(&(fp->uf_lines)); 17180 vim_free(name); 17181 name = NULL; 17182 } 17183 } 17184 else 17185 { 17186 char numbuf[20]; 17187 17188 fp = NULL; 17189 if (fudi.fd_newkey == NULL && !eap->forceit) 17190 { 17191 EMSG(_(e_funcdict)); 17192 goto erret; 17193 } 17194 if (fudi.fd_di == NULL) 17195 { 17196 /* Can't add a function to a locked dictionary */ 17197 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17198 goto erret; 17199 } 17200 /* Can't change an existing function if it is locked */ 17201 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17202 goto erret; 17203 17204 /* Give the function a sequential number. Can only be used with a 17205 * Funcref! */ 17206 vim_free(name); 17207 sprintf(numbuf, "%d", ++func_nr); 17208 name = vim_strsave((char_u *)numbuf); 17209 if (name == NULL) 17210 goto erret; 17211 } 17212 17213 if (fp == NULL) 17214 { 17215 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17216 { 17217 int slen, plen; 17218 char_u *scriptname; 17219 17220 /* Check that the autoload name matches the script name. */ 17221 j = FAIL; 17222 if (sourcing_name != NULL) 17223 { 17224 scriptname = autoload_name(name); 17225 if (scriptname != NULL) 17226 { 17227 p = vim_strchr(scriptname, '/'); 17228 plen = STRLEN(p); 17229 slen = STRLEN(sourcing_name); 17230 if (slen > plen && fnamecmp(p, 17231 sourcing_name + slen - plen) == 0) 17232 j = OK; 17233 vim_free(scriptname); 17234 } 17235 } 17236 if (j == FAIL) 17237 { 17238 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17239 goto erret; 17240 } 17241 } 17242 17243 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17244 if (fp == NULL) 17245 goto erret; 17246 17247 if (fudi.fd_dict != NULL) 17248 { 17249 if (fudi.fd_di == NULL) 17250 { 17251 /* add new dict entry */ 17252 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17253 if (fudi.fd_di == NULL) 17254 { 17255 vim_free(fp); 17256 goto erret; 17257 } 17258 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17259 { 17260 vim_free(fudi.fd_di); 17261 goto erret; 17262 } 17263 } 17264 else 17265 /* overwrite existing dict entry */ 17266 clear_tv(&fudi.fd_di->di_tv); 17267 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17268 fudi.fd_di->di_tv.v_lock = 0; 17269 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17270 fp->uf_refcount = 1; 17271 } 17272 17273 /* insert the new function in the function list */ 17274 STRCPY(fp->uf_name, name); 17275 hash_add(&func_hashtab, UF2HIKEY(fp)); 17276 } 17277 fp->uf_args = newargs; 17278 fp->uf_lines = newlines; 17279 #ifdef FEAT_PROFILE 17280 fp->uf_tml_count = NULL; 17281 fp->uf_tml_total = NULL; 17282 fp->uf_tml_self = NULL; 17283 fp->uf_profiling = FALSE; 17284 if (prof_def_func()) 17285 func_do_profile(fp); 17286 #endif 17287 fp->uf_varargs = varargs; 17288 fp->uf_flags = flags; 17289 fp->uf_calls = 0; 17290 fp->uf_script_ID = current_SID; 17291 goto ret_free; 17292 17293 erret: 17294 ga_clear_strings(&newargs); 17295 ga_clear_strings(&newlines); 17296 ret_free: 17297 vim_free(skip_until); 17298 vim_free(fudi.fd_newkey); 17299 vim_free(name); 17300 did_emsg |= saved_did_emsg; 17301 } 17302 17303 /* 17304 * Get a function name, translating "<SID>" and "<SNR>". 17305 * Also handles a Funcref in a List or Dictionary. 17306 * Returns the function name in allocated memory, or NULL for failure. 17307 * flags: 17308 * TFN_INT: internal function name OK 17309 * TFN_QUIET: be quiet 17310 * Advances "pp" to just after the function name (if no error). 17311 */ 17312 static char_u * 17313 trans_function_name(pp, skip, flags, fdp) 17314 char_u **pp; 17315 int skip; /* only find the end, don't evaluate */ 17316 int flags; 17317 funcdict_T *fdp; /* return: info about dictionary used */ 17318 { 17319 char_u *name = NULL; 17320 char_u *start; 17321 char_u *end; 17322 int lead; 17323 char_u sid_buf[20]; 17324 int len; 17325 lval_T lv; 17326 17327 if (fdp != NULL) 17328 vim_memset(fdp, 0, sizeof(funcdict_T)); 17329 start = *pp; 17330 17331 /* Check for hard coded <SNR>: already translated function ID (from a user 17332 * command). */ 17333 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17334 && (*pp)[2] == (int)KE_SNR) 17335 { 17336 *pp += 3; 17337 len = get_id_len(pp) + 3; 17338 return vim_strnsave(start, len); 17339 } 17340 17341 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17342 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17343 lead = eval_fname_script(start); 17344 if (lead > 2) 17345 start += lead; 17346 17347 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17348 lead > 2 ? 0 : FNE_CHECK_START); 17349 if (end == start) 17350 { 17351 if (!skip) 17352 EMSG(_("E129: Function name required")); 17353 goto theend; 17354 } 17355 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17356 { 17357 /* 17358 * Report an invalid expression in braces, unless the expression 17359 * evaluation has been cancelled due to an aborting error, an 17360 * interrupt, or an exception. 17361 */ 17362 if (!aborting()) 17363 { 17364 if (end != NULL) 17365 EMSG2(_(e_invarg2), start); 17366 } 17367 else 17368 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17369 goto theend; 17370 } 17371 17372 if (lv.ll_tv != NULL) 17373 { 17374 if (fdp != NULL) 17375 { 17376 fdp->fd_dict = lv.ll_dict; 17377 fdp->fd_newkey = lv.ll_newkey; 17378 lv.ll_newkey = NULL; 17379 fdp->fd_di = lv.ll_di; 17380 } 17381 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17382 { 17383 name = vim_strsave(lv.ll_tv->vval.v_string); 17384 *pp = end; 17385 } 17386 else 17387 { 17388 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17389 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17390 EMSG(_(e_funcref)); 17391 else 17392 *pp = end; 17393 name = NULL; 17394 } 17395 goto theend; 17396 } 17397 17398 if (lv.ll_name == NULL) 17399 { 17400 /* Error found, but continue after the function name. */ 17401 *pp = end; 17402 goto theend; 17403 } 17404 17405 if (lv.ll_exp_name != NULL) 17406 len = STRLEN(lv.ll_exp_name); 17407 else 17408 { 17409 if (lead == 2) /* skip over "s:" */ 17410 lv.ll_name += 2; 17411 len = (int)(end - lv.ll_name); 17412 } 17413 17414 /* 17415 * Copy the function name to allocated memory. 17416 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17417 * Accept <SNR>123_name() outside a script. 17418 */ 17419 if (skip) 17420 lead = 0; /* do nothing */ 17421 else if (lead > 0) 17422 { 17423 lead = 3; 17424 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17425 { 17426 if (current_SID <= 0) 17427 { 17428 EMSG(_(e_usingsid)); 17429 goto theend; 17430 } 17431 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17432 lead += (int)STRLEN(sid_buf); 17433 } 17434 } 17435 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17436 { 17437 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17438 goto theend; 17439 } 17440 name = alloc((unsigned)(len + lead + 1)); 17441 if (name != NULL) 17442 { 17443 if (lead > 0) 17444 { 17445 name[0] = K_SPECIAL; 17446 name[1] = KS_EXTRA; 17447 name[2] = (int)KE_SNR; 17448 if (lead > 3) /* If it's "<SID>" */ 17449 STRCPY(name + 3, sid_buf); 17450 } 17451 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17452 name[len + lead] = NUL; 17453 } 17454 *pp = end; 17455 17456 theend: 17457 clear_lval(&lv); 17458 return name; 17459 } 17460 17461 /* 17462 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17463 * Return 2 if "p" starts with "s:". 17464 * Return 0 otherwise. 17465 */ 17466 static int 17467 eval_fname_script(p) 17468 char_u *p; 17469 { 17470 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17471 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17472 return 5; 17473 if (p[0] == 's' && p[1] == ':') 17474 return 2; 17475 return 0; 17476 } 17477 17478 /* 17479 * Return TRUE if "p" starts with "<SID>" or "s:". 17480 * Only works if eval_fname_script() returned non-zero for "p"! 17481 */ 17482 static int 17483 eval_fname_sid(p) 17484 char_u *p; 17485 { 17486 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17487 } 17488 17489 /* 17490 * List the head of the function: "name(arg1, arg2)". 17491 */ 17492 static void 17493 list_func_head(fp, indent) 17494 ufunc_T *fp; 17495 int indent; 17496 { 17497 int j; 17498 17499 msg_start(); 17500 if (indent) 17501 MSG_PUTS(" "); 17502 MSG_PUTS("function "); 17503 if (fp->uf_name[0] == K_SPECIAL) 17504 { 17505 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17506 msg_puts(fp->uf_name + 3); 17507 } 17508 else 17509 msg_puts(fp->uf_name); 17510 msg_putchar('('); 17511 for (j = 0; j < fp->uf_args.ga_len; ++j) 17512 { 17513 if (j) 17514 MSG_PUTS(", "); 17515 msg_puts(FUNCARG(fp, j)); 17516 } 17517 if (fp->uf_varargs) 17518 { 17519 if (j) 17520 MSG_PUTS(", "); 17521 MSG_PUTS("..."); 17522 } 17523 msg_putchar(')'); 17524 #ifdef FEAT_EVAL 17525 if (p_verbose > 0) 17526 last_set_msg(fp->uf_script_ID); 17527 #endif 17528 } 17529 17530 /* 17531 * Find a function by name, return pointer to it in ufuncs. 17532 * Return NULL for unknown function. 17533 */ 17534 static ufunc_T * 17535 find_func(name) 17536 char_u *name; 17537 { 17538 hashitem_T *hi; 17539 17540 hi = hash_find(&func_hashtab, name); 17541 if (!HASHITEM_EMPTY(hi)) 17542 return HI2UF(hi); 17543 return NULL; 17544 } 17545 17546 #if defined(EXITFREE) || defined(PROTO) 17547 void 17548 free_all_functions() 17549 { 17550 hashitem_T *hi; 17551 17552 /* Need to start all over every time, because func_free() may change the 17553 * hash table. */ 17554 while (func_hashtab.ht_used > 0) 17555 for (hi = func_hashtab.ht_array; ; ++hi) 17556 if (!HASHITEM_EMPTY(hi)) 17557 { 17558 func_free(HI2UF(hi)); 17559 break; 17560 } 17561 } 17562 #endif 17563 17564 /* 17565 * Return TRUE if a function "name" exists. 17566 */ 17567 static int 17568 function_exists(name) 17569 char_u *name; 17570 { 17571 char_u *p = name; 17572 int n = FALSE; 17573 17574 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17575 if (p != NULL) 17576 { 17577 if (builtin_function(p)) 17578 n = (find_internal_func(p) >= 0); 17579 else 17580 n = (find_func(p) != NULL); 17581 vim_free(p); 17582 } 17583 return n; 17584 } 17585 17586 /* 17587 * Return TRUE if "name" looks like a builtin function name: starts with a 17588 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17589 */ 17590 static int 17591 builtin_function(name) 17592 char_u *name; 17593 { 17594 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17595 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17596 } 17597 17598 #if defined(FEAT_PROFILE) || defined(PROTO) 17599 /* 17600 * Start profiling function "fp". 17601 */ 17602 static void 17603 func_do_profile(fp) 17604 ufunc_T *fp; 17605 { 17606 fp->uf_tm_count = 0; 17607 profile_zero(&fp->uf_tm_self); 17608 profile_zero(&fp->uf_tm_total); 17609 if (fp->uf_tml_count == NULL) 17610 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17611 (sizeof(int) * fp->uf_lines.ga_len)); 17612 if (fp->uf_tml_total == NULL) 17613 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17614 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17615 if (fp->uf_tml_self == NULL) 17616 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17617 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17618 fp->uf_tml_idx = -1; 17619 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17620 || fp->uf_tml_self == NULL) 17621 return; /* out of memory */ 17622 17623 fp->uf_profiling = TRUE; 17624 } 17625 17626 /* 17627 * Dump the profiling results for all functions in file "fd". 17628 */ 17629 void 17630 func_dump_profile(fd) 17631 FILE *fd; 17632 { 17633 hashitem_T *hi; 17634 int todo; 17635 ufunc_T *fp; 17636 int i; 17637 ufunc_T **sorttab; 17638 int st_len = 0; 17639 17640 todo = func_hashtab.ht_used; 17641 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17642 17643 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17644 { 17645 if (!HASHITEM_EMPTY(hi)) 17646 { 17647 --todo; 17648 fp = HI2UF(hi); 17649 if (fp->uf_profiling) 17650 { 17651 if (sorttab != NULL) 17652 sorttab[st_len++] = fp; 17653 17654 if (fp->uf_name[0] == K_SPECIAL) 17655 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17656 else 17657 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17658 if (fp->uf_tm_count == 1) 17659 fprintf(fd, "Called 1 time\n"); 17660 else 17661 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17662 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17663 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17664 fprintf(fd, "\n"); 17665 fprintf(fd, "count total (s) self (s)\n"); 17666 17667 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17668 { 17669 prof_func_line(fd, fp->uf_tml_count[i], 17670 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17671 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17672 } 17673 fprintf(fd, "\n"); 17674 } 17675 } 17676 } 17677 17678 if (sorttab != NULL && st_len > 0) 17679 { 17680 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17681 prof_total_cmp); 17682 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17683 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17684 prof_self_cmp); 17685 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17686 } 17687 } 17688 17689 static void 17690 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17691 FILE *fd; 17692 ufunc_T **sorttab; 17693 int st_len; 17694 char *title; 17695 int prefer_self; /* when equal print only self time */ 17696 { 17697 int i; 17698 ufunc_T *fp; 17699 17700 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17701 fprintf(fd, "count total (s) self (s) function\n"); 17702 for (i = 0; i < 20 && i < st_len; ++i) 17703 { 17704 fp = sorttab[i]; 17705 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17706 prefer_self); 17707 if (fp->uf_name[0] == K_SPECIAL) 17708 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17709 else 17710 fprintf(fd, " %s()\n", fp->uf_name); 17711 } 17712 fprintf(fd, "\n"); 17713 } 17714 17715 /* 17716 * Print the count and times for one function or function line. 17717 */ 17718 static void 17719 prof_func_line(fd, count, total, self, prefer_self) 17720 FILE *fd; 17721 int count; 17722 proftime_T *total; 17723 proftime_T *self; 17724 int prefer_self; /* when equal print only self time */ 17725 { 17726 if (count > 0) 17727 { 17728 fprintf(fd, "%5d ", count); 17729 if (prefer_self && profile_equal(total, self)) 17730 fprintf(fd, " "); 17731 else 17732 fprintf(fd, "%s ", profile_msg(total)); 17733 if (!prefer_self && profile_equal(total, self)) 17734 fprintf(fd, " "); 17735 else 17736 fprintf(fd, "%s ", profile_msg(self)); 17737 } 17738 else 17739 fprintf(fd, " "); 17740 } 17741 17742 /* 17743 * Compare function for total time sorting. 17744 */ 17745 static int 17746 #ifdef __BORLANDC__ 17747 _RTLENTRYF 17748 #endif 17749 prof_total_cmp(s1, s2) 17750 const void *s1; 17751 const void *s2; 17752 { 17753 ufunc_T *p1, *p2; 17754 17755 p1 = *(ufunc_T **)s1; 17756 p2 = *(ufunc_T **)s2; 17757 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 17758 } 17759 17760 /* 17761 * Compare function for self time sorting. 17762 */ 17763 static int 17764 #ifdef __BORLANDC__ 17765 _RTLENTRYF 17766 #endif 17767 prof_self_cmp(s1, s2) 17768 const void *s1; 17769 const void *s2; 17770 { 17771 ufunc_T *p1, *p2; 17772 17773 p1 = *(ufunc_T **)s1; 17774 p2 = *(ufunc_T **)s2; 17775 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 17776 } 17777 17778 #endif 17779 17780 /* The names of packages that once were loaded is remembered. */ 17781 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 17782 17783 /* 17784 * If "name" has a package name try autoloading the script for it. 17785 * Return TRUE if a package was loaded. 17786 */ 17787 static int 17788 script_autoload(name, reload) 17789 char_u *name; 17790 int reload; /* load script again when already loaded */ 17791 { 17792 char_u *p; 17793 char_u *scriptname, *tofree; 17794 int ret = FALSE; 17795 int i; 17796 17797 /* If there is no '#' after name[0] there is no package name. */ 17798 p = vim_strchr(name, AUTOLOAD_CHAR); 17799 if (p == NULL || p == name) 17800 return FALSE; 17801 17802 tofree = scriptname = autoload_name(name); 17803 17804 /* Find the name in the list of previously loaded package names. Skip 17805 * "autoload/", it's always the same. */ 17806 for (i = 0; i < ga_loaded.ga_len; ++i) 17807 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 17808 break; 17809 if (!reload && i < ga_loaded.ga_len) 17810 ret = FALSE; /* was loaded already */ 17811 else 17812 { 17813 /* Remember the name if it wasn't loaded already. */ 17814 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 17815 { 17816 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 17817 tofree = NULL; 17818 } 17819 17820 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 17821 if (source_runtime(scriptname, FALSE) == OK) 17822 ret = TRUE; 17823 } 17824 17825 vim_free(tofree); 17826 return ret; 17827 } 17828 17829 /* 17830 * Return the autoload script name for a function or variable name. 17831 * Returns NULL when out of memory. 17832 */ 17833 static char_u * 17834 autoload_name(name) 17835 char_u *name; 17836 { 17837 char_u *p; 17838 char_u *scriptname; 17839 17840 /* Get the script file name: replace '#' with '/', append ".vim". */ 17841 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 17842 if (scriptname == NULL) 17843 return FALSE; 17844 STRCPY(scriptname, "autoload/"); 17845 STRCAT(scriptname, name); 17846 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 17847 STRCAT(scriptname, ".vim"); 17848 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 17849 *p = '/'; 17850 return scriptname; 17851 } 17852 17853 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 17854 17855 /* 17856 * Function given to ExpandGeneric() to obtain the list of user defined 17857 * function names. 17858 */ 17859 char_u * 17860 get_user_func_name(xp, idx) 17861 expand_T *xp; 17862 int idx; 17863 { 17864 static long_u done; 17865 static hashitem_T *hi; 17866 ufunc_T *fp; 17867 17868 if (idx == 0) 17869 { 17870 done = 0; 17871 hi = func_hashtab.ht_array; 17872 } 17873 if (done < func_hashtab.ht_used) 17874 { 17875 if (done++ > 0) 17876 ++hi; 17877 while (HASHITEM_EMPTY(hi)) 17878 ++hi; 17879 fp = HI2UF(hi); 17880 17881 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 17882 return fp->uf_name; /* prevents overflow */ 17883 17884 cat_func_name(IObuff, fp); 17885 if (xp->xp_context != EXPAND_USER_FUNC) 17886 { 17887 STRCAT(IObuff, "("); 17888 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 17889 STRCAT(IObuff, ")"); 17890 } 17891 return IObuff; 17892 } 17893 return NULL; 17894 } 17895 17896 #endif /* FEAT_CMDL_COMPL */ 17897 17898 /* 17899 * Copy the function name of "fp" to buffer "buf". 17900 * "buf" must be able to hold the function name plus three bytes. 17901 * Takes care of script-local function names. 17902 */ 17903 static void 17904 cat_func_name(buf, fp) 17905 char_u *buf; 17906 ufunc_T *fp; 17907 { 17908 if (fp->uf_name[0] == K_SPECIAL) 17909 { 17910 STRCPY(buf, "<SNR>"); 17911 STRCAT(buf, fp->uf_name + 3); 17912 } 17913 else 17914 STRCPY(buf, fp->uf_name); 17915 } 17916 17917 /* 17918 * ":delfunction {name}" 17919 */ 17920 void 17921 ex_delfunction(eap) 17922 exarg_T *eap; 17923 { 17924 ufunc_T *fp = NULL; 17925 char_u *p; 17926 char_u *name; 17927 funcdict_T fudi; 17928 17929 p = eap->arg; 17930 name = trans_function_name(&p, eap->skip, 0, &fudi); 17931 vim_free(fudi.fd_newkey); 17932 if (name == NULL) 17933 { 17934 if (fudi.fd_dict != NULL && !eap->skip) 17935 EMSG(_(e_funcref)); 17936 return; 17937 } 17938 if (!ends_excmd(*skipwhite(p))) 17939 { 17940 vim_free(name); 17941 EMSG(_(e_trailing)); 17942 return; 17943 } 17944 eap->nextcmd = check_nextcmd(p); 17945 if (eap->nextcmd != NULL) 17946 *p = NUL; 17947 17948 if (!eap->skip) 17949 fp = find_func(name); 17950 vim_free(name); 17951 17952 if (!eap->skip) 17953 { 17954 if (fp == NULL) 17955 { 17956 EMSG2(_(e_nofunc), eap->arg); 17957 return; 17958 } 17959 if (fp->uf_calls > 0) 17960 { 17961 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 17962 return; 17963 } 17964 17965 if (fudi.fd_dict != NULL) 17966 { 17967 /* Delete the dict item that refers to the function, it will 17968 * invoke func_unref() and possibly delete the function. */ 17969 dictitem_remove(fudi.fd_dict, fudi.fd_di); 17970 } 17971 else 17972 func_free(fp); 17973 } 17974 } 17975 17976 /* 17977 * Free a function and remove it from the list of functions. 17978 */ 17979 static void 17980 func_free(fp) 17981 ufunc_T *fp; 17982 { 17983 hashitem_T *hi; 17984 17985 /* clear this function */ 17986 ga_clear_strings(&(fp->uf_args)); 17987 ga_clear_strings(&(fp->uf_lines)); 17988 #ifdef FEAT_PROFILE 17989 vim_free(fp->uf_tml_count); 17990 vim_free(fp->uf_tml_total); 17991 vim_free(fp->uf_tml_self); 17992 #endif 17993 17994 /* remove the function from the function hashtable */ 17995 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 17996 if (HASHITEM_EMPTY(hi)) 17997 EMSG2(_(e_intern2), "func_free()"); 17998 else 17999 hash_remove(&func_hashtab, hi); 18000 18001 vim_free(fp); 18002 } 18003 18004 /* 18005 * Unreference a Function: decrement the reference count and free it when it 18006 * becomes zero. Only for numbered functions. 18007 */ 18008 static void 18009 func_unref(name) 18010 char_u *name; 18011 { 18012 ufunc_T *fp; 18013 18014 if (name != NULL && isdigit(*name)) 18015 { 18016 fp = find_func(name); 18017 if (fp == NULL) 18018 EMSG2(_(e_intern2), "func_unref()"); 18019 else if (--fp->uf_refcount <= 0) 18020 { 18021 /* Only delete it when it's not being used. Otherwise it's done 18022 * when "uf_calls" becomes zero. */ 18023 if (fp->uf_calls == 0) 18024 func_free(fp); 18025 } 18026 } 18027 } 18028 18029 /* 18030 * Count a reference to a Function. 18031 */ 18032 static void 18033 func_ref(name) 18034 char_u *name; 18035 { 18036 ufunc_T *fp; 18037 18038 if (name != NULL && isdigit(*name)) 18039 { 18040 fp = find_func(name); 18041 if (fp == NULL) 18042 EMSG2(_(e_intern2), "func_ref()"); 18043 else 18044 ++fp->uf_refcount; 18045 } 18046 } 18047 18048 /* 18049 * Call a user function. 18050 */ 18051 static void 18052 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18053 ufunc_T *fp; /* pointer to function */ 18054 int argcount; /* nr of args */ 18055 typval_T *argvars; /* arguments */ 18056 typval_T *rettv; /* return value */ 18057 linenr_T firstline; /* first line of range */ 18058 linenr_T lastline; /* last line of range */ 18059 dict_T *selfdict; /* Dictionary for "self" */ 18060 { 18061 char_u *save_sourcing_name; 18062 linenr_T save_sourcing_lnum; 18063 scid_T save_current_SID; 18064 funccall_T fc; 18065 int save_did_emsg; 18066 static int depth = 0; 18067 dictitem_T *v; 18068 int fixvar_idx = 0; /* index in fixvar[] */ 18069 int i; 18070 int ai; 18071 char_u numbuf[NUMBUFLEN]; 18072 char_u *name; 18073 #ifdef FEAT_PROFILE 18074 proftime_T wait_start; 18075 #endif 18076 18077 /* If depth of calling is getting too high, don't execute the function */ 18078 if (depth >= p_mfd) 18079 { 18080 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18081 rettv->v_type = VAR_NUMBER; 18082 rettv->vval.v_number = -1; 18083 return; 18084 } 18085 ++depth; 18086 18087 line_breakcheck(); /* check for CTRL-C hit */ 18088 18089 fc.caller = current_funccal; 18090 current_funccal = &fc; 18091 fc.func = fp; 18092 fc.rettv = rettv; 18093 rettv->vval.v_number = 0; 18094 fc.linenr = 0; 18095 fc.returned = FALSE; 18096 fc.level = ex_nesting_level; 18097 /* Check if this function has a breakpoint. */ 18098 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18099 fc.dbg_tick = debug_tick; 18100 18101 /* 18102 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18103 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18104 * each argument variable and saves a lot of time. 18105 */ 18106 /* 18107 * Init l: variables. 18108 */ 18109 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18110 if (selfdict != NULL) 18111 { 18112 /* Set l:self to "selfdict". */ 18113 v = &fc.fixvar[fixvar_idx++].var; 18114 STRCPY(v->di_key, "self"); 18115 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18116 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18117 v->di_tv.v_type = VAR_DICT; 18118 v->di_tv.v_lock = 0; 18119 v->di_tv.vval.v_dict = selfdict; 18120 ++selfdict->dv_refcount; 18121 } 18122 18123 /* 18124 * Init a: variables. 18125 * Set a:0 to "argcount". 18126 * Set a:000 to a list with room for the "..." arguments. 18127 */ 18128 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18129 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18130 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18131 v = &fc.fixvar[fixvar_idx++].var; 18132 STRCPY(v->di_key, "000"); 18133 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18134 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18135 v->di_tv.v_type = VAR_LIST; 18136 v->di_tv.v_lock = VAR_FIXED; 18137 v->di_tv.vval.v_list = &fc.l_varlist; 18138 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18139 fc.l_varlist.lv_refcount = 99999; 18140 18141 /* 18142 * Set a:firstline to "firstline" and a:lastline to "lastline". 18143 * Set a:name to named arguments. 18144 * Set a:N to the "..." arguments. 18145 */ 18146 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18147 (varnumber_T)firstline); 18148 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18149 (varnumber_T)lastline); 18150 for (i = 0; i < argcount; ++i) 18151 { 18152 ai = i - fp->uf_args.ga_len; 18153 if (ai < 0) 18154 /* named argument a:name */ 18155 name = FUNCARG(fp, i); 18156 else 18157 { 18158 /* "..." argument a:1, a:2, etc. */ 18159 sprintf((char *)numbuf, "%d", ai + 1); 18160 name = numbuf; 18161 } 18162 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18163 { 18164 v = &fc.fixvar[fixvar_idx++].var; 18165 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18166 } 18167 else 18168 { 18169 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18170 + STRLEN(name))); 18171 if (v == NULL) 18172 break; 18173 v->di_flags = DI_FLAGS_RO; 18174 } 18175 STRCPY(v->di_key, name); 18176 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18177 18178 /* Note: the values are copied directly to avoid alloc/free. 18179 * "argvars" must have VAR_FIXED for v_lock. */ 18180 v->di_tv = argvars[i]; 18181 v->di_tv.v_lock = VAR_FIXED; 18182 18183 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18184 { 18185 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18186 fc.l_listitems[ai].li_tv = argvars[i]; 18187 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18188 } 18189 } 18190 18191 /* Don't redraw while executing the function. */ 18192 ++RedrawingDisabled; 18193 save_sourcing_name = sourcing_name; 18194 save_sourcing_lnum = sourcing_lnum; 18195 sourcing_lnum = 1; 18196 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18197 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18198 if (sourcing_name != NULL) 18199 { 18200 if (save_sourcing_name != NULL 18201 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18202 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18203 else 18204 STRCPY(sourcing_name, "function "); 18205 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18206 18207 if (p_verbose >= 12) 18208 { 18209 ++no_wait_return; 18210 verbose_enter_scroll(); 18211 18212 smsg((char_u *)_("calling %s"), sourcing_name); 18213 if (p_verbose >= 14) 18214 { 18215 char_u buf[MSG_BUF_LEN]; 18216 char_u numbuf[NUMBUFLEN]; 18217 char_u *tofree; 18218 18219 msg_puts((char_u *)"("); 18220 for (i = 0; i < argcount; ++i) 18221 { 18222 if (i > 0) 18223 msg_puts((char_u *)", "); 18224 if (argvars[i].v_type == VAR_NUMBER) 18225 msg_outnum((long)argvars[i].vval.v_number); 18226 else 18227 { 18228 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18229 buf, MSG_BUF_CLEN); 18230 msg_puts(buf); 18231 vim_free(tofree); 18232 } 18233 } 18234 msg_puts((char_u *)")"); 18235 } 18236 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18237 18238 verbose_leave_scroll(); 18239 --no_wait_return; 18240 } 18241 } 18242 #ifdef FEAT_PROFILE 18243 if (do_profiling) 18244 { 18245 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18246 func_do_profile(fp); 18247 if (fp->uf_profiling 18248 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18249 { 18250 ++fp->uf_tm_count; 18251 profile_start(&fp->uf_tm_start); 18252 profile_zero(&fp->uf_tm_children); 18253 } 18254 script_prof_save(&wait_start); 18255 } 18256 #endif 18257 18258 save_current_SID = current_SID; 18259 current_SID = fp->uf_script_ID; 18260 save_did_emsg = did_emsg; 18261 did_emsg = FALSE; 18262 18263 /* call do_cmdline() to execute the lines */ 18264 do_cmdline(NULL, get_func_line, (void *)&fc, 18265 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18266 18267 --RedrawingDisabled; 18268 18269 /* when the function was aborted because of an error, return -1 */ 18270 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18271 { 18272 clear_tv(rettv); 18273 rettv->v_type = VAR_NUMBER; 18274 rettv->vval.v_number = -1; 18275 } 18276 18277 #ifdef FEAT_PROFILE 18278 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18279 { 18280 profile_end(&fp->uf_tm_start); 18281 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18282 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18283 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18284 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18285 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18286 { 18287 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18288 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18289 } 18290 } 18291 #endif 18292 18293 /* when being verbose, mention the return value */ 18294 if (p_verbose >= 12) 18295 { 18296 ++no_wait_return; 18297 verbose_enter_scroll(); 18298 18299 if (aborting()) 18300 smsg((char_u *)_("%s aborted"), sourcing_name); 18301 else if (fc.rettv->v_type == VAR_NUMBER) 18302 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18303 (long)fc.rettv->vval.v_number); 18304 else 18305 { 18306 char_u buf[MSG_BUF_LEN]; 18307 char_u numbuf[NUMBUFLEN]; 18308 char_u *tofree; 18309 18310 /* The value may be very long. Skip the middle part, so that we 18311 * have some idea how it starts and ends. smsg() would always 18312 * truncate it at the end. */ 18313 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18314 buf, MSG_BUF_CLEN); 18315 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18316 vim_free(tofree); 18317 } 18318 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18319 18320 verbose_leave_scroll(); 18321 --no_wait_return; 18322 } 18323 18324 vim_free(sourcing_name); 18325 sourcing_name = save_sourcing_name; 18326 sourcing_lnum = save_sourcing_lnum; 18327 current_SID = save_current_SID; 18328 #ifdef FEAT_PROFILE 18329 if (do_profiling) 18330 script_prof_restore(&wait_start); 18331 #endif 18332 18333 if (p_verbose >= 12 && sourcing_name != NULL) 18334 { 18335 ++no_wait_return; 18336 verbose_enter_scroll(); 18337 18338 smsg((char_u *)_("continuing in %s"), sourcing_name); 18339 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18340 18341 verbose_leave_scroll(); 18342 --no_wait_return; 18343 } 18344 18345 did_emsg |= save_did_emsg; 18346 current_funccal = fc.caller; 18347 18348 /* The a: variables typevals were not alloced, only free the allocated 18349 * variables. */ 18350 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18351 18352 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18353 --depth; 18354 } 18355 18356 /* 18357 * Add a number variable "name" to dict "dp" with value "nr". 18358 */ 18359 static void 18360 add_nr_var(dp, v, name, nr) 18361 dict_T *dp; 18362 dictitem_T *v; 18363 char *name; 18364 varnumber_T nr; 18365 { 18366 STRCPY(v->di_key, name); 18367 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18368 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18369 v->di_tv.v_type = VAR_NUMBER; 18370 v->di_tv.v_lock = VAR_FIXED; 18371 v->di_tv.vval.v_number = nr; 18372 } 18373 18374 /* 18375 * ":return [expr]" 18376 */ 18377 void 18378 ex_return(eap) 18379 exarg_T *eap; 18380 { 18381 char_u *arg = eap->arg; 18382 typval_T rettv; 18383 int returning = FALSE; 18384 18385 if (current_funccal == NULL) 18386 { 18387 EMSG(_("E133: :return not inside a function")); 18388 return; 18389 } 18390 18391 if (eap->skip) 18392 ++emsg_skip; 18393 18394 eap->nextcmd = NULL; 18395 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18396 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18397 { 18398 if (!eap->skip) 18399 returning = do_return(eap, FALSE, TRUE, &rettv); 18400 else 18401 clear_tv(&rettv); 18402 } 18403 /* It's safer to return also on error. */ 18404 else if (!eap->skip) 18405 { 18406 /* 18407 * Return unless the expression evaluation has been cancelled due to an 18408 * aborting error, an interrupt, or an exception. 18409 */ 18410 if (!aborting()) 18411 returning = do_return(eap, FALSE, TRUE, NULL); 18412 } 18413 18414 /* When skipping or the return gets pending, advance to the next command 18415 * in this line (!returning). Otherwise, ignore the rest of the line. 18416 * Following lines will be ignored by get_func_line(). */ 18417 if (returning) 18418 eap->nextcmd = NULL; 18419 else if (eap->nextcmd == NULL) /* no argument */ 18420 eap->nextcmd = check_nextcmd(arg); 18421 18422 if (eap->skip) 18423 --emsg_skip; 18424 } 18425 18426 /* 18427 * Return from a function. Possibly makes the return pending. Also called 18428 * for a pending return at the ":endtry" or after returning from an extra 18429 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18430 * when called due to a ":return" command. "rettv" may point to a typval_T 18431 * with the return rettv. Returns TRUE when the return can be carried out, 18432 * FALSE when the return gets pending. 18433 */ 18434 int 18435 do_return(eap, reanimate, is_cmd, rettv) 18436 exarg_T *eap; 18437 int reanimate; 18438 int is_cmd; 18439 void *rettv; 18440 { 18441 int idx; 18442 struct condstack *cstack = eap->cstack; 18443 18444 if (reanimate) 18445 /* Undo the return. */ 18446 current_funccal->returned = FALSE; 18447 18448 /* 18449 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18450 * not in its finally clause (which then is to be executed next) is found. 18451 * In this case, make the ":return" pending for execution at the ":endtry". 18452 * Otherwise, return normally. 18453 */ 18454 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18455 if (idx >= 0) 18456 { 18457 cstack->cs_pending[idx] = CSTP_RETURN; 18458 18459 if (!is_cmd && !reanimate) 18460 /* A pending return again gets pending. "rettv" points to an 18461 * allocated variable with the rettv of the original ":return"'s 18462 * argument if present or is NULL else. */ 18463 cstack->cs_rettv[idx] = rettv; 18464 else 18465 { 18466 /* When undoing a return in order to make it pending, get the stored 18467 * return rettv. */ 18468 if (reanimate) 18469 rettv = current_funccal->rettv; 18470 18471 if (rettv != NULL) 18472 { 18473 /* Store the value of the pending return. */ 18474 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18475 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18476 else 18477 EMSG(_(e_outofmem)); 18478 } 18479 else 18480 cstack->cs_rettv[idx] = NULL; 18481 18482 if (reanimate) 18483 { 18484 /* The pending return value could be overwritten by a ":return" 18485 * without argument in a finally clause; reset the default 18486 * return value. */ 18487 current_funccal->rettv->v_type = VAR_NUMBER; 18488 current_funccal->rettv->vval.v_number = 0; 18489 } 18490 } 18491 report_make_pending(CSTP_RETURN, rettv); 18492 } 18493 else 18494 { 18495 current_funccal->returned = TRUE; 18496 18497 /* If the return is carried out now, store the return value. For 18498 * a return immediately after reanimation, the value is already 18499 * there. */ 18500 if (!reanimate && rettv != NULL) 18501 { 18502 clear_tv(current_funccal->rettv); 18503 *current_funccal->rettv = *(typval_T *)rettv; 18504 if (!is_cmd) 18505 vim_free(rettv); 18506 } 18507 } 18508 18509 return idx < 0; 18510 } 18511 18512 /* 18513 * Free the variable with a pending return value. 18514 */ 18515 void 18516 discard_pending_return(rettv) 18517 void *rettv; 18518 { 18519 free_tv((typval_T *)rettv); 18520 } 18521 18522 /* 18523 * Generate a return command for producing the value of "rettv". The result 18524 * is an allocated string. Used by report_pending() for verbose messages. 18525 */ 18526 char_u * 18527 get_return_cmd(rettv) 18528 void *rettv; 18529 { 18530 char_u *s = NULL; 18531 char_u *tofree = NULL; 18532 char_u numbuf[NUMBUFLEN]; 18533 18534 if (rettv != NULL) 18535 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18536 if (s == NULL) 18537 s = (char_u *)""; 18538 18539 STRCPY(IObuff, ":return "); 18540 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18541 if (STRLEN(s) + 8 >= IOSIZE) 18542 STRCPY(IObuff + IOSIZE - 4, "..."); 18543 vim_free(tofree); 18544 return vim_strsave(IObuff); 18545 } 18546 18547 /* 18548 * Get next function line. 18549 * Called by do_cmdline() to get the next line. 18550 * Returns allocated string, or NULL for end of function. 18551 */ 18552 /* ARGSUSED */ 18553 char_u * 18554 get_func_line(c, cookie, indent) 18555 int c; /* not used */ 18556 void *cookie; 18557 int indent; /* not used */ 18558 { 18559 funccall_T *fcp = (funccall_T *)cookie; 18560 ufunc_T *fp = fcp->func; 18561 char_u *retval; 18562 garray_T *gap; /* growarray with function lines */ 18563 18564 /* If breakpoints have been added/deleted need to check for it. */ 18565 if (fcp->dbg_tick != debug_tick) 18566 { 18567 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18568 sourcing_lnum); 18569 fcp->dbg_tick = debug_tick; 18570 } 18571 #ifdef FEAT_PROFILE 18572 if (do_profiling) 18573 func_line_end(cookie); 18574 #endif 18575 18576 gap = &fp->uf_lines; 18577 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18578 retval = NULL; 18579 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18580 retval = NULL; 18581 else 18582 { 18583 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18584 sourcing_lnum = fcp->linenr; 18585 #ifdef FEAT_PROFILE 18586 if (do_profiling) 18587 func_line_start(cookie); 18588 #endif 18589 } 18590 18591 /* Did we encounter a breakpoint? */ 18592 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18593 { 18594 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18595 /* Find next breakpoint. */ 18596 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18597 sourcing_lnum); 18598 fcp->dbg_tick = debug_tick; 18599 } 18600 18601 return retval; 18602 } 18603 18604 #if defined(FEAT_PROFILE) || defined(PROTO) 18605 /* 18606 * Called when starting to read a function line. 18607 * "sourcing_lnum" must be correct! 18608 * When skipping lines it may not actually be executed, but we won't find out 18609 * until later and we need to store the time now. 18610 */ 18611 void 18612 func_line_start(cookie) 18613 void *cookie; 18614 { 18615 funccall_T *fcp = (funccall_T *)cookie; 18616 ufunc_T *fp = fcp->func; 18617 18618 if (fp->uf_profiling && sourcing_lnum >= 1 18619 && sourcing_lnum <= fp->uf_lines.ga_len) 18620 { 18621 fp->uf_tml_idx = sourcing_lnum - 1; 18622 fp->uf_tml_execed = FALSE; 18623 profile_start(&fp->uf_tml_start); 18624 profile_zero(&fp->uf_tml_children); 18625 profile_get_wait(&fp->uf_tml_wait); 18626 } 18627 } 18628 18629 /* 18630 * Called when actually executing a function line. 18631 */ 18632 void 18633 func_line_exec(cookie) 18634 void *cookie; 18635 { 18636 funccall_T *fcp = (funccall_T *)cookie; 18637 ufunc_T *fp = fcp->func; 18638 18639 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18640 fp->uf_tml_execed = TRUE; 18641 } 18642 18643 /* 18644 * Called when done with a function line. 18645 */ 18646 void 18647 func_line_end(cookie) 18648 void *cookie; 18649 { 18650 funccall_T *fcp = (funccall_T *)cookie; 18651 ufunc_T *fp = fcp->func; 18652 18653 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18654 { 18655 if (fp->uf_tml_execed) 18656 { 18657 ++fp->uf_tml_count[fp->uf_tml_idx]; 18658 profile_end(&fp->uf_tml_start); 18659 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18660 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18661 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18662 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18663 } 18664 fp->uf_tml_idx = -1; 18665 } 18666 } 18667 #endif 18668 18669 /* 18670 * Return TRUE if the currently active function should be ended, because a 18671 * return was encountered or an error occured. Used inside a ":while". 18672 */ 18673 int 18674 func_has_ended(cookie) 18675 void *cookie; 18676 { 18677 funccall_T *fcp = (funccall_T *)cookie; 18678 18679 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18680 * an error inside a try conditional. */ 18681 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18682 || fcp->returned); 18683 } 18684 18685 /* 18686 * return TRUE if cookie indicates a function which "abort"s on errors. 18687 */ 18688 int 18689 func_has_abort(cookie) 18690 void *cookie; 18691 { 18692 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18693 } 18694 18695 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18696 typedef enum 18697 { 18698 VAR_FLAVOUR_DEFAULT, 18699 VAR_FLAVOUR_SESSION, 18700 VAR_FLAVOUR_VIMINFO 18701 } var_flavour_T; 18702 18703 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18704 18705 static var_flavour_T 18706 var_flavour(varname) 18707 char_u *varname; 18708 { 18709 char_u *p = varname; 18710 18711 if (ASCII_ISUPPER(*p)) 18712 { 18713 while (*(++p)) 18714 if (ASCII_ISLOWER(*p)) 18715 return VAR_FLAVOUR_SESSION; 18716 return VAR_FLAVOUR_VIMINFO; 18717 } 18718 else 18719 return VAR_FLAVOUR_DEFAULT; 18720 } 18721 #endif 18722 18723 #if defined(FEAT_VIMINFO) || defined(PROTO) 18724 /* 18725 * Restore global vars that start with a capital from the viminfo file 18726 */ 18727 int 18728 read_viminfo_varlist(virp, writing) 18729 vir_T *virp; 18730 int writing; 18731 { 18732 char_u *tab; 18733 int is_string = FALSE; 18734 typval_T tv; 18735 18736 if (!writing && (find_viminfo_parameter('!') != NULL)) 18737 { 18738 tab = vim_strchr(virp->vir_line + 1, '\t'); 18739 if (tab != NULL) 18740 { 18741 *tab++ = '\0'; /* isolate the variable name */ 18742 if (*tab == 'S') /* string var */ 18743 is_string = TRUE; 18744 18745 tab = vim_strchr(tab, '\t'); 18746 if (tab != NULL) 18747 { 18748 if (is_string) 18749 { 18750 tv.v_type = VAR_STRING; 18751 tv.vval.v_string = viminfo_readstring(virp, 18752 (int)(tab - virp->vir_line + 1), TRUE); 18753 } 18754 else 18755 { 18756 tv.v_type = VAR_NUMBER; 18757 tv.vval.v_number = atol((char *)tab + 1); 18758 } 18759 set_var(virp->vir_line + 1, &tv, FALSE); 18760 if (is_string) 18761 vim_free(tv.vval.v_string); 18762 } 18763 } 18764 } 18765 18766 return viminfo_readline(virp); 18767 } 18768 18769 /* 18770 * Write global vars that start with a capital to the viminfo file 18771 */ 18772 void 18773 write_viminfo_varlist(fp) 18774 FILE *fp; 18775 { 18776 hashitem_T *hi; 18777 dictitem_T *this_var; 18778 int todo; 18779 char *s; 18780 char_u *p; 18781 char_u *tofree; 18782 char_u numbuf[NUMBUFLEN]; 18783 18784 if (find_viminfo_parameter('!') == NULL) 18785 return; 18786 18787 fprintf(fp, _("\n# global variables:\n")); 18788 18789 todo = globvarht.ht_used; 18790 for (hi = globvarht.ht_array; todo > 0; ++hi) 18791 { 18792 if (!HASHITEM_EMPTY(hi)) 18793 { 18794 --todo; 18795 this_var = HI2DI(hi); 18796 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 18797 { 18798 switch (this_var->di_tv.v_type) 18799 { 18800 case VAR_STRING: s = "STR"; break; 18801 case VAR_NUMBER: s = "NUM"; break; 18802 default: continue; 18803 } 18804 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 18805 p = echo_string(&this_var->di_tv, &tofree, numbuf); 18806 if (p != NULL) 18807 viminfo_writestring(fp, p); 18808 vim_free(tofree); 18809 } 18810 } 18811 } 18812 } 18813 #endif 18814 18815 #if defined(FEAT_SESSION) || defined(PROTO) 18816 int 18817 store_session_globals(fd) 18818 FILE *fd; 18819 { 18820 hashitem_T *hi; 18821 dictitem_T *this_var; 18822 int todo; 18823 char_u *p, *t; 18824 18825 todo = globvarht.ht_used; 18826 for (hi = globvarht.ht_array; todo > 0; ++hi) 18827 { 18828 if (!HASHITEM_EMPTY(hi)) 18829 { 18830 --todo; 18831 this_var = HI2DI(hi); 18832 if ((this_var->di_tv.v_type == VAR_NUMBER 18833 || this_var->di_tv.v_type == VAR_STRING) 18834 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 18835 { 18836 /* Escape special characters with a backslash. Turn a LF and 18837 * CR into \n and \r. */ 18838 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 18839 (char_u *)"\\\"\n\r"); 18840 if (p == NULL) /* out of memory */ 18841 break; 18842 for (t = p; *t != NUL; ++t) 18843 if (*t == '\n') 18844 *t = 'n'; 18845 else if (*t == '\r') 18846 *t = 'r'; 18847 if ((fprintf(fd, "let %s = %c%s%c", 18848 this_var->di_key, 18849 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18850 : ' ', 18851 p, 18852 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18853 : ' ') < 0) 18854 || put_eol(fd) == FAIL) 18855 { 18856 vim_free(p); 18857 return FAIL; 18858 } 18859 vim_free(p); 18860 } 18861 } 18862 } 18863 return OK; 18864 } 18865 #endif 18866 18867 /* 18868 * Display script name where an item was last set. 18869 * Should only be invoked when 'verbose' is non-zero. 18870 */ 18871 void 18872 last_set_msg(scriptID) 18873 scid_T scriptID; 18874 { 18875 if (scriptID != 0) 18876 { 18877 verbose_enter(); 18878 MSG_PUTS(_("\n\tLast set from ")); 18879 MSG_PUTS(get_scriptname(scriptID)); 18880 verbose_leave(); 18881 } 18882 } 18883 18884 #endif /* FEAT_EVAL */ 18885 18886 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 18887 18888 18889 #ifdef WIN3264 18890 /* 18891 * Functions for ":8" filename modifier: get 8.3 version of a filename. 18892 */ 18893 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18894 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 18895 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18896 18897 /* 18898 * Get the short pathname of a file. 18899 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 18900 */ 18901 static int 18902 get_short_pathname(fnamep, bufp, fnamelen) 18903 char_u **fnamep; 18904 char_u **bufp; 18905 int *fnamelen; 18906 { 18907 int l,len; 18908 char_u *newbuf; 18909 18910 len = *fnamelen; 18911 18912 l = GetShortPathName(*fnamep, *fnamep, len); 18913 if (l > len - 1) 18914 { 18915 /* If that doesn't work (not enough space), then save the string 18916 * and try again with a new buffer big enough 18917 */ 18918 newbuf = vim_strnsave(*fnamep, l); 18919 if (newbuf == NULL) 18920 return 0; 18921 18922 vim_free(*bufp); 18923 *fnamep = *bufp = newbuf; 18924 18925 l = GetShortPathName(*fnamep,*fnamep,l+1); 18926 18927 /* Really should always succeed, as the buffer is big enough */ 18928 } 18929 18930 *fnamelen = l; 18931 return 1; 18932 } 18933 18934 /* 18935 * Create a short path name. Returns the length of the buffer it needs. 18936 * Doesn't copy over the end of the buffer passed in. 18937 */ 18938 static int 18939 shortpath_for_invalid_fname(fname, bufp, fnamelen) 18940 char_u **fname; 18941 char_u **bufp; 18942 int *fnamelen; 18943 { 18944 char_u *s, *p, *pbuf2, *pbuf3; 18945 char_u ch; 18946 int len, len2, plen, slen; 18947 18948 /* Make a copy */ 18949 len2 = *fnamelen; 18950 pbuf2 = vim_strnsave(*fname, len2); 18951 pbuf3 = NULL; 18952 18953 s = pbuf2 + len2 - 1; /* Find the end */ 18954 slen = 1; 18955 plen = len2; 18956 18957 if (after_pathsep(pbuf2, s + 1)) 18958 { 18959 --s; 18960 ++slen; 18961 --plen; 18962 } 18963 18964 do 18965 { 18966 /* Go back one path-seperator */ 18967 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 18968 { 18969 --s; 18970 ++slen; 18971 --plen; 18972 } 18973 if (s <= pbuf2) 18974 break; 18975 18976 /* Remeber the character that is about to be blatted */ 18977 ch = *s; 18978 *s = 0; /* get_short_pathname requires a null-terminated string */ 18979 18980 /* Try it in situ */ 18981 p = pbuf2; 18982 if (!get_short_pathname(&p, &pbuf3, &plen)) 18983 { 18984 vim_free(pbuf2); 18985 return -1; 18986 } 18987 *s = ch; /* Preserve the string */ 18988 } while (plen == 0); 18989 18990 if (plen > 0) 18991 { 18992 /* Remeber the length of the new string. */ 18993 *fnamelen = len = plen + slen; 18994 vim_free(*bufp); 18995 if (len > len2) 18996 { 18997 /* If there's not enough space in the currently allocated string, 18998 * then copy it to a buffer big enough. 18999 */ 19000 *fname= *bufp = vim_strnsave(p, len); 19001 if (*fname == NULL) 19002 return -1; 19003 } 19004 else 19005 { 19006 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 19007 *fname = *bufp = pbuf2; 19008 if (p != pbuf2) 19009 strncpy(*fname, p, plen); 19010 pbuf2 = NULL; 19011 } 19012 /* Concat the next bit */ 19013 strncpy(*fname + plen, s, slen); 19014 (*fname)[len] = '\0'; 19015 } 19016 vim_free(pbuf3); 19017 vim_free(pbuf2); 19018 return 0; 19019 } 19020 19021 /* 19022 * Get a pathname for a partial path. 19023 */ 19024 static int 19025 shortpath_for_partial(fnamep, bufp, fnamelen) 19026 char_u **fnamep; 19027 char_u **bufp; 19028 int *fnamelen; 19029 { 19030 int sepcount, len, tflen; 19031 char_u *p; 19032 char_u *pbuf, *tfname; 19033 int hasTilde; 19034 19035 /* Count up the path seperators from the RHS.. so we know which part 19036 * of the path to return. 19037 */ 19038 sepcount = 0; 19039 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19040 if (vim_ispathsep(*p)) 19041 ++sepcount; 19042 19043 /* Need full path first (use expand_env() to remove a "~/") */ 19044 hasTilde = (**fnamep == '~'); 19045 if (hasTilde) 19046 pbuf = tfname = expand_env_save(*fnamep); 19047 else 19048 pbuf = tfname = FullName_save(*fnamep, FALSE); 19049 19050 len = tflen = STRLEN(tfname); 19051 19052 if (!get_short_pathname(&tfname, &pbuf, &len)) 19053 return -1; 19054 19055 if (len == 0) 19056 { 19057 /* Don't have a valid filename, so shorten the rest of the 19058 * path if we can. This CAN give us invalid 8.3 filenames, but 19059 * there's not a lot of point in guessing what it might be. 19060 */ 19061 len = tflen; 19062 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19063 return -1; 19064 } 19065 19066 /* Count the paths backward to find the beginning of the desired string. */ 19067 for (p = tfname + len - 1; p >= tfname; --p) 19068 { 19069 #ifdef FEAT_MBYTE 19070 if (has_mbyte) 19071 p -= mb_head_off(tfname, p); 19072 #endif 19073 if (vim_ispathsep(*p)) 19074 { 19075 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19076 break; 19077 else 19078 sepcount --; 19079 } 19080 } 19081 if (hasTilde) 19082 { 19083 --p; 19084 if (p >= tfname) 19085 *p = '~'; 19086 else 19087 return -1; 19088 } 19089 else 19090 ++p; 19091 19092 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19093 vim_free(*bufp); 19094 *fnamelen = (int)STRLEN(p); 19095 *bufp = pbuf; 19096 *fnamep = p; 19097 19098 return 0; 19099 } 19100 #endif /* WIN3264 */ 19101 19102 /* 19103 * Adjust a filename, according to a string of modifiers. 19104 * *fnamep must be NUL terminated when called. When returning, the length is 19105 * determined by *fnamelen. 19106 * Returns valid flags. 19107 * When there is an error, *fnamep is set to NULL. 19108 */ 19109 int 19110 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19111 char_u *src; /* string with modifiers */ 19112 int *usedlen; /* characters after src that are used */ 19113 char_u **fnamep; /* file name so far */ 19114 char_u **bufp; /* buffer for allocated file name or NULL */ 19115 int *fnamelen; /* length of fnamep */ 19116 { 19117 int valid = 0; 19118 char_u *tail; 19119 char_u *s, *p, *pbuf; 19120 char_u dirname[MAXPATHL]; 19121 int c; 19122 int has_fullname = 0; 19123 #ifdef WIN3264 19124 int has_shortname = 0; 19125 #endif 19126 19127 repeat: 19128 /* ":p" - full path/file_name */ 19129 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19130 { 19131 has_fullname = 1; 19132 19133 valid |= VALID_PATH; 19134 *usedlen += 2; 19135 19136 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19137 if ((*fnamep)[0] == '~' 19138 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19139 && ((*fnamep)[1] == '/' 19140 # ifdef BACKSLASH_IN_FILENAME 19141 || (*fnamep)[1] == '\\' 19142 # endif 19143 || (*fnamep)[1] == NUL) 19144 19145 #endif 19146 ) 19147 { 19148 *fnamep = expand_env_save(*fnamep); 19149 vim_free(*bufp); /* free any allocated file name */ 19150 *bufp = *fnamep; 19151 if (*fnamep == NULL) 19152 return -1; 19153 } 19154 19155 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19156 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19157 { 19158 if (vim_ispathsep(*p) 19159 && p[1] == '.' 19160 && (p[2] == NUL 19161 || vim_ispathsep(p[2]) 19162 || (p[2] == '.' 19163 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19164 break; 19165 } 19166 19167 /* FullName_save() is slow, don't use it when not needed. */ 19168 if (*p != NUL || !vim_isAbsName(*fnamep)) 19169 { 19170 *fnamep = FullName_save(*fnamep, *p != NUL); 19171 vim_free(*bufp); /* free any allocated file name */ 19172 *bufp = *fnamep; 19173 if (*fnamep == NULL) 19174 return -1; 19175 } 19176 19177 /* Append a path separator to a directory. */ 19178 if (mch_isdir(*fnamep)) 19179 { 19180 /* Make room for one or two extra characters. */ 19181 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19182 vim_free(*bufp); /* free any allocated file name */ 19183 *bufp = *fnamep; 19184 if (*fnamep == NULL) 19185 return -1; 19186 add_pathsep(*fnamep); 19187 } 19188 } 19189 19190 /* ":." - path relative to the current directory */ 19191 /* ":~" - path relative to the home directory */ 19192 /* ":8" - shortname path - postponed till after */ 19193 while (src[*usedlen] == ':' 19194 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19195 { 19196 *usedlen += 2; 19197 if (c == '8') 19198 { 19199 #ifdef WIN3264 19200 has_shortname = 1; /* Postpone this. */ 19201 #endif 19202 continue; 19203 } 19204 pbuf = NULL; 19205 /* Need full path first (use expand_env() to remove a "~/") */ 19206 if (!has_fullname) 19207 { 19208 if (c == '.' && **fnamep == '~') 19209 p = pbuf = expand_env_save(*fnamep); 19210 else 19211 p = pbuf = FullName_save(*fnamep, FALSE); 19212 } 19213 else 19214 p = *fnamep; 19215 19216 has_fullname = 0; 19217 19218 if (p != NULL) 19219 { 19220 if (c == '.') 19221 { 19222 mch_dirname(dirname, MAXPATHL); 19223 s = shorten_fname(p, dirname); 19224 if (s != NULL) 19225 { 19226 *fnamep = s; 19227 if (pbuf != NULL) 19228 { 19229 vim_free(*bufp); /* free any allocated file name */ 19230 *bufp = pbuf; 19231 pbuf = NULL; 19232 } 19233 } 19234 } 19235 else 19236 { 19237 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19238 /* Only replace it when it starts with '~' */ 19239 if (*dirname == '~') 19240 { 19241 s = vim_strsave(dirname); 19242 if (s != NULL) 19243 { 19244 *fnamep = s; 19245 vim_free(*bufp); 19246 *bufp = s; 19247 } 19248 } 19249 } 19250 vim_free(pbuf); 19251 } 19252 } 19253 19254 tail = gettail(*fnamep); 19255 *fnamelen = (int)STRLEN(*fnamep); 19256 19257 /* ":h" - head, remove "/file_name", can be repeated */ 19258 /* Don't remove the first "/" or "c:\" */ 19259 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19260 { 19261 valid |= VALID_HEAD; 19262 *usedlen += 2; 19263 s = get_past_head(*fnamep); 19264 while (tail > s && after_pathsep(s, tail)) 19265 --tail; 19266 *fnamelen = (int)(tail - *fnamep); 19267 #ifdef VMS 19268 if (*fnamelen > 0) 19269 *fnamelen += 1; /* the path separator is part of the path */ 19270 #endif 19271 while (tail > s && !after_pathsep(s, tail)) 19272 mb_ptr_back(*fnamep, tail); 19273 } 19274 19275 /* ":8" - shortname */ 19276 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19277 { 19278 *usedlen += 2; 19279 #ifdef WIN3264 19280 has_shortname = 1; 19281 #endif 19282 } 19283 19284 #ifdef WIN3264 19285 /* Check shortname after we have done 'heads' and before we do 'tails' 19286 */ 19287 if (has_shortname) 19288 { 19289 pbuf = NULL; 19290 /* Copy the string if it is shortened by :h */ 19291 if (*fnamelen < (int)STRLEN(*fnamep)) 19292 { 19293 p = vim_strnsave(*fnamep, *fnamelen); 19294 if (p == 0) 19295 return -1; 19296 vim_free(*bufp); 19297 *bufp = *fnamep = p; 19298 } 19299 19300 /* Split into two implementations - makes it easier. First is where 19301 * there isn't a full name already, second is where there is. 19302 */ 19303 if (!has_fullname && !vim_isAbsName(*fnamep)) 19304 { 19305 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19306 return -1; 19307 } 19308 else 19309 { 19310 int l; 19311 19312 /* Simple case, already have the full-name 19313 * Nearly always shorter, so try first time. */ 19314 l = *fnamelen; 19315 if (!get_short_pathname(fnamep, bufp, &l)) 19316 return -1; 19317 19318 if (l == 0) 19319 { 19320 /* Couldn't find the filename.. search the paths. 19321 */ 19322 l = *fnamelen; 19323 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19324 return -1; 19325 } 19326 *fnamelen = l; 19327 } 19328 } 19329 #endif /* WIN3264 */ 19330 19331 /* ":t" - tail, just the basename */ 19332 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19333 { 19334 *usedlen += 2; 19335 *fnamelen -= (int)(tail - *fnamep); 19336 *fnamep = tail; 19337 } 19338 19339 /* ":e" - extension, can be repeated */ 19340 /* ":r" - root, without extension, can be repeated */ 19341 while (src[*usedlen] == ':' 19342 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19343 { 19344 /* find a '.' in the tail: 19345 * - for second :e: before the current fname 19346 * - otherwise: The last '.' 19347 */ 19348 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19349 s = *fnamep - 2; 19350 else 19351 s = *fnamep + *fnamelen - 1; 19352 for ( ; s > tail; --s) 19353 if (s[0] == '.') 19354 break; 19355 if (src[*usedlen + 1] == 'e') /* :e */ 19356 { 19357 if (s > tail) 19358 { 19359 *fnamelen += (int)(*fnamep - (s + 1)); 19360 *fnamep = s + 1; 19361 #ifdef VMS 19362 /* cut version from the extension */ 19363 s = *fnamep + *fnamelen - 1; 19364 for ( ; s > *fnamep; --s) 19365 if (s[0] == ';') 19366 break; 19367 if (s > *fnamep) 19368 *fnamelen = s - *fnamep; 19369 #endif 19370 } 19371 else if (*fnamep <= tail) 19372 *fnamelen = 0; 19373 } 19374 else /* :r */ 19375 { 19376 if (s > tail) /* remove one extension */ 19377 *fnamelen = (int)(s - *fnamep); 19378 } 19379 *usedlen += 2; 19380 } 19381 19382 /* ":s?pat?foo?" - substitute */ 19383 /* ":gs?pat?foo?" - global substitute */ 19384 if (src[*usedlen] == ':' 19385 && (src[*usedlen + 1] == 's' 19386 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19387 { 19388 char_u *str; 19389 char_u *pat; 19390 char_u *sub; 19391 int sep; 19392 char_u *flags; 19393 int didit = FALSE; 19394 19395 flags = (char_u *)""; 19396 s = src + *usedlen + 2; 19397 if (src[*usedlen + 1] == 'g') 19398 { 19399 flags = (char_u *)"g"; 19400 ++s; 19401 } 19402 19403 sep = *s++; 19404 if (sep) 19405 { 19406 /* find end of pattern */ 19407 p = vim_strchr(s, sep); 19408 if (p != NULL) 19409 { 19410 pat = vim_strnsave(s, (int)(p - s)); 19411 if (pat != NULL) 19412 { 19413 s = p + 1; 19414 /* find end of substitution */ 19415 p = vim_strchr(s, sep); 19416 if (p != NULL) 19417 { 19418 sub = vim_strnsave(s, (int)(p - s)); 19419 str = vim_strnsave(*fnamep, *fnamelen); 19420 if (sub != NULL && str != NULL) 19421 { 19422 *usedlen = (int)(p + 1 - src); 19423 s = do_string_sub(str, pat, sub, flags); 19424 if (s != NULL) 19425 { 19426 *fnamep = s; 19427 *fnamelen = (int)STRLEN(s); 19428 vim_free(*bufp); 19429 *bufp = s; 19430 didit = TRUE; 19431 } 19432 } 19433 vim_free(sub); 19434 vim_free(str); 19435 } 19436 vim_free(pat); 19437 } 19438 } 19439 /* after using ":s", repeat all the modifiers */ 19440 if (didit) 19441 goto repeat; 19442 } 19443 } 19444 19445 return valid; 19446 } 19447 19448 /* 19449 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19450 * "flags" can be "g" to do a global substitute. 19451 * Returns an allocated string, NULL for error. 19452 */ 19453 char_u * 19454 do_string_sub(str, pat, sub, flags) 19455 char_u *str; 19456 char_u *pat; 19457 char_u *sub; 19458 char_u *flags; 19459 { 19460 int sublen; 19461 regmatch_T regmatch; 19462 int i; 19463 int do_all; 19464 char_u *tail; 19465 garray_T ga; 19466 char_u *ret; 19467 char_u *save_cpo; 19468 19469 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19470 save_cpo = p_cpo; 19471 p_cpo = (char_u *)""; 19472 19473 ga_init2(&ga, 1, 200); 19474 19475 do_all = (flags[0] == 'g'); 19476 19477 regmatch.rm_ic = p_ic; 19478 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19479 if (regmatch.regprog != NULL) 19480 { 19481 tail = str; 19482 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19483 { 19484 /* 19485 * Get some space for a temporary buffer to do the substitution 19486 * into. It will contain: 19487 * - The text up to where the match is. 19488 * - The substituted text. 19489 * - The text after the match. 19490 */ 19491 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19492 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19493 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19494 { 19495 ga_clear(&ga); 19496 break; 19497 } 19498 19499 /* copy the text up to where the match is */ 19500 i = (int)(regmatch.startp[0] - tail); 19501 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19502 /* add the substituted text */ 19503 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19504 + ga.ga_len + i, TRUE, TRUE, FALSE); 19505 ga.ga_len += i + sublen - 1; 19506 /* avoid getting stuck on a match with an empty string */ 19507 if (tail == regmatch.endp[0]) 19508 { 19509 if (*tail == NUL) 19510 break; 19511 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19512 ++ga.ga_len; 19513 } 19514 else 19515 { 19516 tail = regmatch.endp[0]; 19517 if (*tail == NUL) 19518 break; 19519 } 19520 if (!do_all) 19521 break; 19522 } 19523 19524 if (ga.ga_data != NULL) 19525 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19526 19527 vim_free(regmatch.regprog); 19528 } 19529 19530 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19531 ga_clear(&ga); 19532 p_cpo = save_cpo; 19533 19534 return ret; 19535 } 19536 19537 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19538