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 DEBUG 10047 "debug", 10048 #endif 10049 #ifdef FEAT_CON_DIALOG 10050 "dialog_con", 10051 #endif 10052 #ifdef FEAT_GUI_DIALOG 10053 "dialog_gui", 10054 #endif 10055 #ifdef FEAT_DIFF 10056 "diff", 10057 #endif 10058 #ifdef FEAT_DIGRAPHS 10059 "digraphs", 10060 #endif 10061 #ifdef FEAT_DND 10062 "dnd", 10063 #endif 10064 #ifdef FEAT_EMACS_TAGS 10065 "emacs_tags", 10066 #endif 10067 "eval", /* always present, of course! */ 10068 #ifdef FEAT_EX_EXTRA 10069 "ex_extra", 10070 #endif 10071 #ifdef FEAT_SEARCH_EXTRA 10072 "extra_search", 10073 #endif 10074 #ifdef FEAT_FKMAP 10075 "farsi", 10076 #endif 10077 #ifdef FEAT_SEARCHPATH 10078 "file_in_path", 10079 #endif 10080 #if defined(UNIX) && !defined(USE_SYSTEM) 10081 "filterpipe", 10082 #endif 10083 #ifdef FEAT_FIND_ID 10084 "find_in_path", 10085 #endif 10086 #ifdef FEAT_FOLDING 10087 "folding", 10088 #endif 10089 #ifdef FEAT_FOOTER 10090 "footer", 10091 #endif 10092 #if !defined(USE_SYSTEM) && defined(UNIX) 10093 "fork", 10094 #endif 10095 #ifdef FEAT_GETTEXT 10096 "gettext", 10097 #endif 10098 #ifdef FEAT_GUI 10099 "gui", 10100 #endif 10101 #ifdef FEAT_GUI_ATHENA 10102 # ifdef FEAT_GUI_NEXTAW 10103 "gui_neXtaw", 10104 # else 10105 "gui_athena", 10106 # endif 10107 #endif 10108 #ifdef FEAT_GUI_KDE 10109 "gui_kde", 10110 #endif 10111 #ifdef FEAT_GUI_GTK 10112 "gui_gtk", 10113 # ifdef HAVE_GTK2 10114 "gui_gtk2", 10115 # endif 10116 #endif 10117 #ifdef FEAT_GUI_MAC 10118 "gui_mac", 10119 #endif 10120 #ifdef FEAT_GUI_MOTIF 10121 "gui_motif", 10122 #endif 10123 #ifdef FEAT_GUI_PHOTON 10124 "gui_photon", 10125 #endif 10126 #ifdef FEAT_GUI_W16 10127 "gui_win16", 10128 #endif 10129 #ifdef FEAT_GUI_W32 10130 "gui_win32", 10131 #endif 10132 #ifdef FEAT_HANGULIN 10133 "hangul_input", 10134 #endif 10135 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10136 "iconv", 10137 #endif 10138 #ifdef FEAT_INS_EXPAND 10139 "insert_expand", 10140 #endif 10141 #ifdef FEAT_JUMPLIST 10142 "jumplist", 10143 #endif 10144 #ifdef FEAT_KEYMAP 10145 "keymap", 10146 #endif 10147 #ifdef FEAT_LANGMAP 10148 "langmap", 10149 #endif 10150 #ifdef FEAT_LIBCALL 10151 "libcall", 10152 #endif 10153 #ifdef FEAT_LINEBREAK 10154 "linebreak", 10155 #endif 10156 #ifdef FEAT_LISP 10157 "lispindent", 10158 #endif 10159 #ifdef FEAT_LISTCMDS 10160 "listcmds", 10161 #endif 10162 #ifdef FEAT_LOCALMAP 10163 "localmap", 10164 #endif 10165 #ifdef FEAT_MENU 10166 "menu", 10167 #endif 10168 #ifdef FEAT_SESSION 10169 "mksession", 10170 #endif 10171 #ifdef FEAT_MODIFY_FNAME 10172 "modify_fname", 10173 #endif 10174 #ifdef FEAT_MOUSE 10175 "mouse", 10176 #endif 10177 #ifdef FEAT_MOUSESHAPE 10178 "mouseshape", 10179 #endif 10180 #if defined(UNIX) || defined(VMS) 10181 # ifdef FEAT_MOUSE_DEC 10182 "mouse_dec", 10183 # endif 10184 # ifdef FEAT_MOUSE_GPM 10185 "mouse_gpm", 10186 # endif 10187 # ifdef FEAT_MOUSE_JSB 10188 "mouse_jsbterm", 10189 # endif 10190 # ifdef FEAT_MOUSE_NET 10191 "mouse_netterm", 10192 # endif 10193 # ifdef FEAT_MOUSE_PTERM 10194 "mouse_pterm", 10195 # endif 10196 # ifdef FEAT_MOUSE_XTERM 10197 "mouse_xterm", 10198 # endif 10199 #endif 10200 #ifdef FEAT_MBYTE 10201 "multi_byte", 10202 #endif 10203 #ifdef FEAT_MBYTE_IME 10204 "multi_byte_ime", 10205 #endif 10206 #ifdef FEAT_MULTI_LANG 10207 "multi_lang", 10208 #endif 10209 #ifdef FEAT_MZSCHEME 10210 #ifndef DYNAMIC_MZSCHEME 10211 "mzscheme", 10212 #endif 10213 #endif 10214 #ifdef FEAT_OLE 10215 "ole", 10216 #endif 10217 #ifdef FEAT_OSFILETYPE 10218 "osfiletype", 10219 #endif 10220 #ifdef FEAT_PATH_EXTRA 10221 "path_extra", 10222 #endif 10223 #ifdef FEAT_PERL 10224 #ifndef DYNAMIC_PERL 10225 "perl", 10226 #endif 10227 #endif 10228 #ifdef FEAT_PYTHON 10229 #ifndef DYNAMIC_PYTHON 10230 "python", 10231 #endif 10232 #endif 10233 #ifdef FEAT_POSTSCRIPT 10234 "postscript", 10235 #endif 10236 #ifdef FEAT_PRINTER 10237 "printer", 10238 #endif 10239 #ifdef FEAT_PROFILE 10240 "profile", 10241 #endif 10242 #ifdef FEAT_QUICKFIX 10243 "quickfix", 10244 #endif 10245 #ifdef FEAT_RIGHTLEFT 10246 "rightleft", 10247 #endif 10248 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10249 "ruby", 10250 #endif 10251 #ifdef FEAT_SCROLLBIND 10252 "scrollbind", 10253 #endif 10254 #ifdef FEAT_CMDL_INFO 10255 "showcmd", 10256 "cmdline_info", 10257 #endif 10258 #ifdef FEAT_SIGNS 10259 "signs", 10260 #endif 10261 #ifdef FEAT_SMARTINDENT 10262 "smartindent", 10263 #endif 10264 #ifdef FEAT_SNIFF 10265 "sniff", 10266 #endif 10267 #ifdef FEAT_STL_OPT 10268 "statusline", 10269 #endif 10270 #ifdef FEAT_SUN_WORKSHOP 10271 "sun_workshop", 10272 #endif 10273 #ifdef FEAT_NETBEANS_INTG 10274 "netbeans_intg", 10275 #endif 10276 #ifdef FEAT_SYN_HL 10277 "spell", 10278 #endif 10279 #ifdef FEAT_SYN_HL 10280 "syntax", 10281 #endif 10282 #if defined(USE_SYSTEM) || !defined(UNIX) 10283 "system", 10284 #endif 10285 #ifdef FEAT_TAG_BINS 10286 "tag_binary", 10287 #endif 10288 #ifdef FEAT_TAG_OLDSTATIC 10289 "tag_old_static", 10290 #endif 10291 #ifdef FEAT_TAG_ANYWHITE 10292 "tag_any_white", 10293 #endif 10294 #ifdef FEAT_TCL 10295 # ifndef DYNAMIC_TCL 10296 "tcl", 10297 # endif 10298 #endif 10299 #ifdef TERMINFO 10300 "terminfo", 10301 #endif 10302 #ifdef FEAT_TERMRESPONSE 10303 "termresponse", 10304 #endif 10305 #ifdef FEAT_TEXTOBJ 10306 "textobjects", 10307 #endif 10308 #ifdef HAVE_TGETENT 10309 "tgetent", 10310 #endif 10311 #ifdef FEAT_TITLE 10312 "title", 10313 #endif 10314 #ifdef FEAT_TOOLBAR 10315 "toolbar", 10316 #endif 10317 #ifdef FEAT_USR_CMDS 10318 "user-commands", /* was accidentally included in 5.4 */ 10319 "user_commands", 10320 #endif 10321 #ifdef FEAT_VIMINFO 10322 "viminfo", 10323 #endif 10324 #ifdef FEAT_VERTSPLIT 10325 "vertsplit", 10326 #endif 10327 #ifdef FEAT_VIRTUALEDIT 10328 "virtualedit", 10329 #endif 10330 #ifdef FEAT_VISUAL 10331 "visual", 10332 #endif 10333 #ifdef FEAT_VISUALEXTRA 10334 "visualextra", 10335 #endif 10336 #ifdef FEAT_VREPLACE 10337 "vreplace", 10338 #endif 10339 #ifdef FEAT_WILDIGN 10340 "wildignore", 10341 #endif 10342 #ifdef FEAT_WILDMENU 10343 "wildmenu", 10344 #endif 10345 #ifdef FEAT_WINDOWS 10346 "windows", 10347 #endif 10348 #ifdef FEAT_WAK 10349 "winaltkeys", 10350 #endif 10351 #ifdef FEAT_WRITEBACKUP 10352 "writebackup", 10353 #endif 10354 #ifdef FEAT_XIM 10355 "xim", 10356 #endif 10357 #ifdef FEAT_XFONTSET 10358 "xfontset", 10359 #endif 10360 #ifdef USE_XSMP 10361 "xsmp", 10362 #endif 10363 #ifdef USE_XSMP_INTERACT 10364 "xsmp_interact", 10365 #endif 10366 #ifdef FEAT_XCLIPBOARD 10367 "xterm_clipboard", 10368 #endif 10369 #ifdef FEAT_XTERM_SAVE 10370 "xterm_save", 10371 #endif 10372 #if defined(UNIX) && defined(FEAT_X11) 10373 "X11", 10374 #endif 10375 NULL 10376 }; 10377 10378 name = get_tv_string(&argvars[0]); 10379 for (i = 0; has_list[i] != NULL; ++i) 10380 if (STRICMP(name, has_list[i]) == 0) 10381 { 10382 n = TRUE; 10383 break; 10384 } 10385 10386 if (n == FALSE) 10387 { 10388 if (STRNICMP(name, "patch", 5) == 0) 10389 n = has_patch(atoi((char *)name + 5)); 10390 else if (STRICMP(name, "vim_starting") == 0) 10391 n = (starting != 0); 10392 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10393 else if (STRICMP(name, "balloon_multiline") == 0) 10394 n = multiline_balloon_available(); 10395 #endif 10396 #ifdef DYNAMIC_TCL 10397 else if (STRICMP(name, "tcl") == 0) 10398 n = tcl_enabled(FALSE); 10399 #endif 10400 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10401 else if (STRICMP(name, "iconv") == 0) 10402 n = iconv_enabled(FALSE); 10403 #endif 10404 #ifdef DYNAMIC_MZSCHEME 10405 else if (STRICMP(name, "mzscheme") == 0) 10406 n = mzscheme_enabled(FALSE); 10407 #endif 10408 #ifdef DYNAMIC_RUBY 10409 else if (STRICMP(name, "ruby") == 0) 10410 n = ruby_enabled(FALSE); 10411 #endif 10412 #ifdef DYNAMIC_PYTHON 10413 else if (STRICMP(name, "python") == 0) 10414 n = python_enabled(FALSE); 10415 #endif 10416 #ifdef DYNAMIC_PERL 10417 else if (STRICMP(name, "perl") == 0) 10418 n = perl_enabled(FALSE); 10419 #endif 10420 #ifdef FEAT_GUI 10421 else if (STRICMP(name, "gui_running") == 0) 10422 n = (gui.in_use || gui.starting); 10423 # ifdef FEAT_GUI_W32 10424 else if (STRICMP(name, "gui_win32s") == 0) 10425 n = gui_is_win32s(); 10426 # endif 10427 # ifdef FEAT_BROWSE 10428 else if (STRICMP(name, "browse") == 0) 10429 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10430 # endif 10431 #endif 10432 #ifdef FEAT_SYN_HL 10433 else if (STRICMP(name, "syntax_items") == 0) 10434 n = syntax_present(curbuf); 10435 #endif 10436 #if defined(WIN3264) 10437 else if (STRICMP(name, "win95") == 0) 10438 n = mch_windows95(); 10439 #endif 10440 #ifdef FEAT_NETBEANS_INTG 10441 else if (STRICMP(name, "netbeans_enabled") == 0) 10442 n = usingNetbeans; 10443 #endif 10444 } 10445 10446 rettv->vval.v_number = n; 10447 } 10448 10449 /* 10450 * "has_key()" function 10451 */ 10452 static void 10453 f_has_key(argvars, rettv) 10454 typval_T *argvars; 10455 typval_T *rettv; 10456 { 10457 rettv->vval.v_number = 0; 10458 if (argvars[0].v_type != VAR_DICT) 10459 { 10460 EMSG(_(e_dictreq)); 10461 return; 10462 } 10463 if (argvars[0].vval.v_dict == NULL) 10464 return; 10465 10466 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10467 get_tv_string(&argvars[1]), -1) != NULL; 10468 } 10469 10470 /* 10471 * "hasmapto()" function 10472 */ 10473 static void 10474 f_hasmapto(argvars, rettv) 10475 typval_T *argvars; 10476 typval_T *rettv; 10477 { 10478 char_u *name; 10479 char_u *mode; 10480 char_u buf[NUMBUFLEN]; 10481 10482 name = get_tv_string(&argvars[0]); 10483 if (argvars[1].v_type == VAR_UNKNOWN) 10484 mode = (char_u *)"nvo"; 10485 else 10486 mode = get_tv_string_buf(&argvars[1], buf); 10487 10488 if (map_to_exists(name, mode)) 10489 rettv->vval.v_number = TRUE; 10490 else 10491 rettv->vval.v_number = FALSE; 10492 } 10493 10494 /* 10495 * "histadd()" function 10496 */ 10497 /*ARGSUSED*/ 10498 static void 10499 f_histadd(argvars, rettv) 10500 typval_T *argvars; 10501 typval_T *rettv; 10502 { 10503 #ifdef FEAT_CMDHIST 10504 int histype; 10505 char_u *str; 10506 char_u buf[NUMBUFLEN]; 10507 #endif 10508 10509 rettv->vval.v_number = FALSE; 10510 if (check_restricted() || check_secure()) 10511 return; 10512 #ifdef FEAT_CMDHIST 10513 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10514 histype = str != NULL ? get_histtype(str) : -1; 10515 if (histype >= 0) 10516 { 10517 str = get_tv_string_buf(&argvars[1], buf); 10518 if (*str != NUL) 10519 { 10520 add_to_history(histype, str, FALSE, NUL); 10521 rettv->vval.v_number = TRUE; 10522 return; 10523 } 10524 } 10525 #endif 10526 } 10527 10528 /* 10529 * "histdel()" function 10530 */ 10531 /*ARGSUSED*/ 10532 static void 10533 f_histdel(argvars, rettv) 10534 typval_T *argvars; 10535 typval_T *rettv; 10536 { 10537 #ifdef FEAT_CMDHIST 10538 int n; 10539 char_u buf[NUMBUFLEN]; 10540 char_u *str; 10541 10542 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10543 if (str == NULL) 10544 n = 0; 10545 else if (argvars[1].v_type == VAR_UNKNOWN) 10546 /* only one argument: clear entire history */ 10547 n = clr_history(get_histtype(str)); 10548 else if (argvars[1].v_type == VAR_NUMBER) 10549 /* index given: remove that entry */ 10550 n = del_history_idx(get_histtype(str), 10551 (int)get_tv_number(&argvars[1])); 10552 else 10553 /* string given: remove all matching entries */ 10554 n = del_history_entry(get_histtype(str), 10555 get_tv_string_buf(&argvars[1], buf)); 10556 rettv->vval.v_number = n; 10557 #else 10558 rettv->vval.v_number = 0; 10559 #endif 10560 } 10561 10562 /* 10563 * "histget()" function 10564 */ 10565 /*ARGSUSED*/ 10566 static void 10567 f_histget(argvars, rettv) 10568 typval_T *argvars; 10569 typval_T *rettv; 10570 { 10571 #ifdef FEAT_CMDHIST 10572 int type; 10573 int idx; 10574 char_u *str; 10575 10576 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10577 if (str == NULL) 10578 rettv->vval.v_string = NULL; 10579 else 10580 { 10581 type = get_histtype(str); 10582 if (argvars[1].v_type == VAR_UNKNOWN) 10583 idx = get_history_idx(type); 10584 else 10585 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10586 /* -1 on type error */ 10587 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10588 } 10589 #else 10590 rettv->vval.v_string = NULL; 10591 #endif 10592 rettv->v_type = VAR_STRING; 10593 } 10594 10595 /* 10596 * "histnr()" function 10597 */ 10598 /*ARGSUSED*/ 10599 static void 10600 f_histnr(argvars, rettv) 10601 typval_T *argvars; 10602 typval_T *rettv; 10603 { 10604 int i; 10605 10606 #ifdef FEAT_CMDHIST 10607 char_u *history = get_tv_string_chk(&argvars[0]); 10608 10609 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10610 if (i >= HIST_CMD && i < HIST_COUNT) 10611 i = get_history_idx(i); 10612 else 10613 #endif 10614 i = -1; 10615 rettv->vval.v_number = i; 10616 } 10617 10618 /* 10619 * "highlightID(name)" function 10620 */ 10621 static void 10622 f_hlID(argvars, rettv) 10623 typval_T *argvars; 10624 typval_T *rettv; 10625 { 10626 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10627 } 10628 10629 /* 10630 * "highlight_exists()" function 10631 */ 10632 static void 10633 f_hlexists(argvars, rettv) 10634 typval_T *argvars; 10635 typval_T *rettv; 10636 { 10637 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10638 } 10639 10640 /* 10641 * "hostname()" function 10642 */ 10643 /*ARGSUSED*/ 10644 static void 10645 f_hostname(argvars, rettv) 10646 typval_T *argvars; 10647 typval_T *rettv; 10648 { 10649 char_u hostname[256]; 10650 10651 mch_get_host_name(hostname, 256); 10652 rettv->v_type = VAR_STRING; 10653 rettv->vval.v_string = vim_strsave(hostname); 10654 } 10655 10656 /* 10657 * iconv() function 10658 */ 10659 /*ARGSUSED*/ 10660 static void 10661 f_iconv(argvars, rettv) 10662 typval_T *argvars; 10663 typval_T *rettv; 10664 { 10665 #ifdef FEAT_MBYTE 10666 char_u buf1[NUMBUFLEN]; 10667 char_u buf2[NUMBUFLEN]; 10668 char_u *from, *to, *str; 10669 vimconv_T vimconv; 10670 #endif 10671 10672 rettv->v_type = VAR_STRING; 10673 rettv->vval.v_string = NULL; 10674 10675 #ifdef FEAT_MBYTE 10676 str = get_tv_string(&argvars[0]); 10677 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10678 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10679 vimconv.vc_type = CONV_NONE; 10680 convert_setup(&vimconv, from, to); 10681 10682 /* If the encodings are equal, no conversion needed. */ 10683 if (vimconv.vc_type == CONV_NONE) 10684 rettv->vval.v_string = vim_strsave(str); 10685 else 10686 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10687 10688 convert_setup(&vimconv, NULL, NULL); 10689 vim_free(from); 10690 vim_free(to); 10691 #endif 10692 } 10693 10694 /* 10695 * "indent()" function 10696 */ 10697 static void 10698 f_indent(argvars, rettv) 10699 typval_T *argvars; 10700 typval_T *rettv; 10701 { 10702 linenr_T lnum; 10703 10704 lnum = get_tv_lnum(argvars); 10705 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10706 rettv->vval.v_number = get_indent_lnum(lnum); 10707 else 10708 rettv->vval.v_number = -1; 10709 } 10710 10711 /* 10712 * "index()" function 10713 */ 10714 static void 10715 f_index(argvars, rettv) 10716 typval_T *argvars; 10717 typval_T *rettv; 10718 { 10719 list_T *l; 10720 listitem_T *item; 10721 long idx = 0; 10722 int ic = FALSE; 10723 10724 rettv->vval.v_number = -1; 10725 if (argvars[0].v_type != VAR_LIST) 10726 { 10727 EMSG(_(e_listreq)); 10728 return; 10729 } 10730 l = argvars[0].vval.v_list; 10731 if (l != NULL) 10732 { 10733 item = l->lv_first; 10734 if (argvars[2].v_type != VAR_UNKNOWN) 10735 { 10736 int error = FALSE; 10737 10738 /* Start at specified item. Use the cached index that list_find() 10739 * sets, so that a negative number also works. */ 10740 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10741 idx = l->lv_idx; 10742 if (argvars[3].v_type != VAR_UNKNOWN) 10743 ic = get_tv_number_chk(&argvars[3], &error); 10744 if (error) 10745 item = NULL; 10746 } 10747 10748 for ( ; item != NULL; item = item->li_next, ++idx) 10749 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10750 { 10751 rettv->vval.v_number = idx; 10752 break; 10753 } 10754 } 10755 } 10756 10757 static int inputsecret_flag = 0; 10758 10759 /* 10760 * "input()" function 10761 * Also handles inputsecret() when inputsecret is set. 10762 */ 10763 static void 10764 f_input(argvars, rettv) 10765 typval_T *argvars; 10766 typval_T *rettv; 10767 { 10768 char_u *prompt = get_tv_string_chk(&argvars[0]); 10769 char_u *p = NULL; 10770 int c; 10771 char_u buf[NUMBUFLEN]; 10772 int cmd_silent_save = cmd_silent; 10773 char_u *defstr = (char_u *)""; 10774 10775 rettv->v_type = VAR_STRING; 10776 10777 #ifdef NO_CONSOLE_INPUT 10778 /* While starting up, there is no place to enter text. */ 10779 if (no_console_input()) 10780 { 10781 rettv->vval.v_string = NULL; 10782 return; 10783 } 10784 #endif 10785 10786 cmd_silent = FALSE; /* Want to see the prompt. */ 10787 if (prompt != NULL) 10788 { 10789 /* Only the part of the message after the last NL is considered as 10790 * prompt for the command line */ 10791 p = vim_strrchr(prompt, '\n'); 10792 if (p == NULL) 10793 p = prompt; 10794 else 10795 { 10796 ++p; 10797 c = *p; 10798 *p = NUL; 10799 msg_start(); 10800 msg_clr_eos(); 10801 msg_puts_attr(prompt, echo_attr); 10802 msg_didout = FALSE; 10803 msg_starthere(); 10804 *p = c; 10805 } 10806 cmdline_row = msg_row; 10807 10808 if (argvars[1].v_type != VAR_UNKNOWN) 10809 { 10810 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10811 if (defstr != NULL) 10812 stuffReadbuffSpec(defstr); 10813 } 10814 10815 if (defstr != NULL) 10816 rettv->vval.v_string = 10817 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr); 10818 10819 /* since the user typed this, no need to wait for return */ 10820 need_wait_return = FALSE; 10821 msg_didout = FALSE; 10822 } 10823 cmd_silent = cmd_silent_save; 10824 } 10825 10826 /* 10827 * "inputdialog()" function 10828 */ 10829 static void 10830 f_inputdialog(argvars, rettv) 10831 typval_T *argvars; 10832 typval_T *rettv; 10833 { 10834 #if defined(FEAT_GUI_TEXTDIALOG) 10835 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10836 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10837 { 10838 char_u *message; 10839 char_u buf[NUMBUFLEN]; 10840 char_u *defstr = (char_u *)""; 10841 10842 message = get_tv_string_chk(&argvars[0]); 10843 if (argvars[1].v_type != VAR_UNKNOWN 10844 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10845 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10846 else 10847 IObuff[0] = NUL; 10848 if (message != NULL && defstr != NULL 10849 && do_dialog(VIM_QUESTION, NULL, message, 10850 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10851 rettv->vval.v_string = vim_strsave(IObuff); 10852 else 10853 { 10854 if (message != NULL && defstr != NULL 10855 && argvars[1].v_type != VAR_UNKNOWN 10856 && argvars[2].v_type != VAR_UNKNOWN) 10857 rettv->vval.v_string = vim_strsave( 10858 get_tv_string_buf(&argvars[2], buf)); 10859 else 10860 rettv->vval.v_string = NULL; 10861 } 10862 rettv->v_type = VAR_STRING; 10863 } 10864 else 10865 #endif 10866 f_input(argvars, rettv); 10867 } 10868 10869 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 10870 10871 /* 10872 * "inputrestore()" function 10873 */ 10874 /*ARGSUSED*/ 10875 static void 10876 f_inputrestore(argvars, rettv) 10877 typval_T *argvars; 10878 typval_T *rettv; 10879 { 10880 if (ga_userinput.ga_len > 0) 10881 { 10882 --ga_userinput.ga_len; 10883 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 10884 + ga_userinput.ga_len); 10885 rettv->vval.v_number = 0; /* OK */ 10886 } 10887 else if (p_verbose > 1) 10888 { 10889 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 10890 rettv->vval.v_number = 1; /* Failed */ 10891 } 10892 } 10893 10894 /* 10895 * "inputsave()" function 10896 */ 10897 /*ARGSUSED*/ 10898 static void 10899 f_inputsave(argvars, rettv) 10900 typval_T *argvars; 10901 typval_T *rettv; 10902 { 10903 /* Add an entry to the stack of typehead storage. */ 10904 if (ga_grow(&ga_userinput, 1) == OK) 10905 { 10906 save_typeahead((tasave_T *)(ga_userinput.ga_data) 10907 + ga_userinput.ga_len); 10908 ++ga_userinput.ga_len; 10909 rettv->vval.v_number = 0; /* OK */ 10910 } 10911 else 10912 rettv->vval.v_number = 1; /* Failed */ 10913 } 10914 10915 /* 10916 * "inputsecret()" function 10917 */ 10918 static void 10919 f_inputsecret(argvars, rettv) 10920 typval_T *argvars; 10921 typval_T *rettv; 10922 { 10923 ++cmdline_star; 10924 ++inputsecret_flag; 10925 f_input(argvars, rettv); 10926 --cmdline_star; 10927 --inputsecret_flag; 10928 } 10929 10930 /* 10931 * "insert()" function 10932 */ 10933 static void 10934 f_insert(argvars, rettv) 10935 typval_T *argvars; 10936 typval_T *rettv; 10937 { 10938 long before = 0; 10939 listitem_T *item; 10940 list_T *l; 10941 int error = FALSE; 10942 10943 rettv->vval.v_number = 0; 10944 if (argvars[0].v_type != VAR_LIST) 10945 EMSG2(_(e_listarg), "insert()"); 10946 else if ((l = argvars[0].vval.v_list) != NULL 10947 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 10948 { 10949 if (argvars[2].v_type != VAR_UNKNOWN) 10950 before = get_tv_number_chk(&argvars[2], &error); 10951 if (error) 10952 return; /* type error; errmsg already given */ 10953 10954 if (before == l->lv_len) 10955 item = NULL; 10956 else 10957 { 10958 item = list_find(l, before); 10959 if (item == NULL) 10960 { 10961 EMSGN(_(e_listidx), before); 10962 l = NULL; 10963 } 10964 } 10965 if (l != NULL) 10966 { 10967 list_insert_tv(l, &argvars[1], item); 10968 copy_tv(&argvars[0], rettv); 10969 } 10970 } 10971 } 10972 10973 /* 10974 * "isdirectory()" function 10975 */ 10976 static void 10977 f_isdirectory(argvars, rettv) 10978 typval_T *argvars; 10979 typval_T *rettv; 10980 { 10981 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 10982 } 10983 10984 /* 10985 * "islocked()" function 10986 */ 10987 static void 10988 f_islocked(argvars, rettv) 10989 typval_T *argvars; 10990 typval_T *rettv; 10991 { 10992 lval_T lv; 10993 char_u *end; 10994 dictitem_T *di; 10995 10996 rettv->vval.v_number = -1; 10997 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 10998 FNE_CHECK_START); 10999 if (end != NULL && lv.ll_name != NULL) 11000 { 11001 if (*end != NUL) 11002 EMSG(_(e_trailing)); 11003 else 11004 { 11005 if (lv.ll_tv == NULL) 11006 { 11007 if (check_changedtick(lv.ll_name)) 11008 rettv->vval.v_number = 1; /* always locked */ 11009 else 11010 { 11011 di = find_var(lv.ll_name, NULL); 11012 if (di != NULL) 11013 { 11014 /* Consider a variable locked when: 11015 * 1. the variable itself is locked 11016 * 2. the value of the variable is locked. 11017 * 3. the List or Dict value is locked. 11018 */ 11019 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11020 || tv_islocked(&di->di_tv)); 11021 } 11022 } 11023 } 11024 else if (lv.ll_range) 11025 EMSG(_("E745: Range not allowed")); 11026 else if (lv.ll_newkey != NULL) 11027 EMSG2(_(e_dictkey), lv.ll_newkey); 11028 else if (lv.ll_list != NULL) 11029 /* List item. */ 11030 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11031 else 11032 /* Dictionary item. */ 11033 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11034 } 11035 } 11036 11037 clear_lval(&lv); 11038 } 11039 11040 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11041 11042 /* 11043 * Turn a dict into a list: 11044 * "what" == 0: list of keys 11045 * "what" == 1: list of values 11046 * "what" == 2: list of items 11047 */ 11048 static void 11049 dict_list(argvars, rettv, what) 11050 typval_T *argvars; 11051 typval_T *rettv; 11052 int what; 11053 { 11054 list_T *l; 11055 list_T *l2; 11056 dictitem_T *di; 11057 hashitem_T *hi; 11058 listitem_T *li; 11059 listitem_T *li2; 11060 dict_T *d; 11061 int todo; 11062 11063 rettv->vval.v_number = 0; 11064 if (argvars[0].v_type != VAR_DICT) 11065 { 11066 EMSG(_(e_dictreq)); 11067 return; 11068 } 11069 if ((d = argvars[0].vval.v_dict) == NULL) 11070 return; 11071 11072 l = list_alloc(); 11073 if (l == NULL) 11074 return; 11075 rettv->v_type = VAR_LIST; 11076 rettv->vval.v_list = l; 11077 ++l->lv_refcount; 11078 11079 todo = d->dv_hashtab.ht_used; 11080 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11081 { 11082 if (!HASHITEM_EMPTY(hi)) 11083 { 11084 --todo; 11085 di = HI2DI(hi); 11086 11087 li = listitem_alloc(); 11088 if (li == NULL) 11089 break; 11090 list_append(l, li); 11091 11092 if (what == 0) 11093 { 11094 /* keys() */ 11095 li->li_tv.v_type = VAR_STRING; 11096 li->li_tv.v_lock = 0; 11097 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11098 } 11099 else if (what == 1) 11100 { 11101 /* values() */ 11102 copy_tv(&di->di_tv, &li->li_tv); 11103 } 11104 else 11105 { 11106 /* items() */ 11107 l2 = list_alloc(); 11108 li->li_tv.v_type = VAR_LIST; 11109 li->li_tv.v_lock = 0; 11110 li->li_tv.vval.v_list = l2; 11111 if (l2 == NULL) 11112 break; 11113 ++l2->lv_refcount; 11114 11115 li2 = listitem_alloc(); 11116 if (li2 == NULL) 11117 break; 11118 list_append(l2, li2); 11119 li2->li_tv.v_type = VAR_STRING; 11120 li2->li_tv.v_lock = 0; 11121 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11122 11123 li2 = listitem_alloc(); 11124 if (li2 == NULL) 11125 break; 11126 list_append(l2, li2); 11127 copy_tv(&di->di_tv, &li2->li_tv); 11128 } 11129 } 11130 } 11131 } 11132 11133 /* 11134 * "items(dict)" function 11135 */ 11136 static void 11137 f_items(argvars, rettv) 11138 typval_T *argvars; 11139 typval_T *rettv; 11140 { 11141 dict_list(argvars, rettv, 2); 11142 } 11143 11144 /* 11145 * "join()" function 11146 */ 11147 static void 11148 f_join(argvars, rettv) 11149 typval_T *argvars; 11150 typval_T *rettv; 11151 { 11152 garray_T ga; 11153 char_u *sep; 11154 11155 rettv->vval.v_number = 0; 11156 if (argvars[0].v_type != VAR_LIST) 11157 { 11158 EMSG(_(e_listreq)); 11159 return; 11160 } 11161 if (argvars[0].vval.v_list == NULL) 11162 return; 11163 if (argvars[1].v_type == VAR_UNKNOWN) 11164 sep = (char_u *)" "; 11165 else 11166 sep = get_tv_string_chk(&argvars[1]); 11167 11168 rettv->v_type = VAR_STRING; 11169 11170 if (sep != NULL) 11171 { 11172 ga_init2(&ga, (int)sizeof(char), 80); 11173 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11174 ga_append(&ga, NUL); 11175 rettv->vval.v_string = (char_u *)ga.ga_data; 11176 } 11177 else 11178 rettv->vval.v_string = NULL; 11179 } 11180 11181 /* 11182 * "keys()" function 11183 */ 11184 static void 11185 f_keys(argvars, rettv) 11186 typval_T *argvars; 11187 typval_T *rettv; 11188 { 11189 dict_list(argvars, rettv, 0); 11190 } 11191 11192 /* 11193 * "last_buffer_nr()" function. 11194 */ 11195 /*ARGSUSED*/ 11196 static void 11197 f_last_buffer_nr(argvars, rettv) 11198 typval_T *argvars; 11199 typval_T *rettv; 11200 { 11201 int n = 0; 11202 buf_T *buf; 11203 11204 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11205 if (n < buf->b_fnum) 11206 n = buf->b_fnum; 11207 11208 rettv->vval.v_number = n; 11209 } 11210 11211 /* 11212 * "len()" function 11213 */ 11214 static void 11215 f_len(argvars, rettv) 11216 typval_T *argvars; 11217 typval_T *rettv; 11218 { 11219 switch (argvars[0].v_type) 11220 { 11221 case VAR_STRING: 11222 case VAR_NUMBER: 11223 rettv->vval.v_number = (varnumber_T)STRLEN( 11224 get_tv_string(&argvars[0])); 11225 break; 11226 case VAR_LIST: 11227 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11228 break; 11229 case VAR_DICT: 11230 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11231 break; 11232 default: 11233 EMSG(_("E701: Invalid type for len()")); 11234 break; 11235 } 11236 } 11237 11238 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11239 11240 static void 11241 libcall_common(argvars, rettv, type) 11242 typval_T *argvars; 11243 typval_T *rettv; 11244 int type; 11245 { 11246 #ifdef FEAT_LIBCALL 11247 char_u *string_in; 11248 char_u **string_result; 11249 int nr_result; 11250 #endif 11251 11252 rettv->v_type = type; 11253 if (type == VAR_NUMBER) 11254 rettv->vval.v_number = 0; 11255 else 11256 rettv->vval.v_string = NULL; 11257 11258 if (check_restricted() || check_secure()) 11259 return; 11260 11261 #ifdef FEAT_LIBCALL 11262 /* The first two args must be strings, otherwise its meaningless */ 11263 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11264 { 11265 string_in = NULL; 11266 if (argvars[2].v_type == VAR_STRING) 11267 string_in = argvars[2].vval.v_string; 11268 if (type == VAR_NUMBER) 11269 string_result = NULL; 11270 else 11271 string_result = &rettv->vval.v_string; 11272 if (mch_libcall(argvars[0].vval.v_string, 11273 argvars[1].vval.v_string, 11274 string_in, 11275 argvars[2].vval.v_number, 11276 string_result, 11277 &nr_result) == OK 11278 && type == VAR_NUMBER) 11279 rettv->vval.v_number = nr_result; 11280 } 11281 #endif 11282 } 11283 11284 /* 11285 * "libcall()" function 11286 */ 11287 static void 11288 f_libcall(argvars, rettv) 11289 typval_T *argvars; 11290 typval_T *rettv; 11291 { 11292 libcall_common(argvars, rettv, VAR_STRING); 11293 } 11294 11295 /* 11296 * "libcallnr()" function 11297 */ 11298 static void 11299 f_libcallnr(argvars, rettv) 11300 typval_T *argvars; 11301 typval_T *rettv; 11302 { 11303 libcall_common(argvars, rettv, VAR_NUMBER); 11304 } 11305 11306 /* 11307 * "line(string)" function 11308 */ 11309 static void 11310 f_line(argvars, rettv) 11311 typval_T *argvars; 11312 typval_T *rettv; 11313 { 11314 linenr_T lnum = 0; 11315 pos_T *fp; 11316 11317 fp = var2fpos(&argvars[0], TRUE); 11318 if (fp != NULL) 11319 lnum = fp->lnum; 11320 rettv->vval.v_number = lnum; 11321 } 11322 11323 /* 11324 * "line2byte(lnum)" function 11325 */ 11326 /*ARGSUSED*/ 11327 static void 11328 f_line2byte(argvars, rettv) 11329 typval_T *argvars; 11330 typval_T *rettv; 11331 { 11332 #ifndef FEAT_BYTEOFF 11333 rettv->vval.v_number = -1; 11334 #else 11335 linenr_T lnum; 11336 11337 lnum = get_tv_lnum(argvars); 11338 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11339 rettv->vval.v_number = -1; 11340 else 11341 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11342 if (rettv->vval.v_number >= 0) 11343 ++rettv->vval.v_number; 11344 #endif 11345 } 11346 11347 /* 11348 * "lispindent(lnum)" function 11349 */ 11350 static void 11351 f_lispindent(argvars, rettv) 11352 typval_T *argvars; 11353 typval_T *rettv; 11354 { 11355 #ifdef FEAT_LISP 11356 pos_T pos; 11357 linenr_T lnum; 11358 11359 pos = curwin->w_cursor; 11360 lnum = get_tv_lnum(argvars); 11361 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11362 { 11363 curwin->w_cursor.lnum = lnum; 11364 rettv->vval.v_number = get_lisp_indent(); 11365 curwin->w_cursor = pos; 11366 } 11367 else 11368 #endif 11369 rettv->vval.v_number = -1; 11370 } 11371 11372 /* 11373 * "localtime()" function 11374 */ 11375 /*ARGSUSED*/ 11376 static void 11377 f_localtime(argvars, rettv) 11378 typval_T *argvars; 11379 typval_T *rettv; 11380 { 11381 rettv->vval.v_number = (varnumber_T)time(NULL); 11382 } 11383 11384 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11385 11386 static void 11387 get_maparg(argvars, rettv, exact) 11388 typval_T *argvars; 11389 typval_T *rettv; 11390 int exact; 11391 { 11392 char_u *keys; 11393 char_u *which; 11394 char_u buf[NUMBUFLEN]; 11395 char_u *keys_buf = NULL; 11396 char_u *rhs; 11397 int mode; 11398 garray_T ga; 11399 11400 /* return empty string for failure */ 11401 rettv->v_type = VAR_STRING; 11402 rettv->vval.v_string = NULL; 11403 11404 keys = get_tv_string(&argvars[0]); 11405 if (*keys == NUL) 11406 return; 11407 11408 if (argvars[1].v_type != VAR_UNKNOWN) 11409 which = get_tv_string_buf_chk(&argvars[1], buf); 11410 else 11411 which = (char_u *)""; 11412 if (which == NULL) 11413 return; 11414 11415 mode = get_map_mode(&which, 0); 11416 11417 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11418 rhs = check_map(keys, mode, exact, FALSE); 11419 vim_free(keys_buf); 11420 if (rhs != NULL) 11421 { 11422 ga_init(&ga); 11423 ga.ga_itemsize = 1; 11424 ga.ga_growsize = 40; 11425 11426 while (*rhs != NUL) 11427 ga_concat(&ga, str2special(&rhs, FALSE)); 11428 11429 ga_append(&ga, NUL); 11430 rettv->vval.v_string = (char_u *)ga.ga_data; 11431 } 11432 } 11433 11434 /* 11435 * "map()" function 11436 */ 11437 static void 11438 f_map(argvars, rettv) 11439 typval_T *argvars; 11440 typval_T *rettv; 11441 { 11442 filter_map(argvars, rettv, TRUE); 11443 } 11444 11445 /* 11446 * "maparg()" function 11447 */ 11448 static void 11449 f_maparg(argvars, rettv) 11450 typval_T *argvars; 11451 typval_T *rettv; 11452 { 11453 get_maparg(argvars, rettv, TRUE); 11454 } 11455 11456 /* 11457 * "mapcheck()" function 11458 */ 11459 static void 11460 f_mapcheck(argvars, rettv) 11461 typval_T *argvars; 11462 typval_T *rettv; 11463 { 11464 get_maparg(argvars, rettv, FALSE); 11465 } 11466 11467 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11468 11469 static void 11470 find_some_match(argvars, rettv, type) 11471 typval_T *argvars; 11472 typval_T *rettv; 11473 int type; 11474 { 11475 char_u *str = NULL; 11476 char_u *expr = NULL; 11477 char_u *pat; 11478 regmatch_T regmatch; 11479 char_u patbuf[NUMBUFLEN]; 11480 char_u strbuf[NUMBUFLEN]; 11481 char_u *save_cpo; 11482 long start = 0; 11483 long nth = 1; 11484 int match = 0; 11485 list_T *l = NULL; 11486 listitem_T *li = NULL; 11487 long idx = 0; 11488 char_u *tofree = NULL; 11489 11490 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11491 save_cpo = p_cpo; 11492 p_cpo = (char_u *)""; 11493 11494 rettv->vval.v_number = -1; 11495 if (type == 3) 11496 { 11497 /* return empty list when there are no matches */ 11498 if ((rettv->vval.v_list = list_alloc()) == NULL) 11499 goto theend; 11500 rettv->v_type = VAR_LIST; 11501 ++rettv->vval.v_list->lv_refcount; 11502 } 11503 else if (type == 2) 11504 { 11505 rettv->v_type = VAR_STRING; 11506 rettv->vval.v_string = NULL; 11507 } 11508 11509 if (argvars[0].v_type == VAR_LIST) 11510 { 11511 if ((l = argvars[0].vval.v_list) == NULL) 11512 goto theend; 11513 li = l->lv_first; 11514 } 11515 else 11516 expr = str = get_tv_string(&argvars[0]); 11517 11518 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11519 if (pat == NULL) 11520 goto theend; 11521 11522 if (argvars[2].v_type != VAR_UNKNOWN) 11523 { 11524 int error = FALSE; 11525 11526 start = get_tv_number_chk(&argvars[2], &error); 11527 if (error) 11528 goto theend; 11529 if (l != NULL) 11530 { 11531 li = list_find(l, start); 11532 if (li == NULL) 11533 goto theend; 11534 idx = l->lv_idx; /* use the cached index */ 11535 } 11536 else 11537 { 11538 if (start < 0) 11539 start = 0; 11540 if (start > (long)STRLEN(str)) 11541 goto theend; 11542 str += start; 11543 } 11544 11545 if (argvars[3].v_type != VAR_UNKNOWN) 11546 nth = get_tv_number_chk(&argvars[3], &error); 11547 if (error) 11548 goto theend; 11549 } 11550 11551 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11552 if (regmatch.regprog != NULL) 11553 { 11554 regmatch.rm_ic = p_ic; 11555 11556 for (;;) 11557 { 11558 if (l != NULL) 11559 { 11560 if (li == NULL) 11561 { 11562 match = FALSE; 11563 break; 11564 } 11565 vim_free(tofree); 11566 str = echo_string(&li->li_tv, &tofree, strbuf); 11567 if (str == NULL) 11568 break; 11569 } 11570 11571 match = vim_regexec_nl(®match, str, (colnr_T)0); 11572 11573 if (match && --nth <= 0) 11574 break; 11575 if (l == NULL && !match) 11576 break; 11577 11578 /* Advance to just after the match. */ 11579 if (l != NULL) 11580 { 11581 li = li->li_next; 11582 ++idx; 11583 } 11584 else 11585 { 11586 #ifdef FEAT_MBYTE 11587 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11588 #else 11589 str = regmatch.startp[0] + 1; 11590 #endif 11591 } 11592 } 11593 11594 if (match) 11595 { 11596 if (type == 3) 11597 { 11598 int i; 11599 11600 /* return list with matched string and submatches */ 11601 for (i = 0; i < NSUBEXP; ++i) 11602 { 11603 if (regmatch.endp[i] == NULL) 11604 break; 11605 li = listitem_alloc(); 11606 if (li == NULL) 11607 break; 11608 li->li_tv.v_type = VAR_STRING; 11609 li->li_tv.v_lock = 0; 11610 li->li_tv.vval.v_string = vim_strnsave(regmatch.startp[i], 11611 (int)(regmatch.endp[i] - regmatch.startp[i])); 11612 list_append(rettv->vval.v_list, li); 11613 } 11614 } 11615 else if (type == 2) 11616 { 11617 /* return matched string */ 11618 if (l != NULL) 11619 copy_tv(&li->li_tv, rettv); 11620 else 11621 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11622 (int)(regmatch.endp[0] - regmatch.startp[0])); 11623 } 11624 else if (l != NULL) 11625 rettv->vval.v_number = idx; 11626 else 11627 { 11628 if (type != 0) 11629 rettv->vval.v_number = 11630 (varnumber_T)(regmatch.startp[0] - str); 11631 else 11632 rettv->vval.v_number = 11633 (varnumber_T)(regmatch.endp[0] - str); 11634 rettv->vval.v_number += str - expr; 11635 } 11636 } 11637 vim_free(regmatch.regprog); 11638 } 11639 11640 theend: 11641 vim_free(tofree); 11642 p_cpo = save_cpo; 11643 } 11644 11645 /* 11646 * "match()" function 11647 */ 11648 static void 11649 f_match(argvars, rettv) 11650 typval_T *argvars; 11651 typval_T *rettv; 11652 { 11653 find_some_match(argvars, rettv, 1); 11654 } 11655 11656 /* 11657 * "matchend()" function 11658 */ 11659 static void 11660 f_matchend(argvars, rettv) 11661 typval_T *argvars; 11662 typval_T *rettv; 11663 { 11664 find_some_match(argvars, rettv, 0); 11665 } 11666 11667 /* 11668 * "matchlist()" function 11669 */ 11670 static void 11671 f_matchlist(argvars, rettv) 11672 typval_T *argvars; 11673 typval_T *rettv; 11674 { 11675 find_some_match(argvars, rettv, 3); 11676 } 11677 11678 /* 11679 * "matchstr()" function 11680 */ 11681 static void 11682 f_matchstr(argvars, rettv) 11683 typval_T *argvars; 11684 typval_T *rettv; 11685 { 11686 find_some_match(argvars, rettv, 2); 11687 } 11688 11689 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11690 11691 static void 11692 max_min(argvars, rettv, domax) 11693 typval_T *argvars; 11694 typval_T *rettv; 11695 int domax; 11696 { 11697 long n = 0; 11698 long i; 11699 int error = FALSE; 11700 11701 if (argvars[0].v_type == VAR_LIST) 11702 { 11703 list_T *l; 11704 listitem_T *li; 11705 11706 l = argvars[0].vval.v_list; 11707 if (l != NULL) 11708 { 11709 li = l->lv_first; 11710 if (li != NULL) 11711 { 11712 n = get_tv_number_chk(&li->li_tv, &error); 11713 for (;;) 11714 { 11715 li = li->li_next; 11716 if (li == NULL) 11717 break; 11718 i = get_tv_number_chk(&li->li_tv, &error); 11719 if (domax ? i > n : i < n) 11720 n = i; 11721 } 11722 } 11723 } 11724 } 11725 else if (argvars[0].v_type == VAR_DICT) 11726 { 11727 dict_T *d; 11728 int first = TRUE; 11729 hashitem_T *hi; 11730 int todo; 11731 11732 d = argvars[0].vval.v_dict; 11733 if (d != NULL) 11734 { 11735 todo = d->dv_hashtab.ht_used; 11736 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11737 { 11738 if (!HASHITEM_EMPTY(hi)) 11739 { 11740 --todo; 11741 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11742 if (first) 11743 { 11744 n = i; 11745 first = FALSE; 11746 } 11747 else if (domax ? i > n : i < n) 11748 n = i; 11749 } 11750 } 11751 } 11752 } 11753 else 11754 EMSG(_(e_listdictarg)); 11755 rettv->vval.v_number = error ? 0 : n; 11756 } 11757 11758 /* 11759 * "max()" function 11760 */ 11761 static void 11762 f_max(argvars, rettv) 11763 typval_T *argvars; 11764 typval_T *rettv; 11765 { 11766 max_min(argvars, rettv, TRUE); 11767 } 11768 11769 /* 11770 * "min()" function 11771 */ 11772 static void 11773 f_min(argvars, rettv) 11774 typval_T *argvars; 11775 typval_T *rettv; 11776 { 11777 max_min(argvars, rettv, FALSE); 11778 } 11779 11780 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11781 11782 /* 11783 * Create the directory in which "dir" is located, and higher levels when 11784 * needed. 11785 */ 11786 static int 11787 mkdir_recurse(dir, prot) 11788 char_u *dir; 11789 int prot; 11790 { 11791 char_u *p; 11792 char_u *updir; 11793 int r = FAIL; 11794 11795 /* Get end of directory name in "dir". 11796 * We're done when it's "/" or "c:/". */ 11797 p = gettail_sep(dir); 11798 if (p <= get_past_head(dir)) 11799 return OK; 11800 11801 /* If the directory exists we're done. Otherwise: create it.*/ 11802 updir = vim_strnsave(dir, (int)(p - dir)); 11803 if (updir == NULL) 11804 return FAIL; 11805 if (mch_isdir(updir)) 11806 r = OK; 11807 else if (mkdir_recurse(updir, prot) == OK) 11808 r = vim_mkdir_emsg(updir, prot); 11809 vim_free(updir); 11810 return r; 11811 } 11812 11813 #ifdef vim_mkdir 11814 /* 11815 * "mkdir()" function 11816 */ 11817 static void 11818 f_mkdir(argvars, rettv) 11819 typval_T *argvars; 11820 typval_T *rettv; 11821 { 11822 char_u *dir; 11823 char_u buf[NUMBUFLEN]; 11824 int prot = 0755; 11825 11826 rettv->vval.v_number = FAIL; 11827 if (check_restricted() || check_secure()) 11828 return; 11829 11830 dir = get_tv_string_buf(&argvars[0], buf); 11831 if (argvars[1].v_type != VAR_UNKNOWN) 11832 { 11833 if (argvars[2].v_type != VAR_UNKNOWN) 11834 prot = get_tv_number_chk(&argvars[2], NULL); 11835 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11836 mkdir_recurse(dir, prot); 11837 } 11838 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11839 } 11840 #endif 11841 11842 /* 11843 * "mode()" function 11844 */ 11845 /*ARGSUSED*/ 11846 static void 11847 f_mode(argvars, rettv) 11848 typval_T *argvars; 11849 typval_T *rettv; 11850 { 11851 char_u buf[2]; 11852 11853 #ifdef FEAT_VISUAL 11854 if (VIsual_active) 11855 { 11856 if (VIsual_select) 11857 buf[0] = VIsual_mode + 's' - 'v'; 11858 else 11859 buf[0] = VIsual_mode; 11860 } 11861 else 11862 #endif 11863 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11864 buf[0] = 'r'; 11865 else if (State & INSERT) 11866 { 11867 if (State & REPLACE_FLAG) 11868 buf[0] = 'R'; 11869 else 11870 buf[0] = 'i'; 11871 } 11872 else if (State & CMDLINE) 11873 buf[0] = 'c'; 11874 else 11875 buf[0] = 'n'; 11876 11877 buf[1] = NUL; 11878 rettv->vval.v_string = vim_strsave(buf); 11879 rettv->v_type = VAR_STRING; 11880 } 11881 11882 /* 11883 * "nextnonblank()" function 11884 */ 11885 static void 11886 f_nextnonblank(argvars, rettv) 11887 typval_T *argvars; 11888 typval_T *rettv; 11889 { 11890 linenr_T lnum; 11891 11892 for (lnum = get_tv_lnum(argvars); ; ++lnum) 11893 { 11894 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 11895 { 11896 lnum = 0; 11897 break; 11898 } 11899 if (*skipwhite(ml_get(lnum)) != NUL) 11900 break; 11901 } 11902 rettv->vval.v_number = lnum; 11903 } 11904 11905 /* 11906 * "nr2char()" function 11907 */ 11908 static void 11909 f_nr2char(argvars, rettv) 11910 typval_T *argvars; 11911 typval_T *rettv; 11912 { 11913 char_u buf[NUMBUFLEN]; 11914 11915 #ifdef FEAT_MBYTE 11916 if (has_mbyte) 11917 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 11918 else 11919 #endif 11920 { 11921 buf[0] = (char_u)get_tv_number(&argvars[0]); 11922 buf[1] = NUL; 11923 } 11924 rettv->v_type = VAR_STRING; 11925 rettv->vval.v_string = vim_strsave(buf); 11926 } 11927 11928 /* 11929 * "prevnonblank()" function 11930 */ 11931 static void 11932 f_prevnonblank(argvars, rettv) 11933 typval_T *argvars; 11934 typval_T *rettv; 11935 { 11936 linenr_T lnum; 11937 11938 lnum = get_tv_lnum(argvars); 11939 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 11940 lnum = 0; 11941 else 11942 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 11943 --lnum; 11944 rettv->vval.v_number = lnum; 11945 } 11946 11947 #ifdef HAVE_STDARG_H 11948 /* This dummy va_list is here because: 11949 * - passing a NULL pointer doesn't work when va_list isn't a pointer 11950 * - locally in the function results in a "used before set" warning 11951 * - using va_start() to initialize it gives "function with fixed args" error */ 11952 static va_list ap; 11953 #endif 11954 11955 /* 11956 * "printf()" function 11957 */ 11958 static void 11959 f_printf(argvars, rettv) 11960 typval_T *argvars; 11961 typval_T *rettv; 11962 { 11963 rettv->v_type = VAR_STRING; 11964 rettv->vval.v_string = NULL; 11965 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 11966 { 11967 char_u buf[NUMBUFLEN]; 11968 int len; 11969 char_u *s; 11970 int saved_did_emsg = did_emsg; 11971 char *fmt; 11972 11973 /* Get the required length, allocate the buffer and do it for real. */ 11974 did_emsg = FALSE; 11975 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 11976 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 11977 if (!did_emsg) 11978 { 11979 s = alloc(len + 1); 11980 if (s != NULL) 11981 { 11982 rettv->vval.v_string = s; 11983 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 11984 } 11985 } 11986 did_emsg |= saved_did_emsg; 11987 } 11988 #endif 11989 } 11990 11991 /* 11992 * "range()" function 11993 */ 11994 static void 11995 f_range(argvars, rettv) 11996 typval_T *argvars; 11997 typval_T *rettv; 11998 { 11999 long start; 12000 long end; 12001 long stride = 1; 12002 long i; 12003 list_T *l; 12004 listitem_T *li; 12005 int error = FALSE; 12006 12007 start = get_tv_number_chk(&argvars[0], &error); 12008 if (argvars[1].v_type == VAR_UNKNOWN) 12009 { 12010 end = start - 1; 12011 start = 0; 12012 } 12013 else 12014 { 12015 end = get_tv_number_chk(&argvars[1], &error); 12016 if (argvars[2].v_type != VAR_UNKNOWN) 12017 stride = get_tv_number_chk(&argvars[2], &error); 12018 } 12019 12020 rettv->vval.v_number = 0; 12021 if (error) 12022 return; /* type error; errmsg already given */ 12023 if (stride == 0) 12024 EMSG(_("E726: Stride is zero")); 12025 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12026 EMSG(_("E727: Start past end")); 12027 else 12028 { 12029 l = list_alloc(); 12030 if (l != NULL) 12031 { 12032 rettv->v_type = VAR_LIST; 12033 rettv->vval.v_list = l; 12034 ++l->lv_refcount; 12035 12036 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12037 { 12038 li = listitem_alloc(); 12039 if (li == NULL) 12040 break; 12041 li->li_tv.v_type = VAR_NUMBER; 12042 li->li_tv.v_lock = 0; 12043 li->li_tv.vval.v_number = i; 12044 list_append(l, li); 12045 } 12046 } 12047 } 12048 } 12049 12050 /* 12051 * "readfile()" function 12052 */ 12053 static void 12054 f_readfile(argvars, rettv) 12055 typval_T *argvars; 12056 typval_T *rettv; 12057 { 12058 int binary = FALSE; 12059 char_u *fname; 12060 FILE *fd; 12061 list_T *l; 12062 listitem_T *li; 12063 #define FREAD_SIZE 200 /* optimized for text lines */ 12064 char_u buf[FREAD_SIZE]; 12065 int readlen; /* size of last fread() */ 12066 int buflen; /* nr of valid chars in buf[] */ 12067 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12068 int tolist; /* first byte in buf[] still to be put in list */ 12069 int chop; /* how many CR to chop off */ 12070 char_u *prev = NULL; /* previously read bytes, if any */ 12071 int prevlen = 0; /* length of "prev" if not NULL */ 12072 char_u *s; 12073 int len; 12074 long maxline = MAXLNUM; 12075 long cnt = 0; 12076 12077 if (argvars[1].v_type != VAR_UNKNOWN) 12078 { 12079 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12080 binary = TRUE; 12081 if (argvars[2].v_type != VAR_UNKNOWN) 12082 maxline = get_tv_number(&argvars[2]); 12083 } 12084 12085 l = list_alloc(); 12086 if (l == NULL) 12087 return; 12088 rettv->v_type = VAR_LIST; 12089 rettv->vval.v_list = l; 12090 l->lv_refcount = 1; 12091 12092 /* Always open the file in binary mode, library functions have a mind of 12093 * their own about CR-LF conversion. */ 12094 fname = get_tv_string(&argvars[0]); 12095 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12096 { 12097 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12098 return; 12099 } 12100 12101 filtd = 0; 12102 while (cnt < maxline || maxline < 0) 12103 { 12104 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12105 buflen = filtd + readlen; 12106 tolist = 0; 12107 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12108 { 12109 if (buf[filtd] == '\n' || readlen <= 0) 12110 { 12111 /* Only when in binary mode add an empty list item when the 12112 * last line ends in a '\n'. */ 12113 if (!binary && readlen == 0 && filtd == 0) 12114 break; 12115 12116 /* Found end-of-line or end-of-file: add a text line to the 12117 * list. */ 12118 chop = 0; 12119 if (!binary) 12120 while (filtd - chop - 1 >= tolist 12121 && buf[filtd - chop - 1] == '\r') 12122 ++chop; 12123 len = filtd - tolist - chop; 12124 if (prev == NULL) 12125 s = vim_strnsave(buf + tolist, len); 12126 else 12127 { 12128 s = alloc((unsigned)(prevlen + len + 1)); 12129 if (s != NULL) 12130 { 12131 mch_memmove(s, prev, prevlen); 12132 vim_free(prev); 12133 prev = NULL; 12134 mch_memmove(s + prevlen, buf + tolist, len); 12135 s[prevlen + len] = NUL; 12136 } 12137 } 12138 tolist = filtd + 1; 12139 12140 li = listitem_alloc(); 12141 if (li == NULL) 12142 { 12143 vim_free(s); 12144 break; 12145 } 12146 li->li_tv.v_type = VAR_STRING; 12147 li->li_tv.v_lock = 0; 12148 li->li_tv.vval.v_string = s; 12149 list_append(l, li); 12150 12151 if (++cnt >= maxline && maxline >= 0) 12152 break; 12153 if (readlen <= 0) 12154 break; 12155 } 12156 else if (buf[filtd] == NUL) 12157 buf[filtd] = '\n'; 12158 } 12159 if (readlen <= 0) 12160 break; 12161 12162 if (tolist == 0) 12163 { 12164 /* "buf" is full, need to move text to an allocated buffer */ 12165 if (prev == NULL) 12166 { 12167 prev = vim_strnsave(buf, buflen); 12168 prevlen = buflen; 12169 } 12170 else 12171 { 12172 s = alloc((unsigned)(prevlen + buflen)); 12173 if (s != NULL) 12174 { 12175 mch_memmove(s, prev, prevlen); 12176 mch_memmove(s + prevlen, buf, buflen); 12177 vim_free(prev); 12178 prev = s; 12179 prevlen += buflen; 12180 } 12181 } 12182 filtd = 0; 12183 } 12184 else 12185 { 12186 mch_memmove(buf, buf + tolist, buflen - tolist); 12187 filtd -= tolist; 12188 } 12189 } 12190 12191 /* 12192 * For a negative line count use only the lines at the end of the file, 12193 * free the rest. 12194 */ 12195 if (maxline < 0) 12196 while (cnt > -maxline) 12197 { 12198 listitem_remove(l, l->lv_first); 12199 --cnt; 12200 } 12201 12202 vim_free(prev); 12203 fclose(fd); 12204 } 12205 12206 12207 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12208 static void make_connection __ARGS((void)); 12209 static int check_connection __ARGS((void)); 12210 12211 static void 12212 make_connection() 12213 { 12214 if (X_DISPLAY == NULL 12215 # ifdef FEAT_GUI 12216 && !gui.in_use 12217 # endif 12218 ) 12219 { 12220 x_force_connect = TRUE; 12221 setup_term_clip(); 12222 x_force_connect = FALSE; 12223 } 12224 } 12225 12226 static int 12227 check_connection() 12228 { 12229 make_connection(); 12230 if (X_DISPLAY == NULL) 12231 { 12232 EMSG(_("E240: No connection to Vim server")); 12233 return FAIL; 12234 } 12235 return OK; 12236 } 12237 #endif 12238 12239 #ifdef FEAT_CLIENTSERVER 12240 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12241 12242 static void 12243 remote_common(argvars, rettv, expr) 12244 typval_T *argvars; 12245 typval_T *rettv; 12246 int expr; 12247 { 12248 char_u *server_name; 12249 char_u *keys; 12250 char_u *r = NULL; 12251 char_u buf[NUMBUFLEN]; 12252 # ifdef WIN32 12253 HWND w; 12254 # else 12255 Window w; 12256 # endif 12257 12258 if (check_restricted() || check_secure()) 12259 return; 12260 12261 # ifdef FEAT_X11 12262 if (check_connection() == FAIL) 12263 return; 12264 # endif 12265 12266 server_name = get_tv_string_chk(&argvars[0]); 12267 if (server_name == NULL) 12268 return; /* type error; errmsg already given */ 12269 keys = get_tv_string_buf(&argvars[1], buf); 12270 # ifdef WIN32 12271 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12272 # else 12273 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12274 < 0) 12275 # endif 12276 { 12277 if (r != NULL) 12278 EMSG(r); /* sending worked but evaluation failed */ 12279 else 12280 EMSG2(_("E241: Unable to send to %s"), server_name); 12281 return; 12282 } 12283 12284 rettv->vval.v_string = r; 12285 12286 if (argvars[2].v_type != VAR_UNKNOWN) 12287 { 12288 dictitem_T v; 12289 char_u str[30]; 12290 char_u *idvar; 12291 12292 sprintf((char *)str, "0x%x", (unsigned int)w); 12293 v.di_tv.v_type = VAR_STRING; 12294 v.di_tv.vval.v_string = vim_strsave(str); 12295 idvar = get_tv_string_chk(&argvars[2]); 12296 if (idvar != NULL) 12297 set_var(idvar, &v.di_tv, FALSE); 12298 vim_free(v.di_tv.vval.v_string); 12299 } 12300 } 12301 #endif 12302 12303 /* 12304 * "remote_expr()" function 12305 */ 12306 /*ARGSUSED*/ 12307 static void 12308 f_remote_expr(argvars, rettv) 12309 typval_T *argvars; 12310 typval_T *rettv; 12311 { 12312 rettv->v_type = VAR_STRING; 12313 rettv->vval.v_string = NULL; 12314 #ifdef FEAT_CLIENTSERVER 12315 remote_common(argvars, rettv, TRUE); 12316 #endif 12317 } 12318 12319 /* 12320 * "remote_foreground()" function 12321 */ 12322 /*ARGSUSED*/ 12323 static void 12324 f_remote_foreground(argvars, rettv) 12325 typval_T *argvars; 12326 typval_T *rettv; 12327 { 12328 rettv->vval.v_number = 0; 12329 #ifdef FEAT_CLIENTSERVER 12330 # ifdef WIN32 12331 /* On Win32 it's done in this application. */ 12332 { 12333 char_u *server_name = get_tv_string_chk(&argvars[0]); 12334 12335 if (server_name != NULL) 12336 serverForeground(server_name); 12337 } 12338 # else 12339 /* Send a foreground() expression to the server. */ 12340 argvars[1].v_type = VAR_STRING; 12341 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12342 argvars[2].v_type = VAR_UNKNOWN; 12343 remote_common(argvars, rettv, TRUE); 12344 vim_free(argvars[1].vval.v_string); 12345 # endif 12346 #endif 12347 } 12348 12349 /*ARGSUSED*/ 12350 static void 12351 f_remote_peek(argvars, rettv) 12352 typval_T *argvars; 12353 typval_T *rettv; 12354 { 12355 #ifdef FEAT_CLIENTSERVER 12356 dictitem_T v; 12357 char_u *s = NULL; 12358 # ifdef WIN32 12359 int n = 0; 12360 # endif 12361 char_u *serverid; 12362 12363 if (check_restricted() || check_secure()) 12364 { 12365 rettv->vval.v_number = -1; 12366 return; 12367 } 12368 serverid = get_tv_string_chk(&argvars[0]); 12369 if (serverid == NULL) 12370 { 12371 rettv->vval.v_number = -1; 12372 return; /* type error; errmsg already given */ 12373 } 12374 # ifdef WIN32 12375 sscanf(serverid, "%x", &n); 12376 if (n == 0) 12377 rettv->vval.v_number = -1; 12378 else 12379 { 12380 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12381 rettv->vval.v_number = (s != NULL); 12382 } 12383 # else 12384 rettv->vval.v_number = 0; 12385 if (check_connection() == FAIL) 12386 return; 12387 12388 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12389 serverStrToWin(serverid), &s); 12390 # endif 12391 12392 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12393 { 12394 char_u *retvar; 12395 12396 v.di_tv.v_type = VAR_STRING; 12397 v.di_tv.vval.v_string = vim_strsave(s); 12398 retvar = get_tv_string_chk(&argvars[1]); 12399 if (retvar != NULL) 12400 set_var(retvar, &v.di_tv, FALSE); 12401 vim_free(v.di_tv.vval.v_string); 12402 } 12403 #else 12404 rettv->vval.v_number = -1; 12405 #endif 12406 } 12407 12408 /*ARGSUSED*/ 12409 static void 12410 f_remote_read(argvars, rettv) 12411 typval_T *argvars; 12412 typval_T *rettv; 12413 { 12414 char_u *r = NULL; 12415 12416 #ifdef FEAT_CLIENTSERVER 12417 char_u *serverid = get_tv_string_chk(&argvars[0]); 12418 12419 if (serverid != NULL && !check_restricted() && !check_secure()) 12420 { 12421 # ifdef WIN32 12422 /* The server's HWND is encoded in the 'id' parameter */ 12423 int n = 0; 12424 12425 sscanf(serverid, "%x", &n); 12426 if (n != 0) 12427 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12428 if (r == NULL) 12429 # else 12430 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12431 serverStrToWin(serverid), &r, FALSE) < 0) 12432 # endif 12433 EMSG(_("E277: Unable to read a server reply")); 12434 } 12435 #endif 12436 rettv->v_type = VAR_STRING; 12437 rettv->vval.v_string = r; 12438 } 12439 12440 /* 12441 * "remote_send()" function 12442 */ 12443 /*ARGSUSED*/ 12444 static void 12445 f_remote_send(argvars, rettv) 12446 typval_T *argvars; 12447 typval_T *rettv; 12448 { 12449 rettv->v_type = VAR_STRING; 12450 rettv->vval.v_string = NULL; 12451 #ifdef FEAT_CLIENTSERVER 12452 remote_common(argvars, rettv, FALSE); 12453 #endif 12454 } 12455 12456 /* 12457 * "remove()" function 12458 */ 12459 static void 12460 f_remove(argvars, rettv) 12461 typval_T *argvars; 12462 typval_T *rettv; 12463 { 12464 list_T *l; 12465 listitem_T *item, *item2; 12466 listitem_T *li; 12467 long idx; 12468 long end; 12469 char_u *key; 12470 dict_T *d; 12471 dictitem_T *di; 12472 12473 rettv->vval.v_number = 0; 12474 if (argvars[0].v_type == VAR_DICT) 12475 { 12476 if (argvars[2].v_type != VAR_UNKNOWN) 12477 EMSG2(_(e_toomanyarg), "remove()"); 12478 else if ((d = argvars[0].vval.v_dict) != NULL 12479 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12480 { 12481 key = get_tv_string_chk(&argvars[1]); 12482 if (key != NULL) 12483 { 12484 di = dict_find(d, key, -1); 12485 if (di == NULL) 12486 EMSG2(_(e_dictkey), key); 12487 else 12488 { 12489 *rettv = di->di_tv; 12490 init_tv(&di->di_tv); 12491 dictitem_remove(d, di); 12492 } 12493 } 12494 } 12495 } 12496 else if (argvars[0].v_type != VAR_LIST) 12497 EMSG2(_(e_listdictarg), "remove()"); 12498 else if ((l = argvars[0].vval.v_list) != NULL 12499 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12500 { 12501 int error = FALSE; 12502 12503 idx = get_tv_number_chk(&argvars[1], &error); 12504 if (error) 12505 ; /* type error: do nothing, errmsg already given */ 12506 else if ((item = list_find(l, idx)) == NULL) 12507 EMSGN(_(e_listidx), idx); 12508 else 12509 { 12510 if (argvars[2].v_type == VAR_UNKNOWN) 12511 { 12512 /* Remove one item, return its value. */ 12513 list_remove(l, item, item); 12514 *rettv = item->li_tv; 12515 vim_free(item); 12516 } 12517 else 12518 { 12519 /* Remove range of items, return list with values. */ 12520 end = get_tv_number_chk(&argvars[2], &error); 12521 if (error) 12522 ; /* type error: do nothing */ 12523 else if ((item2 = list_find(l, end)) == NULL) 12524 EMSGN(_(e_listidx), end); 12525 else 12526 { 12527 int cnt = 0; 12528 12529 for (li = item; li != NULL; li = li->li_next) 12530 { 12531 ++cnt; 12532 if (li == item2) 12533 break; 12534 } 12535 if (li == NULL) /* didn't find "item2" after "item" */ 12536 EMSG(_(e_invrange)); 12537 else 12538 { 12539 list_remove(l, item, item2); 12540 l = list_alloc(); 12541 if (l != NULL) 12542 { 12543 rettv->v_type = VAR_LIST; 12544 rettv->vval.v_list = l; 12545 l->lv_first = item; 12546 l->lv_last = item2; 12547 l->lv_refcount = 1; 12548 item->li_prev = NULL; 12549 item2->li_next = NULL; 12550 l->lv_len = cnt; 12551 } 12552 } 12553 } 12554 } 12555 } 12556 } 12557 } 12558 12559 /* 12560 * "rename({from}, {to})" function 12561 */ 12562 static void 12563 f_rename(argvars, rettv) 12564 typval_T *argvars; 12565 typval_T *rettv; 12566 { 12567 char_u buf[NUMBUFLEN]; 12568 12569 if (check_restricted() || check_secure()) 12570 rettv->vval.v_number = -1; 12571 else 12572 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12573 get_tv_string_buf(&argvars[1], buf)); 12574 } 12575 12576 /* 12577 * "repeat()" function 12578 */ 12579 /*ARGSUSED*/ 12580 static void 12581 f_repeat(argvars, rettv) 12582 typval_T *argvars; 12583 typval_T *rettv; 12584 { 12585 char_u *p; 12586 int n; 12587 int slen; 12588 int len; 12589 char_u *r; 12590 int i; 12591 list_T *l; 12592 12593 n = get_tv_number(&argvars[1]); 12594 if (argvars[0].v_type == VAR_LIST) 12595 { 12596 l = list_alloc(); 12597 if (l != NULL && argvars[0].vval.v_list != NULL) 12598 { 12599 l->lv_refcount = 1; 12600 while (n-- > 0) 12601 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12602 break; 12603 } 12604 rettv->v_type = VAR_LIST; 12605 rettv->vval.v_list = l; 12606 } 12607 else 12608 { 12609 p = get_tv_string(&argvars[0]); 12610 rettv->v_type = VAR_STRING; 12611 rettv->vval.v_string = NULL; 12612 12613 slen = (int)STRLEN(p); 12614 len = slen * n; 12615 if (len <= 0) 12616 return; 12617 12618 r = alloc(len + 1); 12619 if (r != NULL) 12620 { 12621 for (i = 0; i < n; i++) 12622 mch_memmove(r + i * slen, p, (size_t)slen); 12623 r[len] = NUL; 12624 } 12625 12626 rettv->vval.v_string = r; 12627 } 12628 } 12629 12630 /* 12631 * "resolve()" function 12632 */ 12633 static void 12634 f_resolve(argvars, rettv) 12635 typval_T *argvars; 12636 typval_T *rettv; 12637 { 12638 char_u *p; 12639 12640 p = get_tv_string(&argvars[0]); 12641 #ifdef FEAT_SHORTCUT 12642 { 12643 char_u *v = NULL; 12644 12645 v = mch_resolve_shortcut(p); 12646 if (v != NULL) 12647 rettv->vval.v_string = v; 12648 else 12649 rettv->vval.v_string = vim_strsave(p); 12650 } 12651 #else 12652 # ifdef HAVE_READLINK 12653 { 12654 char_u buf[MAXPATHL + 1]; 12655 char_u *cpy; 12656 int len; 12657 char_u *remain = NULL; 12658 char_u *q; 12659 int is_relative_to_current = FALSE; 12660 int has_trailing_pathsep = FALSE; 12661 int limit = 100; 12662 12663 p = vim_strsave(p); 12664 12665 if (p[0] == '.' && (vim_ispathsep(p[1]) 12666 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12667 is_relative_to_current = TRUE; 12668 12669 len = STRLEN(p); 12670 if (len > 0 && after_pathsep(p, p + len)) 12671 has_trailing_pathsep = TRUE; 12672 12673 q = getnextcomp(p); 12674 if (*q != NUL) 12675 { 12676 /* Separate the first path component in "p", and keep the 12677 * remainder (beginning with the path separator). */ 12678 remain = vim_strsave(q - 1); 12679 q[-1] = NUL; 12680 } 12681 12682 for (;;) 12683 { 12684 for (;;) 12685 { 12686 len = readlink((char *)p, (char *)buf, MAXPATHL); 12687 if (len <= 0) 12688 break; 12689 buf[len] = NUL; 12690 12691 if (limit-- == 0) 12692 { 12693 vim_free(p); 12694 vim_free(remain); 12695 EMSG(_("E655: Too many symbolic links (cycle?)")); 12696 rettv->vval.v_string = NULL; 12697 goto fail; 12698 } 12699 12700 /* Ensure that the result will have a trailing path separator 12701 * if the argument has one. */ 12702 if (remain == NULL && has_trailing_pathsep) 12703 add_pathsep(buf); 12704 12705 /* Separate the first path component in the link value and 12706 * concatenate the remainders. */ 12707 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12708 if (*q != NUL) 12709 { 12710 if (remain == NULL) 12711 remain = vim_strsave(q - 1); 12712 else 12713 { 12714 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12715 if (cpy != NULL) 12716 { 12717 STRCAT(cpy, remain); 12718 vim_free(remain); 12719 remain = cpy; 12720 } 12721 } 12722 q[-1] = NUL; 12723 } 12724 12725 q = gettail(p); 12726 if (q > p && *q == NUL) 12727 { 12728 /* Ignore trailing path separator. */ 12729 q[-1] = NUL; 12730 q = gettail(p); 12731 } 12732 if (q > p && !mch_isFullName(buf)) 12733 { 12734 /* symlink is relative to directory of argument */ 12735 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12736 if (cpy != NULL) 12737 { 12738 STRCPY(cpy, p); 12739 STRCPY(gettail(cpy), buf); 12740 vim_free(p); 12741 p = cpy; 12742 } 12743 } 12744 else 12745 { 12746 vim_free(p); 12747 p = vim_strsave(buf); 12748 } 12749 } 12750 12751 if (remain == NULL) 12752 break; 12753 12754 /* Append the first path component of "remain" to "p". */ 12755 q = getnextcomp(remain + 1); 12756 len = q - remain - (*q != NUL); 12757 cpy = vim_strnsave(p, STRLEN(p) + len); 12758 if (cpy != NULL) 12759 { 12760 STRNCAT(cpy, remain, len); 12761 vim_free(p); 12762 p = cpy; 12763 } 12764 /* Shorten "remain". */ 12765 if (*q != NUL) 12766 STRCPY(remain, q - 1); 12767 else 12768 { 12769 vim_free(remain); 12770 remain = NULL; 12771 } 12772 } 12773 12774 /* If the result is a relative path name, make it explicitly relative to 12775 * the current directory if and only if the argument had this form. */ 12776 if (!vim_ispathsep(*p)) 12777 { 12778 if (is_relative_to_current 12779 && *p != NUL 12780 && !(p[0] == '.' 12781 && (p[1] == NUL 12782 || vim_ispathsep(p[1]) 12783 || (p[1] == '.' 12784 && (p[2] == NUL 12785 || vim_ispathsep(p[2])))))) 12786 { 12787 /* Prepend "./". */ 12788 cpy = concat_str((char_u *)"./", p); 12789 if (cpy != NULL) 12790 { 12791 vim_free(p); 12792 p = cpy; 12793 } 12794 } 12795 else if (!is_relative_to_current) 12796 { 12797 /* Strip leading "./". */ 12798 q = p; 12799 while (q[0] == '.' && vim_ispathsep(q[1])) 12800 q += 2; 12801 if (q > p) 12802 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12803 } 12804 } 12805 12806 /* Ensure that the result will have no trailing path separator 12807 * if the argument had none. But keep "/" or "//". */ 12808 if (!has_trailing_pathsep) 12809 { 12810 q = p + STRLEN(p); 12811 if (after_pathsep(p, q)) 12812 *gettail_sep(p) = NUL; 12813 } 12814 12815 rettv->vval.v_string = p; 12816 } 12817 # else 12818 rettv->vval.v_string = vim_strsave(p); 12819 # endif 12820 #endif 12821 12822 simplify_filename(rettv->vval.v_string); 12823 12824 #ifdef HAVE_READLINK 12825 fail: 12826 #endif 12827 rettv->v_type = VAR_STRING; 12828 } 12829 12830 /* 12831 * "reverse({list})" function 12832 */ 12833 static void 12834 f_reverse(argvars, rettv) 12835 typval_T *argvars; 12836 typval_T *rettv; 12837 { 12838 list_T *l; 12839 listitem_T *li, *ni; 12840 12841 rettv->vval.v_number = 0; 12842 if (argvars[0].v_type != VAR_LIST) 12843 EMSG2(_(e_listarg), "reverse()"); 12844 else if ((l = argvars[0].vval.v_list) != NULL 12845 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12846 { 12847 li = l->lv_last; 12848 l->lv_first = l->lv_last = NULL; 12849 l->lv_len = 0; 12850 while (li != NULL) 12851 { 12852 ni = li->li_prev; 12853 list_append(l, li); 12854 li = ni; 12855 } 12856 rettv->vval.v_list = l; 12857 rettv->v_type = VAR_LIST; 12858 ++l->lv_refcount; 12859 } 12860 } 12861 12862 #define SP_NOMOVE 1 /* don't move cursor */ 12863 #define SP_REPEAT 2 /* repeat to find outer pair */ 12864 #define SP_RETCOUNT 4 /* return matchcount */ 12865 #define SP_SETPCMARK 8 /* set previous context mark */ 12866 12867 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12868 12869 /* 12870 * Get flags for a search function. 12871 * Possibly sets "p_ws". 12872 * Returns BACKWARD, FORWARD or zero (for an error). 12873 */ 12874 static int 12875 get_search_arg(varp, flagsp) 12876 typval_T *varp; 12877 int *flagsp; 12878 { 12879 int dir = FORWARD; 12880 char_u *flags; 12881 char_u nbuf[NUMBUFLEN]; 12882 int mask; 12883 12884 if (varp->v_type != VAR_UNKNOWN) 12885 { 12886 flags = get_tv_string_buf_chk(varp, nbuf); 12887 if (flags == NULL) 12888 return 0; /* type error; errmsg already given */ 12889 while (*flags != NUL) 12890 { 12891 switch (*flags) 12892 { 12893 case 'b': dir = BACKWARD; break; 12894 case 'w': p_ws = TRUE; break; 12895 case 'W': p_ws = FALSE; break; 12896 default: mask = 0; 12897 if (flagsp != NULL) 12898 switch (*flags) 12899 { 12900 case 'n': mask = SP_NOMOVE; break; 12901 case 'r': mask = SP_REPEAT; break; 12902 case 'm': mask = SP_RETCOUNT; break; 12903 case 's': mask = SP_SETPCMARK; break; 12904 } 12905 if (mask == 0) 12906 { 12907 EMSG2(_(e_invarg2), flags); 12908 dir = 0; 12909 } 12910 else 12911 *flagsp |= mask; 12912 } 12913 if (dir == 0) 12914 break; 12915 ++flags; 12916 } 12917 } 12918 return dir; 12919 } 12920 12921 /* 12922 * "search()" function 12923 */ 12924 static void 12925 f_search(argvars, rettv) 12926 typval_T *argvars; 12927 typval_T *rettv; 12928 { 12929 char_u *pat; 12930 pos_T pos; 12931 pos_T save_cursor; 12932 int save_p_ws = p_ws; 12933 int dir; 12934 int flags = 0; 12935 12936 rettv->vval.v_number = 0; /* default: FAIL */ 12937 12938 pat = get_tv_string(&argvars[0]); 12939 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 12940 if (dir == 0) 12941 goto theend; 12942 /* 12943 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 12944 * Check to make sure only those flags are set. 12945 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 12946 * flags cannot be set. Check for that condition also. 12947 */ 12948 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 12949 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 12950 { 12951 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 12952 goto theend; 12953 } 12954 12955 pos = save_cursor = curwin->w_cursor; 12956 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 12957 SEARCH_KEEP, RE_SEARCH) != FAIL) 12958 { 12959 rettv->vval.v_number = pos.lnum; 12960 if (flags & SP_SETPCMARK) 12961 setpcmark(); 12962 curwin->w_cursor = pos; 12963 /* "/$" will put the cursor after the end of the line, may need to 12964 * correct that here */ 12965 check_cursor(); 12966 } 12967 12968 /* If 'n' flag is used: restore cursor position. */ 12969 if (flags & SP_NOMOVE) 12970 curwin->w_cursor = save_cursor; 12971 theend: 12972 p_ws = save_p_ws; 12973 } 12974 12975 /* 12976 * "searchpair()" function 12977 */ 12978 static void 12979 f_searchpair(argvars, rettv) 12980 typval_T *argvars; 12981 typval_T *rettv; 12982 { 12983 char_u *spat, *mpat, *epat; 12984 char_u *skip; 12985 int save_p_ws = p_ws; 12986 int dir; 12987 int flags = 0; 12988 char_u nbuf1[NUMBUFLEN]; 12989 char_u nbuf2[NUMBUFLEN]; 12990 char_u nbuf3[NUMBUFLEN]; 12991 12992 rettv->vval.v_number = 0; /* default: FAIL */ 12993 12994 /* Get the three pattern arguments: start, middle, end. */ 12995 spat = get_tv_string_chk(&argvars[0]); 12996 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 12997 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 12998 if (spat == NULL || mpat == NULL || epat == NULL) 12999 goto theend; /* type error */ 13000 13001 /* Handle the optional fourth argument: flags */ 13002 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13003 if (dir == 0) 13004 goto theend; 13005 /* 13006 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13007 */ 13008 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13009 { 13010 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13011 goto theend; 13012 } 13013 13014 /* Optional fifth argument: skip expresion */ 13015 if (argvars[3].v_type == VAR_UNKNOWN 13016 || argvars[4].v_type == VAR_UNKNOWN) 13017 skip = (char_u *)""; 13018 else 13019 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13020 if (skip == NULL) 13021 goto theend; /* type error */ 13022 13023 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13024 13025 theend: 13026 p_ws = save_p_ws; 13027 } 13028 13029 /* 13030 * Search for a start/middle/end thing. 13031 * Used by searchpair(), see its documentation for the details. 13032 * Returns 0 or -1 for no match, 13033 */ 13034 long 13035 do_searchpair(spat, mpat, epat, dir, skip, flags) 13036 char_u *spat; /* start pattern */ 13037 char_u *mpat; /* middle pattern */ 13038 char_u *epat; /* end pattern */ 13039 int dir; /* BACKWARD or FORWARD */ 13040 char_u *skip; /* skip expression */ 13041 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13042 { 13043 char_u *save_cpo; 13044 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13045 long retval = 0; 13046 pos_T pos; 13047 pos_T firstpos; 13048 pos_T foundpos; 13049 pos_T save_cursor; 13050 pos_T save_pos; 13051 int n; 13052 int r; 13053 int nest = 1; 13054 int err; 13055 13056 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13057 save_cpo = p_cpo; 13058 p_cpo = (char_u *)""; 13059 13060 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13061 * start/middle/end (pat3, for the top pair). */ 13062 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13063 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13064 if (pat2 == NULL || pat3 == NULL) 13065 goto theend; 13066 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13067 if (*mpat == NUL) 13068 STRCPY(pat3, pat2); 13069 else 13070 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13071 spat, epat, mpat); 13072 13073 save_cursor = curwin->w_cursor; 13074 pos = curwin->w_cursor; 13075 firstpos.lnum = 0; 13076 foundpos.lnum = 0; 13077 pat = pat3; 13078 for (;;) 13079 { 13080 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13081 SEARCH_KEEP, RE_SEARCH); 13082 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13083 /* didn't find it or found the first match again: FAIL */ 13084 break; 13085 13086 if (firstpos.lnum == 0) 13087 firstpos = pos; 13088 if (equalpos(pos, foundpos)) 13089 { 13090 /* Found the same position again. Can happen with a pattern that 13091 * has "\zs" at the end and searching backwards. Advance one 13092 * character and try again. */ 13093 if (dir == BACKWARD) 13094 decl(&pos); 13095 else 13096 incl(&pos); 13097 } 13098 foundpos = pos; 13099 13100 /* If the skip pattern matches, ignore this match. */ 13101 if (*skip != NUL) 13102 { 13103 save_pos = curwin->w_cursor; 13104 curwin->w_cursor = pos; 13105 r = eval_to_bool(skip, &err, NULL, FALSE); 13106 curwin->w_cursor = save_pos; 13107 if (err) 13108 { 13109 /* Evaluating {skip} caused an error, break here. */ 13110 curwin->w_cursor = save_cursor; 13111 retval = -1; 13112 break; 13113 } 13114 if (r) 13115 continue; 13116 } 13117 13118 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13119 { 13120 /* Found end when searching backwards or start when searching 13121 * forward: nested pair. */ 13122 ++nest; 13123 pat = pat2; /* nested, don't search for middle */ 13124 } 13125 else 13126 { 13127 /* Found end when searching forward or start when searching 13128 * backward: end of (nested) pair; or found middle in outer pair. */ 13129 if (--nest == 1) 13130 pat = pat3; /* outer level, search for middle */ 13131 } 13132 13133 if (nest == 0) 13134 { 13135 /* Found the match: return matchcount or line number. */ 13136 if (flags & SP_RETCOUNT) 13137 ++retval; 13138 else 13139 retval = pos.lnum; 13140 if (flags & SP_SETPCMARK) 13141 setpcmark(); 13142 curwin->w_cursor = pos; 13143 if (!(flags & SP_REPEAT)) 13144 break; 13145 nest = 1; /* search for next unmatched */ 13146 } 13147 } 13148 13149 /* If 'n' flag is used or search failed: restore cursor position. */ 13150 if ((flags & SP_NOMOVE) || retval == 0) 13151 curwin->w_cursor = save_cursor; 13152 13153 theend: 13154 vim_free(pat2); 13155 vim_free(pat3); 13156 p_cpo = save_cpo; 13157 13158 return retval; 13159 } 13160 13161 /*ARGSUSED*/ 13162 static void 13163 f_server2client(argvars, rettv) 13164 typval_T *argvars; 13165 typval_T *rettv; 13166 { 13167 #ifdef FEAT_CLIENTSERVER 13168 char_u buf[NUMBUFLEN]; 13169 char_u *server = get_tv_string_chk(&argvars[0]); 13170 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13171 13172 rettv->vval.v_number = -1; 13173 if (server == NULL || reply == NULL) 13174 return; 13175 if (check_restricted() || check_secure()) 13176 return; 13177 # ifdef FEAT_X11 13178 if (check_connection() == FAIL) 13179 return; 13180 # endif 13181 13182 if (serverSendReply(server, reply) < 0) 13183 { 13184 EMSG(_("E258: Unable to send to client")); 13185 return; 13186 } 13187 rettv->vval.v_number = 0; 13188 #else 13189 rettv->vval.v_number = -1; 13190 #endif 13191 } 13192 13193 /*ARGSUSED*/ 13194 static void 13195 f_serverlist(argvars, rettv) 13196 typval_T *argvars; 13197 typval_T *rettv; 13198 { 13199 char_u *r = NULL; 13200 13201 #ifdef FEAT_CLIENTSERVER 13202 # ifdef WIN32 13203 r = serverGetVimNames(); 13204 # else 13205 make_connection(); 13206 if (X_DISPLAY != NULL) 13207 r = serverGetVimNames(X_DISPLAY); 13208 # endif 13209 #endif 13210 rettv->v_type = VAR_STRING; 13211 rettv->vval.v_string = r; 13212 } 13213 13214 /* 13215 * "setbufvar()" function 13216 */ 13217 /*ARGSUSED*/ 13218 static void 13219 f_setbufvar(argvars, rettv) 13220 typval_T *argvars; 13221 typval_T *rettv; 13222 { 13223 buf_T *buf; 13224 #ifdef FEAT_AUTOCMD 13225 aco_save_T aco; 13226 #else 13227 buf_T *save_curbuf; 13228 #endif 13229 char_u *varname, *bufvarname; 13230 typval_T *varp; 13231 char_u nbuf[NUMBUFLEN]; 13232 13233 rettv->vval.v_number = 0; 13234 13235 if (check_restricted() || check_secure()) 13236 return; 13237 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13238 varname = get_tv_string_chk(&argvars[1]); 13239 buf = get_buf_tv(&argvars[0]); 13240 varp = &argvars[2]; 13241 13242 if (buf != NULL && varname != NULL && varp != NULL) 13243 { 13244 /* set curbuf to be our buf, temporarily */ 13245 #ifdef FEAT_AUTOCMD 13246 aucmd_prepbuf(&aco, buf); 13247 #else 13248 save_curbuf = curbuf; 13249 curbuf = buf; 13250 #endif 13251 13252 if (*varname == '&') 13253 { 13254 long numval; 13255 char_u *strval; 13256 int error = FALSE; 13257 13258 ++varname; 13259 numval = get_tv_number_chk(varp, &error); 13260 strval = get_tv_string_buf_chk(varp, nbuf); 13261 if (!error && strval != NULL) 13262 set_option_value(varname, numval, strval, OPT_LOCAL); 13263 } 13264 else 13265 { 13266 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13267 if (bufvarname != NULL) 13268 { 13269 STRCPY(bufvarname, "b:"); 13270 STRCPY(bufvarname + 2, varname); 13271 set_var(bufvarname, varp, TRUE); 13272 vim_free(bufvarname); 13273 } 13274 } 13275 13276 /* reset notion of buffer */ 13277 #ifdef FEAT_AUTOCMD 13278 aucmd_restbuf(&aco); 13279 #else 13280 curbuf = save_curbuf; 13281 #endif 13282 } 13283 } 13284 13285 /* 13286 * "setcmdpos()" function 13287 */ 13288 static void 13289 f_setcmdpos(argvars, rettv) 13290 typval_T *argvars; 13291 typval_T *rettv; 13292 { 13293 int pos = (int)get_tv_number(&argvars[0]) - 1; 13294 13295 if (pos >= 0) 13296 rettv->vval.v_number = set_cmdline_pos(pos); 13297 } 13298 13299 /* 13300 * "setline()" function 13301 */ 13302 static void 13303 f_setline(argvars, rettv) 13304 typval_T *argvars; 13305 typval_T *rettv; 13306 { 13307 linenr_T lnum; 13308 char_u *line = NULL; 13309 list_T *l = NULL; 13310 listitem_T *li = NULL; 13311 long added = 0; 13312 linenr_T lcount = curbuf->b_ml.ml_line_count; 13313 13314 lnum = get_tv_lnum(&argvars[0]); 13315 if (argvars[1].v_type == VAR_LIST) 13316 { 13317 l = argvars[1].vval.v_list; 13318 li = l->lv_first; 13319 } 13320 else 13321 line = get_tv_string_chk(&argvars[1]); 13322 13323 rettv->vval.v_number = 0; /* OK */ 13324 for (;;) 13325 { 13326 if (l != NULL) 13327 { 13328 /* list argument, get next string */ 13329 if (li == NULL) 13330 break; 13331 line = get_tv_string_chk(&li->li_tv); 13332 li = li->li_next; 13333 } 13334 13335 rettv->vval.v_number = 1; /* FAIL */ 13336 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13337 break; 13338 if (lnum <= curbuf->b_ml.ml_line_count) 13339 { 13340 /* existing line, replace it */ 13341 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13342 { 13343 changed_bytes(lnum, 0); 13344 check_cursor_col(); 13345 rettv->vval.v_number = 0; /* OK */ 13346 } 13347 } 13348 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13349 { 13350 /* lnum is one past the last line, append the line */ 13351 ++added; 13352 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13353 rettv->vval.v_number = 0; /* OK */ 13354 } 13355 13356 if (l == NULL) /* only one string argument */ 13357 break; 13358 ++lnum; 13359 } 13360 13361 if (added > 0) 13362 appended_lines_mark(lcount, added); 13363 } 13364 13365 /* 13366 * "setqflist()" function 13367 */ 13368 /*ARGSUSED*/ 13369 static void 13370 f_setqflist(argvars, rettv) 13371 typval_T *argvars; 13372 typval_T *rettv; 13373 { 13374 char_u *act; 13375 int action = ' '; 13376 13377 rettv->vval.v_number = -1; 13378 13379 #ifdef FEAT_QUICKFIX 13380 if (argvars[0].v_type != VAR_LIST) 13381 EMSG(_(e_listreq)); 13382 else 13383 { 13384 list_T *l = argvars[0].vval.v_list; 13385 13386 if (argvars[1].v_type == VAR_STRING) 13387 { 13388 act = get_tv_string_chk(&argvars[1]); 13389 if (act == NULL) 13390 return; /* type error; errmsg already given */ 13391 if (*act == 'a' || *act == 'r') 13392 action = *act; 13393 } 13394 13395 if (l != NULL && set_errorlist(l, action) == OK) 13396 rettv->vval.v_number = 0; 13397 } 13398 #endif 13399 } 13400 13401 /* 13402 * "setreg()" function 13403 */ 13404 static void 13405 f_setreg(argvars, rettv) 13406 typval_T *argvars; 13407 typval_T *rettv; 13408 { 13409 int regname; 13410 char_u *strregname; 13411 char_u *stropt; 13412 char_u *strval; 13413 int append; 13414 char_u yank_type; 13415 long block_len; 13416 13417 block_len = -1; 13418 yank_type = MAUTO; 13419 append = FALSE; 13420 13421 strregname = get_tv_string_chk(argvars); 13422 rettv->vval.v_number = 1; /* FAIL is default */ 13423 13424 if (strregname == NULL) 13425 return; /* type error; errmsg already given */ 13426 regname = *strregname; 13427 if (regname == 0 || regname == '@') 13428 regname = '"'; 13429 else if (regname == '=') 13430 return; 13431 13432 if (argvars[2].v_type != VAR_UNKNOWN) 13433 { 13434 stropt = get_tv_string_chk(&argvars[2]); 13435 if (stropt == NULL) 13436 return; /* type error */ 13437 for (; *stropt != NUL; ++stropt) 13438 switch (*stropt) 13439 { 13440 case 'a': case 'A': /* append */ 13441 append = TRUE; 13442 break; 13443 case 'v': case 'c': /* character-wise selection */ 13444 yank_type = MCHAR; 13445 break; 13446 case 'V': case 'l': /* line-wise selection */ 13447 yank_type = MLINE; 13448 break; 13449 #ifdef FEAT_VISUAL 13450 case 'b': case Ctrl_V: /* block-wise selection */ 13451 yank_type = MBLOCK; 13452 if (VIM_ISDIGIT(stropt[1])) 13453 { 13454 ++stropt; 13455 block_len = getdigits(&stropt) - 1; 13456 --stropt; 13457 } 13458 break; 13459 #endif 13460 } 13461 } 13462 13463 strval = get_tv_string_chk(&argvars[1]); 13464 if (strval != NULL) 13465 write_reg_contents_ex(regname, strval, -1, 13466 append, yank_type, block_len); 13467 rettv->vval.v_number = 0; 13468 } 13469 13470 13471 /* 13472 * "setwinvar(expr)" function 13473 */ 13474 /*ARGSUSED*/ 13475 static void 13476 f_setwinvar(argvars, rettv) 13477 typval_T *argvars; 13478 typval_T *rettv; 13479 { 13480 win_T *win; 13481 #ifdef FEAT_WINDOWS 13482 win_T *save_curwin; 13483 #endif 13484 char_u *varname, *winvarname; 13485 typval_T *varp; 13486 char_u nbuf[NUMBUFLEN]; 13487 13488 rettv->vval.v_number = 0; 13489 13490 if (check_restricted() || check_secure()) 13491 return; 13492 win = find_win_by_nr(&argvars[0]); 13493 varname = get_tv_string_chk(&argvars[1]); 13494 varp = &argvars[2]; 13495 13496 if (win != NULL && varname != NULL && varp != NULL) 13497 { 13498 #ifdef FEAT_WINDOWS 13499 /* set curwin to be our win, temporarily */ 13500 save_curwin = curwin; 13501 curwin = win; 13502 curbuf = curwin->w_buffer; 13503 #endif 13504 13505 if (*varname == '&') 13506 { 13507 long numval; 13508 char_u *strval; 13509 int error = FALSE; 13510 13511 ++varname; 13512 numval = get_tv_number_chk(varp, &error); 13513 strval = get_tv_string_buf_chk(varp, nbuf); 13514 if (!error && strval != NULL) 13515 set_option_value(varname, numval, strval, OPT_LOCAL); 13516 } 13517 else 13518 { 13519 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13520 if (winvarname != NULL) 13521 { 13522 STRCPY(winvarname, "w:"); 13523 STRCPY(winvarname + 2, varname); 13524 set_var(winvarname, varp, TRUE); 13525 vim_free(winvarname); 13526 } 13527 } 13528 13529 #ifdef FEAT_WINDOWS 13530 /* Restore current window, if it's still valid (autocomands can make 13531 * it invalid). */ 13532 if (win_valid(save_curwin)) 13533 { 13534 curwin = save_curwin; 13535 curbuf = curwin->w_buffer; 13536 } 13537 #endif 13538 } 13539 } 13540 13541 /* 13542 * "simplify()" function 13543 */ 13544 static void 13545 f_simplify(argvars, rettv) 13546 typval_T *argvars; 13547 typval_T *rettv; 13548 { 13549 char_u *p; 13550 13551 p = get_tv_string(&argvars[0]); 13552 rettv->vval.v_string = vim_strsave(p); 13553 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13554 rettv->v_type = VAR_STRING; 13555 } 13556 13557 static int 13558 #ifdef __BORLANDC__ 13559 _RTLENTRYF 13560 #endif 13561 item_compare __ARGS((const void *s1, const void *s2)); 13562 static int 13563 #ifdef __BORLANDC__ 13564 _RTLENTRYF 13565 #endif 13566 item_compare2 __ARGS((const void *s1, const void *s2)); 13567 13568 static int item_compare_ic; 13569 static char_u *item_compare_func; 13570 static int item_compare_func_err; 13571 #define ITEM_COMPARE_FAIL 999 13572 13573 /* 13574 * Compare functions for f_sort() below. 13575 */ 13576 static int 13577 #ifdef __BORLANDC__ 13578 _RTLENTRYF 13579 #endif 13580 item_compare(s1, s2) 13581 const void *s1; 13582 const void *s2; 13583 { 13584 char_u *p1, *p2; 13585 char_u *tofree1, *tofree2; 13586 int res; 13587 char_u numbuf1[NUMBUFLEN]; 13588 char_u numbuf2[NUMBUFLEN]; 13589 13590 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13591 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13592 if (item_compare_ic) 13593 res = STRICMP(p1, p2); 13594 else 13595 res = STRCMP(p1, p2); 13596 vim_free(tofree1); 13597 vim_free(tofree2); 13598 return res; 13599 } 13600 13601 static int 13602 #ifdef __BORLANDC__ 13603 _RTLENTRYF 13604 #endif 13605 item_compare2(s1, s2) 13606 const void *s1; 13607 const void *s2; 13608 { 13609 int res; 13610 typval_T rettv; 13611 typval_T argv[2]; 13612 int dummy; 13613 13614 /* shortcut after failure in previous call; compare all items equal */ 13615 if (item_compare_func_err) 13616 return 0; 13617 13618 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13619 * in the copy without changing the original list items. */ 13620 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13621 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13622 13623 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13624 res = call_func(item_compare_func, STRLEN(item_compare_func), 13625 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13626 clear_tv(&argv[0]); 13627 clear_tv(&argv[1]); 13628 13629 if (res == FAIL) 13630 res = ITEM_COMPARE_FAIL; 13631 else 13632 /* return value has wrong type */ 13633 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13634 if (item_compare_func_err) 13635 res = ITEM_COMPARE_FAIL; 13636 clear_tv(&rettv); 13637 return res; 13638 } 13639 13640 /* 13641 * "sort({list})" function 13642 */ 13643 static void 13644 f_sort(argvars, rettv) 13645 typval_T *argvars; 13646 typval_T *rettv; 13647 { 13648 list_T *l; 13649 listitem_T *li; 13650 listitem_T **ptrs; 13651 long len; 13652 long i; 13653 13654 rettv->vval.v_number = 0; 13655 if (argvars[0].v_type != VAR_LIST) 13656 EMSG2(_(e_listarg), "sort()"); 13657 else 13658 { 13659 l = argvars[0].vval.v_list; 13660 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13661 return; 13662 rettv->vval.v_list = l; 13663 rettv->v_type = VAR_LIST; 13664 ++l->lv_refcount; 13665 13666 len = list_len(l); 13667 if (len <= 1) 13668 return; /* short list sorts pretty quickly */ 13669 13670 item_compare_ic = FALSE; 13671 item_compare_func = NULL; 13672 if (argvars[1].v_type != VAR_UNKNOWN) 13673 { 13674 if (argvars[1].v_type == VAR_FUNC) 13675 item_compare_func = argvars[1].vval.v_string; 13676 else 13677 { 13678 int error = FALSE; 13679 13680 i = get_tv_number_chk(&argvars[1], &error); 13681 if (error) 13682 return; /* type error; errmsg already given */ 13683 if (i == 1) 13684 item_compare_ic = TRUE; 13685 else 13686 item_compare_func = get_tv_string(&argvars[1]); 13687 } 13688 } 13689 13690 /* Make an array with each entry pointing to an item in the List. */ 13691 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13692 if (ptrs == NULL) 13693 return; 13694 i = 0; 13695 for (li = l->lv_first; li != NULL; li = li->li_next) 13696 ptrs[i++] = li; 13697 13698 item_compare_func_err = FALSE; 13699 /* test the compare function */ 13700 if (item_compare_func != NULL 13701 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13702 == ITEM_COMPARE_FAIL) 13703 EMSG(_("E702: Sort compare function failed")); 13704 else 13705 { 13706 /* Sort the array with item pointers. */ 13707 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13708 item_compare_func == NULL ? item_compare : item_compare2); 13709 13710 if (!item_compare_func_err) 13711 { 13712 /* Clear the List and append the items in the sorted order. */ 13713 l->lv_first = l->lv_last = NULL; 13714 l->lv_len = 0; 13715 for (i = 0; i < len; ++i) 13716 list_append(l, ptrs[i]); 13717 } 13718 } 13719 13720 vim_free(ptrs); 13721 } 13722 } 13723 13724 /* 13725 * "soundfold({word})" function 13726 */ 13727 static void 13728 f_soundfold(argvars, rettv) 13729 typval_T *argvars; 13730 typval_T *rettv; 13731 { 13732 char_u *s; 13733 13734 rettv->v_type = VAR_STRING; 13735 s = get_tv_string(&argvars[0]); 13736 #ifdef FEAT_SYN_HL 13737 rettv->vval.v_string = eval_soundfold(s); 13738 #else 13739 rettv->vval.v_string = vim_strsave(s); 13740 #endif 13741 } 13742 13743 /* 13744 * "spellbadword()" function 13745 */ 13746 /* ARGSUSED */ 13747 static void 13748 f_spellbadword(argvars, rettv) 13749 typval_T *argvars; 13750 typval_T *rettv; 13751 { 13752 int len; 13753 13754 rettv->vval.v_string = NULL; 13755 rettv->v_type = VAR_STRING; 13756 13757 #ifdef FEAT_SYN_HL 13758 /* Find the start and length of the badly spelled word. */ 13759 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL); 13760 if (len != 0) 13761 rettv->vval.v_string = vim_strnsave(ml_get_cursor(), len); 13762 #endif 13763 } 13764 13765 /* 13766 * "spellsuggest()" function 13767 */ 13768 static void 13769 f_spellsuggest(argvars, rettv) 13770 typval_T *argvars; 13771 typval_T *rettv; 13772 { 13773 char_u *str; 13774 int maxcount; 13775 garray_T ga; 13776 list_T *l; 13777 listitem_T *li; 13778 int i; 13779 13780 l = list_alloc(); 13781 if (l == NULL) 13782 return; 13783 rettv->v_type = VAR_LIST; 13784 rettv->vval.v_list = l; 13785 ++l->lv_refcount; 13786 13787 #ifdef FEAT_SYN_HL 13788 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13789 { 13790 str = get_tv_string(&argvars[0]); 13791 if (argvars[1].v_type != VAR_UNKNOWN) 13792 { 13793 maxcount = get_tv_number(&argvars[1]); 13794 if (maxcount <= 0) 13795 return; 13796 } 13797 else 13798 maxcount = 25; 13799 13800 spell_suggest_list(&ga, str, maxcount, FALSE); 13801 13802 for (i = 0; i < ga.ga_len; ++i) 13803 { 13804 str = ((char_u **)ga.ga_data)[i]; 13805 13806 li = listitem_alloc(); 13807 if (li == NULL) 13808 vim_free(str); 13809 else 13810 { 13811 li->li_tv.v_type = VAR_STRING; 13812 li->li_tv.v_lock = 0; 13813 li->li_tv.vval.v_string = str; 13814 list_append(l, li); 13815 } 13816 } 13817 ga_clear(&ga); 13818 } 13819 #endif 13820 } 13821 13822 static void 13823 f_split(argvars, rettv) 13824 typval_T *argvars; 13825 typval_T *rettv; 13826 { 13827 char_u *str; 13828 char_u *end; 13829 char_u *pat = NULL; 13830 regmatch_T regmatch; 13831 char_u patbuf[NUMBUFLEN]; 13832 char_u *save_cpo; 13833 int match; 13834 listitem_T *ni; 13835 list_T *l; 13836 colnr_T col = 0; 13837 int keepempty = FALSE; 13838 int typeerr = FALSE; 13839 13840 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13841 save_cpo = p_cpo; 13842 p_cpo = (char_u *)""; 13843 13844 str = get_tv_string(&argvars[0]); 13845 if (argvars[1].v_type != VAR_UNKNOWN) 13846 { 13847 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13848 if (pat == NULL) 13849 typeerr = TRUE; 13850 if (argvars[2].v_type != VAR_UNKNOWN) 13851 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 13852 } 13853 if (pat == NULL || *pat == NUL) 13854 pat = (char_u *)"[\\x01- ]\\+"; 13855 13856 l = list_alloc(); 13857 if (l == NULL) 13858 return; 13859 rettv->v_type = VAR_LIST; 13860 rettv->vval.v_list = l; 13861 ++l->lv_refcount; 13862 if (typeerr) 13863 return; 13864 13865 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13866 if (regmatch.regprog != NULL) 13867 { 13868 regmatch.rm_ic = FALSE; 13869 while (*str != NUL || keepempty) 13870 { 13871 if (*str == NUL) 13872 match = FALSE; /* empty item at the end */ 13873 else 13874 match = vim_regexec_nl(®match, str, col); 13875 if (match) 13876 end = regmatch.startp[0]; 13877 else 13878 end = str + STRLEN(str); 13879 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 13880 && match && end < regmatch.endp[0])) 13881 { 13882 ni = listitem_alloc(); 13883 if (ni == NULL) 13884 break; 13885 ni->li_tv.v_type = VAR_STRING; 13886 ni->li_tv.v_lock = 0; 13887 ni->li_tv.vval.v_string = vim_strnsave(str, end - str); 13888 list_append(l, ni); 13889 } 13890 if (!match) 13891 break; 13892 /* Advance to just after the match. */ 13893 if (regmatch.endp[0] > str) 13894 col = 0; 13895 else 13896 { 13897 /* Don't get stuck at the same match. */ 13898 #ifdef FEAT_MBYTE 13899 col = (*mb_ptr2len)(regmatch.endp[0]); 13900 #else 13901 col = 1; 13902 #endif 13903 } 13904 str = regmatch.endp[0]; 13905 } 13906 13907 vim_free(regmatch.regprog); 13908 } 13909 13910 p_cpo = save_cpo; 13911 } 13912 13913 #ifdef HAVE_STRFTIME 13914 /* 13915 * "strftime({format}[, {time}])" function 13916 */ 13917 static void 13918 f_strftime(argvars, rettv) 13919 typval_T *argvars; 13920 typval_T *rettv; 13921 { 13922 char_u result_buf[256]; 13923 struct tm *curtime; 13924 time_t seconds; 13925 char_u *p; 13926 13927 rettv->v_type = VAR_STRING; 13928 13929 p = get_tv_string(&argvars[0]); 13930 if (argvars[1].v_type == VAR_UNKNOWN) 13931 seconds = time(NULL); 13932 else 13933 seconds = (time_t)get_tv_number(&argvars[1]); 13934 curtime = localtime(&seconds); 13935 /* MSVC returns NULL for an invalid value of seconds. */ 13936 if (curtime == NULL) 13937 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 13938 else 13939 { 13940 # ifdef FEAT_MBYTE 13941 vimconv_T conv; 13942 char_u *enc; 13943 13944 conv.vc_type = CONV_NONE; 13945 enc = enc_locale(); 13946 convert_setup(&conv, p_enc, enc); 13947 if (conv.vc_type != CONV_NONE) 13948 p = string_convert(&conv, p, NULL); 13949 # endif 13950 if (p != NULL) 13951 (void)strftime((char *)result_buf, sizeof(result_buf), 13952 (char *)p, curtime); 13953 else 13954 result_buf[0] = NUL; 13955 13956 # ifdef FEAT_MBYTE 13957 if (conv.vc_type != CONV_NONE) 13958 vim_free(p); 13959 convert_setup(&conv, enc, p_enc); 13960 if (conv.vc_type != CONV_NONE) 13961 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 13962 else 13963 # endif 13964 rettv->vval.v_string = vim_strsave(result_buf); 13965 13966 # ifdef FEAT_MBYTE 13967 /* Release conversion descriptors */ 13968 convert_setup(&conv, NULL, NULL); 13969 vim_free(enc); 13970 # endif 13971 } 13972 } 13973 #endif 13974 13975 /* 13976 * "stridx()" function 13977 */ 13978 static void 13979 f_stridx(argvars, rettv) 13980 typval_T *argvars; 13981 typval_T *rettv; 13982 { 13983 char_u buf[NUMBUFLEN]; 13984 char_u *needle; 13985 char_u *haystack; 13986 char_u *save_haystack; 13987 char_u *pos; 13988 int start_idx; 13989 13990 needle = get_tv_string_chk(&argvars[1]); 13991 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 13992 rettv->vval.v_number = -1; 13993 if (needle == NULL || haystack == NULL) 13994 return; /* type error; errmsg already given */ 13995 13996 if (argvars[2].v_type != VAR_UNKNOWN) 13997 { 13998 int error = FALSE; 13999 14000 start_idx = get_tv_number_chk(&argvars[2], &error); 14001 if (error || start_idx >= (int)STRLEN(haystack)) 14002 return; 14003 if (start_idx >= 0) 14004 haystack += start_idx; 14005 } 14006 14007 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14008 if (pos != NULL) 14009 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14010 } 14011 14012 /* 14013 * "string()" function 14014 */ 14015 static void 14016 f_string(argvars, rettv) 14017 typval_T *argvars; 14018 typval_T *rettv; 14019 { 14020 char_u *tofree; 14021 char_u numbuf[NUMBUFLEN]; 14022 14023 rettv->v_type = VAR_STRING; 14024 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14025 if (tofree == NULL) 14026 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14027 } 14028 14029 /* 14030 * "strlen()" function 14031 */ 14032 static void 14033 f_strlen(argvars, rettv) 14034 typval_T *argvars; 14035 typval_T *rettv; 14036 { 14037 rettv->vval.v_number = (varnumber_T)(STRLEN( 14038 get_tv_string(&argvars[0]))); 14039 } 14040 14041 /* 14042 * "strpart()" function 14043 */ 14044 static void 14045 f_strpart(argvars, rettv) 14046 typval_T *argvars; 14047 typval_T *rettv; 14048 { 14049 char_u *p; 14050 int n; 14051 int len; 14052 int slen; 14053 int error = FALSE; 14054 14055 p = get_tv_string(&argvars[0]); 14056 slen = (int)STRLEN(p); 14057 14058 n = get_tv_number_chk(&argvars[1], &error); 14059 if (error) 14060 len = 0; 14061 else if (argvars[2].v_type != VAR_UNKNOWN) 14062 len = get_tv_number(&argvars[2]); 14063 else 14064 len = slen - n; /* default len: all bytes that are available. */ 14065 14066 /* 14067 * Only return the overlap between the specified part and the actual 14068 * string. 14069 */ 14070 if (n < 0) 14071 { 14072 len += n; 14073 n = 0; 14074 } 14075 else if (n > slen) 14076 n = slen; 14077 if (len < 0) 14078 len = 0; 14079 else if (n + len > slen) 14080 len = slen - n; 14081 14082 rettv->v_type = VAR_STRING; 14083 rettv->vval.v_string = vim_strnsave(p + n, len); 14084 } 14085 14086 /* 14087 * "strridx()" function 14088 */ 14089 static void 14090 f_strridx(argvars, rettv) 14091 typval_T *argvars; 14092 typval_T *rettv; 14093 { 14094 char_u buf[NUMBUFLEN]; 14095 char_u *needle; 14096 char_u *haystack; 14097 char_u *rest; 14098 char_u *lastmatch = NULL; 14099 int haystack_len, end_idx; 14100 14101 needle = get_tv_string_chk(&argvars[1]); 14102 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14103 haystack_len = STRLEN(haystack); 14104 14105 rettv->vval.v_number = -1; 14106 if (needle == NULL || haystack == NULL) 14107 return; /* type error; errmsg already given */ 14108 if (argvars[2].v_type != VAR_UNKNOWN) 14109 { 14110 /* Third argument: upper limit for index */ 14111 end_idx = get_tv_number_chk(&argvars[2], NULL); 14112 if (end_idx < 0) 14113 return; /* can never find a match */ 14114 } 14115 else 14116 end_idx = haystack_len; 14117 14118 if (*needle == NUL) 14119 { 14120 /* Empty string matches past the end. */ 14121 lastmatch = haystack + end_idx; 14122 } 14123 else 14124 { 14125 for (rest = haystack; *rest != '\0'; ++rest) 14126 { 14127 rest = (char_u *)strstr((char *)rest, (char *)needle); 14128 if (rest == NULL || rest > haystack + end_idx) 14129 break; 14130 lastmatch = rest; 14131 } 14132 } 14133 14134 if (lastmatch == NULL) 14135 rettv->vval.v_number = -1; 14136 else 14137 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14138 } 14139 14140 /* 14141 * "strtrans()" function 14142 */ 14143 static void 14144 f_strtrans(argvars, rettv) 14145 typval_T *argvars; 14146 typval_T *rettv; 14147 { 14148 rettv->v_type = VAR_STRING; 14149 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14150 } 14151 14152 /* 14153 * "submatch()" function 14154 */ 14155 static void 14156 f_submatch(argvars, rettv) 14157 typval_T *argvars; 14158 typval_T *rettv; 14159 { 14160 rettv->v_type = VAR_STRING; 14161 rettv->vval.v_string = 14162 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14163 } 14164 14165 /* 14166 * "substitute()" function 14167 */ 14168 static void 14169 f_substitute(argvars, rettv) 14170 typval_T *argvars; 14171 typval_T *rettv; 14172 { 14173 char_u patbuf[NUMBUFLEN]; 14174 char_u subbuf[NUMBUFLEN]; 14175 char_u flagsbuf[NUMBUFLEN]; 14176 14177 char_u *str = get_tv_string_chk(&argvars[0]); 14178 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14179 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14180 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14181 14182 rettv->v_type = VAR_STRING; 14183 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14184 rettv->vval.v_string = NULL; 14185 else 14186 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14187 } 14188 14189 /* 14190 * "synID(lnum, col, trans)" function 14191 */ 14192 /*ARGSUSED*/ 14193 static void 14194 f_synID(argvars, rettv) 14195 typval_T *argvars; 14196 typval_T *rettv; 14197 { 14198 int id = 0; 14199 #ifdef FEAT_SYN_HL 14200 long lnum; 14201 long col; 14202 int trans; 14203 int transerr = FALSE; 14204 14205 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14206 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14207 trans = get_tv_number_chk(&argvars[2], &transerr); 14208 14209 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14210 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14211 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14212 #endif 14213 14214 rettv->vval.v_number = id; 14215 } 14216 14217 /* 14218 * "synIDattr(id, what [, mode])" function 14219 */ 14220 /*ARGSUSED*/ 14221 static void 14222 f_synIDattr(argvars, rettv) 14223 typval_T *argvars; 14224 typval_T *rettv; 14225 { 14226 char_u *p = NULL; 14227 #ifdef FEAT_SYN_HL 14228 int id; 14229 char_u *what; 14230 char_u *mode; 14231 char_u modebuf[NUMBUFLEN]; 14232 int modec; 14233 14234 id = get_tv_number(&argvars[0]); 14235 what = get_tv_string(&argvars[1]); 14236 if (argvars[2].v_type != VAR_UNKNOWN) 14237 { 14238 mode = get_tv_string_buf(&argvars[2], modebuf); 14239 modec = TOLOWER_ASC(mode[0]); 14240 if (modec != 't' && modec != 'c' 14241 #ifdef FEAT_GUI 14242 && modec != 'g' 14243 #endif 14244 ) 14245 modec = 0; /* replace invalid with current */ 14246 } 14247 else 14248 { 14249 #ifdef FEAT_GUI 14250 if (gui.in_use) 14251 modec = 'g'; 14252 else 14253 #endif 14254 if (t_colors > 1) 14255 modec = 'c'; 14256 else 14257 modec = 't'; 14258 } 14259 14260 14261 switch (TOLOWER_ASC(what[0])) 14262 { 14263 case 'b': 14264 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14265 p = highlight_color(id, what, modec); 14266 else /* bold */ 14267 p = highlight_has_attr(id, HL_BOLD, modec); 14268 break; 14269 14270 case 'f': /* fg[#] */ 14271 p = highlight_color(id, what, modec); 14272 break; 14273 14274 case 'i': 14275 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14276 p = highlight_has_attr(id, HL_INVERSE, modec); 14277 else /* italic */ 14278 p = highlight_has_attr(id, HL_ITALIC, modec); 14279 break; 14280 14281 case 'n': /* name */ 14282 p = get_highlight_name(NULL, id - 1); 14283 break; 14284 14285 case 'r': /* reverse */ 14286 p = highlight_has_attr(id, HL_INVERSE, modec); 14287 break; 14288 14289 case 's': /* standout */ 14290 p = highlight_has_attr(id, HL_STANDOUT, modec); 14291 break; 14292 14293 case 'u': 14294 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14295 /* underline */ 14296 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14297 else 14298 /* undercurl */ 14299 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14300 break; 14301 } 14302 14303 if (p != NULL) 14304 p = vim_strsave(p); 14305 #endif 14306 rettv->v_type = VAR_STRING; 14307 rettv->vval.v_string = p; 14308 } 14309 14310 /* 14311 * "synIDtrans(id)" function 14312 */ 14313 /*ARGSUSED*/ 14314 static void 14315 f_synIDtrans(argvars, rettv) 14316 typval_T *argvars; 14317 typval_T *rettv; 14318 { 14319 int id; 14320 14321 #ifdef FEAT_SYN_HL 14322 id = get_tv_number(&argvars[0]); 14323 14324 if (id > 0) 14325 id = syn_get_final_id(id); 14326 else 14327 #endif 14328 id = 0; 14329 14330 rettv->vval.v_number = id; 14331 } 14332 14333 /* 14334 * "system()" function 14335 */ 14336 static void 14337 f_system(argvars, rettv) 14338 typval_T *argvars; 14339 typval_T *rettv; 14340 { 14341 char_u *res = NULL; 14342 char_u *p; 14343 char_u *infile = NULL; 14344 char_u buf[NUMBUFLEN]; 14345 int err = FALSE; 14346 FILE *fd; 14347 14348 if (argvars[1].v_type != VAR_UNKNOWN) 14349 { 14350 /* 14351 * Write the string to a temp file, to be used for input of the shell 14352 * command. 14353 */ 14354 if ((infile = vim_tempname('i')) == NULL) 14355 { 14356 EMSG(_(e_notmp)); 14357 return; 14358 } 14359 14360 fd = mch_fopen((char *)infile, WRITEBIN); 14361 if (fd == NULL) 14362 { 14363 EMSG2(_(e_notopen), infile); 14364 goto done; 14365 } 14366 p = get_tv_string_buf_chk(&argvars[1], buf); 14367 if (p == NULL) 14368 goto done; /* type error; errmsg already given */ 14369 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14370 err = TRUE; 14371 if (fclose(fd) != 0) 14372 err = TRUE; 14373 if (err) 14374 { 14375 EMSG(_("E677: Error writing temp file")); 14376 goto done; 14377 } 14378 } 14379 14380 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14381 14382 #ifdef USE_CR 14383 /* translate <CR> into <NL> */ 14384 if (res != NULL) 14385 { 14386 char_u *s; 14387 14388 for (s = res; *s; ++s) 14389 { 14390 if (*s == CAR) 14391 *s = NL; 14392 } 14393 } 14394 #else 14395 # ifdef USE_CRNL 14396 /* translate <CR><NL> into <NL> */ 14397 if (res != NULL) 14398 { 14399 char_u *s, *d; 14400 14401 d = res; 14402 for (s = res; *s; ++s) 14403 { 14404 if (s[0] == CAR && s[1] == NL) 14405 ++s; 14406 *d++ = *s; 14407 } 14408 *d = NUL; 14409 } 14410 # endif 14411 #endif 14412 14413 done: 14414 if (infile != NULL) 14415 { 14416 mch_remove(infile); 14417 vim_free(infile); 14418 } 14419 rettv->v_type = VAR_STRING; 14420 rettv->vval.v_string = res; 14421 } 14422 14423 /* 14424 * "taglist()" function 14425 */ 14426 static void 14427 f_taglist(argvars, rettv) 14428 typval_T *argvars; 14429 typval_T *rettv; 14430 { 14431 char_u *tag_pattern; 14432 list_T *l; 14433 14434 tag_pattern = get_tv_string(&argvars[0]); 14435 14436 rettv->vval.v_number = FALSE; 14437 if (*tag_pattern == NUL) 14438 return; 14439 14440 l = list_alloc(); 14441 if (l != NULL) 14442 { 14443 if (get_tags(l, tag_pattern) != FAIL) 14444 { 14445 rettv->vval.v_list = l; 14446 rettv->v_type = VAR_LIST; 14447 ++l->lv_refcount; 14448 } 14449 else 14450 list_free(l); 14451 } 14452 } 14453 14454 /* 14455 * "tempname()" function 14456 */ 14457 /*ARGSUSED*/ 14458 static void 14459 f_tempname(argvars, rettv) 14460 typval_T *argvars; 14461 typval_T *rettv; 14462 { 14463 static int x = 'A'; 14464 14465 rettv->v_type = VAR_STRING; 14466 rettv->vval.v_string = vim_tempname(x); 14467 14468 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14469 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14470 do 14471 { 14472 if (x == 'Z') 14473 x = '0'; 14474 else if (x == '9') 14475 x = 'A'; 14476 else 14477 { 14478 #ifdef EBCDIC 14479 if (x == 'I') 14480 x = 'J'; 14481 else if (x == 'R') 14482 x = 'S'; 14483 else 14484 #endif 14485 ++x; 14486 } 14487 } while (x == 'I' || x == 'O'); 14488 } 14489 14490 /* 14491 * "test(list)" function: Just checking the walls... 14492 */ 14493 /*ARGSUSED*/ 14494 static void 14495 f_test(argvars, rettv) 14496 typval_T *argvars; 14497 typval_T *rettv; 14498 { 14499 /* Used for unit testing. Change the code below to your liking. */ 14500 #if 0 14501 listitem_T *li; 14502 list_T *l; 14503 char_u *bad, *good; 14504 14505 if (argvars[0].v_type != VAR_LIST) 14506 return; 14507 l = argvars[0].vval.v_list; 14508 if (l == NULL) 14509 return; 14510 li = l->lv_first; 14511 if (li == NULL) 14512 return; 14513 bad = get_tv_string(&li->li_tv); 14514 li = li->li_next; 14515 if (li == NULL) 14516 return; 14517 good = get_tv_string(&li->li_tv); 14518 rettv->vval.v_number = test_edit_score(bad, good); 14519 #endif 14520 } 14521 14522 /* 14523 * "tolower(string)" function 14524 */ 14525 static void 14526 f_tolower(argvars, rettv) 14527 typval_T *argvars; 14528 typval_T *rettv; 14529 { 14530 char_u *p; 14531 14532 p = vim_strsave(get_tv_string(&argvars[0])); 14533 rettv->v_type = VAR_STRING; 14534 rettv->vval.v_string = p; 14535 14536 if (p != NULL) 14537 while (*p != NUL) 14538 { 14539 #ifdef FEAT_MBYTE 14540 int l; 14541 14542 if (enc_utf8) 14543 { 14544 int c, lc; 14545 14546 c = utf_ptr2char(p); 14547 lc = utf_tolower(c); 14548 l = utf_ptr2len(p); 14549 /* TODO: reallocate string when byte count changes. */ 14550 if (utf_char2len(lc) == l) 14551 utf_char2bytes(lc, p); 14552 p += l; 14553 } 14554 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14555 p += l; /* skip multi-byte character */ 14556 else 14557 #endif 14558 { 14559 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14560 ++p; 14561 } 14562 } 14563 } 14564 14565 /* 14566 * "toupper(string)" function 14567 */ 14568 static void 14569 f_toupper(argvars, rettv) 14570 typval_T *argvars; 14571 typval_T *rettv; 14572 { 14573 rettv->v_type = VAR_STRING; 14574 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14575 } 14576 14577 /* 14578 * "tr(string, fromstr, tostr)" function 14579 */ 14580 static void 14581 f_tr(argvars, rettv) 14582 typval_T *argvars; 14583 typval_T *rettv; 14584 { 14585 char_u *instr; 14586 char_u *fromstr; 14587 char_u *tostr; 14588 char_u *p; 14589 #ifdef FEAT_MBYTE 14590 int inlen; 14591 int fromlen; 14592 int tolen; 14593 int idx; 14594 char_u *cpstr; 14595 int cplen; 14596 int first = TRUE; 14597 #endif 14598 char_u buf[NUMBUFLEN]; 14599 char_u buf2[NUMBUFLEN]; 14600 garray_T ga; 14601 14602 instr = get_tv_string(&argvars[0]); 14603 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14604 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14605 14606 /* Default return value: empty string. */ 14607 rettv->v_type = VAR_STRING; 14608 rettv->vval.v_string = NULL; 14609 if (fromstr == NULL || tostr == NULL) 14610 return; /* type error; errmsg already given */ 14611 ga_init2(&ga, (int)sizeof(char), 80); 14612 14613 #ifdef FEAT_MBYTE 14614 if (!has_mbyte) 14615 #endif 14616 /* not multi-byte: fromstr and tostr must be the same length */ 14617 if (STRLEN(fromstr) != STRLEN(tostr)) 14618 { 14619 #ifdef FEAT_MBYTE 14620 error: 14621 #endif 14622 EMSG2(_(e_invarg2), fromstr); 14623 ga_clear(&ga); 14624 return; 14625 } 14626 14627 /* fromstr and tostr have to contain the same number of chars */ 14628 while (*instr != NUL) 14629 { 14630 #ifdef FEAT_MBYTE 14631 if (has_mbyte) 14632 { 14633 inlen = (*mb_ptr2len)(instr); 14634 cpstr = instr; 14635 cplen = inlen; 14636 idx = 0; 14637 for (p = fromstr; *p != NUL; p += fromlen) 14638 { 14639 fromlen = (*mb_ptr2len)(p); 14640 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14641 { 14642 for (p = tostr; *p != NUL; p += tolen) 14643 { 14644 tolen = (*mb_ptr2len)(p); 14645 if (idx-- == 0) 14646 { 14647 cplen = tolen; 14648 cpstr = p; 14649 break; 14650 } 14651 } 14652 if (*p == NUL) /* tostr is shorter than fromstr */ 14653 goto error; 14654 break; 14655 } 14656 ++idx; 14657 } 14658 14659 if (first && cpstr == instr) 14660 { 14661 /* Check that fromstr and tostr have the same number of 14662 * (multi-byte) characters. Done only once when a character 14663 * of instr doesn't appear in fromstr. */ 14664 first = FALSE; 14665 for (p = tostr; *p != NUL; p += tolen) 14666 { 14667 tolen = (*mb_ptr2len)(p); 14668 --idx; 14669 } 14670 if (idx != 0) 14671 goto error; 14672 } 14673 14674 ga_grow(&ga, cplen); 14675 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14676 ga.ga_len += cplen; 14677 14678 instr += inlen; 14679 } 14680 else 14681 #endif 14682 { 14683 /* When not using multi-byte chars we can do it faster. */ 14684 p = vim_strchr(fromstr, *instr); 14685 if (p != NULL) 14686 ga_append(&ga, tostr[p - fromstr]); 14687 else 14688 ga_append(&ga, *instr); 14689 ++instr; 14690 } 14691 } 14692 14693 rettv->vval.v_string = ga.ga_data; 14694 } 14695 14696 /* 14697 * "type(expr)" function 14698 */ 14699 static void 14700 f_type(argvars, rettv) 14701 typval_T *argvars; 14702 typval_T *rettv; 14703 { 14704 int n; 14705 14706 switch (argvars[0].v_type) 14707 { 14708 case VAR_NUMBER: n = 0; break; 14709 case VAR_STRING: n = 1; break; 14710 case VAR_FUNC: n = 2; break; 14711 case VAR_LIST: n = 3; break; 14712 case VAR_DICT: n = 4; break; 14713 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14714 } 14715 rettv->vval.v_number = n; 14716 } 14717 14718 /* 14719 * "values(dict)" function 14720 */ 14721 static void 14722 f_values(argvars, rettv) 14723 typval_T *argvars; 14724 typval_T *rettv; 14725 { 14726 dict_list(argvars, rettv, 1); 14727 } 14728 14729 /* 14730 * "virtcol(string)" function 14731 */ 14732 static void 14733 f_virtcol(argvars, rettv) 14734 typval_T *argvars; 14735 typval_T *rettv; 14736 { 14737 colnr_T vcol = 0; 14738 pos_T *fp; 14739 14740 fp = var2fpos(&argvars[0], FALSE); 14741 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14742 { 14743 getvvcol(curwin, fp, NULL, NULL, &vcol); 14744 ++vcol; 14745 } 14746 14747 rettv->vval.v_number = vcol; 14748 } 14749 14750 /* 14751 * "visualmode()" function 14752 */ 14753 /*ARGSUSED*/ 14754 static void 14755 f_visualmode(argvars, rettv) 14756 typval_T *argvars; 14757 typval_T *rettv; 14758 { 14759 #ifdef FEAT_VISUAL 14760 char_u str[2]; 14761 14762 rettv->v_type = VAR_STRING; 14763 str[0] = curbuf->b_visual_mode_eval; 14764 str[1] = NUL; 14765 rettv->vval.v_string = vim_strsave(str); 14766 14767 /* A non-zero number or non-empty string argument: reset mode. */ 14768 if ((argvars[0].v_type == VAR_NUMBER 14769 && argvars[0].vval.v_number != 0) 14770 || (argvars[0].v_type == VAR_STRING 14771 && *get_tv_string(&argvars[0]) != NUL)) 14772 curbuf->b_visual_mode_eval = NUL; 14773 #else 14774 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14775 #endif 14776 } 14777 14778 /* 14779 * "winbufnr(nr)" function 14780 */ 14781 static void 14782 f_winbufnr(argvars, rettv) 14783 typval_T *argvars; 14784 typval_T *rettv; 14785 { 14786 win_T *wp; 14787 14788 wp = find_win_by_nr(&argvars[0]); 14789 if (wp == NULL) 14790 rettv->vval.v_number = -1; 14791 else 14792 rettv->vval.v_number = wp->w_buffer->b_fnum; 14793 } 14794 14795 /* 14796 * "wincol()" function 14797 */ 14798 /*ARGSUSED*/ 14799 static void 14800 f_wincol(argvars, rettv) 14801 typval_T *argvars; 14802 typval_T *rettv; 14803 { 14804 validate_cursor(); 14805 rettv->vval.v_number = curwin->w_wcol + 1; 14806 } 14807 14808 /* 14809 * "winheight(nr)" function 14810 */ 14811 static void 14812 f_winheight(argvars, rettv) 14813 typval_T *argvars; 14814 typval_T *rettv; 14815 { 14816 win_T *wp; 14817 14818 wp = find_win_by_nr(&argvars[0]); 14819 if (wp == NULL) 14820 rettv->vval.v_number = -1; 14821 else 14822 rettv->vval.v_number = wp->w_height; 14823 } 14824 14825 /* 14826 * "winline()" function 14827 */ 14828 /*ARGSUSED*/ 14829 static void 14830 f_winline(argvars, rettv) 14831 typval_T *argvars; 14832 typval_T *rettv; 14833 { 14834 validate_cursor(); 14835 rettv->vval.v_number = curwin->w_wrow + 1; 14836 } 14837 14838 /* 14839 * "winnr()" function 14840 */ 14841 /* ARGSUSED */ 14842 static void 14843 f_winnr(argvars, rettv) 14844 typval_T *argvars; 14845 typval_T *rettv; 14846 { 14847 int nr = 1; 14848 #ifdef FEAT_WINDOWS 14849 win_T *wp; 14850 win_T *twin = curwin; 14851 char_u *arg; 14852 14853 if (argvars[0].v_type != VAR_UNKNOWN) 14854 { 14855 arg = get_tv_string_chk(&argvars[0]); 14856 if (arg == NULL) 14857 nr = 0; /* type error; errmsg already given */ 14858 else if (STRCMP(arg, "$") == 0) 14859 twin = lastwin; 14860 else if (STRCMP(arg, "#") == 0) 14861 { 14862 twin = prevwin; 14863 if (prevwin == NULL) 14864 nr = 0; 14865 } 14866 else 14867 { 14868 EMSG2(_(e_invexpr2), arg); 14869 nr = 0; 14870 } 14871 } 14872 14873 if (nr > 0) 14874 for (wp = firstwin; wp != twin; wp = wp->w_next) 14875 ++nr; 14876 #endif 14877 rettv->vval.v_number = nr; 14878 } 14879 14880 /* 14881 * "winrestcmd()" function 14882 */ 14883 /* ARGSUSED */ 14884 static void 14885 f_winrestcmd(argvars, rettv) 14886 typval_T *argvars; 14887 typval_T *rettv; 14888 { 14889 #ifdef FEAT_WINDOWS 14890 win_T *wp; 14891 int winnr = 1; 14892 garray_T ga; 14893 char_u buf[50]; 14894 14895 ga_init2(&ga, (int)sizeof(char), 70); 14896 for (wp = firstwin; wp != NULL; wp = wp->w_next) 14897 { 14898 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 14899 ga_concat(&ga, buf); 14900 # ifdef FEAT_VERTSPLIT 14901 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 14902 ga_concat(&ga, buf); 14903 # endif 14904 ++winnr; 14905 } 14906 ga_append(&ga, NUL); 14907 14908 rettv->vval.v_string = ga.ga_data; 14909 #else 14910 rettv->vval.v_string = NULL; 14911 #endif 14912 rettv->v_type = VAR_STRING; 14913 } 14914 14915 /* 14916 * "winwidth(nr)" function 14917 */ 14918 static void 14919 f_winwidth(argvars, rettv) 14920 typval_T *argvars; 14921 typval_T *rettv; 14922 { 14923 win_T *wp; 14924 14925 wp = find_win_by_nr(&argvars[0]); 14926 if (wp == NULL) 14927 rettv->vval.v_number = -1; 14928 else 14929 #ifdef FEAT_VERTSPLIT 14930 rettv->vval.v_number = wp->w_width; 14931 #else 14932 rettv->vval.v_number = Columns; 14933 #endif 14934 } 14935 14936 /* 14937 * "writefile()" function 14938 */ 14939 static void 14940 f_writefile(argvars, rettv) 14941 typval_T *argvars; 14942 typval_T *rettv; 14943 { 14944 int binary = FALSE; 14945 char_u *fname; 14946 FILE *fd; 14947 listitem_T *li; 14948 char_u *s; 14949 int ret = 0; 14950 int c; 14951 14952 if (argvars[0].v_type != VAR_LIST) 14953 { 14954 EMSG2(_(e_listarg), "writefile()"); 14955 return; 14956 } 14957 if (argvars[0].vval.v_list == NULL) 14958 return; 14959 14960 if (argvars[2].v_type != VAR_UNKNOWN 14961 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 14962 binary = TRUE; 14963 14964 /* Always open the file in binary mode, library functions have a mind of 14965 * their own about CR-LF conversion. */ 14966 fname = get_tv_string(&argvars[1]); 14967 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 14968 { 14969 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 14970 ret = -1; 14971 } 14972 else 14973 { 14974 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 14975 li = li->li_next) 14976 { 14977 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 14978 { 14979 if (*s == '\n') 14980 c = putc(NUL, fd); 14981 else 14982 c = putc(*s, fd); 14983 if (c == EOF) 14984 { 14985 ret = -1; 14986 break; 14987 } 14988 } 14989 if (!binary || li->li_next != NULL) 14990 if (putc('\n', fd) == EOF) 14991 { 14992 ret = -1; 14993 break; 14994 } 14995 if (ret < 0) 14996 { 14997 EMSG(_(e_write)); 14998 break; 14999 } 15000 } 15001 fclose(fd); 15002 } 15003 15004 rettv->vval.v_number = ret; 15005 } 15006 15007 /* 15008 * Translate a String variable into a position. 15009 */ 15010 static pos_T * 15011 var2fpos(varp, lnum) 15012 typval_T *varp; 15013 int lnum; /* TRUE when $ is last line */ 15014 { 15015 char_u *name; 15016 static pos_T pos; 15017 pos_T *pp; 15018 15019 name = get_tv_string_chk(varp); 15020 if (name == NULL) 15021 return NULL; 15022 if (name[0] == '.') /* cursor */ 15023 return &curwin->w_cursor; 15024 if (name[0] == '\'') /* mark */ 15025 { 15026 pp = getmark(name[1], FALSE); 15027 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15028 return NULL; 15029 return pp; 15030 } 15031 if (name[0] == '$') /* last column or line */ 15032 { 15033 if (lnum) 15034 { 15035 pos.lnum = curbuf->b_ml.ml_line_count; 15036 pos.col = 0; 15037 } 15038 else 15039 { 15040 pos.lnum = curwin->w_cursor.lnum; 15041 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15042 } 15043 return &pos; 15044 } 15045 return NULL; 15046 } 15047 15048 /* 15049 * Get the length of an environment variable name. 15050 * Advance "arg" to the first character after the name. 15051 * Return 0 for error. 15052 */ 15053 static int 15054 get_env_len(arg) 15055 char_u **arg; 15056 { 15057 char_u *p; 15058 int len; 15059 15060 for (p = *arg; vim_isIDc(*p); ++p) 15061 ; 15062 if (p == *arg) /* no name found */ 15063 return 0; 15064 15065 len = (int)(p - *arg); 15066 *arg = p; 15067 return len; 15068 } 15069 15070 /* 15071 * Get the length of the name of a function or internal variable. 15072 * "arg" is advanced to the first non-white character after the name. 15073 * Return 0 if something is wrong. 15074 */ 15075 static int 15076 get_id_len(arg) 15077 char_u **arg; 15078 { 15079 char_u *p; 15080 int len; 15081 15082 /* Find the end of the name. */ 15083 for (p = *arg; eval_isnamec(*p); ++p) 15084 ; 15085 if (p == *arg) /* no name found */ 15086 return 0; 15087 15088 len = (int)(p - *arg); 15089 *arg = skipwhite(p); 15090 15091 return len; 15092 } 15093 15094 /* 15095 * Get the length of the name of a variable or function. 15096 * Only the name is recognized, does not handle ".key" or "[idx]". 15097 * "arg" is advanced to the first non-white character after the name. 15098 * Return -1 if curly braces expansion failed. 15099 * Return 0 if something else is wrong. 15100 * If the name contains 'magic' {}'s, expand them and return the 15101 * expanded name in an allocated string via 'alias' - caller must free. 15102 */ 15103 static int 15104 get_name_len(arg, alias, evaluate, verbose) 15105 char_u **arg; 15106 char_u **alias; 15107 int evaluate; 15108 int verbose; 15109 { 15110 int len; 15111 char_u *p; 15112 char_u *expr_start; 15113 char_u *expr_end; 15114 15115 *alias = NULL; /* default to no alias */ 15116 15117 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15118 && (*arg)[2] == (int)KE_SNR) 15119 { 15120 /* hard coded <SNR>, already translated */ 15121 *arg += 3; 15122 return get_id_len(arg) + 3; 15123 } 15124 len = eval_fname_script(*arg); 15125 if (len > 0) 15126 { 15127 /* literal "<SID>", "s:" or "<SNR>" */ 15128 *arg += len; 15129 } 15130 15131 /* 15132 * Find the end of the name; check for {} construction. 15133 */ 15134 p = find_name_end(*arg, &expr_start, &expr_end, 15135 len > 0 ? 0 : FNE_CHECK_START); 15136 if (expr_start != NULL) 15137 { 15138 char_u *temp_string; 15139 15140 if (!evaluate) 15141 { 15142 len += (int)(p - *arg); 15143 *arg = skipwhite(p); 15144 return len; 15145 } 15146 15147 /* 15148 * Include any <SID> etc in the expanded string: 15149 * Thus the -len here. 15150 */ 15151 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15152 if (temp_string == NULL) 15153 return -1; 15154 *alias = temp_string; 15155 *arg = skipwhite(p); 15156 return (int)STRLEN(temp_string); 15157 } 15158 15159 len += get_id_len(arg); 15160 if (len == 0 && verbose) 15161 EMSG2(_(e_invexpr2), *arg); 15162 15163 return len; 15164 } 15165 15166 /* 15167 * Find the end of a variable or function name, taking care of magic braces. 15168 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15169 * start and end of the first magic braces item. 15170 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15171 * Return a pointer to just after the name. Equal to "arg" if there is no 15172 * valid name. 15173 */ 15174 static char_u * 15175 find_name_end(arg, expr_start, expr_end, flags) 15176 char_u *arg; 15177 char_u **expr_start; 15178 char_u **expr_end; 15179 int flags; 15180 { 15181 int mb_nest = 0; 15182 int br_nest = 0; 15183 char_u *p; 15184 15185 if (expr_start != NULL) 15186 { 15187 *expr_start = NULL; 15188 *expr_end = NULL; 15189 } 15190 15191 /* Quick check for valid starting character. */ 15192 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15193 return arg; 15194 15195 for (p = arg; *p != NUL 15196 && (eval_isnamec(*p) 15197 || *p == '{' 15198 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15199 || mb_nest != 0 15200 || br_nest != 0); mb_ptr_adv(p)) 15201 { 15202 if (*p == '\'') 15203 { 15204 /* skip over 'string' to avoid counting [ and ] inside it. */ 15205 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15206 ; 15207 if (*p == NUL) 15208 break; 15209 } 15210 else if (*p == '"') 15211 { 15212 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15213 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15214 if (*p == '\\' && p[1] != NUL) 15215 ++p; 15216 if (*p == NUL) 15217 break; 15218 } 15219 15220 if (mb_nest == 0) 15221 { 15222 if (*p == '[') 15223 ++br_nest; 15224 else if (*p == ']') 15225 --br_nest; 15226 } 15227 15228 if (br_nest == 0) 15229 { 15230 if (*p == '{') 15231 { 15232 mb_nest++; 15233 if (expr_start != NULL && *expr_start == NULL) 15234 *expr_start = p; 15235 } 15236 else if (*p == '}') 15237 { 15238 mb_nest--; 15239 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15240 *expr_end = p; 15241 } 15242 } 15243 } 15244 15245 return p; 15246 } 15247 15248 /* 15249 * Expands out the 'magic' {}'s in a variable/function name. 15250 * Note that this can call itself recursively, to deal with 15251 * constructs like foo{bar}{baz}{bam} 15252 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15253 * "in_start" ^ 15254 * "expr_start" ^ 15255 * "expr_end" ^ 15256 * "in_end" ^ 15257 * 15258 * Returns a new allocated string, which the caller must free. 15259 * Returns NULL for failure. 15260 */ 15261 static char_u * 15262 make_expanded_name(in_start, expr_start, expr_end, in_end) 15263 char_u *in_start; 15264 char_u *expr_start; 15265 char_u *expr_end; 15266 char_u *in_end; 15267 { 15268 char_u c1; 15269 char_u *retval = NULL; 15270 char_u *temp_result; 15271 char_u *nextcmd = NULL; 15272 15273 if (expr_end == NULL || in_end == NULL) 15274 return NULL; 15275 *expr_start = NUL; 15276 *expr_end = NUL; 15277 c1 = *in_end; 15278 *in_end = NUL; 15279 15280 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15281 if (temp_result != NULL && nextcmd == NULL) 15282 { 15283 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15284 + (in_end - expr_end) + 1)); 15285 if (retval != NULL) 15286 { 15287 STRCPY(retval, in_start); 15288 STRCAT(retval, temp_result); 15289 STRCAT(retval, expr_end + 1); 15290 } 15291 } 15292 vim_free(temp_result); 15293 15294 *in_end = c1; /* put char back for error messages */ 15295 *expr_start = '{'; 15296 *expr_end = '}'; 15297 15298 if (retval != NULL) 15299 { 15300 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15301 if (expr_start != NULL) 15302 { 15303 /* Further expansion! */ 15304 temp_result = make_expanded_name(retval, expr_start, 15305 expr_end, temp_result); 15306 vim_free(retval); 15307 retval = temp_result; 15308 } 15309 } 15310 15311 return retval; 15312 } 15313 15314 /* 15315 * Return TRUE if character "c" can be used in a variable or function name. 15316 * Does not include '{' or '}' for magic braces. 15317 */ 15318 static int 15319 eval_isnamec(c) 15320 int c; 15321 { 15322 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15323 } 15324 15325 /* 15326 * Return TRUE if character "c" can be used as the first character in a 15327 * variable or function name (excluding '{' and '}'). 15328 */ 15329 static int 15330 eval_isnamec1(c) 15331 int c; 15332 { 15333 return (ASCII_ISALPHA(c) || c == '_'); 15334 } 15335 15336 /* 15337 * Set number v: variable to "val". 15338 */ 15339 void 15340 set_vim_var_nr(idx, val) 15341 int idx; 15342 long val; 15343 { 15344 vimvars[idx].vv_nr = val; 15345 } 15346 15347 /* 15348 * Get number v: variable value. 15349 */ 15350 long 15351 get_vim_var_nr(idx) 15352 int idx; 15353 { 15354 return vimvars[idx].vv_nr; 15355 } 15356 15357 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15358 /* 15359 * Get string v: variable value. Uses a static buffer, can only be used once. 15360 */ 15361 char_u * 15362 get_vim_var_str(idx) 15363 int idx; 15364 { 15365 return get_tv_string(&vimvars[idx].vv_tv); 15366 } 15367 #endif 15368 15369 /* 15370 * Set v:count, v:count1 and v:prevcount. 15371 */ 15372 void 15373 set_vcount(count, count1) 15374 long count; 15375 long count1; 15376 { 15377 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15378 vimvars[VV_COUNT].vv_nr = count; 15379 vimvars[VV_COUNT1].vv_nr = count1; 15380 } 15381 15382 /* 15383 * Set string v: variable to a copy of "val". 15384 */ 15385 void 15386 set_vim_var_string(idx, val, len) 15387 int idx; 15388 char_u *val; 15389 int len; /* length of "val" to use or -1 (whole string) */ 15390 { 15391 /* Need to do this (at least) once, since we can't initialize a union. 15392 * Will always be invoked when "v:progname" is set. */ 15393 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15394 15395 vim_free(vimvars[idx].vv_str); 15396 if (val == NULL) 15397 vimvars[idx].vv_str = NULL; 15398 else if (len == -1) 15399 vimvars[idx].vv_str = vim_strsave(val); 15400 else 15401 vimvars[idx].vv_str = vim_strnsave(val, len); 15402 } 15403 15404 /* 15405 * Set v:register if needed. 15406 */ 15407 void 15408 set_reg_var(c) 15409 int c; 15410 { 15411 char_u regname; 15412 15413 if (c == 0 || c == ' ') 15414 regname = '"'; 15415 else 15416 regname = c; 15417 /* Avoid free/alloc when the value is already right. */ 15418 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15419 set_vim_var_string(VV_REG, ®name, 1); 15420 } 15421 15422 /* 15423 * Get or set v:exception. If "oldval" == NULL, return the current value. 15424 * Otherwise, restore the value to "oldval" and return NULL. 15425 * Must always be called in pairs to save and restore v:exception! Does not 15426 * take care of memory allocations. 15427 */ 15428 char_u * 15429 v_exception(oldval) 15430 char_u *oldval; 15431 { 15432 if (oldval == NULL) 15433 return vimvars[VV_EXCEPTION].vv_str; 15434 15435 vimvars[VV_EXCEPTION].vv_str = oldval; 15436 return NULL; 15437 } 15438 15439 /* 15440 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15441 * Otherwise, restore the value to "oldval" and return NULL. 15442 * Must always be called in pairs to save and restore v:throwpoint! Does not 15443 * take care of memory allocations. 15444 */ 15445 char_u * 15446 v_throwpoint(oldval) 15447 char_u *oldval; 15448 { 15449 if (oldval == NULL) 15450 return vimvars[VV_THROWPOINT].vv_str; 15451 15452 vimvars[VV_THROWPOINT].vv_str = oldval; 15453 return NULL; 15454 } 15455 15456 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15457 /* 15458 * Set v:cmdarg. 15459 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15460 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15461 * Must always be called in pairs! 15462 */ 15463 char_u * 15464 set_cmdarg(eap, oldarg) 15465 exarg_T *eap; 15466 char_u *oldarg; 15467 { 15468 char_u *oldval; 15469 char_u *newval; 15470 unsigned len; 15471 15472 oldval = vimvars[VV_CMDARG].vv_str; 15473 if (eap == NULL) 15474 { 15475 vim_free(oldval); 15476 vimvars[VV_CMDARG].vv_str = oldarg; 15477 return NULL; 15478 } 15479 15480 if (eap->force_bin == FORCE_BIN) 15481 len = 6; 15482 else if (eap->force_bin == FORCE_NOBIN) 15483 len = 8; 15484 else 15485 len = 0; 15486 if (eap->force_ff != 0) 15487 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15488 # ifdef FEAT_MBYTE 15489 if (eap->force_enc != 0) 15490 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15491 # endif 15492 15493 newval = alloc(len + 1); 15494 if (newval == NULL) 15495 return NULL; 15496 15497 if (eap->force_bin == FORCE_BIN) 15498 sprintf((char *)newval, " ++bin"); 15499 else if (eap->force_bin == FORCE_NOBIN) 15500 sprintf((char *)newval, " ++nobin"); 15501 else 15502 *newval = NUL; 15503 if (eap->force_ff != 0) 15504 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15505 eap->cmd + eap->force_ff); 15506 # ifdef FEAT_MBYTE 15507 if (eap->force_enc != 0) 15508 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15509 eap->cmd + eap->force_enc); 15510 # endif 15511 vimvars[VV_CMDARG].vv_str = newval; 15512 return oldval; 15513 } 15514 #endif 15515 15516 /* 15517 * Get the value of internal variable "name". 15518 * Return OK or FAIL. 15519 */ 15520 static int 15521 get_var_tv(name, len, rettv, verbose) 15522 char_u *name; 15523 int len; /* length of "name" */ 15524 typval_T *rettv; /* NULL when only checking existence */ 15525 int verbose; /* may give error message */ 15526 { 15527 int ret = OK; 15528 typval_T *tv = NULL; 15529 typval_T atv; 15530 dictitem_T *v; 15531 int cc; 15532 15533 /* truncate the name, so that we can use strcmp() */ 15534 cc = name[len]; 15535 name[len] = NUL; 15536 15537 /* 15538 * Check for "b:changedtick". 15539 */ 15540 if (STRCMP(name, "b:changedtick") == 0) 15541 { 15542 atv.v_type = VAR_NUMBER; 15543 atv.vval.v_number = curbuf->b_changedtick; 15544 tv = &atv; 15545 } 15546 15547 /* 15548 * Check for user-defined variables. 15549 */ 15550 else 15551 { 15552 v = find_var(name, NULL); 15553 if (v != NULL) 15554 tv = &v->di_tv; 15555 } 15556 15557 if (tv == NULL) 15558 { 15559 if (rettv != NULL && verbose) 15560 EMSG2(_(e_undefvar), name); 15561 ret = FAIL; 15562 } 15563 else if (rettv != NULL) 15564 copy_tv(tv, rettv); 15565 15566 name[len] = cc; 15567 15568 return ret; 15569 } 15570 15571 /* 15572 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15573 * Also handle function call with Funcref variable: func(expr) 15574 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15575 */ 15576 static int 15577 handle_subscript(arg, rettv, evaluate, verbose) 15578 char_u **arg; 15579 typval_T *rettv; 15580 int evaluate; /* do more than finding the end */ 15581 int verbose; /* give error messages */ 15582 { 15583 int ret = OK; 15584 dict_T *selfdict = NULL; 15585 char_u *s; 15586 int len; 15587 typval_T functv; 15588 15589 while (ret == OK 15590 && (**arg == '[' 15591 || (**arg == '.' && rettv->v_type == VAR_DICT) 15592 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15593 && !vim_iswhite(*(*arg - 1))) 15594 { 15595 if (**arg == '(') 15596 { 15597 /* need to copy the funcref so that we can clear rettv */ 15598 functv = *rettv; 15599 rettv->v_type = VAR_UNKNOWN; 15600 15601 /* Invoke the function. Recursive! */ 15602 s = functv.vval.v_string; 15603 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15604 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15605 &len, evaluate, selfdict); 15606 15607 /* Clear the funcref afterwards, so that deleting it while 15608 * evaluating the arguments is possible (see test55). */ 15609 clear_tv(&functv); 15610 15611 /* Stop the expression evaluation when immediately aborting on 15612 * error, or when an interrupt occurred or an exception was thrown 15613 * but not caught. */ 15614 if (aborting()) 15615 { 15616 if (ret == OK) 15617 clear_tv(rettv); 15618 ret = FAIL; 15619 } 15620 dict_unref(selfdict); 15621 selfdict = NULL; 15622 } 15623 else /* **arg == '[' || **arg == '.' */ 15624 { 15625 dict_unref(selfdict); 15626 if (rettv->v_type == VAR_DICT) 15627 { 15628 selfdict = rettv->vval.v_dict; 15629 if (selfdict != NULL) 15630 ++selfdict->dv_refcount; 15631 } 15632 else 15633 selfdict = NULL; 15634 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15635 { 15636 clear_tv(rettv); 15637 ret = FAIL; 15638 } 15639 } 15640 } 15641 dict_unref(selfdict); 15642 return ret; 15643 } 15644 15645 /* 15646 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15647 * value). 15648 */ 15649 static typval_T * 15650 alloc_tv() 15651 { 15652 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15653 } 15654 15655 /* 15656 * Allocate memory for a variable type-value, and assign a string to it. 15657 * The string "s" must have been allocated, it is consumed. 15658 * Return NULL for out of memory, the variable otherwise. 15659 */ 15660 static typval_T * 15661 alloc_string_tv(s) 15662 char_u *s; 15663 { 15664 typval_T *rettv; 15665 15666 rettv = alloc_tv(); 15667 if (rettv != NULL) 15668 { 15669 rettv->v_type = VAR_STRING; 15670 rettv->vval.v_string = s; 15671 } 15672 else 15673 vim_free(s); 15674 return rettv; 15675 } 15676 15677 /* 15678 * Free the memory for a variable type-value. 15679 */ 15680 static void 15681 free_tv(varp) 15682 typval_T *varp; 15683 { 15684 if (varp != NULL) 15685 { 15686 switch (varp->v_type) 15687 { 15688 case VAR_FUNC: 15689 func_unref(varp->vval.v_string); 15690 /*FALLTHROUGH*/ 15691 case VAR_STRING: 15692 vim_free(varp->vval.v_string); 15693 break; 15694 case VAR_LIST: 15695 list_unref(varp->vval.v_list); 15696 break; 15697 case VAR_DICT: 15698 dict_unref(varp->vval.v_dict); 15699 break; 15700 case VAR_NUMBER: 15701 case VAR_UNKNOWN: 15702 break; 15703 default: 15704 EMSG2(_(e_intern2), "free_tv()"); 15705 break; 15706 } 15707 vim_free(varp); 15708 } 15709 } 15710 15711 /* 15712 * Free the memory for a variable value and set the value to NULL or 0. 15713 */ 15714 void 15715 clear_tv(varp) 15716 typval_T *varp; 15717 { 15718 if (varp != NULL) 15719 { 15720 switch (varp->v_type) 15721 { 15722 case VAR_FUNC: 15723 func_unref(varp->vval.v_string); 15724 /*FALLTHROUGH*/ 15725 case VAR_STRING: 15726 vim_free(varp->vval.v_string); 15727 varp->vval.v_string = NULL; 15728 break; 15729 case VAR_LIST: 15730 list_unref(varp->vval.v_list); 15731 varp->vval.v_list = NULL; 15732 break; 15733 case VAR_DICT: 15734 dict_unref(varp->vval.v_dict); 15735 varp->vval.v_dict = NULL; 15736 break; 15737 case VAR_NUMBER: 15738 varp->vval.v_number = 0; 15739 break; 15740 case VAR_UNKNOWN: 15741 break; 15742 default: 15743 EMSG2(_(e_intern2), "clear_tv()"); 15744 } 15745 varp->v_lock = 0; 15746 } 15747 } 15748 15749 /* 15750 * Set the value of a variable to NULL without freeing items. 15751 */ 15752 static void 15753 init_tv(varp) 15754 typval_T *varp; 15755 { 15756 if (varp != NULL) 15757 vim_memset(varp, 0, sizeof(typval_T)); 15758 } 15759 15760 /* 15761 * Get the number value of a variable. 15762 * If it is a String variable, uses vim_str2nr(). 15763 * For incompatible types, return 0. 15764 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15765 * caller of incompatible types: it sets *denote to TRUE if "denote" 15766 * is not NULL or returns -1 otherwise. 15767 */ 15768 static long 15769 get_tv_number(varp) 15770 typval_T *varp; 15771 { 15772 int error = FALSE; 15773 15774 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15775 } 15776 15777 long 15778 get_tv_number_chk(varp, denote) 15779 typval_T *varp; 15780 int *denote; 15781 { 15782 long n = 0L; 15783 15784 switch (varp->v_type) 15785 { 15786 case VAR_NUMBER: 15787 return (long)(varp->vval.v_number); 15788 case VAR_FUNC: 15789 EMSG(_("E703: Using a Funcref as a number")); 15790 break; 15791 case VAR_STRING: 15792 if (varp->vval.v_string != NULL) 15793 vim_str2nr(varp->vval.v_string, NULL, NULL, 15794 TRUE, TRUE, &n, NULL); 15795 return n; 15796 case VAR_LIST: 15797 EMSG(_("E745: Using a List as a number")); 15798 break; 15799 case VAR_DICT: 15800 EMSG(_("E728: Using a Dictionary as a number")); 15801 break; 15802 default: 15803 EMSG2(_(e_intern2), "get_tv_number()"); 15804 break; 15805 } 15806 if (denote == NULL) /* useful for values that must be unsigned */ 15807 n = -1; 15808 else 15809 *denote = TRUE; 15810 return n; 15811 } 15812 15813 /* 15814 * Get the lnum from the first argument. 15815 * Also accepts ".", "$", etc., but that only works for the current buffer. 15816 * Returns -1 on error. 15817 */ 15818 static linenr_T 15819 get_tv_lnum(argvars) 15820 typval_T *argvars; 15821 { 15822 typval_T rettv; 15823 linenr_T lnum; 15824 15825 lnum = get_tv_number_chk(&argvars[0], NULL); 15826 if (lnum == 0) /* no valid number, try using line() */ 15827 { 15828 rettv.v_type = VAR_NUMBER; 15829 f_line(argvars, &rettv); 15830 lnum = rettv.vval.v_number; 15831 clear_tv(&rettv); 15832 } 15833 return lnum; 15834 } 15835 15836 /* 15837 * Get the lnum from the first argument. 15838 * Also accepts "$", then "buf" is used. 15839 * Returns 0 on error. 15840 */ 15841 static linenr_T 15842 get_tv_lnum_buf(argvars, buf) 15843 typval_T *argvars; 15844 buf_T *buf; 15845 { 15846 if (argvars[0].v_type == VAR_STRING 15847 && argvars[0].vval.v_string != NULL 15848 && argvars[0].vval.v_string[0] == '$' 15849 && buf != NULL) 15850 return buf->b_ml.ml_line_count; 15851 return get_tv_number_chk(&argvars[0], NULL); 15852 } 15853 15854 /* 15855 * Get the string value of a variable. 15856 * If it is a Number variable, the number is converted into a string. 15857 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 15858 * get_tv_string_buf() uses a given buffer. 15859 * If the String variable has never been set, return an empty string. 15860 * Never returns NULL; 15861 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 15862 * NULL on error. 15863 */ 15864 static char_u * 15865 get_tv_string(varp) 15866 typval_T *varp; 15867 { 15868 static char_u mybuf[NUMBUFLEN]; 15869 15870 return get_tv_string_buf(varp, mybuf); 15871 } 15872 15873 static char_u * 15874 get_tv_string_buf(varp, buf) 15875 typval_T *varp; 15876 char_u *buf; 15877 { 15878 char_u *res = get_tv_string_buf_chk(varp, buf); 15879 15880 return res != NULL ? res : (char_u *)""; 15881 } 15882 15883 char_u * 15884 get_tv_string_chk(varp) 15885 typval_T *varp; 15886 { 15887 static char_u mybuf[NUMBUFLEN]; 15888 15889 return get_tv_string_buf_chk(varp, mybuf); 15890 } 15891 15892 static char_u * 15893 get_tv_string_buf_chk(varp, buf) 15894 typval_T *varp; 15895 char_u *buf; 15896 { 15897 switch (varp->v_type) 15898 { 15899 case VAR_NUMBER: 15900 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 15901 return buf; 15902 case VAR_FUNC: 15903 EMSG(_("E729: using Funcref as a String")); 15904 break; 15905 case VAR_LIST: 15906 EMSG(_("E730: using List as a String")); 15907 break; 15908 case VAR_DICT: 15909 EMSG(_("E731: using Dictionary as a String")); 15910 break; 15911 case VAR_STRING: 15912 if (varp->vval.v_string != NULL) 15913 return varp->vval.v_string; 15914 return (char_u *)""; 15915 default: 15916 EMSG2(_(e_intern2), "get_tv_string_buf()"); 15917 break; 15918 } 15919 return NULL; 15920 } 15921 15922 /* 15923 * Find variable "name" in the list of variables. 15924 * Return a pointer to it if found, NULL if not found. 15925 * Careful: "a:0" variables don't have a name. 15926 * When "htp" is not NULL we are writing to the variable, set "htp" to the 15927 * hashtab_T used. 15928 */ 15929 static dictitem_T * 15930 find_var(name, htp) 15931 char_u *name; 15932 hashtab_T **htp; 15933 { 15934 char_u *varname; 15935 hashtab_T *ht; 15936 15937 ht = find_var_ht(name, &varname); 15938 if (htp != NULL) 15939 *htp = ht; 15940 if (ht == NULL) 15941 return NULL; 15942 return find_var_in_ht(ht, varname, htp != NULL); 15943 } 15944 15945 /* 15946 * Find variable "varname" in hashtab "ht". 15947 * Returns NULL if not found. 15948 */ 15949 static dictitem_T * 15950 find_var_in_ht(ht, varname, writing) 15951 hashtab_T *ht; 15952 char_u *varname; 15953 int writing; 15954 { 15955 hashitem_T *hi; 15956 15957 if (*varname == NUL) 15958 { 15959 /* Must be something like "s:", otherwise "ht" would be NULL. */ 15960 switch (varname[-2]) 15961 { 15962 case 's': return &SCRIPT_SV(current_SID).sv_var; 15963 case 'g': return &globvars_var; 15964 case 'v': return &vimvars_var; 15965 case 'b': return &curbuf->b_bufvar; 15966 case 'w': return &curwin->w_winvar; 15967 case 'l': return current_funccal == NULL 15968 ? NULL : ¤t_funccal->l_vars_var; 15969 case 'a': return current_funccal == NULL 15970 ? NULL : ¤t_funccal->l_avars_var; 15971 } 15972 return NULL; 15973 } 15974 15975 hi = hash_find(ht, varname); 15976 if (HASHITEM_EMPTY(hi)) 15977 { 15978 /* For global variables we may try auto-loading the script. If it 15979 * worked find the variable again. Don't auto-load a script if it was 15980 * loaded already, otherwise it would be loaded every time when 15981 * checking if a function name is a Funcref variable. */ 15982 if (ht == &globvarht && !writing 15983 && script_autoload(varname, FALSE) && !aborting()) 15984 hi = hash_find(ht, varname); 15985 if (HASHITEM_EMPTY(hi)) 15986 return NULL; 15987 } 15988 return HI2DI(hi); 15989 } 15990 15991 /* 15992 * Find the hashtab used for a variable name. 15993 * Set "varname" to the start of name without ':'. 15994 */ 15995 static hashtab_T * 15996 find_var_ht(name, varname) 15997 char_u *name; 15998 char_u **varname; 15999 { 16000 hashitem_T *hi; 16001 16002 if (name[1] != ':') 16003 { 16004 /* The name must not start with a colon or #. */ 16005 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16006 return NULL; 16007 *varname = name; 16008 16009 /* "version" is "v:version" in all scopes */ 16010 hi = hash_find(&compat_hashtab, name); 16011 if (!HASHITEM_EMPTY(hi)) 16012 return &compat_hashtab; 16013 16014 if (current_funccal == NULL) 16015 return &globvarht; /* global variable */ 16016 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16017 } 16018 *varname = name + 2; 16019 if (*name == 'g') /* global variable */ 16020 return &globvarht; 16021 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16022 */ 16023 if (vim_strchr(name + 2, ':') != NULL 16024 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16025 return NULL; 16026 if (*name == 'b') /* buffer variable */ 16027 return &curbuf->b_vars.dv_hashtab; 16028 if (*name == 'w') /* window variable */ 16029 return &curwin->w_vars.dv_hashtab; 16030 if (*name == 'v') /* v: variable */ 16031 return &vimvarht; 16032 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16033 return ¤t_funccal->l_avars.dv_hashtab; 16034 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16035 return ¤t_funccal->l_vars.dv_hashtab; 16036 if (*name == 's' /* script variable */ 16037 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16038 return &SCRIPT_VARS(current_SID); 16039 return NULL; 16040 } 16041 16042 /* 16043 * Get the string value of a (global/local) variable. 16044 * Returns NULL when it doesn't exist. 16045 */ 16046 char_u * 16047 get_var_value(name) 16048 char_u *name; 16049 { 16050 dictitem_T *v; 16051 16052 v = find_var(name, NULL); 16053 if (v == NULL) 16054 return NULL; 16055 return get_tv_string(&v->di_tv); 16056 } 16057 16058 /* 16059 * Allocate a new hashtab for a sourced script. It will be used while 16060 * sourcing this script and when executing functions defined in the script. 16061 */ 16062 void 16063 new_script_vars(id) 16064 scid_T id; 16065 { 16066 int i; 16067 hashtab_T *ht; 16068 scriptvar_T *sv; 16069 16070 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16071 { 16072 /* Re-allocating ga_data means that an ht_array pointing to 16073 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16074 * at its init value. Also reset "v_dict", it's always the same. */ 16075 for (i = 1; i <= ga_scripts.ga_len; ++i) 16076 { 16077 ht = &SCRIPT_VARS(i); 16078 if (ht->ht_mask == HT_INIT_SIZE - 1) 16079 ht->ht_array = ht->ht_smallarray; 16080 sv = &SCRIPT_SV(i); 16081 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16082 } 16083 16084 while (ga_scripts.ga_len < id) 16085 { 16086 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16087 init_var_dict(&sv->sv_dict, &sv->sv_var); 16088 ++ga_scripts.ga_len; 16089 } 16090 } 16091 } 16092 16093 /* 16094 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16095 * point to it. 16096 */ 16097 void 16098 init_var_dict(dict, dict_var) 16099 dict_T *dict; 16100 dictitem_T *dict_var; 16101 { 16102 hash_init(&dict->dv_hashtab); 16103 dict->dv_refcount = 99999; 16104 dict_var->di_tv.vval.v_dict = dict; 16105 dict_var->di_tv.v_type = VAR_DICT; 16106 dict_var->di_tv.v_lock = VAR_FIXED; 16107 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16108 dict_var->di_key[0] = NUL; 16109 } 16110 16111 /* 16112 * Clean up a list of internal variables. 16113 * Frees all allocated variables and the value they contain. 16114 * Clears hashtab "ht", does not free it. 16115 */ 16116 void 16117 vars_clear(ht) 16118 hashtab_T *ht; 16119 { 16120 vars_clear_ext(ht, TRUE); 16121 } 16122 16123 /* 16124 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16125 */ 16126 static void 16127 vars_clear_ext(ht, free_val) 16128 hashtab_T *ht; 16129 int free_val; 16130 { 16131 int todo; 16132 hashitem_T *hi; 16133 dictitem_T *v; 16134 16135 hash_lock(ht); 16136 todo = ht->ht_used; 16137 for (hi = ht->ht_array; todo > 0; ++hi) 16138 { 16139 if (!HASHITEM_EMPTY(hi)) 16140 { 16141 --todo; 16142 16143 /* Free the variable. Don't remove it from the hashtab, 16144 * ht_array might change then. hash_clear() takes care of it 16145 * later. */ 16146 v = HI2DI(hi); 16147 if (free_val) 16148 clear_tv(&v->di_tv); 16149 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16150 vim_free(v); 16151 } 16152 } 16153 hash_clear(ht); 16154 ht->ht_used = 0; 16155 } 16156 16157 /* 16158 * Delete a variable from hashtab "ht" at item "hi". 16159 * Clear the variable value and free the dictitem. 16160 */ 16161 static void 16162 delete_var(ht, hi) 16163 hashtab_T *ht; 16164 hashitem_T *hi; 16165 { 16166 dictitem_T *di = HI2DI(hi); 16167 16168 hash_remove(ht, hi); 16169 clear_tv(&di->di_tv); 16170 vim_free(di); 16171 } 16172 16173 /* 16174 * List the value of one internal variable. 16175 */ 16176 static void 16177 list_one_var(v, prefix) 16178 dictitem_T *v; 16179 char_u *prefix; 16180 { 16181 char_u *tofree; 16182 char_u *s; 16183 char_u numbuf[NUMBUFLEN]; 16184 16185 s = echo_string(&v->di_tv, &tofree, numbuf); 16186 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16187 s == NULL ? (char_u *)"" : s); 16188 vim_free(tofree); 16189 } 16190 16191 static void 16192 list_one_var_a(prefix, name, type, string) 16193 char_u *prefix; 16194 char_u *name; 16195 int type; 16196 char_u *string; 16197 { 16198 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16199 if (name != NULL) /* "a:" vars don't have a name stored */ 16200 msg_puts(name); 16201 msg_putchar(' '); 16202 msg_advance(22); 16203 if (type == VAR_NUMBER) 16204 msg_putchar('#'); 16205 else if (type == VAR_FUNC) 16206 msg_putchar('*'); 16207 else if (type == VAR_LIST) 16208 { 16209 msg_putchar('['); 16210 if (*string == '[') 16211 ++string; 16212 } 16213 else if (type == VAR_DICT) 16214 { 16215 msg_putchar('{'); 16216 if (*string == '{') 16217 ++string; 16218 } 16219 else 16220 msg_putchar(' '); 16221 16222 msg_outtrans(string); 16223 16224 if (type == VAR_FUNC) 16225 msg_puts((char_u *)"()"); 16226 } 16227 16228 /* 16229 * Set variable "name" to value in "tv". 16230 * If the variable already exists, the value is updated. 16231 * Otherwise the variable is created. 16232 */ 16233 static void 16234 set_var(name, tv, copy) 16235 char_u *name; 16236 typval_T *tv; 16237 int copy; /* make copy of value in "tv" */ 16238 { 16239 dictitem_T *v; 16240 char_u *varname; 16241 hashtab_T *ht; 16242 char_u *p; 16243 16244 if (tv->v_type == VAR_FUNC) 16245 { 16246 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16247 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16248 ? name[2] : name[0])) 16249 { 16250 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16251 return; 16252 } 16253 if (function_exists(name)) 16254 { 16255 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16256 name); 16257 return; 16258 } 16259 } 16260 16261 ht = find_var_ht(name, &varname); 16262 if (ht == NULL || *varname == NUL) 16263 { 16264 EMSG2(_(e_illvar), name); 16265 return; 16266 } 16267 16268 v = find_var_in_ht(ht, varname, TRUE); 16269 if (v != NULL) 16270 { 16271 /* existing variable, need to clear the value */ 16272 if (var_check_ro(v->di_flags, name) 16273 || tv_check_lock(v->di_tv.v_lock, name)) 16274 return; 16275 if (v->di_tv.v_type != tv->v_type 16276 && !((v->di_tv.v_type == VAR_STRING 16277 || v->di_tv.v_type == VAR_NUMBER) 16278 && (tv->v_type == VAR_STRING 16279 || tv->v_type == VAR_NUMBER))) 16280 { 16281 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16282 return; 16283 } 16284 16285 /* 16286 * Handle setting internal v: variables separately: we don't change 16287 * the type. 16288 */ 16289 if (ht == &vimvarht) 16290 { 16291 if (v->di_tv.v_type == VAR_STRING) 16292 { 16293 vim_free(v->di_tv.vval.v_string); 16294 if (copy || tv->v_type != VAR_STRING) 16295 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16296 else 16297 { 16298 /* Take over the string to avoid an extra alloc/free. */ 16299 v->di_tv.vval.v_string = tv->vval.v_string; 16300 tv->vval.v_string = NULL; 16301 } 16302 } 16303 else if (v->di_tv.v_type != VAR_NUMBER) 16304 EMSG2(_(e_intern2), "set_var()"); 16305 else 16306 v->di_tv.vval.v_number = get_tv_number(tv); 16307 return; 16308 } 16309 16310 clear_tv(&v->di_tv); 16311 } 16312 else /* add a new variable */ 16313 { 16314 /* Make sure the variable name is valid. */ 16315 for (p = varname; *p != NUL; ++p) 16316 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16317 { 16318 EMSG2(_(e_illvar), varname); 16319 return; 16320 } 16321 16322 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16323 + STRLEN(varname))); 16324 if (v == NULL) 16325 return; 16326 STRCPY(v->di_key, varname); 16327 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16328 { 16329 vim_free(v); 16330 return; 16331 } 16332 v->di_flags = 0; 16333 } 16334 16335 if (copy || tv->v_type == VAR_NUMBER) 16336 copy_tv(tv, &v->di_tv); 16337 else 16338 { 16339 v->di_tv = *tv; 16340 v->di_tv.v_lock = 0; 16341 init_tv(tv); 16342 } 16343 } 16344 16345 /* 16346 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16347 * Also give an error message. 16348 */ 16349 static int 16350 var_check_ro(flags, name) 16351 int flags; 16352 char_u *name; 16353 { 16354 if (flags & DI_FLAGS_RO) 16355 { 16356 EMSG2(_(e_readonlyvar), name); 16357 return TRUE; 16358 } 16359 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16360 { 16361 EMSG2(_(e_readonlysbx), name); 16362 return TRUE; 16363 } 16364 return FALSE; 16365 } 16366 16367 /* 16368 * Return TRUE if typeval "tv" is set to be locked (immutable). 16369 * Also give an error message, using "name". 16370 */ 16371 static int 16372 tv_check_lock(lock, name) 16373 int lock; 16374 char_u *name; 16375 { 16376 if (lock & VAR_LOCKED) 16377 { 16378 EMSG2(_("E741: Value is locked: %s"), 16379 name == NULL ? (char_u *)_("Unknown") : name); 16380 return TRUE; 16381 } 16382 if (lock & VAR_FIXED) 16383 { 16384 EMSG2(_("E742: Cannot change value of %s"), 16385 name == NULL ? (char_u *)_("Unknown") : name); 16386 return TRUE; 16387 } 16388 return FALSE; 16389 } 16390 16391 /* 16392 * Copy the values from typval_T "from" to typval_T "to". 16393 * When needed allocates string or increases reference count. 16394 * Does not make a copy of a list or dict but copies the reference! 16395 */ 16396 static void 16397 copy_tv(from, to) 16398 typval_T *from; 16399 typval_T *to; 16400 { 16401 to->v_type = from->v_type; 16402 to->v_lock = 0; 16403 switch (from->v_type) 16404 { 16405 case VAR_NUMBER: 16406 to->vval.v_number = from->vval.v_number; 16407 break; 16408 case VAR_STRING: 16409 case VAR_FUNC: 16410 if (from->vval.v_string == NULL) 16411 to->vval.v_string = NULL; 16412 else 16413 { 16414 to->vval.v_string = vim_strsave(from->vval.v_string); 16415 if (from->v_type == VAR_FUNC) 16416 func_ref(to->vval.v_string); 16417 } 16418 break; 16419 case VAR_LIST: 16420 if (from->vval.v_list == NULL) 16421 to->vval.v_list = NULL; 16422 else 16423 { 16424 to->vval.v_list = from->vval.v_list; 16425 ++to->vval.v_list->lv_refcount; 16426 } 16427 break; 16428 case VAR_DICT: 16429 if (from->vval.v_dict == NULL) 16430 to->vval.v_dict = NULL; 16431 else 16432 { 16433 to->vval.v_dict = from->vval.v_dict; 16434 ++to->vval.v_dict->dv_refcount; 16435 } 16436 break; 16437 default: 16438 EMSG2(_(e_intern2), "copy_tv()"); 16439 break; 16440 } 16441 } 16442 16443 /* 16444 * Make a copy of an item. 16445 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16446 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16447 * reference to an already copied list/dict can be used. 16448 * Returns FAIL or OK. 16449 */ 16450 static int 16451 item_copy(from, to, deep, copyID) 16452 typval_T *from; 16453 typval_T *to; 16454 int deep; 16455 int copyID; 16456 { 16457 static int recurse = 0; 16458 int ret = OK; 16459 16460 if (recurse >= DICT_MAXNEST) 16461 { 16462 EMSG(_("E698: variable nested too deep for making a copy")); 16463 return FAIL; 16464 } 16465 ++recurse; 16466 16467 switch (from->v_type) 16468 { 16469 case VAR_NUMBER: 16470 case VAR_STRING: 16471 case VAR_FUNC: 16472 copy_tv(from, to); 16473 break; 16474 case VAR_LIST: 16475 to->v_type = VAR_LIST; 16476 to->v_lock = 0; 16477 if (from->vval.v_list == NULL) 16478 to->vval.v_list = NULL; 16479 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16480 { 16481 /* use the copy made earlier */ 16482 to->vval.v_list = from->vval.v_list->lv_copylist; 16483 ++to->vval.v_list->lv_refcount; 16484 } 16485 else 16486 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16487 if (to->vval.v_list == NULL) 16488 ret = FAIL; 16489 break; 16490 case VAR_DICT: 16491 to->v_type = VAR_DICT; 16492 to->v_lock = 0; 16493 if (from->vval.v_dict == NULL) 16494 to->vval.v_dict = NULL; 16495 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16496 { 16497 /* use the copy made earlier */ 16498 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16499 ++to->vval.v_dict->dv_refcount; 16500 } 16501 else 16502 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16503 if (to->vval.v_dict == NULL) 16504 ret = FAIL; 16505 break; 16506 default: 16507 EMSG2(_(e_intern2), "item_copy()"); 16508 ret = FAIL; 16509 } 16510 --recurse; 16511 return ret; 16512 } 16513 16514 /* 16515 * ":echo expr1 ..." print each argument separated with a space, add a 16516 * newline at the end. 16517 * ":echon expr1 ..." print each argument plain. 16518 */ 16519 void 16520 ex_echo(eap) 16521 exarg_T *eap; 16522 { 16523 char_u *arg = eap->arg; 16524 typval_T rettv; 16525 char_u *tofree; 16526 char_u *p; 16527 int needclr = TRUE; 16528 int atstart = TRUE; 16529 char_u numbuf[NUMBUFLEN]; 16530 16531 if (eap->skip) 16532 ++emsg_skip; 16533 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16534 { 16535 p = arg; 16536 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16537 { 16538 /* 16539 * Report the invalid expression unless the expression evaluation 16540 * has been cancelled due to an aborting error, an interrupt, or an 16541 * exception. 16542 */ 16543 if (!aborting()) 16544 EMSG2(_(e_invexpr2), p); 16545 break; 16546 } 16547 if (!eap->skip) 16548 { 16549 if (atstart) 16550 { 16551 atstart = FALSE; 16552 /* Call msg_start() after eval1(), evaluating the expression 16553 * may cause a message to appear. */ 16554 if (eap->cmdidx == CMD_echo) 16555 msg_start(); 16556 } 16557 else if (eap->cmdidx == CMD_echo) 16558 msg_puts_attr((char_u *)" ", echo_attr); 16559 p = echo_string(&rettv, &tofree, numbuf); 16560 if (p != NULL) 16561 for ( ; *p != NUL && !got_int; ++p) 16562 { 16563 if (*p == '\n' || *p == '\r' || *p == TAB) 16564 { 16565 if (*p != TAB && needclr) 16566 { 16567 /* remove any text still there from the command */ 16568 msg_clr_eos(); 16569 needclr = FALSE; 16570 } 16571 msg_putchar_attr(*p, echo_attr); 16572 } 16573 else 16574 { 16575 #ifdef FEAT_MBYTE 16576 if (has_mbyte) 16577 { 16578 int i = (*mb_ptr2len)(p); 16579 16580 (void)msg_outtrans_len_attr(p, i, echo_attr); 16581 p += i - 1; 16582 } 16583 else 16584 #endif 16585 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16586 } 16587 } 16588 vim_free(tofree); 16589 } 16590 clear_tv(&rettv); 16591 arg = skipwhite(arg); 16592 } 16593 eap->nextcmd = check_nextcmd(arg); 16594 16595 if (eap->skip) 16596 --emsg_skip; 16597 else 16598 { 16599 /* remove text that may still be there from the command */ 16600 if (needclr) 16601 msg_clr_eos(); 16602 if (eap->cmdidx == CMD_echo) 16603 msg_end(); 16604 } 16605 } 16606 16607 /* 16608 * ":echohl {name}". 16609 */ 16610 void 16611 ex_echohl(eap) 16612 exarg_T *eap; 16613 { 16614 int id; 16615 16616 id = syn_name2id(eap->arg); 16617 if (id == 0) 16618 echo_attr = 0; 16619 else 16620 echo_attr = syn_id2attr(id); 16621 } 16622 16623 /* 16624 * ":execute expr1 ..." execute the result of an expression. 16625 * ":echomsg expr1 ..." Print a message 16626 * ":echoerr expr1 ..." Print an error 16627 * Each gets spaces around each argument and a newline at the end for 16628 * echo commands 16629 */ 16630 void 16631 ex_execute(eap) 16632 exarg_T *eap; 16633 { 16634 char_u *arg = eap->arg; 16635 typval_T rettv; 16636 int ret = OK; 16637 char_u *p; 16638 garray_T ga; 16639 int len; 16640 int save_did_emsg; 16641 16642 ga_init2(&ga, 1, 80); 16643 16644 if (eap->skip) 16645 ++emsg_skip; 16646 while (*arg != NUL && *arg != '|' && *arg != '\n') 16647 { 16648 p = arg; 16649 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16650 { 16651 /* 16652 * Report the invalid expression unless the expression evaluation 16653 * has been cancelled due to an aborting error, an interrupt, or an 16654 * exception. 16655 */ 16656 if (!aborting()) 16657 EMSG2(_(e_invexpr2), p); 16658 ret = FAIL; 16659 break; 16660 } 16661 16662 if (!eap->skip) 16663 { 16664 p = get_tv_string(&rettv); 16665 len = (int)STRLEN(p); 16666 if (ga_grow(&ga, len + 2) == FAIL) 16667 { 16668 clear_tv(&rettv); 16669 ret = FAIL; 16670 break; 16671 } 16672 if (ga.ga_len) 16673 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16674 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16675 ga.ga_len += len; 16676 } 16677 16678 clear_tv(&rettv); 16679 arg = skipwhite(arg); 16680 } 16681 16682 if (ret != FAIL && ga.ga_data != NULL) 16683 { 16684 if (eap->cmdidx == CMD_echomsg) 16685 MSG_ATTR(ga.ga_data, echo_attr); 16686 else if (eap->cmdidx == CMD_echoerr) 16687 { 16688 /* We don't want to abort following commands, restore did_emsg. */ 16689 save_did_emsg = did_emsg; 16690 EMSG((char_u *)ga.ga_data); 16691 if (!force_abort) 16692 did_emsg = save_did_emsg; 16693 } 16694 else if (eap->cmdidx == CMD_execute) 16695 do_cmdline((char_u *)ga.ga_data, 16696 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16697 } 16698 16699 ga_clear(&ga); 16700 16701 if (eap->skip) 16702 --emsg_skip; 16703 16704 eap->nextcmd = check_nextcmd(arg); 16705 } 16706 16707 /* 16708 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16709 * "arg" points to the "&" or '+' when called, to "option" when returning. 16710 * Returns NULL when no option name found. Otherwise pointer to the char 16711 * after the option name. 16712 */ 16713 static char_u * 16714 find_option_end(arg, opt_flags) 16715 char_u **arg; 16716 int *opt_flags; 16717 { 16718 char_u *p = *arg; 16719 16720 ++p; 16721 if (*p == 'g' && p[1] == ':') 16722 { 16723 *opt_flags = OPT_GLOBAL; 16724 p += 2; 16725 } 16726 else if (*p == 'l' && p[1] == ':') 16727 { 16728 *opt_flags = OPT_LOCAL; 16729 p += 2; 16730 } 16731 else 16732 *opt_flags = 0; 16733 16734 if (!ASCII_ISALPHA(*p)) 16735 return NULL; 16736 *arg = p; 16737 16738 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16739 p += 4; /* termcap option */ 16740 else 16741 while (ASCII_ISALPHA(*p)) 16742 ++p; 16743 return p; 16744 } 16745 16746 /* 16747 * ":function" 16748 */ 16749 void 16750 ex_function(eap) 16751 exarg_T *eap; 16752 { 16753 char_u *theline; 16754 int j; 16755 int c; 16756 int saved_did_emsg; 16757 char_u *name = NULL; 16758 char_u *p; 16759 char_u *arg; 16760 garray_T newargs; 16761 garray_T newlines; 16762 int varargs = FALSE; 16763 int mustend = FALSE; 16764 int flags = 0; 16765 ufunc_T *fp; 16766 int indent; 16767 int nesting; 16768 char_u *skip_until = NULL; 16769 dictitem_T *v; 16770 funcdict_T fudi; 16771 static int func_nr = 0; /* number for nameless function */ 16772 int paren; 16773 hashtab_T *ht; 16774 int todo; 16775 hashitem_T *hi; 16776 16777 /* 16778 * ":function" without argument: list functions. 16779 */ 16780 if (ends_excmd(*eap->arg)) 16781 { 16782 if (!eap->skip) 16783 { 16784 todo = func_hashtab.ht_used; 16785 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16786 { 16787 if (!HASHITEM_EMPTY(hi)) 16788 { 16789 --todo; 16790 fp = HI2UF(hi); 16791 if (!isdigit(*fp->uf_name)) 16792 list_func_head(fp, FALSE); 16793 } 16794 } 16795 } 16796 eap->nextcmd = check_nextcmd(eap->arg); 16797 return; 16798 } 16799 16800 /* 16801 * Get the function name. There are these situations: 16802 * func normal function name 16803 * "name" == func, "fudi.fd_dict" == NULL 16804 * dict.func new dictionary entry 16805 * "name" == NULL, "fudi.fd_dict" set, 16806 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 16807 * dict.func existing dict entry with a Funcref 16808 * "name" == func, "fudi.fd_dict" set, 16809 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16810 * dict.func existing dict entry that's not a Funcref 16811 * "name" == NULL, "fudi.fd_dict" set, 16812 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16813 */ 16814 p = eap->arg; 16815 name = trans_function_name(&p, eap->skip, 0, &fudi); 16816 paren = (vim_strchr(p, '(') != NULL); 16817 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 16818 { 16819 /* 16820 * Return on an invalid expression in braces, unless the expression 16821 * evaluation has been cancelled due to an aborting error, an 16822 * interrupt, or an exception. 16823 */ 16824 if (!aborting()) 16825 { 16826 if (!eap->skip && fudi.fd_newkey != NULL) 16827 EMSG2(_(e_dictkey), fudi.fd_newkey); 16828 vim_free(fudi.fd_newkey); 16829 return; 16830 } 16831 else 16832 eap->skip = TRUE; 16833 } 16834 /* An error in a function call during evaluation of an expression in magic 16835 * braces should not cause the function not to be defined. */ 16836 saved_did_emsg = did_emsg; 16837 did_emsg = FALSE; 16838 16839 /* 16840 * ":function func" with only function name: list function. 16841 */ 16842 if (!paren) 16843 { 16844 if (!ends_excmd(*skipwhite(p))) 16845 { 16846 EMSG(_(e_trailing)); 16847 goto ret_free; 16848 } 16849 eap->nextcmd = check_nextcmd(p); 16850 if (eap->nextcmd != NULL) 16851 *p = NUL; 16852 if (!eap->skip && !got_int) 16853 { 16854 fp = find_func(name); 16855 if (fp != NULL) 16856 { 16857 list_func_head(fp, TRUE); 16858 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 16859 { 16860 msg_putchar('\n'); 16861 msg_outnum((long)(j + 1)); 16862 if (j < 9) 16863 msg_putchar(' '); 16864 if (j < 99) 16865 msg_putchar(' '); 16866 msg_prt_line(FUNCLINE(fp, j), FALSE); 16867 out_flush(); /* show a line at a time */ 16868 ui_breakcheck(); 16869 } 16870 if (!got_int) 16871 { 16872 msg_putchar('\n'); 16873 msg_puts((char_u *)" endfunction"); 16874 } 16875 } 16876 else 16877 emsg_funcname("E123: Undefined function: %s", name); 16878 } 16879 goto ret_free; 16880 } 16881 16882 /* 16883 * ":function name(arg1, arg2)" Define function. 16884 */ 16885 p = skipwhite(p); 16886 if (*p != '(') 16887 { 16888 if (!eap->skip) 16889 { 16890 EMSG2(_("E124: Missing '(': %s"), eap->arg); 16891 goto ret_free; 16892 } 16893 /* attempt to continue by skipping some text */ 16894 if (vim_strchr(p, '(') != NULL) 16895 p = vim_strchr(p, '('); 16896 } 16897 p = skipwhite(p + 1); 16898 16899 ga_init2(&newargs, (int)sizeof(char_u *), 3); 16900 ga_init2(&newlines, (int)sizeof(char_u *), 3); 16901 16902 if (!eap->skip) 16903 { 16904 /* Check the name of the function. */ 16905 if (name != NULL) 16906 arg = name; 16907 else 16908 arg = fudi.fd_newkey; 16909 if (arg != NULL) 16910 { 16911 if (*arg == K_SPECIAL) 16912 j = 3; 16913 else 16914 j = 0; 16915 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 16916 : eval_isnamec(arg[j]))) 16917 ++j; 16918 if (arg[j] != NUL) 16919 emsg_funcname(_(e_invarg2), arg); 16920 } 16921 } 16922 16923 /* 16924 * Isolate the arguments: "arg1, arg2, ...)" 16925 */ 16926 while (*p != ')') 16927 { 16928 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 16929 { 16930 varargs = TRUE; 16931 p += 3; 16932 mustend = TRUE; 16933 } 16934 else 16935 { 16936 arg = p; 16937 while (ASCII_ISALNUM(*p) || *p == '_') 16938 ++p; 16939 if (arg == p || isdigit(*arg) 16940 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 16941 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 16942 { 16943 if (!eap->skip) 16944 EMSG2(_("E125: Illegal argument: %s"), arg); 16945 break; 16946 } 16947 if (ga_grow(&newargs, 1) == FAIL) 16948 goto erret; 16949 c = *p; 16950 *p = NUL; 16951 arg = vim_strsave(arg); 16952 if (arg == NULL) 16953 goto erret; 16954 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 16955 *p = c; 16956 newargs.ga_len++; 16957 if (*p == ',') 16958 ++p; 16959 else 16960 mustend = TRUE; 16961 } 16962 p = skipwhite(p); 16963 if (mustend && *p != ')') 16964 { 16965 if (!eap->skip) 16966 EMSG2(_(e_invarg2), eap->arg); 16967 break; 16968 } 16969 } 16970 ++p; /* skip the ')' */ 16971 16972 /* find extra arguments "range", "dict" and "abort" */ 16973 for (;;) 16974 { 16975 p = skipwhite(p); 16976 if (STRNCMP(p, "range", 5) == 0) 16977 { 16978 flags |= FC_RANGE; 16979 p += 5; 16980 } 16981 else if (STRNCMP(p, "dict", 4) == 0) 16982 { 16983 flags |= FC_DICT; 16984 p += 4; 16985 } 16986 else if (STRNCMP(p, "abort", 5) == 0) 16987 { 16988 flags |= FC_ABORT; 16989 p += 5; 16990 } 16991 else 16992 break; 16993 } 16994 16995 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 16996 EMSG(_(e_trailing)); 16997 16998 /* 16999 * Read the body of the function, until ":endfunction" is found. 17000 */ 17001 if (KeyTyped) 17002 { 17003 /* Check if the function already exists, don't let the user type the 17004 * whole function before telling him it doesn't work! For a script we 17005 * need to skip the body to be able to find what follows. */ 17006 if (!eap->skip && !eap->forceit) 17007 { 17008 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 17009 EMSG(_(e_funcdict)); 17010 else if (name != NULL && find_func(name) != NULL) 17011 emsg_funcname(e_funcexts, name); 17012 } 17013 17014 if (!eap->skip && did_emsg) 17015 goto erret; 17016 17017 msg_putchar('\n'); /* don't overwrite the function name */ 17018 cmdline_row = msg_row; 17019 } 17020 17021 indent = 2; 17022 nesting = 0; 17023 for (;;) 17024 { 17025 msg_scroll = TRUE; 17026 need_wait_return = FALSE; 17027 if (eap->getline == NULL) 17028 theline = getcmdline(':', 0L, indent); 17029 else 17030 theline = eap->getline(':', eap->cookie, indent); 17031 if (KeyTyped) 17032 lines_left = Rows - 1; 17033 if (theline == NULL) 17034 { 17035 EMSG(_("E126: Missing :endfunction")); 17036 goto erret; 17037 } 17038 17039 if (skip_until != NULL) 17040 { 17041 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17042 * don't check for ":endfunc". */ 17043 if (STRCMP(theline, skip_until) == 0) 17044 { 17045 vim_free(skip_until); 17046 skip_until = NULL; 17047 } 17048 } 17049 else 17050 { 17051 /* skip ':' and blanks*/ 17052 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17053 ; 17054 17055 /* Check for "endfunction". */ 17056 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17057 { 17058 vim_free(theline); 17059 break; 17060 } 17061 17062 /* Increase indent inside "if", "while", "for" and "try", decrease 17063 * at "end". */ 17064 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17065 indent -= 2; 17066 else if (STRNCMP(p, "if", 2) == 0 17067 || STRNCMP(p, "wh", 2) == 0 17068 || STRNCMP(p, "for", 3) == 0 17069 || STRNCMP(p, "try", 3) == 0) 17070 indent += 2; 17071 17072 /* Check for defining a function inside this function. */ 17073 if (checkforcmd(&p, "function", 2)) 17074 { 17075 if (*p == '!') 17076 p = skipwhite(p + 1); 17077 p += eval_fname_script(p); 17078 if (ASCII_ISALPHA(*p)) 17079 { 17080 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17081 if (*skipwhite(p) == '(') 17082 { 17083 ++nesting; 17084 indent += 2; 17085 } 17086 } 17087 } 17088 17089 /* Check for ":append" or ":insert". */ 17090 p = skip_range(p, NULL); 17091 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17092 || (p[0] == 'i' 17093 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17094 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17095 skip_until = vim_strsave((char_u *)"."); 17096 17097 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17098 arg = skipwhite(skiptowhite(p)); 17099 if (arg[0] == '<' && arg[1] =='<' 17100 && ((p[0] == 'p' && p[1] == 'y' 17101 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17102 || (p[0] == 'p' && p[1] == 'e' 17103 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17104 || (p[0] == 't' && p[1] == 'c' 17105 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17106 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17107 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17108 || (p[0] == 'm' && p[1] == 'z' 17109 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17110 )) 17111 { 17112 /* ":python <<" continues until a dot, like ":append" */ 17113 p = skipwhite(arg + 2); 17114 if (*p == NUL) 17115 skip_until = vim_strsave((char_u *)"."); 17116 else 17117 skip_until = vim_strsave(p); 17118 } 17119 } 17120 17121 /* Add the line to the function. */ 17122 if (ga_grow(&newlines, 1) == FAIL) 17123 { 17124 vim_free(theline); 17125 goto erret; 17126 } 17127 17128 /* Copy the line to newly allocated memory. get_one_sourceline() 17129 * allocates 250 bytes per line, this saves 80% on average. The cost 17130 * is an extra alloc/free. */ 17131 p = vim_strsave(theline); 17132 if (p != NULL) 17133 { 17134 vim_free(theline); 17135 theline = p; 17136 } 17137 17138 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17139 newlines.ga_len++; 17140 } 17141 17142 /* Don't define the function when skipping commands or when an error was 17143 * detected. */ 17144 if (eap->skip || did_emsg) 17145 goto erret; 17146 17147 /* 17148 * If there are no errors, add the function 17149 */ 17150 if (fudi.fd_dict == NULL) 17151 { 17152 v = find_var(name, &ht); 17153 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17154 { 17155 emsg_funcname("E707: Function name conflicts with variable: %s", 17156 name); 17157 goto erret; 17158 } 17159 17160 fp = find_func(name); 17161 if (fp != NULL) 17162 { 17163 if (!eap->forceit) 17164 { 17165 emsg_funcname(e_funcexts, name); 17166 goto erret; 17167 } 17168 if (fp->uf_calls > 0) 17169 { 17170 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17171 name); 17172 goto erret; 17173 } 17174 /* redefine existing function */ 17175 ga_clear_strings(&(fp->uf_args)); 17176 ga_clear_strings(&(fp->uf_lines)); 17177 vim_free(name); 17178 name = NULL; 17179 } 17180 } 17181 else 17182 { 17183 char numbuf[20]; 17184 17185 fp = NULL; 17186 if (fudi.fd_newkey == NULL && !eap->forceit) 17187 { 17188 EMSG(_(e_funcdict)); 17189 goto erret; 17190 } 17191 if (fudi.fd_di == NULL) 17192 { 17193 /* Can't add a function to a locked dictionary */ 17194 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17195 goto erret; 17196 } 17197 /* Can't change an existing function if it is locked */ 17198 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17199 goto erret; 17200 17201 /* Give the function a sequential number. Can only be used with a 17202 * Funcref! */ 17203 vim_free(name); 17204 sprintf(numbuf, "%d", ++func_nr); 17205 name = vim_strsave((char_u *)numbuf); 17206 if (name == NULL) 17207 goto erret; 17208 } 17209 17210 if (fp == NULL) 17211 { 17212 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17213 { 17214 int slen, plen; 17215 char_u *scriptname; 17216 17217 /* Check that the autoload name matches the script name. */ 17218 j = FAIL; 17219 if (sourcing_name != NULL) 17220 { 17221 scriptname = autoload_name(name); 17222 if (scriptname != NULL) 17223 { 17224 p = vim_strchr(scriptname, '/'); 17225 plen = STRLEN(p); 17226 slen = STRLEN(sourcing_name); 17227 if (slen > plen && fnamecmp(p, 17228 sourcing_name + slen - plen) == 0) 17229 j = OK; 17230 vim_free(scriptname); 17231 } 17232 } 17233 if (j == FAIL) 17234 { 17235 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17236 goto erret; 17237 } 17238 } 17239 17240 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17241 if (fp == NULL) 17242 goto erret; 17243 17244 if (fudi.fd_dict != NULL) 17245 { 17246 if (fudi.fd_di == NULL) 17247 { 17248 /* add new dict entry */ 17249 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17250 if (fudi.fd_di == NULL) 17251 { 17252 vim_free(fp); 17253 goto erret; 17254 } 17255 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17256 { 17257 vim_free(fudi.fd_di); 17258 goto erret; 17259 } 17260 } 17261 else 17262 /* overwrite existing dict entry */ 17263 clear_tv(&fudi.fd_di->di_tv); 17264 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17265 fudi.fd_di->di_tv.v_lock = 0; 17266 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17267 fp->uf_refcount = 1; 17268 } 17269 17270 /* insert the new function in the function list */ 17271 STRCPY(fp->uf_name, name); 17272 hash_add(&func_hashtab, UF2HIKEY(fp)); 17273 } 17274 fp->uf_args = newargs; 17275 fp->uf_lines = newlines; 17276 #ifdef FEAT_PROFILE 17277 fp->uf_tml_count = NULL; 17278 fp->uf_tml_total = NULL; 17279 fp->uf_tml_self = NULL; 17280 fp->uf_profiling = FALSE; 17281 if (prof_def_func()) 17282 func_do_profile(fp); 17283 #endif 17284 fp->uf_varargs = varargs; 17285 fp->uf_flags = flags; 17286 fp->uf_calls = 0; 17287 fp->uf_script_ID = current_SID; 17288 goto ret_free; 17289 17290 erret: 17291 ga_clear_strings(&newargs); 17292 ga_clear_strings(&newlines); 17293 ret_free: 17294 vim_free(skip_until); 17295 vim_free(fudi.fd_newkey); 17296 vim_free(name); 17297 did_emsg |= saved_did_emsg; 17298 } 17299 17300 /* 17301 * Get a function name, translating "<SID>" and "<SNR>". 17302 * Also handles a Funcref in a List or Dictionary. 17303 * Returns the function name in allocated memory, or NULL for failure. 17304 * flags: 17305 * TFN_INT: internal function name OK 17306 * TFN_QUIET: be quiet 17307 * Advances "pp" to just after the function name (if no error). 17308 */ 17309 static char_u * 17310 trans_function_name(pp, skip, flags, fdp) 17311 char_u **pp; 17312 int skip; /* only find the end, don't evaluate */ 17313 int flags; 17314 funcdict_T *fdp; /* return: info about dictionary used */ 17315 { 17316 char_u *name = NULL; 17317 char_u *start; 17318 char_u *end; 17319 int lead; 17320 char_u sid_buf[20]; 17321 int len; 17322 lval_T lv; 17323 17324 if (fdp != NULL) 17325 vim_memset(fdp, 0, sizeof(funcdict_T)); 17326 start = *pp; 17327 17328 /* Check for hard coded <SNR>: already translated function ID (from a user 17329 * command). */ 17330 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17331 && (*pp)[2] == (int)KE_SNR) 17332 { 17333 *pp += 3; 17334 len = get_id_len(pp) + 3; 17335 return vim_strnsave(start, len); 17336 } 17337 17338 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17339 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17340 lead = eval_fname_script(start); 17341 if (lead > 2) 17342 start += lead; 17343 17344 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17345 lead > 2 ? 0 : FNE_CHECK_START); 17346 if (end == start) 17347 { 17348 if (!skip) 17349 EMSG(_("E129: Function name required")); 17350 goto theend; 17351 } 17352 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17353 { 17354 /* 17355 * Report an invalid expression in braces, unless the expression 17356 * evaluation has been cancelled due to an aborting error, an 17357 * interrupt, or an exception. 17358 */ 17359 if (!aborting()) 17360 { 17361 if (end != NULL) 17362 EMSG2(_(e_invarg2), start); 17363 } 17364 else 17365 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17366 goto theend; 17367 } 17368 17369 if (lv.ll_tv != NULL) 17370 { 17371 if (fdp != NULL) 17372 { 17373 fdp->fd_dict = lv.ll_dict; 17374 fdp->fd_newkey = lv.ll_newkey; 17375 lv.ll_newkey = NULL; 17376 fdp->fd_di = lv.ll_di; 17377 } 17378 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17379 { 17380 name = vim_strsave(lv.ll_tv->vval.v_string); 17381 *pp = end; 17382 } 17383 else 17384 { 17385 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17386 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17387 EMSG(_(e_funcref)); 17388 else 17389 *pp = end; 17390 name = NULL; 17391 } 17392 goto theend; 17393 } 17394 17395 if (lv.ll_name == NULL) 17396 { 17397 /* Error found, but continue after the function name. */ 17398 *pp = end; 17399 goto theend; 17400 } 17401 17402 if (lv.ll_exp_name != NULL) 17403 len = STRLEN(lv.ll_exp_name); 17404 else 17405 { 17406 if (lead == 2) /* skip over "s:" */ 17407 lv.ll_name += 2; 17408 len = (int)(end - lv.ll_name); 17409 } 17410 17411 /* 17412 * Copy the function name to allocated memory. 17413 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17414 * Accept <SNR>123_name() outside a script. 17415 */ 17416 if (skip) 17417 lead = 0; /* do nothing */ 17418 else if (lead > 0) 17419 { 17420 lead = 3; 17421 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17422 { 17423 if (current_SID <= 0) 17424 { 17425 EMSG(_(e_usingsid)); 17426 goto theend; 17427 } 17428 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17429 lead += (int)STRLEN(sid_buf); 17430 } 17431 } 17432 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17433 { 17434 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17435 goto theend; 17436 } 17437 name = alloc((unsigned)(len + lead + 1)); 17438 if (name != NULL) 17439 { 17440 if (lead > 0) 17441 { 17442 name[0] = K_SPECIAL; 17443 name[1] = KS_EXTRA; 17444 name[2] = (int)KE_SNR; 17445 if (lead > 3) /* If it's "<SID>" */ 17446 STRCPY(name + 3, sid_buf); 17447 } 17448 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17449 name[len + lead] = NUL; 17450 } 17451 *pp = end; 17452 17453 theend: 17454 clear_lval(&lv); 17455 return name; 17456 } 17457 17458 /* 17459 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17460 * Return 2 if "p" starts with "s:". 17461 * Return 0 otherwise. 17462 */ 17463 static int 17464 eval_fname_script(p) 17465 char_u *p; 17466 { 17467 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17468 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17469 return 5; 17470 if (p[0] == 's' && p[1] == ':') 17471 return 2; 17472 return 0; 17473 } 17474 17475 /* 17476 * Return TRUE if "p" starts with "<SID>" or "s:". 17477 * Only works if eval_fname_script() returned non-zero for "p"! 17478 */ 17479 static int 17480 eval_fname_sid(p) 17481 char_u *p; 17482 { 17483 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17484 } 17485 17486 /* 17487 * List the head of the function: "name(arg1, arg2)". 17488 */ 17489 static void 17490 list_func_head(fp, indent) 17491 ufunc_T *fp; 17492 int indent; 17493 { 17494 int j; 17495 17496 msg_start(); 17497 if (indent) 17498 MSG_PUTS(" "); 17499 MSG_PUTS("function "); 17500 if (fp->uf_name[0] == K_SPECIAL) 17501 { 17502 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17503 msg_puts(fp->uf_name + 3); 17504 } 17505 else 17506 msg_puts(fp->uf_name); 17507 msg_putchar('('); 17508 for (j = 0; j < fp->uf_args.ga_len; ++j) 17509 { 17510 if (j) 17511 MSG_PUTS(", "); 17512 msg_puts(FUNCARG(fp, j)); 17513 } 17514 if (fp->uf_varargs) 17515 { 17516 if (j) 17517 MSG_PUTS(", "); 17518 MSG_PUTS("..."); 17519 } 17520 msg_putchar(')'); 17521 #ifdef FEAT_EVAL 17522 if (p_verbose > 0) 17523 last_set_msg(fp->uf_script_ID); 17524 #endif 17525 } 17526 17527 /* 17528 * Find a function by name, return pointer to it in ufuncs. 17529 * Return NULL for unknown function. 17530 */ 17531 static ufunc_T * 17532 find_func(name) 17533 char_u *name; 17534 { 17535 hashitem_T *hi; 17536 17537 hi = hash_find(&func_hashtab, name); 17538 if (!HASHITEM_EMPTY(hi)) 17539 return HI2UF(hi); 17540 return NULL; 17541 } 17542 17543 #if defined(EXITFREE) || defined(PROTO) 17544 void 17545 free_all_functions() 17546 { 17547 hashitem_T *hi; 17548 17549 /* Need to start all over every time, because func_free() may change the 17550 * hash table. */ 17551 while (func_hashtab.ht_used > 0) 17552 for (hi = func_hashtab.ht_array; ; ++hi) 17553 if (!HASHITEM_EMPTY(hi)) 17554 { 17555 func_free(HI2UF(hi)); 17556 break; 17557 } 17558 } 17559 #endif 17560 17561 /* 17562 * Return TRUE if a function "name" exists. 17563 */ 17564 static int 17565 function_exists(name) 17566 char_u *name; 17567 { 17568 char_u *p = name; 17569 int n = FALSE; 17570 17571 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17572 if (p != NULL) 17573 { 17574 if (builtin_function(p)) 17575 n = (find_internal_func(p) >= 0); 17576 else 17577 n = (find_func(p) != NULL); 17578 vim_free(p); 17579 } 17580 return n; 17581 } 17582 17583 /* 17584 * Return TRUE if "name" looks like a builtin function name: starts with a 17585 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17586 */ 17587 static int 17588 builtin_function(name) 17589 char_u *name; 17590 { 17591 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17592 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17593 } 17594 17595 #if defined(FEAT_PROFILE) || defined(PROTO) 17596 /* 17597 * Start profiling function "fp". 17598 */ 17599 static void 17600 func_do_profile(fp) 17601 ufunc_T *fp; 17602 { 17603 fp->uf_tm_count = 0; 17604 profile_zero(&fp->uf_tm_self); 17605 profile_zero(&fp->uf_tm_total); 17606 if (fp->uf_tml_count == NULL) 17607 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17608 (sizeof(int) * fp->uf_lines.ga_len)); 17609 if (fp->uf_tml_total == NULL) 17610 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17611 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17612 if (fp->uf_tml_self == NULL) 17613 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17614 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17615 fp->uf_tml_idx = -1; 17616 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17617 || fp->uf_tml_self == NULL) 17618 return; /* out of memory */ 17619 17620 fp->uf_profiling = TRUE; 17621 } 17622 17623 /* 17624 * Dump the profiling results for all functions in file "fd". 17625 */ 17626 void 17627 func_dump_profile(fd) 17628 FILE *fd; 17629 { 17630 hashitem_T *hi; 17631 int todo; 17632 ufunc_T *fp; 17633 int i; 17634 ufunc_T **sorttab; 17635 int st_len = 0; 17636 17637 todo = func_hashtab.ht_used; 17638 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17639 17640 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17641 { 17642 if (!HASHITEM_EMPTY(hi)) 17643 { 17644 --todo; 17645 fp = HI2UF(hi); 17646 if (fp->uf_profiling) 17647 { 17648 if (sorttab != NULL) 17649 sorttab[st_len++] = fp; 17650 17651 if (fp->uf_name[0] == K_SPECIAL) 17652 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17653 else 17654 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17655 if (fp->uf_tm_count == 1) 17656 fprintf(fd, "Called 1 time\n"); 17657 else 17658 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17659 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17660 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17661 fprintf(fd, "\n"); 17662 fprintf(fd, "count total (s) self (s)\n"); 17663 17664 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17665 { 17666 prof_func_line(fd, fp->uf_tml_count[i], 17667 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17668 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17669 } 17670 fprintf(fd, "\n"); 17671 } 17672 } 17673 } 17674 17675 if (sorttab != NULL && st_len > 0) 17676 { 17677 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17678 prof_total_cmp); 17679 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17680 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17681 prof_self_cmp); 17682 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17683 } 17684 } 17685 17686 static void 17687 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17688 FILE *fd; 17689 ufunc_T **sorttab; 17690 int st_len; 17691 char *title; 17692 int prefer_self; /* when equal print only self time */ 17693 { 17694 int i; 17695 ufunc_T *fp; 17696 17697 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17698 fprintf(fd, "count total (s) self (s) function\n"); 17699 for (i = 0; i < 20 && i < st_len; ++i) 17700 { 17701 fp = sorttab[i]; 17702 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17703 prefer_self); 17704 if (fp->uf_name[0] == K_SPECIAL) 17705 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17706 else 17707 fprintf(fd, " %s()\n", fp->uf_name); 17708 } 17709 fprintf(fd, "\n"); 17710 } 17711 17712 /* 17713 * Print the count and times for one function or function line. 17714 */ 17715 static void 17716 prof_func_line(fd, count, total, self, prefer_self) 17717 FILE *fd; 17718 int count; 17719 proftime_T *total; 17720 proftime_T *self; 17721 int prefer_self; /* when equal print only self time */ 17722 { 17723 if (count > 0) 17724 { 17725 fprintf(fd, "%5d ", count); 17726 if (prefer_self && profile_equal(total, self)) 17727 fprintf(fd, " "); 17728 else 17729 fprintf(fd, "%s ", profile_msg(total)); 17730 if (!prefer_self && profile_equal(total, self)) 17731 fprintf(fd, " "); 17732 else 17733 fprintf(fd, "%s ", profile_msg(self)); 17734 } 17735 else 17736 fprintf(fd, " "); 17737 } 17738 17739 /* 17740 * Compare function for total time sorting. 17741 */ 17742 static int 17743 #ifdef __BORLANDC__ 17744 _RTLENTRYF 17745 #endif 17746 prof_total_cmp(s1, s2) 17747 const void *s1; 17748 const void *s2; 17749 { 17750 ufunc_T *p1, *p2; 17751 17752 p1 = *(ufunc_T **)s1; 17753 p2 = *(ufunc_T **)s2; 17754 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 17755 } 17756 17757 /* 17758 * Compare function for self time sorting. 17759 */ 17760 static int 17761 #ifdef __BORLANDC__ 17762 _RTLENTRYF 17763 #endif 17764 prof_self_cmp(s1, s2) 17765 const void *s1; 17766 const void *s2; 17767 { 17768 ufunc_T *p1, *p2; 17769 17770 p1 = *(ufunc_T **)s1; 17771 p2 = *(ufunc_T **)s2; 17772 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 17773 } 17774 17775 #endif 17776 17777 /* The names of packages that once were loaded is remembered. */ 17778 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 17779 17780 /* 17781 * If "name" has a package name try autoloading the script for it. 17782 * Return TRUE if a package was loaded. 17783 */ 17784 static int 17785 script_autoload(name, reload) 17786 char_u *name; 17787 int reload; /* load script again when already loaded */ 17788 { 17789 char_u *p; 17790 char_u *scriptname, *tofree; 17791 int ret = FALSE; 17792 int i; 17793 17794 /* If there is no '#' after name[0] there is no package name. */ 17795 p = vim_strchr(name, AUTOLOAD_CHAR); 17796 if (p == NULL || p == name) 17797 return FALSE; 17798 17799 tofree = scriptname = autoload_name(name); 17800 17801 /* Find the name in the list of previously loaded package names. Skip 17802 * "autoload/", it's always the same. */ 17803 for (i = 0; i < ga_loaded.ga_len; ++i) 17804 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 17805 break; 17806 if (!reload && i < ga_loaded.ga_len) 17807 ret = FALSE; /* was loaded already */ 17808 else 17809 { 17810 /* Remember the name if it wasn't loaded already. */ 17811 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 17812 { 17813 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 17814 tofree = NULL; 17815 } 17816 17817 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 17818 if (source_runtime(scriptname, FALSE) == OK) 17819 ret = TRUE; 17820 } 17821 17822 vim_free(tofree); 17823 return ret; 17824 } 17825 17826 /* 17827 * Return the autoload script name for a function or variable name. 17828 * Returns NULL when out of memory. 17829 */ 17830 static char_u * 17831 autoload_name(name) 17832 char_u *name; 17833 { 17834 char_u *p; 17835 char_u *scriptname; 17836 17837 /* Get the script file name: replace '#' with '/', append ".vim". */ 17838 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 17839 if (scriptname == NULL) 17840 return FALSE; 17841 STRCPY(scriptname, "autoload/"); 17842 STRCAT(scriptname, name); 17843 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 17844 STRCAT(scriptname, ".vim"); 17845 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 17846 *p = '/'; 17847 return scriptname; 17848 } 17849 17850 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 17851 17852 /* 17853 * Function given to ExpandGeneric() to obtain the list of user defined 17854 * function names. 17855 */ 17856 char_u * 17857 get_user_func_name(xp, idx) 17858 expand_T *xp; 17859 int idx; 17860 { 17861 static long_u done; 17862 static hashitem_T *hi; 17863 ufunc_T *fp; 17864 17865 if (idx == 0) 17866 { 17867 done = 0; 17868 hi = func_hashtab.ht_array; 17869 } 17870 if (done < func_hashtab.ht_used) 17871 { 17872 if (done++ > 0) 17873 ++hi; 17874 while (HASHITEM_EMPTY(hi)) 17875 ++hi; 17876 fp = HI2UF(hi); 17877 17878 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 17879 return fp->uf_name; /* prevents overflow */ 17880 17881 cat_func_name(IObuff, fp); 17882 if (xp->xp_context != EXPAND_USER_FUNC) 17883 { 17884 STRCAT(IObuff, "("); 17885 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 17886 STRCAT(IObuff, ")"); 17887 } 17888 return IObuff; 17889 } 17890 return NULL; 17891 } 17892 17893 #endif /* FEAT_CMDL_COMPL */ 17894 17895 /* 17896 * Copy the function name of "fp" to buffer "buf". 17897 * "buf" must be able to hold the function name plus three bytes. 17898 * Takes care of script-local function names. 17899 */ 17900 static void 17901 cat_func_name(buf, fp) 17902 char_u *buf; 17903 ufunc_T *fp; 17904 { 17905 if (fp->uf_name[0] == K_SPECIAL) 17906 { 17907 STRCPY(buf, "<SNR>"); 17908 STRCAT(buf, fp->uf_name + 3); 17909 } 17910 else 17911 STRCPY(buf, fp->uf_name); 17912 } 17913 17914 /* 17915 * ":delfunction {name}" 17916 */ 17917 void 17918 ex_delfunction(eap) 17919 exarg_T *eap; 17920 { 17921 ufunc_T *fp = NULL; 17922 char_u *p; 17923 char_u *name; 17924 funcdict_T fudi; 17925 17926 p = eap->arg; 17927 name = trans_function_name(&p, eap->skip, 0, &fudi); 17928 vim_free(fudi.fd_newkey); 17929 if (name == NULL) 17930 { 17931 if (fudi.fd_dict != NULL && !eap->skip) 17932 EMSG(_(e_funcref)); 17933 return; 17934 } 17935 if (!ends_excmd(*skipwhite(p))) 17936 { 17937 vim_free(name); 17938 EMSG(_(e_trailing)); 17939 return; 17940 } 17941 eap->nextcmd = check_nextcmd(p); 17942 if (eap->nextcmd != NULL) 17943 *p = NUL; 17944 17945 if (!eap->skip) 17946 fp = find_func(name); 17947 vim_free(name); 17948 17949 if (!eap->skip) 17950 { 17951 if (fp == NULL) 17952 { 17953 EMSG2(_(e_nofunc), eap->arg); 17954 return; 17955 } 17956 if (fp->uf_calls > 0) 17957 { 17958 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 17959 return; 17960 } 17961 17962 if (fudi.fd_dict != NULL) 17963 { 17964 /* Delete the dict item that refers to the function, it will 17965 * invoke func_unref() and possibly delete the function. */ 17966 dictitem_remove(fudi.fd_dict, fudi.fd_di); 17967 } 17968 else 17969 func_free(fp); 17970 } 17971 } 17972 17973 /* 17974 * Free a function and remove it from the list of functions. 17975 */ 17976 static void 17977 func_free(fp) 17978 ufunc_T *fp; 17979 { 17980 hashitem_T *hi; 17981 17982 /* clear this function */ 17983 ga_clear_strings(&(fp->uf_args)); 17984 ga_clear_strings(&(fp->uf_lines)); 17985 #ifdef FEAT_PROFILE 17986 vim_free(fp->uf_tml_count); 17987 vim_free(fp->uf_tml_total); 17988 vim_free(fp->uf_tml_self); 17989 #endif 17990 17991 /* remove the function from the function hashtable */ 17992 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 17993 if (HASHITEM_EMPTY(hi)) 17994 EMSG2(_(e_intern2), "func_free()"); 17995 else 17996 hash_remove(&func_hashtab, hi); 17997 17998 vim_free(fp); 17999 } 18000 18001 /* 18002 * Unreference a Function: decrement the reference count and free it when it 18003 * becomes zero. Only for numbered functions. 18004 */ 18005 static void 18006 func_unref(name) 18007 char_u *name; 18008 { 18009 ufunc_T *fp; 18010 18011 if (name != NULL && isdigit(*name)) 18012 { 18013 fp = find_func(name); 18014 if (fp == NULL) 18015 EMSG2(_(e_intern2), "func_unref()"); 18016 else if (--fp->uf_refcount <= 0) 18017 { 18018 /* Only delete it when it's not being used. Otherwise it's done 18019 * when "uf_calls" becomes zero. */ 18020 if (fp->uf_calls == 0) 18021 func_free(fp); 18022 } 18023 } 18024 } 18025 18026 /* 18027 * Count a reference to a Function. 18028 */ 18029 static void 18030 func_ref(name) 18031 char_u *name; 18032 { 18033 ufunc_T *fp; 18034 18035 if (name != NULL && isdigit(*name)) 18036 { 18037 fp = find_func(name); 18038 if (fp == NULL) 18039 EMSG2(_(e_intern2), "func_ref()"); 18040 else 18041 ++fp->uf_refcount; 18042 } 18043 } 18044 18045 /* 18046 * Call a user function. 18047 */ 18048 static void 18049 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18050 ufunc_T *fp; /* pointer to function */ 18051 int argcount; /* nr of args */ 18052 typval_T *argvars; /* arguments */ 18053 typval_T *rettv; /* return value */ 18054 linenr_T firstline; /* first line of range */ 18055 linenr_T lastline; /* last line of range */ 18056 dict_T *selfdict; /* Dictionary for "self" */ 18057 { 18058 char_u *save_sourcing_name; 18059 linenr_T save_sourcing_lnum; 18060 scid_T save_current_SID; 18061 funccall_T fc; 18062 int save_did_emsg; 18063 static int depth = 0; 18064 dictitem_T *v; 18065 int fixvar_idx = 0; /* index in fixvar[] */ 18066 int i; 18067 int ai; 18068 char_u numbuf[NUMBUFLEN]; 18069 char_u *name; 18070 #ifdef FEAT_PROFILE 18071 proftime_T wait_start; 18072 #endif 18073 18074 /* If depth of calling is getting too high, don't execute the function */ 18075 if (depth >= p_mfd) 18076 { 18077 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18078 rettv->v_type = VAR_NUMBER; 18079 rettv->vval.v_number = -1; 18080 return; 18081 } 18082 ++depth; 18083 18084 line_breakcheck(); /* check for CTRL-C hit */ 18085 18086 fc.caller = current_funccal; 18087 current_funccal = &fc; 18088 fc.func = fp; 18089 fc.rettv = rettv; 18090 rettv->vval.v_number = 0; 18091 fc.linenr = 0; 18092 fc.returned = FALSE; 18093 fc.level = ex_nesting_level; 18094 /* Check if this function has a breakpoint. */ 18095 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18096 fc.dbg_tick = debug_tick; 18097 18098 /* 18099 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18100 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18101 * each argument variable and saves a lot of time. 18102 */ 18103 /* 18104 * Init l: variables. 18105 */ 18106 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18107 if (selfdict != NULL) 18108 { 18109 /* Set l:self to "selfdict". */ 18110 v = &fc.fixvar[fixvar_idx++].var; 18111 STRCPY(v->di_key, "self"); 18112 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18113 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18114 v->di_tv.v_type = VAR_DICT; 18115 v->di_tv.v_lock = 0; 18116 v->di_tv.vval.v_dict = selfdict; 18117 ++selfdict->dv_refcount; 18118 } 18119 18120 /* 18121 * Init a: variables. 18122 * Set a:0 to "argcount". 18123 * Set a:000 to a list with room for the "..." arguments. 18124 */ 18125 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18126 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18127 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18128 v = &fc.fixvar[fixvar_idx++].var; 18129 STRCPY(v->di_key, "000"); 18130 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18131 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18132 v->di_tv.v_type = VAR_LIST; 18133 v->di_tv.v_lock = VAR_FIXED; 18134 v->di_tv.vval.v_list = &fc.l_varlist; 18135 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18136 fc.l_varlist.lv_refcount = 99999; 18137 18138 /* 18139 * Set a:firstline to "firstline" and a:lastline to "lastline". 18140 * Set a:name to named arguments. 18141 * Set a:N to the "..." arguments. 18142 */ 18143 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18144 (varnumber_T)firstline); 18145 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18146 (varnumber_T)lastline); 18147 for (i = 0; i < argcount; ++i) 18148 { 18149 ai = i - fp->uf_args.ga_len; 18150 if (ai < 0) 18151 /* named argument a:name */ 18152 name = FUNCARG(fp, i); 18153 else 18154 { 18155 /* "..." argument a:1, a:2, etc. */ 18156 sprintf((char *)numbuf, "%d", ai + 1); 18157 name = numbuf; 18158 } 18159 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18160 { 18161 v = &fc.fixvar[fixvar_idx++].var; 18162 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18163 } 18164 else 18165 { 18166 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18167 + STRLEN(name))); 18168 if (v == NULL) 18169 break; 18170 v->di_flags = DI_FLAGS_RO; 18171 } 18172 STRCPY(v->di_key, name); 18173 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18174 18175 /* Note: the values are copied directly to avoid alloc/free. 18176 * "argvars" must have VAR_FIXED for v_lock. */ 18177 v->di_tv = argvars[i]; 18178 v->di_tv.v_lock = VAR_FIXED; 18179 18180 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18181 { 18182 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18183 fc.l_listitems[ai].li_tv = argvars[i]; 18184 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18185 } 18186 } 18187 18188 /* Don't redraw while executing the function. */ 18189 ++RedrawingDisabled; 18190 save_sourcing_name = sourcing_name; 18191 save_sourcing_lnum = sourcing_lnum; 18192 sourcing_lnum = 1; 18193 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18194 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18195 if (sourcing_name != NULL) 18196 { 18197 if (save_sourcing_name != NULL 18198 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18199 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18200 else 18201 STRCPY(sourcing_name, "function "); 18202 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18203 18204 if (p_verbose >= 12) 18205 { 18206 ++no_wait_return; 18207 verbose_enter_scroll(); 18208 18209 smsg((char_u *)_("calling %s"), sourcing_name); 18210 if (p_verbose >= 14) 18211 { 18212 char_u buf[MSG_BUF_LEN]; 18213 char_u numbuf[NUMBUFLEN]; 18214 char_u *tofree; 18215 18216 msg_puts((char_u *)"("); 18217 for (i = 0; i < argcount; ++i) 18218 { 18219 if (i > 0) 18220 msg_puts((char_u *)", "); 18221 if (argvars[i].v_type == VAR_NUMBER) 18222 msg_outnum((long)argvars[i].vval.v_number); 18223 else 18224 { 18225 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18226 buf, MSG_BUF_CLEN); 18227 msg_puts(buf); 18228 vim_free(tofree); 18229 } 18230 } 18231 msg_puts((char_u *)")"); 18232 } 18233 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18234 18235 verbose_leave_scroll(); 18236 --no_wait_return; 18237 } 18238 } 18239 #ifdef FEAT_PROFILE 18240 if (do_profiling) 18241 { 18242 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18243 func_do_profile(fp); 18244 if (fp->uf_profiling 18245 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18246 { 18247 ++fp->uf_tm_count; 18248 profile_start(&fp->uf_tm_start); 18249 profile_zero(&fp->uf_tm_children); 18250 } 18251 script_prof_save(&wait_start); 18252 } 18253 #endif 18254 18255 save_current_SID = current_SID; 18256 current_SID = fp->uf_script_ID; 18257 save_did_emsg = did_emsg; 18258 did_emsg = FALSE; 18259 18260 /* call do_cmdline() to execute the lines */ 18261 do_cmdline(NULL, get_func_line, (void *)&fc, 18262 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18263 18264 --RedrawingDisabled; 18265 18266 /* when the function was aborted because of an error, return -1 */ 18267 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18268 { 18269 clear_tv(rettv); 18270 rettv->v_type = VAR_NUMBER; 18271 rettv->vval.v_number = -1; 18272 } 18273 18274 #ifdef FEAT_PROFILE 18275 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18276 { 18277 profile_end(&fp->uf_tm_start); 18278 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18279 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18280 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18281 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18282 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18283 { 18284 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18285 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18286 } 18287 } 18288 #endif 18289 18290 /* when being verbose, mention the return value */ 18291 if (p_verbose >= 12) 18292 { 18293 ++no_wait_return; 18294 verbose_enter_scroll(); 18295 18296 if (aborting()) 18297 smsg((char_u *)_("%s aborted"), sourcing_name); 18298 else if (fc.rettv->v_type == VAR_NUMBER) 18299 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18300 (long)fc.rettv->vval.v_number); 18301 else 18302 { 18303 char_u buf[MSG_BUF_LEN]; 18304 char_u numbuf[NUMBUFLEN]; 18305 char_u *tofree; 18306 18307 /* The value may be very long. Skip the middle part, so that we 18308 * have some idea how it starts and ends. smsg() would always 18309 * truncate it at the end. */ 18310 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18311 buf, MSG_BUF_CLEN); 18312 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18313 vim_free(tofree); 18314 } 18315 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18316 18317 verbose_leave_scroll(); 18318 --no_wait_return; 18319 } 18320 18321 vim_free(sourcing_name); 18322 sourcing_name = save_sourcing_name; 18323 sourcing_lnum = save_sourcing_lnum; 18324 current_SID = save_current_SID; 18325 #ifdef FEAT_PROFILE 18326 if (do_profiling) 18327 script_prof_restore(&wait_start); 18328 #endif 18329 18330 if (p_verbose >= 12 && sourcing_name != NULL) 18331 { 18332 ++no_wait_return; 18333 verbose_enter_scroll(); 18334 18335 smsg((char_u *)_("continuing in %s"), sourcing_name); 18336 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18337 18338 verbose_leave_scroll(); 18339 --no_wait_return; 18340 } 18341 18342 did_emsg |= save_did_emsg; 18343 current_funccal = fc.caller; 18344 18345 /* The a: variables typevals were not alloced, only free the allocated 18346 * variables. */ 18347 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18348 18349 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18350 --depth; 18351 } 18352 18353 /* 18354 * Add a number variable "name" to dict "dp" with value "nr". 18355 */ 18356 static void 18357 add_nr_var(dp, v, name, nr) 18358 dict_T *dp; 18359 dictitem_T *v; 18360 char *name; 18361 varnumber_T nr; 18362 { 18363 STRCPY(v->di_key, name); 18364 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18365 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18366 v->di_tv.v_type = VAR_NUMBER; 18367 v->di_tv.v_lock = VAR_FIXED; 18368 v->di_tv.vval.v_number = nr; 18369 } 18370 18371 /* 18372 * ":return [expr]" 18373 */ 18374 void 18375 ex_return(eap) 18376 exarg_T *eap; 18377 { 18378 char_u *arg = eap->arg; 18379 typval_T rettv; 18380 int returning = FALSE; 18381 18382 if (current_funccal == NULL) 18383 { 18384 EMSG(_("E133: :return not inside a function")); 18385 return; 18386 } 18387 18388 if (eap->skip) 18389 ++emsg_skip; 18390 18391 eap->nextcmd = NULL; 18392 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18393 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18394 { 18395 if (!eap->skip) 18396 returning = do_return(eap, FALSE, TRUE, &rettv); 18397 else 18398 clear_tv(&rettv); 18399 } 18400 /* It's safer to return also on error. */ 18401 else if (!eap->skip) 18402 { 18403 /* 18404 * Return unless the expression evaluation has been cancelled due to an 18405 * aborting error, an interrupt, or an exception. 18406 */ 18407 if (!aborting()) 18408 returning = do_return(eap, FALSE, TRUE, NULL); 18409 } 18410 18411 /* When skipping or the return gets pending, advance to the next command 18412 * in this line (!returning). Otherwise, ignore the rest of the line. 18413 * Following lines will be ignored by get_func_line(). */ 18414 if (returning) 18415 eap->nextcmd = NULL; 18416 else if (eap->nextcmd == NULL) /* no argument */ 18417 eap->nextcmd = check_nextcmd(arg); 18418 18419 if (eap->skip) 18420 --emsg_skip; 18421 } 18422 18423 /* 18424 * Return from a function. Possibly makes the return pending. Also called 18425 * for a pending return at the ":endtry" or after returning from an extra 18426 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18427 * when called due to a ":return" command. "rettv" may point to a typval_T 18428 * with the return rettv. Returns TRUE when the return can be carried out, 18429 * FALSE when the return gets pending. 18430 */ 18431 int 18432 do_return(eap, reanimate, is_cmd, rettv) 18433 exarg_T *eap; 18434 int reanimate; 18435 int is_cmd; 18436 void *rettv; 18437 { 18438 int idx; 18439 struct condstack *cstack = eap->cstack; 18440 18441 if (reanimate) 18442 /* Undo the return. */ 18443 current_funccal->returned = FALSE; 18444 18445 /* 18446 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18447 * not in its finally clause (which then is to be executed next) is found. 18448 * In this case, make the ":return" pending for execution at the ":endtry". 18449 * Otherwise, return normally. 18450 */ 18451 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18452 if (idx >= 0) 18453 { 18454 cstack->cs_pending[idx] = CSTP_RETURN; 18455 18456 if (!is_cmd && !reanimate) 18457 /* A pending return again gets pending. "rettv" points to an 18458 * allocated variable with the rettv of the original ":return"'s 18459 * argument if present or is NULL else. */ 18460 cstack->cs_rettv[idx] = rettv; 18461 else 18462 { 18463 /* When undoing a return in order to make it pending, get the stored 18464 * return rettv. */ 18465 if (reanimate) 18466 rettv = current_funccal->rettv; 18467 18468 if (rettv != NULL) 18469 { 18470 /* Store the value of the pending return. */ 18471 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18472 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18473 else 18474 EMSG(_(e_outofmem)); 18475 } 18476 else 18477 cstack->cs_rettv[idx] = NULL; 18478 18479 if (reanimate) 18480 { 18481 /* The pending return value could be overwritten by a ":return" 18482 * without argument in a finally clause; reset the default 18483 * return value. */ 18484 current_funccal->rettv->v_type = VAR_NUMBER; 18485 current_funccal->rettv->vval.v_number = 0; 18486 } 18487 } 18488 report_make_pending(CSTP_RETURN, rettv); 18489 } 18490 else 18491 { 18492 current_funccal->returned = TRUE; 18493 18494 /* If the return is carried out now, store the return value. For 18495 * a return immediately after reanimation, the value is already 18496 * there. */ 18497 if (!reanimate && rettv != NULL) 18498 { 18499 clear_tv(current_funccal->rettv); 18500 *current_funccal->rettv = *(typval_T *)rettv; 18501 if (!is_cmd) 18502 vim_free(rettv); 18503 } 18504 } 18505 18506 return idx < 0; 18507 } 18508 18509 /* 18510 * Free the variable with a pending return value. 18511 */ 18512 void 18513 discard_pending_return(rettv) 18514 void *rettv; 18515 { 18516 free_tv((typval_T *)rettv); 18517 } 18518 18519 /* 18520 * Generate a return command for producing the value of "rettv". The result 18521 * is an allocated string. Used by report_pending() for verbose messages. 18522 */ 18523 char_u * 18524 get_return_cmd(rettv) 18525 void *rettv; 18526 { 18527 char_u *s = NULL; 18528 char_u *tofree = NULL; 18529 char_u numbuf[NUMBUFLEN]; 18530 18531 if (rettv != NULL) 18532 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18533 if (s == NULL) 18534 s = (char_u *)""; 18535 18536 STRCPY(IObuff, ":return "); 18537 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18538 if (STRLEN(s) + 8 >= IOSIZE) 18539 STRCPY(IObuff + IOSIZE - 4, "..."); 18540 vim_free(tofree); 18541 return vim_strsave(IObuff); 18542 } 18543 18544 /* 18545 * Get next function line. 18546 * Called by do_cmdline() to get the next line. 18547 * Returns allocated string, or NULL for end of function. 18548 */ 18549 /* ARGSUSED */ 18550 char_u * 18551 get_func_line(c, cookie, indent) 18552 int c; /* not used */ 18553 void *cookie; 18554 int indent; /* not used */ 18555 { 18556 funccall_T *fcp = (funccall_T *)cookie; 18557 ufunc_T *fp = fcp->func; 18558 char_u *retval; 18559 garray_T *gap; /* growarray with function lines */ 18560 18561 /* If breakpoints have been added/deleted need to check for it. */ 18562 if (fcp->dbg_tick != debug_tick) 18563 { 18564 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18565 sourcing_lnum); 18566 fcp->dbg_tick = debug_tick; 18567 } 18568 #ifdef FEAT_PROFILE 18569 if (do_profiling) 18570 func_line_end(cookie); 18571 #endif 18572 18573 gap = &fp->uf_lines; 18574 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18575 retval = NULL; 18576 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18577 retval = NULL; 18578 else 18579 { 18580 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18581 sourcing_lnum = fcp->linenr; 18582 #ifdef FEAT_PROFILE 18583 if (do_profiling) 18584 func_line_start(cookie); 18585 #endif 18586 } 18587 18588 /* Did we encounter a breakpoint? */ 18589 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18590 { 18591 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18592 /* Find next breakpoint. */ 18593 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18594 sourcing_lnum); 18595 fcp->dbg_tick = debug_tick; 18596 } 18597 18598 return retval; 18599 } 18600 18601 #if defined(FEAT_PROFILE) || defined(PROTO) 18602 /* 18603 * Called when starting to read a function line. 18604 * "sourcing_lnum" must be correct! 18605 * When skipping lines it may not actually be executed, but we won't find out 18606 * until later and we need to store the time now. 18607 */ 18608 void 18609 func_line_start(cookie) 18610 void *cookie; 18611 { 18612 funccall_T *fcp = (funccall_T *)cookie; 18613 ufunc_T *fp = fcp->func; 18614 18615 if (fp->uf_profiling && sourcing_lnum >= 1 18616 && sourcing_lnum <= fp->uf_lines.ga_len) 18617 { 18618 fp->uf_tml_idx = sourcing_lnum - 1; 18619 fp->uf_tml_execed = FALSE; 18620 profile_start(&fp->uf_tml_start); 18621 profile_zero(&fp->uf_tml_children); 18622 profile_get_wait(&fp->uf_tml_wait); 18623 } 18624 } 18625 18626 /* 18627 * Called when actually executing a function line. 18628 */ 18629 void 18630 func_line_exec(cookie) 18631 void *cookie; 18632 { 18633 funccall_T *fcp = (funccall_T *)cookie; 18634 ufunc_T *fp = fcp->func; 18635 18636 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18637 fp->uf_tml_execed = TRUE; 18638 } 18639 18640 /* 18641 * Called when done with a function line. 18642 */ 18643 void 18644 func_line_end(cookie) 18645 void *cookie; 18646 { 18647 funccall_T *fcp = (funccall_T *)cookie; 18648 ufunc_T *fp = fcp->func; 18649 18650 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18651 { 18652 if (fp->uf_tml_execed) 18653 { 18654 ++fp->uf_tml_count[fp->uf_tml_idx]; 18655 profile_end(&fp->uf_tml_start); 18656 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18657 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18658 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18659 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18660 } 18661 fp->uf_tml_idx = -1; 18662 } 18663 } 18664 #endif 18665 18666 /* 18667 * Return TRUE if the currently active function should be ended, because a 18668 * return was encountered or an error occured. Used inside a ":while". 18669 */ 18670 int 18671 func_has_ended(cookie) 18672 void *cookie; 18673 { 18674 funccall_T *fcp = (funccall_T *)cookie; 18675 18676 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18677 * an error inside a try conditional. */ 18678 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18679 || fcp->returned); 18680 } 18681 18682 /* 18683 * return TRUE if cookie indicates a function which "abort"s on errors. 18684 */ 18685 int 18686 func_has_abort(cookie) 18687 void *cookie; 18688 { 18689 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18690 } 18691 18692 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18693 typedef enum 18694 { 18695 VAR_FLAVOUR_DEFAULT, 18696 VAR_FLAVOUR_SESSION, 18697 VAR_FLAVOUR_VIMINFO 18698 } var_flavour_T; 18699 18700 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18701 18702 static var_flavour_T 18703 var_flavour(varname) 18704 char_u *varname; 18705 { 18706 char_u *p = varname; 18707 18708 if (ASCII_ISUPPER(*p)) 18709 { 18710 while (*(++p)) 18711 if (ASCII_ISLOWER(*p)) 18712 return VAR_FLAVOUR_SESSION; 18713 return VAR_FLAVOUR_VIMINFO; 18714 } 18715 else 18716 return VAR_FLAVOUR_DEFAULT; 18717 } 18718 #endif 18719 18720 #if defined(FEAT_VIMINFO) || defined(PROTO) 18721 /* 18722 * Restore global vars that start with a capital from the viminfo file 18723 */ 18724 int 18725 read_viminfo_varlist(virp, writing) 18726 vir_T *virp; 18727 int writing; 18728 { 18729 char_u *tab; 18730 int is_string = FALSE; 18731 typval_T tv; 18732 18733 if (!writing && (find_viminfo_parameter('!') != NULL)) 18734 { 18735 tab = vim_strchr(virp->vir_line + 1, '\t'); 18736 if (tab != NULL) 18737 { 18738 *tab++ = '\0'; /* isolate the variable name */ 18739 if (*tab == 'S') /* string var */ 18740 is_string = TRUE; 18741 18742 tab = vim_strchr(tab, '\t'); 18743 if (tab != NULL) 18744 { 18745 if (is_string) 18746 { 18747 tv.v_type = VAR_STRING; 18748 tv.vval.v_string = viminfo_readstring(virp, 18749 (int)(tab - virp->vir_line + 1), TRUE); 18750 } 18751 else 18752 { 18753 tv.v_type = VAR_NUMBER; 18754 tv.vval.v_number = atol((char *)tab + 1); 18755 } 18756 set_var(virp->vir_line + 1, &tv, FALSE); 18757 if (is_string) 18758 vim_free(tv.vval.v_string); 18759 } 18760 } 18761 } 18762 18763 return viminfo_readline(virp); 18764 } 18765 18766 /* 18767 * Write global vars that start with a capital to the viminfo file 18768 */ 18769 void 18770 write_viminfo_varlist(fp) 18771 FILE *fp; 18772 { 18773 hashitem_T *hi; 18774 dictitem_T *this_var; 18775 int todo; 18776 char *s; 18777 char_u *p; 18778 char_u *tofree; 18779 char_u numbuf[NUMBUFLEN]; 18780 18781 if (find_viminfo_parameter('!') == NULL) 18782 return; 18783 18784 fprintf(fp, _("\n# global variables:\n")); 18785 18786 todo = globvarht.ht_used; 18787 for (hi = globvarht.ht_array; todo > 0; ++hi) 18788 { 18789 if (!HASHITEM_EMPTY(hi)) 18790 { 18791 --todo; 18792 this_var = HI2DI(hi); 18793 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 18794 { 18795 switch (this_var->di_tv.v_type) 18796 { 18797 case VAR_STRING: s = "STR"; break; 18798 case VAR_NUMBER: s = "NUM"; break; 18799 default: continue; 18800 } 18801 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 18802 p = echo_string(&this_var->di_tv, &tofree, numbuf); 18803 if (p != NULL) 18804 viminfo_writestring(fp, p); 18805 vim_free(tofree); 18806 } 18807 } 18808 } 18809 } 18810 #endif 18811 18812 #if defined(FEAT_SESSION) || defined(PROTO) 18813 int 18814 store_session_globals(fd) 18815 FILE *fd; 18816 { 18817 hashitem_T *hi; 18818 dictitem_T *this_var; 18819 int todo; 18820 char_u *p, *t; 18821 18822 todo = globvarht.ht_used; 18823 for (hi = globvarht.ht_array; todo > 0; ++hi) 18824 { 18825 if (!HASHITEM_EMPTY(hi)) 18826 { 18827 --todo; 18828 this_var = HI2DI(hi); 18829 if ((this_var->di_tv.v_type == VAR_NUMBER 18830 || this_var->di_tv.v_type == VAR_STRING) 18831 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 18832 { 18833 /* Escape special characters with a backslash. Turn a LF and 18834 * CR into \n and \r. */ 18835 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 18836 (char_u *)"\\\"\n\r"); 18837 if (p == NULL) /* out of memory */ 18838 break; 18839 for (t = p; *t != NUL; ++t) 18840 if (*t == '\n') 18841 *t = 'n'; 18842 else if (*t == '\r') 18843 *t = 'r'; 18844 if ((fprintf(fd, "let %s = %c%s%c", 18845 this_var->di_key, 18846 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18847 : ' ', 18848 p, 18849 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18850 : ' ') < 0) 18851 || put_eol(fd) == FAIL) 18852 { 18853 vim_free(p); 18854 return FAIL; 18855 } 18856 vim_free(p); 18857 } 18858 } 18859 } 18860 return OK; 18861 } 18862 #endif 18863 18864 /* 18865 * Display script name where an item was last set. 18866 * Should only be invoked when 'verbose' is non-zero. 18867 */ 18868 void 18869 last_set_msg(scriptID) 18870 scid_T scriptID; 18871 { 18872 if (scriptID != 0) 18873 { 18874 verbose_enter(); 18875 MSG_PUTS(_("\n\tLast set from ")); 18876 MSG_PUTS(get_scriptname(scriptID)); 18877 verbose_leave(); 18878 } 18879 } 18880 18881 #endif /* FEAT_EVAL */ 18882 18883 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 18884 18885 18886 #ifdef WIN3264 18887 /* 18888 * Functions for ":8" filename modifier: get 8.3 version of a filename. 18889 */ 18890 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18891 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 18892 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18893 18894 /* 18895 * Get the short pathname of a file. 18896 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 18897 */ 18898 static int 18899 get_short_pathname(fnamep, bufp, fnamelen) 18900 char_u **fnamep; 18901 char_u **bufp; 18902 int *fnamelen; 18903 { 18904 int l,len; 18905 char_u *newbuf; 18906 18907 len = *fnamelen; 18908 18909 l = GetShortPathName(*fnamep, *fnamep, len); 18910 if (l > len - 1) 18911 { 18912 /* If that doesn't work (not enough space), then save the string 18913 * and try again with a new buffer big enough 18914 */ 18915 newbuf = vim_strnsave(*fnamep, l); 18916 if (newbuf == NULL) 18917 return 0; 18918 18919 vim_free(*bufp); 18920 *fnamep = *bufp = newbuf; 18921 18922 l = GetShortPathName(*fnamep,*fnamep,l+1); 18923 18924 /* Really should always succeed, as the buffer is big enough */ 18925 } 18926 18927 *fnamelen = l; 18928 return 1; 18929 } 18930 18931 /* 18932 * Create a short path name. Returns the length of the buffer it needs. 18933 * Doesn't copy over the end of the buffer passed in. 18934 */ 18935 static int 18936 shortpath_for_invalid_fname(fname, bufp, fnamelen) 18937 char_u **fname; 18938 char_u **bufp; 18939 int *fnamelen; 18940 { 18941 char_u *s, *p, *pbuf2, *pbuf3; 18942 char_u ch; 18943 int len, len2, plen, slen; 18944 18945 /* Make a copy */ 18946 len2 = *fnamelen; 18947 pbuf2 = vim_strnsave(*fname, len2); 18948 pbuf3 = NULL; 18949 18950 s = pbuf2 + len2 - 1; /* Find the end */ 18951 slen = 1; 18952 plen = len2; 18953 18954 if (after_pathsep(pbuf2, s + 1)) 18955 { 18956 --s; 18957 ++slen; 18958 --plen; 18959 } 18960 18961 do 18962 { 18963 /* Go back one path-seperator */ 18964 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 18965 { 18966 --s; 18967 ++slen; 18968 --plen; 18969 } 18970 if (s <= pbuf2) 18971 break; 18972 18973 /* Remeber the character that is about to be blatted */ 18974 ch = *s; 18975 *s = 0; /* get_short_pathname requires a null-terminated string */ 18976 18977 /* Try it in situ */ 18978 p = pbuf2; 18979 if (!get_short_pathname(&p, &pbuf3, &plen)) 18980 { 18981 vim_free(pbuf2); 18982 return -1; 18983 } 18984 *s = ch; /* Preserve the string */ 18985 } while (plen == 0); 18986 18987 if (plen > 0) 18988 { 18989 /* Remeber the length of the new string. */ 18990 *fnamelen = len = plen + slen; 18991 vim_free(*bufp); 18992 if (len > len2) 18993 { 18994 /* If there's not enough space in the currently allocated string, 18995 * then copy it to a buffer big enough. 18996 */ 18997 *fname= *bufp = vim_strnsave(p, len); 18998 if (*fname == NULL) 18999 return -1; 19000 } 19001 else 19002 { 19003 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 19004 *fname = *bufp = pbuf2; 19005 if (p != pbuf2) 19006 strncpy(*fname, p, plen); 19007 pbuf2 = NULL; 19008 } 19009 /* Concat the next bit */ 19010 strncpy(*fname + plen, s, slen); 19011 (*fname)[len] = '\0'; 19012 } 19013 vim_free(pbuf3); 19014 vim_free(pbuf2); 19015 return 0; 19016 } 19017 19018 /* 19019 * Get a pathname for a partial path. 19020 */ 19021 static int 19022 shortpath_for_partial(fnamep, bufp, fnamelen) 19023 char_u **fnamep; 19024 char_u **bufp; 19025 int *fnamelen; 19026 { 19027 int sepcount, len, tflen; 19028 char_u *p; 19029 char_u *pbuf, *tfname; 19030 int hasTilde; 19031 19032 /* Count up the path seperators from the RHS.. so we know which part 19033 * of the path to return. 19034 */ 19035 sepcount = 0; 19036 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19037 if (vim_ispathsep(*p)) 19038 ++sepcount; 19039 19040 /* Need full path first (use expand_env() to remove a "~/") */ 19041 hasTilde = (**fnamep == '~'); 19042 if (hasTilde) 19043 pbuf = tfname = expand_env_save(*fnamep); 19044 else 19045 pbuf = tfname = FullName_save(*fnamep, FALSE); 19046 19047 len = tflen = STRLEN(tfname); 19048 19049 if (!get_short_pathname(&tfname, &pbuf, &len)) 19050 return -1; 19051 19052 if (len == 0) 19053 { 19054 /* Don't have a valid filename, so shorten the rest of the 19055 * path if we can. This CAN give us invalid 8.3 filenames, but 19056 * there's not a lot of point in guessing what it might be. 19057 */ 19058 len = tflen; 19059 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19060 return -1; 19061 } 19062 19063 /* Count the paths backward to find the beginning of the desired string. */ 19064 for (p = tfname + len - 1; p >= tfname; --p) 19065 { 19066 #ifdef FEAT_MBYTE 19067 if (has_mbyte) 19068 p -= mb_head_off(tfname, p); 19069 #endif 19070 if (vim_ispathsep(*p)) 19071 { 19072 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19073 break; 19074 else 19075 sepcount --; 19076 } 19077 } 19078 if (hasTilde) 19079 { 19080 --p; 19081 if (p >= tfname) 19082 *p = '~'; 19083 else 19084 return -1; 19085 } 19086 else 19087 ++p; 19088 19089 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19090 vim_free(*bufp); 19091 *fnamelen = (int)STRLEN(p); 19092 *bufp = pbuf; 19093 *fnamep = p; 19094 19095 return 0; 19096 } 19097 #endif /* WIN3264 */ 19098 19099 /* 19100 * Adjust a filename, according to a string of modifiers. 19101 * *fnamep must be NUL terminated when called. When returning, the length is 19102 * determined by *fnamelen. 19103 * Returns valid flags. 19104 * When there is an error, *fnamep is set to NULL. 19105 */ 19106 int 19107 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19108 char_u *src; /* string with modifiers */ 19109 int *usedlen; /* characters after src that are used */ 19110 char_u **fnamep; /* file name so far */ 19111 char_u **bufp; /* buffer for allocated file name or NULL */ 19112 int *fnamelen; /* length of fnamep */ 19113 { 19114 int valid = 0; 19115 char_u *tail; 19116 char_u *s, *p, *pbuf; 19117 char_u dirname[MAXPATHL]; 19118 int c; 19119 int has_fullname = 0; 19120 #ifdef WIN3264 19121 int has_shortname = 0; 19122 #endif 19123 19124 repeat: 19125 /* ":p" - full path/file_name */ 19126 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19127 { 19128 has_fullname = 1; 19129 19130 valid |= VALID_PATH; 19131 *usedlen += 2; 19132 19133 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19134 if ((*fnamep)[0] == '~' 19135 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19136 && ((*fnamep)[1] == '/' 19137 # ifdef BACKSLASH_IN_FILENAME 19138 || (*fnamep)[1] == '\\' 19139 # endif 19140 || (*fnamep)[1] == NUL) 19141 19142 #endif 19143 ) 19144 { 19145 *fnamep = expand_env_save(*fnamep); 19146 vim_free(*bufp); /* free any allocated file name */ 19147 *bufp = *fnamep; 19148 if (*fnamep == NULL) 19149 return -1; 19150 } 19151 19152 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19153 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19154 { 19155 if (vim_ispathsep(*p) 19156 && p[1] == '.' 19157 && (p[2] == NUL 19158 || vim_ispathsep(p[2]) 19159 || (p[2] == '.' 19160 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19161 break; 19162 } 19163 19164 /* FullName_save() is slow, don't use it when not needed. */ 19165 if (*p != NUL || !vim_isAbsName(*fnamep)) 19166 { 19167 *fnamep = FullName_save(*fnamep, *p != NUL); 19168 vim_free(*bufp); /* free any allocated file name */ 19169 *bufp = *fnamep; 19170 if (*fnamep == NULL) 19171 return -1; 19172 } 19173 19174 /* Append a path separator to a directory. */ 19175 if (mch_isdir(*fnamep)) 19176 { 19177 /* Make room for one or two extra characters. */ 19178 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19179 vim_free(*bufp); /* free any allocated file name */ 19180 *bufp = *fnamep; 19181 if (*fnamep == NULL) 19182 return -1; 19183 add_pathsep(*fnamep); 19184 } 19185 } 19186 19187 /* ":." - path relative to the current directory */ 19188 /* ":~" - path relative to the home directory */ 19189 /* ":8" - shortname path - postponed till after */ 19190 while (src[*usedlen] == ':' 19191 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19192 { 19193 *usedlen += 2; 19194 if (c == '8') 19195 { 19196 #ifdef WIN3264 19197 has_shortname = 1; /* Postpone this. */ 19198 #endif 19199 continue; 19200 } 19201 pbuf = NULL; 19202 /* Need full path first (use expand_env() to remove a "~/") */ 19203 if (!has_fullname) 19204 { 19205 if (c == '.' && **fnamep == '~') 19206 p = pbuf = expand_env_save(*fnamep); 19207 else 19208 p = pbuf = FullName_save(*fnamep, FALSE); 19209 } 19210 else 19211 p = *fnamep; 19212 19213 has_fullname = 0; 19214 19215 if (p != NULL) 19216 { 19217 if (c == '.') 19218 { 19219 mch_dirname(dirname, MAXPATHL); 19220 s = shorten_fname(p, dirname); 19221 if (s != NULL) 19222 { 19223 *fnamep = s; 19224 if (pbuf != NULL) 19225 { 19226 vim_free(*bufp); /* free any allocated file name */ 19227 *bufp = pbuf; 19228 pbuf = NULL; 19229 } 19230 } 19231 } 19232 else 19233 { 19234 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19235 /* Only replace it when it starts with '~' */ 19236 if (*dirname == '~') 19237 { 19238 s = vim_strsave(dirname); 19239 if (s != NULL) 19240 { 19241 *fnamep = s; 19242 vim_free(*bufp); 19243 *bufp = s; 19244 } 19245 } 19246 } 19247 vim_free(pbuf); 19248 } 19249 } 19250 19251 tail = gettail(*fnamep); 19252 *fnamelen = (int)STRLEN(*fnamep); 19253 19254 /* ":h" - head, remove "/file_name", can be repeated */ 19255 /* Don't remove the first "/" or "c:\" */ 19256 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19257 { 19258 valid |= VALID_HEAD; 19259 *usedlen += 2; 19260 s = get_past_head(*fnamep); 19261 while (tail > s && after_pathsep(s, tail)) 19262 --tail; 19263 *fnamelen = (int)(tail - *fnamep); 19264 #ifdef VMS 19265 if (*fnamelen > 0) 19266 *fnamelen += 1; /* the path separator is part of the path */ 19267 #endif 19268 while (tail > s && !after_pathsep(s, tail)) 19269 mb_ptr_back(*fnamep, tail); 19270 } 19271 19272 /* ":8" - shortname */ 19273 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19274 { 19275 *usedlen += 2; 19276 #ifdef WIN3264 19277 has_shortname = 1; 19278 #endif 19279 } 19280 19281 #ifdef WIN3264 19282 /* Check shortname after we have done 'heads' and before we do 'tails' 19283 */ 19284 if (has_shortname) 19285 { 19286 pbuf = NULL; 19287 /* Copy the string if it is shortened by :h */ 19288 if (*fnamelen < (int)STRLEN(*fnamep)) 19289 { 19290 p = vim_strnsave(*fnamep, *fnamelen); 19291 if (p == 0) 19292 return -1; 19293 vim_free(*bufp); 19294 *bufp = *fnamep = p; 19295 } 19296 19297 /* Split into two implementations - makes it easier. First is where 19298 * there isn't a full name already, second is where there is. 19299 */ 19300 if (!has_fullname && !vim_isAbsName(*fnamep)) 19301 { 19302 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19303 return -1; 19304 } 19305 else 19306 { 19307 int l; 19308 19309 /* Simple case, already have the full-name 19310 * Nearly always shorter, so try first time. */ 19311 l = *fnamelen; 19312 if (!get_short_pathname(fnamep, bufp, &l)) 19313 return -1; 19314 19315 if (l == 0) 19316 { 19317 /* Couldn't find the filename.. search the paths. 19318 */ 19319 l = *fnamelen; 19320 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19321 return -1; 19322 } 19323 *fnamelen = l; 19324 } 19325 } 19326 #endif /* WIN3264 */ 19327 19328 /* ":t" - tail, just the basename */ 19329 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19330 { 19331 *usedlen += 2; 19332 *fnamelen -= (int)(tail - *fnamep); 19333 *fnamep = tail; 19334 } 19335 19336 /* ":e" - extension, can be repeated */ 19337 /* ":r" - root, without extension, can be repeated */ 19338 while (src[*usedlen] == ':' 19339 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19340 { 19341 /* find a '.' in the tail: 19342 * - for second :e: before the current fname 19343 * - otherwise: The last '.' 19344 */ 19345 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19346 s = *fnamep - 2; 19347 else 19348 s = *fnamep + *fnamelen - 1; 19349 for ( ; s > tail; --s) 19350 if (s[0] == '.') 19351 break; 19352 if (src[*usedlen + 1] == 'e') /* :e */ 19353 { 19354 if (s > tail) 19355 { 19356 *fnamelen += (int)(*fnamep - (s + 1)); 19357 *fnamep = s + 1; 19358 #ifdef VMS 19359 /* cut version from the extension */ 19360 s = *fnamep + *fnamelen - 1; 19361 for ( ; s > *fnamep; --s) 19362 if (s[0] == ';') 19363 break; 19364 if (s > *fnamep) 19365 *fnamelen = s - *fnamep; 19366 #endif 19367 } 19368 else if (*fnamep <= tail) 19369 *fnamelen = 0; 19370 } 19371 else /* :r */ 19372 { 19373 if (s > tail) /* remove one extension */ 19374 *fnamelen = (int)(s - *fnamep); 19375 } 19376 *usedlen += 2; 19377 } 19378 19379 /* ":s?pat?foo?" - substitute */ 19380 /* ":gs?pat?foo?" - global substitute */ 19381 if (src[*usedlen] == ':' 19382 && (src[*usedlen + 1] == 's' 19383 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19384 { 19385 char_u *str; 19386 char_u *pat; 19387 char_u *sub; 19388 int sep; 19389 char_u *flags; 19390 int didit = FALSE; 19391 19392 flags = (char_u *)""; 19393 s = src + *usedlen + 2; 19394 if (src[*usedlen + 1] == 'g') 19395 { 19396 flags = (char_u *)"g"; 19397 ++s; 19398 } 19399 19400 sep = *s++; 19401 if (sep) 19402 { 19403 /* find end of pattern */ 19404 p = vim_strchr(s, sep); 19405 if (p != NULL) 19406 { 19407 pat = vim_strnsave(s, (int)(p - s)); 19408 if (pat != NULL) 19409 { 19410 s = p + 1; 19411 /* find end of substitution */ 19412 p = vim_strchr(s, sep); 19413 if (p != NULL) 19414 { 19415 sub = vim_strnsave(s, (int)(p - s)); 19416 str = vim_strnsave(*fnamep, *fnamelen); 19417 if (sub != NULL && str != NULL) 19418 { 19419 *usedlen = (int)(p + 1 - src); 19420 s = do_string_sub(str, pat, sub, flags); 19421 if (s != NULL) 19422 { 19423 *fnamep = s; 19424 *fnamelen = (int)STRLEN(s); 19425 vim_free(*bufp); 19426 *bufp = s; 19427 didit = TRUE; 19428 } 19429 } 19430 vim_free(sub); 19431 vim_free(str); 19432 } 19433 vim_free(pat); 19434 } 19435 } 19436 /* after using ":s", repeat all the modifiers */ 19437 if (didit) 19438 goto repeat; 19439 } 19440 } 19441 19442 return valid; 19443 } 19444 19445 /* 19446 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19447 * "flags" can be "g" to do a global substitute. 19448 * Returns an allocated string, NULL for error. 19449 */ 19450 char_u * 19451 do_string_sub(str, pat, sub, flags) 19452 char_u *str; 19453 char_u *pat; 19454 char_u *sub; 19455 char_u *flags; 19456 { 19457 int sublen; 19458 regmatch_T regmatch; 19459 int i; 19460 int do_all; 19461 char_u *tail; 19462 garray_T ga; 19463 char_u *ret; 19464 char_u *save_cpo; 19465 19466 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19467 save_cpo = p_cpo; 19468 p_cpo = (char_u *)""; 19469 19470 ga_init2(&ga, 1, 200); 19471 19472 do_all = (flags[0] == 'g'); 19473 19474 regmatch.rm_ic = p_ic; 19475 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19476 if (regmatch.regprog != NULL) 19477 { 19478 tail = str; 19479 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19480 { 19481 /* 19482 * Get some space for a temporary buffer to do the substitution 19483 * into. It will contain: 19484 * - The text up to where the match is. 19485 * - The substituted text. 19486 * - The text after the match. 19487 */ 19488 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19489 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19490 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19491 { 19492 ga_clear(&ga); 19493 break; 19494 } 19495 19496 /* copy the text up to where the match is */ 19497 i = (int)(regmatch.startp[0] - tail); 19498 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19499 /* add the substituted text */ 19500 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19501 + ga.ga_len + i, TRUE, TRUE, FALSE); 19502 ga.ga_len += i + sublen - 1; 19503 /* avoid getting stuck on a match with an empty string */ 19504 if (tail == regmatch.endp[0]) 19505 { 19506 if (*tail == NUL) 19507 break; 19508 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19509 ++ga.ga_len; 19510 } 19511 else 19512 { 19513 tail = regmatch.endp[0]; 19514 if (*tail == NUL) 19515 break; 19516 } 19517 if (!do_all) 19518 break; 19519 } 19520 19521 if (ga.ga_data != NULL) 19522 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19523 19524 vim_free(regmatch.regprog); 19525 } 19526 19527 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19528 ga_clear(&ga); 19529 p_cpo = save_cpo; 19530 19531 return ret; 19532 } 19533 19534 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19535