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 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 468 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 469 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 558 #ifdef vim_mkdir 559 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 560 #endif 561 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 593 #ifdef HAVE_STRFTIME 594 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 595 #endif 596 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 625 626 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 627 static int get_env_len __ARGS((char_u **arg)); 628 static int get_id_len __ARGS((char_u **arg)); 629 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 630 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 631 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 632 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 633 valid character */ 634 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 635 static int eval_isnamec __ARGS((int c)); 636 static int eval_isnamec1 __ARGS((int c)); 637 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 638 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 639 static typval_T *alloc_tv __ARGS((void)); 640 static typval_T *alloc_string_tv __ARGS((char_u *string)); 641 static void free_tv __ARGS((typval_T *varp)); 642 static void init_tv __ARGS((typval_T *varp)); 643 static long get_tv_number __ARGS((typval_T *varp)); 644 static long get_tv_number_chk __ARGS((typval_T *varp, int *denote)); 645 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 646 static char_u *get_tv_string __ARGS((typval_T *varp)); 647 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 648 static char_u *get_tv_string_chk __ARGS((typval_T *varp)); 649 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 650 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 651 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 652 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 653 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 654 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 655 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 656 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 657 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 658 static int var_check_ro __ARGS((int flags, char_u *name)); 659 static int tv_check_lock __ARGS((int lock, char_u *name)); 660 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 661 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 662 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 663 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 664 static int eval_fname_script __ARGS((char_u *p)); 665 static int eval_fname_sid __ARGS((char_u *p)); 666 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 667 static ufunc_T *find_func __ARGS((char_u *name)); 668 static int function_exists __ARGS((char_u *name)); 669 static int builtin_function __ARGS((char_u *name)); 670 #ifdef FEAT_PROFILE 671 static void func_do_profile __ARGS((ufunc_T *fp)); 672 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 673 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 674 static int 675 # ifdef __BORLANDC__ 676 _RTLENTRYF 677 # endif 678 prof_total_cmp __ARGS((const void *s1, const void *s2)); 679 static int 680 # ifdef __BORLANDC__ 681 _RTLENTRYF 682 # endif 683 prof_self_cmp __ARGS((const void *s1, const void *s2)); 684 #endif 685 static int script_autoload __ARGS((char_u *name, int reload)); 686 static char_u *autoload_name __ARGS((char_u *name)); 687 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 688 static void func_free __ARGS((ufunc_T *fp)); 689 static void func_unref __ARGS((char_u *name)); 690 static void func_ref __ARGS((char_u *name)); 691 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)); 692 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 693 694 /* Character used as separated in autoload function/variable names. */ 695 #define AUTOLOAD_CHAR '#' 696 697 /* 698 * Initialize the global and v: variables. 699 */ 700 void 701 eval_init() 702 { 703 int i; 704 struct vimvar *p; 705 706 init_var_dict(&globvardict, &globvars_var); 707 init_var_dict(&vimvardict, &vimvars_var); 708 hash_init(&compat_hashtab); 709 hash_init(&func_hashtab); 710 711 for (i = 0; i < VV_LEN; ++i) 712 { 713 p = &vimvars[i]; 714 STRCPY(p->vv_di.di_key, p->vv_name); 715 if (p->vv_flags & VV_RO) 716 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 717 else if (p->vv_flags & VV_RO_SBX) 718 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 719 else 720 p->vv_di.di_flags = DI_FLAGS_FIX; 721 722 /* add to v: scope dict, unless the value is not always available */ 723 if (p->vv_type != VAR_UNKNOWN) 724 hash_add(&vimvarht, p->vv_di.di_key); 725 if (p->vv_flags & VV_COMPAT) 726 /* add to compat scope dict */ 727 hash_add(&compat_hashtab, p->vv_di.di_key); 728 } 729 } 730 731 #if defined(EXITFREE) || defined(PROTO) 732 void 733 eval_clear() 734 { 735 int i; 736 struct vimvar *p; 737 738 for (i = 0; i < VV_LEN; ++i) 739 { 740 p = &vimvars[i]; 741 if (p->vv_di.di_tv.v_type == VAR_STRING) 742 { 743 vim_free(p->vv_di.di_tv.vval.v_string); 744 p->vv_di.di_tv.vval.v_string = NULL; 745 } 746 } 747 hash_clear(&vimvarht); 748 hash_clear(&compat_hashtab); 749 750 /* script-local variables */ 751 for (i = 1; i <= ga_scripts.ga_len; ++i) 752 vars_clear(&SCRIPT_VARS(i)); 753 ga_clear(&ga_scripts); 754 free_scriptnames(); 755 756 /* global variables */ 757 vars_clear(&globvarht); 758 759 /* functions */ 760 free_all_functions(); 761 hash_clear(&func_hashtab); 762 763 /* unreferenced lists and dicts */ 764 (void)garbage_collect(); 765 } 766 #endif 767 768 /* 769 * Return the name of the executed function. 770 */ 771 char_u * 772 func_name(cookie) 773 void *cookie; 774 { 775 return ((funccall_T *)cookie)->func->uf_name; 776 } 777 778 /* 779 * Return the address holding the next breakpoint line for a funccall cookie. 780 */ 781 linenr_T * 782 func_breakpoint(cookie) 783 void *cookie; 784 { 785 return &((funccall_T *)cookie)->breakpoint; 786 } 787 788 /* 789 * Return the address holding the debug tick for a funccall cookie. 790 */ 791 int * 792 func_dbg_tick(cookie) 793 void *cookie; 794 { 795 return &((funccall_T *)cookie)->dbg_tick; 796 } 797 798 /* 799 * Return the nesting level for a funccall cookie. 800 */ 801 int 802 func_level(cookie) 803 void *cookie; 804 { 805 return ((funccall_T *)cookie)->level; 806 } 807 808 /* pointer to funccal for currently active function */ 809 funccall_T *current_funccal = NULL; 810 811 /* 812 * Return TRUE when a function was ended by a ":return" command. 813 */ 814 int 815 current_func_returned() 816 { 817 return current_funccal->returned; 818 } 819 820 821 /* 822 * Set an internal variable to a string value. Creates the variable if it does 823 * not already exist. 824 */ 825 void 826 set_internal_string_var(name, value) 827 char_u *name; 828 char_u *value; 829 { 830 char_u *val; 831 typval_T *tvp; 832 833 val = vim_strsave(value); 834 if (val != NULL) 835 { 836 tvp = alloc_string_tv(val); 837 if (tvp != NULL) 838 { 839 set_var(name, tvp, FALSE); 840 free_tv(tvp); 841 } 842 } 843 } 844 845 static lval_T *redir_lval = NULL; 846 static char_u *redir_endp = NULL; 847 static char_u *redir_varname = NULL; 848 849 /* 850 * Start recording command output to a variable 851 * Returns OK if successfully completed the setup. FAIL otherwise. 852 */ 853 int 854 var_redir_start(name, append) 855 char_u *name; 856 int append; /* append to an existing variable */ 857 { 858 int save_emsg; 859 int err; 860 typval_T tv; 861 862 /* Make sure a valid variable name is specified */ 863 if (!eval_isnamec1(*name)) 864 { 865 EMSG(_(e_invarg)); 866 return FAIL; 867 } 868 869 redir_varname = vim_strsave(name); 870 if (redir_varname == NULL) 871 return FAIL; 872 873 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 874 if (redir_lval == NULL) 875 { 876 var_redir_stop(); 877 return FAIL; 878 } 879 880 /* Parse the variable name (can be a dict or list entry). */ 881 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 882 FNE_CHECK_START); 883 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 884 { 885 if (redir_endp != NULL && *redir_endp != NUL) 886 /* Trailing characters are present after the variable name */ 887 EMSG(_(e_trailing)); 888 else 889 EMSG(_(e_invarg)); 890 var_redir_stop(); 891 return FAIL; 892 } 893 894 /* check if we can write to the variable: set it to or append an empty 895 * string */ 896 save_emsg = did_emsg; 897 did_emsg = FALSE; 898 tv.v_type = VAR_STRING; 899 tv.vval.v_string = (char_u *)""; 900 if (append) 901 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 902 else 903 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 904 err = did_emsg; 905 did_emsg += save_emsg; 906 if (err) 907 { 908 var_redir_stop(); 909 return FAIL; 910 } 911 if (redir_lval->ll_newkey != NULL) 912 { 913 /* Dictionary item was created, don't do it again. */ 914 vim_free(redir_lval->ll_newkey); 915 redir_lval->ll_newkey = NULL; 916 } 917 918 return OK; 919 } 920 921 /* 922 * Append "value[len]" to the variable set by var_redir_start(). 923 */ 924 void 925 var_redir_str(value, len) 926 char_u *value; 927 int len; 928 { 929 char_u *val; 930 typval_T tv; 931 int save_emsg; 932 int err; 933 934 if (redir_lval == NULL) 935 return; 936 937 if (len == -1) 938 /* Append the entire string */ 939 val = vim_strsave(value); 940 else 941 /* Append only the specified number of characters */ 942 val = vim_strnsave(value, len); 943 if (val == NULL) 944 return; 945 946 tv.v_type = VAR_STRING; 947 tv.vval.v_string = val; 948 949 save_emsg = did_emsg; 950 did_emsg = FALSE; 951 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 952 err = did_emsg; 953 did_emsg += save_emsg; 954 if (err) 955 var_redir_stop(); 956 957 vim_free(tv.vval.v_string); 958 } 959 960 /* 961 * Stop redirecting command output to a variable. 962 */ 963 void 964 var_redir_stop() 965 { 966 if (redir_lval != NULL) 967 { 968 clear_lval(redir_lval); 969 vim_free(redir_lval); 970 redir_lval = NULL; 971 } 972 vim_free(redir_varname); 973 redir_varname = NULL; 974 } 975 976 # if defined(FEAT_MBYTE) || defined(PROTO) 977 int 978 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 979 char_u *enc_from; 980 char_u *enc_to; 981 char_u *fname_from; 982 char_u *fname_to; 983 { 984 int err = FALSE; 985 986 set_vim_var_string(VV_CC_FROM, enc_from, -1); 987 set_vim_var_string(VV_CC_TO, enc_to, -1); 988 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 989 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 990 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 991 err = TRUE; 992 set_vim_var_string(VV_CC_FROM, NULL, -1); 993 set_vim_var_string(VV_CC_TO, NULL, -1); 994 set_vim_var_string(VV_FNAME_IN, NULL, -1); 995 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 996 997 if (err) 998 return FAIL; 999 return OK; 1000 } 1001 # endif 1002 1003 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1004 int 1005 eval_printexpr(fname, args) 1006 char_u *fname; 1007 char_u *args; 1008 { 1009 int err = FALSE; 1010 1011 set_vim_var_string(VV_FNAME_IN, fname, -1); 1012 set_vim_var_string(VV_CMDARG, args, -1); 1013 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1014 err = TRUE; 1015 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1016 set_vim_var_string(VV_CMDARG, NULL, -1); 1017 1018 if (err) 1019 { 1020 mch_remove(fname); 1021 return FAIL; 1022 } 1023 return OK; 1024 } 1025 # endif 1026 1027 # if defined(FEAT_DIFF) || defined(PROTO) 1028 void 1029 eval_diff(origfile, newfile, outfile) 1030 char_u *origfile; 1031 char_u *newfile; 1032 char_u *outfile; 1033 { 1034 int err = FALSE; 1035 1036 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1037 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1038 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1039 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1040 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1041 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1042 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1043 } 1044 1045 void 1046 eval_patch(origfile, difffile, outfile) 1047 char_u *origfile; 1048 char_u *difffile; 1049 char_u *outfile; 1050 { 1051 int err; 1052 1053 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1054 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1055 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1056 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1057 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1058 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1059 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1060 } 1061 # endif 1062 1063 /* 1064 * Top level evaluation function, returning a boolean. 1065 * Sets "error" to TRUE if there was an error. 1066 * Return TRUE or FALSE. 1067 */ 1068 int 1069 eval_to_bool(arg, error, nextcmd, skip) 1070 char_u *arg; 1071 int *error; 1072 char_u **nextcmd; 1073 int skip; /* only parse, don't execute */ 1074 { 1075 typval_T tv; 1076 int retval = FALSE; 1077 1078 if (skip) 1079 ++emsg_skip; 1080 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1081 *error = TRUE; 1082 else 1083 { 1084 *error = FALSE; 1085 if (!skip) 1086 { 1087 retval = (get_tv_number_chk(&tv, error) != 0); 1088 clear_tv(&tv); 1089 } 1090 } 1091 if (skip) 1092 --emsg_skip; 1093 1094 return retval; 1095 } 1096 1097 /* 1098 * Top level evaluation function, returning a string. If "skip" is TRUE, 1099 * only parsing to "nextcmd" is done, without reporting errors. Return 1100 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1101 */ 1102 char_u * 1103 eval_to_string_skip(arg, nextcmd, skip) 1104 char_u *arg; 1105 char_u **nextcmd; 1106 int skip; /* only parse, don't execute */ 1107 { 1108 typval_T tv; 1109 char_u *retval; 1110 1111 if (skip) 1112 ++emsg_skip; 1113 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1114 retval = NULL; 1115 else 1116 { 1117 retval = vim_strsave(get_tv_string(&tv)); 1118 clear_tv(&tv); 1119 } 1120 if (skip) 1121 --emsg_skip; 1122 1123 return retval; 1124 } 1125 1126 /* 1127 * Skip over an expression at "*pp". 1128 * Return FAIL for an error, OK otherwise. 1129 */ 1130 int 1131 skip_expr(pp) 1132 char_u **pp; 1133 { 1134 typval_T rettv; 1135 1136 *pp = skipwhite(*pp); 1137 return eval1(pp, &rettv, FALSE); 1138 } 1139 1140 /* 1141 * Top level evaluation function, returning a string. 1142 * Return pointer to allocated memory, or NULL for failure. 1143 */ 1144 char_u * 1145 eval_to_string(arg, nextcmd) 1146 char_u *arg; 1147 char_u **nextcmd; 1148 { 1149 typval_T tv; 1150 char_u *retval; 1151 1152 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1153 retval = NULL; 1154 else 1155 { 1156 retval = vim_strsave(get_tv_string(&tv)); 1157 clear_tv(&tv); 1158 } 1159 1160 return retval; 1161 } 1162 1163 /* 1164 * Call eval_to_string() with "sandbox" set and not using local variables. 1165 */ 1166 char_u * 1167 eval_to_string_safe(arg, nextcmd) 1168 char_u *arg; 1169 char_u **nextcmd; 1170 { 1171 char_u *retval; 1172 void *save_funccalp; 1173 1174 save_funccalp = save_funccal(); 1175 ++sandbox; 1176 retval = eval_to_string(arg, nextcmd); 1177 --sandbox; 1178 restore_funccal(save_funccalp); 1179 return retval; 1180 } 1181 1182 /* 1183 * Top level evaluation function, returning a number. 1184 * Evaluates "expr" silently. 1185 * Returns -1 for an error. 1186 */ 1187 int 1188 eval_to_number(expr) 1189 char_u *expr; 1190 { 1191 typval_T rettv; 1192 int retval; 1193 char_u *p = skipwhite(expr); 1194 1195 ++emsg_off; 1196 1197 if (eval1(&p, &rettv, TRUE) == FAIL) 1198 retval = -1; 1199 else 1200 { 1201 retval = get_tv_number_chk(&rettv, NULL); 1202 clear_tv(&rettv); 1203 } 1204 --emsg_off; 1205 1206 return retval; 1207 } 1208 1209 /* 1210 * Prepare v: variable "idx" to be used. 1211 * Save the current typeval in "save_tv". 1212 * When not used yet add the variable to the v: hashtable. 1213 */ 1214 static void 1215 prepare_vimvar(idx, save_tv) 1216 int idx; 1217 typval_T *save_tv; 1218 { 1219 *save_tv = vimvars[idx].vv_tv; 1220 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1221 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1222 } 1223 1224 /* 1225 * Restore v: variable "idx" to typeval "save_tv". 1226 * When no longer defined, remove the variable from the v: hashtable. 1227 */ 1228 static void 1229 restore_vimvar(idx, save_tv) 1230 int idx; 1231 typval_T *save_tv; 1232 { 1233 hashitem_T *hi; 1234 1235 clear_tv(&vimvars[idx].vv_tv); 1236 vimvars[idx].vv_tv = *save_tv; 1237 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1238 { 1239 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1240 if (HASHITEM_EMPTY(hi)) 1241 EMSG2(_(e_intern2), "restore_vimvar()"); 1242 else 1243 hash_remove(&vimvarht, hi); 1244 } 1245 } 1246 1247 #if defined(FEAT_SYN_HL) || defined(PROTO) 1248 /* 1249 * Evaluate an expression to a list with suggestions. 1250 * For the "expr:" part of 'spellsuggest'. 1251 */ 1252 list_T * 1253 eval_spell_expr(badword, expr) 1254 char_u *badword; 1255 char_u *expr; 1256 { 1257 typval_T save_val; 1258 typval_T rettv; 1259 list_T *list = NULL; 1260 char_u *p = skipwhite(expr); 1261 1262 /* Set "v:val" to the bad word. */ 1263 prepare_vimvar(VV_VAL, &save_val); 1264 vimvars[VV_VAL].vv_type = VAR_STRING; 1265 vimvars[VV_VAL].vv_str = badword; 1266 if (p_verbose == 0) 1267 ++emsg_off; 1268 1269 if (eval1(&p, &rettv, TRUE) == OK) 1270 { 1271 if (rettv.v_type != VAR_LIST) 1272 clear_tv(&rettv); 1273 else 1274 list = rettv.vval.v_list; 1275 } 1276 1277 if (p_verbose == 0) 1278 --emsg_off; 1279 vimvars[VV_VAL].vv_str = NULL; 1280 restore_vimvar(VV_VAL, &save_val); 1281 1282 return list; 1283 } 1284 1285 /* 1286 * "list" is supposed to contain two items: a word and a number. Return the 1287 * word in "pp" and the number as the return value. 1288 * Return -1 if anything isn't right. 1289 * Used to get the good word and score from the eval_spell_expr() result. 1290 */ 1291 int 1292 get_spellword(list, pp) 1293 list_T *list; 1294 char_u **pp; 1295 { 1296 listitem_T *li; 1297 1298 li = list->lv_first; 1299 if (li == NULL) 1300 return -1; 1301 *pp = get_tv_string(&li->li_tv); 1302 1303 li = li->li_next; 1304 if (li == NULL) 1305 return -1; 1306 return get_tv_number(&li->li_tv); 1307 } 1308 #endif 1309 1310 /* 1311 * Top level evaluation function, 1312 */ 1313 typval_T * 1314 eval_expr(arg, nextcmd) 1315 char_u *arg; 1316 char_u **nextcmd; 1317 { 1318 typval_T *tv; 1319 1320 tv = (typval_T *)alloc(sizeof(typval_T)); 1321 if (!tv) 1322 return NULL; 1323 1324 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1325 { 1326 vim_free(tv); 1327 return NULL; 1328 } 1329 1330 return tv; 1331 } 1332 1333 1334 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1335 /* 1336 * Call some vimL function and return the result in "*rettv". 1337 * Uses argv[argc] for the function arguments. 1338 * Returns OK or FAIL. 1339 */ 1340 static int 1341 call_vim_function(func, argc, argv, safe, rettv) 1342 char_u *func; 1343 int argc; 1344 char_u **argv; 1345 int safe; /* use the sandbox */ 1346 typval_T *rettv; 1347 { 1348 typval_T *argvars; 1349 long n; 1350 int len; 1351 int i; 1352 int doesrange; 1353 void *save_funccalp = NULL; 1354 int ret; 1355 1356 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1357 if (argvars == NULL) 1358 return FAIL; 1359 1360 for (i = 0; i < argc; i++) 1361 { 1362 /* Pass a NULL or empty argument as an empty string */ 1363 if (argv[i] == NULL || *argv[i] == NUL) 1364 { 1365 argvars[i].v_type = VAR_STRING; 1366 argvars[i].vval.v_string = (char_u *)""; 1367 continue; 1368 } 1369 1370 /* Recognize a number argument, the others must be strings. */ 1371 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1372 if (len != 0 && len == (int)STRLEN(argv[i])) 1373 { 1374 argvars[i].v_type = VAR_NUMBER; 1375 argvars[i].vval.v_number = n; 1376 } 1377 else 1378 { 1379 argvars[i].v_type = VAR_STRING; 1380 argvars[i].vval.v_string = argv[i]; 1381 } 1382 } 1383 1384 if (safe) 1385 { 1386 save_funccalp = save_funccal(); 1387 ++sandbox; 1388 } 1389 1390 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1391 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1392 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1393 &doesrange, TRUE, NULL); 1394 if (safe) 1395 { 1396 --sandbox; 1397 restore_funccal(save_funccalp); 1398 } 1399 vim_free(argvars); 1400 1401 if (ret == FAIL) 1402 clear_tv(rettv); 1403 1404 return ret; 1405 } 1406 1407 /* 1408 * Call some vimL function and return the result as a string 1409 * Uses argv[argc] for the function arguments. 1410 */ 1411 void * 1412 call_func_retstr(func, argc, argv, safe) 1413 char_u *func; 1414 int argc; 1415 char_u **argv; 1416 int safe; /* use the sandbox */ 1417 { 1418 typval_T rettv; 1419 char_u *retval = NULL; 1420 1421 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1422 return NULL; 1423 1424 retval = vim_strsave(get_tv_string(&rettv)); 1425 1426 clear_tv(&rettv); 1427 1428 return retval; 1429 } 1430 1431 /* 1432 * Call some vimL function and return the result as a list 1433 * Uses argv[argc] for the function arguments. 1434 */ 1435 void * 1436 call_func_retlist(func, argc, argv, safe) 1437 char_u *func; 1438 int argc; 1439 char_u **argv; 1440 int safe; /* use the sandbox */ 1441 { 1442 typval_T rettv; 1443 1444 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1445 return NULL; 1446 1447 if (rettv.v_type != VAR_LIST) 1448 { 1449 clear_tv(&rettv); 1450 return NULL; 1451 } 1452 1453 return rettv.vval.v_list; 1454 } 1455 1456 #endif 1457 1458 /* 1459 * Save the current function call pointer, and set it to NULL. 1460 * Used when executing autocommands and for ":source". 1461 */ 1462 void * 1463 save_funccal() 1464 { 1465 funccall_T *fc = current_funccal; 1466 1467 current_funccal = NULL; 1468 return (void *)fc; 1469 } 1470 1471 void 1472 restore_funccal(vfc) 1473 void *vfc; 1474 { 1475 funccall_T *fc = (funccall_T *)vfc; 1476 1477 current_funccal = fc; 1478 } 1479 1480 #if defined(FEAT_PROFILE) || defined(PROTO) 1481 /* 1482 * Prepare profiling for entering a child or something else that is not 1483 * counted for the script/function itself. 1484 * Should always be called in pair with prof_child_exit(). 1485 */ 1486 void 1487 prof_child_enter(tm) 1488 proftime_T *tm; /* place to store waittime */ 1489 { 1490 funccall_T *fc = current_funccal; 1491 1492 if (fc != NULL && fc->func->uf_profiling) 1493 profile_start(&fc->prof_child); 1494 script_prof_save(tm); 1495 } 1496 1497 /* 1498 * Take care of time spent in a child. 1499 * Should always be called after prof_child_enter(). 1500 */ 1501 void 1502 prof_child_exit(tm) 1503 proftime_T *tm; /* where waittime was stored */ 1504 { 1505 funccall_T *fc = current_funccal; 1506 1507 if (fc != NULL && fc->func->uf_profiling) 1508 { 1509 profile_end(&fc->prof_child); 1510 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1511 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1512 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1513 } 1514 script_prof_restore(tm); 1515 } 1516 #endif 1517 1518 1519 #ifdef FEAT_FOLDING 1520 /* 1521 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1522 * it in "*cp". Doesn't give error messages. 1523 */ 1524 int 1525 eval_foldexpr(arg, cp) 1526 char_u *arg; 1527 int *cp; 1528 { 1529 typval_T tv; 1530 int retval; 1531 char_u *s; 1532 1533 ++emsg_off; 1534 ++sandbox; 1535 *cp = NUL; 1536 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1537 retval = 0; 1538 else 1539 { 1540 /* If the result is a number, just return the number. */ 1541 if (tv.v_type == VAR_NUMBER) 1542 retval = tv.vval.v_number; 1543 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1544 retval = 0; 1545 else 1546 { 1547 /* If the result is a string, check if there is a non-digit before 1548 * the number. */ 1549 s = tv.vval.v_string; 1550 if (!VIM_ISDIGIT(*s) && *s != '-') 1551 *cp = *s++; 1552 retval = atol((char *)s); 1553 } 1554 clear_tv(&tv); 1555 } 1556 --emsg_off; 1557 --sandbox; 1558 1559 return retval; 1560 } 1561 #endif 1562 1563 /* 1564 * ":let" list all variable values 1565 * ":let var1 var2" list variable values 1566 * ":let var = expr" assignment command. 1567 * ":let var += expr" assignment command. 1568 * ":let var -= expr" assignment command. 1569 * ":let var .= expr" assignment command. 1570 * ":let [var1, var2] = expr" unpack list. 1571 */ 1572 void 1573 ex_let(eap) 1574 exarg_T *eap; 1575 { 1576 char_u *arg = eap->arg; 1577 char_u *expr = NULL; 1578 typval_T rettv; 1579 int i; 1580 int var_count = 0; 1581 int semicolon = 0; 1582 char_u op[2]; 1583 1584 expr = skip_var_list(arg, &var_count, &semicolon); 1585 if (expr == NULL) 1586 return; 1587 expr = vim_strchr(expr, '='); 1588 if (expr == NULL) 1589 { 1590 /* 1591 * ":let" without "=": list variables 1592 */ 1593 if (*arg == '[') 1594 EMSG(_(e_invarg)); 1595 else if (!ends_excmd(*arg)) 1596 /* ":let var1 var2" */ 1597 arg = list_arg_vars(eap, arg); 1598 else if (!eap->skip) 1599 { 1600 /* ":let" */ 1601 list_glob_vars(); 1602 list_buf_vars(); 1603 list_win_vars(); 1604 list_vim_vars(); 1605 } 1606 eap->nextcmd = check_nextcmd(arg); 1607 } 1608 else 1609 { 1610 op[0] = '='; 1611 op[1] = NUL; 1612 if (expr > arg) 1613 { 1614 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1615 op[0] = expr[-1]; /* +=, -= or .= */ 1616 } 1617 expr = skipwhite(expr + 1); 1618 1619 if (eap->skip) 1620 ++emsg_skip; 1621 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1622 if (eap->skip) 1623 { 1624 if (i != FAIL) 1625 clear_tv(&rettv); 1626 --emsg_skip; 1627 } 1628 else if (i != FAIL) 1629 { 1630 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1631 op); 1632 clear_tv(&rettv); 1633 } 1634 } 1635 } 1636 1637 /* 1638 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1639 * Handles both "var" with any type and "[var, var; var]" with a list type. 1640 * When "nextchars" is not NULL it points to a string with characters that 1641 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1642 * or concatenate. 1643 * Returns OK or FAIL; 1644 */ 1645 static int 1646 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1647 char_u *arg_start; 1648 typval_T *tv; 1649 int copy; /* copy values from "tv", don't move */ 1650 int semicolon; /* from skip_var_list() */ 1651 int var_count; /* from skip_var_list() */ 1652 char_u *nextchars; 1653 { 1654 char_u *arg = arg_start; 1655 list_T *l; 1656 int i; 1657 listitem_T *item; 1658 typval_T ltv; 1659 1660 if (*arg != '[') 1661 { 1662 /* 1663 * ":let var = expr" or ":for var in list" 1664 */ 1665 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1666 return FAIL; 1667 return OK; 1668 } 1669 1670 /* 1671 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1672 */ 1673 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1674 { 1675 EMSG(_(e_listreq)); 1676 return FAIL; 1677 } 1678 1679 i = list_len(l); 1680 if (semicolon == 0 && var_count < i) 1681 { 1682 EMSG(_("E687: Less targets than List items")); 1683 return FAIL; 1684 } 1685 if (var_count - semicolon > i) 1686 { 1687 EMSG(_("E688: More targets than List items")); 1688 return FAIL; 1689 } 1690 1691 item = l->lv_first; 1692 while (*arg != ']') 1693 { 1694 arg = skipwhite(arg + 1); 1695 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1696 item = item->li_next; 1697 if (arg == NULL) 1698 return FAIL; 1699 1700 arg = skipwhite(arg); 1701 if (*arg == ';') 1702 { 1703 /* Put the rest of the list (may be empty) in the var after ';'. 1704 * Create a new list for this. */ 1705 l = list_alloc(); 1706 if (l == NULL) 1707 return FAIL; 1708 while (item != NULL) 1709 { 1710 list_append_tv(l, &item->li_tv); 1711 item = item->li_next; 1712 } 1713 1714 ltv.v_type = VAR_LIST; 1715 ltv.v_lock = 0; 1716 ltv.vval.v_list = l; 1717 l->lv_refcount = 1; 1718 1719 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1720 (char_u *)"]", nextchars); 1721 clear_tv(<v); 1722 if (arg == NULL) 1723 return FAIL; 1724 break; 1725 } 1726 else if (*arg != ',' && *arg != ']') 1727 { 1728 EMSG2(_(e_intern2), "ex_let_vars()"); 1729 return FAIL; 1730 } 1731 } 1732 1733 return OK; 1734 } 1735 1736 /* 1737 * Skip over assignable variable "var" or list of variables "[var, var]". 1738 * Used for ":let varvar = expr" and ":for varvar in expr". 1739 * For "[var, var]" increment "*var_count" for each variable. 1740 * for "[var, var; var]" set "semicolon". 1741 * Return NULL for an error. 1742 */ 1743 static char_u * 1744 skip_var_list(arg, var_count, semicolon) 1745 char_u *arg; 1746 int *var_count; 1747 int *semicolon; 1748 { 1749 char_u *p, *s; 1750 1751 if (*arg == '[') 1752 { 1753 /* "[var, var]": find the matching ']'. */ 1754 p = arg; 1755 for (;;) 1756 { 1757 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1758 s = skip_var_one(p); 1759 if (s == p) 1760 { 1761 EMSG2(_(e_invarg2), p); 1762 return NULL; 1763 } 1764 ++*var_count; 1765 1766 p = skipwhite(s); 1767 if (*p == ']') 1768 break; 1769 else if (*p == ';') 1770 { 1771 if (*semicolon == 1) 1772 { 1773 EMSG(_("Double ; in list of variables")); 1774 return NULL; 1775 } 1776 *semicolon = 1; 1777 } 1778 else if (*p != ',') 1779 { 1780 EMSG2(_(e_invarg2), p); 1781 return NULL; 1782 } 1783 } 1784 return p + 1; 1785 } 1786 else 1787 return skip_var_one(arg); 1788 } 1789 1790 /* 1791 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1792 * l[idx]. 1793 */ 1794 static char_u * 1795 skip_var_one(arg) 1796 char_u *arg; 1797 { 1798 if (*arg == '@' && arg[1] != NUL) 1799 return arg + 2; 1800 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1801 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1802 } 1803 1804 /* 1805 * List variables for hashtab "ht" with prefix "prefix". 1806 * If "empty" is TRUE also list NULL strings as empty strings. 1807 */ 1808 static void 1809 list_hashtable_vars(ht, prefix, empty) 1810 hashtab_T *ht; 1811 char_u *prefix; 1812 int empty; 1813 { 1814 hashitem_T *hi; 1815 dictitem_T *di; 1816 int todo; 1817 1818 todo = ht->ht_used; 1819 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1820 { 1821 if (!HASHITEM_EMPTY(hi)) 1822 { 1823 --todo; 1824 di = HI2DI(hi); 1825 if (empty || di->di_tv.v_type != VAR_STRING 1826 || di->di_tv.vval.v_string != NULL) 1827 list_one_var(di, prefix); 1828 } 1829 } 1830 } 1831 1832 /* 1833 * List global variables. 1834 */ 1835 static void 1836 list_glob_vars() 1837 { 1838 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1839 } 1840 1841 /* 1842 * List buffer variables. 1843 */ 1844 static void 1845 list_buf_vars() 1846 { 1847 char_u numbuf[NUMBUFLEN]; 1848 1849 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1850 1851 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1852 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1853 } 1854 1855 /* 1856 * List window variables. 1857 */ 1858 static void 1859 list_win_vars() 1860 { 1861 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1862 } 1863 1864 /* 1865 * List Vim variables. 1866 */ 1867 static void 1868 list_vim_vars() 1869 { 1870 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1871 } 1872 1873 /* 1874 * List variables in "arg". 1875 */ 1876 static char_u * 1877 list_arg_vars(eap, arg) 1878 exarg_T *eap; 1879 char_u *arg; 1880 { 1881 int error = FALSE; 1882 int len; 1883 char_u *name; 1884 char_u *name_start; 1885 char_u *arg_subsc; 1886 char_u *tofree; 1887 typval_T tv; 1888 1889 while (!ends_excmd(*arg) && !got_int) 1890 { 1891 if (error || eap->skip) 1892 { 1893 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1894 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1895 { 1896 emsg_severe = TRUE; 1897 EMSG(_(e_trailing)); 1898 break; 1899 } 1900 } 1901 else 1902 { 1903 /* get_name_len() takes care of expanding curly braces */ 1904 name_start = name = arg; 1905 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1906 if (len <= 0) 1907 { 1908 /* This is mainly to keep test 49 working: when expanding 1909 * curly braces fails overrule the exception error message. */ 1910 if (len < 0 && !aborting()) 1911 { 1912 emsg_severe = TRUE; 1913 EMSG2(_(e_invarg2), arg); 1914 break; 1915 } 1916 error = TRUE; 1917 } 1918 else 1919 { 1920 if (tofree != NULL) 1921 name = tofree; 1922 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1923 error = TRUE; 1924 else 1925 { 1926 /* handle d.key, l[idx], f(expr) */ 1927 arg_subsc = arg; 1928 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1929 error = TRUE; 1930 else 1931 { 1932 if (arg == arg_subsc && len == 2 && name[1] == ':') 1933 { 1934 switch (*name) 1935 { 1936 case 'g': list_glob_vars(); break; 1937 case 'b': list_buf_vars(); break; 1938 case 'w': list_win_vars(); break; 1939 case 'v': list_vim_vars(); break; 1940 default: 1941 EMSG2(_("E738: Can't list variables for %s"), name); 1942 } 1943 } 1944 else 1945 { 1946 char_u numbuf[NUMBUFLEN]; 1947 char_u *tf; 1948 int c; 1949 char_u *s; 1950 1951 s = echo_string(&tv, &tf, numbuf); 1952 c = *arg; 1953 *arg = NUL; 1954 list_one_var_a((char_u *)"", 1955 arg == arg_subsc ? name : name_start, 1956 tv.v_type, s == NULL ? (char_u *)"" : s); 1957 *arg = c; 1958 vim_free(tf); 1959 } 1960 clear_tv(&tv); 1961 } 1962 } 1963 } 1964 1965 vim_free(tofree); 1966 } 1967 1968 arg = skipwhite(arg); 1969 } 1970 1971 return arg; 1972 } 1973 1974 /* 1975 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 1976 * Returns a pointer to the char just after the var name. 1977 * Returns NULL if there is an error. 1978 */ 1979 static char_u * 1980 ex_let_one(arg, tv, copy, endchars, op) 1981 char_u *arg; /* points to variable name */ 1982 typval_T *tv; /* value to assign to variable */ 1983 int copy; /* copy value from "tv" */ 1984 char_u *endchars; /* valid chars after variable name or NULL */ 1985 char_u *op; /* "+", "-", "." or NULL*/ 1986 { 1987 int c1; 1988 char_u *name; 1989 char_u *p; 1990 char_u *arg_end = NULL; 1991 int len; 1992 int opt_flags; 1993 char_u *tofree = NULL; 1994 1995 /* 1996 * ":let $VAR = expr": Set environment variable. 1997 */ 1998 if (*arg == '$') 1999 { 2000 /* Find the end of the name. */ 2001 ++arg; 2002 name = arg; 2003 len = get_env_len(&arg); 2004 if (len == 0) 2005 EMSG2(_(e_invarg2), name - 1); 2006 else 2007 { 2008 if (op != NULL && (*op == '+' || *op == '-')) 2009 EMSG2(_(e_letwrong), op); 2010 else if (endchars != NULL 2011 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2012 EMSG(_(e_letunexp)); 2013 else 2014 { 2015 c1 = name[len]; 2016 name[len] = NUL; 2017 p = get_tv_string_chk(tv); 2018 if (p != NULL && op != NULL && *op == '.') 2019 { 2020 int mustfree = FALSE; 2021 char_u *s = vim_getenv(name, &mustfree); 2022 2023 if (s != NULL) 2024 { 2025 p = tofree = concat_str(s, p); 2026 if (mustfree) 2027 vim_free(s); 2028 } 2029 } 2030 if (p != NULL) 2031 { 2032 vim_setenv(name, p); 2033 if (STRICMP(name, "HOME") == 0) 2034 init_homedir(); 2035 else if (didset_vim && STRICMP(name, "VIM") == 0) 2036 didset_vim = FALSE; 2037 else if (didset_vimruntime 2038 && STRICMP(name, "VIMRUNTIME") == 0) 2039 didset_vimruntime = FALSE; 2040 arg_end = arg; 2041 } 2042 name[len] = c1; 2043 vim_free(tofree); 2044 } 2045 } 2046 } 2047 2048 /* 2049 * ":let &option = expr": Set option value. 2050 * ":let &l:option = expr": Set local option value. 2051 * ":let &g:option = expr": Set global option value. 2052 */ 2053 else if (*arg == '&') 2054 { 2055 /* Find the end of the name. */ 2056 p = find_option_end(&arg, &opt_flags); 2057 if (p == NULL || (endchars != NULL 2058 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2059 EMSG(_(e_letunexp)); 2060 else 2061 { 2062 long n; 2063 int opt_type; 2064 long numval; 2065 char_u *stringval = NULL; 2066 char_u *s; 2067 2068 c1 = *p; 2069 *p = NUL; 2070 2071 n = get_tv_number(tv); 2072 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2073 if (s != NULL && op != NULL && *op != '=') 2074 { 2075 opt_type = get_option_value(arg, &numval, 2076 &stringval, opt_flags); 2077 if ((opt_type == 1 && *op == '.') 2078 || (opt_type == 0 && *op != '.')) 2079 EMSG2(_(e_letwrong), op); 2080 else 2081 { 2082 if (opt_type == 1) /* number */ 2083 { 2084 if (*op == '+') 2085 n = numval + n; 2086 else 2087 n = numval - n; 2088 } 2089 else if (opt_type == 0 && stringval != NULL) /* string */ 2090 { 2091 s = concat_str(stringval, s); 2092 vim_free(stringval); 2093 stringval = s; 2094 } 2095 } 2096 } 2097 if (s != NULL) 2098 { 2099 set_option_value(arg, n, s, opt_flags); 2100 arg_end = p; 2101 } 2102 *p = c1; 2103 vim_free(stringval); 2104 } 2105 } 2106 2107 /* 2108 * ":let @r = expr": Set register contents. 2109 */ 2110 else if (*arg == '@') 2111 { 2112 ++arg; 2113 if (op != NULL && (*op == '+' || *op == '-')) 2114 EMSG2(_(e_letwrong), op); 2115 else if (endchars != NULL 2116 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2117 EMSG(_(e_letunexp)); 2118 else 2119 { 2120 char_u *tofree = NULL; 2121 char_u *s; 2122 2123 p = get_tv_string_chk(tv); 2124 if (p != NULL && op != NULL && *op == '.') 2125 { 2126 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2127 if (s != NULL) 2128 { 2129 p = tofree = concat_str(s, p); 2130 vim_free(s); 2131 } 2132 } 2133 if (p != NULL) 2134 { 2135 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2136 arg_end = arg + 1; 2137 } 2138 vim_free(tofree); 2139 } 2140 } 2141 2142 /* 2143 * ":let var = expr": Set internal variable. 2144 * ":let {expr} = expr": Idem, name made with curly braces 2145 */ 2146 else if (eval_isnamec1(*arg) || *arg == '{') 2147 { 2148 lval_T lv; 2149 2150 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2151 if (p != NULL && lv.ll_name != NULL) 2152 { 2153 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2154 EMSG(_(e_letunexp)); 2155 else 2156 { 2157 set_var_lval(&lv, p, tv, copy, op); 2158 arg_end = p; 2159 } 2160 } 2161 clear_lval(&lv); 2162 } 2163 2164 else 2165 EMSG2(_(e_invarg2), arg); 2166 2167 return arg_end; 2168 } 2169 2170 /* 2171 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2172 */ 2173 static int 2174 check_changedtick(arg) 2175 char_u *arg; 2176 { 2177 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2178 { 2179 EMSG2(_(e_readonlyvar), arg); 2180 return TRUE; 2181 } 2182 return FALSE; 2183 } 2184 2185 /* 2186 * Get an lval: variable, Dict item or List item that can be assigned a value 2187 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2188 * "name.key", "name.key[expr]" etc. 2189 * Indexing only works if "name" is an existing List or Dictionary. 2190 * "name" points to the start of the name. 2191 * If "rettv" is not NULL it points to the value to be assigned. 2192 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2193 * wrong; must end in space or cmd separator. 2194 * 2195 * Returns a pointer to just after the name, including indexes. 2196 * When an evaluation error occurs "lp->ll_name" is NULL; 2197 * Returns NULL for a parsing error. Still need to free items in "lp"! 2198 */ 2199 static char_u * 2200 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2201 char_u *name; 2202 typval_T *rettv; 2203 lval_T *lp; 2204 int unlet; 2205 int skip; 2206 int quiet; /* don't give error messages */ 2207 int fne_flags; /* flags for find_name_end() */ 2208 { 2209 char_u *p; 2210 char_u *expr_start, *expr_end; 2211 int cc; 2212 dictitem_T *v; 2213 typval_T var1; 2214 typval_T var2; 2215 int empty1 = FALSE; 2216 listitem_T *ni; 2217 char_u *key = NULL; 2218 int len; 2219 hashtab_T *ht; 2220 2221 /* Clear everything in "lp". */ 2222 vim_memset(lp, 0, sizeof(lval_T)); 2223 2224 if (skip) 2225 { 2226 /* When skipping just find the end of the name. */ 2227 lp->ll_name = name; 2228 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2229 } 2230 2231 /* Find the end of the name. */ 2232 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2233 if (expr_start != NULL) 2234 { 2235 /* Don't expand the name when we already know there is an error. */ 2236 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2237 && *p != '[' && *p != '.') 2238 { 2239 EMSG(_(e_trailing)); 2240 return NULL; 2241 } 2242 2243 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2244 if (lp->ll_exp_name == NULL) 2245 { 2246 /* Report an invalid expression in braces, unless the 2247 * expression evaluation has been cancelled due to an 2248 * aborting error, an interrupt, or an exception. */ 2249 if (!aborting() && !quiet) 2250 { 2251 emsg_severe = TRUE; 2252 EMSG2(_(e_invarg2), name); 2253 return NULL; 2254 } 2255 } 2256 lp->ll_name = lp->ll_exp_name; 2257 } 2258 else 2259 lp->ll_name = name; 2260 2261 /* Without [idx] or .key we are done. */ 2262 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2263 return p; 2264 2265 cc = *p; 2266 *p = NUL; 2267 v = find_var(lp->ll_name, &ht); 2268 if (v == NULL && !quiet) 2269 EMSG2(_(e_undefvar), lp->ll_name); 2270 *p = cc; 2271 if (v == NULL) 2272 return NULL; 2273 2274 /* 2275 * Loop until no more [idx] or .key is following. 2276 */ 2277 lp->ll_tv = &v->di_tv; 2278 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2279 { 2280 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2281 && !(lp->ll_tv->v_type == VAR_DICT 2282 && lp->ll_tv->vval.v_dict != NULL)) 2283 { 2284 if (!quiet) 2285 EMSG(_("E689: Can only index a List or Dictionary")); 2286 return NULL; 2287 } 2288 if (lp->ll_range) 2289 { 2290 if (!quiet) 2291 EMSG(_("E708: [:] must come last")); 2292 return NULL; 2293 } 2294 2295 len = -1; 2296 if (*p == '.') 2297 { 2298 key = p + 1; 2299 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2300 ; 2301 if (len == 0) 2302 { 2303 if (!quiet) 2304 EMSG(_(e_emptykey)); 2305 return NULL; 2306 } 2307 p = key + len; 2308 } 2309 else 2310 { 2311 /* Get the index [expr] or the first index [expr: ]. */ 2312 p = skipwhite(p + 1); 2313 if (*p == ':') 2314 empty1 = TRUE; 2315 else 2316 { 2317 empty1 = FALSE; 2318 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2319 return NULL; 2320 if (get_tv_string_chk(&var1) == NULL) 2321 { 2322 /* not a number or string */ 2323 clear_tv(&var1); 2324 return NULL; 2325 } 2326 } 2327 2328 /* Optionally get the second index [ :expr]. */ 2329 if (*p == ':') 2330 { 2331 if (lp->ll_tv->v_type == VAR_DICT) 2332 { 2333 if (!quiet) 2334 EMSG(_(e_dictrange)); 2335 if (!empty1) 2336 clear_tv(&var1); 2337 return NULL; 2338 } 2339 if (rettv != NULL && (rettv->v_type != VAR_LIST 2340 || rettv->vval.v_list == NULL)) 2341 { 2342 if (!quiet) 2343 EMSG(_("E709: [:] requires a List value")); 2344 if (!empty1) 2345 clear_tv(&var1); 2346 return NULL; 2347 } 2348 p = skipwhite(p + 1); 2349 if (*p == ']') 2350 lp->ll_empty2 = TRUE; 2351 else 2352 { 2353 lp->ll_empty2 = FALSE; 2354 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2355 { 2356 if (!empty1) 2357 clear_tv(&var1); 2358 return NULL; 2359 } 2360 if (get_tv_string_chk(&var2) == NULL) 2361 { 2362 /* not a number or string */ 2363 if (!empty1) 2364 clear_tv(&var1); 2365 clear_tv(&var2); 2366 return NULL; 2367 } 2368 } 2369 lp->ll_range = TRUE; 2370 } 2371 else 2372 lp->ll_range = FALSE; 2373 2374 if (*p != ']') 2375 { 2376 if (!quiet) 2377 EMSG(_(e_missbrac)); 2378 if (!empty1) 2379 clear_tv(&var1); 2380 if (lp->ll_range && !lp->ll_empty2) 2381 clear_tv(&var2); 2382 return NULL; 2383 } 2384 2385 /* Skip to past ']'. */ 2386 ++p; 2387 } 2388 2389 if (lp->ll_tv->v_type == VAR_DICT) 2390 { 2391 if (len == -1) 2392 { 2393 /* "[key]": get key from "var1" */ 2394 key = get_tv_string(&var1); /* is number or string */ 2395 if (*key == NUL) 2396 { 2397 if (!quiet) 2398 EMSG(_(e_emptykey)); 2399 clear_tv(&var1); 2400 return NULL; 2401 } 2402 } 2403 lp->ll_list = NULL; 2404 lp->ll_dict = lp->ll_tv->vval.v_dict; 2405 lp->ll_di = dict_find(lp->ll_dict, key, len); 2406 if (lp->ll_di == NULL) 2407 { 2408 /* Key does not exist in dict: may need to add it. */ 2409 if (*p == '[' || *p == '.' || unlet) 2410 { 2411 if (!quiet) 2412 EMSG2(_(e_dictkey), key); 2413 if (len == -1) 2414 clear_tv(&var1); 2415 return NULL; 2416 } 2417 if (len == -1) 2418 lp->ll_newkey = vim_strsave(key); 2419 else 2420 lp->ll_newkey = vim_strnsave(key, len); 2421 if (len == -1) 2422 clear_tv(&var1); 2423 if (lp->ll_newkey == NULL) 2424 p = NULL; 2425 break; 2426 } 2427 if (len == -1) 2428 clear_tv(&var1); 2429 lp->ll_tv = &lp->ll_di->di_tv; 2430 } 2431 else 2432 { 2433 /* 2434 * Get the number and item for the only or first index of the List. 2435 */ 2436 if (empty1) 2437 lp->ll_n1 = 0; 2438 else 2439 { 2440 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2441 clear_tv(&var1); 2442 } 2443 lp->ll_dict = NULL; 2444 lp->ll_list = lp->ll_tv->vval.v_list; 2445 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2446 if (lp->ll_li == NULL) 2447 { 2448 if (!quiet) 2449 EMSGN(_(e_listidx), lp->ll_n1); 2450 if (lp->ll_range && !lp->ll_empty2) 2451 clear_tv(&var2); 2452 return NULL; 2453 } 2454 2455 /* 2456 * May need to find the item or absolute index for the second 2457 * index of a range. 2458 * When no index given: "lp->ll_empty2" is TRUE. 2459 * Otherwise "lp->ll_n2" is set to the second index. 2460 */ 2461 if (lp->ll_range && !lp->ll_empty2) 2462 { 2463 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2464 clear_tv(&var2); 2465 if (lp->ll_n2 < 0) 2466 { 2467 ni = list_find(lp->ll_list, lp->ll_n2); 2468 if (ni == NULL) 2469 { 2470 if (!quiet) 2471 EMSGN(_(e_listidx), lp->ll_n2); 2472 return NULL; 2473 } 2474 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2475 } 2476 2477 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2478 if (lp->ll_n1 < 0) 2479 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2480 if (lp->ll_n2 < lp->ll_n1) 2481 { 2482 if (!quiet) 2483 EMSGN(_(e_listidx), lp->ll_n2); 2484 return NULL; 2485 } 2486 } 2487 2488 lp->ll_tv = &lp->ll_li->li_tv; 2489 } 2490 } 2491 2492 return p; 2493 } 2494 2495 /* 2496 * Clear lval "lp" that was filled by get_lval(). 2497 */ 2498 static void 2499 clear_lval(lp) 2500 lval_T *lp; 2501 { 2502 vim_free(lp->ll_exp_name); 2503 vim_free(lp->ll_newkey); 2504 } 2505 2506 /* 2507 * Set a variable that was parsed by get_lval() to "rettv". 2508 * "endp" points to just after the parsed name. 2509 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2510 */ 2511 static void 2512 set_var_lval(lp, endp, rettv, copy, op) 2513 lval_T *lp; 2514 char_u *endp; 2515 typval_T *rettv; 2516 int copy; 2517 char_u *op; 2518 { 2519 int cc; 2520 listitem_T *ni; 2521 listitem_T *ri; 2522 dictitem_T *di; 2523 2524 if (lp->ll_tv == NULL) 2525 { 2526 if (!check_changedtick(lp->ll_name)) 2527 { 2528 cc = *endp; 2529 *endp = NUL; 2530 if (op != NULL && *op != '=') 2531 { 2532 typval_T tv; 2533 2534 /* handle +=, -= and .= */ 2535 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2536 &tv, TRUE) == OK) 2537 { 2538 if (tv_op(&tv, rettv, op) == OK) 2539 set_var(lp->ll_name, &tv, FALSE); 2540 clear_tv(&tv); 2541 } 2542 } 2543 else 2544 set_var(lp->ll_name, rettv, copy); 2545 *endp = cc; 2546 } 2547 } 2548 else if (tv_check_lock(lp->ll_newkey == NULL 2549 ? lp->ll_tv->v_lock 2550 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2551 ; 2552 else if (lp->ll_range) 2553 { 2554 /* 2555 * Assign the List values to the list items. 2556 */ 2557 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2558 { 2559 if (op != NULL && *op != '=') 2560 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2561 else 2562 { 2563 clear_tv(&lp->ll_li->li_tv); 2564 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2565 } 2566 ri = ri->li_next; 2567 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2568 break; 2569 if (lp->ll_li->li_next == NULL) 2570 { 2571 /* Need to add an empty item. */ 2572 ni = listitem_alloc(); 2573 if (ni == NULL) 2574 { 2575 ri = NULL; 2576 break; 2577 } 2578 ni->li_tv.v_type = VAR_NUMBER; 2579 ni->li_tv.v_lock = 0; 2580 ni->li_tv.vval.v_number = 0; 2581 list_append(lp->ll_list, ni); 2582 } 2583 lp->ll_li = lp->ll_li->li_next; 2584 ++lp->ll_n1; 2585 } 2586 if (ri != NULL) 2587 EMSG(_("E710: List value has more items than target")); 2588 else if (lp->ll_empty2 2589 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2590 : lp->ll_n1 != lp->ll_n2) 2591 EMSG(_("E711: List value has not enough items")); 2592 } 2593 else 2594 { 2595 /* 2596 * Assign to a List or Dictionary item. 2597 */ 2598 if (lp->ll_newkey != NULL) 2599 { 2600 if (op != NULL && *op != '=') 2601 { 2602 EMSG2(_(e_letwrong), op); 2603 return; 2604 } 2605 2606 /* Need to add an item to the Dictionary. */ 2607 di = dictitem_alloc(lp->ll_newkey); 2608 if (di == NULL) 2609 return; 2610 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2611 { 2612 vim_free(di); 2613 return; 2614 } 2615 lp->ll_tv = &di->di_tv; 2616 } 2617 else if (op != NULL && *op != '=') 2618 { 2619 tv_op(lp->ll_tv, rettv, op); 2620 return; 2621 } 2622 else 2623 clear_tv(lp->ll_tv); 2624 2625 /* 2626 * Assign the value to the variable or list item. 2627 */ 2628 if (copy) 2629 copy_tv(rettv, lp->ll_tv); 2630 else 2631 { 2632 *lp->ll_tv = *rettv; 2633 lp->ll_tv->v_lock = 0; 2634 init_tv(rettv); 2635 } 2636 } 2637 } 2638 2639 /* 2640 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2641 * Returns OK or FAIL. 2642 */ 2643 static int 2644 tv_op(tv1, tv2, op) 2645 typval_T *tv1; 2646 typval_T *tv2; 2647 char_u *op; 2648 { 2649 long n; 2650 char_u numbuf[NUMBUFLEN]; 2651 char_u *s; 2652 2653 /* Can't do anything with a Funcref or a Dict on the right. */ 2654 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2655 { 2656 switch (tv1->v_type) 2657 { 2658 case VAR_DICT: 2659 case VAR_FUNC: 2660 break; 2661 2662 case VAR_LIST: 2663 if (*op != '+' || tv2->v_type != VAR_LIST) 2664 break; 2665 /* List += List */ 2666 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2667 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2668 return OK; 2669 2670 case VAR_NUMBER: 2671 case VAR_STRING: 2672 if (tv2->v_type == VAR_LIST) 2673 break; 2674 if (*op == '+' || *op == '-') 2675 { 2676 /* nr += nr or nr -= nr*/ 2677 n = get_tv_number(tv1); 2678 if (*op == '+') 2679 n += get_tv_number(tv2); 2680 else 2681 n -= get_tv_number(tv2); 2682 clear_tv(tv1); 2683 tv1->v_type = VAR_NUMBER; 2684 tv1->vval.v_number = n; 2685 } 2686 else 2687 { 2688 /* str .= str */ 2689 s = get_tv_string(tv1); 2690 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2691 clear_tv(tv1); 2692 tv1->v_type = VAR_STRING; 2693 tv1->vval.v_string = s; 2694 } 2695 return OK; 2696 } 2697 } 2698 2699 EMSG2(_(e_letwrong), op); 2700 return FAIL; 2701 } 2702 2703 /* 2704 * Add a watcher to a list. 2705 */ 2706 static void 2707 list_add_watch(l, lw) 2708 list_T *l; 2709 listwatch_T *lw; 2710 { 2711 lw->lw_next = l->lv_watch; 2712 l->lv_watch = lw; 2713 } 2714 2715 /* 2716 * Remove a watcher from a list. 2717 * No warning when it isn't found... 2718 */ 2719 static void 2720 list_rem_watch(l, lwrem) 2721 list_T *l; 2722 listwatch_T *lwrem; 2723 { 2724 listwatch_T *lw, **lwp; 2725 2726 lwp = &l->lv_watch; 2727 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2728 { 2729 if (lw == lwrem) 2730 { 2731 *lwp = lw->lw_next; 2732 break; 2733 } 2734 lwp = &lw->lw_next; 2735 } 2736 } 2737 2738 /* 2739 * Just before removing an item from a list: advance watchers to the next 2740 * item. 2741 */ 2742 static void 2743 list_fix_watch(l, item) 2744 list_T *l; 2745 listitem_T *item; 2746 { 2747 listwatch_T *lw; 2748 2749 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2750 if (lw->lw_item == item) 2751 lw->lw_item = item->li_next; 2752 } 2753 2754 /* 2755 * Evaluate the expression used in a ":for var in expr" command. 2756 * "arg" points to "var". 2757 * Set "*errp" to TRUE for an error, FALSE otherwise; 2758 * Return a pointer that holds the info. Null when there is an error. 2759 */ 2760 void * 2761 eval_for_line(arg, errp, nextcmdp, skip) 2762 char_u *arg; 2763 int *errp; 2764 char_u **nextcmdp; 2765 int skip; 2766 { 2767 forinfo_T *fi; 2768 char_u *expr; 2769 typval_T tv; 2770 list_T *l; 2771 2772 *errp = TRUE; /* default: there is an error */ 2773 2774 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2775 if (fi == NULL) 2776 return NULL; 2777 2778 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2779 if (expr == NULL) 2780 return fi; 2781 2782 expr = skipwhite(expr); 2783 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2784 { 2785 EMSG(_("E690: Missing \"in\" after :for")); 2786 return fi; 2787 } 2788 2789 if (skip) 2790 ++emsg_skip; 2791 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2792 { 2793 *errp = FALSE; 2794 if (!skip) 2795 { 2796 l = tv.vval.v_list; 2797 if (tv.v_type != VAR_LIST || l == NULL) 2798 { 2799 EMSG(_(e_listreq)); 2800 clear_tv(&tv); 2801 } 2802 else 2803 { 2804 fi->fi_list = l; 2805 list_add_watch(l, &fi->fi_lw); 2806 fi->fi_lw.lw_item = l->lv_first; 2807 } 2808 } 2809 } 2810 if (skip) 2811 --emsg_skip; 2812 2813 return fi; 2814 } 2815 2816 /* 2817 * Use the first item in a ":for" list. Advance to the next. 2818 * Assign the values to the variable (list). "arg" points to the first one. 2819 * Return TRUE when a valid item was found, FALSE when at end of list or 2820 * something wrong. 2821 */ 2822 int 2823 next_for_item(fi_void, arg) 2824 void *fi_void; 2825 char_u *arg; 2826 { 2827 forinfo_T *fi = (forinfo_T *)fi_void; 2828 int result; 2829 listitem_T *item; 2830 2831 item = fi->fi_lw.lw_item; 2832 if (item == NULL) 2833 result = FALSE; 2834 else 2835 { 2836 fi->fi_lw.lw_item = item->li_next; 2837 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2838 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2839 } 2840 return result; 2841 } 2842 2843 /* 2844 * Free the structure used to store info used by ":for". 2845 */ 2846 void 2847 free_for_info(fi_void) 2848 void *fi_void; 2849 { 2850 forinfo_T *fi = (forinfo_T *)fi_void; 2851 2852 if (fi != NULL && fi->fi_list != NULL) 2853 { 2854 list_rem_watch(fi->fi_list, &fi->fi_lw); 2855 list_unref(fi->fi_list); 2856 } 2857 vim_free(fi); 2858 } 2859 2860 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2861 2862 void 2863 set_context_for_expression(xp, arg, cmdidx) 2864 expand_T *xp; 2865 char_u *arg; 2866 cmdidx_T cmdidx; 2867 { 2868 int got_eq = FALSE; 2869 int c; 2870 char_u *p; 2871 2872 if (cmdidx == CMD_let) 2873 { 2874 xp->xp_context = EXPAND_USER_VARS; 2875 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2876 { 2877 /* ":let var1 var2 ...": find last space. */ 2878 for (p = arg + STRLEN(arg); p >= arg; ) 2879 { 2880 xp->xp_pattern = p; 2881 mb_ptr_back(arg, p); 2882 if (vim_iswhite(*p)) 2883 break; 2884 } 2885 return; 2886 } 2887 } 2888 else 2889 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2890 : EXPAND_EXPRESSION; 2891 while ((xp->xp_pattern = vim_strpbrk(arg, 2892 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2893 { 2894 c = *xp->xp_pattern; 2895 if (c == '&') 2896 { 2897 c = xp->xp_pattern[1]; 2898 if (c == '&') 2899 { 2900 ++xp->xp_pattern; 2901 xp->xp_context = cmdidx != CMD_let || got_eq 2902 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2903 } 2904 else if (c != ' ') 2905 { 2906 xp->xp_context = EXPAND_SETTINGS; 2907 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2908 xp->xp_pattern += 2; 2909 2910 } 2911 } 2912 else if (c == '$') 2913 { 2914 /* environment variable */ 2915 xp->xp_context = EXPAND_ENV_VARS; 2916 } 2917 else if (c == '=') 2918 { 2919 got_eq = TRUE; 2920 xp->xp_context = EXPAND_EXPRESSION; 2921 } 2922 else if (c == '<' 2923 && xp->xp_context == EXPAND_FUNCTIONS 2924 && vim_strchr(xp->xp_pattern, '(') == NULL) 2925 { 2926 /* Function name can start with "<SNR>" */ 2927 break; 2928 } 2929 else if (cmdidx != CMD_let || got_eq) 2930 { 2931 if (c == '"') /* string */ 2932 { 2933 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2934 if (c == '\\' && xp->xp_pattern[1] != NUL) 2935 ++xp->xp_pattern; 2936 xp->xp_context = EXPAND_NOTHING; 2937 } 2938 else if (c == '\'') /* literal string */ 2939 { 2940 /* Trick: '' is like stopping and starting a literal string. */ 2941 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2942 /* skip */ ; 2943 xp->xp_context = EXPAND_NOTHING; 2944 } 2945 else if (c == '|') 2946 { 2947 if (xp->xp_pattern[1] == '|') 2948 { 2949 ++xp->xp_pattern; 2950 xp->xp_context = EXPAND_EXPRESSION; 2951 } 2952 else 2953 xp->xp_context = EXPAND_COMMANDS; 2954 } 2955 else 2956 xp->xp_context = EXPAND_EXPRESSION; 2957 } 2958 else 2959 /* Doesn't look like something valid, expand as an expression 2960 * anyway. */ 2961 xp->xp_context = EXPAND_EXPRESSION; 2962 arg = xp->xp_pattern; 2963 if (*arg != NUL) 2964 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 2965 /* skip */ ; 2966 } 2967 xp->xp_pattern = arg; 2968 } 2969 2970 #endif /* FEAT_CMDL_COMPL */ 2971 2972 /* 2973 * ":1,25call func(arg1, arg2)" function call. 2974 */ 2975 void 2976 ex_call(eap) 2977 exarg_T *eap; 2978 { 2979 char_u *arg = eap->arg; 2980 char_u *startarg; 2981 char_u *name; 2982 char_u *tofree; 2983 int len; 2984 typval_T rettv; 2985 linenr_T lnum; 2986 int doesrange; 2987 int failed = FALSE; 2988 funcdict_T fudi; 2989 2990 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 2991 vim_free(fudi.fd_newkey); 2992 if (tofree == NULL) 2993 return; 2994 2995 /* Increase refcount on dictionary, it could get deleted when evaluating 2996 * the arguments. */ 2997 if (fudi.fd_dict != NULL) 2998 ++fudi.fd_dict->dv_refcount; 2999 3000 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3001 len = STRLEN(tofree); 3002 name = deref_func_name(tofree, &len); 3003 3004 /* Skip white space to allow ":call func ()". Not good, but required for 3005 * backward compatibility. */ 3006 startarg = skipwhite(arg); 3007 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3008 3009 if (*startarg != '(') 3010 { 3011 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3012 goto end; 3013 } 3014 3015 /* 3016 * When skipping, evaluate the function once, to find the end of the 3017 * arguments. 3018 * When the function takes a range, this is discovered after the first 3019 * call, and the loop is broken. 3020 */ 3021 if (eap->skip) 3022 { 3023 ++emsg_skip; 3024 lnum = eap->line2; /* do it once, also with an invalid range */ 3025 } 3026 else 3027 lnum = eap->line1; 3028 for ( ; lnum <= eap->line2; ++lnum) 3029 { 3030 if (!eap->skip && eap->addr_count > 0) 3031 { 3032 curwin->w_cursor.lnum = lnum; 3033 curwin->w_cursor.col = 0; 3034 } 3035 arg = startarg; 3036 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3037 eap->line1, eap->line2, &doesrange, 3038 !eap->skip, fudi.fd_dict) == FAIL) 3039 { 3040 failed = TRUE; 3041 break; 3042 } 3043 clear_tv(&rettv); 3044 if (doesrange || eap->skip) 3045 break; 3046 /* Stop when immediately aborting on error, or when an interrupt 3047 * occurred or an exception was thrown but not caught. 3048 * get_func_tv() returned OK, so that the check for trailing 3049 * characters below is executed. */ 3050 if (aborting()) 3051 break; 3052 } 3053 if (eap->skip) 3054 --emsg_skip; 3055 3056 if (!failed) 3057 { 3058 /* Check for trailing illegal characters and a following command. */ 3059 if (!ends_excmd(*arg)) 3060 { 3061 emsg_severe = TRUE; 3062 EMSG(_(e_trailing)); 3063 } 3064 else 3065 eap->nextcmd = check_nextcmd(arg); 3066 } 3067 3068 end: 3069 dict_unref(fudi.fd_dict); 3070 vim_free(tofree); 3071 } 3072 3073 /* 3074 * ":unlet[!] var1 ... " command. 3075 */ 3076 void 3077 ex_unlet(eap) 3078 exarg_T *eap; 3079 { 3080 ex_unletlock(eap, eap->arg, 0); 3081 } 3082 3083 /* 3084 * ":lockvar" and ":unlockvar" commands 3085 */ 3086 void 3087 ex_lockvar(eap) 3088 exarg_T *eap; 3089 { 3090 char_u *arg = eap->arg; 3091 int deep = 2; 3092 3093 if (eap->forceit) 3094 deep = -1; 3095 else if (vim_isdigit(*arg)) 3096 { 3097 deep = getdigits(&arg); 3098 arg = skipwhite(arg); 3099 } 3100 3101 ex_unletlock(eap, arg, deep); 3102 } 3103 3104 /* 3105 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3106 */ 3107 static void 3108 ex_unletlock(eap, argstart, deep) 3109 exarg_T *eap; 3110 char_u *argstart; 3111 int deep; 3112 { 3113 char_u *arg = argstart; 3114 char_u *name_end; 3115 int error = FALSE; 3116 lval_T lv; 3117 3118 do 3119 { 3120 /* Parse the name and find the end. */ 3121 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3122 FNE_CHECK_START); 3123 if (lv.ll_name == NULL) 3124 error = TRUE; /* error but continue parsing */ 3125 if (name_end == NULL || (!vim_iswhite(*name_end) 3126 && !ends_excmd(*name_end))) 3127 { 3128 if (name_end != NULL) 3129 { 3130 emsg_severe = TRUE; 3131 EMSG(_(e_trailing)); 3132 } 3133 if (!(eap->skip || error)) 3134 clear_lval(&lv); 3135 break; 3136 } 3137 3138 if (!error && !eap->skip) 3139 { 3140 if (eap->cmdidx == CMD_unlet) 3141 { 3142 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3143 error = TRUE; 3144 } 3145 else 3146 { 3147 if (do_lock_var(&lv, name_end, deep, 3148 eap->cmdidx == CMD_lockvar) == FAIL) 3149 error = TRUE; 3150 } 3151 } 3152 3153 if (!eap->skip) 3154 clear_lval(&lv); 3155 3156 arg = skipwhite(name_end); 3157 } while (!ends_excmd(*arg)); 3158 3159 eap->nextcmd = check_nextcmd(arg); 3160 } 3161 3162 static int 3163 do_unlet_var(lp, name_end, forceit) 3164 lval_T *lp; 3165 char_u *name_end; 3166 int forceit; 3167 { 3168 int ret = OK; 3169 int cc; 3170 3171 if (lp->ll_tv == NULL) 3172 { 3173 cc = *name_end; 3174 *name_end = NUL; 3175 3176 /* Normal name or expanded name. */ 3177 if (check_changedtick(lp->ll_name)) 3178 ret = FAIL; 3179 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3180 ret = FAIL; 3181 *name_end = cc; 3182 } 3183 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3184 return FAIL; 3185 else if (lp->ll_range) 3186 { 3187 listitem_T *li; 3188 3189 /* Delete a range of List items. */ 3190 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3191 { 3192 li = lp->ll_li->li_next; 3193 listitem_remove(lp->ll_list, lp->ll_li); 3194 lp->ll_li = li; 3195 ++lp->ll_n1; 3196 } 3197 } 3198 else 3199 { 3200 if (lp->ll_list != NULL) 3201 /* unlet a List item. */ 3202 listitem_remove(lp->ll_list, lp->ll_li); 3203 else 3204 /* unlet a Dictionary item. */ 3205 dictitem_remove(lp->ll_dict, lp->ll_di); 3206 } 3207 3208 return ret; 3209 } 3210 3211 /* 3212 * "unlet" a variable. Return OK if it existed, FAIL if not. 3213 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3214 */ 3215 int 3216 do_unlet(name, forceit) 3217 char_u *name; 3218 int forceit; 3219 { 3220 hashtab_T *ht; 3221 hashitem_T *hi; 3222 char_u *varname; 3223 3224 ht = find_var_ht(name, &varname); 3225 if (ht != NULL && *varname != NUL) 3226 { 3227 hi = hash_find(ht, varname); 3228 if (!HASHITEM_EMPTY(hi)) 3229 { 3230 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3231 return FAIL; 3232 delete_var(ht, hi); 3233 return OK; 3234 } 3235 } 3236 if (forceit) 3237 return OK; 3238 EMSG2(_("E108: No such variable: \"%s\""), name); 3239 return FAIL; 3240 } 3241 3242 /* 3243 * Lock or unlock variable indicated by "lp". 3244 * "deep" is the levels to go (-1 for unlimited); 3245 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3246 */ 3247 static int 3248 do_lock_var(lp, name_end, deep, lock) 3249 lval_T *lp; 3250 char_u *name_end; 3251 int deep; 3252 int lock; 3253 { 3254 int ret = OK; 3255 int cc; 3256 dictitem_T *di; 3257 3258 if (deep == 0) /* nothing to do */ 3259 return OK; 3260 3261 if (lp->ll_tv == NULL) 3262 { 3263 cc = *name_end; 3264 *name_end = NUL; 3265 3266 /* Normal name or expanded name. */ 3267 if (check_changedtick(lp->ll_name)) 3268 ret = FAIL; 3269 else 3270 { 3271 di = find_var(lp->ll_name, NULL); 3272 if (di == NULL) 3273 ret = FAIL; 3274 else 3275 { 3276 if (lock) 3277 di->di_flags |= DI_FLAGS_LOCK; 3278 else 3279 di->di_flags &= ~DI_FLAGS_LOCK; 3280 item_lock(&di->di_tv, deep, lock); 3281 } 3282 } 3283 *name_end = cc; 3284 } 3285 else if (lp->ll_range) 3286 { 3287 listitem_T *li = lp->ll_li; 3288 3289 /* (un)lock a range of List items. */ 3290 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3291 { 3292 item_lock(&li->li_tv, deep, lock); 3293 li = li->li_next; 3294 ++lp->ll_n1; 3295 } 3296 } 3297 else if (lp->ll_list != NULL) 3298 /* (un)lock a List item. */ 3299 item_lock(&lp->ll_li->li_tv, deep, lock); 3300 else 3301 /* un(lock) a Dictionary item. */ 3302 item_lock(&lp->ll_di->di_tv, deep, lock); 3303 3304 return ret; 3305 } 3306 3307 /* 3308 * Lock or unlock an item. "deep" is nr of levels to go. 3309 */ 3310 static void 3311 item_lock(tv, deep, lock) 3312 typval_T *tv; 3313 int deep; 3314 int lock; 3315 { 3316 static int recurse = 0; 3317 list_T *l; 3318 listitem_T *li; 3319 dict_T *d; 3320 hashitem_T *hi; 3321 int todo; 3322 3323 if (recurse >= DICT_MAXNEST) 3324 { 3325 EMSG(_("E743: variable nested too deep for (un)lock")); 3326 return; 3327 } 3328 if (deep == 0) 3329 return; 3330 ++recurse; 3331 3332 /* lock/unlock the item itself */ 3333 if (lock) 3334 tv->v_lock |= VAR_LOCKED; 3335 else 3336 tv->v_lock &= ~VAR_LOCKED; 3337 3338 switch (tv->v_type) 3339 { 3340 case VAR_LIST: 3341 if ((l = tv->vval.v_list) != NULL) 3342 { 3343 if (lock) 3344 l->lv_lock |= VAR_LOCKED; 3345 else 3346 l->lv_lock &= ~VAR_LOCKED; 3347 if (deep < 0 || deep > 1) 3348 /* recursive: lock/unlock the items the List contains */ 3349 for (li = l->lv_first; li != NULL; li = li->li_next) 3350 item_lock(&li->li_tv, deep - 1, lock); 3351 } 3352 break; 3353 case VAR_DICT: 3354 if ((d = tv->vval.v_dict) != NULL) 3355 { 3356 if (lock) 3357 d->dv_lock |= VAR_LOCKED; 3358 else 3359 d->dv_lock &= ~VAR_LOCKED; 3360 if (deep < 0 || deep > 1) 3361 { 3362 /* recursive: lock/unlock the items the List contains */ 3363 todo = d->dv_hashtab.ht_used; 3364 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3365 { 3366 if (!HASHITEM_EMPTY(hi)) 3367 { 3368 --todo; 3369 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3370 } 3371 } 3372 } 3373 } 3374 } 3375 --recurse; 3376 } 3377 3378 /* 3379 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3380 * it refers to a List or Dictionary that is locked. 3381 */ 3382 static int 3383 tv_islocked(tv) 3384 typval_T *tv; 3385 { 3386 return (tv->v_lock & VAR_LOCKED) 3387 || (tv->v_type == VAR_LIST 3388 && tv->vval.v_list != NULL 3389 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3390 || (tv->v_type == VAR_DICT 3391 && tv->vval.v_dict != NULL 3392 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3393 } 3394 3395 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3396 /* 3397 * Delete all "menutrans_" variables. 3398 */ 3399 void 3400 del_menutrans_vars() 3401 { 3402 hashitem_T *hi; 3403 int todo; 3404 3405 hash_lock(&globvarht); 3406 todo = globvarht.ht_used; 3407 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3408 { 3409 if (!HASHITEM_EMPTY(hi)) 3410 { 3411 --todo; 3412 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3413 delete_var(&globvarht, hi); 3414 } 3415 } 3416 hash_unlock(&globvarht); 3417 } 3418 #endif 3419 3420 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3421 3422 /* 3423 * Local string buffer for the next two functions to store a variable name 3424 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3425 * get_user_var_name(). 3426 */ 3427 3428 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3429 3430 static char_u *varnamebuf = NULL; 3431 static int varnamebuflen = 0; 3432 3433 /* 3434 * Function to concatenate a prefix and a variable name. 3435 */ 3436 static char_u * 3437 cat_prefix_varname(prefix, name) 3438 int prefix; 3439 char_u *name; 3440 { 3441 int len; 3442 3443 len = (int)STRLEN(name) + 3; 3444 if (len > varnamebuflen) 3445 { 3446 vim_free(varnamebuf); 3447 len += 10; /* some additional space */ 3448 varnamebuf = alloc(len); 3449 if (varnamebuf == NULL) 3450 { 3451 varnamebuflen = 0; 3452 return NULL; 3453 } 3454 varnamebuflen = len; 3455 } 3456 *varnamebuf = prefix; 3457 varnamebuf[1] = ':'; 3458 STRCPY(varnamebuf + 2, name); 3459 return varnamebuf; 3460 } 3461 3462 /* 3463 * Function given to ExpandGeneric() to obtain the list of user defined 3464 * (global/buffer/window/built-in) variable names. 3465 */ 3466 /*ARGSUSED*/ 3467 char_u * 3468 get_user_var_name(xp, idx) 3469 expand_T *xp; 3470 int idx; 3471 { 3472 static long_u gdone; 3473 static long_u bdone; 3474 static long_u wdone; 3475 static int vidx; 3476 static hashitem_T *hi; 3477 hashtab_T *ht; 3478 3479 if (idx == 0) 3480 gdone = bdone = wdone = vidx = 0; 3481 3482 /* Global variables */ 3483 if (gdone < globvarht.ht_used) 3484 { 3485 if (gdone++ == 0) 3486 hi = globvarht.ht_array; 3487 else 3488 ++hi; 3489 while (HASHITEM_EMPTY(hi)) 3490 ++hi; 3491 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3492 return cat_prefix_varname('g', hi->hi_key); 3493 return hi->hi_key; 3494 } 3495 3496 /* b: variables */ 3497 ht = &curbuf->b_vars.dv_hashtab; 3498 if (bdone < ht->ht_used) 3499 { 3500 if (bdone++ == 0) 3501 hi = ht->ht_array; 3502 else 3503 ++hi; 3504 while (HASHITEM_EMPTY(hi)) 3505 ++hi; 3506 return cat_prefix_varname('b', hi->hi_key); 3507 } 3508 if (bdone == ht->ht_used) 3509 { 3510 ++bdone; 3511 return (char_u *)"b:changedtick"; 3512 } 3513 3514 /* w: variables */ 3515 ht = &curwin->w_vars.dv_hashtab; 3516 if (wdone < ht->ht_used) 3517 { 3518 if (wdone++ == 0) 3519 hi = ht->ht_array; 3520 else 3521 ++hi; 3522 while (HASHITEM_EMPTY(hi)) 3523 ++hi; 3524 return cat_prefix_varname('w', hi->hi_key); 3525 } 3526 3527 /* v: variables */ 3528 if (vidx < VV_LEN) 3529 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3530 3531 vim_free(varnamebuf); 3532 varnamebuf = NULL; 3533 varnamebuflen = 0; 3534 return NULL; 3535 } 3536 3537 #endif /* FEAT_CMDL_COMPL */ 3538 3539 /* 3540 * types for expressions. 3541 */ 3542 typedef enum 3543 { 3544 TYPE_UNKNOWN = 0 3545 , TYPE_EQUAL /* == */ 3546 , TYPE_NEQUAL /* != */ 3547 , TYPE_GREATER /* > */ 3548 , TYPE_GEQUAL /* >= */ 3549 , TYPE_SMALLER /* < */ 3550 , TYPE_SEQUAL /* <= */ 3551 , TYPE_MATCH /* =~ */ 3552 , TYPE_NOMATCH /* !~ */ 3553 } exptype_T; 3554 3555 /* 3556 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3557 * executed. The function may return OK, but the rettv will be of type 3558 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3559 */ 3560 3561 /* 3562 * Handle zero level expression. 3563 * This calls eval1() and handles error message and nextcmd. 3564 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3565 * Return OK or FAIL. 3566 */ 3567 static int 3568 eval0(arg, rettv, nextcmd, evaluate) 3569 char_u *arg; 3570 typval_T *rettv; 3571 char_u **nextcmd; 3572 int evaluate; 3573 { 3574 int ret; 3575 char_u *p; 3576 3577 p = skipwhite(arg); 3578 ret = eval1(&p, rettv, evaluate); 3579 if (ret == FAIL || !ends_excmd(*p)) 3580 { 3581 if (ret != FAIL) 3582 clear_tv(rettv); 3583 /* 3584 * Report the invalid expression unless the expression evaluation has 3585 * been cancelled due to an aborting error, an interrupt, or an 3586 * exception. 3587 */ 3588 if (!aborting()) 3589 EMSG2(_(e_invexpr2), arg); 3590 ret = FAIL; 3591 } 3592 if (nextcmd != NULL) 3593 *nextcmd = check_nextcmd(p); 3594 3595 return ret; 3596 } 3597 3598 /* 3599 * Handle top level expression: 3600 * expr1 ? expr0 : expr0 3601 * 3602 * "arg" must point to the first non-white of the expression. 3603 * "arg" is advanced to the next non-white after the recognized expression. 3604 * 3605 * Return OK or FAIL. 3606 */ 3607 static int 3608 eval1(arg, rettv, evaluate) 3609 char_u **arg; 3610 typval_T *rettv; 3611 int evaluate; 3612 { 3613 int result; 3614 typval_T var2; 3615 3616 /* 3617 * Get the first variable. 3618 */ 3619 if (eval2(arg, rettv, evaluate) == FAIL) 3620 return FAIL; 3621 3622 if ((*arg)[0] == '?') 3623 { 3624 result = FALSE; 3625 if (evaluate) 3626 { 3627 int error = FALSE; 3628 3629 if (get_tv_number_chk(rettv, &error) != 0) 3630 result = TRUE; 3631 clear_tv(rettv); 3632 if (error) 3633 return FAIL; 3634 } 3635 3636 /* 3637 * Get the second variable. 3638 */ 3639 *arg = skipwhite(*arg + 1); 3640 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3641 return FAIL; 3642 3643 /* 3644 * Check for the ":". 3645 */ 3646 if ((*arg)[0] != ':') 3647 { 3648 EMSG(_("E109: Missing ':' after '?'")); 3649 if (evaluate && result) 3650 clear_tv(rettv); 3651 return FAIL; 3652 } 3653 3654 /* 3655 * Get the third variable. 3656 */ 3657 *arg = skipwhite(*arg + 1); 3658 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3659 { 3660 if (evaluate && result) 3661 clear_tv(rettv); 3662 return FAIL; 3663 } 3664 if (evaluate && !result) 3665 *rettv = var2; 3666 } 3667 3668 return OK; 3669 } 3670 3671 /* 3672 * Handle first level expression: 3673 * expr2 || expr2 || expr2 logical OR 3674 * 3675 * "arg" must point to the first non-white of the expression. 3676 * "arg" is advanced to the next non-white after the recognized expression. 3677 * 3678 * Return OK or FAIL. 3679 */ 3680 static int 3681 eval2(arg, rettv, evaluate) 3682 char_u **arg; 3683 typval_T *rettv; 3684 int evaluate; 3685 { 3686 typval_T var2; 3687 long result; 3688 int first; 3689 int error = FALSE; 3690 3691 /* 3692 * Get the first variable. 3693 */ 3694 if (eval3(arg, rettv, evaluate) == FAIL) 3695 return FAIL; 3696 3697 /* 3698 * Repeat until there is no following "||". 3699 */ 3700 first = TRUE; 3701 result = FALSE; 3702 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3703 { 3704 if (evaluate && first) 3705 { 3706 if (get_tv_number_chk(rettv, &error) != 0) 3707 result = TRUE; 3708 clear_tv(rettv); 3709 if (error) 3710 return FAIL; 3711 first = FALSE; 3712 } 3713 3714 /* 3715 * Get the second variable. 3716 */ 3717 *arg = skipwhite(*arg + 2); 3718 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3719 return FAIL; 3720 3721 /* 3722 * Compute the result. 3723 */ 3724 if (evaluate && !result) 3725 { 3726 if (get_tv_number_chk(&var2, &error) != 0) 3727 result = TRUE; 3728 clear_tv(&var2); 3729 if (error) 3730 return FAIL; 3731 } 3732 if (evaluate) 3733 { 3734 rettv->v_type = VAR_NUMBER; 3735 rettv->vval.v_number = result; 3736 } 3737 } 3738 3739 return OK; 3740 } 3741 3742 /* 3743 * Handle second level expression: 3744 * expr3 && expr3 && expr3 logical AND 3745 * 3746 * "arg" must point to the first non-white of the expression. 3747 * "arg" is advanced to the next non-white after the recognized expression. 3748 * 3749 * Return OK or FAIL. 3750 */ 3751 static int 3752 eval3(arg, rettv, evaluate) 3753 char_u **arg; 3754 typval_T *rettv; 3755 int evaluate; 3756 { 3757 typval_T var2; 3758 long result; 3759 int first; 3760 int error = FALSE; 3761 3762 /* 3763 * Get the first variable. 3764 */ 3765 if (eval4(arg, rettv, evaluate) == FAIL) 3766 return FAIL; 3767 3768 /* 3769 * Repeat until there is no following "&&". 3770 */ 3771 first = TRUE; 3772 result = TRUE; 3773 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3774 { 3775 if (evaluate && first) 3776 { 3777 if (get_tv_number_chk(rettv, &error) == 0) 3778 result = FALSE; 3779 clear_tv(rettv); 3780 if (error) 3781 return FAIL; 3782 first = FALSE; 3783 } 3784 3785 /* 3786 * Get the second variable. 3787 */ 3788 *arg = skipwhite(*arg + 2); 3789 if (eval4(arg, &var2, evaluate && result) == FAIL) 3790 return FAIL; 3791 3792 /* 3793 * Compute the result. 3794 */ 3795 if (evaluate && result) 3796 { 3797 if (get_tv_number_chk(&var2, &error) == 0) 3798 result = FALSE; 3799 clear_tv(&var2); 3800 if (error) 3801 return FAIL; 3802 } 3803 if (evaluate) 3804 { 3805 rettv->v_type = VAR_NUMBER; 3806 rettv->vval.v_number = result; 3807 } 3808 } 3809 3810 return OK; 3811 } 3812 3813 /* 3814 * Handle third level expression: 3815 * var1 == var2 3816 * var1 =~ var2 3817 * var1 != var2 3818 * var1 !~ var2 3819 * var1 > var2 3820 * var1 >= var2 3821 * var1 < var2 3822 * var1 <= var2 3823 * var1 is var2 3824 * var1 isnot var2 3825 * 3826 * "arg" must point to the first non-white of the expression. 3827 * "arg" is advanced to the next non-white after the recognized expression. 3828 * 3829 * Return OK or FAIL. 3830 */ 3831 static int 3832 eval4(arg, rettv, evaluate) 3833 char_u **arg; 3834 typval_T *rettv; 3835 int evaluate; 3836 { 3837 typval_T var2; 3838 char_u *p; 3839 int i; 3840 exptype_T type = TYPE_UNKNOWN; 3841 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3842 int len = 2; 3843 long n1, n2; 3844 char_u *s1, *s2; 3845 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3846 regmatch_T regmatch; 3847 int ic; 3848 char_u *save_cpo; 3849 3850 /* 3851 * Get the first variable. 3852 */ 3853 if (eval5(arg, rettv, evaluate) == FAIL) 3854 return FAIL; 3855 3856 p = *arg; 3857 switch (p[0]) 3858 { 3859 case '=': if (p[1] == '=') 3860 type = TYPE_EQUAL; 3861 else if (p[1] == '~') 3862 type = TYPE_MATCH; 3863 break; 3864 case '!': if (p[1] == '=') 3865 type = TYPE_NEQUAL; 3866 else if (p[1] == '~') 3867 type = TYPE_NOMATCH; 3868 break; 3869 case '>': if (p[1] != '=') 3870 { 3871 type = TYPE_GREATER; 3872 len = 1; 3873 } 3874 else 3875 type = TYPE_GEQUAL; 3876 break; 3877 case '<': if (p[1] != '=') 3878 { 3879 type = TYPE_SMALLER; 3880 len = 1; 3881 } 3882 else 3883 type = TYPE_SEQUAL; 3884 break; 3885 case 'i': if (p[1] == 's') 3886 { 3887 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3888 len = 5; 3889 if (!vim_isIDc(p[len])) 3890 { 3891 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3892 type_is = TRUE; 3893 } 3894 } 3895 break; 3896 } 3897 3898 /* 3899 * If there is a comparitive operator, use it. 3900 */ 3901 if (type != TYPE_UNKNOWN) 3902 { 3903 /* extra question mark appended: ignore case */ 3904 if (p[len] == '?') 3905 { 3906 ic = TRUE; 3907 ++len; 3908 } 3909 /* extra '#' appended: match case */ 3910 else if (p[len] == '#') 3911 { 3912 ic = FALSE; 3913 ++len; 3914 } 3915 /* nothing appened: use 'ignorecase' */ 3916 else 3917 ic = p_ic; 3918 3919 /* 3920 * Get the second variable. 3921 */ 3922 *arg = skipwhite(p + len); 3923 if (eval5(arg, &var2, evaluate) == FAIL) 3924 { 3925 clear_tv(rettv); 3926 return FAIL; 3927 } 3928 3929 if (evaluate) 3930 { 3931 if (type_is && rettv->v_type != var2.v_type) 3932 { 3933 /* For "is" a different type always means FALSE, for "notis" 3934 * it means TRUE. */ 3935 n1 = (type == TYPE_NEQUAL); 3936 } 3937 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3938 { 3939 if (type_is) 3940 { 3941 n1 = (rettv->v_type == var2.v_type 3942 && rettv->vval.v_list == var2.vval.v_list); 3943 if (type == TYPE_NEQUAL) 3944 n1 = !n1; 3945 } 3946 else if (rettv->v_type != var2.v_type 3947 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3948 { 3949 if (rettv->v_type != var2.v_type) 3950 EMSG(_("E691: Can only compare List with List")); 3951 else 3952 EMSG(_("E692: Invalid operation for Lists")); 3953 clear_tv(rettv); 3954 clear_tv(&var2); 3955 return FAIL; 3956 } 3957 else 3958 { 3959 /* Compare two Lists for being equal or unequal. */ 3960 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3961 if (type == TYPE_NEQUAL) 3962 n1 = !n1; 3963 } 3964 } 3965 3966 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 3967 { 3968 if (type_is) 3969 { 3970 n1 = (rettv->v_type == var2.v_type 3971 && rettv->vval.v_dict == var2.vval.v_dict); 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(_("E735: Can only compare Dictionary with Dictionary")); 3980 else 3981 EMSG(_("E736: Invalid operation for Dictionary")); 3982 clear_tv(rettv); 3983 clear_tv(&var2); 3984 return FAIL; 3985 } 3986 else 3987 { 3988 /* Compare two Dictionaries for being equal or unequal. */ 3989 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 3990 if (type == TYPE_NEQUAL) 3991 n1 = !n1; 3992 } 3993 } 3994 3995 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 3996 { 3997 if (rettv->v_type != var2.v_type 3998 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3999 { 4000 if (rettv->v_type != var2.v_type) 4001 EMSG(_("E693: Can only compare Funcref with Funcref")); 4002 else 4003 EMSG(_("E694: Invalid operation for Funcrefs")); 4004 clear_tv(rettv); 4005 clear_tv(&var2); 4006 return FAIL; 4007 } 4008 else 4009 { 4010 /* Compare two Funcrefs for being equal or unequal. */ 4011 if (rettv->vval.v_string == NULL 4012 || var2.vval.v_string == NULL) 4013 n1 = FALSE; 4014 else 4015 n1 = STRCMP(rettv->vval.v_string, 4016 var2.vval.v_string) == 0; 4017 if (type == TYPE_NEQUAL) 4018 n1 = !n1; 4019 } 4020 } 4021 4022 /* 4023 * If one of the two variables is a number, compare as a number. 4024 * When using "=~" or "!~", always compare as string. 4025 */ 4026 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4027 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4028 { 4029 n1 = get_tv_number(rettv); 4030 n2 = get_tv_number(&var2); 4031 switch (type) 4032 { 4033 case TYPE_EQUAL: n1 = (n1 == n2); break; 4034 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4035 case TYPE_GREATER: n1 = (n1 > n2); break; 4036 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4037 case TYPE_SMALLER: n1 = (n1 < n2); break; 4038 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4039 case TYPE_UNKNOWN: 4040 case TYPE_MATCH: 4041 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4042 } 4043 } 4044 else 4045 { 4046 s1 = get_tv_string_buf(rettv, buf1); 4047 s2 = get_tv_string_buf(&var2, buf2); 4048 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4049 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4050 else 4051 i = 0; 4052 n1 = FALSE; 4053 switch (type) 4054 { 4055 case TYPE_EQUAL: n1 = (i == 0); break; 4056 case TYPE_NEQUAL: n1 = (i != 0); break; 4057 case TYPE_GREATER: n1 = (i > 0); break; 4058 case TYPE_GEQUAL: n1 = (i >= 0); break; 4059 case TYPE_SMALLER: n1 = (i < 0); break; 4060 case TYPE_SEQUAL: n1 = (i <= 0); break; 4061 4062 case TYPE_MATCH: 4063 case TYPE_NOMATCH: 4064 /* avoid 'l' flag in 'cpoptions' */ 4065 save_cpo = p_cpo; 4066 p_cpo = (char_u *)""; 4067 regmatch.regprog = vim_regcomp(s2, 4068 RE_MAGIC + RE_STRING); 4069 regmatch.rm_ic = ic; 4070 if (regmatch.regprog != NULL) 4071 { 4072 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4073 vim_free(regmatch.regprog); 4074 if (type == TYPE_NOMATCH) 4075 n1 = !n1; 4076 } 4077 p_cpo = save_cpo; 4078 break; 4079 4080 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4081 } 4082 } 4083 clear_tv(rettv); 4084 clear_tv(&var2); 4085 rettv->v_type = VAR_NUMBER; 4086 rettv->vval.v_number = n1; 4087 } 4088 } 4089 4090 return OK; 4091 } 4092 4093 /* 4094 * Handle fourth level expression: 4095 * + number addition 4096 * - number subtraction 4097 * . string concatenation 4098 * 4099 * "arg" must point to the first non-white of the expression. 4100 * "arg" is advanced to the next non-white after the recognized expression. 4101 * 4102 * Return OK or FAIL. 4103 */ 4104 static int 4105 eval5(arg, rettv, evaluate) 4106 char_u **arg; 4107 typval_T *rettv; 4108 int evaluate; 4109 { 4110 typval_T var2; 4111 typval_T var3; 4112 int op; 4113 long n1, n2; 4114 char_u *s1, *s2; 4115 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4116 char_u *p; 4117 4118 /* 4119 * Get the first variable. 4120 */ 4121 if (eval6(arg, rettv, evaluate) == FAIL) 4122 return FAIL; 4123 4124 /* 4125 * Repeat computing, until no '+', '-' or '.' is following. 4126 */ 4127 for (;;) 4128 { 4129 op = **arg; 4130 if (op != '+' && op != '-' && op != '.') 4131 break; 4132 4133 if (op != '+' || rettv->v_type != VAR_LIST) 4134 { 4135 /* For "list + ...", an illegal use of the first operand as 4136 * a number cannot be determined before evaluating the 2nd 4137 * operand: if this is also a list, all is ok. 4138 * For "something . ...", "something - ..." or "non-list + ...", 4139 * we know that the first operand needs to be a string or number 4140 * without evaluating the 2nd operand. So check before to avoid 4141 * side effects after an error. */ 4142 if (evaluate && get_tv_string_chk(rettv) == NULL) 4143 { 4144 clear_tv(rettv); 4145 return FAIL; 4146 } 4147 } 4148 4149 /* 4150 * Get the second variable. 4151 */ 4152 *arg = skipwhite(*arg + 1); 4153 if (eval6(arg, &var2, evaluate) == FAIL) 4154 { 4155 clear_tv(rettv); 4156 return FAIL; 4157 } 4158 4159 if (evaluate) 4160 { 4161 /* 4162 * Compute the result. 4163 */ 4164 if (op == '.') 4165 { 4166 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4167 s2 = get_tv_string_buf_chk(&var2, buf2); 4168 if (s2 == NULL) /* type error ? */ 4169 { 4170 clear_tv(rettv); 4171 clear_tv(&var2); 4172 return FAIL; 4173 } 4174 p = concat_str(s1, s2); 4175 clear_tv(rettv); 4176 rettv->v_type = VAR_STRING; 4177 rettv->vval.v_string = p; 4178 } 4179 else if (op == '+' && rettv->v_type == VAR_LIST 4180 && var2.v_type == VAR_LIST) 4181 { 4182 /* concatenate Lists */ 4183 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4184 &var3) == FAIL) 4185 { 4186 clear_tv(rettv); 4187 clear_tv(&var2); 4188 return FAIL; 4189 } 4190 clear_tv(rettv); 4191 *rettv = var3; 4192 } 4193 else 4194 { 4195 int error = FALSE; 4196 4197 n1 = get_tv_number_chk(rettv, &error); 4198 if (error) 4199 { 4200 /* This can only happen for "list + non-list". 4201 * For "non-list + ..." or "something - ...", we returned 4202 * before evaluating the 2nd operand. */ 4203 clear_tv(rettv); 4204 return FAIL; 4205 } 4206 n2 = get_tv_number_chk(&var2, &error); 4207 if (error) 4208 { 4209 clear_tv(rettv); 4210 clear_tv(&var2); 4211 return FAIL; 4212 } 4213 clear_tv(rettv); 4214 if (op == '+') 4215 n1 = n1 + n2; 4216 else 4217 n1 = n1 - n2; 4218 rettv->v_type = VAR_NUMBER; 4219 rettv->vval.v_number = n1; 4220 } 4221 clear_tv(&var2); 4222 } 4223 } 4224 return OK; 4225 } 4226 4227 /* 4228 * Handle fifth level expression: 4229 * * number multiplication 4230 * / number division 4231 * % number modulo 4232 * 4233 * "arg" must point to the first non-white of the expression. 4234 * "arg" is advanced to the next non-white after the recognized expression. 4235 * 4236 * Return OK or FAIL. 4237 */ 4238 static int 4239 eval6(arg, rettv, evaluate) 4240 char_u **arg; 4241 typval_T *rettv; 4242 int evaluate; 4243 { 4244 typval_T var2; 4245 int op; 4246 long n1, n2; 4247 int error = FALSE; 4248 4249 /* 4250 * Get the first variable. 4251 */ 4252 if (eval7(arg, rettv, evaluate) == FAIL) 4253 return FAIL; 4254 4255 /* 4256 * Repeat computing, until no '*', '/' or '%' is following. 4257 */ 4258 for (;;) 4259 { 4260 op = **arg; 4261 if (op != '*' && op != '/' && op != '%') 4262 break; 4263 4264 if (evaluate) 4265 { 4266 n1 = get_tv_number_chk(rettv, &error); 4267 clear_tv(rettv); 4268 if (error) 4269 return FAIL; 4270 } 4271 else 4272 n1 = 0; 4273 4274 /* 4275 * Get the second variable. 4276 */ 4277 *arg = skipwhite(*arg + 1); 4278 if (eval7(arg, &var2, evaluate) == FAIL) 4279 return FAIL; 4280 4281 if (evaluate) 4282 { 4283 n2 = get_tv_number_chk(&var2, &error); 4284 clear_tv(&var2); 4285 if (error) 4286 return FAIL; 4287 4288 /* 4289 * Compute the result. 4290 */ 4291 if (op == '*') 4292 n1 = n1 * n2; 4293 else if (op == '/') 4294 { 4295 if (n2 == 0) /* give an error message? */ 4296 n1 = 0x7fffffffL; 4297 else 4298 n1 = n1 / n2; 4299 } 4300 else 4301 { 4302 if (n2 == 0) /* give an error message? */ 4303 n1 = 0; 4304 else 4305 n1 = n1 % n2; 4306 } 4307 rettv->v_type = VAR_NUMBER; 4308 rettv->vval.v_number = n1; 4309 } 4310 } 4311 4312 return OK; 4313 } 4314 4315 /* 4316 * Handle sixth level expression: 4317 * number number constant 4318 * "string" string contstant 4319 * 'string' literal string contstant 4320 * &option-name option value 4321 * @r register contents 4322 * identifier variable value 4323 * function() function call 4324 * $VAR environment variable 4325 * (expression) nested expression 4326 * [expr, expr] List 4327 * {key: val, key: val} Dictionary 4328 * 4329 * Also handle: 4330 * ! in front logical NOT 4331 * - in front unary minus 4332 * + in front unary plus (ignored) 4333 * trailing [] subscript in String or List 4334 * trailing .name entry in Dictionary 4335 * 4336 * "arg" must point to the first non-white of the expression. 4337 * "arg" is advanced to the next non-white after the recognized expression. 4338 * 4339 * Return OK or FAIL. 4340 */ 4341 static int 4342 eval7(arg, rettv, evaluate) 4343 char_u **arg; 4344 typval_T *rettv; 4345 int evaluate; 4346 { 4347 long n; 4348 int len; 4349 char_u *s; 4350 int val; 4351 char_u *start_leader, *end_leader; 4352 int ret = OK; 4353 char_u *alias; 4354 4355 /* 4356 * Initialise variable so that clear_tv() can't mistake this for a 4357 * string and free a string that isn't there. 4358 */ 4359 rettv->v_type = VAR_UNKNOWN; 4360 4361 /* 4362 * Skip '!' and '-' characters. They are handled later. 4363 */ 4364 start_leader = *arg; 4365 while (**arg == '!' || **arg == '-' || **arg == '+') 4366 *arg = skipwhite(*arg + 1); 4367 end_leader = *arg; 4368 4369 switch (**arg) 4370 { 4371 /* 4372 * Number constant. 4373 */ 4374 case '0': 4375 case '1': 4376 case '2': 4377 case '3': 4378 case '4': 4379 case '5': 4380 case '6': 4381 case '7': 4382 case '8': 4383 case '9': 4384 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4385 *arg += len; 4386 if (evaluate) 4387 { 4388 rettv->v_type = VAR_NUMBER; 4389 rettv->vval.v_number = n; 4390 } 4391 break; 4392 4393 /* 4394 * String constant: "string". 4395 */ 4396 case '"': ret = get_string_tv(arg, rettv, evaluate); 4397 break; 4398 4399 /* 4400 * Literal string constant: 'str''ing'. 4401 */ 4402 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4403 break; 4404 4405 /* 4406 * List: [expr, expr] 4407 */ 4408 case '[': ret = get_list_tv(arg, rettv, evaluate); 4409 break; 4410 4411 /* 4412 * Dictionary: {key: val, key: val} 4413 */ 4414 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4415 break; 4416 4417 /* 4418 * Option value: &name 4419 */ 4420 case '&': ret = get_option_tv(arg, rettv, evaluate); 4421 break; 4422 4423 /* 4424 * Environment variable: $VAR. 4425 */ 4426 case '$': ret = get_env_tv(arg, rettv, evaluate); 4427 break; 4428 4429 /* 4430 * Register contents: @r. 4431 */ 4432 case '@': ++*arg; 4433 if (evaluate) 4434 { 4435 rettv->v_type = VAR_STRING; 4436 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4437 } 4438 if (**arg != NUL) 4439 ++*arg; 4440 break; 4441 4442 /* 4443 * nested expression: (expression). 4444 */ 4445 case '(': *arg = skipwhite(*arg + 1); 4446 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4447 if (**arg == ')') 4448 ++*arg; 4449 else if (ret == OK) 4450 { 4451 EMSG(_("E110: Missing ')'")); 4452 clear_tv(rettv); 4453 ret = FAIL; 4454 } 4455 break; 4456 4457 default: ret = NOTDONE; 4458 break; 4459 } 4460 4461 if (ret == NOTDONE) 4462 { 4463 /* 4464 * Must be a variable or function name. 4465 * Can also be a curly-braces kind of name: {expr}. 4466 */ 4467 s = *arg; 4468 len = get_name_len(arg, &alias, evaluate, TRUE); 4469 if (alias != NULL) 4470 s = alias; 4471 4472 if (len <= 0) 4473 ret = FAIL; 4474 else 4475 { 4476 if (**arg == '(') /* recursive! */ 4477 { 4478 /* If "s" is the name of a variable of type VAR_FUNC 4479 * use its contents. */ 4480 s = deref_func_name(s, &len); 4481 4482 /* Invoke the function. */ 4483 ret = get_func_tv(s, len, rettv, arg, 4484 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4485 &len, evaluate, NULL); 4486 /* Stop the expression evaluation when immediately 4487 * aborting on error, or when an interrupt occurred or 4488 * an exception was thrown but not caught. */ 4489 if (aborting()) 4490 { 4491 if (ret == OK) 4492 clear_tv(rettv); 4493 ret = FAIL; 4494 } 4495 } 4496 else if (evaluate) 4497 ret = get_var_tv(s, len, rettv, TRUE); 4498 else 4499 ret = OK; 4500 } 4501 4502 if (alias != NULL) 4503 vim_free(alias); 4504 } 4505 4506 *arg = skipwhite(*arg); 4507 4508 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4509 * expr(expr). */ 4510 if (ret == OK) 4511 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4512 4513 /* 4514 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4515 */ 4516 if (ret == OK && evaluate && end_leader > start_leader) 4517 { 4518 int error = FALSE; 4519 4520 val = get_tv_number_chk(rettv, &error); 4521 if (error) 4522 { 4523 clear_tv(rettv); 4524 ret = FAIL; 4525 } 4526 else 4527 { 4528 while (end_leader > start_leader) 4529 { 4530 --end_leader; 4531 if (*end_leader == '!') 4532 val = !val; 4533 else if (*end_leader == '-') 4534 val = -val; 4535 } 4536 clear_tv(rettv); 4537 rettv->v_type = VAR_NUMBER; 4538 rettv->vval.v_number = val; 4539 } 4540 } 4541 4542 return ret; 4543 } 4544 4545 /* 4546 * Evaluate an "[expr]" or "[expr:expr]" index. 4547 * "*arg" points to the '['. 4548 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4549 */ 4550 static int 4551 eval_index(arg, rettv, evaluate, verbose) 4552 char_u **arg; 4553 typval_T *rettv; 4554 int evaluate; 4555 int verbose; /* give error messages */ 4556 { 4557 int empty1 = FALSE, empty2 = FALSE; 4558 typval_T var1, var2; 4559 long n1, n2 = 0; 4560 long len = -1; 4561 int range = FALSE; 4562 char_u *s; 4563 char_u *key = NULL; 4564 4565 if (rettv->v_type == VAR_FUNC) 4566 { 4567 if (verbose) 4568 EMSG(_("E695: Cannot index a Funcref")); 4569 return FAIL; 4570 } 4571 4572 if (**arg == '.') 4573 { 4574 /* 4575 * dict.name 4576 */ 4577 key = *arg + 1; 4578 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4579 ; 4580 if (len == 0) 4581 return FAIL; 4582 *arg = skipwhite(key + len); 4583 } 4584 else 4585 { 4586 /* 4587 * something[idx] 4588 * 4589 * Get the (first) variable from inside the []. 4590 */ 4591 *arg = skipwhite(*arg + 1); 4592 if (**arg == ':') 4593 empty1 = TRUE; 4594 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4595 return FAIL; 4596 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4597 { 4598 /* not a number or string */ 4599 clear_tv(&var1); 4600 return FAIL; 4601 } 4602 4603 /* 4604 * Get the second variable from inside the [:]. 4605 */ 4606 if (**arg == ':') 4607 { 4608 range = TRUE; 4609 *arg = skipwhite(*arg + 1); 4610 if (**arg == ']') 4611 empty2 = TRUE; 4612 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4613 { 4614 if (!empty1) 4615 clear_tv(&var1); 4616 return FAIL; 4617 } 4618 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4619 { 4620 /* not a number or string */ 4621 if (!empty1) 4622 clear_tv(&var1); 4623 clear_tv(&var2); 4624 return FAIL; 4625 } 4626 } 4627 4628 /* Check for the ']'. */ 4629 if (**arg != ']') 4630 { 4631 if (verbose) 4632 EMSG(_(e_missbrac)); 4633 clear_tv(&var1); 4634 if (range) 4635 clear_tv(&var2); 4636 return FAIL; 4637 } 4638 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4639 } 4640 4641 if (evaluate) 4642 { 4643 n1 = 0; 4644 if (!empty1 && rettv->v_type != VAR_DICT) 4645 { 4646 n1 = get_tv_number(&var1); 4647 clear_tv(&var1); 4648 } 4649 if (range) 4650 { 4651 if (empty2) 4652 n2 = -1; 4653 else 4654 { 4655 n2 = get_tv_number(&var2); 4656 clear_tv(&var2); 4657 } 4658 } 4659 4660 switch (rettv->v_type) 4661 { 4662 case VAR_NUMBER: 4663 case VAR_STRING: 4664 s = get_tv_string(rettv); 4665 len = (long)STRLEN(s); 4666 if (range) 4667 { 4668 /* The resulting variable is a substring. If the indexes 4669 * are out of range the result is empty. */ 4670 if (n1 < 0) 4671 { 4672 n1 = len + n1; 4673 if (n1 < 0) 4674 n1 = 0; 4675 } 4676 if (n2 < 0) 4677 n2 = len + n2; 4678 else if (n2 >= len) 4679 n2 = len; 4680 if (n1 >= len || n2 < 0 || n1 > n2) 4681 s = NULL; 4682 else 4683 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4684 } 4685 else 4686 { 4687 /* The resulting variable is a string of a single 4688 * character. If the index is too big or negative the 4689 * result is empty. */ 4690 if (n1 >= len || n1 < 0) 4691 s = NULL; 4692 else 4693 s = vim_strnsave(s + n1, 1); 4694 } 4695 clear_tv(rettv); 4696 rettv->v_type = VAR_STRING; 4697 rettv->vval.v_string = s; 4698 break; 4699 4700 case VAR_LIST: 4701 len = list_len(rettv->vval.v_list); 4702 if (n1 < 0) 4703 n1 = len + n1; 4704 if (!empty1 && (n1 < 0 || n1 >= len)) 4705 { 4706 if (verbose) 4707 EMSGN(_(e_listidx), n1); 4708 return FAIL; 4709 } 4710 if (range) 4711 { 4712 list_T *l; 4713 listitem_T *item; 4714 4715 if (n2 < 0) 4716 n2 = len + n2; 4717 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4718 { 4719 if (verbose) 4720 EMSGN(_(e_listidx), n2); 4721 return FAIL; 4722 } 4723 l = list_alloc(); 4724 if (l == NULL) 4725 return FAIL; 4726 for (item = list_find(rettv->vval.v_list, n1); 4727 n1 <= n2; ++n1) 4728 { 4729 if (list_append_tv(l, &item->li_tv) == FAIL) 4730 { 4731 list_free(l); 4732 return FAIL; 4733 } 4734 item = item->li_next; 4735 } 4736 clear_tv(rettv); 4737 rettv->v_type = VAR_LIST; 4738 rettv->vval.v_list = l; 4739 ++l->lv_refcount; 4740 } 4741 else 4742 { 4743 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4744 &var1); 4745 clear_tv(rettv); 4746 *rettv = var1; 4747 } 4748 break; 4749 4750 case VAR_DICT: 4751 if (range) 4752 { 4753 if (verbose) 4754 EMSG(_(e_dictrange)); 4755 if (len == -1) 4756 clear_tv(&var1); 4757 return FAIL; 4758 } 4759 { 4760 dictitem_T *item; 4761 4762 if (len == -1) 4763 { 4764 key = get_tv_string(&var1); 4765 if (*key == NUL) 4766 { 4767 if (verbose) 4768 EMSG(_(e_emptykey)); 4769 clear_tv(&var1); 4770 return FAIL; 4771 } 4772 } 4773 4774 item = dict_find(rettv->vval.v_dict, key, (int)len); 4775 4776 if (item == NULL && verbose) 4777 EMSG2(_(e_dictkey), key); 4778 if (len == -1) 4779 clear_tv(&var1); 4780 if (item == NULL) 4781 return FAIL; 4782 4783 copy_tv(&item->di_tv, &var1); 4784 clear_tv(rettv); 4785 *rettv = var1; 4786 } 4787 break; 4788 } 4789 } 4790 4791 return OK; 4792 } 4793 4794 /* 4795 * Get an option value. 4796 * "arg" points to the '&' or '+' before the option name. 4797 * "arg" is advanced to character after the option name. 4798 * Return OK or FAIL. 4799 */ 4800 static int 4801 get_option_tv(arg, rettv, evaluate) 4802 char_u **arg; 4803 typval_T *rettv; /* when NULL, only check if option exists */ 4804 int evaluate; 4805 { 4806 char_u *option_end; 4807 long numval; 4808 char_u *stringval; 4809 int opt_type; 4810 int c; 4811 int working = (**arg == '+'); /* has("+option") */ 4812 int ret = OK; 4813 int opt_flags; 4814 4815 /* 4816 * Isolate the option name and find its value. 4817 */ 4818 option_end = find_option_end(arg, &opt_flags); 4819 if (option_end == NULL) 4820 { 4821 if (rettv != NULL) 4822 EMSG2(_("E112: Option name missing: %s"), *arg); 4823 return FAIL; 4824 } 4825 4826 if (!evaluate) 4827 { 4828 *arg = option_end; 4829 return OK; 4830 } 4831 4832 c = *option_end; 4833 *option_end = NUL; 4834 opt_type = get_option_value(*arg, &numval, 4835 rettv == NULL ? NULL : &stringval, opt_flags); 4836 4837 if (opt_type == -3) /* invalid name */ 4838 { 4839 if (rettv != NULL) 4840 EMSG2(_("E113: Unknown option: %s"), *arg); 4841 ret = FAIL; 4842 } 4843 else if (rettv != NULL) 4844 { 4845 if (opt_type == -2) /* hidden string option */ 4846 { 4847 rettv->v_type = VAR_STRING; 4848 rettv->vval.v_string = NULL; 4849 } 4850 else if (opt_type == -1) /* hidden number option */ 4851 { 4852 rettv->v_type = VAR_NUMBER; 4853 rettv->vval.v_number = 0; 4854 } 4855 else if (opt_type == 1) /* number option */ 4856 { 4857 rettv->v_type = VAR_NUMBER; 4858 rettv->vval.v_number = numval; 4859 } 4860 else /* string option */ 4861 { 4862 rettv->v_type = VAR_STRING; 4863 rettv->vval.v_string = stringval; 4864 } 4865 } 4866 else if (working && (opt_type == -2 || opt_type == -1)) 4867 ret = FAIL; 4868 4869 *option_end = c; /* put back for error messages */ 4870 *arg = option_end; 4871 4872 return ret; 4873 } 4874 4875 /* 4876 * Allocate a variable for a string constant. 4877 * Return OK or FAIL. 4878 */ 4879 static int 4880 get_string_tv(arg, rettv, evaluate) 4881 char_u **arg; 4882 typval_T *rettv; 4883 int evaluate; 4884 { 4885 char_u *p; 4886 char_u *name; 4887 int extra = 0; 4888 4889 /* 4890 * Find the end of the string, skipping backslashed characters. 4891 */ 4892 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4893 { 4894 if (*p == '\\' && p[1] != NUL) 4895 { 4896 ++p; 4897 /* A "\<x>" form occupies at least 4 characters, and produces up 4898 * to 6 characters: reserve space for 2 extra */ 4899 if (*p == '<') 4900 extra += 2; 4901 } 4902 } 4903 4904 if (*p != '"') 4905 { 4906 EMSG2(_("E114: Missing quote: %s"), *arg); 4907 return FAIL; 4908 } 4909 4910 /* If only parsing, set *arg and return here */ 4911 if (!evaluate) 4912 { 4913 *arg = p + 1; 4914 return OK; 4915 } 4916 4917 /* 4918 * Copy the string into allocated memory, handling backslashed 4919 * characters. 4920 */ 4921 name = alloc((unsigned)(p - *arg + extra)); 4922 if (name == NULL) 4923 return FAIL; 4924 rettv->v_type = VAR_STRING; 4925 rettv->vval.v_string = name; 4926 4927 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4928 { 4929 if (*p == '\\') 4930 { 4931 switch (*++p) 4932 { 4933 case 'b': *name++ = BS; ++p; break; 4934 case 'e': *name++ = ESC; ++p; break; 4935 case 'f': *name++ = FF; ++p; break; 4936 case 'n': *name++ = NL; ++p; break; 4937 case 'r': *name++ = CAR; ++p; break; 4938 case 't': *name++ = TAB; ++p; break; 4939 4940 case 'X': /* hex: "\x1", "\x12" */ 4941 case 'x': 4942 case 'u': /* Unicode: "\u0023" */ 4943 case 'U': 4944 if (vim_isxdigit(p[1])) 4945 { 4946 int n, nr; 4947 int c = toupper(*p); 4948 4949 if (c == 'X') 4950 n = 2; 4951 else 4952 n = 4; 4953 nr = 0; 4954 while (--n >= 0 && vim_isxdigit(p[1])) 4955 { 4956 ++p; 4957 nr = (nr << 4) + hex2nr(*p); 4958 } 4959 ++p; 4960 #ifdef FEAT_MBYTE 4961 /* For "\u" store the number according to 4962 * 'encoding'. */ 4963 if (c != 'X') 4964 name += (*mb_char2bytes)(nr, name); 4965 else 4966 #endif 4967 *name++ = nr; 4968 } 4969 break; 4970 4971 /* octal: "\1", "\12", "\123" */ 4972 case '0': 4973 case '1': 4974 case '2': 4975 case '3': 4976 case '4': 4977 case '5': 4978 case '6': 4979 case '7': *name = *p++ - '0'; 4980 if (*p >= '0' && *p <= '7') 4981 { 4982 *name = (*name << 3) + *p++ - '0'; 4983 if (*p >= '0' && *p <= '7') 4984 *name = (*name << 3) + *p++ - '0'; 4985 } 4986 ++name; 4987 break; 4988 4989 /* Special key, e.g.: "\<C-W>" */ 4990 case '<': extra = trans_special(&p, name, TRUE); 4991 if (extra != 0) 4992 { 4993 name += extra; 4994 break; 4995 } 4996 /* FALLTHROUGH */ 4997 4998 default: MB_COPY_CHAR(p, name); 4999 break; 5000 } 5001 } 5002 else 5003 MB_COPY_CHAR(p, name); 5004 5005 } 5006 *name = NUL; 5007 *arg = p + 1; 5008 5009 return OK; 5010 } 5011 5012 /* 5013 * Allocate a variable for a 'str''ing' constant. 5014 * Return OK or FAIL. 5015 */ 5016 static int 5017 get_lit_string_tv(arg, rettv, evaluate) 5018 char_u **arg; 5019 typval_T *rettv; 5020 int evaluate; 5021 { 5022 char_u *p; 5023 char_u *str; 5024 int reduce = 0; 5025 5026 /* 5027 * Find the end of the string, skipping ''. 5028 */ 5029 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5030 { 5031 if (*p == '\'') 5032 { 5033 if (p[1] != '\'') 5034 break; 5035 ++reduce; 5036 ++p; 5037 } 5038 } 5039 5040 if (*p != '\'') 5041 { 5042 EMSG2(_("E115: Missing quote: %s"), *arg); 5043 return FAIL; 5044 } 5045 5046 /* If only parsing return after setting "*arg" */ 5047 if (!evaluate) 5048 { 5049 *arg = p + 1; 5050 return OK; 5051 } 5052 5053 /* 5054 * Copy the string into allocated memory, handling '' to ' reduction. 5055 */ 5056 str = alloc((unsigned)((p - *arg) - reduce)); 5057 if (str == NULL) 5058 return FAIL; 5059 rettv->v_type = VAR_STRING; 5060 rettv->vval.v_string = str; 5061 5062 for (p = *arg + 1; *p != NUL; ) 5063 { 5064 if (*p == '\'') 5065 { 5066 if (p[1] != '\'') 5067 break; 5068 ++p; 5069 } 5070 MB_COPY_CHAR(p, str); 5071 } 5072 *str = NUL; 5073 *arg = p + 1; 5074 5075 return OK; 5076 } 5077 5078 /* 5079 * Allocate a variable for a List and fill it from "*arg". 5080 * Return OK or FAIL. 5081 */ 5082 static int 5083 get_list_tv(arg, rettv, evaluate) 5084 char_u **arg; 5085 typval_T *rettv; 5086 int evaluate; 5087 { 5088 list_T *l = NULL; 5089 typval_T tv; 5090 listitem_T *item; 5091 5092 if (evaluate) 5093 { 5094 l = list_alloc(); 5095 if (l == NULL) 5096 return FAIL; 5097 } 5098 5099 *arg = skipwhite(*arg + 1); 5100 while (**arg != ']' && **arg != NUL) 5101 { 5102 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5103 goto failret; 5104 if (evaluate) 5105 { 5106 item = listitem_alloc(); 5107 if (item != NULL) 5108 { 5109 item->li_tv = tv; 5110 item->li_tv.v_lock = 0; 5111 list_append(l, item); 5112 } 5113 else 5114 clear_tv(&tv); 5115 } 5116 5117 if (**arg == ']') 5118 break; 5119 if (**arg != ',') 5120 { 5121 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5122 goto failret; 5123 } 5124 *arg = skipwhite(*arg + 1); 5125 } 5126 5127 if (**arg != ']') 5128 { 5129 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5130 failret: 5131 if (evaluate) 5132 list_free(l); 5133 return FAIL; 5134 } 5135 5136 *arg = skipwhite(*arg + 1); 5137 if (evaluate) 5138 { 5139 rettv->v_type = VAR_LIST; 5140 rettv->vval.v_list = l; 5141 ++l->lv_refcount; 5142 } 5143 5144 return OK; 5145 } 5146 5147 /* 5148 * Allocate an empty header for a list. 5149 */ 5150 static list_T * 5151 list_alloc() 5152 { 5153 list_T *l; 5154 5155 l = (list_T *)alloc_clear(sizeof(list_T)); 5156 if (l != NULL) 5157 { 5158 /* Prepend the list to the list of lists for garbage collection. */ 5159 if (first_list != NULL) 5160 first_list->lv_used_prev = l; 5161 l->lv_used_prev = NULL; 5162 l->lv_used_next = first_list; 5163 first_list = l; 5164 } 5165 return l; 5166 } 5167 5168 /* 5169 * Unreference a list: decrement the reference count and free it when it 5170 * becomes zero. 5171 */ 5172 void 5173 list_unref(l) 5174 list_T *l; 5175 { 5176 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5177 list_free(l); 5178 } 5179 5180 /* 5181 * Free a list, including all items it points to. 5182 * Ignores the reference count. 5183 */ 5184 static void 5185 list_free(l) 5186 list_T *l; 5187 { 5188 listitem_T *item; 5189 5190 /* Avoid that recursive reference to the list frees us again. */ 5191 l->lv_refcount = DEL_REFCOUNT; 5192 5193 /* Remove the list from the list of lists for garbage collection. */ 5194 if (l->lv_used_prev == NULL) 5195 first_list = l->lv_used_next; 5196 else 5197 l->lv_used_prev->lv_used_next = l->lv_used_next; 5198 if (l->lv_used_next != NULL) 5199 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5200 5201 for (item = l->lv_first; item != NULL; item = l->lv_first) 5202 { 5203 /* Remove the item before deleting it. */ 5204 l->lv_first = item->li_next; 5205 listitem_free(item); 5206 } 5207 vim_free(l); 5208 } 5209 5210 /* 5211 * Allocate a list item. 5212 */ 5213 static listitem_T * 5214 listitem_alloc() 5215 { 5216 return (listitem_T *)alloc(sizeof(listitem_T)); 5217 } 5218 5219 /* 5220 * Free a list item. Also clears the value. Does not notify watchers. 5221 */ 5222 static void 5223 listitem_free(item) 5224 listitem_T *item; 5225 { 5226 clear_tv(&item->li_tv); 5227 vim_free(item); 5228 } 5229 5230 /* 5231 * Remove a list item from a List and free it. Also clears the value. 5232 */ 5233 static void 5234 listitem_remove(l, item) 5235 list_T *l; 5236 listitem_T *item; 5237 { 5238 list_remove(l, item, item); 5239 listitem_free(item); 5240 } 5241 5242 /* 5243 * Get the number of items in a list. 5244 */ 5245 static long 5246 list_len(l) 5247 list_T *l; 5248 { 5249 if (l == NULL) 5250 return 0L; 5251 return l->lv_len; 5252 } 5253 5254 /* 5255 * Return TRUE when two lists have exactly the same values. 5256 */ 5257 static int 5258 list_equal(l1, l2, ic) 5259 list_T *l1; 5260 list_T *l2; 5261 int ic; /* ignore case for strings */ 5262 { 5263 listitem_T *item1, *item2; 5264 5265 if (list_len(l1) != list_len(l2)) 5266 return FALSE; 5267 5268 for (item1 = l1->lv_first, item2 = l2->lv_first; 5269 item1 != NULL && item2 != NULL; 5270 item1 = item1->li_next, item2 = item2->li_next) 5271 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5272 return FALSE; 5273 return item1 == NULL && item2 == NULL; 5274 } 5275 5276 /* 5277 * Return TRUE when two dictionaries have exactly the same key/values. 5278 */ 5279 static int 5280 dict_equal(d1, d2, ic) 5281 dict_T *d1; 5282 dict_T *d2; 5283 int ic; /* ignore case for strings */ 5284 { 5285 hashitem_T *hi; 5286 dictitem_T *item2; 5287 int todo; 5288 5289 if (dict_len(d1) != dict_len(d2)) 5290 return FALSE; 5291 5292 todo = d1->dv_hashtab.ht_used; 5293 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5294 { 5295 if (!HASHITEM_EMPTY(hi)) 5296 { 5297 item2 = dict_find(d2, hi->hi_key, -1); 5298 if (item2 == NULL) 5299 return FALSE; 5300 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5301 return FALSE; 5302 --todo; 5303 } 5304 } 5305 return TRUE; 5306 } 5307 5308 /* 5309 * Return TRUE if "tv1" and "tv2" have the same value. 5310 * Compares the items just like "==" would compare them, but strings and 5311 * numbers are different. 5312 */ 5313 static int 5314 tv_equal(tv1, tv2, ic) 5315 typval_T *tv1; 5316 typval_T *tv2; 5317 int ic; /* ignore case */ 5318 { 5319 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5320 char_u *s1, *s2; 5321 5322 if (tv1->v_type != tv2->v_type) 5323 return FALSE; 5324 5325 switch (tv1->v_type) 5326 { 5327 case VAR_LIST: 5328 /* recursive! */ 5329 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5330 5331 case VAR_DICT: 5332 /* recursive! */ 5333 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5334 5335 case VAR_FUNC: 5336 return (tv1->vval.v_string != NULL 5337 && tv2->vval.v_string != NULL 5338 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5339 5340 case VAR_NUMBER: 5341 return tv1->vval.v_number == tv2->vval.v_number; 5342 5343 case VAR_STRING: 5344 s1 = get_tv_string_buf(tv1, buf1); 5345 s2 = get_tv_string_buf(tv2, buf2); 5346 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5347 } 5348 5349 EMSG2(_(e_intern2), "tv_equal()"); 5350 return TRUE; 5351 } 5352 5353 /* 5354 * Locate item with index "n" in list "l" and return it. 5355 * A negative index is counted from the end; -1 is the last item. 5356 * Returns NULL when "n" is out of range. 5357 */ 5358 static listitem_T * 5359 list_find(l, n) 5360 list_T *l; 5361 long n; 5362 { 5363 listitem_T *item; 5364 long idx; 5365 5366 if (l == NULL) 5367 return NULL; 5368 5369 /* Negative index is relative to the end. */ 5370 if (n < 0) 5371 n = l->lv_len + n; 5372 5373 /* Check for index out of range. */ 5374 if (n < 0 || n >= l->lv_len) 5375 return NULL; 5376 5377 /* When there is a cached index may start search from there. */ 5378 if (l->lv_idx_item != NULL) 5379 { 5380 if (n < l->lv_idx / 2) 5381 { 5382 /* closest to the start of the list */ 5383 item = l->lv_first; 5384 idx = 0; 5385 } 5386 else if (n > (l->lv_idx + l->lv_len) / 2) 5387 { 5388 /* closest to the end of the list */ 5389 item = l->lv_last; 5390 idx = l->lv_len - 1; 5391 } 5392 else 5393 { 5394 /* closest to the cached index */ 5395 item = l->lv_idx_item; 5396 idx = l->lv_idx; 5397 } 5398 } 5399 else 5400 { 5401 if (n < l->lv_len / 2) 5402 { 5403 /* closest to the start of the list */ 5404 item = l->lv_first; 5405 idx = 0; 5406 } 5407 else 5408 { 5409 /* closest to the end of the list */ 5410 item = l->lv_last; 5411 idx = l->lv_len - 1; 5412 } 5413 } 5414 5415 while (n > idx) 5416 { 5417 /* search forward */ 5418 item = item->li_next; 5419 ++idx; 5420 } 5421 while (n < idx) 5422 { 5423 /* search backward */ 5424 item = item->li_prev; 5425 --idx; 5426 } 5427 5428 /* cache the used index */ 5429 l->lv_idx = idx; 5430 l->lv_idx_item = item; 5431 5432 return item; 5433 } 5434 5435 /* 5436 * Locate "item" list "l" and return its index. 5437 * Returns -1 when "item" is not in the list. 5438 */ 5439 static long 5440 list_idx_of_item(l, item) 5441 list_T *l; 5442 listitem_T *item; 5443 { 5444 long idx = 0; 5445 listitem_T *li; 5446 5447 if (l == NULL) 5448 return -1; 5449 idx = 0; 5450 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5451 ++idx; 5452 if (li == NULL) 5453 return -1; 5454 return idx; 5455 } 5456 5457 /* 5458 * Append item "item" to the end of list "l". 5459 */ 5460 static void 5461 list_append(l, item) 5462 list_T *l; 5463 listitem_T *item; 5464 { 5465 if (l->lv_last == NULL) 5466 { 5467 /* empty list */ 5468 l->lv_first = item; 5469 l->lv_last = item; 5470 item->li_prev = NULL; 5471 } 5472 else 5473 { 5474 l->lv_last->li_next = item; 5475 item->li_prev = l->lv_last; 5476 l->lv_last = item; 5477 } 5478 ++l->lv_len; 5479 item->li_next = NULL; 5480 } 5481 5482 /* 5483 * Append typval_T "tv" to the end of list "l". 5484 * Return FAIL when out of memory. 5485 */ 5486 static int 5487 list_append_tv(l, tv) 5488 list_T *l; 5489 typval_T *tv; 5490 { 5491 listitem_T *li = listitem_alloc(); 5492 5493 if (li == NULL) 5494 return FAIL; 5495 copy_tv(tv, &li->li_tv); 5496 list_append(l, li); 5497 return OK; 5498 } 5499 5500 /* 5501 * Add a dictionary to a list. Used by getqflist(). 5502 * Return FAIL when out of memory. 5503 */ 5504 int 5505 list_append_dict(list, dict) 5506 list_T *list; 5507 dict_T *dict; 5508 { 5509 listitem_T *li = listitem_alloc(); 5510 5511 if (li == NULL) 5512 return FAIL; 5513 li->li_tv.v_type = VAR_DICT; 5514 li->li_tv.v_lock = 0; 5515 li->li_tv.vval.v_dict = dict; 5516 list_append(list, li); 5517 ++dict->dv_refcount; 5518 return OK; 5519 } 5520 5521 /* 5522 * Insert typval_T "tv" in list "l" before "item". 5523 * If "item" is NULL append at the end. 5524 * Return FAIL when out of memory. 5525 */ 5526 static int 5527 list_insert_tv(l, tv, item) 5528 list_T *l; 5529 typval_T *tv; 5530 listitem_T *item; 5531 { 5532 listitem_T *ni = listitem_alloc(); 5533 5534 if (ni == NULL) 5535 return FAIL; 5536 copy_tv(tv, &ni->li_tv); 5537 if (item == NULL) 5538 /* Append new item at end of list. */ 5539 list_append(l, ni); 5540 else 5541 { 5542 /* Insert new item before existing item. */ 5543 ni->li_prev = item->li_prev; 5544 ni->li_next = item; 5545 if (item->li_prev == NULL) 5546 { 5547 l->lv_first = ni; 5548 ++l->lv_idx; 5549 } 5550 else 5551 { 5552 item->li_prev->li_next = ni; 5553 l->lv_idx_item = NULL; 5554 } 5555 item->li_prev = ni; 5556 ++l->lv_len; 5557 } 5558 return OK; 5559 } 5560 5561 /* 5562 * Extend "l1" with "l2". 5563 * If "bef" is NULL append at the end, otherwise insert before this item. 5564 * Returns FAIL when out of memory. 5565 */ 5566 static int 5567 list_extend(l1, l2, bef) 5568 list_T *l1; 5569 list_T *l2; 5570 listitem_T *bef; 5571 { 5572 listitem_T *item; 5573 5574 for (item = l2->lv_first; item != NULL; item = item->li_next) 5575 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5576 return FAIL; 5577 return OK; 5578 } 5579 5580 /* 5581 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5582 * Return FAIL when out of memory. 5583 */ 5584 static int 5585 list_concat(l1, l2, tv) 5586 list_T *l1; 5587 list_T *l2; 5588 typval_T *tv; 5589 { 5590 list_T *l; 5591 5592 /* make a copy of the first list. */ 5593 l = list_copy(l1, FALSE, 0); 5594 if (l == NULL) 5595 return FAIL; 5596 tv->v_type = VAR_LIST; 5597 tv->vval.v_list = l; 5598 5599 /* append all items from the second list */ 5600 return list_extend(l, l2, NULL); 5601 } 5602 5603 /* 5604 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5605 * The refcount of the new list is set to 1. 5606 * See item_copy() for "copyID". 5607 * Returns NULL when out of memory. 5608 */ 5609 static list_T * 5610 list_copy(orig, deep, copyID) 5611 list_T *orig; 5612 int deep; 5613 int copyID; 5614 { 5615 list_T *copy; 5616 listitem_T *item; 5617 listitem_T *ni; 5618 5619 if (orig == NULL) 5620 return NULL; 5621 5622 copy = list_alloc(); 5623 if (copy != NULL) 5624 { 5625 if (copyID != 0) 5626 { 5627 /* Do this before adding the items, because one of the items may 5628 * refer back to this list. */ 5629 orig->lv_copyID = copyID; 5630 orig->lv_copylist = copy; 5631 } 5632 for (item = orig->lv_first; item != NULL && !got_int; 5633 item = item->li_next) 5634 { 5635 ni = listitem_alloc(); 5636 if (ni == NULL) 5637 break; 5638 if (deep) 5639 { 5640 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5641 { 5642 vim_free(ni); 5643 break; 5644 } 5645 } 5646 else 5647 copy_tv(&item->li_tv, &ni->li_tv); 5648 list_append(copy, ni); 5649 } 5650 ++copy->lv_refcount; 5651 if (item != NULL) 5652 { 5653 list_unref(copy); 5654 copy = NULL; 5655 } 5656 } 5657 5658 return copy; 5659 } 5660 5661 /* 5662 * Remove items "item" to "item2" from list "l". 5663 * Does not free the listitem or the value! 5664 */ 5665 static void 5666 list_remove(l, item, item2) 5667 list_T *l; 5668 listitem_T *item; 5669 listitem_T *item2; 5670 { 5671 listitem_T *ip; 5672 5673 /* notify watchers */ 5674 for (ip = item; ip != NULL; ip = ip->li_next) 5675 { 5676 --l->lv_len; 5677 list_fix_watch(l, ip); 5678 if (ip == item2) 5679 break; 5680 } 5681 5682 if (item2->li_next == NULL) 5683 l->lv_last = item->li_prev; 5684 else 5685 item2->li_next->li_prev = item->li_prev; 5686 if (item->li_prev == NULL) 5687 l->lv_first = item2->li_next; 5688 else 5689 item->li_prev->li_next = item2->li_next; 5690 l->lv_idx_item = NULL; 5691 } 5692 5693 /* 5694 * Return an allocated string with the string representation of a list. 5695 * May return NULL. 5696 */ 5697 static char_u * 5698 list2string(tv) 5699 typval_T *tv; 5700 { 5701 garray_T ga; 5702 5703 if (tv->vval.v_list == NULL) 5704 return NULL; 5705 ga_init2(&ga, (int)sizeof(char), 80); 5706 ga_append(&ga, '['); 5707 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5708 { 5709 vim_free(ga.ga_data); 5710 return NULL; 5711 } 5712 ga_append(&ga, ']'); 5713 ga_append(&ga, NUL); 5714 return (char_u *)ga.ga_data; 5715 } 5716 5717 /* 5718 * Join list "l" into a string in "*gap", using separator "sep". 5719 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5720 * Return FAIL or OK. 5721 */ 5722 static int 5723 list_join(gap, l, sep, echo) 5724 garray_T *gap; 5725 list_T *l; 5726 char_u *sep; 5727 int echo; 5728 { 5729 int first = TRUE; 5730 char_u *tofree; 5731 char_u numbuf[NUMBUFLEN]; 5732 listitem_T *item; 5733 char_u *s; 5734 5735 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5736 { 5737 if (first) 5738 first = FALSE; 5739 else 5740 ga_concat(gap, sep); 5741 5742 if (echo) 5743 s = echo_string(&item->li_tv, &tofree, numbuf); 5744 else 5745 s = tv2string(&item->li_tv, &tofree, numbuf); 5746 if (s != NULL) 5747 ga_concat(gap, s); 5748 vim_free(tofree); 5749 if (s == NULL) 5750 return FAIL; 5751 } 5752 return OK; 5753 } 5754 5755 /* 5756 * Garbage collection for lists and dictionaries. 5757 * 5758 * We use reference counts to be able to free most items right away when they 5759 * are no longer used. But for composite items it's possible that it becomes 5760 * unused while the reference count is > 0: When there is a recursive 5761 * reference. Example: 5762 * :let l = [1, 2, 3] 5763 * :let d = {9: l} 5764 * :let l[1] = d 5765 * 5766 * Since this is quite unusual we handle this with garbage collection: every 5767 * once in a while find out which lists and dicts are not referenced from any 5768 * variable. 5769 * 5770 * Here is a good reference text about garbage collection (refers to Python 5771 * but it applies to all reference-counting mechanisms): 5772 * http://python.ca/nas/python/gc/ 5773 */ 5774 5775 /* 5776 * Do garbage collection for lists and dicts. 5777 * Return TRUE if some memory was freed. 5778 */ 5779 int 5780 garbage_collect() 5781 { 5782 dict_T *dd; 5783 list_T *ll; 5784 int copyID = ++current_copyID; 5785 buf_T *buf; 5786 win_T *wp; 5787 int i; 5788 funccall_T *fc; 5789 int did_free = FALSE; 5790 5791 /* 5792 * 1. Go through all accessible variables and mark all lists and dicts 5793 * with copyID. 5794 */ 5795 /* script-local variables */ 5796 for (i = 1; i <= ga_scripts.ga_len; ++i) 5797 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5798 5799 /* buffer-local variables */ 5800 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5801 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5802 5803 /* window-local variables */ 5804 FOR_ALL_WINDOWS(wp) 5805 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5806 5807 /* global variables */ 5808 set_ref_in_ht(&globvarht, copyID); 5809 5810 /* function-local variables */ 5811 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5812 { 5813 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5814 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5815 } 5816 5817 /* 5818 * 2. Go through the list of dicts and free items without the copyID. 5819 */ 5820 for (dd = first_dict; dd != NULL; ) 5821 if (dd->dv_copyID != copyID) 5822 { 5823 dict_free(dd); 5824 did_free = TRUE; 5825 5826 /* restart, next dict may also have been freed */ 5827 dd = first_dict; 5828 } 5829 else 5830 dd = dd->dv_used_next; 5831 5832 /* 5833 * 3. Go through the list of lists and free items without the copyID. 5834 */ 5835 for (ll = first_list; ll != NULL; ) 5836 if (ll->lv_copyID != copyID) 5837 { 5838 list_free(ll); 5839 did_free = TRUE; 5840 5841 /* restart, next dict may also have been freed */ 5842 ll = first_list; 5843 } 5844 else 5845 ll = ll->lv_used_next; 5846 5847 return did_free; 5848 } 5849 5850 /* 5851 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5852 */ 5853 static void 5854 set_ref_in_ht(ht, copyID) 5855 hashtab_T *ht; 5856 int copyID; 5857 { 5858 int todo; 5859 hashitem_T *hi; 5860 5861 todo = ht->ht_used; 5862 for (hi = ht->ht_array; todo > 0; ++hi) 5863 if (!HASHITEM_EMPTY(hi)) 5864 { 5865 --todo; 5866 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5867 } 5868 } 5869 5870 /* 5871 * Mark all lists and dicts referenced through list "l" with "copyID". 5872 */ 5873 static void 5874 set_ref_in_list(l, copyID) 5875 list_T *l; 5876 int copyID; 5877 { 5878 listitem_T *li; 5879 5880 for (li = l->lv_first; li != NULL; li = li->li_next) 5881 set_ref_in_item(&li->li_tv, copyID); 5882 } 5883 5884 /* 5885 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5886 */ 5887 static void 5888 set_ref_in_item(tv, copyID) 5889 typval_T *tv; 5890 int copyID; 5891 { 5892 dict_T *dd; 5893 list_T *ll; 5894 5895 switch (tv->v_type) 5896 { 5897 case VAR_DICT: 5898 dd = tv->vval.v_dict; 5899 if (dd->dv_copyID != copyID) 5900 { 5901 /* Didn't see this dict yet. */ 5902 dd->dv_copyID = copyID; 5903 set_ref_in_ht(&dd->dv_hashtab, copyID); 5904 } 5905 break; 5906 5907 case VAR_LIST: 5908 ll = tv->vval.v_list; 5909 if (ll->lv_copyID != copyID) 5910 { 5911 /* Didn't see this list yet. */ 5912 ll->lv_copyID = copyID; 5913 set_ref_in_list(ll, copyID); 5914 } 5915 break; 5916 } 5917 return; 5918 } 5919 5920 /* 5921 * Allocate an empty header for a dictionary. 5922 */ 5923 dict_T * 5924 dict_alloc() 5925 { 5926 dict_T *d; 5927 5928 d = (dict_T *)alloc(sizeof(dict_T)); 5929 if (d != NULL) 5930 { 5931 /* Add the list to the hashtable for garbage collection. */ 5932 if (first_dict != NULL) 5933 first_dict->dv_used_prev = d; 5934 d->dv_used_next = first_dict; 5935 d->dv_used_prev = NULL; 5936 5937 hash_init(&d->dv_hashtab); 5938 d->dv_lock = 0; 5939 d->dv_refcount = 0; 5940 d->dv_copyID = 0; 5941 } 5942 return d; 5943 } 5944 5945 /* 5946 * Unreference a Dictionary: decrement the reference count and free it when it 5947 * becomes zero. 5948 */ 5949 static void 5950 dict_unref(d) 5951 dict_T *d; 5952 { 5953 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 5954 dict_free(d); 5955 } 5956 5957 /* 5958 * Free a Dictionary, including all items it contains. 5959 * Ignores the reference count. 5960 */ 5961 static void 5962 dict_free(d) 5963 dict_T *d; 5964 { 5965 int todo; 5966 hashitem_T *hi; 5967 dictitem_T *di; 5968 5969 /* Avoid that recursive reference to the dict frees us again. */ 5970 d->dv_refcount = DEL_REFCOUNT; 5971 5972 /* Remove the dict from the list of dicts for garbage collection. */ 5973 if (d->dv_used_prev == NULL) 5974 first_dict = d->dv_used_next; 5975 else 5976 d->dv_used_prev->dv_used_next = d->dv_used_next; 5977 if (d->dv_used_next != NULL) 5978 d->dv_used_next->dv_used_prev = d->dv_used_prev; 5979 5980 /* Lock the hashtab, we don't want it to resize while freeing items. */ 5981 hash_lock(&d->dv_hashtab); 5982 todo = d->dv_hashtab.ht_used; 5983 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 5984 { 5985 if (!HASHITEM_EMPTY(hi)) 5986 { 5987 /* Remove the item before deleting it, just in case there is 5988 * something recursive causing trouble. */ 5989 di = HI2DI(hi); 5990 hash_remove(&d->dv_hashtab, hi); 5991 dictitem_free(di); 5992 --todo; 5993 } 5994 } 5995 hash_clear(&d->dv_hashtab); 5996 vim_free(d); 5997 } 5998 5999 /* 6000 * Allocate a Dictionary item. 6001 * The "key" is copied to the new item. 6002 * Note that the value of the item "di_tv" still needs to be initialized! 6003 * Returns NULL when out of memory. 6004 */ 6005 static dictitem_T * 6006 dictitem_alloc(key) 6007 char_u *key; 6008 { 6009 dictitem_T *di; 6010 6011 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6012 if (di != NULL) 6013 { 6014 STRCPY(di->di_key, key); 6015 di->di_flags = 0; 6016 } 6017 return di; 6018 } 6019 6020 /* 6021 * Make a copy of a Dictionary item. 6022 */ 6023 static dictitem_T * 6024 dictitem_copy(org) 6025 dictitem_T *org; 6026 { 6027 dictitem_T *di; 6028 6029 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6030 if (di != NULL) 6031 { 6032 STRCPY(di->di_key, org->di_key); 6033 di->di_flags = 0; 6034 copy_tv(&org->di_tv, &di->di_tv); 6035 } 6036 return di; 6037 } 6038 6039 /* 6040 * Remove item "item" from Dictionary "dict" and free it. 6041 */ 6042 static void 6043 dictitem_remove(dict, item) 6044 dict_T *dict; 6045 dictitem_T *item; 6046 { 6047 hashitem_T *hi; 6048 6049 hi = hash_find(&dict->dv_hashtab, item->di_key); 6050 if (HASHITEM_EMPTY(hi)) 6051 EMSG2(_(e_intern2), "dictitem_remove()"); 6052 else 6053 hash_remove(&dict->dv_hashtab, hi); 6054 dictitem_free(item); 6055 } 6056 6057 /* 6058 * Free a dict item. Also clears the value. 6059 */ 6060 static void 6061 dictitem_free(item) 6062 dictitem_T *item; 6063 { 6064 clear_tv(&item->di_tv); 6065 vim_free(item); 6066 } 6067 6068 /* 6069 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6070 * The refcount of the new dict is set to 1. 6071 * See item_copy() for "copyID". 6072 * Returns NULL when out of memory. 6073 */ 6074 static dict_T * 6075 dict_copy(orig, deep, copyID) 6076 dict_T *orig; 6077 int deep; 6078 int copyID; 6079 { 6080 dict_T *copy; 6081 dictitem_T *di; 6082 int todo; 6083 hashitem_T *hi; 6084 6085 if (orig == NULL) 6086 return NULL; 6087 6088 copy = dict_alloc(); 6089 if (copy != NULL) 6090 { 6091 if (copyID != 0) 6092 { 6093 orig->dv_copyID = copyID; 6094 orig->dv_copydict = copy; 6095 } 6096 todo = orig->dv_hashtab.ht_used; 6097 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6098 { 6099 if (!HASHITEM_EMPTY(hi)) 6100 { 6101 --todo; 6102 6103 di = dictitem_alloc(hi->hi_key); 6104 if (di == NULL) 6105 break; 6106 if (deep) 6107 { 6108 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6109 copyID) == FAIL) 6110 { 6111 vim_free(di); 6112 break; 6113 } 6114 } 6115 else 6116 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6117 if (dict_add(copy, di) == FAIL) 6118 { 6119 dictitem_free(di); 6120 break; 6121 } 6122 } 6123 } 6124 6125 ++copy->dv_refcount; 6126 if (todo > 0) 6127 { 6128 dict_unref(copy); 6129 copy = NULL; 6130 } 6131 } 6132 6133 return copy; 6134 } 6135 6136 /* 6137 * Add item "item" to Dictionary "d". 6138 * Returns FAIL when out of memory and when key already existed. 6139 */ 6140 static int 6141 dict_add(d, item) 6142 dict_T *d; 6143 dictitem_T *item; 6144 { 6145 return hash_add(&d->dv_hashtab, item->di_key); 6146 } 6147 6148 /* 6149 * Add a number or string entry to dictionary "d". 6150 * When "str" is NULL use number "nr", otherwise use "str". 6151 * Returns FAIL when out of memory and when key already exists. 6152 */ 6153 int 6154 dict_add_nr_str(d, key, nr, str) 6155 dict_T *d; 6156 char *key; 6157 long nr; 6158 char_u *str; 6159 { 6160 dictitem_T *item; 6161 6162 item = dictitem_alloc((char_u *)key); 6163 if (item == NULL) 6164 return FAIL; 6165 item->di_tv.v_lock = 0; 6166 if (str == NULL) 6167 { 6168 item->di_tv.v_type = VAR_NUMBER; 6169 item->di_tv.vval.v_number = nr; 6170 } 6171 else 6172 { 6173 item->di_tv.v_type = VAR_STRING; 6174 item->di_tv.vval.v_string = vim_strsave(str); 6175 } 6176 if (dict_add(d, item) == FAIL) 6177 { 6178 dictitem_free(item); 6179 return FAIL; 6180 } 6181 return OK; 6182 } 6183 6184 /* 6185 * Get the number of items in a Dictionary. 6186 */ 6187 static long 6188 dict_len(d) 6189 dict_T *d; 6190 { 6191 if (d == NULL) 6192 return 0L; 6193 return d->dv_hashtab.ht_used; 6194 } 6195 6196 /* 6197 * Find item "key[len]" in Dictionary "d". 6198 * If "len" is negative use strlen(key). 6199 * Returns NULL when not found. 6200 */ 6201 static dictitem_T * 6202 dict_find(d, key, len) 6203 dict_T *d; 6204 char_u *key; 6205 int len; 6206 { 6207 #define AKEYLEN 200 6208 char_u buf[AKEYLEN]; 6209 char_u *akey; 6210 char_u *tofree = NULL; 6211 hashitem_T *hi; 6212 6213 if (len < 0) 6214 akey = key; 6215 else if (len >= AKEYLEN) 6216 { 6217 tofree = akey = vim_strnsave(key, len); 6218 if (akey == NULL) 6219 return NULL; 6220 } 6221 else 6222 { 6223 /* Avoid a malloc/free by using buf[]. */ 6224 vim_strncpy(buf, key, len); 6225 akey = buf; 6226 } 6227 6228 hi = hash_find(&d->dv_hashtab, akey); 6229 vim_free(tofree); 6230 if (HASHITEM_EMPTY(hi)) 6231 return NULL; 6232 return HI2DI(hi); 6233 } 6234 6235 /* 6236 * Get a string item from a dictionary in allocated memory. 6237 * Returns NULL if the entry doesn't exist or out of memory. 6238 */ 6239 char_u * 6240 get_dict_string(d, key) 6241 dict_T *d; 6242 char_u *key; 6243 { 6244 dictitem_T *di; 6245 6246 di = dict_find(d, key, -1); 6247 if (di == NULL) 6248 return NULL; 6249 return vim_strsave(get_tv_string(&di->di_tv)); 6250 } 6251 6252 /* 6253 * Get a number item from a dictionary. 6254 * Returns 0 if the entry doesn't exist or out of memory. 6255 */ 6256 long 6257 get_dict_number(d, key) 6258 dict_T *d; 6259 char_u *key; 6260 { 6261 dictitem_T *di; 6262 6263 di = dict_find(d, key, -1); 6264 if (di == NULL) 6265 return 0; 6266 return get_tv_number(&di->di_tv); 6267 } 6268 6269 /* 6270 * Return an allocated string with the string representation of a Dictionary. 6271 * May return NULL. 6272 */ 6273 static char_u * 6274 dict2string(tv) 6275 typval_T *tv; 6276 { 6277 garray_T ga; 6278 int first = TRUE; 6279 char_u *tofree; 6280 char_u numbuf[NUMBUFLEN]; 6281 hashitem_T *hi; 6282 char_u *s; 6283 dict_T *d; 6284 int todo; 6285 6286 if ((d = tv->vval.v_dict) == NULL) 6287 return NULL; 6288 ga_init2(&ga, (int)sizeof(char), 80); 6289 ga_append(&ga, '{'); 6290 6291 todo = d->dv_hashtab.ht_used; 6292 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6293 { 6294 if (!HASHITEM_EMPTY(hi)) 6295 { 6296 --todo; 6297 6298 if (first) 6299 first = FALSE; 6300 else 6301 ga_concat(&ga, (char_u *)", "); 6302 6303 tofree = string_quote(hi->hi_key, FALSE); 6304 if (tofree != NULL) 6305 { 6306 ga_concat(&ga, tofree); 6307 vim_free(tofree); 6308 } 6309 ga_concat(&ga, (char_u *)": "); 6310 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6311 if (s != NULL) 6312 ga_concat(&ga, s); 6313 vim_free(tofree); 6314 if (s == NULL) 6315 break; 6316 } 6317 } 6318 if (todo > 0) 6319 { 6320 vim_free(ga.ga_data); 6321 return NULL; 6322 } 6323 6324 ga_append(&ga, '}'); 6325 ga_append(&ga, NUL); 6326 return (char_u *)ga.ga_data; 6327 } 6328 6329 /* 6330 * Allocate a variable for a Dictionary and fill it from "*arg". 6331 * Return OK or FAIL. Returns NOTDONE for {expr}. 6332 */ 6333 static int 6334 get_dict_tv(arg, rettv, evaluate) 6335 char_u **arg; 6336 typval_T *rettv; 6337 int evaluate; 6338 { 6339 dict_T *d = NULL; 6340 typval_T tvkey; 6341 typval_T tv; 6342 char_u *key; 6343 dictitem_T *item; 6344 char_u *start = skipwhite(*arg + 1); 6345 char_u buf[NUMBUFLEN]; 6346 6347 /* 6348 * First check if it's not a curly-braces thing: {expr}. 6349 * Must do this without evaluating, otherwise a function may be called 6350 * twice. Unfortunately this means we need to call eval1() twice for the 6351 * first item. 6352 * But {} is an empty Dictionary. 6353 */ 6354 if (*start != '}') 6355 { 6356 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6357 return FAIL; 6358 if (*start == '}') 6359 return NOTDONE; 6360 } 6361 6362 if (evaluate) 6363 { 6364 d = dict_alloc(); 6365 if (d == NULL) 6366 return FAIL; 6367 } 6368 tvkey.v_type = VAR_UNKNOWN; 6369 tv.v_type = VAR_UNKNOWN; 6370 6371 *arg = skipwhite(*arg + 1); 6372 while (**arg != '}' && **arg != NUL) 6373 { 6374 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6375 goto failret; 6376 if (**arg != ':') 6377 { 6378 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6379 clear_tv(&tvkey); 6380 goto failret; 6381 } 6382 key = get_tv_string_buf_chk(&tvkey, buf); 6383 if (key == NULL || *key == NUL) 6384 { 6385 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6386 if (key != NULL) 6387 EMSG(_(e_emptykey)); 6388 clear_tv(&tvkey); 6389 goto failret; 6390 } 6391 6392 *arg = skipwhite(*arg + 1); 6393 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6394 { 6395 clear_tv(&tvkey); 6396 goto failret; 6397 } 6398 if (evaluate) 6399 { 6400 item = dict_find(d, key, -1); 6401 if (item != NULL) 6402 { 6403 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6404 clear_tv(&tvkey); 6405 clear_tv(&tv); 6406 goto failret; 6407 } 6408 item = dictitem_alloc(key); 6409 clear_tv(&tvkey); 6410 if (item != NULL) 6411 { 6412 item->di_tv = tv; 6413 item->di_tv.v_lock = 0; 6414 if (dict_add(d, item) == FAIL) 6415 dictitem_free(item); 6416 } 6417 } 6418 6419 if (**arg == '}') 6420 break; 6421 if (**arg != ',') 6422 { 6423 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6424 goto failret; 6425 } 6426 *arg = skipwhite(*arg + 1); 6427 } 6428 6429 if (**arg != '}') 6430 { 6431 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6432 failret: 6433 if (evaluate) 6434 dict_free(d); 6435 return FAIL; 6436 } 6437 6438 *arg = skipwhite(*arg + 1); 6439 if (evaluate) 6440 { 6441 rettv->v_type = VAR_DICT; 6442 rettv->vval.v_dict = d; 6443 ++d->dv_refcount; 6444 } 6445 6446 return OK; 6447 } 6448 6449 /* 6450 * Return a string with the string representation of a variable. 6451 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6452 * "numbuf" is used for a number. 6453 * Does not put quotes around strings, as ":echo" displays values. 6454 * May return NULL; 6455 */ 6456 static char_u * 6457 echo_string(tv, tofree, numbuf) 6458 typval_T *tv; 6459 char_u **tofree; 6460 char_u *numbuf; 6461 { 6462 static int recurse = 0; 6463 char_u *r = NULL; 6464 6465 if (recurse >= DICT_MAXNEST) 6466 { 6467 EMSG(_("E724: variable nested too deep for displaying")); 6468 *tofree = NULL; 6469 return NULL; 6470 } 6471 ++recurse; 6472 6473 switch (tv->v_type) 6474 { 6475 case VAR_FUNC: 6476 *tofree = NULL; 6477 r = tv->vval.v_string; 6478 break; 6479 case VAR_LIST: 6480 *tofree = list2string(tv); 6481 r = *tofree; 6482 break; 6483 case VAR_DICT: 6484 *tofree = dict2string(tv); 6485 r = *tofree; 6486 break; 6487 case VAR_STRING: 6488 case VAR_NUMBER: 6489 *tofree = NULL; 6490 r = get_tv_string_buf(tv, numbuf); 6491 break; 6492 default: 6493 EMSG2(_(e_intern2), "echo_string()"); 6494 *tofree = NULL; 6495 } 6496 6497 --recurse; 6498 return r; 6499 } 6500 6501 /* 6502 * Return a string with the string representation of a variable. 6503 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6504 * "numbuf" is used for a number. 6505 * Puts quotes around strings, so that they can be parsed back by eval(). 6506 * May return NULL; 6507 */ 6508 static char_u * 6509 tv2string(tv, tofree, numbuf) 6510 typval_T *tv; 6511 char_u **tofree; 6512 char_u *numbuf; 6513 { 6514 switch (tv->v_type) 6515 { 6516 case VAR_FUNC: 6517 *tofree = string_quote(tv->vval.v_string, TRUE); 6518 return *tofree; 6519 case VAR_STRING: 6520 *tofree = string_quote(tv->vval.v_string, FALSE); 6521 return *tofree; 6522 case VAR_NUMBER: 6523 case VAR_LIST: 6524 case VAR_DICT: 6525 break; 6526 default: 6527 EMSG2(_(e_intern2), "tv2string()"); 6528 } 6529 return echo_string(tv, tofree, numbuf); 6530 } 6531 6532 /* 6533 * Return string "str" in ' quotes, doubling ' characters. 6534 * If "str" is NULL an empty string is assumed. 6535 * If "function" is TRUE make it function('string'). 6536 */ 6537 static char_u * 6538 string_quote(str, function) 6539 char_u *str; 6540 int function; 6541 { 6542 unsigned len; 6543 char_u *p, *r, *s; 6544 6545 len = (function ? 13 : 3); 6546 if (str != NULL) 6547 { 6548 len += STRLEN(str); 6549 for (p = str; *p != NUL; mb_ptr_adv(p)) 6550 if (*p == '\'') 6551 ++len; 6552 } 6553 s = r = alloc(len); 6554 if (r != NULL) 6555 { 6556 if (function) 6557 { 6558 STRCPY(r, "function('"); 6559 r += 10; 6560 } 6561 else 6562 *r++ = '\''; 6563 if (str != NULL) 6564 for (p = str; *p != NUL; ) 6565 { 6566 if (*p == '\'') 6567 *r++ = '\''; 6568 MB_COPY_CHAR(p, r); 6569 } 6570 *r++ = '\''; 6571 if (function) 6572 *r++ = ')'; 6573 *r++ = NUL; 6574 } 6575 return s; 6576 } 6577 6578 /* 6579 * Get the value of an environment variable. 6580 * "arg" is pointing to the '$'. It is advanced to after the name. 6581 * If the environment variable was not set, silently assume it is empty. 6582 * Always return OK. 6583 */ 6584 static int 6585 get_env_tv(arg, rettv, evaluate) 6586 char_u **arg; 6587 typval_T *rettv; 6588 int evaluate; 6589 { 6590 char_u *string = NULL; 6591 int len; 6592 int cc; 6593 char_u *name; 6594 int mustfree = FALSE; 6595 6596 ++*arg; 6597 name = *arg; 6598 len = get_env_len(arg); 6599 if (evaluate) 6600 { 6601 if (len != 0) 6602 { 6603 cc = name[len]; 6604 name[len] = NUL; 6605 /* first try vim_getenv(), fast for normal environment vars */ 6606 string = vim_getenv(name, &mustfree); 6607 if (string != NULL && *string != NUL) 6608 { 6609 if (!mustfree) 6610 string = vim_strsave(string); 6611 } 6612 else 6613 { 6614 if (mustfree) 6615 vim_free(string); 6616 6617 /* next try expanding things like $VIM and ${HOME} */ 6618 string = expand_env_save(name - 1); 6619 if (string != NULL && *string == '$') 6620 { 6621 vim_free(string); 6622 string = NULL; 6623 } 6624 } 6625 name[len] = cc; 6626 } 6627 rettv->v_type = VAR_STRING; 6628 rettv->vval.v_string = string; 6629 } 6630 6631 return OK; 6632 } 6633 6634 /* 6635 * Array with names and number of arguments of all internal functions 6636 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6637 */ 6638 static struct fst 6639 { 6640 char *f_name; /* function name */ 6641 char f_min_argc; /* minimal number of arguments */ 6642 char f_max_argc; /* maximal number of arguments */ 6643 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6644 /* implemenation of function */ 6645 } functions[] = 6646 { 6647 {"add", 2, 2, f_add}, 6648 {"append", 2, 2, f_append}, 6649 {"argc", 0, 0, f_argc}, 6650 {"argidx", 0, 0, f_argidx}, 6651 {"argv", 1, 1, f_argv}, 6652 {"browse", 4, 4, f_browse}, 6653 {"browsedir", 2, 2, f_browsedir}, 6654 {"bufexists", 1, 1, f_bufexists}, 6655 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6656 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6657 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6658 {"buflisted", 1, 1, f_buflisted}, 6659 {"bufloaded", 1, 1, f_bufloaded}, 6660 {"bufname", 1, 1, f_bufname}, 6661 {"bufnr", 1, 1, f_bufnr}, 6662 {"bufwinnr", 1, 1, f_bufwinnr}, 6663 {"byte2line", 1, 1, f_byte2line}, 6664 {"byteidx", 2, 2, f_byteidx}, 6665 {"call", 2, 3, f_call}, 6666 {"char2nr", 1, 1, f_char2nr}, 6667 {"cindent", 1, 1, f_cindent}, 6668 {"col", 1, 1, f_col}, 6669 {"confirm", 1, 4, f_confirm}, 6670 {"copy", 1, 1, f_copy}, 6671 {"count", 2, 4, f_count}, 6672 {"cscope_connection",0,3, f_cscope_connection}, 6673 {"cursor", 2, 2, f_cursor}, 6674 {"deepcopy", 1, 2, f_deepcopy}, 6675 {"delete", 1, 1, f_delete}, 6676 {"did_filetype", 0, 0, f_did_filetype}, 6677 {"diff_filler", 1, 1, f_diff_filler}, 6678 {"diff_hlID", 2, 2, f_diff_hlID}, 6679 {"empty", 1, 1, f_empty}, 6680 {"escape", 2, 2, f_escape}, 6681 {"eval", 1, 1, f_eval}, 6682 {"eventhandler", 0, 0, f_eventhandler}, 6683 {"executable", 1, 1, f_executable}, 6684 {"exists", 1, 1, f_exists}, 6685 {"expand", 1, 2, f_expand}, 6686 {"extend", 2, 3, f_extend}, 6687 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6688 {"filereadable", 1, 1, f_filereadable}, 6689 {"filewritable", 1, 1, f_filewritable}, 6690 {"filter", 2, 2, f_filter}, 6691 {"finddir", 1, 3, f_finddir}, 6692 {"findfile", 1, 3, f_findfile}, 6693 {"fnamemodify", 2, 2, f_fnamemodify}, 6694 {"foldclosed", 1, 1, f_foldclosed}, 6695 {"foldclosedend", 1, 1, f_foldclosedend}, 6696 {"foldlevel", 1, 1, f_foldlevel}, 6697 {"foldtext", 0, 0, f_foldtext}, 6698 {"foldtextresult", 1, 1, f_foldtextresult}, 6699 {"foreground", 0, 0, f_foreground}, 6700 {"function", 1, 1, f_function}, 6701 {"garbagecollect", 0, 0, f_garbagecollect}, 6702 {"get", 2, 3, f_get}, 6703 {"getbufline", 2, 3, f_getbufline}, 6704 {"getbufvar", 2, 2, f_getbufvar}, 6705 {"getchar", 0, 1, f_getchar}, 6706 {"getcharmod", 0, 0, f_getcharmod}, 6707 {"getcmdline", 0, 0, f_getcmdline}, 6708 {"getcmdpos", 0, 0, f_getcmdpos}, 6709 {"getcwd", 0, 0, f_getcwd}, 6710 {"getfontname", 0, 1, f_getfontname}, 6711 {"getfperm", 1, 1, f_getfperm}, 6712 {"getfsize", 1, 1, f_getfsize}, 6713 {"getftime", 1, 1, f_getftime}, 6714 {"getftype", 1, 1, f_getftype}, 6715 {"getline", 1, 2, f_getline}, 6716 {"getqflist", 0, 0, f_getqflist}, 6717 {"getreg", 0, 2, f_getreg}, 6718 {"getregtype", 0, 1, f_getregtype}, 6719 {"getwinposx", 0, 0, f_getwinposx}, 6720 {"getwinposy", 0, 0, f_getwinposy}, 6721 {"getwinvar", 2, 2, f_getwinvar}, 6722 {"glob", 1, 1, f_glob}, 6723 {"globpath", 2, 2, f_globpath}, 6724 {"has", 1, 1, f_has}, 6725 {"has_key", 2, 2, f_has_key}, 6726 {"hasmapto", 1, 2, f_hasmapto}, 6727 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6728 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6729 {"histadd", 2, 2, f_histadd}, 6730 {"histdel", 1, 2, f_histdel}, 6731 {"histget", 1, 2, f_histget}, 6732 {"histnr", 1, 1, f_histnr}, 6733 {"hlID", 1, 1, f_hlID}, 6734 {"hlexists", 1, 1, f_hlexists}, 6735 {"hostname", 0, 0, f_hostname}, 6736 {"iconv", 3, 3, f_iconv}, 6737 {"indent", 1, 1, f_indent}, 6738 {"index", 2, 4, f_index}, 6739 {"input", 1, 2, f_input}, 6740 {"inputdialog", 1, 3, f_inputdialog}, 6741 {"inputrestore", 0, 0, f_inputrestore}, 6742 {"inputsave", 0, 0, f_inputsave}, 6743 {"inputsecret", 1, 2, f_inputsecret}, 6744 {"insert", 2, 3, f_insert}, 6745 {"isdirectory", 1, 1, f_isdirectory}, 6746 {"islocked", 1, 1, f_islocked}, 6747 {"items", 1, 1, f_items}, 6748 {"join", 1, 2, f_join}, 6749 {"keys", 1, 1, f_keys}, 6750 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6751 {"len", 1, 1, f_len}, 6752 {"libcall", 3, 3, f_libcall}, 6753 {"libcallnr", 3, 3, f_libcallnr}, 6754 {"line", 1, 1, f_line}, 6755 {"line2byte", 1, 1, f_line2byte}, 6756 {"lispindent", 1, 1, f_lispindent}, 6757 {"localtime", 0, 0, f_localtime}, 6758 {"map", 2, 2, f_map}, 6759 {"maparg", 1, 2, f_maparg}, 6760 {"mapcheck", 1, 2, f_mapcheck}, 6761 {"match", 2, 4, f_match}, 6762 {"matchend", 2, 4, f_matchend}, 6763 {"matchlist", 2, 4, f_matchlist}, 6764 {"matchstr", 2, 4, f_matchstr}, 6765 {"max", 1, 1, f_max}, 6766 {"min", 1, 1, f_min}, 6767 #ifdef vim_mkdir 6768 {"mkdir", 1, 3, f_mkdir}, 6769 #endif 6770 {"mode", 0, 0, f_mode}, 6771 {"nextnonblank", 1, 1, f_nextnonblank}, 6772 {"nr2char", 1, 1, f_nr2char}, 6773 {"prevnonblank", 1, 1, f_prevnonblank}, 6774 {"range", 1, 3, f_range}, 6775 {"readfile", 1, 3, f_readfile}, 6776 {"remote_expr", 2, 3, f_remote_expr}, 6777 {"remote_foreground", 1, 1, f_remote_foreground}, 6778 {"remote_peek", 1, 2, f_remote_peek}, 6779 {"remote_read", 1, 1, f_remote_read}, 6780 {"remote_send", 2, 3, f_remote_send}, 6781 {"remove", 2, 3, f_remove}, 6782 {"rename", 2, 2, f_rename}, 6783 {"repeat", 2, 2, f_repeat}, 6784 {"resolve", 1, 1, f_resolve}, 6785 {"reverse", 1, 1, f_reverse}, 6786 {"search", 1, 2, f_search}, 6787 {"searchpair", 3, 5, f_searchpair}, 6788 {"server2client", 2, 2, f_server2client}, 6789 {"serverlist", 0, 0, f_serverlist}, 6790 {"setbufvar", 3, 3, f_setbufvar}, 6791 {"setcmdpos", 1, 1, f_setcmdpos}, 6792 {"setline", 2, 2, f_setline}, 6793 {"setqflist", 1, 2, f_setqflist}, 6794 {"setreg", 2, 3, f_setreg}, 6795 {"setwinvar", 3, 3, f_setwinvar}, 6796 {"simplify", 1, 1, f_simplify}, 6797 {"sort", 1, 2, f_sort}, 6798 {"soundfold", 1, 1, f_soundfold}, 6799 {"spellbadword", 0, 0, f_spellbadword}, 6800 {"spellsuggest", 1, 2, f_spellsuggest}, 6801 {"split", 1, 3, f_split}, 6802 #ifdef HAVE_STRFTIME 6803 {"strftime", 1, 2, f_strftime}, 6804 #endif 6805 {"stridx", 2, 3, f_stridx}, 6806 {"string", 1, 1, f_string}, 6807 {"strlen", 1, 1, f_strlen}, 6808 {"strpart", 2, 3, f_strpart}, 6809 {"strridx", 2, 3, f_strridx}, 6810 {"strtrans", 1, 1, f_strtrans}, 6811 {"submatch", 1, 1, f_submatch}, 6812 {"substitute", 4, 4, f_substitute}, 6813 {"synID", 3, 3, f_synID}, 6814 {"synIDattr", 2, 3, f_synIDattr}, 6815 {"synIDtrans", 1, 1, f_synIDtrans}, 6816 {"system", 1, 2, f_system}, 6817 {"taglist", 1, 1, f_taglist}, 6818 {"tempname", 0, 0, f_tempname}, 6819 {"tolower", 1, 1, f_tolower}, 6820 {"toupper", 1, 1, f_toupper}, 6821 {"tr", 3, 3, f_tr}, 6822 {"type", 1, 1, f_type}, 6823 {"values", 1, 1, f_values}, 6824 {"virtcol", 1, 1, f_virtcol}, 6825 {"visualmode", 0, 1, f_visualmode}, 6826 {"winbufnr", 1, 1, f_winbufnr}, 6827 {"wincol", 0, 0, f_wincol}, 6828 {"winheight", 1, 1, f_winheight}, 6829 {"winline", 0, 0, f_winline}, 6830 {"winnr", 0, 1, f_winnr}, 6831 {"winrestcmd", 0, 0, f_winrestcmd}, 6832 {"winwidth", 1, 1, f_winwidth}, 6833 {"writefile", 2, 3, f_writefile}, 6834 }; 6835 6836 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6837 6838 /* 6839 * Function given to ExpandGeneric() to obtain the list of internal 6840 * or user defined function names. 6841 */ 6842 char_u * 6843 get_function_name(xp, idx) 6844 expand_T *xp; 6845 int idx; 6846 { 6847 static int intidx = -1; 6848 char_u *name; 6849 6850 if (idx == 0) 6851 intidx = -1; 6852 if (intidx < 0) 6853 { 6854 name = get_user_func_name(xp, idx); 6855 if (name != NULL) 6856 return name; 6857 } 6858 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6859 { 6860 STRCPY(IObuff, functions[intidx].f_name); 6861 STRCAT(IObuff, "("); 6862 if (functions[intidx].f_max_argc == 0) 6863 STRCAT(IObuff, ")"); 6864 return IObuff; 6865 } 6866 6867 return NULL; 6868 } 6869 6870 /* 6871 * Function given to ExpandGeneric() to obtain the list of internal or 6872 * user defined variable or function names. 6873 */ 6874 /*ARGSUSED*/ 6875 char_u * 6876 get_expr_name(xp, idx) 6877 expand_T *xp; 6878 int idx; 6879 { 6880 static int intidx = -1; 6881 char_u *name; 6882 6883 if (idx == 0) 6884 intidx = -1; 6885 if (intidx < 0) 6886 { 6887 name = get_function_name(xp, idx); 6888 if (name != NULL) 6889 return name; 6890 } 6891 return get_user_var_name(xp, ++intidx); 6892 } 6893 6894 #endif /* FEAT_CMDL_COMPL */ 6895 6896 /* 6897 * Find internal function in table above. 6898 * Return index, or -1 if not found 6899 */ 6900 static int 6901 find_internal_func(name) 6902 char_u *name; /* name of the function */ 6903 { 6904 int first = 0; 6905 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 6906 int cmp; 6907 int x; 6908 6909 /* 6910 * Find the function name in the table. Binary search. 6911 */ 6912 while (first <= last) 6913 { 6914 x = first + ((unsigned)(last - first) >> 1); 6915 cmp = STRCMP(name, functions[x].f_name); 6916 if (cmp < 0) 6917 last = x - 1; 6918 else if (cmp > 0) 6919 first = x + 1; 6920 else 6921 return x; 6922 } 6923 return -1; 6924 } 6925 6926 /* 6927 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 6928 * name it contains, otherwise return "name". 6929 */ 6930 static char_u * 6931 deref_func_name(name, lenp) 6932 char_u *name; 6933 int *lenp; 6934 { 6935 dictitem_T *v; 6936 int cc; 6937 6938 cc = name[*lenp]; 6939 name[*lenp] = NUL; 6940 v = find_var(name, NULL); 6941 name[*lenp] = cc; 6942 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 6943 { 6944 if (v->di_tv.vval.v_string == NULL) 6945 { 6946 *lenp = 0; 6947 return (char_u *)""; /* just in case */ 6948 } 6949 *lenp = STRLEN(v->di_tv.vval.v_string); 6950 return v->di_tv.vval.v_string; 6951 } 6952 6953 return name; 6954 } 6955 6956 /* 6957 * Allocate a variable for the result of a function. 6958 * Return OK or FAIL. 6959 */ 6960 static int 6961 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 6962 evaluate, selfdict) 6963 char_u *name; /* name of the function */ 6964 int len; /* length of "name" */ 6965 typval_T *rettv; 6966 char_u **arg; /* argument, pointing to the '(' */ 6967 linenr_T firstline; /* first line of range */ 6968 linenr_T lastline; /* last line of range */ 6969 int *doesrange; /* return: function handled range */ 6970 int evaluate; 6971 dict_T *selfdict; /* Dictionary for "self" */ 6972 { 6973 char_u *argp; 6974 int ret = OK; 6975 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 6976 int argcount = 0; /* number of arguments found */ 6977 6978 /* 6979 * Get the arguments. 6980 */ 6981 argp = *arg; 6982 while (argcount < MAX_FUNC_ARGS) 6983 { 6984 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 6985 if (*argp == ')' || *argp == ',' || *argp == NUL) 6986 break; 6987 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 6988 { 6989 ret = FAIL; 6990 break; 6991 } 6992 ++argcount; 6993 if (*argp != ',') 6994 break; 6995 } 6996 if (*argp == ')') 6997 ++argp; 6998 else 6999 ret = FAIL; 7000 7001 if (ret == OK) 7002 ret = call_func(name, len, rettv, argcount, argvars, 7003 firstline, lastline, doesrange, evaluate, selfdict); 7004 else if (!aborting()) 7005 { 7006 if (argcount == MAX_FUNC_ARGS) 7007 emsg_funcname("E740: Too many arguments for function %s", name); 7008 else 7009 emsg_funcname("E116: Invalid arguments for function %s", name); 7010 } 7011 7012 while (--argcount >= 0) 7013 clear_tv(&argvars[argcount]); 7014 7015 *arg = skipwhite(argp); 7016 return ret; 7017 } 7018 7019 7020 /* 7021 * Call a function with its resolved parameters 7022 * Return OK or FAIL. 7023 */ 7024 static int 7025 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7026 doesrange, evaluate, selfdict) 7027 char_u *name; /* name of the function */ 7028 int len; /* length of "name" */ 7029 typval_T *rettv; /* return value goes here */ 7030 int argcount; /* number of "argvars" */ 7031 typval_T *argvars; /* vars for arguments */ 7032 linenr_T firstline; /* first line of range */ 7033 linenr_T lastline; /* last line of range */ 7034 int *doesrange; /* return: function handled range */ 7035 int evaluate; 7036 dict_T *selfdict; /* Dictionary for "self" */ 7037 { 7038 int ret = FAIL; 7039 #define ERROR_UNKNOWN 0 7040 #define ERROR_TOOMANY 1 7041 #define ERROR_TOOFEW 2 7042 #define ERROR_SCRIPT 3 7043 #define ERROR_DICT 4 7044 #define ERROR_NONE 5 7045 #define ERROR_OTHER 6 7046 int error = ERROR_NONE; 7047 int i; 7048 int llen; 7049 ufunc_T *fp; 7050 int cc; 7051 #define FLEN_FIXED 40 7052 char_u fname_buf[FLEN_FIXED + 1]; 7053 char_u *fname; 7054 7055 /* 7056 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7057 * Change <SNR>123_name() to K_SNR 123_name(). 7058 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7059 */ 7060 cc = name[len]; 7061 name[len] = NUL; 7062 llen = eval_fname_script(name); 7063 if (llen > 0) 7064 { 7065 fname_buf[0] = K_SPECIAL; 7066 fname_buf[1] = KS_EXTRA; 7067 fname_buf[2] = (int)KE_SNR; 7068 i = 3; 7069 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7070 { 7071 if (current_SID <= 0) 7072 error = ERROR_SCRIPT; 7073 else 7074 { 7075 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7076 i = (int)STRLEN(fname_buf); 7077 } 7078 } 7079 if (i + STRLEN(name + llen) < FLEN_FIXED) 7080 { 7081 STRCPY(fname_buf + i, name + llen); 7082 fname = fname_buf; 7083 } 7084 else 7085 { 7086 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7087 if (fname == NULL) 7088 error = ERROR_OTHER; 7089 else 7090 { 7091 mch_memmove(fname, fname_buf, (size_t)i); 7092 STRCPY(fname + i, name + llen); 7093 } 7094 } 7095 } 7096 else 7097 fname = name; 7098 7099 *doesrange = FALSE; 7100 7101 7102 /* execute the function if no errors detected and executing */ 7103 if (evaluate && error == ERROR_NONE) 7104 { 7105 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7106 error = ERROR_UNKNOWN; 7107 7108 if (!builtin_function(fname)) 7109 { 7110 /* 7111 * User defined function. 7112 */ 7113 fp = find_func(fname); 7114 7115 #ifdef FEAT_AUTOCMD 7116 /* Trigger FuncUndefined event, may load the function. */ 7117 if (fp == NULL 7118 && apply_autocmds(EVENT_FUNCUNDEFINED, 7119 fname, fname, TRUE, NULL) 7120 && !aborting()) 7121 { 7122 /* executed an autocommand, search for the function again */ 7123 fp = find_func(fname); 7124 } 7125 #endif 7126 /* Try loading a package. */ 7127 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7128 { 7129 /* loaded a package, search for the function again */ 7130 fp = find_func(fname); 7131 } 7132 7133 if (fp != NULL) 7134 { 7135 if (fp->uf_flags & FC_RANGE) 7136 *doesrange = TRUE; 7137 if (argcount < fp->uf_args.ga_len) 7138 error = ERROR_TOOFEW; 7139 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7140 error = ERROR_TOOMANY; 7141 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7142 error = ERROR_DICT; 7143 else 7144 { 7145 /* 7146 * Call the user function. 7147 * Save and restore search patterns, script variables and 7148 * redo buffer. 7149 */ 7150 save_search_patterns(); 7151 saveRedobuff(); 7152 ++fp->uf_calls; 7153 call_user_func(fp, argcount, argvars, rettv, 7154 firstline, lastline, 7155 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7156 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7157 && fp->uf_refcount <= 0) 7158 /* Function was unreferenced while being used, free it 7159 * now. */ 7160 func_free(fp); 7161 restoreRedobuff(); 7162 restore_search_patterns(); 7163 error = ERROR_NONE; 7164 } 7165 } 7166 } 7167 else 7168 { 7169 /* 7170 * Find the function name in the table, call its implementation. 7171 */ 7172 i = find_internal_func(fname); 7173 if (i >= 0) 7174 { 7175 if (argcount < functions[i].f_min_argc) 7176 error = ERROR_TOOFEW; 7177 else if (argcount > functions[i].f_max_argc) 7178 error = ERROR_TOOMANY; 7179 else 7180 { 7181 argvars[argcount].v_type = VAR_UNKNOWN; 7182 functions[i].f_func(argvars, rettv); 7183 error = ERROR_NONE; 7184 } 7185 } 7186 } 7187 /* 7188 * The function call (or "FuncUndefined" autocommand sequence) might 7189 * have been aborted by an error, an interrupt, or an explicitly thrown 7190 * exception that has not been caught so far. This situation can be 7191 * tested for by calling aborting(). For an error in an internal 7192 * function or for the "E132" error in call_user_func(), however, the 7193 * throw point at which the "force_abort" flag (temporarily reset by 7194 * emsg()) is normally updated has not been reached yet. We need to 7195 * update that flag first to make aborting() reliable. 7196 */ 7197 update_force_abort(); 7198 } 7199 if (error == ERROR_NONE) 7200 ret = OK; 7201 7202 /* 7203 * Report an error unless the argument evaluation or function call has been 7204 * cancelled due to an aborting error, an interrupt, or an exception. 7205 */ 7206 if (!aborting()) 7207 { 7208 switch (error) 7209 { 7210 case ERROR_UNKNOWN: 7211 emsg_funcname("E117: Unknown function: %s", name); 7212 break; 7213 case ERROR_TOOMANY: 7214 emsg_funcname(e_toomanyarg, name); 7215 break; 7216 case ERROR_TOOFEW: 7217 emsg_funcname("E119: Not enough arguments for function: %s", 7218 name); 7219 break; 7220 case ERROR_SCRIPT: 7221 emsg_funcname("E120: Using <SID> not in a script context: %s", 7222 name); 7223 break; 7224 case ERROR_DICT: 7225 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7226 name); 7227 break; 7228 } 7229 } 7230 7231 name[len] = cc; 7232 if (fname != name && fname != fname_buf) 7233 vim_free(fname); 7234 7235 return ret; 7236 } 7237 7238 /* 7239 * Give an error message with a function name. Handle <SNR> things. 7240 */ 7241 static void 7242 emsg_funcname(msg, name) 7243 char *msg; 7244 char_u *name; 7245 { 7246 char_u *p; 7247 7248 if (*name == K_SPECIAL) 7249 p = concat_str((char_u *)"<SNR>", name + 3); 7250 else 7251 p = name; 7252 EMSG2(_(msg), p); 7253 if (p != name) 7254 vim_free(p); 7255 } 7256 7257 /********************************************* 7258 * Implementation of the built-in functions 7259 */ 7260 7261 /* 7262 * "add(list, item)" function 7263 */ 7264 static void 7265 f_add(argvars, rettv) 7266 typval_T *argvars; 7267 typval_T *rettv; 7268 { 7269 list_T *l; 7270 7271 rettv->vval.v_number = 1; /* Default: Failed */ 7272 if (argvars[0].v_type == VAR_LIST) 7273 { 7274 if ((l = argvars[0].vval.v_list) != NULL 7275 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7276 && list_append_tv(l, &argvars[1]) == OK) 7277 copy_tv(&argvars[0], rettv); 7278 } 7279 else 7280 EMSG(_(e_listreq)); 7281 } 7282 7283 /* 7284 * "append(lnum, string/list)" function 7285 */ 7286 static void 7287 f_append(argvars, rettv) 7288 typval_T *argvars; 7289 typval_T *rettv; 7290 { 7291 long lnum; 7292 char_u *line; 7293 list_T *l = NULL; 7294 listitem_T *li = NULL; 7295 typval_T *tv; 7296 long added = 0; 7297 7298 lnum = get_tv_lnum(argvars); 7299 if (lnum >= 0 7300 && lnum <= curbuf->b_ml.ml_line_count 7301 && u_save(lnum, lnum + 1) == OK) 7302 { 7303 if (argvars[1].v_type == VAR_LIST) 7304 { 7305 l = argvars[1].vval.v_list; 7306 if (l == NULL) 7307 return; 7308 li = l->lv_first; 7309 } 7310 rettv->vval.v_number = 0; /* Default: Success */ 7311 for (;;) 7312 { 7313 if (l == NULL) 7314 tv = &argvars[1]; /* append a string */ 7315 else if (li == NULL) 7316 break; /* end of list */ 7317 else 7318 tv = &li->li_tv; /* append item from list */ 7319 line = get_tv_string_chk(tv); 7320 if (line == NULL) /* type error */ 7321 { 7322 rettv->vval.v_number = 1; /* Failed */ 7323 break; 7324 } 7325 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7326 ++added; 7327 if (l == NULL) 7328 break; 7329 li = li->li_next; 7330 } 7331 7332 appended_lines_mark(lnum, added); 7333 if (curwin->w_cursor.lnum > lnum) 7334 curwin->w_cursor.lnum += added; 7335 } 7336 else 7337 rettv->vval.v_number = 1; /* Failed */ 7338 } 7339 7340 /* 7341 * "argc()" function 7342 */ 7343 /* ARGSUSED */ 7344 static void 7345 f_argc(argvars, rettv) 7346 typval_T *argvars; 7347 typval_T *rettv; 7348 { 7349 rettv->vval.v_number = ARGCOUNT; 7350 } 7351 7352 /* 7353 * "argidx()" function 7354 */ 7355 /* ARGSUSED */ 7356 static void 7357 f_argidx(argvars, rettv) 7358 typval_T *argvars; 7359 typval_T *rettv; 7360 { 7361 rettv->vval.v_number = curwin->w_arg_idx; 7362 } 7363 7364 /* 7365 * "argv(nr)" function 7366 */ 7367 static void 7368 f_argv(argvars, rettv) 7369 typval_T *argvars; 7370 typval_T *rettv; 7371 { 7372 int idx; 7373 7374 idx = get_tv_number_chk(&argvars[0], NULL); 7375 if (idx >= 0 && idx < ARGCOUNT) 7376 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7377 else 7378 rettv->vval.v_string = NULL; 7379 rettv->v_type = VAR_STRING; 7380 } 7381 7382 /* 7383 * "browse(save, title, initdir, default)" function 7384 */ 7385 /* ARGSUSED */ 7386 static void 7387 f_browse(argvars, rettv) 7388 typval_T *argvars; 7389 typval_T *rettv; 7390 { 7391 #ifdef FEAT_BROWSE 7392 int save; 7393 char_u *title; 7394 char_u *initdir; 7395 char_u *defname; 7396 char_u buf[NUMBUFLEN]; 7397 char_u buf2[NUMBUFLEN]; 7398 int error = FALSE; 7399 7400 save = get_tv_number_chk(&argvars[0], &error); 7401 title = get_tv_string_chk(&argvars[1]); 7402 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7403 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7404 7405 if (error || title == NULL || initdir == NULL || defname == NULL) 7406 rettv->vval.v_string = NULL; 7407 else 7408 rettv->vval.v_string = 7409 do_browse(save ? BROWSE_SAVE : 0, 7410 title, defname, NULL, initdir, NULL, curbuf); 7411 #else 7412 rettv->vval.v_string = NULL; 7413 #endif 7414 rettv->v_type = VAR_STRING; 7415 } 7416 7417 /* 7418 * "browsedir(title, initdir)" function 7419 */ 7420 /* ARGSUSED */ 7421 static void 7422 f_browsedir(argvars, rettv) 7423 typval_T *argvars; 7424 typval_T *rettv; 7425 { 7426 #ifdef FEAT_BROWSE 7427 char_u *title; 7428 char_u *initdir; 7429 char_u buf[NUMBUFLEN]; 7430 7431 title = get_tv_string_chk(&argvars[0]); 7432 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7433 7434 if (title == NULL || initdir == NULL) 7435 rettv->vval.v_string = NULL; 7436 else 7437 rettv->vval.v_string = do_browse(BROWSE_DIR, 7438 title, NULL, NULL, initdir, NULL, curbuf); 7439 #else 7440 rettv->vval.v_string = NULL; 7441 #endif 7442 rettv->v_type = VAR_STRING; 7443 } 7444 7445 static buf_T *find_buffer __ARGS((typval_T *avar)); 7446 7447 /* 7448 * Find a buffer by number or exact name. 7449 */ 7450 static buf_T * 7451 find_buffer(avar) 7452 typval_T *avar; 7453 { 7454 buf_T *buf = NULL; 7455 7456 if (avar->v_type == VAR_NUMBER) 7457 buf = buflist_findnr((int)avar->vval.v_number); 7458 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7459 { 7460 buf = buflist_findname_exp(avar->vval.v_string); 7461 if (buf == NULL) 7462 { 7463 /* No full path name match, try a match with a URL or a "nofile" 7464 * buffer, these don't use the full path. */ 7465 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7466 if (buf->b_fname != NULL 7467 && (path_with_url(buf->b_fname) 7468 #ifdef FEAT_QUICKFIX 7469 || bt_nofile(buf) 7470 #endif 7471 ) 7472 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7473 break; 7474 } 7475 } 7476 return buf; 7477 } 7478 7479 /* 7480 * "bufexists(expr)" function 7481 */ 7482 static void 7483 f_bufexists(argvars, rettv) 7484 typval_T *argvars; 7485 typval_T *rettv; 7486 { 7487 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7488 } 7489 7490 /* 7491 * "buflisted(expr)" function 7492 */ 7493 static void 7494 f_buflisted(argvars, rettv) 7495 typval_T *argvars; 7496 typval_T *rettv; 7497 { 7498 buf_T *buf; 7499 7500 buf = find_buffer(&argvars[0]); 7501 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7502 } 7503 7504 /* 7505 * "bufloaded(expr)" function 7506 */ 7507 static void 7508 f_bufloaded(argvars, rettv) 7509 typval_T *argvars; 7510 typval_T *rettv; 7511 { 7512 buf_T *buf; 7513 7514 buf = find_buffer(&argvars[0]); 7515 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7516 } 7517 7518 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7519 7520 /* 7521 * Get buffer by number or pattern. 7522 */ 7523 static buf_T * 7524 get_buf_tv(tv) 7525 typval_T *tv; 7526 { 7527 char_u *name = tv->vval.v_string; 7528 int save_magic; 7529 char_u *save_cpo; 7530 buf_T *buf; 7531 7532 if (tv->v_type == VAR_NUMBER) 7533 return buflist_findnr((int)tv->vval.v_number); 7534 if (tv->v_type != VAR_STRING) 7535 return NULL; 7536 if (name == NULL || *name == NUL) 7537 return curbuf; 7538 if (name[0] == '$' && name[1] == NUL) 7539 return lastbuf; 7540 7541 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7542 save_magic = p_magic; 7543 p_magic = TRUE; 7544 save_cpo = p_cpo; 7545 p_cpo = (char_u *)""; 7546 7547 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7548 TRUE, FALSE)); 7549 7550 p_magic = save_magic; 7551 p_cpo = save_cpo; 7552 7553 /* If not found, try expanding the name, like done for bufexists(). */ 7554 if (buf == NULL) 7555 buf = find_buffer(tv); 7556 7557 return buf; 7558 } 7559 7560 /* 7561 * "bufname(expr)" function 7562 */ 7563 static void 7564 f_bufname(argvars, rettv) 7565 typval_T *argvars; 7566 typval_T *rettv; 7567 { 7568 buf_T *buf; 7569 7570 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7571 ++emsg_off; 7572 buf = get_buf_tv(&argvars[0]); 7573 rettv->v_type = VAR_STRING; 7574 if (buf != NULL && buf->b_fname != NULL) 7575 rettv->vval.v_string = vim_strsave(buf->b_fname); 7576 else 7577 rettv->vval.v_string = NULL; 7578 --emsg_off; 7579 } 7580 7581 /* 7582 * "bufnr(expr)" function 7583 */ 7584 static void 7585 f_bufnr(argvars, rettv) 7586 typval_T *argvars; 7587 typval_T *rettv; 7588 { 7589 buf_T *buf; 7590 7591 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7592 ++emsg_off; 7593 buf = get_buf_tv(&argvars[0]); 7594 if (buf != NULL) 7595 rettv->vval.v_number = buf->b_fnum; 7596 else 7597 rettv->vval.v_number = -1; 7598 --emsg_off; 7599 } 7600 7601 /* 7602 * "bufwinnr(nr)" function 7603 */ 7604 static void 7605 f_bufwinnr(argvars, rettv) 7606 typval_T *argvars; 7607 typval_T *rettv; 7608 { 7609 #ifdef FEAT_WINDOWS 7610 win_T *wp; 7611 int winnr = 0; 7612 #endif 7613 buf_T *buf; 7614 7615 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7616 ++emsg_off; 7617 buf = get_buf_tv(&argvars[0]); 7618 #ifdef FEAT_WINDOWS 7619 for (wp = firstwin; wp; wp = wp->w_next) 7620 { 7621 ++winnr; 7622 if (wp->w_buffer == buf) 7623 break; 7624 } 7625 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7626 #else 7627 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7628 #endif 7629 --emsg_off; 7630 } 7631 7632 /* 7633 * "byte2line(byte)" function 7634 */ 7635 /*ARGSUSED*/ 7636 static void 7637 f_byte2line(argvars, rettv) 7638 typval_T *argvars; 7639 typval_T *rettv; 7640 { 7641 #ifndef FEAT_BYTEOFF 7642 rettv->vval.v_number = -1; 7643 #else 7644 long boff = 0; 7645 7646 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7647 if (boff < 0) 7648 rettv->vval.v_number = -1; 7649 else 7650 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7651 (linenr_T)0, &boff); 7652 #endif 7653 } 7654 7655 /* 7656 * "byteidx()" function 7657 */ 7658 /*ARGSUSED*/ 7659 static void 7660 f_byteidx(argvars, rettv) 7661 typval_T *argvars; 7662 typval_T *rettv; 7663 { 7664 #ifdef FEAT_MBYTE 7665 char_u *t; 7666 #endif 7667 char_u *str; 7668 long idx; 7669 7670 str = get_tv_string_chk(&argvars[0]); 7671 idx = get_tv_number_chk(&argvars[1], NULL); 7672 rettv->vval.v_number = -1; 7673 if (str == NULL || idx < 0) 7674 return; 7675 7676 #ifdef FEAT_MBYTE 7677 t = str; 7678 for ( ; idx > 0; idx--) 7679 { 7680 if (*t == NUL) /* EOL reached */ 7681 return; 7682 t += mb_ptr2len_check(t); 7683 } 7684 rettv->vval.v_number = t - str; 7685 #else 7686 if (idx <= STRLEN(str)) 7687 rettv->vval.v_number = idx; 7688 #endif 7689 } 7690 7691 /* 7692 * "call(func, arglist)" function 7693 */ 7694 static void 7695 f_call(argvars, rettv) 7696 typval_T *argvars; 7697 typval_T *rettv; 7698 { 7699 char_u *func; 7700 typval_T argv[MAX_FUNC_ARGS]; 7701 int argc = 0; 7702 listitem_T *item; 7703 int dummy; 7704 dict_T *selfdict = NULL; 7705 7706 rettv->vval.v_number = 0; 7707 if (argvars[1].v_type != VAR_LIST) 7708 { 7709 EMSG(_(e_listreq)); 7710 return; 7711 } 7712 if (argvars[1].vval.v_list == NULL) 7713 return; 7714 7715 if (argvars[0].v_type == VAR_FUNC) 7716 func = argvars[0].vval.v_string; 7717 else 7718 func = get_tv_string(&argvars[0]); 7719 if (*func == NUL) 7720 return; /* type error or empty name */ 7721 7722 if (argvars[2].v_type != VAR_UNKNOWN) 7723 { 7724 if (argvars[2].v_type != VAR_DICT) 7725 { 7726 EMSG(_(e_dictreq)); 7727 return; 7728 } 7729 selfdict = argvars[2].vval.v_dict; 7730 } 7731 7732 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7733 item = item->li_next) 7734 { 7735 if (argc == MAX_FUNC_ARGS) 7736 { 7737 EMSG(_("E699: Too many arguments")); 7738 break; 7739 } 7740 /* Make a copy of each argument. This is needed to be able to set 7741 * v_lock to VAR_FIXED in the copy without changing the original list. 7742 */ 7743 copy_tv(&item->li_tv, &argv[argc++]); 7744 } 7745 7746 if (item == NULL) 7747 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7748 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7749 &dummy, TRUE, selfdict); 7750 7751 /* Free the arguments. */ 7752 while (argc > 0) 7753 clear_tv(&argv[--argc]); 7754 } 7755 7756 /* 7757 * "char2nr(string)" function 7758 */ 7759 static void 7760 f_char2nr(argvars, rettv) 7761 typval_T *argvars; 7762 typval_T *rettv; 7763 { 7764 #ifdef FEAT_MBYTE 7765 if (has_mbyte) 7766 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7767 else 7768 #endif 7769 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7770 } 7771 7772 /* 7773 * "cindent(lnum)" function 7774 */ 7775 static void 7776 f_cindent(argvars, rettv) 7777 typval_T *argvars; 7778 typval_T *rettv; 7779 { 7780 #ifdef FEAT_CINDENT 7781 pos_T pos; 7782 linenr_T lnum; 7783 7784 pos = curwin->w_cursor; 7785 lnum = get_tv_lnum(argvars); 7786 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7787 { 7788 curwin->w_cursor.lnum = lnum; 7789 rettv->vval.v_number = get_c_indent(); 7790 curwin->w_cursor = pos; 7791 } 7792 else 7793 #endif 7794 rettv->vval.v_number = -1; 7795 } 7796 7797 /* 7798 * "col(string)" function 7799 */ 7800 static void 7801 f_col(argvars, rettv) 7802 typval_T *argvars; 7803 typval_T *rettv; 7804 { 7805 colnr_T col = 0; 7806 pos_T *fp; 7807 7808 fp = var2fpos(&argvars[0], FALSE); 7809 if (fp != NULL) 7810 { 7811 if (fp->col == MAXCOL) 7812 { 7813 /* '> can be MAXCOL, get the length of the line then */ 7814 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7815 col = STRLEN(ml_get(fp->lnum)) + 1; 7816 else 7817 col = MAXCOL; 7818 } 7819 else 7820 { 7821 col = fp->col + 1; 7822 #ifdef FEAT_VIRTUALEDIT 7823 /* col(".") when the cursor is on the NUL at the end of the line 7824 * because of "coladd" can be seen as an extra column. */ 7825 if (virtual_active() && fp == &curwin->w_cursor) 7826 { 7827 char_u *p = ml_get_cursor(); 7828 7829 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7830 curwin->w_virtcol - curwin->w_cursor.coladd)) 7831 { 7832 # ifdef FEAT_MBYTE 7833 int l; 7834 7835 if (*p != NUL && p[(l = (*mb_ptr2len_check)(p))] == NUL) 7836 col += l; 7837 # else 7838 if (*p != NUL && p[1] == NUL) 7839 ++col; 7840 # endif 7841 } 7842 } 7843 #endif 7844 } 7845 } 7846 rettv->vval.v_number = col; 7847 } 7848 7849 /* 7850 * "confirm(message, buttons[, default [, type]])" function 7851 */ 7852 /*ARGSUSED*/ 7853 static void 7854 f_confirm(argvars, rettv) 7855 typval_T *argvars; 7856 typval_T *rettv; 7857 { 7858 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7859 char_u *message; 7860 char_u *buttons = NULL; 7861 char_u buf[NUMBUFLEN]; 7862 char_u buf2[NUMBUFLEN]; 7863 int def = 1; 7864 int type = VIM_GENERIC; 7865 char_u *typestr; 7866 int error = FALSE; 7867 7868 message = get_tv_string_chk(&argvars[0]); 7869 if (message == NULL) 7870 error = TRUE; 7871 if (argvars[1].v_type != VAR_UNKNOWN) 7872 { 7873 buttons = get_tv_string_buf_chk(&argvars[1], buf); 7874 if (buttons == NULL) 7875 error = TRUE; 7876 if (argvars[2].v_type != VAR_UNKNOWN) 7877 { 7878 def = get_tv_number_chk(&argvars[2], &error); 7879 if (argvars[3].v_type != VAR_UNKNOWN) 7880 { 7881 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 7882 if (typestr == NULL) 7883 error = TRUE; 7884 else 7885 { 7886 switch (TOUPPER_ASC(*typestr)) 7887 { 7888 case 'E': type = VIM_ERROR; break; 7889 case 'Q': type = VIM_QUESTION; break; 7890 case 'I': type = VIM_INFO; break; 7891 case 'W': type = VIM_WARNING; break; 7892 case 'G': type = VIM_GENERIC; break; 7893 } 7894 } 7895 } 7896 } 7897 } 7898 7899 if (buttons == NULL || *buttons == NUL) 7900 buttons = (char_u *)_("&Ok"); 7901 7902 if (error) 7903 rettv->vval.v_number = 0; 7904 else 7905 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 7906 def, NULL); 7907 #else 7908 rettv->vval.v_number = 0; 7909 #endif 7910 } 7911 7912 /* 7913 * "copy()" function 7914 */ 7915 static void 7916 f_copy(argvars, rettv) 7917 typval_T *argvars; 7918 typval_T *rettv; 7919 { 7920 item_copy(&argvars[0], rettv, FALSE, 0); 7921 } 7922 7923 /* 7924 * "count()" function 7925 */ 7926 static void 7927 f_count(argvars, rettv) 7928 typval_T *argvars; 7929 typval_T *rettv; 7930 { 7931 long n = 0; 7932 int ic = FALSE; 7933 7934 if (argvars[0].v_type == VAR_LIST) 7935 { 7936 listitem_T *li; 7937 list_T *l; 7938 long idx; 7939 7940 if ((l = argvars[0].vval.v_list) != NULL) 7941 { 7942 li = l->lv_first; 7943 if (argvars[2].v_type != VAR_UNKNOWN) 7944 { 7945 int error = FALSE; 7946 7947 ic = get_tv_number_chk(&argvars[2], &error); 7948 if (argvars[3].v_type != VAR_UNKNOWN) 7949 { 7950 idx = get_tv_number_chk(&argvars[3], &error); 7951 if (!error) 7952 { 7953 li = list_find(l, idx); 7954 if (li == NULL) 7955 EMSGN(_(e_listidx), idx); 7956 } 7957 } 7958 if (error) 7959 li = NULL; 7960 } 7961 7962 for ( ; li != NULL; li = li->li_next) 7963 if (tv_equal(&li->li_tv, &argvars[1], ic)) 7964 ++n; 7965 } 7966 } 7967 else if (argvars[0].v_type == VAR_DICT) 7968 { 7969 int todo; 7970 dict_T *d; 7971 hashitem_T *hi; 7972 7973 if ((d = argvars[0].vval.v_dict) != NULL) 7974 { 7975 int error = FALSE; 7976 7977 if (argvars[2].v_type != VAR_UNKNOWN) 7978 { 7979 ic = get_tv_number_chk(&argvars[2], &error); 7980 if (argvars[3].v_type != VAR_UNKNOWN) 7981 EMSG(_(e_invarg)); 7982 } 7983 7984 todo = error ? 0 : d->dv_hashtab.ht_used; 7985 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 7986 { 7987 if (!HASHITEM_EMPTY(hi)) 7988 { 7989 --todo; 7990 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 7991 ++n; 7992 } 7993 } 7994 } 7995 } 7996 else 7997 EMSG2(_(e_listdictarg), "count()"); 7998 rettv->vval.v_number = n; 7999 } 8000 8001 /* 8002 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8003 * 8004 * Checks the existence of a cscope connection. 8005 */ 8006 /*ARGSUSED*/ 8007 static void 8008 f_cscope_connection(argvars, rettv) 8009 typval_T *argvars; 8010 typval_T *rettv; 8011 { 8012 #ifdef FEAT_CSCOPE 8013 int num = 0; 8014 char_u *dbpath = NULL; 8015 char_u *prepend = NULL; 8016 char_u buf[NUMBUFLEN]; 8017 8018 if (argvars[0].v_type != VAR_UNKNOWN 8019 && argvars[1].v_type != VAR_UNKNOWN) 8020 { 8021 num = (int)get_tv_number(&argvars[0]); 8022 dbpath = get_tv_string(&argvars[1]); 8023 if (argvars[2].v_type != VAR_UNKNOWN) 8024 prepend = get_tv_string_buf(&argvars[2], buf); 8025 } 8026 8027 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8028 #else 8029 rettv->vval.v_number = 0; 8030 #endif 8031 } 8032 8033 /* 8034 * "cursor(lnum, col)" function 8035 * 8036 * Moves the cursor to the specified line and column 8037 */ 8038 /*ARGSUSED*/ 8039 static void 8040 f_cursor(argvars, rettv) 8041 typval_T *argvars; 8042 typval_T *rettv; 8043 { 8044 long line, col; 8045 8046 line = get_tv_lnum(argvars); 8047 col = get_tv_number_chk(&argvars[1], NULL); 8048 if (line < 0 || col < 0) 8049 return; /* type error; errmsg already given */ 8050 if (line > 0) 8051 curwin->w_cursor.lnum = line; 8052 if (col > 0) 8053 curwin->w_cursor.col = col - 1; 8054 #ifdef FEAT_VIRTUALEDIT 8055 curwin->w_cursor.coladd = 0; 8056 #endif 8057 8058 /* Make sure the cursor is in a valid position. */ 8059 check_cursor(); 8060 #ifdef FEAT_MBYTE 8061 /* Correct cursor for multi-byte character. */ 8062 if (has_mbyte) 8063 mb_adjust_cursor(); 8064 #endif 8065 8066 curwin->w_set_curswant = TRUE; 8067 } 8068 8069 /* 8070 * "deepcopy()" function 8071 */ 8072 static void 8073 f_deepcopy(argvars, rettv) 8074 typval_T *argvars; 8075 typval_T *rettv; 8076 { 8077 int noref = 0; 8078 8079 if (argvars[1].v_type != VAR_UNKNOWN) 8080 noref = get_tv_number_chk(&argvars[1], NULL); 8081 if (noref < 0 || noref > 1) 8082 EMSG(_(e_invarg)); 8083 else 8084 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8085 } 8086 8087 /* 8088 * "delete()" function 8089 */ 8090 static void 8091 f_delete(argvars, rettv) 8092 typval_T *argvars; 8093 typval_T *rettv; 8094 { 8095 if (check_restricted() || check_secure()) 8096 rettv->vval.v_number = -1; 8097 else 8098 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8099 } 8100 8101 /* 8102 * "did_filetype()" function 8103 */ 8104 /*ARGSUSED*/ 8105 static void 8106 f_did_filetype(argvars, rettv) 8107 typval_T *argvars; 8108 typval_T *rettv; 8109 { 8110 #ifdef FEAT_AUTOCMD 8111 rettv->vval.v_number = did_filetype; 8112 #else 8113 rettv->vval.v_number = 0; 8114 #endif 8115 } 8116 8117 /* 8118 * "diff_filler()" function 8119 */ 8120 /*ARGSUSED*/ 8121 static void 8122 f_diff_filler(argvars, rettv) 8123 typval_T *argvars; 8124 typval_T *rettv; 8125 { 8126 #ifdef FEAT_DIFF 8127 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8128 #endif 8129 } 8130 8131 /* 8132 * "diff_hlID()" function 8133 */ 8134 /*ARGSUSED*/ 8135 static void 8136 f_diff_hlID(argvars, rettv) 8137 typval_T *argvars; 8138 typval_T *rettv; 8139 { 8140 #ifdef FEAT_DIFF 8141 linenr_T lnum = get_tv_lnum(argvars); 8142 static linenr_T prev_lnum = 0; 8143 static int changedtick = 0; 8144 static int fnum = 0; 8145 static int change_start = 0; 8146 static int change_end = 0; 8147 static enum hlf_value hlID = 0; 8148 int filler_lines; 8149 int col; 8150 8151 if (lnum < 0) /* ignore type error in {lnum} arg */ 8152 lnum = 0; 8153 if (lnum != prev_lnum 8154 || changedtick != curbuf->b_changedtick 8155 || fnum != curbuf->b_fnum) 8156 { 8157 /* New line, buffer, change: need to get the values. */ 8158 filler_lines = diff_check(curwin, lnum); 8159 if (filler_lines < 0) 8160 { 8161 if (filler_lines == -1) 8162 { 8163 change_start = MAXCOL; 8164 change_end = -1; 8165 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8166 hlID = HLF_ADD; /* added line */ 8167 else 8168 hlID = HLF_CHD; /* changed line */ 8169 } 8170 else 8171 hlID = HLF_ADD; /* added line */ 8172 } 8173 else 8174 hlID = (enum hlf_value)0; 8175 prev_lnum = lnum; 8176 changedtick = curbuf->b_changedtick; 8177 fnum = curbuf->b_fnum; 8178 } 8179 8180 if (hlID == HLF_CHD || hlID == HLF_TXD) 8181 { 8182 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8183 if (col >= change_start && col <= change_end) 8184 hlID = HLF_TXD; /* changed text */ 8185 else 8186 hlID = HLF_CHD; /* changed line */ 8187 } 8188 rettv->vval.v_number = hlID == (enum hlf_value)0 ? 0 : (int)hlID; 8189 #endif 8190 } 8191 8192 /* 8193 * "empty({expr})" function 8194 */ 8195 static void 8196 f_empty(argvars, rettv) 8197 typval_T *argvars; 8198 typval_T *rettv; 8199 { 8200 int n; 8201 8202 switch (argvars[0].v_type) 8203 { 8204 case VAR_STRING: 8205 case VAR_FUNC: 8206 n = argvars[0].vval.v_string == NULL 8207 || *argvars[0].vval.v_string == NUL; 8208 break; 8209 case VAR_NUMBER: 8210 n = argvars[0].vval.v_number == 0; 8211 break; 8212 case VAR_LIST: 8213 n = argvars[0].vval.v_list == NULL 8214 || argvars[0].vval.v_list->lv_first == NULL; 8215 break; 8216 case VAR_DICT: 8217 n = argvars[0].vval.v_dict == NULL 8218 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8219 break; 8220 default: 8221 EMSG2(_(e_intern2), "f_empty()"); 8222 n = 0; 8223 } 8224 8225 rettv->vval.v_number = n; 8226 } 8227 8228 /* 8229 * "escape({string}, {chars})" function 8230 */ 8231 static void 8232 f_escape(argvars, rettv) 8233 typval_T *argvars; 8234 typval_T *rettv; 8235 { 8236 char_u buf[NUMBUFLEN]; 8237 8238 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8239 get_tv_string_buf(&argvars[1], buf)); 8240 rettv->v_type = VAR_STRING; 8241 } 8242 8243 /* 8244 * "eval()" function 8245 */ 8246 /*ARGSUSED*/ 8247 static void 8248 f_eval(argvars, rettv) 8249 typval_T *argvars; 8250 typval_T *rettv; 8251 { 8252 char_u *s; 8253 8254 s = get_tv_string_chk(&argvars[0]); 8255 if (s != NULL) 8256 s = skipwhite(s); 8257 8258 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8259 { 8260 rettv->v_type = VAR_NUMBER; 8261 rettv->vval.v_number = 0; 8262 } 8263 else if (*s != NUL) 8264 EMSG(_(e_trailing)); 8265 } 8266 8267 /* 8268 * "eventhandler()" function 8269 */ 8270 /*ARGSUSED*/ 8271 static void 8272 f_eventhandler(argvars, rettv) 8273 typval_T *argvars; 8274 typval_T *rettv; 8275 { 8276 rettv->vval.v_number = vgetc_busy; 8277 } 8278 8279 /* 8280 * "executable()" function 8281 */ 8282 static void 8283 f_executable(argvars, rettv) 8284 typval_T *argvars; 8285 typval_T *rettv; 8286 { 8287 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8288 } 8289 8290 /* 8291 * "exists()" function 8292 */ 8293 static void 8294 f_exists(argvars, rettv) 8295 typval_T *argvars; 8296 typval_T *rettv; 8297 { 8298 char_u *p; 8299 char_u *name; 8300 int n = FALSE; 8301 int len = 0; 8302 8303 p = get_tv_string(&argvars[0]); 8304 if (*p == '$') /* environment variable */ 8305 { 8306 /* first try "normal" environment variables (fast) */ 8307 if (mch_getenv(p + 1) != NULL) 8308 n = TRUE; 8309 else 8310 { 8311 /* try expanding things like $VIM and ${HOME} */ 8312 p = expand_env_save(p); 8313 if (p != NULL && *p != '$') 8314 n = TRUE; 8315 vim_free(p); 8316 } 8317 } 8318 else if (*p == '&' || *p == '+') /* option */ 8319 n = (get_option_tv(&p, NULL, TRUE) == OK); 8320 else if (*p == '*') /* internal or user defined function */ 8321 { 8322 n = function_exists(p + 1); 8323 } 8324 else if (*p == ':') 8325 { 8326 n = cmd_exists(p + 1); 8327 } 8328 else if (*p == '#') 8329 { 8330 #ifdef FEAT_AUTOCMD 8331 name = p + 1; 8332 p = vim_strchr(name, '#'); 8333 if (p != NULL) 8334 n = au_exists(name, p, p + 1); 8335 else 8336 n = au_exists(name, name + STRLEN(name), NULL); 8337 #endif 8338 } 8339 else /* internal variable */ 8340 { 8341 char_u *tofree; 8342 typval_T tv; 8343 8344 /* get_name_len() takes care of expanding curly braces */ 8345 name = p; 8346 len = get_name_len(&p, &tofree, TRUE, FALSE); 8347 if (len > 0) 8348 { 8349 if (tofree != NULL) 8350 name = tofree; 8351 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8352 if (n) 8353 { 8354 /* handle d.key, l[idx], f(expr) */ 8355 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8356 if (n) 8357 clear_tv(&tv); 8358 } 8359 } 8360 8361 vim_free(tofree); 8362 } 8363 8364 rettv->vval.v_number = n; 8365 } 8366 8367 /* 8368 * "expand()" function 8369 */ 8370 static void 8371 f_expand(argvars, rettv) 8372 typval_T *argvars; 8373 typval_T *rettv; 8374 { 8375 char_u *s; 8376 int len; 8377 char_u *errormsg; 8378 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8379 expand_T xpc; 8380 int error = FALSE; 8381 8382 rettv->v_type = VAR_STRING; 8383 s = get_tv_string(&argvars[0]); 8384 if (*s == '%' || *s == '#' || *s == '<') 8385 { 8386 ++emsg_off; 8387 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8388 --emsg_off; 8389 } 8390 else 8391 { 8392 /* When the optional second argument is non-zero, don't remove matches 8393 * for 'suffixes' and 'wildignore' */ 8394 if (argvars[1].v_type != VAR_UNKNOWN 8395 && get_tv_number_chk(&argvars[1], &error)) 8396 flags |= WILD_KEEP_ALL; 8397 if (!error) 8398 { 8399 ExpandInit(&xpc); 8400 xpc.xp_context = EXPAND_FILES; 8401 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8402 ExpandCleanup(&xpc); 8403 } 8404 else 8405 rettv->vval.v_string = NULL; 8406 } 8407 } 8408 8409 /* 8410 * "extend(list, list [, idx])" function 8411 * "extend(dict, dict [, action])" function 8412 */ 8413 static void 8414 f_extend(argvars, rettv) 8415 typval_T *argvars; 8416 typval_T *rettv; 8417 { 8418 rettv->vval.v_number = 0; 8419 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8420 { 8421 list_T *l1, *l2; 8422 listitem_T *item; 8423 long before; 8424 int error = FALSE; 8425 8426 l1 = argvars[0].vval.v_list; 8427 l2 = argvars[1].vval.v_list; 8428 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8429 && l2 != NULL) 8430 { 8431 if (argvars[2].v_type != VAR_UNKNOWN) 8432 { 8433 before = get_tv_number_chk(&argvars[2], &error); 8434 if (error) 8435 return; /* type error; errmsg already given */ 8436 8437 if (before == l1->lv_len) 8438 item = NULL; 8439 else 8440 { 8441 item = list_find(l1, before); 8442 if (item == NULL) 8443 { 8444 EMSGN(_(e_listidx), before); 8445 return; 8446 } 8447 } 8448 } 8449 else 8450 item = NULL; 8451 list_extend(l1, l2, item); 8452 8453 copy_tv(&argvars[0], rettv); 8454 } 8455 } 8456 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8457 { 8458 dict_T *d1, *d2; 8459 dictitem_T *di1; 8460 char_u *action; 8461 int i; 8462 hashitem_T *hi2; 8463 int todo; 8464 8465 d1 = argvars[0].vval.v_dict; 8466 d2 = argvars[1].vval.v_dict; 8467 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8468 && d2 != NULL) 8469 { 8470 /* Check the third argument. */ 8471 if (argvars[2].v_type != VAR_UNKNOWN) 8472 { 8473 static char *(av[]) = {"keep", "force", "error"}; 8474 8475 action = get_tv_string_chk(&argvars[2]); 8476 if (action == NULL) 8477 return; /* type error; errmsg already given */ 8478 for (i = 0; i < 3; ++i) 8479 if (STRCMP(action, av[i]) == 0) 8480 break; 8481 if (i == 3) 8482 { 8483 EMSGN(_(e_invarg2), action); 8484 return; 8485 } 8486 } 8487 else 8488 action = (char_u *)"force"; 8489 8490 /* Go over all entries in the second dict and add them to the 8491 * first dict. */ 8492 todo = d2->dv_hashtab.ht_used; 8493 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8494 { 8495 if (!HASHITEM_EMPTY(hi2)) 8496 { 8497 --todo; 8498 di1 = dict_find(d1, hi2->hi_key, -1); 8499 if (di1 == NULL) 8500 { 8501 di1 = dictitem_copy(HI2DI(hi2)); 8502 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8503 dictitem_free(di1); 8504 } 8505 else if (*action == 'e') 8506 { 8507 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8508 break; 8509 } 8510 else if (*action == 'f') 8511 { 8512 clear_tv(&di1->di_tv); 8513 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8514 } 8515 } 8516 } 8517 8518 copy_tv(&argvars[0], rettv); 8519 } 8520 } 8521 else 8522 EMSG2(_(e_listdictarg), "extend()"); 8523 } 8524 8525 /* 8526 * "filereadable()" function 8527 */ 8528 static void 8529 f_filereadable(argvars, rettv) 8530 typval_T *argvars; 8531 typval_T *rettv; 8532 { 8533 FILE *fd; 8534 char_u *p; 8535 int n; 8536 8537 p = get_tv_string(&argvars[0]); 8538 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8539 { 8540 n = TRUE; 8541 fclose(fd); 8542 } 8543 else 8544 n = FALSE; 8545 8546 rettv->vval.v_number = n; 8547 } 8548 8549 /* 8550 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8551 * rights to write into. 8552 */ 8553 static void 8554 f_filewritable(argvars, rettv) 8555 typval_T *argvars; 8556 typval_T *rettv; 8557 { 8558 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8559 } 8560 8561 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8562 8563 static void 8564 findfilendir(argvars, rettv, dir) 8565 typval_T *argvars; 8566 typval_T *rettv; 8567 int dir; 8568 { 8569 #ifdef FEAT_SEARCHPATH 8570 char_u *fname; 8571 char_u *fresult = NULL; 8572 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8573 char_u *p; 8574 char_u pathbuf[NUMBUFLEN]; 8575 int count = 1; 8576 int first = TRUE; 8577 8578 fname = get_tv_string(&argvars[0]); 8579 8580 if (argvars[1].v_type != VAR_UNKNOWN) 8581 { 8582 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8583 if (p == NULL) 8584 count = -1; /* error */ 8585 else 8586 { 8587 if (*p != NUL) 8588 path = p; 8589 8590 if (argvars[2].v_type != VAR_UNKNOWN) 8591 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8592 } 8593 } 8594 8595 if (*fname != NUL && count >= 0) 8596 { 8597 do 8598 { 8599 vim_free(fresult); 8600 fresult = find_file_in_path_option(first ? fname : NULL, 8601 first ? (int)STRLEN(fname) : 0, 8602 0, first, path, dir, NULL); 8603 first = FALSE; 8604 } while (--count > 0 && fresult != NULL); 8605 } 8606 8607 rettv->vval.v_string = fresult; 8608 #else 8609 rettv->vval.v_string = NULL; 8610 #endif 8611 rettv->v_type = VAR_STRING; 8612 } 8613 8614 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8615 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8616 8617 /* 8618 * Implementation of map() and filter(). 8619 */ 8620 static void 8621 filter_map(argvars, rettv, map) 8622 typval_T *argvars; 8623 typval_T *rettv; 8624 int map; 8625 { 8626 char_u buf[NUMBUFLEN]; 8627 char_u *expr; 8628 listitem_T *li, *nli; 8629 list_T *l = NULL; 8630 dictitem_T *di; 8631 hashtab_T *ht; 8632 hashitem_T *hi; 8633 dict_T *d = NULL; 8634 typval_T save_val; 8635 typval_T save_key; 8636 int rem; 8637 int todo; 8638 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8639 8640 8641 rettv->vval.v_number = 0; 8642 if (argvars[0].v_type == VAR_LIST) 8643 { 8644 if ((l = argvars[0].vval.v_list) == NULL 8645 || (map && tv_check_lock(l->lv_lock, msg))) 8646 return; 8647 } 8648 else if (argvars[0].v_type == VAR_DICT) 8649 { 8650 if ((d = argvars[0].vval.v_dict) == NULL 8651 || (map && tv_check_lock(d->dv_lock, msg))) 8652 return; 8653 } 8654 else 8655 { 8656 EMSG2(_(e_listdictarg), msg); 8657 return; 8658 } 8659 8660 expr = get_tv_string_buf_chk(&argvars[1], buf); 8661 /* On type errors, the preceding call has already displayed an error 8662 * message. Avoid a misleading error message for an empty string that 8663 * was not passed as argument. */ 8664 if (expr != NULL) 8665 { 8666 prepare_vimvar(VV_VAL, &save_val); 8667 expr = skipwhite(expr); 8668 8669 if (argvars[0].v_type == VAR_DICT) 8670 { 8671 prepare_vimvar(VV_KEY, &save_key); 8672 vimvars[VV_KEY].vv_type = VAR_STRING; 8673 8674 ht = &d->dv_hashtab; 8675 hash_lock(ht); 8676 todo = ht->ht_used; 8677 for (hi = ht->ht_array; todo > 0; ++hi) 8678 { 8679 if (!HASHITEM_EMPTY(hi)) 8680 { 8681 --todo; 8682 di = HI2DI(hi); 8683 if (tv_check_lock(di->di_tv.v_lock, msg)) 8684 break; 8685 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8686 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8687 break; 8688 if (!map && rem) 8689 dictitem_remove(d, di); 8690 clear_tv(&vimvars[VV_KEY].vv_tv); 8691 } 8692 } 8693 hash_unlock(ht); 8694 8695 restore_vimvar(VV_KEY, &save_key); 8696 } 8697 else 8698 { 8699 for (li = l->lv_first; li != NULL; li = nli) 8700 { 8701 if (tv_check_lock(li->li_tv.v_lock, msg)) 8702 break; 8703 nli = li->li_next; 8704 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8705 break; 8706 if (!map && rem) 8707 listitem_remove(l, li); 8708 } 8709 } 8710 8711 restore_vimvar(VV_VAL, &save_val); 8712 } 8713 8714 copy_tv(&argvars[0], rettv); 8715 } 8716 8717 static int 8718 filter_map_one(tv, expr, map, remp) 8719 typval_T *tv; 8720 char_u *expr; 8721 int map; 8722 int *remp; 8723 { 8724 typval_T rettv; 8725 char_u *s; 8726 8727 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8728 s = expr; 8729 if (eval1(&s, &rettv, TRUE) == FAIL) 8730 return FAIL; 8731 if (*s != NUL) /* check for trailing chars after expr */ 8732 { 8733 EMSG2(_(e_invexpr2), s); 8734 return FAIL; 8735 } 8736 if (map) 8737 { 8738 /* map(): replace the list item value */ 8739 clear_tv(tv); 8740 *tv = rettv; 8741 } 8742 else 8743 { 8744 int error = FALSE; 8745 8746 /* filter(): when expr is zero remove the item */ 8747 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8748 clear_tv(&rettv); 8749 /* On type error, nothing has been removed; return FAIL to stop the 8750 * loop. The error message was given by get_tv_number_chk(). */ 8751 if (error) 8752 return FAIL; 8753 } 8754 clear_tv(&vimvars[VV_VAL].vv_tv); 8755 return OK; 8756 } 8757 8758 /* 8759 * "filter()" function 8760 */ 8761 static void 8762 f_filter(argvars, rettv) 8763 typval_T *argvars; 8764 typval_T *rettv; 8765 { 8766 filter_map(argvars, rettv, FALSE); 8767 } 8768 8769 /* 8770 * "finddir({fname}[, {path}[, {count}]])" function 8771 */ 8772 static void 8773 f_finddir(argvars, rettv) 8774 typval_T *argvars; 8775 typval_T *rettv; 8776 { 8777 findfilendir(argvars, rettv, TRUE); 8778 } 8779 8780 /* 8781 * "findfile({fname}[, {path}[, {count}]])" function 8782 */ 8783 static void 8784 f_findfile(argvars, rettv) 8785 typval_T *argvars; 8786 typval_T *rettv; 8787 { 8788 findfilendir(argvars, rettv, FALSE); 8789 } 8790 8791 /* 8792 * "fnamemodify({fname}, {mods})" function 8793 */ 8794 static void 8795 f_fnamemodify(argvars, rettv) 8796 typval_T *argvars; 8797 typval_T *rettv; 8798 { 8799 char_u *fname; 8800 char_u *mods; 8801 int usedlen = 0; 8802 int len; 8803 char_u *fbuf = NULL; 8804 char_u buf[NUMBUFLEN]; 8805 8806 fname = get_tv_string_chk(&argvars[0]); 8807 mods = get_tv_string_buf_chk(&argvars[1], buf); 8808 if (fname == NULL || mods == NULL) 8809 fname = NULL; 8810 else 8811 { 8812 len = (int)STRLEN(fname); 8813 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8814 } 8815 8816 rettv->v_type = VAR_STRING; 8817 if (fname == NULL) 8818 rettv->vval.v_string = NULL; 8819 else 8820 rettv->vval.v_string = vim_strnsave(fname, len); 8821 vim_free(fbuf); 8822 } 8823 8824 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8825 8826 /* 8827 * "foldclosed()" function 8828 */ 8829 static void 8830 foldclosed_both(argvars, rettv, end) 8831 typval_T *argvars; 8832 typval_T *rettv; 8833 int end; 8834 { 8835 #ifdef FEAT_FOLDING 8836 linenr_T lnum; 8837 linenr_T first, last; 8838 8839 lnum = get_tv_lnum(argvars); 8840 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8841 { 8842 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8843 { 8844 if (end) 8845 rettv->vval.v_number = (varnumber_T)last; 8846 else 8847 rettv->vval.v_number = (varnumber_T)first; 8848 return; 8849 } 8850 } 8851 #endif 8852 rettv->vval.v_number = -1; 8853 } 8854 8855 /* 8856 * "foldclosed()" function 8857 */ 8858 static void 8859 f_foldclosed(argvars, rettv) 8860 typval_T *argvars; 8861 typval_T *rettv; 8862 { 8863 foldclosed_both(argvars, rettv, FALSE); 8864 } 8865 8866 /* 8867 * "foldclosedend()" function 8868 */ 8869 static void 8870 f_foldclosedend(argvars, rettv) 8871 typval_T *argvars; 8872 typval_T *rettv; 8873 { 8874 foldclosed_both(argvars, rettv, TRUE); 8875 } 8876 8877 /* 8878 * "foldlevel()" function 8879 */ 8880 static void 8881 f_foldlevel(argvars, rettv) 8882 typval_T *argvars; 8883 typval_T *rettv; 8884 { 8885 #ifdef FEAT_FOLDING 8886 linenr_T lnum; 8887 8888 lnum = get_tv_lnum(argvars); 8889 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8890 rettv->vval.v_number = foldLevel(lnum); 8891 else 8892 #endif 8893 rettv->vval.v_number = 0; 8894 } 8895 8896 /* 8897 * "foldtext()" function 8898 */ 8899 /*ARGSUSED*/ 8900 static void 8901 f_foldtext(argvars, rettv) 8902 typval_T *argvars; 8903 typval_T *rettv; 8904 { 8905 #ifdef FEAT_FOLDING 8906 linenr_T lnum; 8907 char_u *s; 8908 char_u *r; 8909 int len; 8910 char *txt; 8911 #endif 8912 8913 rettv->v_type = VAR_STRING; 8914 rettv->vval.v_string = NULL; 8915 #ifdef FEAT_FOLDING 8916 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 8917 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 8918 <= curbuf->b_ml.ml_line_count 8919 && vimvars[VV_FOLDDASHES].vv_str != NULL) 8920 { 8921 /* Find first non-empty line in the fold. */ 8922 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 8923 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 8924 { 8925 if (!linewhite(lnum)) 8926 break; 8927 ++lnum; 8928 } 8929 8930 /* Find interesting text in this line. */ 8931 s = skipwhite(ml_get(lnum)); 8932 /* skip C comment-start */ 8933 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 8934 { 8935 s = skipwhite(s + 2); 8936 if (*skipwhite(s) == NUL 8937 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 8938 { 8939 s = skipwhite(ml_get(lnum + 1)); 8940 if (*s == '*') 8941 s = skipwhite(s + 1); 8942 } 8943 } 8944 txt = _("+-%s%3ld lines: "); 8945 r = alloc((unsigned)(STRLEN(txt) 8946 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 8947 + 20 /* for %3ld */ 8948 + STRLEN(s))); /* concatenated */ 8949 if (r != NULL) 8950 { 8951 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 8952 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 8953 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 8954 len = (int)STRLEN(r); 8955 STRCAT(r, s); 8956 /* remove 'foldmarker' and 'commentstring' */ 8957 foldtext_cleanup(r + len); 8958 rettv->vval.v_string = r; 8959 } 8960 } 8961 #endif 8962 } 8963 8964 /* 8965 * "foldtextresult(lnum)" function 8966 */ 8967 /*ARGSUSED*/ 8968 static void 8969 f_foldtextresult(argvars, rettv) 8970 typval_T *argvars; 8971 typval_T *rettv; 8972 { 8973 #ifdef FEAT_FOLDING 8974 linenr_T lnum; 8975 char_u *text; 8976 char_u buf[51]; 8977 foldinfo_T foldinfo; 8978 int fold_count; 8979 #endif 8980 8981 rettv->v_type = VAR_STRING; 8982 rettv->vval.v_string = NULL; 8983 #ifdef FEAT_FOLDING 8984 lnum = get_tv_lnum(argvars); 8985 /* treat illegal types and illegal string values for {lnum} the same */ 8986 if (lnum < 0) 8987 lnum = 0; 8988 fold_count = foldedCount(curwin, lnum, &foldinfo); 8989 if (fold_count > 0) 8990 { 8991 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 8992 &foldinfo, buf); 8993 if (text == buf) 8994 text = vim_strsave(text); 8995 rettv->vval.v_string = text; 8996 } 8997 #endif 8998 } 8999 9000 /* 9001 * "foreground()" function 9002 */ 9003 /*ARGSUSED*/ 9004 static void 9005 f_foreground(argvars, rettv) 9006 typval_T *argvars; 9007 typval_T *rettv; 9008 { 9009 rettv->vval.v_number = 0; 9010 #ifdef FEAT_GUI 9011 if (gui.in_use) 9012 gui_mch_set_foreground(); 9013 #else 9014 # ifdef WIN32 9015 win32_set_foreground(); 9016 # endif 9017 #endif 9018 } 9019 9020 /* 9021 * "function()" function 9022 */ 9023 /*ARGSUSED*/ 9024 static void 9025 f_function(argvars, rettv) 9026 typval_T *argvars; 9027 typval_T *rettv; 9028 { 9029 char_u *s; 9030 9031 rettv->vval.v_number = 0; 9032 s = get_tv_string(&argvars[0]); 9033 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9034 EMSG2(_(e_invarg2), s); 9035 else if (!function_exists(s)) 9036 EMSG2(_("E700: Unknown function: %s"), s); 9037 else 9038 { 9039 rettv->vval.v_string = vim_strsave(s); 9040 rettv->v_type = VAR_FUNC; 9041 } 9042 } 9043 9044 /* 9045 * "garbagecollect()" function 9046 */ 9047 /*ARGSUSED*/ 9048 static void 9049 f_garbagecollect(argvars, rettv) 9050 typval_T *argvars; 9051 typval_T *rettv; 9052 { 9053 garbage_collect(); 9054 } 9055 9056 /* 9057 * "get()" function 9058 */ 9059 static void 9060 f_get(argvars, rettv) 9061 typval_T *argvars; 9062 typval_T *rettv; 9063 { 9064 listitem_T *li; 9065 list_T *l; 9066 dictitem_T *di; 9067 dict_T *d; 9068 typval_T *tv = NULL; 9069 9070 if (argvars[0].v_type == VAR_LIST) 9071 { 9072 if ((l = argvars[0].vval.v_list) != NULL) 9073 { 9074 int error = FALSE; 9075 9076 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9077 if (!error && li != NULL) 9078 tv = &li->li_tv; 9079 } 9080 } 9081 else if (argvars[0].v_type == VAR_DICT) 9082 { 9083 if ((d = argvars[0].vval.v_dict) != NULL) 9084 { 9085 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9086 if (di != NULL) 9087 tv = &di->di_tv; 9088 } 9089 } 9090 else 9091 EMSG2(_(e_listdictarg), "get()"); 9092 9093 if (tv == NULL) 9094 { 9095 if (argvars[2].v_type == VAR_UNKNOWN) 9096 rettv->vval.v_number = 0; 9097 else 9098 copy_tv(&argvars[2], rettv); 9099 } 9100 else 9101 copy_tv(tv, rettv); 9102 } 9103 9104 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9105 9106 /* 9107 * Get line or list of lines from buffer "buf" into "rettv". 9108 * Return a range (from start to end) of lines in rettv from the specified 9109 * buffer. 9110 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9111 */ 9112 static void 9113 get_buffer_lines(buf, start, end, retlist, rettv) 9114 buf_T *buf; 9115 linenr_T start; 9116 linenr_T end; 9117 int retlist; 9118 typval_T *rettv; 9119 { 9120 char_u *p; 9121 list_T *l = NULL; 9122 listitem_T *li; 9123 9124 if (retlist) 9125 { 9126 l = list_alloc(); 9127 if (l == NULL) 9128 return; 9129 9130 rettv->vval.v_list = l; 9131 rettv->v_type = VAR_LIST; 9132 ++l->lv_refcount; 9133 } 9134 else 9135 rettv->vval.v_number = 0; 9136 9137 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9138 return; 9139 9140 if (!retlist) 9141 { 9142 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9143 p = ml_get_buf(buf, start, FALSE); 9144 else 9145 p = (char_u *)""; 9146 9147 rettv->v_type = VAR_STRING; 9148 rettv->vval.v_string = vim_strsave(p); 9149 } 9150 else 9151 { 9152 if (end < start) 9153 return; 9154 9155 if (start < 1) 9156 start = 1; 9157 if (end > buf->b_ml.ml_line_count) 9158 end = buf->b_ml.ml_line_count; 9159 while (start <= end) 9160 { 9161 li = listitem_alloc(); 9162 if (li == NULL) 9163 break; 9164 list_append(l, li); 9165 li->li_tv.v_type = VAR_STRING; 9166 li->li_tv.v_lock = 0; 9167 li->li_tv.vval.v_string = 9168 vim_strsave(ml_get_buf(buf, start++, FALSE)); 9169 } 9170 } 9171 } 9172 9173 /* 9174 * "getbufline()" function 9175 */ 9176 static void 9177 f_getbufline(argvars, rettv) 9178 typval_T *argvars; 9179 typval_T *rettv; 9180 { 9181 linenr_T lnum; 9182 linenr_T end; 9183 buf_T *buf; 9184 9185 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9186 ++emsg_off; 9187 buf = get_buf_tv(&argvars[0]); 9188 --emsg_off; 9189 9190 lnum = get_tv_lnum(&argvars[1]); 9191 if (argvars[2].v_type == VAR_UNKNOWN) 9192 end = lnum; 9193 else 9194 end = get_tv_lnum(&argvars[2]); 9195 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9196 } 9197 9198 /* 9199 * "getbufvar()" function 9200 */ 9201 static void 9202 f_getbufvar(argvars, rettv) 9203 typval_T *argvars; 9204 typval_T *rettv; 9205 { 9206 buf_T *buf; 9207 buf_T *save_curbuf; 9208 char_u *varname; 9209 dictitem_T *v; 9210 9211 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9212 varname = get_tv_string_chk(&argvars[1]); 9213 ++emsg_off; 9214 buf = get_buf_tv(&argvars[0]); 9215 9216 rettv->v_type = VAR_STRING; 9217 rettv->vval.v_string = NULL; 9218 9219 if (buf != NULL && varname != NULL) 9220 { 9221 if (*varname == '&') /* buffer-local-option */ 9222 { 9223 /* set curbuf to be our buf, temporarily */ 9224 save_curbuf = curbuf; 9225 curbuf = buf; 9226 9227 get_option_tv(&varname, rettv, TRUE); 9228 9229 /* restore previous notion of curbuf */ 9230 curbuf = save_curbuf; 9231 } 9232 else 9233 { 9234 if (*varname == NUL) 9235 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9236 * scope prefix before the NUL byte is required by 9237 * find_var_in_ht(). */ 9238 varname = (char_u *)"b:" + 2; 9239 /* look up the variable */ 9240 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9241 if (v != NULL) 9242 copy_tv(&v->di_tv, rettv); 9243 } 9244 } 9245 9246 --emsg_off; 9247 } 9248 9249 /* 9250 * "getchar()" function 9251 */ 9252 static void 9253 f_getchar(argvars, rettv) 9254 typval_T *argvars; 9255 typval_T *rettv; 9256 { 9257 varnumber_T n; 9258 int error = FALSE; 9259 9260 ++no_mapping; 9261 ++allow_keys; 9262 if (argvars[0].v_type == VAR_UNKNOWN) 9263 /* getchar(): blocking wait. */ 9264 n = safe_vgetc(); 9265 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9266 /* getchar(1): only check if char avail */ 9267 n = vpeekc(); 9268 else if (error || vpeekc() == NUL) 9269 /* illegal argument or getchar(0) and no char avail: return zero */ 9270 n = 0; 9271 else 9272 /* getchar(0) and char avail: return char */ 9273 n = safe_vgetc(); 9274 --no_mapping; 9275 --allow_keys; 9276 9277 rettv->vval.v_number = n; 9278 if (IS_SPECIAL(n) || mod_mask != 0) 9279 { 9280 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9281 int i = 0; 9282 9283 /* Turn a special key into three bytes, plus modifier. */ 9284 if (mod_mask != 0) 9285 { 9286 temp[i++] = K_SPECIAL; 9287 temp[i++] = KS_MODIFIER; 9288 temp[i++] = mod_mask; 9289 } 9290 if (IS_SPECIAL(n)) 9291 { 9292 temp[i++] = K_SPECIAL; 9293 temp[i++] = K_SECOND(n); 9294 temp[i++] = K_THIRD(n); 9295 } 9296 #ifdef FEAT_MBYTE 9297 else if (has_mbyte) 9298 i += (*mb_char2bytes)(n, temp + i); 9299 #endif 9300 else 9301 temp[i++] = n; 9302 temp[i++] = NUL; 9303 rettv->v_type = VAR_STRING; 9304 rettv->vval.v_string = vim_strsave(temp); 9305 } 9306 } 9307 9308 /* 9309 * "getcharmod()" function 9310 */ 9311 /*ARGSUSED*/ 9312 static void 9313 f_getcharmod(argvars, rettv) 9314 typval_T *argvars; 9315 typval_T *rettv; 9316 { 9317 rettv->vval.v_number = mod_mask; 9318 } 9319 9320 /* 9321 * "getcmdline()" function 9322 */ 9323 /*ARGSUSED*/ 9324 static void 9325 f_getcmdline(argvars, rettv) 9326 typval_T *argvars; 9327 typval_T *rettv; 9328 { 9329 rettv->v_type = VAR_STRING; 9330 rettv->vval.v_string = get_cmdline_str(); 9331 } 9332 9333 /* 9334 * "getcmdpos()" function 9335 */ 9336 /*ARGSUSED*/ 9337 static void 9338 f_getcmdpos(argvars, rettv) 9339 typval_T *argvars; 9340 typval_T *rettv; 9341 { 9342 rettv->vval.v_number = get_cmdline_pos() + 1; 9343 } 9344 9345 /* 9346 * "getcwd()" function 9347 */ 9348 /*ARGSUSED*/ 9349 static void 9350 f_getcwd(argvars, rettv) 9351 typval_T *argvars; 9352 typval_T *rettv; 9353 { 9354 char_u cwd[MAXPATHL]; 9355 9356 rettv->v_type = VAR_STRING; 9357 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9358 rettv->vval.v_string = NULL; 9359 else 9360 { 9361 rettv->vval.v_string = vim_strsave(cwd); 9362 #ifdef BACKSLASH_IN_FILENAME 9363 if (rettv->vval.v_string != NULL) 9364 slash_adjust(rettv->vval.v_string); 9365 #endif 9366 } 9367 } 9368 9369 /* 9370 * "getfontname()" function 9371 */ 9372 /*ARGSUSED*/ 9373 static void 9374 f_getfontname(argvars, rettv) 9375 typval_T *argvars; 9376 typval_T *rettv; 9377 { 9378 rettv->v_type = VAR_STRING; 9379 rettv->vval.v_string = NULL; 9380 #ifdef FEAT_GUI 9381 if (gui.in_use) 9382 { 9383 GuiFont font; 9384 char_u *name = NULL; 9385 9386 if (argvars[0].v_type == VAR_UNKNOWN) 9387 { 9388 /* Get the "Normal" font. Either the name saved by 9389 * hl_set_font_name() or from the font ID. */ 9390 font = gui.norm_font; 9391 name = hl_get_font_name(); 9392 } 9393 else 9394 { 9395 name = get_tv_string(&argvars[0]); 9396 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9397 return; 9398 font = gui_mch_get_font(name, FALSE); 9399 if (font == NOFONT) 9400 return; /* Invalid font name, return empty string. */ 9401 } 9402 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9403 if (argvars[0].v_type != VAR_UNKNOWN) 9404 gui_mch_free_font(font); 9405 } 9406 #endif 9407 } 9408 9409 /* 9410 * "getfperm({fname})" function 9411 */ 9412 static void 9413 f_getfperm(argvars, rettv) 9414 typval_T *argvars; 9415 typval_T *rettv; 9416 { 9417 char_u *fname; 9418 struct stat st; 9419 char_u *perm = NULL; 9420 char_u flags[] = "rwx"; 9421 int i; 9422 9423 fname = get_tv_string(&argvars[0]); 9424 9425 rettv->v_type = VAR_STRING; 9426 if (mch_stat((char *)fname, &st) >= 0) 9427 { 9428 perm = vim_strsave((char_u *)"---------"); 9429 if (perm != NULL) 9430 { 9431 for (i = 0; i < 9; i++) 9432 { 9433 if (st.st_mode & (1 << (8 - i))) 9434 perm[i] = flags[i % 3]; 9435 } 9436 } 9437 } 9438 rettv->vval.v_string = perm; 9439 } 9440 9441 /* 9442 * "getfsize({fname})" function 9443 */ 9444 static void 9445 f_getfsize(argvars, rettv) 9446 typval_T *argvars; 9447 typval_T *rettv; 9448 { 9449 char_u *fname; 9450 struct stat st; 9451 9452 fname = get_tv_string(&argvars[0]); 9453 9454 rettv->v_type = VAR_NUMBER; 9455 9456 if (mch_stat((char *)fname, &st) >= 0) 9457 { 9458 if (mch_isdir(fname)) 9459 rettv->vval.v_number = 0; 9460 else 9461 rettv->vval.v_number = (varnumber_T)st.st_size; 9462 } 9463 else 9464 rettv->vval.v_number = -1; 9465 } 9466 9467 /* 9468 * "getftime({fname})" function 9469 */ 9470 static void 9471 f_getftime(argvars, rettv) 9472 typval_T *argvars; 9473 typval_T *rettv; 9474 { 9475 char_u *fname; 9476 struct stat st; 9477 9478 fname = get_tv_string(&argvars[0]); 9479 9480 if (mch_stat((char *)fname, &st) >= 0) 9481 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9482 else 9483 rettv->vval.v_number = -1; 9484 } 9485 9486 /* 9487 * "getftype({fname})" function 9488 */ 9489 static void 9490 f_getftype(argvars, rettv) 9491 typval_T *argvars; 9492 typval_T *rettv; 9493 { 9494 char_u *fname; 9495 struct stat st; 9496 char_u *type = NULL; 9497 char *t; 9498 9499 fname = get_tv_string(&argvars[0]); 9500 9501 rettv->v_type = VAR_STRING; 9502 if (mch_lstat((char *)fname, &st) >= 0) 9503 { 9504 #ifdef S_ISREG 9505 if (S_ISREG(st.st_mode)) 9506 t = "file"; 9507 else if (S_ISDIR(st.st_mode)) 9508 t = "dir"; 9509 # ifdef S_ISLNK 9510 else if (S_ISLNK(st.st_mode)) 9511 t = "link"; 9512 # endif 9513 # ifdef S_ISBLK 9514 else if (S_ISBLK(st.st_mode)) 9515 t = "bdev"; 9516 # endif 9517 # ifdef S_ISCHR 9518 else if (S_ISCHR(st.st_mode)) 9519 t = "cdev"; 9520 # endif 9521 # ifdef S_ISFIFO 9522 else if (S_ISFIFO(st.st_mode)) 9523 t = "fifo"; 9524 # endif 9525 # ifdef S_ISSOCK 9526 else if (S_ISSOCK(st.st_mode)) 9527 t = "fifo"; 9528 # endif 9529 else 9530 t = "other"; 9531 #else 9532 # ifdef S_IFMT 9533 switch (st.st_mode & S_IFMT) 9534 { 9535 case S_IFREG: t = "file"; break; 9536 case S_IFDIR: t = "dir"; break; 9537 # ifdef S_IFLNK 9538 case S_IFLNK: t = "link"; break; 9539 # endif 9540 # ifdef S_IFBLK 9541 case S_IFBLK: t = "bdev"; break; 9542 # endif 9543 # ifdef S_IFCHR 9544 case S_IFCHR: t = "cdev"; break; 9545 # endif 9546 # ifdef S_IFIFO 9547 case S_IFIFO: t = "fifo"; break; 9548 # endif 9549 # ifdef S_IFSOCK 9550 case S_IFSOCK: t = "socket"; break; 9551 # endif 9552 default: t = "other"; 9553 } 9554 # else 9555 if (mch_isdir(fname)) 9556 t = "dir"; 9557 else 9558 t = "file"; 9559 # endif 9560 #endif 9561 type = vim_strsave((char_u *)t); 9562 } 9563 rettv->vval.v_string = type; 9564 } 9565 9566 /* 9567 * "getline(lnum, [end])" function 9568 */ 9569 static void 9570 f_getline(argvars, rettv) 9571 typval_T *argvars; 9572 typval_T *rettv; 9573 { 9574 linenr_T lnum; 9575 linenr_T end; 9576 int retlist; 9577 9578 lnum = get_tv_lnum(argvars); 9579 if (argvars[1].v_type == VAR_UNKNOWN) 9580 { 9581 end = 0; 9582 retlist = FALSE; 9583 } 9584 else 9585 { 9586 end = get_tv_lnum(&argvars[1]); 9587 retlist = TRUE; 9588 } 9589 9590 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9591 } 9592 9593 /* 9594 * "getqflist()" function 9595 */ 9596 /*ARGSUSED*/ 9597 static void 9598 f_getqflist(argvars, rettv) 9599 typval_T *argvars; 9600 typval_T *rettv; 9601 { 9602 #ifdef FEAT_QUICKFIX 9603 list_T *l; 9604 #endif 9605 9606 rettv->vval.v_number = FALSE; 9607 #ifdef FEAT_QUICKFIX 9608 l = list_alloc(); 9609 if (l != NULL) 9610 { 9611 if (get_errorlist(l) != FAIL) 9612 { 9613 rettv->vval.v_list = l; 9614 rettv->v_type = VAR_LIST; 9615 ++l->lv_refcount; 9616 } 9617 else 9618 list_free(l); 9619 } 9620 #endif 9621 } 9622 9623 /* 9624 * "getreg()" function 9625 */ 9626 static void 9627 f_getreg(argvars, rettv) 9628 typval_T *argvars; 9629 typval_T *rettv; 9630 { 9631 char_u *strregname; 9632 int regname; 9633 int arg2 = FALSE; 9634 int error = FALSE; 9635 9636 if (argvars[0].v_type != VAR_UNKNOWN) 9637 { 9638 strregname = get_tv_string_chk(&argvars[0]); 9639 error = strregname == NULL; 9640 if (argvars[1].v_type != VAR_UNKNOWN) 9641 arg2 = get_tv_number_chk(&argvars[1], &error); 9642 } 9643 else 9644 strregname = vimvars[VV_REG].vv_str; 9645 regname = (strregname == NULL ? '"' : *strregname); 9646 if (regname == 0) 9647 regname = '"'; 9648 9649 rettv->v_type = VAR_STRING; 9650 rettv->vval.v_string = error ? NULL : 9651 get_reg_contents(regname, TRUE, arg2); 9652 } 9653 9654 /* 9655 * "getregtype()" function 9656 */ 9657 static void 9658 f_getregtype(argvars, rettv) 9659 typval_T *argvars; 9660 typval_T *rettv; 9661 { 9662 char_u *strregname; 9663 int regname; 9664 char_u buf[NUMBUFLEN + 2]; 9665 long reglen = 0; 9666 9667 if (argvars[0].v_type != VAR_UNKNOWN) 9668 { 9669 strregname = get_tv_string_chk(&argvars[0]); 9670 if (strregname == NULL) /* type error; errmsg already given */ 9671 { 9672 rettv->v_type = VAR_STRING; 9673 rettv->vval.v_string = NULL; 9674 return; 9675 } 9676 } 9677 else 9678 /* Default to v:register */ 9679 strregname = vimvars[VV_REG].vv_str; 9680 9681 regname = (strregname == NULL ? '"' : *strregname); 9682 if (regname == 0) 9683 regname = '"'; 9684 9685 buf[0] = NUL; 9686 buf[1] = NUL; 9687 switch (get_reg_type(regname, ®len)) 9688 { 9689 case MLINE: buf[0] = 'V'; break; 9690 case MCHAR: buf[0] = 'v'; break; 9691 #ifdef FEAT_VISUAL 9692 case MBLOCK: 9693 buf[0] = Ctrl_V; 9694 sprintf((char *)buf + 1, "%ld", reglen + 1); 9695 break; 9696 #endif 9697 } 9698 rettv->v_type = VAR_STRING; 9699 rettv->vval.v_string = vim_strsave(buf); 9700 } 9701 9702 /* 9703 * "getwinposx()" function 9704 */ 9705 /*ARGSUSED*/ 9706 static void 9707 f_getwinposx(argvars, rettv) 9708 typval_T *argvars; 9709 typval_T *rettv; 9710 { 9711 rettv->vval.v_number = -1; 9712 #ifdef FEAT_GUI 9713 if (gui.in_use) 9714 { 9715 int x, y; 9716 9717 if (gui_mch_get_winpos(&x, &y) == OK) 9718 rettv->vval.v_number = x; 9719 } 9720 #endif 9721 } 9722 9723 /* 9724 * "getwinposy()" function 9725 */ 9726 /*ARGSUSED*/ 9727 static void 9728 f_getwinposy(argvars, rettv) 9729 typval_T *argvars; 9730 typval_T *rettv; 9731 { 9732 rettv->vval.v_number = -1; 9733 #ifdef FEAT_GUI 9734 if (gui.in_use) 9735 { 9736 int x, y; 9737 9738 if (gui_mch_get_winpos(&x, &y) == OK) 9739 rettv->vval.v_number = y; 9740 } 9741 #endif 9742 } 9743 9744 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9745 9746 static win_T * 9747 find_win_by_nr(vp) 9748 typval_T *vp; 9749 { 9750 #ifdef FEAT_WINDOWS 9751 win_T *wp; 9752 #endif 9753 int nr; 9754 9755 nr = get_tv_number_chk(vp, NULL); 9756 9757 #ifdef FEAT_WINDOWS 9758 if (nr < 0) 9759 return NULL; 9760 if (nr == 0) 9761 return curwin; 9762 9763 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9764 if (--nr <= 0) 9765 break; 9766 return wp; 9767 #else 9768 if (nr == 0 || nr == 1) 9769 return curwin; 9770 return NULL; 9771 #endif 9772 } 9773 9774 /* 9775 * "getwinvar()" function 9776 */ 9777 static void 9778 f_getwinvar(argvars, rettv) 9779 typval_T *argvars; 9780 typval_T *rettv; 9781 { 9782 win_T *win, *oldcurwin; 9783 char_u *varname; 9784 dictitem_T *v; 9785 9786 win = find_win_by_nr(&argvars[0]); 9787 varname = get_tv_string_chk(&argvars[1]); 9788 ++emsg_off; 9789 9790 rettv->v_type = VAR_STRING; 9791 rettv->vval.v_string = NULL; 9792 9793 if (win != NULL && varname != NULL) 9794 { 9795 if (*varname == '&') /* window-local-option */ 9796 { 9797 /* Set curwin to be our win, temporarily. Also set curbuf, so 9798 * that we can get buffer-local options. */ 9799 oldcurwin = curwin; 9800 curwin = win; 9801 curbuf = win->w_buffer; 9802 9803 get_option_tv(&varname, rettv, 1); 9804 9805 /* restore previous notion of curwin */ 9806 curwin = oldcurwin; 9807 curbuf = curwin->w_buffer; 9808 } 9809 else 9810 { 9811 if (*varname == NUL) 9812 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9813 * scope prefix before the NUL byte is required by 9814 * find_var_in_ht(). */ 9815 varname = (char_u *)"w:" + 2; 9816 /* look up the variable */ 9817 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9818 if (v != NULL) 9819 copy_tv(&v->di_tv, rettv); 9820 } 9821 } 9822 9823 --emsg_off; 9824 } 9825 9826 /* 9827 * "glob()" function 9828 */ 9829 static void 9830 f_glob(argvars, rettv) 9831 typval_T *argvars; 9832 typval_T *rettv; 9833 { 9834 expand_T xpc; 9835 9836 ExpandInit(&xpc); 9837 xpc.xp_context = EXPAND_FILES; 9838 rettv->v_type = VAR_STRING; 9839 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9840 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9841 ExpandCleanup(&xpc); 9842 } 9843 9844 /* 9845 * "globpath()" function 9846 */ 9847 static void 9848 f_globpath(argvars, rettv) 9849 typval_T *argvars; 9850 typval_T *rettv; 9851 { 9852 char_u buf1[NUMBUFLEN]; 9853 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9854 9855 rettv->v_type = VAR_STRING; 9856 if (file == NULL) 9857 rettv->vval.v_string = NULL; 9858 else 9859 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9860 } 9861 9862 /* 9863 * "has()" function 9864 */ 9865 static void 9866 f_has(argvars, rettv) 9867 typval_T *argvars; 9868 typval_T *rettv; 9869 { 9870 int i; 9871 char_u *name; 9872 int n = FALSE; 9873 static char *(has_list[]) = 9874 { 9875 #ifdef AMIGA 9876 "amiga", 9877 # ifdef FEAT_ARP 9878 "arp", 9879 # endif 9880 #endif 9881 #ifdef __BEOS__ 9882 "beos", 9883 #endif 9884 #ifdef MSDOS 9885 # ifdef DJGPP 9886 "dos32", 9887 # else 9888 "dos16", 9889 # endif 9890 #endif 9891 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 9892 "mac", 9893 #endif 9894 #if defined(MACOS_X_UNIX) 9895 "macunix", 9896 #endif 9897 #ifdef OS2 9898 "os2", 9899 #endif 9900 #ifdef __QNX__ 9901 "qnx", 9902 #endif 9903 #ifdef RISCOS 9904 "riscos", 9905 #endif 9906 #ifdef UNIX 9907 "unix", 9908 #endif 9909 #ifdef VMS 9910 "vms", 9911 #endif 9912 #ifdef WIN16 9913 "win16", 9914 #endif 9915 #ifdef WIN32 9916 "win32", 9917 #endif 9918 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 9919 "win32unix", 9920 #endif 9921 #ifdef WIN64 9922 "win64", 9923 #endif 9924 #ifdef EBCDIC 9925 "ebcdic", 9926 #endif 9927 #ifndef CASE_INSENSITIVE_FILENAME 9928 "fname_case", 9929 #endif 9930 #ifdef FEAT_ARABIC 9931 "arabic", 9932 #endif 9933 #ifdef FEAT_AUTOCMD 9934 "autocmd", 9935 #endif 9936 #ifdef FEAT_BEVAL 9937 "balloon_eval", 9938 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 9939 "balloon_multiline", 9940 # endif 9941 #endif 9942 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 9943 "builtin_terms", 9944 # ifdef ALL_BUILTIN_TCAPS 9945 "all_builtin_terms", 9946 # endif 9947 #endif 9948 #ifdef FEAT_BYTEOFF 9949 "byte_offset", 9950 #endif 9951 #ifdef FEAT_CINDENT 9952 "cindent", 9953 #endif 9954 #ifdef FEAT_CLIENTSERVER 9955 "clientserver", 9956 #endif 9957 #ifdef FEAT_CLIPBOARD 9958 "clipboard", 9959 #endif 9960 #ifdef FEAT_CMDL_COMPL 9961 "cmdline_compl", 9962 #endif 9963 #ifdef FEAT_CMDHIST 9964 "cmdline_hist", 9965 #endif 9966 #ifdef FEAT_COMMENTS 9967 "comments", 9968 #endif 9969 #ifdef FEAT_CRYPT 9970 "cryptv", 9971 #endif 9972 #ifdef FEAT_CSCOPE 9973 "cscope", 9974 #endif 9975 #ifdef DEBUG 9976 "debug", 9977 #endif 9978 #ifdef FEAT_CON_DIALOG 9979 "dialog_con", 9980 #endif 9981 #ifdef FEAT_GUI_DIALOG 9982 "dialog_gui", 9983 #endif 9984 #ifdef FEAT_DIFF 9985 "diff", 9986 #endif 9987 #ifdef FEAT_DIGRAPHS 9988 "digraphs", 9989 #endif 9990 #ifdef FEAT_DND 9991 "dnd", 9992 #endif 9993 #ifdef FEAT_EMACS_TAGS 9994 "emacs_tags", 9995 #endif 9996 "eval", /* always present, of course! */ 9997 #ifdef FEAT_EX_EXTRA 9998 "ex_extra", 9999 #endif 10000 #ifdef FEAT_SEARCH_EXTRA 10001 "extra_search", 10002 #endif 10003 #ifdef FEAT_FKMAP 10004 "farsi", 10005 #endif 10006 #ifdef FEAT_SEARCHPATH 10007 "file_in_path", 10008 #endif 10009 #if defined(UNIX) && !defined(USE_SYSTEM) 10010 "filterpipe", 10011 #endif 10012 #ifdef FEAT_FIND_ID 10013 "find_in_path", 10014 #endif 10015 #ifdef FEAT_FOLDING 10016 "folding", 10017 #endif 10018 #ifdef FEAT_FOOTER 10019 "footer", 10020 #endif 10021 #if !defined(USE_SYSTEM) && defined(UNIX) 10022 "fork", 10023 #endif 10024 #ifdef FEAT_GETTEXT 10025 "gettext", 10026 #endif 10027 #ifdef FEAT_GUI 10028 "gui", 10029 #endif 10030 #ifdef FEAT_GUI_ATHENA 10031 # ifdef FEAT_GUI_NEXTAW 10032 "gui_neXtaw", 10033 # else 10034 "gui_athena", 10035 # endif 10036 #endif 10037 #ifdef FEAT_GUI_KDE 10038 "gui_kde", 10039 #endif 10040 #ifdef FEAT_GUI_GTK 10041 "gui_gtk", 10042 # ifdef HAVE_GTK2 10043 "gui_gtk2", 10044 # endif 10045 #endif 10046 #ifdef FEAT_GUI_MAC 10047 "gui_mac", 10048 #endif 10049 #ifdef FEAT_GUI_MOTIF 10050 "gui_motif", 10051 #endif 10052 #ifdef FEAT_GUI_PHOTON 10053 "gui_photon", 10054 #endif 10055 #ifdef FEAT_GUI_W16 10056 "gui_win16", 10057 #endif 10058 #ifdef FEAT_GUI_W32 10059 "gui_win32", 10060 #endif 10061 #ifdef FEAT_HANGULIN 10062 "hangul_input", 10063 #endif 10064 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10065 "iconv", 10066 #endif 10067 #ifdef FEAT_INS_EXPAND 10068 "insert_expand", 10069 #endif 10070 #ifdef FEAT_JUMPLIST 10071 "jumplist", 10072 #endif 10073 #ifdef FEAT_KEYMAP 10074 "keymap", 10075 #endif 10076 #ifdef FEAT_LANGMAP 10077 "langmap", 10078 #endif 10079 #ifdef FEAT_LIBCALL 10080 "libcall", 10081 #endif 10082 #ifdef FEAT_LINEBREAK 10083 "linebreak", 10084 #endif 10085 #ifdef FEAT_LISP 10086 "lispindent", 10087 #endif 10088 #ifdef FEAT_LISTCMDS 10089 "listcmds", 10090 #endif 10091 #ifdef FEAT_LOCALMAP 10092 "localmap", 10093 #endif 10094 #ifdef FEAT_MENU 10095 "menu", 10096 #endif 10097 #ifdef FEAT_SESSION 10098 "mksession", 10099 #endif 10100 #ifdef FEAT_MODIFY_FNAME 10101 "modify_fname", 10102 #endif 10103 #ifdef FEAT_MOUSE 10104 "mouse", 10105 #endif 10106 #ifdef FEAT_MOUSESHAPE 10107 "mouseshape", 10108 #endif 10109 #if defined(UNIX) || defined(VMS) 10110 # ifdef FEAT_MOUSE_DEC 10111 "mouse_dec", 10112 # endif 10113 # ifdef FEAT_MOUSE_GPM 10114 "mouse_gpm", 10115 # endif 10116 # ifdef FEAT_MOUSE_JSB 10117 "mouse_jsbterm", 10118 # endif 10119 # ifdef FEAT_MOUSE_NET 10120 "mouse_netterm", 10121 # endif 10122 # ifdef FEAT_MOUSE_PTERM 10123 "mouse_pterm", 10124 # endif 10125 # ifdef FEAT_MOUSE_XTERM 10126 "mouse_xterm", 10127 # endif 10128 #endif 10129 #ifdef FEAT_MBYTE 10130 "multi_byte", 10131 #endif 10132 #ifdef FEAT_MBYTE_IME 10133 "multi_byte_ime", 10134 #endif 10135 #ifdef FEAT_MULTI_LANG 10136 "multi_lang", 10137 #endif 10138 #ifdef FEAT_MZSCHEME 10139 #ifndef DYNAMIC_MZSCHEME 10140 "mzscheme", 10141 #endif 10142 #endif 10143 #ifdef FEAT_OLE 10144 "ole", 10145 #endif 10146 #ifdef FEAT_OSFILETYPE 10147 "osfiletype", 10148 #endif 10149 #ifdef FEAT_PATH_EXTRA 10150 "path_extra", 10151 #endif 10152 #ifdef FEAT_PERL 10153 #ifndef DYNAMIC_PERL 10154 "perl", 10155 #endif 10156 #endif 10157 #ifdef FEAT_PYTHON 10158 #ifndef DYNAMIC_PYTHON 10159 "python", 10160 #endif 10161 #endif 10162 #ifdef FEAT_POSTSCRIPT 10163 "postscript", 10164 #endif 10165 #ifdef FEAT_PRINTER 10166 "printer", 10167 #endif 10168 #ifdef FEAT_PROFILE 10169 "profile", 10170 #endif 10171 #ifdef FEAT_QUICKFIX 10172 "quickfix", 10173 #endif 10174 #ifdef FEAT_RIGHTLEFT 10175 "rightleft", 10176 #endif 10177 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10178 "ruby", 10179 #endif 10180 #ifdef FEAT_SCROLLBIND 10181 "scrollbind", 10182 #endif 10183 #ifdef FEAT_CMDL_INFO 10184 "showcmd", 10185 "cmdline_info", 10186 #endif 10187 #ifdef FEAT_SIGNS 10188 "signs", 10189 #endif 10190 #ifdef FEAT_SMARTINDENT 10191 "smartindent", 10192 #endif 10193 #ifdef FEAT_SNIFF 10194 "sniff", 10195 #endif 10196 #ifdef FEAT_STL_OPT 10197 "statusline", 10198 #endif 10199 #ifdef FEAT_SUN_WORKSHOP 10200 "sun_workshop", 10201 #endif 10202 #ifdef FEAT_NETBEANS_INTG 10203 "netbeans_intg", 10204 #endif 10205 #ifdef FEAT_SYN_HL 10206 "spell", 10207 #endif 10208 #ifdef FEAT_SYN_HL 10209 "syntax", 10210 #endif 10211 #if defined(USE_SYSTEM) || !defined(UNIX) 10212 "system", 10213 #endif 10214 #ifdef FEAT_TAG_BINS 10215 "tag_binary", 10216 #endif 10217 #ifdef FEAT_TAG_OLDSTATIC 10218 "tag_old_static", 10219 #endif 10220 #ifdef FEAT_TAG_ANYWHITE 10221 "tag_any_white", 10222 #endif 10223 #ifdef FEAT_TCL 10224 # ifndef DYNAMIC_TCL 10225 "tcl", 10226 # endif 10227 #endif 10228 #ifdef TERMINFO 10229 "terminfo", 10230 #endif 10231 #ifdef FEAT_TERMRESPONSE 10232 "termresponse", 10233 #endif 10234 #ifdef FEAT_TEXTOBJ 10235 "textobjects", 10236 #endif 10237 #ifdef HAVE_TGETENT 10238 "tgetent", 10239 #endif 10240 #ifdef FEAT_TITLE 10241 "title", 10242 #endif 10243 #ifdef FEAT_TOOLBAR 10244 "toolbar", 10245 #endif 10246 #ifdef FEAT_USR_CMDS 10247 "user-commands", /* was accidentally included in 5.4 */ 10248 "user_commands", 10249 #endif 10250 #ifdef FEAT_VIMINFO 10251 "viminfo", 10252 #endif 10253 #ifdef FEAT_VERTSPLIT 10254 "vertsplit", 10255 #endif 10256 #ifdef FEAT_VIRTUALEDIT 10257 "virtualedit", 10258 #endif 10259 #ifdef FEAT_VISUAL 10260 "visual", 10261 #endif 10262 #ifdef FEAT_VISUALEXTRA 10263 "visualextra", 10264 #endif 10265 #ifdef FEAT_VREPLACE 10266 "vreplace", 10267 #endif 10268 #ifdef FEAT_WILDIGN 10269 "wildignore", 10270 #endif 10271 #ifdef FEAT_WILDMENU 10272 "wildmenu", 10273 #endif 10274 #ifdef FEAT_WINDOWS 10275 "windows", 10276 #endif 10277 #ifdef FEAT_WAK 10278 "winaltkeys", 10279 #endif 10280 #ifdef FEAT_WRITEBACKUP 10281 "writebackup", 10282 #endif 10283 #ifdef FEAT_XIM 10284 "xim", 10285 #endif 10286 #ifdef FEAT_XFONTSET 10287 "xfontset", 10288 #endif 10289 #ifdef USE_XSMP 10290 "xsmp", 10291 #endif 10292 #ifdef USE_XSMP_INTERACT 10293 "xsmp_interact", 10294 #endif 10295 #ifdef FEAT_XCLIPBOARD 10296 "xterm_clipboard", 10297 #endif 10298 #ifdef FEAT_XTERM_SAVE 10299 "xterm_save", 10300 #endif 10301 #if defined(UNIX) && defined(FEAT_X11) 10302 "X11", 10303 #endif 10304 NULL 10305 }; 10306 10307 name = get_tv_string(&argvars[0]); 10308 for (i = 0; has_list[i] != NULL; ++i) 10309 if (STRICMP(name, has_list[i]) == 0) 10310 { 10311 n = TRUE; 10312 break; 10313 } 10314 10315 if (n == FALSE) 10316 { 10317 if (STRNICMP(name, "patch", 5) == 0) 10318 n = has_patch(atoi((char *)name + 5)); 10319 else if (STRICMP(name, "vim_starting") == 0) 10320 n = (starting != 0); 10321 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10322 else if (STRICMP(name, "balloon_multiline") == 0) 10323 n = multiline_balloon_available(); 10324 #endif 10325 #ifdef DYNAMIC_TCL 10326 else if (STRICMP(name, "tcl") == 0) 10327 n = tcl_enabled(FALSE); 10328 #endif 10329 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10330 else if (STRICMP(name, "iconv") == 0) 10331 n = iconv_enabled(FALSE); 10332 #endif 10333 #ifdef DYNAMIC_MZSCHEME 10334 else if (STRICMP(name, "mzscheme") == 0) 10335 n = mzscheme_enabled(FALSE); 10336 #endif 10337 #ifdef DYNAMIC_RUBY 10338 else if (STRICMP(name, "ruby") == 0) 10339 n = ruby_enabled(FALSE); 10340 #endif 10341 #ifdef DYNAMIC_PYTHON 10342 else if (STRICMP(name, "python") == 0) 10343 n = python_enabled(FALSE); 10344 #endif 10345 #ifdef DYNAMIC_PERL 10346 else if (STRICMP(name, "perl") == 0) 10347 n = perl_enabled(FALSE); 10348 #endif 10349 #ifdef FEAT_GUI 10350 else if (STRICMP(name, "gui_running") == 0) 10351 n = (gui.in_use || gui.starting); 10352 # ifdef FEAT_GUI_W32 10353 else if (STRICMP(name, "gui_win32s") == 0) 10354 n = gui_is_win32s(); 10355 # endif 10356 # ifdef FEAT_BROWSE 10357 else if (STRICMP(name, "browse") == 0) 10358 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10359 # endif 10360 #endif 10361 #ifdef FEAT_SYN_HL 10362 else if (STRICMP(name, "syntax_items") == 0) 10363 n = syntax_present(curbuf); 10364 #endif 10365 #if defined(WIN3264) 10366 else if (STRICMP(name, "win95") == 0) 10367 n = mch_windows95(); 10368 #endif 10369 #ifdef FEAT_NETBEANS_INTG 10370 else if (STRICMP(name, "netbeans_enabled") == 0) 10371 n = usingNetbeans; 10372 #endif 10373 } 10374 10375 rettv->vval.v_number = n; 10376 } 10377 10378 /* 10379 * "has_key()" function 10380 */ 10381 static void 10382 f_has_key(argvars, rettv) 10383 typval_T *argvars; 10384 typval_T *rettv; 10385 { 10386 rettv->vval.v_number = 0; 10387 if (argvars[0].v_type != VAR_DICT) 10388 { 10389 EMSG(_(e_dictreq)); 10390 return; 10391 } 10392 if (argvars[0].vval.v_dict == NULL) 10393 return; 10394 10395 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10396 get_tv_string(&argvars[1]), -1) != NULL; 10397 } 10398 10399 /* 10400 * "hasmapto()" function 10401 */ 10402 static void 10403 f_hasmapto(argvars, rettv) 10404 typval_T *argvars; 10405 typval_T *rettv; 10406 { 10407 char_u *name; 10408 char_u *mode; 10409 char_u buf[NUMBUFLEN]; 10410 10411 name = get_tv_string(&argvars[0]); 10412 if (argvars[1].v_type == VAR_UNKNOWN) 10413 mode = (char_u *)"nvo"; 10414 else 10415 mode = get_tv_string_buf(&argvars[1], buf); 10416 10417 if (map_to_exists(name, mode)) 10418 rettv->vval.v_number = TRUE; 10419 else 10420 rettv->vval.v_number = FALSE; 10421 } 10422 10423 /* 10424 * "histadd()" function 10425 */ 10426 /*ARGSUSED*/ 10427 static void 10428 f_histadd(argvars, rettv) 10429 typval_T *argvars; 10430 typval_T *rettv; 10431 { 10432 #ifdef FEAT_CMDHIST 10433 int histype; 10434 char_u *str; 10435 char_u buf[NUMBUFLEN]; 10436 #endif 10437 10438 rettv->vval.v_number = FALSE; 10439 if (check_restricted() || check_secure()) 10440 return; 10441 #ifdef FEAT_CMDHIST 10442 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10443 histype = str != NULL ? get_histtype(str) : -1; 10444 if (histype >= 0) 10445 { 10446 str = get_tv_string_buf(&argvars[1], buf); 10447 if (*str != NUL) 10448 { 10449 add_to_history(histype, str, FALSE, NUL); 10450 rettv->vval.v_number = TRUE; 10451 return; 10452 } 10453 } 10454 #endif 10455 } 10456 10457 /* 10458 * "histdel()" function 10459 */ 10460 /*ARGSUSED*/ 10461 static void 10462 f_histdel(argvars, rettv) 10463 typval_T *argvars; 10464 typval_T *rettv; 10465 { 10466 #ifdef FEAT_CMDHIST 10467 int n; 10468 char_u buf[NUMBUFLEN]; 10469 char_u *str; 10470 10471 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10472 if (str == NULL) 10473 n = 0; 10474 else if (argvars[1].v_type == VAR_UNKNOWN) 10475 /* only one argument: clear entire history */ 10476 n = clr_history(get_histtype(str)); 10477 else if (argvars[1].v_type == VAR_NUMBER) 10478 /* index given: remove that entry */ 10479 n = del_history_idx(get_histtype(str), 10480 (int)get_tv_number(&argvars[1])); 10481 else 10482 /* string given: remove all matching entries */ 10483 n = del_history_entry(get_histtype(str), 10484 get_tv_string_buf(&argvars[1], buf)); 10485 rettv->vval.v_number = n; 10486 #else 10487 rettv->vval.v_number = 0; 10488 #endif 10489 } 10490 10491 /* 10492 * "histget()" function 10493 */ 10494 /*ARGSUSED*/ 10495 static void 10496 f_histget(argvars, rettv) 10497 typval_T *argvars; 10498 typval_T *rettv; 10499 { 10500 #ifdef FEAT_CMDHIST 10501 int type; 10502 int idx; 10503 char_u *str; 10504 10505 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10506 if (str == NULL) 10507 rettv->vval.v_string = NULL; 10508 else 10509 { 10510 type = get_histtype(str); 10511 if (argvars[1].v_type == VAR_UNKNOWN) 10512 idx = get_history_idx(type); 10513 else 10514 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10515 /* -1 on type error */ 10516 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10517 } 10518 #else 10519 rettv->vval.v_string = NULL; 10520 #endif 10521 rettv->v_type = VAR_STRING; 10522 } 10523 10524 /* 10525 * "histnr()" function 10526 */ 10527 /*ARGSUSED*/ 10528 static void 10529 f_histnr(argvars, rettv) 10530 typval_T *argvars; 10531 typval_T *rettv; 10532 { 10533 int i; 10534 10535 #ifdef FEAT_CMDHIST 10536 char_u *history = get_tv_string_chk(&argvars[0]); 10537 10538 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10539 if (i >= HIST_CMD && i < HIST_COUNT) 10540 i = get_history_idx(i); 10541 else 10542 #endif 10543 i = -1; 10544 rettv->vval.v_number = i; 10545 } 10546 10547 /* 10548 * "highlightID(name)" function 10549 */ 10550 static void 10551 f_hlID(argvars, rettv) 10552 typval_T *argvars; 10553 typval_T *rettv; 10554 { 10555 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10556 } 10557 10558 /* 10559 * "highlight_exists()" function 10560 */ 10561 static void 10562 f_hlexists(argvars, rettv) 10563 typval_T *argvars; 10564 typval_T *rettv; 10565 { 10566 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10567 } 10568 10569 /* 10570 * "hostname()" function 10571 */ 10572 /*ARGSUSED*/ 10573 static void 10574 f_hostname(argvars, rettv) 10575 typval_T *argvars; 10576 typval_T *rettv; 10577 { 10578 char_u hostname[256]; 10579 10580 mch_get_host_name(hostname, 256); 10581 rettv->v_type = VAR_STRING; 10582 rettv->vval.v_string = vim_strsave(hostname); 10583 } 10584 10585 /* 10586 * iconv() function 10587 */ 10588 /*ARGSUSED*/ 10589 static void 10590 f_iconv(argvars, rettv) 10591 typval_T *argvars; 10592 typval_T *rettv; 10593 { 10594 #ifdef FEAT_MBYTE 10595 char_u buf1[NUMBUFLEN]; 10596 char_u buf2[NUMBUFLEN]; 10597 char_u *from, *to, *str; 10598 vimconv_T vimconv; 10599 #endif 10600 10601 rettv->v_type = VAR_STRING; 10602 rettv->vval.v_string = NULL; 10603 10604 #ifdef FEAT_MBYTE 10605 str = get_tv_string(&argvars[0]); 10606 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10607 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10608 vimconv.vc_type = CONV_NONE; 10609 convert_setup(&vimconv, from, to); 10610 10611 /* If the encodings are equal, no conversion needed. */ 10612 if (vimconv.vc_type == CONV_NONE) 10613 rettv->vval.v_string = vim_strsave(str); 10614 else 10615 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10616 10617 convert_setup(&vimconv, NULL, NULL); 10618 vim_free(from); 10619 vim_free(to); 10620 #endif 10621 } 10622 10623 /* 10624 * "indent()" function 10625 */ 10626 static void 10627 f_indent(argvars, rettv) 10628 typval_T *argvars; 10629 typval_T *rettv; 10630 { 10631 linenr_T lnum; 10632 10633 lnum = get_tv_lnum(argvars); 10634 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10635 rettv->vval.v_number = get_indent_lnum(lnum); 10636 else 10637 rettv->vval.v_number = -1; 10638 } 10639 10640 /* 10641 * "index()" function 10642 */ 10643 static void 10644 f_index(argvars, rettv) 10645 typval_T *argvars; 10646 typval_T *rettv; 10647 { 10648 list_T *l; 10649 listitem_T *item; 10650 long idx = 0; 10651 int ic = FALSE; 10652 10653 rettv->vval.v_number = -1; 10654 if (argvars[0].v_type != VAR_LIST) 10655 { 10656 EMSG(_(e_listreq)); 10657 return; 10658 } 10659 l = argvars[0].vval.v_list; 10660 if (l != NULL) 10661 { 10662 item = l->lv_first; 10663 if (argvars[2].v_type != VAR_UNKNOWN) 10664 { 10665 int error = FALSE; 10666 10667 /* Start at specified item. Use the cached index that list_find() 10668 * sets, so that a negative number also works. */ 10669 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10670 idx = l->lv_idx; 10671 if (argvars[3].v_type != VAR_UNKNOWN) 10672 ic = get_tv_number_chk(&argvars[3], &error); 10673 if (error) 10674 item = NULL; 10675 } 10676 10677 for ( ; item != NULL; item = item->li_next, ++idx) 10678 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10679 { 10680 rettv->vval.v_number = idx; 10681 break; 10682 } 10683 } 10684 } 10685 10686 static int inputsecret_flag = 0; 10687 10688 /* 10689 * "input()" function 10690 * Also handles inputsecret() when inputsecret is set. 10691 */ 10692 static void 10693 f_input(argvars, rettv) 10694 typval_T *argvars; 10695 typval_T *rettv; 10696 { 10697 char_u *prompt = get_tv_string_chk(&argvars[0]); 10698 char_u *p = NULL; 10699 int c; 10700 char_u buf[NUMBUFLEN]; 10701 int cmd_silent_save = cmd_silent; 10702 char_u *defstr = (char_u *)""; 10703 10704 rettv->v_type = VAR_STRING; 10705 10706 #ifdef NO_CONSOLE_INPUT 10707 /* While starting up, there is no place to enter text. */ 10708 if (no_console_input()) 10709 { 10710 rettv->vval.v_string = NULL; 10711 return; 10712 } 10713 #endif 10714 10715 cmd_silent = FALSE; /* Want to see the prompt. */ 10716 if (prompt != NULL) 10717 { 10718 /* Only the part of the message after the last NL is considered as 10719 * prompt for the command line */ 10720 p = vim_strrchr(prompt, '\n'); 10721 if (p == NULL) 10722 p = prompt; 10723 else 10724 { 10725 ++p; 10726 c = *p; 10727 *p = NUL; 10728 msg_start(); 10729 msg_clr_eos(); 10730 msg_puts_attr(prompt, echo_attr); 10731 msg_didout = FALSE; 10732 msg_starthere(); 10733 *p = c; 10734 } 10735 cmdline_row = msg_row; 10736 10737 if (argvars[1].v_type != VAR_UNKNOWN) 10738 { 10739 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10740 if (defstr != NULL) 10741 stuffReadbuffSpec(defstr); 10742 } 10743 10744 if (defstr != NULL) 10745 rettv->vval.v_string = 10746 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr); 10747 10748 /* since the user typed this, no need to wait for return */ 10749 need_wait_return = FALSE; 10750 msg_didout = FALSE; 10751 } 10752 cmd_silent = cmd_silent_save; 10753 } 10754 10755 /* 10756 * "inputdialog()" function 10757 */ 10758 static void 10759 f_inputdialog(argvars, rettv) 10760 typval_T *argvars; 10761 typval_T *rettv; 10762 { 10763 #if defined(FEAT_GUI_TEXTDIALOG) 10764 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10765 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10766 { 10767 char_u *message; 10768 char_u buf[NUMBUFLEN]; 10769 char_u *defstr = (char_u *)""; 10770 10771 message = get_tv_string_chk(&argvars[0]); 10772 if (argvars[1].v_type != VAR_UNKNOWN 10773 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10774 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10775 else 10776 IObuff[0] = NUL; 10777 if (message != NULL && defstr != NULL 10778 && do_dialog(VIM_QUESTION, NULL, message, 10779 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10780 rettv->vval.v_string = vim_strsave(IObuff); 10781 else 10782 { 10783 if (message != NULL && defstr != NULL 10784 && argvars[1].v_type != VAR_UNKNOWN 10785 && argvars[2].v_type != VAR_UNKNOWN) 10786 rettv->vval.v_string = vim_strsave( 10787 get_tv_string_buf(&argvars[2], buf)); 10788 else 10789 rettv->vval.v_string = NULL; 10790 } 10791 rettv->v_type = VAR_STRING; 10792 } 10793 else 10794 #endif 10795 f_input(argvars, rettv); 10796 } 10797 10798 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 10799 10800 /* 10801 * "inputrestore()" function 10802 */ 10803 /*ARGSUSED*/ 10804 static void 10805 f_inputrestore(argvars, rettv) 10806 typval_T *argvars; 10807 typval_T *rettv; 10808 { 10809 if (ga_userinput.ga_len > 0) 10810 { 10811 --ga_userinput.ga_len; 10812 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 10813 + ga_userinput.ga_len); 10814 rettv->vval.v_number = 0; /* OK */ 10815 } 10816 else if (p_verbose > 1) 10817 { 10818 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 10819 rettv->vval.v_number = 1; /* Failed */ 10820 } 10821 } 10822 10823 /* 10824 * "inputsave()" function 10825 */ 10826 /*ARGSUSED*/ 10827 static void 10828 f_inputsave(argvars, rettv) 10829 typval_T *argvars; 10830 typval_T *rettv; 10831 { 10832 /* Add an entry to the stack of typehead storage. */ 10833 if (ga_grow(&ga_userinput, 1) == OK) 10834 { 10835 save_typeahead((tasave_T *)(ga_userinput.ga_data) 10836 + ga_userinput.ga_len); 10837 ++ga_userinput.ga_len; 10838 rettv->vval.v_number = 0; /* OK */ 10839 } 10840 else 10841 rettv->vval.v_number = 1; /* Failed */ 10842 } 10843 10844 /* 10845 * "inputsecret()" function 10846 */ 10847 static void 10848 f_inputsecret(argvars, rettv) 10849 typval_T *argvars; 10850 typval_T *rettv; 10851 { 10852 ++cmdline_star; 10853 ++inputsecret_flag; 10854 f_input(argvars, rettv); 10855 --cmdline_star; 10856 --inputsecret_flag; 10857 } 10858 10859 /* 10860 * "insert()" function 10861 */ 10862 static void 10863 f_insert(argvars, rettv) 10864 typval_T *argvars; 10865 typval_T *rettv; 10866 { 10867 long before = 0; 10868 listitem_T *item; 10869 list_T *l; 10870 int error = FALSE; 10871 10872 rettv->vval.v_number = 0; 10873 if (argvars[0].v_type != VAR_LIST) 10874 EMSG2(_(e_listarg), "insert()"); 10875 else if ((l = argvars[0].vval.v_list) != NULL 10876 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 10877 { 10878 if (argvars[2].v_type != VAR_UNKNOWN) 10879 before = get_tv_number_chk(&argvars[2], &error); 10880 if (error) 10881 return; /* type error; errmsg already given */ 10882 10883 if (before == l->lv_len) 10884 item = NULL; 10885 else 10886 { 10887 item = list_find(l, before); 10888 if (item == NULL) 10889 { 10890 EMSGN(_(e_listidx), before); 10891 l = NULL; 10892 } 10893 } 10894 if (l != NULL) 10895 { 10896 list_insert_tv(l, &argvars[1], item); 10897 copy_tv(&argvars[0], rettv); 10898 } 10899 } 10900 } 10901 10902 /* 10903 * "isdirectory()" function 10904 */ 10905 static void 10906 f_isdirectory(argvars, rettv) 10907 typval_T *argvars; 10908 typval_T *rettv; 10909 { 10910 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 10911 } 10912 10913 /* 10914 * "islocked()" function 10915 */ 10916 static void 10917 f_islocked(argvars, rettv) 10918 typval_T *argvars; 10919 typval_T *rettv; 10920 { 10921 lval_T lv; 10922 char_u *end; 10923 dictitem_T *di; 10924 10925 rettv->vval.v_number = -1; 10926 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 10927 FNE_CHECK_START); 10928 if (end != NULL && lv.ll_name != NULL) 10929 { 10930 if (*end != NUL) 10931 EMSG(_(e_trailing)); 10932 else 10933 { 10934 if (lv.ll_tv == NULL) 10935 { 10936 if (check_changedtick(lv.ll_name)) 10937 rettv->vval.v_number = 1; /* always locked */ 10938 else 10939 { 10940 di = find_var(lv.ll_name, NULL); 10941 if (di != NULL) 10942 { 10943 /* Consider a variable locked when: 10944 * 1. the variable itself is locked 10945 * 2. the value of the variable is locked. 10946 * 3. the List or Dict value is locked. 10947 */ 10948 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 10949 || tv_islocked(&di->di_tv)); 10950 } 10951 } 10952 } 10953 else if (lv.ll_range) 10954 EMSG(_("E745: Range not allowed")); 10955 else if (lv.ll_newkey != NULL) 10956 EMSG2(_(e_dictkey), lv.ll_newkey); 10957 else if (lv.ll_list != NULL) 10958 /* List item. */ 10959 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 10960 else 10961 /* Dictionary item. */ 10962 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 10963 } 10964 } 10965 10966 clear_lval(&lv); 10967 } 10968 10969 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 10970 10971 /* 10972 * Turn a dict into a list: 10973 * "what" == 0: list of keys 10974 * "what" == 1: list of values 10975 * "what" == 2: list of items 10976 */ 10977 static void 10978 dict_list(argvars, rettv, what) 10979 typval_T *argvars; 10980 typval_T *rettv; 10981 int what; 10982 { 10983 list_T *l; 10984 list_T *l2; 10985 dictitem_T *di; 10986 hashitem_T *hi; 10987 listitem_T *li; 10988 listitem_T *li2; 10989 dict_T *d; 10990 int todo; 10991 10992 rettv->vval.v_number = 0; 10993 if (argvars[0].v_type != VAR_DICT) 10994 { 10995 EMSG(_(e_dictreq)); 10996 return; 10997 } 10998 if ((d = argvars[0].vval.v_dict) == NULL) 10999 return; 11000 11001 l = list_alloc(); 11002 if (l == NULL) 11003 return; 11004 rettv->v_type = VAR_LIST; 11005 rettv->vval.v_list = l; 11006 ++l->lv_refcount; 11007 11008 todo = d->dv_hashtab.ht_used; 11009 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11010 { 11011 if (!HASHITEM_EMPTY(hi)) 11012 { 11013 --todo; 11014 di = HI2DI(hi); 11015 11016 li = listitem_alloc(); 11017 if (li == NULL) 11018 break; 11019 list_append(l, li); 11020 11021 if (what == 0) 11022 { 11023 /* keys() */ 11024 li->li_tv.v_type = VAR_STRING; 11025 li->li_tv.v_lock = 0; 11026 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11027 } 11028 else if (what == 1) 11029 { 11030 /* values() */ 11031 copy_tv(&di->di_tv, &li->li_tv); 11032 } 11033 else 11034 { 11035 /* items() */ 11036 l2 = list_alloc(); 11037 li->li_tv.v_type = VAR_LIST; 11038 li->li_tv.v_lock = 0; 11039 li->li_tv.vval.v_list = l2; 11040 if (l2 == NULL) 11041 break; 11042 ++l2->lv_refcount; 11043 11044 li2 = listitem_alloc(); 11045 if (li2 == NULL) 11046 break; 11047 list_append(l2, li2); 11048 li2->li_tv.v_type = VAR_STRING; 11049 li2->li_tv.v_lock = 0; 11050 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11051 11052 li2 = listitem_alloc(); 11053 if (li2 == NULL) 11054 break; 11055 list_append(l2, li2); 11056 copy_tv(&di->di_tv, &li2->li_tv); 11057 } 11058 } 11059 } 11060 } 11061 11062 /* 11063 * "items(dict)" function 11064 */ 11065 static void 11066 f_items(argvars, rettv) 11067 typval_T *argvars; 11068 typval_T *rettv; 11069 { 11070 dict_list(argvars, rettv, 2); 11071 } 11072 11073 /* 11074 * "join()" function 11075 */ 11076 static void 11077 f_join(argvars, rettv) 11078 typval_T *argvars; 11079 typval_T *rettv; 11080 { 11081 garray_T ga; 11082 char_u *sep; 11083 11084 rettv->vval.v_number = 0; 11085 if (argvars[0].v_type != VAR_LIST) 11086 { 11087 EMSG(_(e_listreq)); 11088 return; 11089 } 11090 if (argvars[0].vval.v_list == NULL) 11091 return; 11092 if (argvars[1].v_type == VAR_UNKNOWN) 11093 sep = (char_u *)" "; 11094 else 11095 sep = get_tv_string_chk(&argvars[1]); 11096 11097 rettv->v_type = VAR_STRING; 11098 11099 if (sep != NULL) 11100 { 11101 ga_init2(&ga, (int)sizeof(char), 80); 11102 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11103 ga_append(&ga, NUL); 11104 rettv->vval.v_string = (char_u *)ga.ga_data; 11105 } 11106 else 11107 rettv->vval.v_string = NULL; 11108 } 11109 11110 /* 11111 * "keys()" function 11112 */ 11113 static void 11114 f_keys(argvars, rettv) 11115 typval_T *argvars; 11116 typval_T *rettv; 11117 { 11118 dict_list(argvars, rettv, 0); 11119 } 11120 11121 /* 11122 * "last_buffer_nr()" function. 11123 */ 11124 /*ARGSUSED*/ 11125 static void 11126 f_last_buffer_nr(argvars, rettv) 11127 typval_T *argvars; 11128 typval_T *rettv; 11129 { 11130 int n = 0; 11131 buf_T *buf; 11132 11133 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11134 if (n < buf->b_fnum) 11135 n = buf->b_fnum; 11136 11137 rettv->vval.v_number = n; 11138 } 11139 11140 /* 11141 * "len()" function 11142 */ 11143 static void 11144 f_len(argvars, rettv) 11145 typval_T *argvars; 11146 typval_T *rettv; 11147 { 11148 switch (argvars[0].v_type) 11149 { 11150 case VAR_STRING: 11151 case VAR_NUMBER: 11152 rettv->vval.v_number = (varnumber_T)STRLEN( 11153 get_tv_string(&argvars[0])); 11154 break; 11155 case VAR_LIST: 11156 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11157 break; 11158 case VAR_DICT: 11159 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11160 break; 11161 default: 11162 EMSG(_("E701: Invalid type for len()")); 11163 break; 11164 } 11165 } 11166 11167 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11168 11169 static void 11170 libcall_common(argvars, rettv, type) 11171 typval_T *argvars; 11172 typval_T *rettv; 11173 int type; 11174 { 11175 #ifdef FEAT_LIBCALL 11176 char_u *string_in; 11177 char_u **string_result; 11178 int nr_result; 11179 #endif 11180 11181 rettv->v_type = type; 11182 if (type == VAR_NUMBER) 11183 rettv->vval.v_number = 0; 11184 else 11185 rettv->vval.v_string = NULL; 11186 11187 if (check_restricted() || check_secure()) 11188 return; 11189 11190 #ifdef FEAT_LIBCALL 11191 /* The first two args must be strings, otherwise its meaningless */ 11192 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11193 { 11194 string_in = NULL; 11195 if (argvars[2].v_type == VAR_STRING) 11196 string_in = argvars[2].vval.v_string; 11197 if (type == VAR_NUMBER) 11198 string_result = NULL; 11199 else 11200 string_result = &rettv->vval.v_string; 11201 if (mch_libcall(argvars[0].vval.v_string, 11202 argvars[1].vval.v_string, 11203 string_in, 11204 argvars[2].vval.v_number, 11205 string_result, 11206 &nr_result) == OK 11207 && type == VAR_NUMBER) 11208 rettv->vval.v_number = nr_result; 11209 } 11210 #endif 11211 } 11212 11213 /* 11214 * "libcall()" function 11215 */ 11216 static void 11217 f_libcall(argvars, rettv) 11218 typval_T *argvars; 11219 typval_T *rettv; 11220 { 11221 libcall_common(argvars, rettv, VAR_STRING); 11222 } 11223 11224 /* 11225 * "libcallnr()" function 11226 */ 11227 static void 11228 f_libcallnr(argvars, rettv) 11229 typval_T *argvars; 11230 typval_T *rettv; 11231 { 11232 libcall_common(argvars, rettv, VAR_NUMBER); 11233 } 11234 11235 /* 11236 * "line(string)" function 11237 */ 11238 static void 11239 f_line(argvars, rettv) 11240 typval_T *argvars; 11241 typval_T *rettv; 11242 { 11243 linenr_T lnum = 0; 11244 pos_T *fp; 11245 11246 fp = var2fpos(&argvars[0], TRUE); 11247 if (fp != NULL) 11248 lnum = fp->lnum; 11249 rettv->vval.v_number = lnum; 11250 } 11251 11252 /* 11253 * "line2byte(lnum)" function 11254 */ 11255 /*ARGSUSED*/ 11256 static void 11257 f_line2byte(argvars, rettv) 11258 typval_T *argvars; 11259 typval_T *rettv; 11260 { 11261 #ifndef FEAT_BYTEOFF 11262 rettv->vval.v_number = -1; 11263 #else 11264 linenr_T lnum; 11265 11266 lnum = get_tv_lnum(argvars); 11267 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11268 rettv->vval.v_number = -1; 11269 else 11270 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11271 if (rettv->vval.v_number >= 0) 11272 ++rettv->vval.v_number; 11273 #endif 11274 } 11275 11276 /* 11277 * "lispindent(lnum)" function 11278 */ 11279 static void 11280 f_lispindent(argvars, rettv) 11281 typval_T *argvars; 11282 typval_T *rettv; 11283 { 11284 #ifdef FEAT_LISP 11285 pos_T pos; 11286 linenr_T lnum; 11287 11288 pos = curwin->w_cursor; 11289 lnum = get_tv_lnum(argvars); 11290 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11291 { 11292 curwin->w_cursor.lnum = lnum; 11293 rettv->vval.v_number = get_lisp_indent(); 11294 curwin->w_cursor = pos; 11295 } 11296 else 11297 #endif 11298 rettv->vval.v_number = -1; 11299 } 11300 11301 /* 11302 * "localtime()" function 11303 */ 11304 /*ARGSUSED*/ 11305 static void 11306 f_localtime(argvars, rettv) 11307 typval_T *argvars; 11308 typval_T *rettv; 11309 { 11310 rettv->vval.v_number = (varnumber_T)time(NULL); 11311 } 11312 11313 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11314 11315 static void 11316 get_maparg(argvars, rettv, exact) 11317 typval_T *argvars; 11318 typval_T *rettv; 11319 int exact; 11320 { 11321 char_u *keys; 11322 char_u *which; 11323 char_u buf[NUMBUFLEN]; 11324 char_u *keys_buf = NULL; 11325 char_u *rhs; 11326 int mode; 11327 garray_T ga; 11328 11329 /* return empty string for failure */ 11330 rettv->v_type = VAR_STRING; 11331 rettv->vval.v_string = NULL; 11332 11333 keys = get_tv_string(&argvars[0]); 11334 if (*keys == NUL) 11335 return; 11336 11337 if (argvars[1].v_type != VAR_UNKNOWN) 11338 which = get_tv_string_buf_chk(&argvars[1], buf); 11339 else 11340 which = (char_u *)""; 11341 if (which == NULL) 11342 return; 11343 11344 mode = get_map_mode(&which, 0); 11345 11346 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11347 rhs = check_map(keys, mode, exact, FALSE); 11348 vim_free(keys_buf); 11349 if (rhs != NULL) 11350 { 11351 ga_init(&ga); 11352 ga.ga_itemsize = 1; 11353 ga.ga_growsize = 40; 11354 11355 while (*rhs != NUL) 11356 ga_concat(&ga, str2special(&rhs, FALSE)); 11357 11358 ga_append(&ga, NUL); 11359 rettv->vval.v_string = (char_u *)ga.ga_data; 11360 } 11361 } 11362 11363 /* 11364 * "map()" function 11365 */ 11366 static void 11367 f_map(argvars, rettv) 11368 typval_T *argvars; 11369 typval_T *rettv; 11370 { 11371 filter_map(argvars, rettv, TRUE); 11372 } 11373 11374 /* 11375 * "maparg()" function 11376 */ 11377 static void 11378 f_maparg(argvars, rettv) 11379 typval_T *argvars; 11380 typval_T *rettv; 11381 { 11382 get_maparg(argvars, rettv, TRUE); 11383 } 11384 11385 /* 11386 * "mapcheck()" function 11387 */ 11388 static void 11389 f_mapcheck(argvars, rettv) 11390 typval_T *argvars; 11391 typval_T *rettv; 11392 { 11393 get_maparg(argvars, rettv, FALSE); 11394 } 11395 11396 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11397 11398 static void 11399 find_some_match(argvars, rettv, type) 11400 typval_T *argvars; 11401 typval_T *rettv; 11402 int type; 11403 { 11404 char_u *str = NULL; 11405 char_u *expr = NULL; 11406 char_u *pat; 11407 regmatch_T regmatch; 11408 char_u patbuf[NUMBUFLEN]; 11409 char_u strbuf[NUMBUFLEN]; 11410 char_u *save_cpo; 11411 long start = 0; 11412 long nth = 1; 11413 int match = 0; 11414 list_T *l = NULL; 11415 listitem_T *li = NULL; 11416 long idx = 0; 11417 char_u *tofree = NULL; 11418 11419 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11420 save_cpo = p_cpo; 11421 p_cpo = (char_u *)""; 11422 11423 rettv->vval.v_number = -1; 11424 if (type == 3) 11425 { 11426 /* return empty list when there are no matches */ 11427 if ((rettv->vval.v_list = list_alloc()) == NULL) 11428 goto theend; 11429 rettv->v_type = VAR_LIST; 11430 ++rettv->vval.v_list->lv_refcount; 11431 } 11432 else if (type == 2) 11433 { 11434 rettv->v_type = VAR_STRING; 11435 rettv->vval.v_string = NULL; 11436 } 11437 11438 if (argvars[0].v_type == VAR_LIST) 11439 { 11440 if ((l = argvars[0].vval.v_list) == NULL) 11441 goto theend; 11442 li = l->lv_first; 11443 } 11444 else 11445 expr = str = get_tv_string(&argvars[0]); 11446 11447 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11448 if (pat == NULL) 11449 goto theend; 11450 11451 if (argvars[2].v_type != VAR_UNKNOWN) 11452 { 11453 int error = FALSE; 11454 11455 start = get_tv_number_chk(&argvars[2], &error); 11456 if (error) 11457 goto theend; 11458 if (l != NULL) 11459 { 11460 li = list_find(l, start); 11461 if (li == NULL) 11462 goto theend; 11463 idx = l->lv_idx; /* use the cached index */ 11464 } 11465 else 11466 { 11467 if (start < 0) 11468 start = 0; 11469 if (start > (long)STRLEN(str)) 11470 goto theend; 11471 str += start; 11472 } 11473 11474 if (argvars[3].v_type != VAR_UNKNOWN) 11475 nth = get_tv_number_chk(&argvars[3], &error); 11476 if (error) 11477 goto theend; 11478 } 11479 11480 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11481 if (regmatch.regprog != NULL) 11482 { 11483 regmatch.rm_ic = p_ic; 11484 11485 for (;;) 11486 { 11487 if (l != NULL) 11488 { 11489 if (li == NULL) 11490 { 11491 match = FALSE; 11492 break; 11493 } 11494 vim_free(tofree); 11495 str = echo_string(&li->li_tv, &tofree, strbuf); 11496 if (str == NULL) 11497 break; 11498 } 11499 11500 match = vim_regexec_nl(®match, str, (colnr_T)0); 11501 11502 if (match && --nth <= 0) 11503 break; 11504 if (l == NULL && !match) 11505 break; 11506 11507 /* Advance to just after the match. */ 11508 if (l != NULL) 11509 { 11510 li = li->li_next; 11511 ++idx; 11512 } 11513 else 11514 { 11515 #ifdef FEAT_MBYTE 11516 str = regmatch.startp[0] + mb_ptr2len_check(regmatch.startp[0]); 11517 #else 11518 str = regmatch.startp[0] + 1; 11519 #endif 11520 } 11521 } 11522 11523 if (match) 11524 { 11525 if (type == 3) 11526 { 11527 int i; 11528 11529 /* return list with matched string and submatches */ 11530 for (i = 0; i < NSUBEXP; ++i) 11531 { 11532 if (regmatch.endp[i] == NULL) 11533 break; 11534 li = listitem_alloc(); 11535 if (li == NULL) 11536 break; 11537 li->li_tv.v_type = VAR_STRING; 11538 li->li_tv.v_lock = 0; 11539 li->li_tv.vval.v_string = vim_strnsave(regmatch.startp[i], 11540 (int)(regmatch.endp[i] - regmatch.startp[i])); 11541 list_append(rettv->vval.v_list, li); 11542 } 11543 } 11544 else if (type == 2) 11545 { 11546 /* return matched string */ 11547 if (l != NULL) 11548 copy_tv(&li->li_tv, rettv); 11549 else 11550 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11551 (int)(regmatch.endp[0] - regmatch.startp[0])); 11552 } 11553 else if (l != NULL) 11554 rettv->vval.v_number = idx; 11555 else 11556 { 11557 if (type != 0) 11558 rettv->vval.v_number = 11559 (varnumber_T)(regmatch.startp[0] - str); 11560 else 11561 rettv->vval.v_number = 11562 (varnumber_T)(regmatch.endp[0] - str); 11563 rettv->vval.v_number += str - expr; 11564 } 11565 } 11566 vim_free(regmatch.regprog); 11567 } 11568 11569 theend: 11570 vim_free(tofree); 11571 p_cpo = save_cpo; 11572 } 11573 11574 /* 11575 * "match()" function 11576 */ 11577 static void 11578 f_match(argvars, rettv) 11579 typval_T *argvars; 11580 typval_T *rettv; 11581 { 11582 find_some_match(argvars, rettv, 1); 11583 } 11584 11585 /* 11586 * "matchend()" function 11587 */ 11588 static void 11589 f_matchend(argvars, rettv) 11590 typval_T *argvars; 11591 typval_T *rettv; 11592 { 11593 find_some_match(argvars, rettv, 0); 11594 } 11595 11596 /* 11597 * "matchlist()" function 11598 */ 11599 static void 11600 f_matchlist(argvars, rettv) 11601 typval_T *argvars; 11602 typval_T *rettv; 11603 { 11604 find_some_match(argvars, rettv, 3); 11605 } 11606 11607 /* 11608 * "matchstr()" function 11609 */ 11610 static void 11611 f_matchstr(argvars, rettv) 11612 typval_T *argvars; 11613 typval_T *rettv; 11614 { 11615 find_some_match(argvars, rettv, 2); 11616 } 11617 11618 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11619 11620 static void 11621 max_min(argvars, rettv, domax) 11622 typval_T *argvars; 11623 typval_T *rettv; 11624 int domax; 11625 { 11626 long n = 0; 11627 long i; 11628 int error = FALSE; 11629 11630 if (argvars[0].v_type == VAR_LIST) 11631 { 11632 list_T *l; 11633 listitem_T *li; 11634 11635 l = argvars[0].vval.v_list; 11636 if (l != NULL) 11637 { 11638 li = l->lv_first; 11639 if (li != NULL) 11640 { 11641 n = get_tv_number_chk(&li->li_tv, &error); 11642 for (;;) 11643 { 11644 li = li->li_next; 11645 if (li == NULL) 11646 break; 11647 i = get_tv_number_chk(&li->li_tv, &error); 11648 if (domax ? i > n : i < n) 11649 n = i; 11650 } 11651 } 11652 } 11653 } 11654 else if (argvars[0].v_type == VAR_DICT) 11655 { 11656 dict_T *d; 11657 int first = TRUE; 11658 hashitem_T *hi; 11659 int todo; 11660 11661 d = argvars[0].vval.v_dict; 11662 if (d != NULL) 11663 { 11664 todo = d->dv_hashtab.ht_used; 11665 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11666 { 11667 if (!HASHITEM_EMPTY(hi)) 11668 { 11669 --todo; 11670 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11671 if (first) 11672 { 11673 n = i; 11674 first = FALSE; 11675 } 11676 else if (domax ? i > n : i < n) 11677 n = i; 11678 } 11679 } 11680 } 11681 } 11682 else 11683 EMSG(_(e_listdictarg)); 11684 rettv->vval.v_number = error ? 0 : n; 11685 } 11686 11687 /* 11688 * "max()" function 11689 */ 11690 static void 11691 f_max(argvars, rettv) 11692 typval_T *argvars; 11693 typval_T *rettv; 11694 { 11695 max_min(argvars, rettv, TRUE); 11696 } 11697 11698 /* 11699 * "min()" function 11700 */ 11701 static void 11702 f_min(argvars, rettv) 11703 typval_T *argvars; 11704 typval_T *rettv; 11705 { 11706 max_min(argvars, rettv, FALSE); 11707 } 11708 11709 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11710 11711 /* 11712 * Create the directory in which "dir" is located, and higher levels when 11713 * needed. 11714 */ 11715 static int 11716 mkdir_recurse(dir, prot) 11717 char_u *dir; 11718 int prot; 11719 { 11720 char_u *p; 11721 char_u *updir; 11722 int r = FAIL; 11723 11724 /* Get end of directory name in "dir". 11725 * We're done when it's "/" or "c:/". */ 11726 p = gettail_sep(dir); 11727 if (p <= get_past_head(dir)) 11728 return OK; 11729 11730 /* If the directory exists we're done. Otherwise: create it.*/ 11731 updir = vim_strnsave(dir, (int)(p - dir)); 11732 if (updir == NULL) 11733 return FAIL; 11734 if (mch_isdir(updir)) 11735 r = OK; 11736 else if (mkdir_recurse(updir, prot) == OK) 11737 r = vim_mkdir_emsg(updir, prot); 11738 vim_free(updir); 11739 return r; 11740 } 11741 11742 #ifdef vim_mkdir 11743 /* 11744 * "mkdir()" function 11745 */ 11746 static void 11747 f_mkdir(argvars, rettv) 11748 typval_T *argvars; 11749 typval_T *rettv; 11750 { 11751 char_u *dir; 11752 char_u buf[NUMBUFLEN]; 11753 int prot = 0755; 11754 11755 rettv->vval.v_number = FAIL; 11756 if (check_restricted() || check_secure()) 11757 return; 11758 11759 dir = get_tv_string_buf(&argvars[0], buf); 11760 if (argvars[1].v_type != VAR_UNKNOWN) 11761 { 11762 if (argvars[2].v_type != VAR_UNKNOWN) 11763 prot = get_tv_number_chk(&argvars[2], NULL); 11764 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11765 mkdir_recurse(dir, prot); 11766 } 11767 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11768 } 11769 #endif 11770 11771 /* 11772 * "mode()" function 11773 */ 11774 /*ARGSUSED*/ 11775 static void 11776 f_mode(argvars, rettv) 11777 typval_T *argvars; 11778 typval_T *rettv; 11779 { 11780 char_u buf[2]; 11781 11782 #ifdef FEAT_VISUAL 11783 if (VIsual_active) 11784 { 11785 if (VIsual_select) 11786 buf[0] = VIsual_mode + 's' - 'v'; 11787 else 11788 buf[0] = VIsual_mode; 11789 } 11790 else 11791 #endif 11792 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11793 buf[0] = 'r'; 11794 else if (State & INSERT) 11795 { 11796 if (State & REPLACE_FLAG) 11797 buf[0] = 'R'; 11798 else 11799 buf[0] = 'i'; 11800 } 11801 else if (State & CMDLINE) 11802 buf[0] = 'c'; 11803 else 11804 buf[0] = 'n'; 11805 11806 buf[1] = NUL; 11807 rettv->vval.v_string = vim_strsave(buf); 11808 rettv->v_type = VAR_STRING; 11809 } 11810 11811 /* 11812 * "nextnonblank()" function 11813 */ 11814 static void 11815 f_nextnonblank(argvars, rettv) 11816 typval_T *argvars; 11817 typval_T *rettv; 11818 { 11819 linenr_T lnum; 11820 11821 for (lnum = get_tv_lnum(argvars); ; ++lnum) 11822 { 11823 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 11824 { 11825 lnum = 0; 11826 break; 11827 } 11828 if (*skipwhite(ml_get(lnum)) != NUL) 11829 break; 11830 } 11831 rettv->vval.v_number = lnum; 11832 } 11833 11834 /* 11835 * "nr2char()" function 11836 */ 11837 static void 11838 f_nr2char(argvars, rettv) 11839 typval_T *argvars; 11840 typval_T *rettv; 11841 { 11842 char_u buf[NUMBUFLEN]; 11843 11844 #ifdef FEAT_MBYTE 11845 if (has_mbyte) 11846 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 11847 else 11848 #endif 11849 { 11850 buf[0] = (char_u)get_tv_number(&argvars[0]); 11851 buf[1] = NUL; 11852 } 11853 rettv->v_type = VAR_STRING; 11854 rettv->vval.v_string = vim_strsave(buf); 11855 } 11856 11857 /* 11858 * "prevnonblank()" function 11859 */ 11860 static void 11861 f_prevnonblank(argvars, rettv) 11862 typval_T *argvars; 11863 typval_T *rettv; 11864 { 11865 linenr_T lnum; 11866 11867 lnum = get_tv_lnum(argvars); 11868 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 11869 lnum = 0; 11870 else 11871 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 11872 --lnum; 11873 rettv->vval.v_number = lnum; 11874 } 11875 11876 /* 11877 * "range()" function 11878 */ 11879 static void 11880 f_range(argvars, rettv) 11881 typval_T *argvars; 11882 typval_T *rettv; 11883 { 11884 long start; 11885 long end; 11886 long stride = 1; 11887 long i; 11888 list_T *l; 11889 listitem_T *li; 11890 int error = FALSE; 11891 11892 start = get_tv_number_chk(&argvars[0], &error); 11893 if (argvars[1].v_type == VAR_UNKNOWN) 11894 { 11895 end = start - 1; 11896 start = 0; 11897 } 11898 else 11899 { 11900 end = get_tv_number_chk(&argvars[1], &error); 11901 if (argvars[2].v_type != VAR_UNKNOWN) 11902 stride = get_tv_number_chk(&argvars[2], &error); 11903 } 11904 11905 rettv->vval.v_number = 0; 11906 if (error) 11907 return; /* type error; errmsg already given */ 11908 if (stride == 0) 11909 EMSG(_("E726: Stride is zero")); 11910 else if (stride > 0 ? end + 1 < start : end - 1 > start) 11911 EMSG(_("E727: Start past end")); 11912 else 11913 { 11914 l = list_alloc(); 11915 if (l != NULL) 11916 { 11917 rettv->v_type = VAR_LIST; 11918 rettv->vval.v_list = l; 11919 ++l->lv_refcount; 11920 11921 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 11922 { 11923 li = listitem_alloc(); 11924 if (li == NULL) 11925 break; 11926 li->li_tv.v_type = VAR_NUMBER; 11927 li->li_tv.v_lock = 0; 11928 li->li_tv.vval.v_number = i; 11929 list_append(l, li); 11930 } 11931 } 11932 } 11933 } 11934 11935 /* 11936 * "readfile()" function 11937 */ 11938 static void 11939 f_readfile(argvars, rettv) 11940 typval_T *argvars; 11941 typval_T *rettv; 11942 { 11943 int binary = FALSE; 11944 char_u *fname; 11945 FILE *fd; 11946 list_T *l; 11947 listitem_T *li; 11948 #define FREAD_SIZE 200 /* optimized for text lines */ 11949 char_u buf[FREAD_SIZE]; 11950 int readlen; /* size of last fread() */ 11951 int buflen; /* nr of valid chars in buf[] */ 11952 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 11953 int tolist; /* first byte in buf[] still to be put in list */ 11954 int chop; /* how many CR to chop off */ 11955 char_u *prev = NULL; /* previously read bytes, if any */ 11956 int prevlen = 0; /* length of "prev" if not NULL */ 11957 char_u *s; 11958 int len; 11959 long maxline = MAXLNUM; 11960 long cnt = 0; 11961 11962 if (argvars[1].v_type != VAR_UNKNOWN) 11963 { 11964 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 11965 binary = TRUE; 11966 if (argvars[2].v_type != VAR_UNKNOWN) 11967 maxline = get_tv_number(&argvars[2]); 11968 } 11969 11970 l = list_alloc(); 11971 if (l == NULL) 11972 return; 11973 rettv->v_type = VAR_LIST; 11974 rettv->vval.v_list = l; 11975 l->lv_refcount = 1; 11976 11977 /* Always open the file in binary mode, library functions have a mind of 11978 * their own about CR-LF conversion. */ 11979 fname = get_tv_string(&argvars[0]); 11980 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 11981 { 11982 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 11983 return; 11984 } 11985 11986 filtd = 0; 11987 while (cnt < maxline || maxline < 0) 11988 { 11989 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 11990 buflen = filtd + readlen; 11991 tolist = 0; 11992 for ( ; filtd < buflen || readlen <= 0; ++filtd) 11993 { 11994 if (buf[filtd] == '\n' || readlen <= 0) 11995 { 11996 /* Only when in binary mode add an empty list item when the 11997 * last line ends in a '\n'. */ 11998 if (!binary && readlen == 0 && filtd == 0) 11999 break; 12000 12001 /* Found end-of-line or end-of-file: add a text line to the 12002 * list. */ 12003 chop = 0; 12004 if (!binary) 12005 while (filtd - chop - 1 >= tolist 12006 && buf[filtd - chop - 1] == '\r') 12007 ++chop; 12008 len = filtd - tolist - chop; 12009 if (prev == NULL) 12010 s = vim_strnsave(buf + tolist, len); 12011 else 12012 { 12013 s = alloc((unsigned)(prevlen + len + 1)); 12014 if (s != NULL) 12015 { 12016 mch_memmove(s, prev, prevlen); 12017 vim_free(prev); 12018 prev = NULL; 12019 mch_memmove(s + prevlen, buf + tolist, len); 12020 s[prevlen + len] = NUL; 12021 } 12022 } 12023 tolist = filtd + 1; 12024 12025 li = listitem_alloc(); 12026 if (li == NULL) 12027 { 12028 vim_free(s); 12029 break; 12030 } 12031 li->li_tv.v_type = VAR_STRING; 12032 li->li_tv.v_lock = 0; 12033 li->li_tv.vval.v_string = s; 12034 list_append(l, li); 12035 12036 if (++cnt >= maxline && maxline >= 0) 12037 break; 12038 if (readlen <= 0) 12039 break; 12040 } 12041 else if (buf[filtd] == NUL) 12042 buf[filtd] = '\n'; 12043 } 12044 if (readlen <= 0) 12045 break; 12046 12047 if (tolist == 0) 12048 { 12049 /* "buf" is full, need to move text to an allocated buffer */ 12050 if (prev == NULL) 12051 { 12052 prev = vim_strnsave(buf, buflen); 12053 prevlen = buflen; 12054 } 12055 else 12056 { 12057 s = alloc((unsigned)(prevlen + buflen)); 12058 if (s != NULL) 12059 { 12060 mch_memmove(s, prev, prevlen); 12061 mch_memmove(s + prevlen, buf, buflen); 12062 vim_free(prev); 12063 prev = s; 12064 prevlen += buflen; 12065 } 12066 } 12067 filtd = 0; 12068 } 12069 else 12070 { 12071 mch_memmove(buf, buf + tolist, buflen - tolist); 12072 filtd -= tolist; 12073 } 12074 } 12075 12076 /* 12077 * For a negative line count use only the lines at the end of the file, 12078 * free the rest. 12079 */ 12080 if (maxline < 0) 12081 while (cnt > -maxline) 12082 { 12083 listitem_remove(l, l->lv_first); 12084 --cnt; 12085 } 12086 12087 vim_free(prev); 12088 fclose(fd); 12089 } 12090 12091 12092 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12093 static void make_connection __ARGS((void)); 12094 static int check_connection __ARGS((void)); 12095 12096 static void 12097 make_connection() 12098 { 12099 if (X_DISPLAY == NULL 12100 # ifdef FEAT_GUI 12101 && !gui.in_use 12102 # endif 12103 ) 12104 { 12105 x_force_connect = TRUE; 12106 setup_term_clip(); 12107 x_force_connect = FALSE; 12108 } 12109 } 12110 12111 static int 12112 check_connection() 12113 { 12114 make_connection(); 12115 if (X_DISPLAY == NULL) 12116 { 12117 EMSG(_("E240: No connection to Vim server")); 12118 return FAIL; 12119 } 12120 return OK; 12121 } 12122 #endif 12123 12124 #ifdef FEAT_CLIENTSERVER 12125 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12126 12127 static void 12128 remote_common(argvars, rettv, expr) 12129 typval_T *argvars; 12130 typval_T *rettv; 12131 int expr; 12132 { 12133 char_u *server_name; 12134 char_u *keys; 12135 char_u *r = NULL; 12136 char_u buf[NUMBUFLEN]; 12137 # ifdef WIN32 12138 HWND w; 12139 # else 12140 Window w; 12141 # endif 12142 12143 if (check_restricted() || check_secure()) 12144 return; 12145 12146 # ifdef FEAT_X11 12147 if (check_connection() == FAIL) 12148 return; 12149 # endif 12150 12151 server_name = get_tv_string_chk(&argvars[0]); 12152 if (server_name == NULL) 12153 return; /* type error; errmsg already given */ 12154 keys = get_tv_string_buf(&argvars[1], buf); 12155 # ifdef WIN32 12156 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12157 # else 12158 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12159 < 0) 12160 # endif 12161 { 12162 if (r != NULL) 12163 EMSG(r); /* sending worked but evaluation failed */ 12164 else 12165 EMSG2(_("E241: Unable to send to %s"), server_name); 12166 return; 12167 } 12168 12169 rettv->vval.v_string = r; 12170 12171 if (argvars[2].v_type != VAR_UNKNOWN) 12172 { 12173 dictitem_T v; 12174 char_u str[30]; 12175 char_u *idvar; 12176 12177 sprintf((char *)str, "0x%x", (unsigned int)w); 12178 v.di_tv.v_type = VAR_STRING; 12179 v.di_tv.vval.v_string = vim_strsave(str); 12180 idvar = get_tv_string_chk(&argvars[2]); 12181 if (idvar != NULL) 12182 set_var(idvar, &v.di_tv, FALSE); 12183 vim_free(v.di_tv.vval.v_string); 12184 } 12185 } 12186 #endif 12187 12188 /* 12189 * "remote_expr()" function 12190 */ 12191 /*ARGSUSED*/ 12192 static void 12193 f_remote_expr(argvars, rettv) 12194 typval_T *argvars; 12195 typval_T *rettv; 12196 { 12197 rettv->v_type = VAR_STRING; 12198 rettv->vval.v_string = NULL; 12199 #ifdef FEAT_CLIENTSERVER 12200 remote_common(argvars, rettv, TRUE); 12201 #endif 12202 } 12203 12204 /* 12205 * "remote_foreground()" function 12206 */ 12207 /*ARGSUSED*/ 12208 static void 12209 f_remote_foreground(argvars, rettv) 12210 typval_T *argvars; 12211 typval_T *rettv; 12212 { 12213 rettv->vval.v_number = 0; 12214 #ifdef FEAT_CLIENTSERVER 12215 # ifdef WIN32 12216 /* On Win32 it's done in this application. */ 12217 { 12218 char_u *server_name = get_tv_string_chk(&argvars[0]); 12219 12220 if (server_name != NULL) 12221 serverForeground(server_name); 12222 } 12223 # else 12224 /* Send a foreground() expression to the server. */ 12225 argvars[1].v_type = VAR_STRING; 12226 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12227 argvars[2].v_type = VAR_UNKNOWN; 12228 remote_common(argvars, rettv, TRUE); 12229 vim_free(argvars[1].vval.v_string); 12230 # endif 12231 #endif 12232 } 12233 12234 /*ARGSUSED*/ 12235 static void 12236 f_remote_peek(argvars, rettv) 12237 typval_T *argvars; 12238 typval_T *rettv; 12239 { 12240 #ifdef FEAT_CLIENTSERVER 12241 dictitem_T v; 12242 char_u *s = NULL; 12243 # ifdef WIN32 12244 int n = 0; 12245 # endif 12246 char_u *serverid; 12247 12248 if (check_restricted() || check_secure()) 12249 { 12250 rettv->vval.v_number = -1; 12251 return; 12252 } 12253 serverid = get_tv_string_chk(&argvars[0]); 12254 if (serverid == NULL) 12255 { 12256 rettv->vval.v_number = -1; 12257 return; /* type error; errmsg already given */ 12258 } 12259 # ifdef WIN32 12260 sscanf(serverid, "%x", &n); 12261 if (n == 0) 12262 rettv->vval.v_number = -1; 12263 else 12264 { 12265 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12266 rettv->vval.v_number = (s != NULL); 12267 } 12268 # else 12269 rettv->vval.v_number = 0; 12270 if (check_connection() == FAIL) 12271 return; 12272 12273 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12274 serverStrToWin(serverid), &s); 12275 # endif 12276 12277 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12278 { 12279 char_u *retvar; 12280 12281 v.di_tv.v_type = VAR_STRING; 12282 v.di_tv.vval.v_string = vim_strsave(s); 12283 retvar = get_tv_string_chk(&argvars[1]); 12284 if (retvar != NULL) 12285 set_var(retvar, &v.di_tv, FALSE); 12286 vim_free(v.di_tv.vval.v_string); 12287 } 12288 #else 12289 rettv->vval.v_number = -1; 12290 #endif 12291 } 12292 12293 /*ARGSUSED*/ 12294 static void 12295 f_remote_read(argvars, rettv) 12296 typval_T *argvars; 12297 typval_T *rettv; 12298 { 12299 char_u *r = NULL; 12300 12301 #ifdef FEAT_CLIENTSERVER 12302 char_u *serverid = get_tv_string_chk(&argvars[0]); 12303 12304 if (serverid != NULL && !check_restricted() && !check_secure()) 12305 { 12306 # ifdef WIN32 12307 /* The server's HWND is encoded in the 'id' parameter */ 12308 int n = 0; 12309 12310 sscanf(serverid, "%x", &n); 12311 if (n != 0) 12312 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12313 if (r == NULL) 12314 # else 12315 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12316 serverStrToWin(serverid), &r, FALSE) < 0) 12317 # endif 12318 EMSG(_("E277: Unable to read a server reply")); 12319 } 12320 #endif 12321 rettv->v_type = VAR_STRING; 12322 rettv->vval.v_string = r; 12323 } 12324 12325 /* 12326 * "remote_send()" function 12327 */ 12328 /*ARGSUSED*/ 12329 static void 12330 f_remote_send(argvars, rettv) 12331 typval_T *argvars; 12332 typval_T *rettv; 12333 { 12334 rettv->v_type = VAR_STRING; 12335 rettv->vval.v_string = NULL; 12336 #ifdef FEAT_CLIENTSERVER 12337 remote_common(argvars, rettv, FALSE); 12338 #endif 12339 } 12340 12341 /* 12342 * "remove()" function 12343 */ 12344 static void 12345 f_remove(argvars, rettv) 12346 typval_T *argvars; 12347 typval_T *rettv; 12348 { 12349 list_T *l; 12350 listitem_T *item, *item2; 12351 listitem_T *li; 12352 long idx; 12353 long end; 12354 char_u *key; 12355 dict_T *d; 12356 dictitem_T *di; 12357 12358 rettv->vval.v_number = 0; 12359 if (argvars[0].v_type == VAR_DICT) 12360 { 12361 if (argvars[2].v_type != VAR_UNKNOWN) 12362 EMSG2(_(e_toomanyarg), "remove()"); 12363 else if ((d = argvars[0].vval.v_dict) != NULL 12364 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12365 { 12366 key = get_tv_string_chk(&argvars[1]); 12367 if (key != NULL) 12368 { 12369 di = dict_find(d, key, -1); 12370 if (di == NULL) 12371 EMSG2(_(e_dictkey), key); 12372 else 12373 { 12374 *rettv = di->di_tv; 12375 init_tv(&di->di_tv); 12376 dictitem_remove(d, di); 12377 } 12378 } 12379 } 12380 } 12381 else if (argvars[0].v_type != VAR_LIST) 12382 EMSG2(_(e_listdictarg), "remove()"); 12383 else if ((l = argvars[0].vval.v_list) != NULL 12384 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12385 { 12386 int error = FALSE; 12387 12388 idx = get_tv_number_chk(&argvars[1], &error); 12389 if (error) 12390 ; /* type error: do nothing, errmsg already given */ 12391 else if ((item = list_find(l, idx)) == NULL) 12392 EMSGN(_(e_listidx), idx); 12393 else 12394 { 12395 if (argvars[2].v_type == VAR_UNKNOWN) 12396 { 12397 /* Remove one item, return its value. */ 12398 list_remove(l, item, item); 12399 *rettv = item->li_tv; 12400 vim_free(item); 12401 } 12402 else 12403 { 12404 /* Remove range of items, return list with values. */ 12405 end = get_tv_number_chk(&argvars[2], &error); 12406 if (error) 12407 ; /* type error: do nothing */ 12408 else if ((item2 = list_find(l, end)) == NULL) 12409 EMSGN(_(e_listidx), end); 12410 else 12411 { 12412 int cnt = 0; 12413 12414 for (li = item; li != NULL; li = li->li_next) 12415 { 12416 ++cnt; 12417 if (li == item2) 12418 break; 12419 } 12420 if (li == NULL) /* didn't find "item2" after "item" */ 12421 EMSG(_(e_invrange)); 12422 else 12423 { 12424 list_remove(l, item, item2); 12425 l = list_alloc(); 12426 if (l != NULL) 12427 { 12428 rettv->v_type = VAR_LIST; 12429 rettv->vval.v_list = l; 12430 l->lv_first = item; 12431 l->lv_last = item2; 12432 l->lv_refcount = 1; 12433 item->li_prev = NULL; 12434 item2->li_next = NULL; 12435 l->lv_len = cnt; 12436 } 12437 } 12438 } 12439 } 12440 } 12441 } 12442 } 12443 12444 /* 12445 * "rename({from}, {to})" function 12446 */ 12447 static void 12448 f_rename(argvars, rettv) 12449 typval_T *argvars; 12450 typval_T *rettv; 12451 { 12452 char_u buf[NUMBUFLEN]; 12453 12454 if (check_restricted() || check_secure()) 12455 rettv->vval.v_number = -1; 12456 else 12457 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12458 get_tv_string_buf(&argvars[1], buf)); 12459 } 12460 12461 /* 12462 * "repeat()" function 12463 */ 12464 /*ARGSUSED*/ 12465 static void 12466 f_repeat(argvars, rettv) 12467 typval_T *argvars; 12468 typval_T *rettv; 12469 { 12470 char_u *p; 12471 int n; 12472 int slen; 12473 int len; 12474 char_u *r; 12475 int i; 12476 list_T *l; 12477 12478 n = get_tv_number(&argvars[1]); 12479 if (argvars[0].v_type == VAR_LIST) 12480 { 12481 l = list_alloc(); 12482 if (l != NULL && argvars[0].vval.v_list != NULL) 12483 { 12484 l->lv_refcount = 1; 12485 while (n-- > 0) 12486 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12487 break; 12488 } 12489 rettv->v_type = VAR_LIST; 12490 rettv->vval.v_list = l; 12491 } 12492 else 12493 { 12494 p = get_tv_string(&argvars[0]); 12495 rettv->v_type = VAR_STRING; 12496 rettv->vval.v_string = NULL; 12497 12498 slen = (int)STRLEN(p); 12499 len = slen * n; 12500 if (len <= 0) 12501 return; 12502 12503 r = alloc(len + 1); 12504 if (r != NULL) 12505 { 12506 for (i = 0; i < n; i++) 12507 mch_memmove(r + i * slen, p, (size_t)slen); 12508 r[len] = NUL; 12509 } 12510 12511 rettv->vval.v_string = r; 12512 } 12513 } 12514 12515 /* 12516 * "resolve()" function 12517 */ 12518 static void 12519 f_resolve(argvars, rettv) 12520 typval_T *argvars; 12521 typval_T *rettv; 12522 { 12523 char_u *p; 12524 12525 p = get_tv_string(&argvars[0]); 12526 #ifdef FEAT_SHORTCUT 12527 { 12528 char_u *v = NULL; 12529 12530 v = mch_resolve_shortcut(p); 12531 if (v != NULL) 12532 rettv->vval.v_string = v; 12533 else 12534 rettv->vval.v_string = vim_strsave(p); 12535 } 12536 #else 12537 # ifdef HAVE_READLINK 12538 { 12539 char_u buf[MAXPATHL + 1]; 12540 char_u *cpy; 12541 int len; 12542 char_u *remain = NULL; 12543 char_u *q; 12544 int is_relative_to_current = FALSE; 12545 int has_trailing_pathsep = FALSE; 12546 int limit = 100; 12547 12548 p = vim_strsave(p); 12549 12550 if (p[0] == '.' && (vim_ispathsep(p[1]) 12551 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12552 is_relative_to_current = TRUE; 12553 12554 len = STRLEN(p); 12555 if (len > 0 && after_pathsep(p, p + len)) 12556 has_trailing_pathsep = TRUE; 12557 12558 q = getnextcomp(p); 12559 if (*q != NUL) 12560 { 12561 /* Separate the first path component in "p", and keep the 12562 * remainder (beginning with the path separator). */ 12563 remain = vim_strsave(q - 1); 12564 q[-1] = NUL; 12565 } 12566 12567 for (;;) 12568 { 12569 for (;;) 12570 { 12571 len = readlink((char *)p, (char *)buf, MAXPATHL); 12572 if (len <= 0) 12573 break; 12574 buf[len] = NUL; 12575 12576 if (limit-- == 0) 12577 { 12578 vim_free(p); 12579 vim_free(remain); 12580 EMSG(_("E655: Too many symbolic links (cycle?)")); 12581 rettv->vval.v_string = NULL; 12582 goto fail; 12583 } 12584 12585 /* Ensure that the result will have a trailing path separator 12586 * if the argument has one. */ 12587 if (remain == NULL && has_trailing_pathsep) 12588 add_pathsep(buf); 12589 12590 /* Separate the first path component in the link value and 12591 * concatenate the remainders. */ 12592 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12593 if (*q != NUL) 12594 { 12595 if (remain == NULL) 12596 remain = vim_strsave(q - 1); 12597 else 12598 { 12599 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12600 if (cpy != NULL) 12601 { 12602 STRCAT(cpy, remain); 12603 vim_free(remain); 12604 remain = cpy; 12605 } 12606 } 12607 q[-1] = NUL; 12608 } 12609 12610 q = gettail(p); 12611 if (q > p && *q == NUL) 12612 { 12613 /* Ignore trailing path separator. */ 12614 q[-1] = NUL; 12615 q = gettail(p); 12616 } 12617 if (q > p && !mch_isFullName(buf)) 12618 { 12619 /* symlink is relative to directory of argument */ 12620 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12621 if (cpy != NULL) 12622 { 12623 STRCPY(cpy, p); 12624 STRCPY(gettail(cpy), buf); 12625 vim_free(p); 12626 p = cpy; 12627 } 12628 } 12629 else 12630 { 12631 vim_free(p); 12632 p = vim_strsave(buf); 12633 } 12634 } 12635 12636 if (remain == NULL) 12637 break; 12638 12639 /* Append the first path component of "remain" to "p". */ 12640 q = getnextcomp(remain + 1); 12641 len = q - remain - (*q != NUL); 12642 cpy = vim_strnsave(p, STRLEN(p) + len); 12643 if (cpy != NULL) 12644 { 12645 STRNCAT(cpy, remain, len); 12646 vim_free(p); 12647 p = cpy; 12648 } 12649 /* Shorten "remain". */ 12650 if (*q != NUL) 12651 STRCPY(remain, q - 1); 12652 else 12653 { 12654 vim_free(remain); 12655 remain = NULL; 12656 } 12657 } 12658 12659 /* If the result is a relative path name, make it explicitly relative to 12660 * the current directory if and only if the argument had this form. */ 12661 if (!vim_ispathsep(*p)) 12662 { 12663 if (is_relative_to_current 12664 && *p != NUL 12665 && !(p[0] == '.' 12666 && (p[1] == NUL 12667 || vim_ispathsep(p[1]) 12668 || (p[1] == '.' 12669 && (p[2] == NUL 12670 || vim_ispathsep(p[2])))))) 12671 { 12672 /* Prepend "./". */ 12673 cpy = concat_str((char_u *)"./", p); 12674 if (cpy != NULL) 12675 { 12676 vim_free(p); 12677 p = cpy; 12678 } 12679 } 12680 else if (!is_relative_to_current) 12681 { 12682 /* Strip leading "./". */ 12683 q = p; 12684 while (q[0] == '.' && vim_ispathsep(q[1])) 12685 q += 2; 12686 if (q > p) 12687 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12688 } 12689 } 12690 12691 /* Ensure that the result will have no trailing path separator 12692 * if the argument had none. But keep "/" or "//". */ 12693 if (!has_trailing_pathsep) 12694 { 12695 q = p + STRLEN(p); 12696 if (after_pathsep(p, q)) 12697 *gettail_sep(p) = NUL; 12698 } 12699 12700 rettv->vval.v_string = p; 12701 } 12702 # else 12703 rettv->vval.v_string = vim_strsave(p); 12704 # endif 12705 #endif 12706 12707 simplify_filename(rettv->vval.v_string); 12708 12709 #ifdef HAVE_READLINK 12710 fail: 12711 #endif 12712 rettv->v_type = VAR_STRING; 12713 } 12714 12715 /* 12716 * "reverse({list})" function 12717 */ 12718 static void 12719 f_reverse(argvars, rettv) 12720 typval_T *argvars; 12721 typval_T *rettv; 12722 { 12723 list_T *l; 12724 listitem_T *li, *ni; 12725 12726 rettv->vval.v_number = 0; 12727 if (argvars[0].v_type != VAR_LIST) 12728 EMSG2(_(e_listarg), "reverse()"); 12729 else if ((l = argvars[0].vval.v_list) != NULL 12730 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12731 { 12732 li = l->lv_last; 12733 l->lv_first = l->lv_last = NULL; 12734 l->lv_len = 0; 12735 while (li != NULL) 12736 { 12737 ni = li->li_prev; 12738 list_append(l, li); 12739 li = ni; 12740 } 12741 rettv->vval.v_list = l; 12742 rettv->v_type = VAR_LIST; 12743 ++l->lv_refcount; 12744 } 12745 } 12746 12747 #define SP_NOMOVE 1 /* don't move cursor */ 12748 #define SP_REPEAT 2 /* repeat to find outer pair */ 12749 #define SP_RETCOUNT 4 /* return matchcount */ 12750 #define SP_SETPCMARK 8 /* set previous context mark */ 12751 12752 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12753 12754 /* 12755 * Get flags for a search function. 12756 * Possibly sets "p_ws". 12757 * Returns BACKWARD, FORWARD or zero (for an error). 12758 */ 12759 static int 12760 get_search_arg(varp, flagsp) 12761 typval_T *varp; 12762 int *flagsp; 12763 { 12764 int dir = FORWARD; 12765 char_u *flags; 12766 char_u nbuf[NUMBUFLEN]; 12767 int mask; 12768 12769 if (varp->v_type != VAR_UNKNOWN) 12770 { 12771 flags = get_tv_string_buf_chk(varp, nbuf); 12772 if (flags == NULL) 12773 return 0; /* type error; errmsg already given */ 12774 while (*flags != NUL) 12775 { 12776 switch (*flags) 12777 { 12778 case 'b': dir = BACKWARD; break; 12779 case 'w': p_ws = TRUE; break; 12780 case 'W': p_ws = FALSE; break; 12781 default: mask = 0; 12782 if (flagsp != NULL) 12783 switch (*flags) 12784 { 12785 case 'n': mask = SP_NOMOVE; break; 12786 case 'r': mask = SP_REPEAT; break; 12787 case 'm': mask = SP_RETCOUNT; break; 12788 case 's': mask = SP_SETPCMARK; break; 12789 } 12790 if (mask == 0) 12791 { 12792 EMSG2(_(e_invarg2), flags); 12793 dir = 0; 12794 } 12795 else 12796 *flagsp |= mask; 12797 } 12798 if (dir == 0) 12799 break; 12800 ++flags; 12801 } 12802 } 12803 return dir; 12804 } 12805 12806 /* 12807 * "search()" function 12808 */ 12809 static void 12810 f_search(argvars, rettv) 12811 typval_T *argvars; 12812 typval_T *rettv; 12813 { 12814 char_u *pat; 12815 pos_T pos; 12816 pos_T save_cursor; 12817 int save_p_ws = p_ws; 12818 int dir; 12819 int flags = 0; 12820 12821 rettv->vval.v_number = 0; /* default: FAIL */ 12822 12823 pat = get_tv_string(&argvars[0]); 12824 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 12825 if (dir == 0) 12826 goto theend; 12827 /* 12828 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 12829 * Check to make sure only those flags are set. 12830 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 12831 * flags cannot be set. Check for that condition also. 12832 */ 12833 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 12834 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 12835 { 12836 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 12837 goto theend; 12838 } 12839 12840 pos = save_cursor = curwin->w_cursor; 12841 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 12842 SEARCH_KEEP, RE_SEARCH) != FAIL) 12843 { 12844 rettv->vval.v_number = pos.lnum; 12845 if (flags & SP_SETPCMARK) 12846 setpcmark(); 12847 curwin->w_cursor = pos; 12848 /* "/$" will put the cursor after the end of the line, may need to 12849 * correct that here */ 12850 check_cursor(); 12851 } 12852 12853 /* If 'n' flag is used: restore cursor position. */ 12854 if (flags & SP_NOMOVE) 12855 curwin->w_cursor = save_cursor; 12856 theend: 12857 p_ws = save_p_ws; 12858 } 12859 12860 /* 12861 * "searchpair()" function 12862 */ 12863 static void 12864 f_searchpair(argvars, rettv) 12865 typval_T *argvars; 12866 typval_T *rettv; 12867 { 12868 char_u *spat, *mpat, *epat; 12869 char_u *skip; 12870 int save_p_ws = p_ws; 12871 int dir; 12872 int flags = 0; 12873 char_u nbuf1[NUMBUFLEN]; 12874 char_u nbuf2[NUMBUFLEN]; 12875 char_u nbuf3[NUMBUFLEN]; 12876 12877 rettv->vval.v_number = 0; /* default: FAIL */ 12878 12879 /* Get the three pattern arguments: start, middle, end. */ 12880 spat = get_tv_string_chk(&argvars[0]); 12881 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 12882 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 12883 if (spat == NULL || mpat == NULL || epat == NULL) 12884 goto theend; /* type error */ 12885 12886 /* Handle the optional fourth argument: flags */ 12887 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 12888 if (dir == 0) 12889 goto theend; 12890 /* 12891 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 12892 */ 12893 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 12894 { 12895 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 12896 goto theend; 12897 } 12898 12899 /* Optional fifth argument: skip expresion */ 12900 if (argvars[3].v_type == VAR_UNKNOWN 12901 || argvars[4].v_type == VAR_UNKNOWN) 12902 skip = (char_u *)""; 12903 else 12904 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 12905 if (skip == NULL) 12906 goto theend; /* type error */ 12907 12908 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 12909 12910 theend: 12911 p_ws = save_p_ws; 12912 } 12913 12914 /* 12915 * Search for a start/middle/end thing. 12916 * Used by searchpair(), see its documentation for the details. 12917 * Returns 0 or -1 for no match, 12918 */ 12919 long 12920 do_searchpair(spat, mpat, epat, dir, skip, flags) 12921 char_u *spat; /* start pattern */ 12922 char_u *mpat; /* middle pattern */ 12923 char_u *epat; /* end pattern */ 12924 int dir; /* BACKWARD or FORWARD */ 12925 char_u *skip; /* skip expression */ 12926 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 12927 { 12928 char_u *save_cpo; 12929 char_u *pat, *pat2 = NULL, *pat3 = NULL; 12930 long retval = 0; 12931 pos_T pos; 12932 pos_T firstpos; 12933 pos_T foundpos; 12934 pos_T save_cursor; 12935 pos_T save_pos; 12936 int n; 12937 int r; 12938 int nest = 1; 12939 int err; 12940 12941 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 12942 save_cpo = p_cpo; 12943 p_cpo = (char_u *)""; 12944 12945 /* Make two search patterns: start/end (pat2, for in nested pairs) and 12946 * start/middle/end (pat3, for the top pair). */ 12947 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 12948 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 12949 if (pat2 == NULL || pat3 == NULL) 12950 goto theend; 12951 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 12952 if (*mpat == NUL) 12953 STRCPY(pat3, pat2); 12954 else 12955 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 12956 spat, epat, mpat); 12957 12958 save_cursor = curwin->w_cursor; 12959 pos = curwin->w_cursor; 12960 firstpos.lnum = 0; 12961 foundpos.lnum = 0; 12962 pat = pat3; 12963 for (;;) 12964 { 12965 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 12966 SEARCH_KEEP, RE_SEARCH); 12967 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 12968 /* didn't find it or found the first match again: FAIL */ 12969 break; 12970 12971 if (firstpos.lnum == 0) 12972 firstpos = pos; 12973 if (equalpos(pos, foundpos)) 12974 { 12975 /* Found the same position again. Can happen with a pattern that 12976 * has "\zs" at the end and searching backwards. Advance one 12977 * character and try again. */ 12978 if (dir == BACKWARD) 12979 decl(&pos); 12980 else 12981 incl(&pos); 12982 } 12983 foundpos = pos; 12984 12985 /* If the skip pattern matches, ignore this match. */ 12986 if (*skip != NUL) 12987 { 12988 save_pos = curwin->w_cursor; 12989 curwin->w_cursor = pos; 12990 r = eval_to_bool(skip, &err, NULL, FALSE); 12991 curwin->w_cursor = save_pos; 12992 if (err) 12993 { 12994 /* Evaluating {skip} caused an error, break here. */ 12995 curwin->w_cursor = save_cursor; 12996 retval = -1; 12997 break; 12998 } 12999 if (r) 13000 continue; 13001 } 13002 13003 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13004 { 13005 /* Found end when searching backwards or start when searching 13006 * forward: nested pair. */ 13007 ++nest; 13008 pat = pat2; /* nested, don't search for middle */ 13009 } 13010 else 13011 { 13012 /* Found end when searching forward or start when searching 13013 * backward: end of (nested) pair; or found middle in outer pair. */ 13014 if (--nest == 1) 13015 pat = pat3; /* outer level, search for middle */ 13016 } 13017 13018 if (nest == 0) 13019 { 13020 /* Found the match: return matchcount or line number. */ 13021 if (flags & SP_RETCOUNT) 13022 ++retval; 13023 else 13024 retval = pos.lnum; 13025 if (flags & SP_SETPCMARK) 13026 setpcmark(); 13027 curwin->w_cursor = pos; 13028 if (!(flags & SP_REPEAT)) 13029 break; 13030 nest = 1; /* search for next unmatched */ 13031 } 13032 } 13033 13034 /* If 'n' flag is used or search failed: restore cursor position. */ 13035 if ((flags & SP_NOMOVE) || retval == 0) 13036 curwin->w_cursor = save_cursor; 13037 13038 theend: 13039 vim_free(pat2); 13040 vim_free(pat3); 13041 p_cpo = save_cpo; 13042 13043 return retval; 13044 } 13045 13046 /*ARGSUSED*/ 13047 static void 13048 f_server2client(argvars, rettv) 13049 typval_T *argvars; 13050 typval_T *rettv; 13051 { 13052 #ifdef FEAT_CLIENTSERVER 13053 char_u buf[NUMBUFLEN]; 13054 char_u *server = get_tv_string_chk(&argvars[0]); 13055 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13056 13057 rettv->vval.v_number = -1; 13058 if (server == NULL || reply == NULL) 13059 return; 13060 if (check_restricted() || check_secure()) 13061 return; 13062 # ifdef FEAT_X11 13063 if (check_connection() == FAIL) 13064 return; 13065 # endif 13066 13067 if (serverSendReply(server, reply) < 0) 13068 { 13069 EMSG(_("E258: Unable to send to client")); 13070 return; 13071 } 13072 rettv->vval.v_number = 0; 13073 #else 13074 rettv->vval.v_number = -1; 13075 #endif 13076 } 13077 13078 /*ARGSUSED*/ 13079 static void 13080 f_serverlist(argvars, rettv) 13081 typval_T *argvars; 13082 typval_T *rettv; 13083 { 13084 char_u *r = NULL; 13085 13086 #ifdef FEAT_CLIENTSERVER 13087 # ifdef WIN32 13088 r = serverGetVimNames(); 13089 # else 13090 make_connection(); 13091 if (X_DISPLAY != NULL) 13092 r = serverGetVimNames(X_DISPLAY); 13093 # endif 13094 #endif 13095 rettv->v_type = VAR_STRING; 13096 rettv->vval.v_string = r; 13097 } 13098 13099 /* 13100 * "setbufvar()" function 13101 */ 13102 /*ARGSUSED*/ 13103 static void 13104 f_setbufvar(argvars, rettv) 13105 typval_T *argvars; 13106 typval_T *rettv; 13107 { 13108 buf_T *buf; 13109 #ifdef FEAT_AUTOCMD 13110 aco_save_T aco; 13111 #else 13112 buf_T *save_curbuf; 13113 #endif 13114 char_u *varname, *bufvarname; 13115 typval_T *varp; 13116 char_u nbuf[NUMBUFLEN]; 13117 13118 rettv->vval.v_number = 0; 13119 13120 if (check_restricted() || check_secure()) 13121 return; 13122 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13123 varname = get_tv_string_chk(&argvars[1]); 13124 buf = get_buf_tv(&argvars[0]); 13125 varp = &argvars[2]; 13126 13127 if (buf != NULL && varname != NULL && varp != NULL) 13128 { 13129 /* set curbuf to be our buf, temporarily */ 13130 #ifdef FEAT_AUTOCMD 13131 aucmd_prepbuf(&aco, buf); 13132 #else 13133 save_curbuf = curbuf; 13134 curbuf = buf; 13135 #endif 13136 13137 if (*varname == '&') 13138 { 13139 long numval; 13140 char_u *strval; 13141 int error = FALSE; 13142 13143 ++varname; 13144 numval = get_tv_number_chk(varp, &error); 13145 strval = get_tv_string_buf_chk(varp, nbuf); 13146 if (!error && strval != NULL) 13147 set_option_value(varname, numval, strval, OPT_LOCAL); 13148 } 13149 else 13150 { 13151 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13152 if (bufvarname != NULL) 13153 { 13154 STRCPY(bufvarname, "b:"); 13155 STRCPY(bufvarname + 2, varname); 13156 set_var(bufvarname, varp, TRUE); 13157 vim_free(bufvarname); 13158 } 13159 } 13160 13161 /* reset notion of buffer */ 13162 #ifdef FEAT_AUTOCMD 13163 aucmd_restbuf(&aco); 13164 #else 13165 curbuf = save_curbuf; 13166 #endif 13167 } 13168 } 13169 13170 /* 13171 * "setcmdpos()" function 13172 */ 13173 static void 13174 f_setcmdpos(argvars, rettv) 13175 typval_T *argvars; 13176 typval_T *rettv; 13177 { 13178 int pos = (int)get_tv_number(&argvars[0]) - 1; 13179 13180 if (pos >= 0) 13181 rettv->vval.v_number = set_cmdline_pos(pos); 13182 } 13183 13184 /* 13185 * "setline()" function 13186 */ 13187 static void 13188 f_setline(argvars, rettv) 13189 typval_T *argvars; 13190 typval_T *rettv; 13191 { 13192 linenr_T lnum; 13193 char_u *line = NULL; 13194 list_T *l = NULL; 13195 listitem_T *li = NULL; 13196 long added = 0; 13197 linenr_T lcount = curbuf->b_ml.ml_line_count; 13198 13199 lnum = get_tv_lnum(&argvars[0]); 13200 if (argvars[1].v_type == VAR_LIST) 13201 { 13202 l = argvars[1].vval.v_list; 13203 li = l->lv_first; 13204 } 13205 else 13206 line = get_tv_string_chk(&argvars[1]); 13207 13208 rettv->vval.v_number = 0; /* OK */ 13209 for (;;) 13210 { 13211 if (l != NULL) 13212 { 13213 /* list argument, get next string */ 13214 if (li == NULL) 13215 break; 13216 line = get_tv_string_chk(&li->li_tv); 13217 li = li->li_next; 13218 } 13219 13220 rettv->vval.v_number = 1; /* FAIL */ 13221 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13222 break; 13223 if (lnum <= curbuf->b_ml.ml_line_count) 13224 { 13225 /* existing line, replace it */ 13226 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13227 { 13228 changed_bytes(lnum, 0); 13229 check_cursor_col(); 13230 rettv->vval.v_number = 0; /* OK */ 13231 } 13232 } 13233 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13234 { 13235 /* lnum is one past the last line, append the line */ 13236 ++added; 13237 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13238 rettv->vval.v_number = 0; /* OK */ 13239 } 13240 13241 if (l == NULL) /* only one string argument */ 13242 break; 13243 ++lnum; 13244 } 13245 13246 if (added > 0) 13247 appended_lines_mark(lcount, added); 13248 } 13249 13250 /* 13251 * "setqflist()" function 13252 */ 13253 /*ARGSUSED*/ 13254 static void 13255 f_setqflist(argvars, rettv) 13256 typval_T *argvars; 13257 typval_T *rettv; 13258 { 13259 char_u *act; 13260 int action = ' '; 13261 13262 rettv->vval.v_number = -1; 13263 13264 #ifdef FEAT_QUICKFIX 13265 if (argvars[0].v_type != VAR_LIST) 13266 EMSG(_(e_listreq)); 13267 else 13268 { 13269 list_T *l = argvars[0].vval.v_list; 13270 13271 if (argvars[1].v_type == VAR_STRING) 13272 { 13273 act = get_tv_string_chk(&argvars[1]); 13274 if (act == NULL) 13275 return; /* type error; errmsg already given */ 13276 if (*act == 'a' || *act == 'r') 13277 action = *act; 13278 } 13279 13280 if (l != NULL && set_errorlist(l, action) == OK) 13281 rettv->vval.v_number = 0; 13282 } 13283 #endif 13284 } 13285 13286 /* 13287 * "setreg()" function 13288 */ 13289 static void 13290 f_setreg(argvars, rettv) 13291 typval_T *argvars; 13292 typval_T *rettv; 13293 { 13294 int regname; 13295 char_u *strregname; 13296 char_u *stropt; 13297 char_u *strval; 13298 int append; 13299 char_u yank_type; 13300 long block_len; 13301 13302 block_len = -1; 13303 yank_type = MAUTO; 13304 append = FALSE; 13305 13306 strregname = get_tv_string_chk(argvars); 13307 rettv->vval.v_number = 1; /* FAIL is default */ 13308 13309 if (strregname == NULL) 13310 return; /* type error; errmsg already given */ 13311 regname = *strregname; 13312 if (regname == 0 || regname == '@') 13313 regname = '"'; 13314 else if (regname == '=') 13315 return; 13316 13317 if (argvars[2].v_type != VAR_UNKNOWN) 13318 { 13319 stropt = get_tv_string_chk(&argvars[2]); 13320 if (stropt == NULL) 13321 return; /* type error */ 13322 for (; *stropt != NUL; ++stropt) 13323 switch (*stropt) 13324 { 13325 case 'a': case 'A': /* append */ 13326 append = TRUE; 13327 break; 13328 case 'v': case 'c': /* character-wise selection */ 13329 yank_type = MCHAR; 13330 break; 13331 case 'V': case 'l': /* line-wise selection */ 13332 yank_type = MLINE; 13333 break; 13334 #ifdef FEAT_VISUAL 13335 case 'b': case Ctrl_V: /* block-wise selection */ 13336 yank_type = MBLOCK; 13337 if (VIM_ISDIGIT(stropt[1])) 13338 { 13339 ++stropt; 13340 block_len = getdigits(&stropt) - 1; 13341 --stropt; 13342 } 13343 break; 13344 #endif 13345 } 13346 } 13347 13348 strval = get_tv_string_chk(&argvars[1]); 13349 if (strval != NULL) 13350 write_reg_contents_ex(regname, strval, -1, 13351 append, yank_type, block_len); 13352 rettv->vval.v_number = 0; 13353 } 13354 13355 13356 /* 13357 * "setwinvar(expr)" function 13358 */ 13359 /*ARGSUSED*/ 13360 static void 13361 f_setwinvar(argvars, rettv) 13362 typval_T *argvars; 13363 typval_T *rettv; 13364 { 13365 win_T *win; 13366 #ifdef FEAT_WINDOWS 13367 win_T *save_curwin; 13368 #endif 13369 char_u *varname, *winvarname; 13370 typval_T *varp; 13371 char_u nbuf[NUMBUFLEN]; 13372 13373 rettv->vval.v_number = 0; 13374 13375 if (check_restricted() || check_secure()) 13376 return; 13377 win = find_win_by_nr(&argvars[0]); 13378 varname = get_tv_string_chk(&argvars[1]); 13379 varp = &argvars[2]; 13380 13381 if (win != NULL && varname != NULL && varp != NULL) 13382 { 13383 #ifdef FEAT_WINDOWS 13384 /* set curwin to be our win, temporarily */ 13385 save_curwin = curwin; 13386 curwin = win; 13387 curbuf = curwin->w_buffer; 13388 #endif 13389 13390 if (*varname == '&') 13391 { 13392 long numval; 13393 char_u *strval; 13394 int error = FALSE; 13395 13396 ++varname; 13397 numval = get_tv_number_chk(varp, &error); 13398 strval = get_tv_string_buf_chk(varp, nbuf); 13399 if (!error && strval != NULL) 13400 set_option_value(varname, numval, strval, OPT_LOCAL); 13401 } 13402 else 13403 { 13404 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13405 if (winvarname != NULL) 13406 { 13407 STRCPY(winvarname, "w:"); 13408 STRCPY(winvarname + 2, varname); 13409 set_var(winvarname, varp, TRUE); 13410 vim_free(winvarname); 13411 } 13412 } 13413 13414 #ifdef FEAT_WINDOWS 13415 /* Restore current window, if it's still valid (autocomands can make 13416 * it invalid). */ 13417 if (win_valid(save_curwin)) 13418 { 13419 curwin = save_curwin; 13420 curbuf = curwin->w_buffer; 13421 } 13422 #endif 13423 } 13424 } 13425 13426 /* 13427 * "simplify()" function 13428 */ 13429 static void 13430 f_simplify(argvars, rettv) 13431 typval_T *argvars; 13432 typval_T *rettv; 13433 { 13434 char_u *p; 13435 13436 p = get_tv_string(&argvars[0]); 13437 rettv->vval.v_string = vim_strsave(p); 13438 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13439 rettv->v_type = VAR_STRING; 13440 } 13441 13442 static int 13443 #ifdef __BORLANDC__ 13444 _RTLENTRYF 13445 #endif 13446 item_compare __ARGS((const void *s1, const void *s2)); 13447 static int 13448 #ifdef __BORLANDC__ 13449 _RTLENTRYF 13450 #endif 13451 item_compare2 __ARGS((const void *s1, const void *s2)); 13452 13453 static int item_compare_ic; 13454 static char_u *item_compare_func; 13455 static int item_compare_func_err; 13456 #define ITEM_COMPARE_FAIL 999 13457 13458 /* 13459 * Compare functions for f_sort() below. 13460 */ 13461 static int 13462 #ifdef __BORLANDC__ 13463 _RTLENTRYF 13464 #endif 13465 item_compare(s1, s2) 13466 const void *s1; 13467 const void *s2; 13468 { 13469 char_u *p1, *p2; 13470 char_u *tofree1, *tofree2; 13471 int res; 13472 char_u numbuf1[NUMBUFLEN]; 13473 char_u numbuf2[NUMBUFLEN]; 13474 13475 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13476 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13477 if (item_compare_ic) 13478 res = STRICMP(p1, p2); 13479 else 13480 res = STRCMP(p1, p2); 13481 vim_free(tofree1); 13482 vim_free(tofree2); 13483 return res; 13484 } 13485 13486 static int 13487 #ifdef __BORLANDC__ 13488 _RTLENTRYF 13489 #endif 13490 item_compare2(s1, s2) 13491 const void *s1; 13492 const void *s2; 13493 { 13494 int res; 13495 typval_T rettv; 13496 typval_T argv[2]; 13497 int dummy; 13498 13499 /* shortcut after failure in previous call; compare all items equal */ 13500 if (item_compare_func_err) 13501 return 0; 13502 13503 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13504 * in the copy without changing the original list items. */ 13505 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13506 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13507 13508 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13509 res = call_func(item_compare_func, STRLEN(item_compare_func), 13510 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13511 clear_tv(&argv[0]); 13512 clear_tv(&argv[1]); 13513 13514 if (res == FAIL) 13515 res = ITEM_COMPARE_FAIL; 13516 else 13517 /* return value has wrong type */ 13518 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13519 if (item_compare_func_err) 13520 res = ITEM_COMPARE_FAIL; 13521 clear_tv(&rettv); 13522 return res; 13523 } 13524 13525 /* 13526 * "sort({list})" function 13527 */ 13528 static void 13529 f_sort(argvars, rettv) 13530 typval_T *argvars; 13531 typval_T *rettv; 13532 { 13533 list_T *l; 13534 listitem_T *li; 13535 listitem_T **ptrs; 13536 long len; 13537 long i; 13538 13539 rettv->vval.v_number = 0; 13540 if (argvars[0].v_type != VAR_LIST) 13541 EMSG2(_(e_listarg), "sort()"); 13542 else 13543 { 13544 l = argvars[0].vval.v_list; 13545 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13546 return; 13547 rettv->vval.v_list = l; 13548 rettv->v_type = VAR_LIST; 13549 ++l->lv_refcount; 13550 13551 len = list_len(l); 13552 if (len <= 1) 13553 return; /* short list sorts pretty quickly */ 13554 13555 item_compare_ic = FALSE; 13556 item_compare_func = NULL; 13557 if (argvars[1].v_type != VAR_UNKNOWN) 13558 { 13559 if (argvars[1].v_type == VAR_FUNC) 13560 item_compare_func = argvars[1].vval.v_string; 13561 else 13562 { 13563 int error = FALSE; 13564 13565 i = get_tv_number_chk(&argvars[1], &error); 13566 if (error) 13567 return; /* type error; errmsg already given */ 13568 if (i == 1) 13569 item_compare_ic = TRUE; 13570 else 13571 item_compare_func = get_tv_string(&argvars[1]); 13572 } 13573 } 13574 13575 /* Make an array with each entry pointing to an item in the List. */ 13576 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13577 if (ptrs == NULL) 13578 return; 13579 i = 0; 13580 for (li = l->lv_first; li != NULL; li = li->li_next) 13581 ptrs[i++] = li; 13582 13583 item_compare_func_err = FALSE; 13584 /* test the compare function */ 13585 if (item_compare_func != NULL 13586 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13587 == ITEM_COMPARE_FAIL) 13588 EMSG(_("E702: Sort compare function failed")); 13589 else 13590 { 13591 /* Sort the array with item pointers. */ 13592 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13593 item_compare_func == NULL ? item_compare : item_compare2); 13594 13595 if (!item_compare_func_err) 13596 { 13597 /* Clear the List and append the items in the sorted order. */ 13598 l->lv_first = l->lv_last = NULL; 13599 l->lv_len = 0; 13600 for (i = 0; i < len; ++i) 13601 list_append(l, ptrs[i]); 13602 } 13603 } 13604 13605 vim_free(ptrs); 13606 } 13607 } 13608 13609 /* 13610 * "soundfold({word})" function 13611 */ 13612 static void 13613 f_soundfold(argvars, rettv) 13614 typval_T *argvars; 13615 typval_T *rettv; 13616 { 13617 char_u *s; 13618 13619 rettv->v_type = VAR_STRING; 13620 s = get_tv_string(&argvars[0]); 13621 #ifdef FEAT_SYN_HL 13622 rettv->vval.v_string = eval_soundfold(s); 13623 #else 13624 rettv->vval.v_string = vim_strsave(s); 13625 #endif 13626 } 13627 13628 /* 13629 * "spellbadword()" function 13630 */ 13631 /* ARGSUSED */ 13632 static void 13633 f_spellbadword(argvars, rettv) 13634 typval_T *argvars; 13635 typval_T *rettv; 13636 { 13637 int attr; 13638 char_u *ptr; 13639 int len; 13640 13641 rettv->vval.v_string = NULL; 13642 rettv->v_type = VAR_STRING; 13643 13644 #ifdef FEAT_SYN_HL 13645 /* Find the start of the badly spelled word. */ 13646 if (spell_move_to(FORWARD, TRUE, TRUE) == FAIL) 13647 return; 13648 13649 /* Get the length of the word and copy it. */ 13650 ptr = ml_get_cursor(); 13651 len = spell_check(curwin, ptr, &attr, NULL); 13652 rettv->vval.v_string = vim_strnsave(ptr, len); 13653 #endif 13654 } 13655 13656 /* 13657 * "spellsuggest()" function 13658 */ 13659 static void 13660 f_spellsuggest(argvars, rettv) 13661 typval_T *argvars; 13662 typval_T *rettv; 13663 { 13664 char_u *str; 13665 int maxcount; 13666 garray_T ga; 13667 list_T *l; 13668 listitem_T *li; 13669 int i; 13670 13671 l = list_alloc(); 13672 if (l == NULL) 13673 return; 13674 rettv->v_type = VAR_LIST; 13675 rettv->vval.v_list = l; 13676 ++l->lv_refcount; 13677 13678 #ifdef FEAT_SYN_HL 13679 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13680 { 13681 str = get_tv_string(&argvars[0]); 13682 if (argvars[1].v_type != VAR_UNKNOWN) 13683 { 13684 maxcount = get_tv_number(&argvars[1]); 13685 if (maxcount <= 0) 13686 return; 13687 } 13688 else 13689 maxcount = 25; 13690 13691 spell_suggest_list(&ga, str, maxcount); 13692 13693 for (i = 0; i < ga.ga_len; ++i) 13694 { 13695 str = ((char_u **)ga.ga_data)[i]; 13696 13697 li = listitem_alloc(); 13698 if (li == NULL) 13699 vim_free(str); 13700 else 13701 { 13702 li->li_tv.v_type = VAR_STRING; 13703 li->li_tv.v_lock = 0; 13704 li->li_tv.vval.v_string = str; 13705 list_append(l, li); 13706 } 13707 } 13708 ga_clear(&ga); 13709 } 13710 #endif 13711 } 13712 13713 static void 13714 f_split(argvars, rettv) 13715 typval_T *argvars; 13716 typval_T *rettv; 13717 { 13718 char_u *str; 13719 char_u *end; 13720 char_u *pat = NULL; 13721 regmatch_T regmatch; 13722 char_u patbuf[NUMBUFLEN]; 13723 char_u *save_cpo; 13724 int match; 13725 listitem_T *ni; 13726 list_T *l; 13727 colnr_T col = 0; 13728 int keepempty = FALSE; 13729 int typeerr = FALSE; 13730 13731 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13732 save_cpo = p_cpo; 13733 p_cpo = (char_u *)""; 13734 13735 str = get_tv_string(&argvars[0]); 13736 if (argvars[1].v_type != VAR_UNKNOWN) 13737 { 13738 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13739 if (pat == NULL) 13740 typeerr = TRUE; 13741 if (argvars[2].v_type != VAR_UNKNOWN) 13742 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 13743 } 13744 if (pat == NULL || *pat == NUL) 13745 pat = (char_u *)"[\\x01- ]\\+"; 13746 13747 l = list_alloc(); 13748 if (l == NULL) 13749 return; 13750 rettv->v_type = VAR_LIST; 13751 rettv->vval.v_list = l; 13752 ++l->lv_refcount; 13753 if (typeerr) 13754 return; 13755 13756 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13757 if (regmatch.regprog != NULL) 13758 { 13759 regmatch.rm_ic = FALSE; 13760 while (*str != NUL || keepempty) 13761 { 13762 if (*str == NUL) 13763 match = FALSE; /* empty item at the end */ 13764 else 13765 match = vim_regexec_nl(®match, str, col); 13766 if (match) 13767 end = regmatch.startp[0]; 13768 else 13769 end = str + STRLEN(str); 13770 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 13771 && match && end < regmatch.endp[0])) 13772 { 13773 ni = listitem_alloc(); 13774 if (ni == NULL) 13775 break; 13776 ni->li_tv.v_type = VAR_STRING; 13777 ni->li_tv.v_lock = 0; 13778 ni->li_tv.vval.v_string = vim_strnsave(str, end - str); 13779 list_append(l, ni); 13780 } 13781 if (!match) 13782 break; 13783 /* Advance to just after the match. */ 13784 if (regmatch.endp[0] > str) 13785 col = 0; 13786 else 13787 { 13788 /* Don't get stuck at the same match. */ 13789 #ifdef FEAT_MBYTE 13790 col = mb_ptr2len_check(regmatch.endp[0]); 13791 #else 13792 col = 1; 13793 #endif 13794 } 13795 str = regmatch.endp[0]; 13796 } 13797 13798 vim_free(regmatch.regprog); 13799 } 13800 13801 p_cpo = save_cpo; 13802 } 13803 13804 #ifdef HAVE_STRFTIME 13805 /* 13806 * "strftime({format}[, {time}])" function 13807 */ 13808 static void 13809 f_strftime(argvars, rettv) 13810 typval_T *argvars; 13811 typval_T *rettv; 13812 { 13813 char_u result_buf[256]; 13814 struct tm *curtime; 13815 time_t seconds; 13816 char_u *p; 13817 13818 rettv->v_type = VAR_STRING; 13819 13820 p = get_tv_string(&argvars[0]); 13821 if (argvars[1].v_type == VAR_UNKNOWN) 13822 seconds = time(NULL); 13823 else 13824 seconds = (time_t)get_tv_number(&argvars[1]); 13825 curtime = localtime(&seconds); 13826 /* MSVC returns NULL for an invalid value of seconds. */ 13827 if (curtime == NULL) 13828 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 13829 else 13830 { 13831 # ifdef FEAT_MBYTE 13832 vimconv_T conv; 13833 char_u *enc; 13834 13835 conv.vc_type = CONV_NONE; 13836 enc = enc_locale(); 13837 convert_setup(&conv, p_enc, enc); 13838 if (conv.vc_type != CONV_NONE) 13839 p = string_convert(&conv, p, NULL); 13840 # endif 13841 if (p != NULL) 13842 (void)strftime((char *)result_buf, sizeof(result_buf), 13843 (char *)p, curtime); 13844 else 13845 result_buf[0] = NUL; 13846 13847 # ifdef FEAT_MBYTE 13848 if (conv.vc_type != CONV_NONE) 13849 vim_free(p); 13850 convert_setup(&conv, enc, p_enc); 13851 if (conv.vc_type != CONV_NONE) 13852 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 13853 else 13854 # endif 13855 rettv->vval.v_string = vim_strsave(result_buf); 13856 13857 # ifdef FEAT_MBYTE 13858 /* Release conversion descriptors */ 13859 convert_setup(&conv, NULL, NULL); 13860 vim_free(enc); 13861 # endif 13862 } 13863 } 13864 #endif 13865 13866 /* 13867 * "stridx()" function 13868 */ 13869 static void 13870 f_stridx(argvars, rettv) 13871 typval_T *argvars; 13872 typval_T *rettv; 13873 { 13874 char_u buf[NUMBUFLEN]; 13875 char_u *needle; 13876 char_u *haystack; 13877 char_u *save_haystack; 13878 char_u *pos; 13879 int start_idx; 13880 13881 needle = get_tv_string_chk(&argvars[1]); 13882 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 13883 rettv->vval.v_number = -1; 13884 if (needle == NULL || haystack == NULL) 13885 return; /* type error; errmsg already given */ 13886 13887 if (argvars[2].v_type != VAR_UNKNOWN) 13888 { 13889 int error = FALSE; 13890 13891 start_idx = get_tv_number_chk(&argvars[2], &error); 13892 if (error || start_idx >= (int)STRLEN(haystack)) 13893 return; 13894 if (start_idx >= 0) 13895 haystack += start_idx; 13896 } 13897 13898 pos = (char_u *)strstr((char *)haystack, (char *)needle); 13899 if (pos != NULL) 13900 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 13901 } 13902 13903 /* 13904 * "string()" function 13905 */ 13906 static void 13907 f_string(argvars, rettv) 13908 typval_T *argvars; 13909 typval_T *rettv; 13910 { 13911 char_u *tofree; 13912 char_u numbuf[NUMBUFLEN]; 13913 13914 rettv->v_type = VAR_STRING; 13915 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 13916 if (tofree == NULL) 13917 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 13918 } 13919 13920 /* 13921 * "strlen()" function 13922 */ 13923 static void 13924 f_strlen(argvars, rettv) 13925 typval_T *argvars; 13926 typval_T *rettv; 13927 { 13928 rettv->vval.v_number = (varnumber_T)(STRLEN( 13929 get_tv_string(&argvars[0]))); 13930 } 13931 13932 /* 13933 * "strpart()" function 13934 */ 13935 static void 13936 f_strpart(argvars, rettv) 13937 typval_T *argvars; 13938 typval_T *rettv; 13939 { 13940 char_u *p; 13941 int n; 13942 int len; 13943 int slen; 13944 int error = FALSE; 13945 13946 p = get_tv_string(&argvars[0]); 13947 slen = (int)STRLEN(p); 13948 13949 n = get_tv_number_chk(&argvars[1], &error); 13950 if (error) 13951 len = 0; 13952 else if (argvars[2].v_type != VAR_UNKNOWN) 13953 len = get_tv_number(&argvars[2]); 13954 else 13955 len = slen - n; /* default len: all bytes that are available. */ 13956 13957 /* 13958 * Only return the overlap between the specified part and the actual 13959 * string. 13960 */ 13961 if (n < 0) 13962 { 13963 len += n; 13964 n = 0; 13965 } 13966 else if (n > slen) 13967 n = slen; 13968 if (len < 0) 13969 len = 0; 13970 else if (n + len > slen) 13971 len = slen - n; 13972 13973 rettv->v_type = VAR_STRING; 13974 rettv->vval.v_string = vim_strnsave(p + n, len); 13975 } 13976 13977 /* 13978 * "strridx()" function 13979 */ 13980 static void 13981 f_strridx(argvars, rettv) 13982 typval_T *argvars; 13983 typval_T *rettv; 13984 { 13985 char_u buf[NUMBUFLEN]; 13986 char_u *needle; 13987 char_u *haystack; 13988 char_u *rest; 13989 char_u *lastmatch = NULL; 13990 int haystack_len, end_idx; 13991 13992 needle = get_tv_string_chk(&argvars[1]); 13993 haystack = get_tv_string_buf_chk(&argvars[0], buf); 13994 haystack_len = STRLEN(haystack); 13995 13996 rettv->vval.v_number = -1; 13997 if (needle == NULL || haystack == NULL) 13998 return; /* type error; errmsg already given */ 13999 if (argvars[2].v_type != VAR_UNKNOWN) 14000 { 14001 /* Third argument: upper limit for index */ 14002 end_idx = get_tv_number_chk(&argvars[2], NULL); 14003 if (end_idx < 0) 14004 return; /* can never find a match */ 14005 } 14006 else 14007 end_idx = haystack_len; 14008 14009 if (*needle == NUL) 14010 { 14011 /* Empty string matches past the end. */ 14012 lastmatch = haystack + end_idx; 14013 } 14014 else 14015 { 14016 for (rest = haystack; *rest != '\0'; ++rest) 14017 { 14018 rest = (char_u *)strstr((char *)rest, (char *)needle); 14019 if (rest == NULL || rest > haystack + end_idx) 14020 break; 14021 lastmatch = rest; 14022 } 14023 } 14024 14025 if (lastmatch == NULL) 14026 rettv->vval.v_number = -1; 14027 else 14028 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14029 } 14030 14031 /* 14032 * "strtrans()" function 14033 */ 14034 static void 14035 f_strtrans(argvars, rettv) 14036 typval_T *argvars; 14037 typval_T *rettv; 14038 { 14039 rettv->v_type = VAR_STRING; 14040 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14041 } 14042 14043 /* 14044 * "submatch()" function 14045 */ 14046 static void 14047 f_submatch(argvars, rettv) 14048 typval_T *argvars; 14049 typval_T *rettv; 14050 { 14051 rettv->v_type = VAR_STRING; 14052 rettv->vval.v_string = 14053 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14054 } 14055 14056 /* 14057 * "substitute()" function 14058 */ 14059 static void 14060 f_substitute(argvars, rettv) 14061 typval_T *argvars; 14062 typval_T *rettv; 14063 { 14064 char_u patbuf[NUMBUFLEN]; 14065 char_u subbuf[NUMBUFLEN]; 14066 char_u flagsbuf[NUMBUFLEN]; 14067 14068 char_u *str = get_tv_string_chk(&argvars[0]); 14069 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14070 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14071 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14072 14073 rettv->v_type = VAR_STRING; 14074 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14075 rettv->vval.v_string = NULL; 14076 else 14077 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14078 } 14079 14080 /* 14081 * "synID(lnum, col, trans)" function 14082 */ 14083 /*ARGSUSED*/ 14084 static void 14085 f_synID(argvars, rettv) 14086 typval_T *argvars; 14087 typval_T *rettv; 14088 { 14089 int id = 0; 14090 #ifdef FEAT_SYN_HL 14091 long lnum; 14092 long col; 14093 int trans; 14094 int transerr = FALSE; 14095 14096 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14097 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14098 trans = get_tv_number_chk(&argvars[2], &transerr); 14099 14100 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14101 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14102 id = syn_get_id(lnum, (colnr_T)col, trans, NULL); 14103 #endif 14104 14105 rettv->vval.v_number = id; 14106 } 14107 14108 /* 14109 * "synIDattr(id, what [, mode])" function 14110 */ 14111 /*ARGSUSED*/ 14112 static void 14113 f_synIDattr(argvars, rettv) 14114 typval_T *argvars; 14115 typval_T *rettv; 14116 { 14117 char_u *p = NULL; 14118 #ifdef FEAT_SYN_HL 14119 int id; 14120 char_u *what; 14121 char_u *mode; 14122 char_u modebuf[NUMBUFLEN]; 14123 int modec; 14124 14125 id = get_tv_number(&argvars[0]); 14126 what = get_tv_string(&argvars[1]); 14127 if (argvars[2].v_type != VAR_UNKNOWN) 14128 { 14129 mode = get_tv_string_buf(&argvars[2], modebuf); 14130 modec = TOLOWER_ASC(mode[0]); 14131 if (modec != 't' && modec != 'c' 14132 #ifdef FEAT_GUI 14133 && modec != 'g' 14134 #endif 14135 ) 14136 modec = 0; /* replace invalid with current */ 14137 } 14138 else 14139 { 14140 #ifdef FEAT_GUI 14141 if (gui.in_use) 14142 modec = 'g'; 14143 else 14144 #endif 14145 if (t_colors > 1) 14146 modec = 'c'; 14147 else 14148 modec = 't'; 14149 } 14150 14151 14152 switch (TOLOWER_ASC(what[0])) 14153 { 14154 case 'b': 14155 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14156 p = highlight_color(id, what, modec); 14157 else /* bold */ 14158 p = highlight_has_attr(id, HL_BOLD, modec); 14159 break; 14160 14161 case 'f': /* fg[#] */ 14162 p = highlight_color(id, what, modec); 14163 break; 14164 14165 case 'i': 14166 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14167 p = highlight_has_attr(id, HL_INVERSE, modec); 14168 else /* italic */ 14169 p = highlight_has_attr(id, HL_ITALIC, modec); 14170 break; 14171 14172 case 'n': /* name */ 14173 p = get_highlight_name(NULL, id - 1); 14174 break; 14175 14176 case 'r': /* reverse */ 14177 p = highlight_has_attr(id, HL_INVERSE, modec); 14178 break; 14179 14180 case 's': /* standout */ 14181 p = highlight_has_attr(id, HL_STANDOUT, modec); 14182 break; 14183 14184 case 'u': 14185 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14186 /* underline */ 14187 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14188 else 14189 /* undercurl */ 14190 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14191 break; 14192 } 14193 14194 if (p != NULL) 14195 p = vim_strsave(p); 14196 #endif 14197 rettv->v_type = VAR_STRING; 14198 rettv->vval.v_string = p; 14199 } 14200 14201 /* 14202 * "synIDtrans(id)" function 14203 */ 14204 /*ARGSUSED*/ 14205 static void 14206 f_synIDtrans(argvars, rettv) 14207 typval_T *argvars; 14208 typval_T *rettv; 14209 { 14210 int id; 14211 14212 #ifdef FEAT_SYN_HL 14213 id = get_tv_number(&argvars[0]); 14214 14215 if (id > 0) 14216 id = syn_get_final_id(id); 14217 else 14218 #endif 14219 id = 0; 14220 14221 rettv->vval.v_number = id; 14222 } 14223 14224 /* 14225 * "system()" function 14226 */ 14227 static void 14228 f_system(argvars, rettv) 14229 typval_T *argvars; 14230 typval_T *rettv; 14231 { 14232 char_u *res = NULL; 14233 char_u *p; 14234 char_u *infile = NULL; 14235 char_u buf[NUMBUFLEN]; 14236 int err = FALSE; 14237 FILE *fd; 14238 14239 if (argvars[1].v_type != VAR_UNKNOWN) 14240 { 14241 /* 14242 * Write the string to a temp file, to be used for input of the shell 14243 * command. 14244 */ 14245 if ((infile = vim_tempname('i')) == NULL) 14246 { 14247 EMSG(_(e_notmp)); 14248 return; 14249 } 14250 14251 fd = mch_fopen((char *)infile, WRITEBIN); 14252 if (fd == NULL) 14253 { 14254 EMSG2(_(e_notopen), infile); 14255 goto done; 14256 } 14257 p = get_tv_string_buf_chk(&argvars[1], buf); 14258 if (p == NULL) 14259 goto done; /* type error; errmsg already given */ 14260 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14261 err = TRUE; 14262 if (fclose(fd) != 0) 14263 err = TRUE; 14264 if (err) 14265 { 14266 EMSG(_("E677: Error writing temp file")); 14267 goto done; 14268 } 14269 } 14270 14271 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14272 14273 #ifdef USE_CR 14274 /* translate <CR> into <NL> */ 14275 if (res != NULL) 14276 { 14277 char_u *s; 14278 14279 for (s = res; *s; ++s) 14280 { 14281 if (*s == CAR) 14282 *s = NL; 14283 } 14284 } 14285 #else 14286 # ifdef USE_CRNL 14287 /* translate <CR><NL> into <NL> */ 14288 if (res != NULL) 14289 { 14290 char_u *s, *d; 14291 14292 d = res; 14293 for (s = res; *s; ++s) 14294 { 14295 if (s[0] == CAR && s[1] == NL) 14296 ++s; 14297 *d++ = *s; 14298 } 14299 *d = NUL; 14300 } 14301 # endif 14302 #endif 14303 14304 done: 14305 if (infile != NULL) 14306 { 14307 mch_remove(infile); 14308 vim_free(infile); 14309 } 14310 rettv->v_type = VAR_STRING; 14311 rettv->vval.v_string = res; 14312 } 14313 14314 /* 14315 * "taglist()" function 14316 */ 14317 static void 14318 f_taglist(argvars, rettv) 14319 typval_T *argvars; 14320 typval_T *rettv; 14321 { 14322 char_u *tag_pattern; 14323 list_T *l; 14324 14325 tag_pattern = get_tv_string(&argvars[0]); 14326 14327 rettv->vval.v_number = FALSE; 14328 if (*tag_pattern == NUL) 14329 return; 14330 14331 l = list_alloc(); 14332 if (l != NULL) 14333 { 14334 if (get_tags(l, tag_pattern) != FAIL) 14335 { 14336 rettv->vval.v_list = l; 14337 rettv->v_type = VAR_LIST; 14338 ++l->lv_refcount; 14339 } 14340 else 14341 list_free(l); 14342 } 14343 } 14344 14345 /* 14346 * "tempname()" function 14347 */ 14348 /*ARGSUSED*/ 14349 static void 14350 f_tempname(argvars, rettv) 14351 typval_T *argvars; 14352 typval_T *rettv; 14353 { 14354 static int x = 'A'; 14355 14356 rettv->v_type = VAR_STRING; 14357 rettv->vval.v_string = vim_tempname(x); 14358 14359 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14360 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14361 do 14362 { 14363 if (x == 'Z') 14364 x = '0'; 14365 else if (x == '9') 14366 x = 'A'; 14367 else 14368 { 14369 #ifdef EBCDIC 14370 if (x == 'I') 14371 x = 'J'; 14372 else if (x == 'R') 14373 x = 'S'; 14374 else 14375 #endif 14376 ++x; 14377 } 14378 } while (x == 'I' || x == 'O'); 14379 } 14380 14381 /* 14382 * "tolower(string)" function 14383 */ 14384 static void 14385 f_tolower(argvars, rettv) 14386 typval_T *argvars; 14387 typval_T *rettv; 14388 { 14389 char_u *p; 14390 14391 p = vim_strsave(get_tv_string(&argvars[0])); 14392 rettv->v_type = VAR_STRING; 14393 rettv->vval.v_string = p; 14394 14395 if (p != NULL) 14396 while (*p != NUL) 14397 { 14398 #ifdef FEAT_MBYTE 14399 int l; 14400 14401 if (enc_utf8) 14402 { 14403 int c, lc; 14404 14405 c = utf_ptr2char(p); 14406 lc = utf_tolower(c); 14407 l = utf_ptr2len_check(p); 14408 /* TODO: reallocate string when byte count changes. */ 14409 if (utf_char2len(lc) == l) 14410 utf_char2bytes(lc, p); 14411 p += l; 14412 } 14413 else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1) 14414 p += l; /* skip multi-byte character */ 14415 else 14416 #endif 14417 { 14418 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14419 ++p; 14420 } 14421 } 14422 } 14423 14424 /* 14425 * "toupper(string)" function 14426 */ 14427 static void 14428 f_toupper(argvars, rettv) 14429 typval_T *argvars; 14430 typval_T *rettv; 14431 { 14432 rettv->v_type = VAR_STRING; 14433 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14434 } 14435 14436 /* 14437 * "tr(string, fromstr, tostr)" function 14438 */ 14439 static void 14440 f_tr(argvars, rettv) 14441 typval_T *argvars; 14442 typval_T *rettv; 14443 { 14444 char_u *instr; 14445 char_u *fromstr; 14446 char_u *tostr; 14447 char_u *p; 14448 #ifdef FEAT_MBYTE 14449 int inlen; 14450 int fromlen; 14451 int tolen; 14452 int idx; 14453 char_u *cpstr; 14454 int cplen; 14455 int first = TRUE; 14456 #endif 14457 char_u buf[NUMBUFLEN]; 14458 char_u buf2[NUMBUFLEN]; 14459 garray_T ga; 14460 14461 instr = get_tv_string(&argvars[0]); 14462 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14463 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14464 14465 /* Default return value: empty string. */ 14466 rettv->v_type = VAR_STRING; 14467 rettv->vval.v_string = NULL; 14468 if (fromstr == NULL || tostr == NULL) 14469 return; /* type error; errmsg already given */ 14470 ga_init2(&ga, (int)sizeof(char), 80); 14471 14472 #ifdef FEAT_MBYTE 14473 if (!has_mbyte) 14474 #endif 14475 /* not multi-byte: fromstr and tostr must be the same length */ 14476 if (STRLEN(fromstr) != STRLEN(tostr)) 14477 { 14478 #ifdef FEAT_MBYTE 14479 error: 14480 #endif 14481 EMSG2(_(e_invarg2), fromstr); 14482 ga_clear(&ga); 14483 return; 14484 } 14485 14486 /* fromstr and tostr have to contain the same number of chars */ 14487 while (*instr != NUL) 14488 { 14489 #ifdef FEAT_MBYTE 14490 if (has_mbyte) 14491 { 14492 inlen = mb_ptr2len_check(instr); 14493 cpstr = instr; 14494 cplen = inlen; 14495 idx = 0; 14496 for (p = fromstr; *p != NUL; p += fromlen) 14497 { 14498 fromlen = mb_ptr2len_check(p); 14499 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14500 { 14501 for (p = tostr; *p != NUL; p += tolen) 14502 { 14503 tolen = mb_ptr2len_check(p); 14504 if (idx-- == 0) 14505 { 14506 cplen = tolen; 14507 cpstr = p; 14508 break; 14509 } 14510 } 14511 if (*p == NUL) /* tostr is shorter than fromstr */ 14512 goto error; 14513 break; 14514 } 14515 ++idx; 14516 } 14517 14518 if (first && cpstr == instr) 14519 { 14520 /* Check that fromstr and tostr have the same number of 14521 * (multi-byte) characters. Done only once when a character 14522 * of instr doesn't appear in fromstr. */ 14523 first = FALSE; 14524 for (p = tostr; *p != NUL; p += tolen) 14525 { 14526 tolen = mb_ptr2len_check(p); 14527 --idx; 14528 } 14529 if (idx != 0) 14530 goto error; 14531 } 14532 14533 ga_grow(&ga, cplen); 14534 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14535 ga.ga_len += cplen; 14536 14537 instr += inlen; 14538 } 14539 else 14540 #endif 14541 { 14542 /* When not using multi-byte chars we can do it faster. */ 14543 p = vim_strchr(fromstr, *instr); 14544 if (p != NULL) 14545 ga_append(&ga, tostr[p - fromstr]); 14546 else 14547 ga_append(&ga, *instr); 14548 ++instr; 14549 } 14550 } 14551 14552 rettv->vval.v_string = ga.ga_data; 14553 } 14554 14555 /* 14556 * "type(expr)" function 14557 */ 14558 static void 14559 f_type(argvars, rettv) 14560 typval_T *argvars; 14561 typval_T *rettv; 14562 { 14563 int n; 14564 14565 switch (argvars[0].v_type) 14566 { 14567 case VAR_NUMBER: n = 0; break; 14568 case VAR_STRING: n = 1; break; 14569 case VAR_FUNC: n = 2; break; 14570 case VAR_LIST: n = 3; break; 14571 case VAR_DICT: n = 4; break; 14572 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14573 } 14574 rettv->vval.v_number = n; 14575 } 14576 14577 /* 14578 * "values(dict)" function 14579 */ 14580 static void 14581 f_values(argvars, rettv) 14582 typval_T *argvars; 14583 typval_T *rettv; 14584 { 14585 dict_list(argvars, rettv, 1); 14586 } 14587 14588 /* 14589 * "virtcol(string)" function 14590 */ 14591 static void 14592 f_virtcol(argvars, rettv) 14593 typval_T *argvars; 14594 typval_T *rettv; 14595 { 14596 colnr_T vcol = 0; 14597 pos_T *fp; 14598 14599 fp = var2fpos(&argvars[0], FALSE); 14600 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14601 { 14602 getvvcol(curwin, fp, NULL, NULL, &vcol); 14603 ++vcol; 14604 } 14605 14606 rettv->vval.v_number = vcol; 14607 } 14608 14609 /* 14610 * "visualmode()" function 14611 */ 14612 /*ARGSUSED*/ 14613 static void 14614 f_visualmode(argvars, rettv) 14615 typval_T *argvars; 14616 typval_T *rettv; 14617 { 14618 #ifdef FEAT_VISUAL 14619 char_u str[2]; 14620 14621 rettv->v_type = VAR_STRING; 14622 str[0] = curbuf->b_visual_mode_eval; 14623 str[1] = NUL; 14624 rettv->vval.v_string = vim_strsave(str); 14625 14626 /* A non-zero number or non-empty string argument: reset mode. */ 14627 if ((argvars[0].v_type == VAR_NUMBER 14628 && argvars[0].vval.v_number != 0) 14629 || (argvars[0].v_type == VAR_STRING 14630 && *get_tv_string(&argvars[0]) != NUL)) 14631 curbuf->b_visual_mode_eval = NUL; 14632 #else 14633 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14634 #endif 14635 } 14636 14637 /* 14638 * "winbufnr(nr)" function 14639 */ 14640 static void 14641 f_winbufnr(argvars, rettv) 14642 typval_T *argvars; 14643 typval_T *rettv; 14644 { 14645 win_T *wp; 14646 14647 wp = find_win_by_nr(&argvars[0]); 14648 if (wp == NULL) 14649 rettv->vval.v_number = -1; 14650 else 14651 rettv->vval.v_number = wp->w_buffer->b_fnum; 14652 } 14653 14654 /* 14655 * "wincol()" function 14656 */ 14657 /*ARGSUSED*/ 14658 static void 14659 f_wincol(argvars, rettv) 14660 typval_T *argvars; 14661 typval_T *rettv; 14662 { 14663 validate_cursor(); 14664 rettv->vval.v_number = curwin->w_wcol + 1; 14665 } 14666 14667 /* 14668 * "winheight(nr)" function 14669 */ 14670 static void 14671 f_winheight(argvars, rettv) 14672 typval_T *argvars; 14673 typval_T *rettv; 14674 { 14675 win_T *wp; 14676 14677 wp = find_win_by_nr(&argvars[0]); 14678 if (wp == NULL) 14679 rettv->vval.v_number = -1; 14680 else 14681 rettv->vval.v_number = wp->w_height; 14682 } 14683 14684 /* 14685 * "winline()" function 14686 */ 14687 /*ARGSUSED*/ 14688 static void 14689 f_winline(argvars, rettv) 14690 typval_T *argvars; 14691 typval_T *rettv; 14692 { 14693 validate_cursor(); 14694 rettv->vval.v_number = curwin->w_wrow + 1; 14695 } 14696 14697 /* 14698 * "winnr()" function 14699 */ 14700 /* ARGSUSED */ 14701 static void 14702 f_winnr(argvars, rettv) 14703 typval_T *argvars; 14704 typval_T *rettv; 14705 { 14706 int nr = 1; 14707 #ifdef FEAT_WINDOWS 14708 win_T *wp; 14709 win_T *twin = curwin; 14710 char_u *arg; 14711 14712 if (argvars[0].v_type != VAR_UNKNOWN) 14713 { 14714 arg = get_tv_string_chk(&argvars[0]); 14715 if (arg == NULL) 14716 nr = 0; /* type error; errmsg already given */ 14717 else if (STRCMP(arg, "$") == 0) 14718 twin = lastwin; 14719 else if (STRCMP(arg, "#") == 0) 14720 { 14721 twin = prevwin; 14722 if (prevwin == NULL) 14723 nr = 0; 14724 } 14725 else 14726 { 14727 EMSG2(_(e_invexpr2), arg); 14728 nr = 0; 14729 } 14730 } 14731 14732 if (nr > 0) 14733 for (wp = firstwin; wp != twin; wp = wp->w_next) 14734 ++nr; 14735 #endif 14736 rettv->vval.v_number = nr; 14737 } 14738 14739 /* 14740 * "winrestcmd()" function 14741 */ 14742 /* ARGSUSED */ 14743 static void 14744 f_winrestcmd(argvars, rettv) 14745 typval_T *argvars; 14746 typval_T *rettv; 14747 { 14748 #ifdef FEAT_WINDOWS 14749 win_T *wp; 14750 int winnr = 1; 14751 garray_T ga; 14752 char_u buf[50]; 14753 14754 ga_init2(&ga, (int)sizeof(char), 70); 14755 for (wp = firstwin; wp != NULL; wp = wp->w_next) 14756 { 14757 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 14758 ga_concat(&ga, buf); 14759 # ifdef FEAT_VERTSPLIT 14760 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 14761 ga_concat(&ga, buf); 14762 # endif 14763 ++winnr; 14764 } 14765 ga_append(&ga, NUL); 14766 14767 rettv->vval.v_string = ga.ga_data; 14768 #else 14769 rettv->vval.v_string = NULL; 14770 #endif 14771 rettv->v_type = VAR_STRING; 14772 } 14773 14774 /* 14775 * "winwidth(nr)" function 14776 */ 14777 static void 14778 f_winwidth(argvars, rettv) 14779 typval_T *argvars; 14780 typval_T *rettv; 14781 { 14782 win_T *wp; 14783 14784 wp = find_win_by_nr(&argvars[0]); 14785 if (wp == NULL) 14786 rettv->vval.v_number = -1; 14787 else 14788 #ifdef FEAT_VERTSPLIT 14789 rettv->vval.v_number = wp->w_width; 14790 #else 14791 rettv->vval.v_number = Columns; 14792 #endif 14793 } 14794 14795 /* 14796 * "writefile()" function 14797 */ 14798 static void 14799 f_writefile(argvars, rettv) 14800 typval_T *argvars; 14801 typval_T *rettv; 14802 { 14803 int binary = FALSE; 14804 char_u *fname; 14805 FILE *fd; 14806 listitem_T *li; 14807 char_u *s; 14808 int ret = 0; 14809 int c; 14810 14811 if (argvars[0].v_type != VAR_LIST) 14812 { 14813 EMSG2(_(e_listarg), "writefile()"); 14814 return; 14815 } 14816 if (argvars[0].vval.v_list == NULL) 14817 return; 14818 14819 if (argvars[2].v_type != VAR_UNKNOWN 14820 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 14821 binary = TRUE; 14822 14823 /* Always open the file in binary mode, library functions have a mind of 14824 * their own about CR-LF conversion. */ 14825 fname = get_tv_string(&argvars[1]); 14826 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 14827 { 14828 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 14829 ret = -1; 14830 } 14831 else 14832 { 14833 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 14834 li = li->li_next) 14835 { 14836 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 14837 { 14838 if (*s == '\n') 14839 c = putc(NUL, fd); 14840 else 14841 c = putc(*s, fd); 14842 if (c == EOF) 14843 { 14844 ret = -1; 14845 break; 14846 } 14847 } 14848 if (!binary || li->li_next != NULL) 14849 if (putc('\n', fd) == EOF) 14850 { 14851 ret = -1; 14852 break; 14853 } 14854 if (ret < 0) 14855 { 14856 EMSG(_(e_write)); 14857 break; 14858 } 14859 } 14860 fclose(fd); 14861 } 14862 14863 rettv->vval.v_number = ret; 14864 } 14865 14866 /* 14867 * Translate a String variable into a position. 14868 */ 14869 static pos_T * 14870 var2fpos(varp, lnum) 14871 typval_T *varp; 14872 int lnum; /* TRUE when $ is last line */ 14873 { 14874 char_u *name; 14875 static pos_T pos; 14876 pos_T *pp; 14877 14878 name = get_tv_string_chk(varp); 14879 if (name == NULL) 14880 return NULL; 14881 if (name[0] == '.') /* cursor */ 14882 return &curwin->w_cursor; 14883 if (name[0] == '\'') /* mark */ 14884 { 14885 pp = getmark(name[1], FALSE); 14886 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 14887 return NULL; 14888 return pp; 14889 } 14890 if (name[0] == '$') /* last column or line */ 14891 { 14892 if (lnum) 14893 { 14894 pos.lnum = curbuf->b_ml.ml_line_count; 14895 pos.col = 0; 14896 } 14897 else 14898 { 14899 pos.lnum = curwin->w_cursor.lnum; 14900 pos.col = (colnr_T)STRLEN(ml_get_curline()); 14901 } 14902 return &pos; 14903 } 14904 return NULL; 14905 } 14906 14907 /* 14908 * Get the length of an environment variable name. 14909 * Advance "arg" to the first character after the name. 14910 * Return 0 for error. 14911 */ 14912 static int 14913 get_env_len(arg) 14914 char_u **arg; 14915 { 14916 char_u *p; 14917 int len; 14918 14919 for (p = *arg; vim_isIDc(*p); ++p) 14920 ; 14921 if (p == *arg) /* no name found */ 14922 return 0; 14923 14924 len = (int)(p - *arg); 14925 *arg = p; 14926 return len; 14927 } 14928 14929 /* 14930 * Get the length of the name of a function or internal variable. 14931 * "arg" is advanced to the first non-white character after the name. 14932 * Return 0 if something is wrong. 14933 */ 14934 static int 14935 get_id_len(arg) 14936 char_u **arg; 14937 { 14938 char_u *p; 14939 int len; 14940 14941 /* Find the end of the name. */ 14942 for (p = *arg; eval_isnamec(*p); ++p) 14943 ; 14944 if (p == *arg) /* no name found */ 14945 return 0; 14946 14947 len = (int)(p - *arg); 14948 *arg = skipwhite(p); 14949 14950 return len; 14951 } 14952 14953 /* 14954 * Get the length of the name of a variable or function. 14955 * Only the name is recognized, does not handle ".key" or "[idx]". 14956 * "arg" is advanced to the first non-white character after the name. 14957 * Return -1 if curly braces expansion failed. 14958 * Return 0 if something else is wrong. 14959 * If the name contains 'magic' {}'s, expand them and return the 14960 * expanded name in an allocated string via 'alias' - caller must free. 14961 */ 14962 static int 14963 get_name_len(arg, alias, evaluate, verbose) 14964 char_u **arg; 14965 char_u **alias; 14966 int evaluate; 14967 int verbose; 14968 { 14969 int len; 14970 char_u *p; 14971 char_u *expr_start; 14972 char_u *expr_end; 14973 14974 *alias = NULL; /* default to no alias */ 14975 14976 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 14977 && (*arg)[2] == (int)KE_SNR) 14978 { 14979 /* hard coded <SNR>, already translated */ 14980 *arg += 3; 14981 return get_id_len(arg) + 3; 14982 } 14983 len = eval_fname_script(*arg); 14984 if (len > 0) 14985 { 14986 /* literal "<SID>", "s:" or "<SNR>" */ 14987 *arg += len; 14988 } 14989 14990 /* 14991 * Find the end of the name; check for {} construction. 14992 */ 14993 p = find_name_end(*arg, &expr_start, &expr_end, 14994 len > 0 ? 0 : FNE_CHECK_START); 14995 if (expr_start != NULL) 14996 { 14997 char_u *temp_string; 14998 14999 if (!evaluate) 15000 { 15001 len += (int)(p - *arg); 15002 *arg = skipwhite(p); 15003 return len; 15004 } 15005 15006 /* 15007 * Include any <SID> etc in the expanded string: 15008 * Thus the -len here. 15009 */ 15010 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15011 if (temp_string == NULL) 15012 return -1; 15013 *alias = temp_string; 15014 *arg = skipwhite(p); 15015 return (int)STRLEN(temp_string); 15016 } 15017 15018 len += get_id_len(arg); 15019 if (len == 0 && verbose) 15020 EMSG2(_(e_invexpr2), *arg); 15021 15022 return len; 15023 } 15024 15025 /* 15026 * Find the end of a variable or function name, taking care of magic braces. 15027 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15028 * start and end of the first magic braces item. 15029 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15030 * Return a pointer to just after the name. Equal to "arg" if there is no 15031 * valid name. 15032 */ 15033 static char_u * 15034 find_name_end(arg, expr_start, expr_end, flags) 15035 char_u *arg; 15036 char_u **expr_start; 15037 char_u **expr_end; 15038 int flags; 15039 { 15040 int mb_nest = 0; 15041 int br_nest = 0; 15042 char_u *p; 15043 15044 if (expr_start != NULL) 15045 { 15046 *expr_start = NULL; 15047 *expr_end = NULL; 15048 } 15049 15050 /* Quick check for valid starting character. */ 15051 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15052 return arg; 15053 15054 for (p = arg; *p != NUL 15055 && (eval_isnamec(*p) 15056 || *p == '{' 15057 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15058 || mb_nest != 0 15059 || br_nest != 0); ++p) 15060 { 15061 if (mb_nest == 0) 15062 { 15063 if (*p == '[') 15064 ++br_nest; 15065 else if (*p == ']') 15066 --br_nest; 15067 } 15068 if (br_nest == 0) 15069 { 15070 if (*p == '{') 15071 { 15072 mb_nest++; 15073 if (expr_start != NULL && *expr_start == NULL) 15074 *expr_start = p; 15075 } 15076 else if (*p == '}') 15077 { 15078 mb_nest--; 15079 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15080 *expr_end = p; 15081 } 15082 } 15083 } 15084 15085 return p; 15086 } 15087 15088 /* 15089 * Expands out the 'magic' {}'s in a variable/function name. 15090 * Note that this can call itself recursively, to deal with 15091 * constructs like foo{bar}{baz}{bam} 15092 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15093 * "in_start" ^ 15094 * "expr_start" ^ 15095 * "expr_end" ^ 15096 * "in_end" ^ 15097 * 15098 * Returns a new allocated string, which the caller must free. 15099 * Returns NULL for failure. 15100 */ 15101 static char_u * 15102 make_expanded_name(in_start, expr_start, expr_end, in_end) 15103 char_u *in_start; 15104 char_u *expr_start; 15105 char_u *expr_end; 15106 char_u *in_end; 15107 { 15108 char_u c1; 15109 char_u *retval = NULL; 15110 char_u *temp_result; 15111 char_u *nextcmd = NULL; 15112 15113 if (expr_end == NULL || in_end == NULL) 15114 return NULL; 15115 *expr_start = NUL; 15116 *expr_end = NUL; 15117 c1 = *in_end; 15118 *in_end = NUL; 15119 15120 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15121 if (temp_result != NULL && nextcmd == NULL) 15122 { 15123 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15124 + (in_end - expr_end) + 1)); 15125 if (retval != NULL) 15126 { 15127 STRCPY(retval, in_start); 15128 STRCAT(retval, temp_result); 15129 STRCAT(retval, expr_end + 1); 15130 } 15131 } 15132 vim_free(temp_result); 15133 15134 *in_end = c1; /* put char back for error messages */ 15135 *expr_start = '{'; 15136 *expr_end = '}'; 15137 15138 if (retval != NULL) 15139 { 15140 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15141 if (expr_start != NULL) 15142 { 15143 /* Further expansion! */ 15144 temp_result = make_expanded_name(retval, expr_start, 15145 expr_end, temp_result); 15146 vim_free(retval); 15147 retval = temp_result; 15148 } 15149 } 15150 15151 return retval; 15152 } 15153 15154 /* 15155 * Return TRUE if character "c" can be used in a variable or function name. 15156 * Does not include '{' or '}' for magic braces. 15157 */ 15158 static int 15159 eval_isnamec(c) 15160 int c; 15161 { 15162 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15163 } 15164 15165 /* 15166 * Return TRUE if character "c" can be used as the first character in a 15167 * variable or function name (excluding '{' and '}'). 15168 */ 15169 static int 15170 eval_isnamec1(c) 15171 int c; 15172 { 15173 return (ASCII_ISALPHA(c) || c == '_'); 15174 } 15175 15176 /* 15177 * Set number v: variable to "val". 15178 */ 15179 void 15180 set_vim_var_nr(idx, val) 15181 int idx; 15182 long val; 15183 { 15184 vimvars[idx].vv_nr = val; 15185 } 15186 15187 /* 15188 * Get number v: variable value. 15189 */ 15190 long 15191 get_vim_var_nr(idx) 15192 int idx; 15193 { 15194 return vimvars[idx].vv_nr; 15195 } 15196 15197 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15198 /* 15199 * Get string v: variable value. Uses a static buffer, can only be used once. 15200 */ 15201 char_u * 15202 get_vim_var_str(idx) 15203 int idx; 15204 { 15205 return get_tv_string(&vimvars[idx].vv_tv); 15206 } 15207 #endif 15208 15209 /* 15210 * Set v:count, v:count1 and v:prevcount. 15211 */ 15212 void 15213 set_vcount(count, count1) 15214 long count; 15215 long count1; 15216 { 15217 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15218 vimvars[VV_COUNT].vv_nr = count; 15219 vimvars[VV_COUNT1].vv_nr = count1; 15220 } 15221 15222 /* 15223 * Set string v: variable to a copy of "val". 15224 */ 15225 void 15226 set_vim_var_string(idx, val, len) 15227 int idx; 15228 char_u *val; 15229 int len; /* length of "val" to use or -1 (whole string) */ 15230 { 15231 /* Need to do this (at least) once, since we can't initialize a union. 15232 * Will always be invoked when "v:progname" is set. */ 15233 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15234 15235 vim_free(vimvars[idx].vv_str); 15236 if (val == NULL) 15237 vimvars[idx].vv_str = NULL; 15238 else if (len == -1) 15239 vimvars[idx].vv_str = vim_strsave(val); 15240 else 15241 vimvars[idx].vv_str = vim_strnsave(val, len); 15242 } 15243 15244 /* 15245 * Set v:register if needed. 15246 */ 15247 void 15248 set_reg_var(c) 15249 int c; 15250 { 15251 char_u regname; 15252 15253 if (c == 0 || c == ' ') 15254 regname = '"'; 15255 else 15256 regname = c; 15257 /* Avoid free/alloc when the value is already right. */ 15258 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15259 set_vim_var_string(VV_REG, ®name, 1); 15260 } 15261 15262 /* 15263 * Get or set v:exception. If "oldval" == NULL, return the current value. 15264 * Otherwise, restore the value to "oldval" and return NULL. 15265 * Must always be called in pairs to save and restore v:exception! Does not 15266 * take care of memory allocations. 15267 */ 15268 char_u * 15269 v_exception(oldval) 15270 char_u *oldval; 15271 { 15272 if (oldval == NULL) 15273 return vimvars[VV_EXCEPTION].vv_str; 15274 15275 vimvars[VV_EXCEPTION].vv_str = oldval; 15276 return NULL; 15277 } 15278 15279 /* 15280 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15281 * Otherwise, restore the value to "oldval" and return NULL. 15282 * Must always be called in pairs to save and restore v:throwpoint! Does not 15283 * take care of memory allocations. 15284 */ 15285 char_u * 15286 v_throwpoint(oldval) 15287 char_u *oldval; 15288 { 15289 if (oldval == NULL) 15290 return vimvars[VV_THROWPOINT].vv_str; 15291 15292 vimvars[VV_THROWPOINT].vv_str = oldval; 15293 return NULL; 15294 } 15295 15296 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15297 /* 15298 * Set v:cmdarg. 15299 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15300 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15301 * Must always be called in pairs! 15302 */ 15303 char_u * 15304 set_cmdarg(eap, oldarg) 15305 exarg_T *eap; 15306 char_u *oldarg; 15307 { 15308 char_u *oldval; 15309 char_u *newval; 15310 unsigned len; 15311 15312 oldval = vimvars[VV_CMDARG].vv_str; 15313 if (eap == NULL) 15314 { 15315 vim_free(oldval); 15316 vimvars[VV_CMDARG].vv_str = oldarg; 15317 return NULL; 15318 } 15319 15320 if (eap->force_bin == FORCE_BIN) 15321 len = 6; 15322 else if (eap->force_bin == FORCE_NOBIN) 15323 len = 8; 15324 else 15325 len = 0; 15326 if (eap->force_ff != 0) 15327 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15328 # ifdef FEAT_MBYTE 15329 if (eap->force_enc != 0) 15330 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15331 # endif 15332 15333 newval = alloc(len + 1); 15334 if (newval == NULL) 15335 return NULL; 15336 15337 if (eap->force_bin == FORCE_BIN) 15338 sprintf((char *)newval, " ++bin"); 15339 else if (eap->force_bin == FORCE_NOBIN) 15340 sprintf((char *)newval, " ++nobin"); 15341 else 15342 *newval = NUL; 15343 if (eap->force_ff != 0) 15344 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15345 eap->cmd + eap->force_ff); 15346 # ifdef FEAT_MBYTE 15347 if (eap->force_enc != 0) 15348 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15349 eap->cmd + eap->force_enc); 15350 # endif 15351 vimvars[VV_CMDARG].vv_str = newval; 15352 return oldval; 15353 } 15354 #endif 15355 15356 /* 15357 * Get the value of internal variable "name". 15358 * Return OK or FAIL. 15359 */ 15360 static int 15361 get_var_tv(name, len, rettv, verbose) 15362 char_u *name; 15363 int len; /* length of "name" */ 15364 typval_T *rettv; /* NULL when only checking existence */ 15365 int verbose; /* may give error message */ 15366 { 15367 int ret = OK; 15368 typval_T *tv = NULL; 15369 typval_T atv; 15370 dictitem_T *v; 15371 int cc; 15372 15373 /* truncate the name, so that we can use strcmp() */ 15374 cc = name[len]; 15375 name[len] = NUL; 15376 15377 /* 15378 * Check for "b:changedtick". 15379 */ 15380 if (STRCMP(name, "b:changedtick") == 0) 15381 { 15382 atv.v_type = VAR_NUMBER; 15383 atv.vval.v_number = curbuf->b_changedtick; 15384 tv = &atv; 15385 } 15386 15387 /* 15388 * Check for user-defined variables. 15389 */ 15390 else 15391 { 15392 v = find_var(name, NULL); 15393 if (v != NULL) 15394 tv = &v->di_tv; 15395 } 15396 15397 if (tv == NULL) 15398 { 15399 if (rettv != NULL && verbose) 15400 EMSG2(_(e_undefvar), name); 15401 ret = FAIL; 15402 } 15403 else if (rettv != NULL) 15404 copy_tv(tv, rettv); 15405 15406 name[len] = cc; 15407 15408 return ret; 15409 } 15410 15411 /* 15412 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15413 * Also handle function call with Funcref variable: func(expr) 15414 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15415 */ 15416 static int 15417 handle_subscript(arg, rettv, evaluate, verbose) 15418 char_u **arg; 15419 typval_T *rettv; 15420 int evaluate; /* do more than finding the end */ 15421 int verbose; /* give error messages */ 15422 { 15423 int ret = OK; 15424 dict_T *selfdict = NULL; 15425 char_u *s; 15426 int len; 15427 typval_T functv; 15428 15429 while (ret == OK 15430 && (**arg == '[' 15431 || (**arg == '.' && rettv->v_type == VAR_DICT) 15432 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15433 && !vim_iswhite(*(*arg - 1))) 15434 { 15435 if (**arg == '(') 15436 { 15437 /* need to copy the funcref so that we can clear rettv */ 15438 functv = *rettv; 15439 rettv->v_type = VAR_UNKNOWN; 15440 15441 /* Invoke the function. Recursive! */ 15442 s = functv.vval.v_string; 15443 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15444 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15445 &len, evaluate, selfdict); 15446 15447 /* Clear the funcref afterwards, so that deleting it while 15448 * evaluating the arguments is possible (see test55). */ 15449 clear_tv(&functv); 15450 15451 /* Stop the expression evaluation when immediately aborting on 15452 * error, or when an interrupt occurred or an exception was thrown 15453 * but not caught. */ 15454 if (aborting()) 15455 { 15456 if (ret == OK) 15457 clear_tv(rettv); 15458 ret = FAIL; 15459 } 15460 dict_unref(selfdict); 15461 selfdict = NULL; 15462 } 15463 else /* **arg == '[' || **arg == '.' */ 15464 { 15465 dict_unref(selfdict); 15466 if (rettv->v_type == VAR_DICT) 15467 { 15468 selfdict = rettv->vval.v_dict; 15469 if (selfdict != NULL) 15470 ++selfdict->dv_refcount; 15471 } 15472 else 15473 selfdict = NULL; 15474 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15475 { 15476 clear_tv(rettv); 15477 ret = FAIL; 15478 } 15479 } 15480 } 15481 dict_unref(selfdict); 15482 return ret; 15483 } 15484 15485 /* 15486 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15487 * value). 15488 */ 15489 static typval_T * 15490 alloc_tv() 15491 { 15492 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15493 } 15494 15495 /* 15496 * Allocate memory for a variable type-value, and assign a string to it. 15497 * The string "s" must have been allocated, it is consumed. 15498 * Return NULL for out of memory, the variable otherwise. 15499 */ 15500 static typval_T * 15501 alloc_string_tv(s) 15502 char_u *s; 15503 { 15504 typval_T *rettv; 15505 15506 rettv = alloc_tv(); 15507 if (rettv != NULL) 15508 { 15509 rettv->v_type = VAR_STRING; 15510 rettv->vval.v_string = s; 15511 } 15512 else 15513 vim_free(s); 15514 return rettv; 15515 } 15516 15517 /* 15518 * Free the memory for a variable type-value. 15519 */ 15520 static void 15521 free_tv(varp) 15522 typval_T *varp; 15523 { 15524 if (varp != NULL) 15525 { 15526 switch (varp->v_type) 15527 { 15528 case VAR_FUNC: 15529 func_unref(varp->vval.v_string); 15530 /*FALLTHROUGH*/ 15531 case VAR_STRING: 15532 vim_free(varp->vval.v_string); 15533 break; 15534 case VAR_LIST: 15535 list_unref(varp->vval.v_list); 15536 break; 15537 case VAR_DICT: 15538 dict_unref(varp->vval.v_dict); 15539 break; 15540 case VAR_NUMBER: 15541 case VAR_UNKNOWN: 15542 break; 15543 default: 15544 EMSG2(_(e_intern2), "free_tv()"); 15545 break; 15546 } 15547 vim_free(varp); 15548 } 15549 } 15550 15551 /* 15552 * Free the memory for a variable value and set the value to NULL or 0. 15553 */ 15554 void 15555 clear_tv(varp) 15556 typval_T *varp; 15557 { 15558 if (varp != NULL) 15559 { 15560 switch (varp->v_type) 15561 { 15562 case VAR_FUNC: 15563 func_unref(varp->vval.v_string); 15564 /*FALLTHROUGH*/ 15565 case VAR_STRING: 15566 vim_free(varp->vval.v_string); 15567 varp->vval.v_string = NULL; 15568 break; 15569 case VAR_LIST: 15570 list_unref(varp->vval.v_list); 15571 varp->vval.v_list = NULL; 15572 break; 15573 case VAR_DICT: 15574 dict_unref(varp->vval.v_dict); 15575 varp->vval.v_dict = NULL; 15576 break; 15577 case VAR_NUMBER: 15578 varp->vval.v_number = 0; 15579 break; 15580 case VAR_UNKNOWN: 15581 break; 15582 default: 15583 EMSG2(_(e_intern2), "clear_tv()"); 15584 } 15585 varp->v_lock = 0; 15586 } 15587 } 15588 15589 /* 15590 * Set the value of a variable to NULL without freeing items. 15591 */ 15592 static void 15593 init_tv(varp) 15594 typval_T *varp; 15595 { 15596 if (varp != NULL) 15597 vim_memset(varp, 0, sizeof(typval_T)); 15598 } 15599 15600 /* 15601 * Get the number value of a variable. 15602 * If it is a String variable, uses vim_str2nr(). 15603 * For incompatible types, return 0. 15604 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15605 * caller of incompatible types: it sets *denote to TRUE if "denote" 15606 * is not NULL or returns -1 otherwise. 15607 */ 15608 static long 15609 get_tv_number(varp) 15610 typval_T *varp; 15611 { 15612 int error = FALSE; 15613 15614 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15615 } 15616 15617 static long 15618 get_tv_number_chk(varp, denote) 15619 typval_T *varp; 15620 int *denote; 15621 { 15622 long n = 0L; 15623 15624 switch (varp->v_type) 15625 { 15626 case VAR_NUMBER: 15627 return (long)(varp->vval.v_number); 15628 case VAR_FUNC: 15629 EMSG(_("E703: Using a Funcref as a number")); 15630 break; 15631 case VAR_STRING: 15632 if (varp->vval.v_string != NULL) 15633 vim_str2nr(varp->vval.v_string, NULL, NULL, 15634 TRUE, TRUE, &n, NULL); 15635 return n; 15636 case VAR_LIST: 15637 EMSG(_("E745: Using a List as a number")); 15638 break; 15639 case VAR_DICT: 15640 EMSG(_("E728: Using a Dictionary as a number")); 15641 break; 15642 default: 15643 EMSG2(_(e_intern2), "get_tv_number()"); 15644 break; 15645 } 15646 if (denote == NULL) /* useful for values that must be unsigned */ 15647 n = -1; 15648 else 15649 *denote = TRUE; 15650 return n; 15651 } 15652 15653 /* 15654 * Get the lnum from the first argument. Also accepts ".", "$", etc. 15655 * Returns -1 on error. 15656 */ 15657 static linenr_T 15658 get_tv_lnum(argvars) 15659 typval_T *argvars; 15660 { 15661 typval_T rettv; 15662 linenr_T lnum; 15663 15664 lnum = get_tv_number_chk(&argvars[0], NULL); 15665 if (lnum == 0) /* no valid number, try using line() */ 15666 { 15667 rettv.v_type = VAR_NUMBER; 15668 f_line(argvars, &rettv); 15669 lnum = rettv.vval.v_number; 15670 clear_tv(&rettv); 15671 } 15672 return lnum; 15673 } 15674 15675 /* 15676 * Get the string value of a variable. 15677 * If it is a Number variable, the number is converted into a string. 15678 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 15679 * get_tv_string_buf() uses a given buffer. 15680 * If the String variable has never been set, return an empty string. 15681 * Never returns NULL; 15682 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 15683 * NULL on error. 15684 */ 15685 static char_u * 15686 get_tv_string(varp) 15687 typval_T *varp; 15688 { 15689 static char_u mybuf[NUMBUFLEN]; 15690 15691 return get_tv_string_buf(varp, mybuf); 15692 } 15693 15694 static char_u * 15695 get_tv_string_buf(varp, buf) 15696 typval_T *varp; 15697 char_u *buf; 15698 { 15699 char_u *res = get_tv_string_buf_chk(varp, buf); 15700 15701 return res != NULL ? res : (char_u *)""; 15702 } 15703 15704 static char_u * 15705 get_tv_string_chk(varp) 15706 typval_T *varp; 15707 { 15708 static char_u mybuf[NUMBUFLEN]; 15709 15710 return get_tv_string_buf_chk(varp, mybuf); 15711 } 15712 15713 static char_u * 15714 get_tv_string_buf_chk(varp, buf) 15715 typval_T *varp; 15716 char_u *buf; 15717 { 15718 switch (varp->v_type) 15719 { 15720 case VAR_NUMBER: 15721 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 15722 return buf; 15723 case VAR_FUNC: 15724 EMSG(_("E729: using Funcref as a String")); 15725 break; 15726 case VAR_LIST: 15727 EMSG(_("E730: using List as a String")); 15728 break; 15729 case VAR_DICT: 15730 EMSG(_("E731: using Dictionary as a String")); 15731 break; 15732 case VAR_STRING: 15733 if (varp->vval.v_string != NULL) 15734 return varp->vval.v_string; 15735 return (char_u *)""; 15736 default: 15737 EMSG2(_(e_intern2), "get_tv_string_buf()"); 15738 break; 15739 } 15740 return NULL; 15741 } 15742 15743 /* 15744 * Find variable "name" in the list of variables. 15745 * Return a pointer to it if found, NULL if not found. 15746 * Careful: "a:0" variables don't have a name. 15747 * When "htp" is not NULL we are writing to the variable, set "htp" to the 15748 * hashtab_T used. 15749 */ 15750 static dictitem_T * 15751 find_var(name, htp) 15752 char_u *name; 15753 hashtab_T **htp; 15754 { 15755 char_u *varname; 15756 hashtab_T *ht; 15757 15758 ht = find_var_ht(name, &varname); 15759 if (htp != NULL) 15760 *htp = ht; 15761 if (ht == NULL) 15762 return NULL; 15763 return find_var_in_ht(ht, varname, htp != NULL); 15764 } 15765 15766 /* 15767 * Find variable "varname" in hashtab "ht". 15768 * Returns NULL if not found. 15769 */ 15770 static dictitem_T * 15771 find_var_in_ht(ht, varname, writing) 15772 hashtab_T *ht; 15773 char_u *varname; 15774 int writing; 15775 { 15776 hashitem_T *hi; 15777 15778 if (*varname == NUL) 15779 { 15780 /* Must be something like "s:", otherwise "ht" would be NULL. */ 15781 switch (varname[-2]) 15782 { 15783 case 's': return &SCRIPT_SV(current_SID).sv_var; 15784 case 'g': return &globvars_var; 15785 case 'v': return &vimvars_var; 15786 case 'b': return &curbuf->b_bufvar; 15787 case 'w': return &curwin->w_winvar; 15788 case 'l': return current_funccal == NULL 15789 ? NULL : ¤t_funccal->l_vars_var; 15790 case 'a': return current_funccal == NULL 15791 ? NULL : ¤t_funccal->l_avars_var; 15792 } 15793 return NULL; 15794 } 15795 15796 hi = hash_find(ht, varname); 15797 if (HASHITEM_EMPTY(hi)) 15798 { 15799 /* For global variables we may try auto-loading the script. If it 15800 * worked find the variable again. Don't auto-load a script if it was 15801 * loaded already, otherwise it would be loaded every time when 15802 * checking if a function name is a Funcref variable. */ 15803 if (ht == &globvarht && !writing 15804 && script_autoload(varname, FALSE) && !aborting()) 15805 hi = hash_find(ht, varname); 15806 if (HASHITEM_EMPTY(hi)) 15807 return NULL; 15808 } 15809 return HI2DI(hi); 15810 } 15811 15812 /* 15813 * Find the hashtab used for a variable name. 15814 * Set "varname" to the start of name without ':'. 15815 */ 15816 static hashtab_T * 15817 find_var_ht(name, varname) 15818 char_u *name; 15819 char_u **varname; 15820 { 15821 hashitem_T *hi; 15822 15823 if (name[1] != ':') 15824 { 15825 /* The name must not start with a colon or #. */ 15826 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 15827 return NULL; 15828 *varname = name; 15829 15830 /* "version" is "v:version" in all scopes */ 15831 hi = hash_find(&compat_hashtab, name); 15832 if (!HASHITEM_EMPTY(hi)) 15833 return &compat_hashtab; 15834 15835 if (current_funccal == NULL) 15836 return &globvarht; /* global variable */ 15837 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 15838 } 15839 *varname = name + 2; 15840 if (*name == 'g') /* global variable */ 15841 return &globvarht; 15842 /* There must be no ':' or '#' in the rest of the name, unless g: is used 15843 */ 15844 if (vim_strchr(name + 2, ':') != NULL 15845 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 15846 return NULL; 15847 if (*name == 'b') /* buffer variable */ 15848 return &curbuf->b_vars.dv_hashtab; 15849 if (*name == 'w') /* window variable */ 15850 return &curwin->w_vars.dv_hashtab; 15851 if (*name == 'v') /* v: variable */ 15852 return &vimvarht; 15853 if (*name == 'a' && current_funccal != NULL) /* function argument */ 15854 return ¤t_funccal->l_avars.dv_hashtab; 15855 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 15856 return ¤t_funccal->l_vars.dv_hashtab; 15857 if (*name == 's' /* script variable */ 15858 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 15859 return &SCRIPT_VARS(current_SID); 15860 return NULL; 15861 } 15862 15863 /* 15864 * Get the string value of a (global/local) variable. 15865 * Returns NULL when it doesn't exist. 15866 */ 15867 char_u * 15868 get_var_value(name) 15869 char_u *name; 15870 { 15871 dictitem_T *v; 15872 15873 v = find_var(name, NULL); 15874 if (v == NULL) 15875 return NULL; 15876 return get_tv_string(&v->di_tv); 15877 } 15878 15879 /* 15880 * Allocate a new hashtab for a sourced script. It will be used while 15881 * sourcing this script and when executing functions defined in the script. 15882 */ 15883 void 15884 new_script_vars(id) 15885 scid_T id; 15886 { 15887 int i; 15888 hashtab_T *ht; 15889 scriptvar_T *sv; 15890 15891 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 15892 { 15893 /* Re-allocating ga_data means that an ht_array pointing to 15894 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 15895 * at its init value. Also reset "v_dict", it's always the same. */ 15896 for (i = 1; i <= ga_scripts.ga_len; ++i) 15897 { 15898 ht = &SCRIPT_VARS(i); 15899 if (ht->ht_mask == HT_INIT_SIZE - 1) 15900 ht->ht_array = ht->ht_smallarray; 15901 sv = &SCRIPT_SV(i); 15902 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 15903 } 15904 15905 while (ga_scripts.ga_len < id) 15906 { 15907 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 15908 init_var_dict(&sv->sv_dict, &sv->sv_var); 15909 ++ga_scripts.ga_len; 15910 } 15911 } 15912 } 15913 15914 /* 15915 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 15916 * point to it. 15917 */ 15918 void 15919 init_var_dict(dict, dict_var) 15920 dict_T *dict; 15921 dictitem_T *dict_var; 15922 { 15923 hash_init(&dict->dv_hashtab); 15924 dict->dv_refcount = 99999; 15925 dict_var->di_tv.vval.v_dict = dict; 15926 dict_var->di_tv.v_type = VAR_DICT; 15927 dict_var->di_tv.v_lock = VAR_FIXED; 15928 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 15929 dict_var->di_key[0] = NUL; 15930 } 15931 15932 /* 15933 * Clean up a list of internal variables. 15934 * Frees all allocated variables and the value they contain. 15935 * Clears hashtab "ht", does not free it. 15936 */ 15937 void 15938 vars_clear(ht) 15939 hashtab_T *ht; 15940 { 15941 vars_clear_ext(ht, TRUE); 15942 } 15943 15944 /* 15945 * Like vars_clear(), but only free the value if "free_val" is TRUE. 15946 */ 15947 static void 15948 vars_clear_ext(ht, free_val) 15949 hashtab_T *ht; 15950 int free_val; 15951 { 15952 int todo; 15953 hashitem_T *hi; 15954 dictitem_T *v; 15955 15956 hash_lock(ht); 15957 todo = ht->ht_used; 15958 for (hi = ht->ht_array; todo > 0; ++hi) 15959 { 15960 if (!HASHITEM_EMPTY(hi)) 15961 { 15962 --todo; 15963 15964 /* Free the variable. Don't remove it from the hashtab, 15965 * ht_array might change then. hash_clear() takes care of it 15966 * later. */ 15967 v = HI2DI(hi); 15968 if (free_val) 15969 clear_tv(&v->di_tv); 15970 if ((v->di_flags & DI_FLAGS_FIX) == 0) 15971 vim_free(v); 15972 } 15973 } 15974 hash_clear(ht); 15975 ht->ht_used = 0; 15976 } 15977 15978 /* 15979 * Delete a variable from hashtab "ht" at item "hi". 15980 * Clear the variable value and free the dictitem. 15981 */ 15982 static void 15983 delete_var(ht, hi) 15984 hashtab_T *ht; 15985 hashitem_T *hi; 15986 { 15987 dictitem_T *di = HI2DI(hi); 15988 15989 hash_remove(ht, hi); 15990 clear_tv(&di->di_tv); 15991 vim_free(di); 15992 } 15993 15994 /* 15995 * List the value of one internal variable. 15996 */ 15997 static void 15998 list_one_var(v, prefix) 15999 dictitem_T *v; 16000 char_u *prefix; 16001 { 16002 char_u *tofree; 16003 char_u *s; 16004 char_u numbuf[NUMBUFLEN]; 16005 16006 s = echo_string(&v->di_tv, &tofree, numbuf); 16007 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16008 s == NULL ? (char_u *)"" : s); 16009 vim_free(tofree); 16010 } 16011 16012 static void 16013 list_one_var_a(prefix, name, type, string) 16014 char_u *prefix; 16015 char_u *name; 16016 int type; 16017 char_u *string; 16018 { 16019 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16020 if (name != NULL) /* "a:" vars don't have a name stored */ 16021 msg_puts(name); 16022 msg_putchar(' '); 16023 msg_advance(22); 16024 if (type == VAR_NUMBER) 16025 msg_putchar('#'); 16026 else if (type == VAR_FUNC) 16027 msg_putchar('*'); 16028 else if (type == VAR_LIST) 16029 { 16030 msg_putchar('['); 16031 if (*string == '[') 16032 ++string; 16033 } 16034 else if (type == VAR_DICT) 16035 { 16036 msg_putchar('{'); 16037 if (*string == '{') 16038 ++string; 16039 } 16040 else 16041 msg_putchar(' '); 16042 16043 msg_outtrans(string); 16044 16045 if (type == VAR_FUNC) 16046 msg_puts((char_u *)"()"); 16047 } 16048 16049 /* 16050 * Set variable "name" to value in "tv". 16051 * If the variable already exists, the value is updated. 16052 * Otherwise the variable is created. 16053 */ 16054 static void 16055 set_var(name, tv, copy) 16056 char_u *name; 16057 typval_T *tv; 16058 int copy; /* make copy of value in "tv" */ 16059 { 16060 dictitem_T *v; 16061 char_u *varname; 16062 hashtab_T *ht; 16063 char_u *p; 16064 16065 if (tv->v_type == VAR_FUNC) 16066 { 16067 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16068 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16069 ? name[2] : name[0])) 16070 { 16071 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16072 return; 16073 } 16074 if (function_exists(name)) 16075 { 16076 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16077 name); 16078 return; 16079 } 16080 } 16081 16082 ht = find_var_ht(name, &varname); 16083 if (ht == NULL || *varname == NUL) 16084 { 16085 EMSG2(_(e_illvar), name); 16086 return; 16087 } 16088 16089 v = find_var_in_ht(ht, varname, TRUE); 16090 if (v != NULL) 16091 { 16092 /* existing variable, need to clear the value */ 16093 if (var_check_ro(v->di_flags, name) 16094 || tv_check_lock(v->di_tv.v_lock, name)) 16095 return; 16096 if (v->di_tv.v_type != tv->v_type 16097 && !((v->di_tv.v_type == VAR_STRING 16098 || v->di_tv.v_type == VAR_NUMBER) 16099 && (tv->v_type == VAR_STRING 16100 || tv->v_type == VAR_NUMBER))) 16101 { 16102 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16103 return; 16104 } 16105 16106 /* 16107 * Handle setting internal v: variables separately: we don't change 16108 * the type. 16109 */ 16110 if (ht == &vimvarht) 16111 { 16112 if (v->di_tv.v_type == VAR_STRING) 16113 { 16114 vim_free(v->di_tv.vval.v_string); 16115 if (copy || tv->v_type != VAR_STRING) 16116 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16117 else 16118 { 16119 /* Take over the string to avoid an extra alloc/free. */ 16120 v->di_tv.vval.v_string = tv->vval.v_string; 16121 tv->vval.v_string = NULL; 16122 } 16123 } 16124 else if (v->di_tv.v_type != VAR_NUMBER) 16125 EMSG2(_(e_intern2), "set_var()"); 16126 else 16127 v->di_tv.vval.v_number = get_tv_number(tv); 16128 return; 16129 } 16130 16131 clear_tv(&v->di_tv); 16132 } 16133 else /* add a new variable */ 16134 { 16135 /* Make sure the variable name is valid. */ 16136 for (p = varname; *p != NUL; ++p) 16137 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16138 { 16139 EMSG2(_(e_illvar), varname); 16140 return; 16141 } 16142 16143 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16144 + STRLEN(varname))); 16145 if (v == NULL) 16146 return; 16147 STRCPY(v->di_key, varname); 16148 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16149 { 16150 vim_free(v); 16151 return; 16152 } 16153 v->di_flags = 0; 16154 } 16155 16156 if (copy || tv->v_type == VAR_NUMBER) 16157 copy_tv(tv, &v->di_tv); 16158 else 16159 { 16160 v->di_tv = *tv; 16161 v->di_tv.v_lock = 0; 16162 init_tv(tv); 16163 } 16164 } 16165 16166 /* 16167 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16168 * Also give an error message. 16169 */ 16170 static int 16171 var_check_ro(flags, name) 16172 int flags; 16173 char_u *name; 16174 { 16175 if (flags & DI_FLAGS_RO) 16176 { 16177 EMSG2(_(e_readonlyvar), name); 16178 return TRUE; 16179 } 16180 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16181 { 16182 EMSG2(_(e_readonlysbx), name); 16183 return TRUE; 16184 } 16185 return FALSE; 16186 } 16187 16188 /* 16189 * Return TRUE if typeval "tv" is set to be locked (immutable). 16190 * Also give an error message, using "name". 16191 */ 16192 static int 16193 tv_check_lock(lock, name) 16194 int lock; 16195 char_u *name; 16196 { 16197 if (lock & VAR_LOCKED) 16198 { 16199 EMSG2(_("E741: Value is locked: %s"), 16200 name == NULL ? (char_u *)_("Unknown") : name); 16201 return TRUE; 16202 } 16203 if (lock & VAR_FIXED) 16204 { 16205 EMSG2(_("E742: Cannot change value of %s"), 16206 name == NULL ? (char_u *)_("Unknown") : name); 16207 return TRUE; 16208 } 16209 return FALSE; 16210 } 16211 16212 /* 16213 * Copy the values from typval_T "from" to typval_T "to". 16214 * When needed allocates string or increases reference count. 16215 * Does not make a copy of a list or dict but copies the reference! 16216 */ 16217 static void 16218 copy_tv(from, to) 16219 typval_T *from; 16220 typval_T *to; 16221 { 16222 to->v_type = from->v_type; 16223 to->v_lock = 0; 16224 switch (from->v_type) 16225 { 16226 case VAR_NUMBER: 16227 to->vval.v_number = from->vval.v_number; 16228 break; 16229 case VAR_STRING: 16230 case VAR_FUNC: 16231 if (from->vval.v_string == NULL) 16232 to->vval.v_string = NULL; 16233 else 16234 { 16235 to->vval.v_string = vim_strsave(from->vval.v_string); 16236 if (from->v_type == VAR_FUNC) 16237 func_ref(to->vval.v_string); 16238 } 16239 break; 16240 case VAR_LIST: 16241 if (from->vval.v_list == NULL) 16242 to->vval.v_list = NULL; 16243 else 16244 { 16245 to->vval.v_list = from->vval.v_list; 16246 ++to->vval.v_list->lv_refcount; 16247 } 16248 break; 16249 case VAR_DICT: 16250 if (from->vval.v_dict == NULL) 16251 to->vval.v_dict = NULL; 16252 else 16253 { 16254 to->vval.v_dict = from->vval.v_dict; 16255 ++to->vval.v_dict->dv_refcount; 16256 } 16257 break; 16258 default: 16259 EMSG2(_(e_intern2), "copy_tv()"); 16260 break; 16261 } 16262 } 16263 16264 /* 16265 * Make a copy of an item. 16266 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16267 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16268 * reference to an already copied list/dict can be used. 16269 * Returns FAIL or OK. 16270 */ 16271 static int 16272 item_copy(from, to, deep, copyID) 16273 typval_T *from; 16274 typval_T *to; 16275 int deep; 16276 int copyID; 16277 { 16278 static int recurse = 0; 16279 int ret = OK; 16280 16281 if (recurse >= DICT_MAXNEST) 16282 { 16283 EMSG(_("E698: variable nested too deep for making a copy")); 16284 return FAIL; 16285 } 16286 ++recurse; 16287 16288 switch (from->v_type) 16289 { 16290 case VAR_NUMBER: 16291 case VAR_STRING: 16292 case VAR_FUNC: 16293 copy_tv(from, to); 16294 break; 16295 case VAR_LIST: 16296 to->v_type = VAR_LIST; 16297 to->v_lock = 0; 16298 if (from->vval.v_list == NULL) 16299 to->vval.v_list = NULL; 16300 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16301 { 16302 /* use the copy made earlier */ 16303 to->vval.v_list = from->vval.v_list->lv_copylist; 16304 ++to->vval.v_list->lv_refcount; 16305 } 16306 else 16307 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16308 if (to->vval.v_list == NULL) 16309 ret = FAIL; 16310 break; 16311 case VAR_DICT: 16312 to->v_type = VAR_DICT; 16313 to->v_lock = 0; 16314 if (from->vval.v_dict == NULL) 16315 to->vval.v_dict = NULL; 16316 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16317 { 16318 /* use the copy made earlier */ 16319 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16320 ++to->vval.v_dict->dv_refcount; 16321 } 16322 else 16323 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16324 if (to->vval.v_dict == NULL) 16325 ret = FAIL; 16326 break; 16327 default: 16328 EMSG2(_(e_intern2), "item_copy()"); 16329 ret = FAIL; 16330 } 16331 --recurse; 16332 return ret; 16333 } 16334 16335 /* 16336 * ":echo expr1 ..." print each argument separated with a space, add a 16337 * newline at the end. 16338 * ":echon expr1 ..." print each argument plain. 16339 */ 16340 void 16341 ex_echo(eap) 16342 exarg_T *eap; 16343 { 16344 char_u *arg = eap->arg; 16345 typval_T rettv; 16346 char_u *tofree; 16347 char_u *p; 16348 int needclr = TRUE; 16349 int atstart = TRUE; 16350 char_u numbuf[NUMBUFLEN]; 16351 16352 if (eap->skip) 16353 ++emsg_skip; 16354 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16355 { 16356 p = arg; 16357 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16358 { 16359 /* 16360 * Report the invalid expression unless the expression evaluation 16361 * has been cancelled due to an aborting error, an interrupt, or an 16362 * exception. 16363 */ 16364 if (!aborting()) 16365 EMSG2(_(e_invexpr2), p); 16366 break; 16367 } 16368 if (!eap->skip) 16369 { 16370 if (atstart) 16371 { 16372 atstart = FALSE; 16373 /* Call msg_start() after eval1(), evaluating the expression 16374 * may cause a message to appear. */ 16375 if (eap->cmdidx == CMD_echo) 16376 msg_start(); 16377 } 16378 else if (eap->cmdidx == CMD_echo) 16379 msg_puts_attr((char_u *)" ", echo_attr); 16380 p = echo_string(&rettv, &tofree, numbuf); 16381 if (p != NULL) 16382 for ( ; *p != NUL && !got_int; ++p) 16383 { 16384 if (*p == '\n' || *p == '\r' || *p == TAB) 16385 { 16386 if (*p != TAB && needclr) 16387 { 16388 /* remove any text still there from the command */ 16389 msg_clr_eos(); 16390 needclr = FALSE; 16391 } 16392 msg_putchar_attr(*p, echo_attr); 16393 } 16394 else 16395 { 16396 #ifdef FEAT_MBYTE 16397 if (has_mbyte) 16398 { 16399 int i = (*mb_ptr2len_check)(p); 16400 16401 (void)msg_outtrans_len_attr(p, i, echo_attr); 16402 p += i - 1; 16403 } 16404 else 16405 #endif 16406 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16407 } 16408 } 16409 vim_free(tofree); 16410 } 16411 clear_tv(&rettv); 16412 arg = skipwhite(arg); 16413 } 16414 eap->nextcmd = check_nextcmd(arg); 16415 16416 if (eap->skip) 16417 --emsg_skip; 16418 else 16419 { 16420 /* remove text that may still be there from the command */ 16421 if (needclr) 16422 msg_clr_eos(); 16423 if (eap->cmdidx == CMD_echo) 16424 msg_end(); 16425 } 16426 } 16427 16428 /* 16429 * ":echohl {name}". 16430 */ 16431 void 16432 ex_echohl(eap) 16433 exarg_T *eap; 16434 { 16435 int id; 16436 16437 id = syn_name2id(eap->arg); 16438 if (id == 0) 16439 echo_attr = 0; 16440 else 16441 echo_attr = syn_id2attr(id); 16442 } 16443 16444 /* 16445 * ":execute expr1 ..." execute the result of an expression. 16446 * ":echomsg expr1 ..." Print a message 16447 * ":echoerr expr1 ..." Print an error 16448 * Each gets spaces around each argument and a newline at the end for 16449 * echo commands 16450 */ 16451 void 16452 ex_execute(eap) 16453 exarg_T *eap; 16454 { 16455 char_u *arg = eap->arg; 16456 typval_T rettv; 16457 int ret = OK; 16458 char_u *p; 16459 garray_T ga; 16460 int len; 16461 int save_did_emsg; 16462 16463 ga_init2(&ga, 1, 80); 16464 16465 if (eap->skip) 16466 ++emsg_skip; 16467 while (*arg != NUL && *arg != '|' && *arg != '\n') 16468 { 16469 p = arg; 16470 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16471 { 16472 /* 16473 * Report the invalid expression unless the expression evaluation 16474 * has been cancelled due to an aborting error, an interrupt, or an 16475 * exception. 16476 */ 16477 if (!aborting()) 16478 EMSG2(_(e_invexpr2), p); 16479 ret = FAIL; 16480 break; 16481 } 16482 16483 if (!eap->skip) 16484 { 16485 p = get_tv_string(&rettv); 16486 len = (int)STRLEN(p); 16487 if (ga_grow(&ga, len + 2) == FAIL) 16488 { 16489 clear_tv(&rettv); 16490 ret = FAIL; 16491 break; 16492 } 16493 if (ga.ga_len) 16494 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16495 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16496 ga.ga_len += len; 16497 } 16498 16499 clear_tv(&rettv); 16500 arg = skipwhite(arg); 16501 } 16502 16503 if (ret != FAIL && ga.ga_data != NULL) 16504 { 16505 if (eap->cmdidx == CMD_echomsg) 16506 MSG_ATTR(ga.ga_data, echo_attr); 16507 else if (eap->cmdidx == CMD_echoerr) 16508 { 16509 /* We don't want to abort following commands, restore did_emsg. */ 16510 save_did_emsg = did_emsg; 16511 EMSG((char_u *)ga.ga_data); 16512 if (!force_abort) 16513 did_emsg = save_did_emsg; 16514 } 16515 else if (eap->cmdidx == CMD_execute) 16516 do_cmdline((char_u *)ga.ga_data, 16517 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16518 } 16519 16520 ga_clear(&ga); 16521 16522 if (eap->skip) 16523 --emsg_skip; 16524 16525 eap->nextcmd = check_nextcmd(arg); 16526 } 16527 16528 /* 16529 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16530 * "arg" points to the "&" or '+' when called, to "option" when returning. 16531 * Returns NULL when no option name found. Otherwise pointer to the char 16532 * after the option name. 16533 */ 16534 static char_u * 16535 find_option_end(arg, opt_flags) 16536 char_u **arg; 16537 int *opt_flags; 16538 { 16539 char_u *p = *arg; 16540 16541 ++p; 16542 if (*p == 'g' && p[1] == ':') 16543 { 16544 *opt_flags = OPT_GLOBAL; 16545 p += 2; 16546 } 16547 else if (*p == 'l' && p[1] == ':') 16548 { 16549 *opt_flags = OPT_LOCAL; 16550 p += 2; 16551 } 16552 else 16553 *opt_flags = 0; 16554 16555 if (!ASCII_ISALPHA(*p)) 16556 return NULL; 16557 *arg = p; 16558 16559 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16560 p += 4; /* termcap option */ 16561 else 16562 while (ASCII_ISALPHA(*p)) 16563 ++p; 16564 return p; 16565 } 16566 16567 /* 16568 * ":function" 16569 */ 16570 void 16571 ex_function(eap) 16572 exarg_T *eap; 16573 { 16574 char_u *theline; 16575 int j; 16576 int c; 16577 int saved_did_emsg; 16578 char_u *name = NULL; 16579 char_u *p; 16580 char_u *arg; 16581 garray_T newargs; 16582 garray_T newlines; 16583 int varargs = FALSE; 16584 int mustend = FALSE; 16585 int flags = 0; 16586 ufunc_T *fp; 16587 int indent; 16588 int nesting; 16589 char_u *skip_until = NULL; 16590 dictitem_T *v; 16591 funcdict_T fudi; 16592 static int func_nr = 0; /* number for nameless function */ 16593 int paren; 16594 hashtab_T *ht; 16595 int todo; 16596 hashitem_T *hi; 16597 16598 /* 16599 * ":function" without argument: list functions. 16600 */ 16601 if (ends_excmd(*eap->arg)) 16602 { 16603 if (!eap->skip) 16604 { 16605 todo = func_hashtab.ht_used; 16606 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16607 { 16608 if (!HASHITEM_EMPTY(hi)) 16609 { 16610 --todo; 16611 fp = HI2UF(hi); 16612 if (!isdigit(*fp->uf_name)) 16613 list_func_head(fp, FALSE); 16614 } 16615 } 16616 } 16617 eap->nextcmd = check_nextcmd(eap->arg); 16618 return; 16619 } 16620 16621 /* 16622 * Get the function name. There are these situations: 16623 * func normal function name 16624 * "name" == func, "fudi.fd_dict" == NULL 16625 * dict.func new dictionary entry 16626 * "name" == NULL, "fudi.fd_dict" set, 16627 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 16628 * dict.func existing dict entry with a Funcref 16629 * "name" == func, "fudi.fd_dict" set, 16630 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16631 * dict.func existing dict entry that's not a Funcref 16632 * "name" == NULL, "fudi.fd_dict" set, 16633 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16634 */ 16635 p = eap->arg; 16636 name = trans_function_name(&p, eap->skip, 0, &fudi); 16637 paren = (vim_strchr(p, '(') != NULL); 16638 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 16639 { 16640 /* 16641 * Return on an invalid expression in braces, unless the expression 16642 * evaluation has been cancelled due to an aborting error, an 16643 * interrupt, or an exception. 16644 */ 16645 if (!aborting()) 16646 { 16647 if (!eap->skip && fudi.fd_newkey != NULL) 16648 EMSG2(_(e_dictkey), fudi.fd_newkey); 16649 vim_free(fudi.fd_newkey); 16650 return; 16651 } 16652 else 16653 eap->skip = TRUE; 16654 } 16655 /* An error in a function call during evaluation of an expression in magic 16656 * braces should not cause the function not to be defined. */ 16657 saved_did_emsg = did_emsg; 16658 did_emsg = FALSE; 16659 16660 /* 16661 * ":function func" with only function name: list function. 16662 */ 16663 if (!paren) 16664 { 16665 if (!ends_excmd(*skipwhite(p))) 16666 { 16667 EMSG(_(e_trailing)); 16668 goto ret_free; 16669 } 16670 eap->nextcmd = check_nextcmd(p); 16671 if (eap->nextcmd != NULL) 16672 *p = NUL; 16673 if (!eap->skip && !got_int) 16674 { 16675 fp = find_func(name); 16676 if (fp != NULL) 16677 { 16678 list_func_head(fp, TRUE); 16679 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 16680 { 16681 msg_putchar('\n'); 16682 msg_outnum((long)(j + 1)); 16683 if (j < 9) 16684 msg_putchar(' '); 16685 if (j < 99) 16686 msg_putchar(' '); 16687 msg_prt_line(FUNCLINE(fp, j), FALSE); 16688 out_flush(); /* show a line at a time */ 16689 ui_breakcheck(); 16690 } 16691 if (!got_int) 16692 { 16693 msg_putchar('\n'); 16694 msg_puts((char_u *)" endfunction"); 16695 } 16696 } 16697 else 16698 emsg_funcname("E123: Undefined function: %s", name); 16699 } 16700 goto ret_free; 16701 } 16702 16703 /* 16704 * ":function name(arg1, arg2)" Define function. 16705 */ 16706 p = skipwhite(p); 16707 if (*p != '(') 16708 { 16709 if (!eap->skip) 16710 { 16711 EMSG2(_("E124: Missing '(': %s"), eap->arg); 16712 goto ret_free; 16713 } 16714 /* attempt to continue by skipping some text */ 16715 if (vim_strchr(p, '(') != NULL) 16716 p = vim_strchr(p, '('); 16717 } 16718 p = skipwhite(p + 1); 16719 16720 ga_init2(&newargs, (int)sizeof(char_u *), 3); 16721 ga_init2(&newlines, (int)sizeof(char_u *), 3); 16722 16723 if (!eap->skip) 16724 { 16725 /* Check the name of the function. */ 16726 if (name != NULL) 16727 arg = name; 16728 else 16729 arg = fudi.fd_newkey; 16730 if (arg != NULL) 16731 { 16732 if (*arg == K_SPECIAL) 16733 j = 3; 16734 else 16735 j = 0; 16736 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 16737 : eval_isnamec(arg[j]))) 16738 ++j; 16739 if (arg[j] != NUL) 16740 emsg_funcname(_(e_invarg2), arg); 16741 } 16742 } 16743 16744 /* 16745 * Isolate the arguments: "arg1, arg2, ...)" 16746 */ 16747 while (*p != ')') 16748 { 16749 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 16750 { 16751 varargs = TRUE; 16752 p += 3; 16753 mustend = TRUE; 16754 } 16755 else 16756 { 16757 arg = p; 16758 while (ASCII_ISALNUM(*p) || *p == '_') 16759 ++p; 16760 if (arg == p || isdigit(*arg) 16761 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 16762 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 16763 { 16764 if (!eap->skip) 16765 EMSG2(_("E125: Illegal argument: %s"), arg); 16766 break; 16767 } 16768 if (ga_grow(&newargs, 1) == FAIL) 16769 goto erret; 16770 c = *p; 16771 *p = NUL; 16772 arg = vim_strsave(arg); 16773 if (arg == NULL) 16774 goto erret; 16775 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 16776 *p = c; 16777 newargs.ga_len++; 16778 if (*p == ',') 16779 ++p; 16780 else 16781 mustend = TRUE; 16782 } 16783 p = skipwhite(p); 16784 if (mustend && *p != ')') 16785 { 16786 if (!eap->skip) 16787 EMSG2(_(e_invarg2), eap->arg); 16788 break; 16789 } 16790 } 16791 ++p; /* skip the ')' */ 16792 16793 /* find extra arguments "range", "dict" and "abort" */ 16794 for (;;) 16795 { 16796 p = skipwhite(p); 16797 if (STRNCMP(p, "range", 5) == 0) 16798 { 16799 flags |= FC_RANGE; 16800 p += 5; 16801 } 16802 else if (STRNCMP(p, "dict", 4) == 0) 16803 { 16804 flags |= FC_DICT; 16805 p += 4; 16806 } 16807 else if (STRNCMP(p, "abort", 5) == 0) 16808 { 16809 flags |= FC_ABORT; 16810 p += 5; 16811 } 16812 else 16813 break; 16814 } 16815 16816 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 16817 EMSG(_(e_trailing)); 16818 16819 /* 16820 * Read the body of the function, until ":endfunction" is found. 16821 */ 16822 if (KeyTyped) 16823 { 16824 /* Check if the function already exists, don't let the user type the 16825 * whole function before telling him it doesn't work! For a script we 16826 * need to skip the body to be able to find what follows. */ 16827 if (!eap->skip && !eap->forceit) 16828 { 16829 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 16830 EMSG(_(e_funcdict)); 16831 else if (name != NULL && find_func(name) != NULL) 16832 emsg_funcname(e_funcexts, name); 16833 } 16834 16835 if (!eap->skip && did_emsg) 16836 goto erret; 16837 16838 msg_putchar('\n'); /* don't overwrite the function name */ 16839 cmdline_row = msg_row; 16840 } 16841 16842 indent = 2; 16843 nesting = 0; 16844 for (;;) 16845 { 16846 msg_scroll = TRUE; 16847 need_wait_return = FALSE; 16848 if (eap->getline == NULL) 16849 theline = getcmdline(':', 0L, indent); 16850 else 16851 theline = eap->getline(':', eap->cookie, indent); 16852 if (KeyTyped) 16853 lines_left = Rows - 1; 16854 if (theline == NULL) 16855 { 16856 EMSG(_("E126: Missing :endfunction")); 16857 goto erret; 16858 } 16859 16860 if (skip_until != NULL) 16861 { 16862 /* between ":append" and "." and between ":python <<EOF" and "EOF" 16863 * don't check for ":endfunc". */ 16864 if (STRCMP(theline, skip_until) == 0) 16865 { 16866 vim_free(skip_until); 16867 skip_until = NULL; 16868 } 16869 } 16870 else 16871 { 16872 /* skip ':' and blanks*/ 16873 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 16874 ; 16875 16876 /* Check for "endfunction". */ 16877 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 16878 { 16879 vim_free(theline); 16880 break; 16881 } 16882 16883 /* Increase indent inside "if", "while", "for" and "try", decrease 16884 * at "end". */ 16885 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 16886 indent -= 2; 16887 else if (STRNCMP(p, "if", 2) == 0 16888 || STRNCMP(p, "wh", 2) == 0 16889 || STRNCMP(p, "for", 3) == 0 16890 || STRNCMP(p, "try", 3) == 0) 16891 indent += 2; 16892 16893 /* Check for defining a function inside this function. */ 16894 if (checkforcmd(&p, "function", 2)) 16895 { 16896 if (*p == '!') 16897 p = skipwhite(p + 1); 16898 p += eval_fname_script(p); 16899 if (ASCII_ISALPHA(*p)) 16900 { 16901 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 16902 if (*skipwhite(p) == '(') 16903 { 16904 ++nesting; 16905 indent += 2; 16906 } 16907 } 16908 } 16909 16910 /* Check for ":append" or ":insert". */ 16911 p = skip_range(p, NULL); 16912 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 16913 || (p[0] == 'i' 16914 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 16915 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 16916 skip_until = vim_strsave((char_u *)"."); 16917 16918 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 16919 arg = skipwhite(skiptowhite(p)); 16920 if (arg[0] == '<' && arg[1] =='<' 16921 && ((p[0] == 'p' && p[1] == 'y' 16922 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 16923 || (p[0] == 'p' && p[1] == 'e' 16924 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 16925 || (p[0] == 't' && p[1] == 'c' 16926 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 16927 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 16928 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 16929 || (p[0] == 'm' && p[1] == 'z' 16930 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 16931 )) 16932 { 16933 /* ":python <<" continues until a dot, like ":append" */ 16934 p = skipwhite(arg + 2); 16935 if (*p == NUL) 16936 skip_until = vim_strsave((char_u *)"."); 16937 else 16938 skip_until = vim_strsave(p); 16939 } 16940 } 16941 16942 /* Add the line to the function. */ 16943 if (ga_grow(&newlines, 1) == FAIL) 16944 { 16945 vim_free(theline); 16946 goto erret; 16947 } 16948 16949 /* Copy the line to newly allocated memory. get_one_sourceline() 16950 * allocates 250 bytes per line, this saves 80% on average. The cost 16951 * is an extra alloc/free. */ 16952 p = vim_strsave(theline); 16953 if (p != NULL) 16954 { 16955 vim_free(theline); 16956 theline = p; 16957 } 16958 16959 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 16960 newlines.ga_len++; 16961 } 16962 16963 /* Don't define the function when skipping commands or when an error was 16964 * detected. */ 16965 if (eap->skip || did_emsg) 16966 goto erret; 16967 16968 /* 16969 * If there are no errors, add the function 16970 */ 16971 if (fudi.fd_dict == NULL) 16972 { 16973 v = find_var(name, &ht); 16974 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 16975 { 16976 emsg_funcname("E707: Function name conflicts with variable: %s", 16977 name); 16978 goto erret; 16979 } 16980 16981 fp = find_func(name); 16982 if (fp != NULL) 16983 { 16984 if (!eap->forceit) 16985 { 16986 emsg_funcname(e_funcexts, name); 16987 goto erret; 16988 } 16989 if (fp->uf_calls > 0) 16990 { 16991 emsg_funcname("E127: Cannot redefine function %s: It is in use", 16992 name); 16993 goto erret; 16994 } 16995 /* redefine existing function */ 16996 ga_clear_strings(&(fp->uf_args)); 16997 ga_clear_strings(&(fp->uf_lines)); 16998 vim_free(name); 16999 name = NULL; 17000 } 17001 } 17002 else 17003 { 17004 char numbuf[20]; 17005 17006 fp = NULL; 17007 if (fudi.fd_newkey == NULL && !eap->forceit) 17008 { 17009 EMSG(_(e_funcdict)); 17010 goto erret; 17011 } 17012 if (fudi.fd_di == NULL) 17013 { 17014 /* Can't add a function to a locked dictionary */ 17015 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17016 goto erret; 17017 } 17018 /* Can't change an existing function if it is locked */ 17019 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17020 goto erret; 17021 17022 /* Give the function a sequential number. Can only be used with a 17023 * Funcref! */ 17024 vim_free(name); 17025 sprintf(numbuf, "%d", ++func_nr); 17026 name = vim_strsave((char_u *)numbuf); 17027 if (name == NULL) 17028 goto erret; 17029 } 17030 17031 if (fp == NULL) 17032 { 17033 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17034 { 17035 int slen, plen; 17036 char_u *scriptname; 17037 17038 /* Check that the autoload name matches the script name. */ 17039 j = FAIL; 17040 if (sourcing_name != NULL) 17041 { 17042 scriptname = autoload_name(name); 17043 if (scriptname != NULL) 17044 { 17045 p = vim_strchr(scriptname, '/'); 17046 plen = STRLEN(p); 17047 slen = STRLEN(sourcing_name); 17048 if (slen > plen && fnamecmp(p, 17049 sourcing_name + slen - plen) == 0) 17050 j = OK; 17051 vim_free(scriptname); 17052 } 17053 } 17054 if (j == FAIL) 17055 { 17056 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17057 goto erret; 17058 } 17059 } 17060 17061 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17062 if (fp == NULL) 17063 goto erret; 17064 17065 if (fudi.fd_dict != NULL) 17066 { 17067 if (fudi.fd_di == NULL) 17068 { 17069 /* add new dict entry */ 17070 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17071 if (fudi.fd_di == NULL) 17072 { 17073 vim_free(fp); 17074 goto erret; 17075 } 17076 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17077 { 17078 vim_free(fudi.fd_di); 17079 goto erret; 17080 } 17081 } 17082 else 17083 /* overwrite existing dict entry */ 17084 clear_tv(&fudi.fd_di->di_tv); 17085 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17086 fudi.fd_di->di_tv.v_lock = 0; 17087 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17088 fp->uf_refcount = 1; 17089 } 17090 17091 /* insert the new function in the function list */ 17092 STRCPY(fp->uf_name, name); 17093 hash_add(&func_hashtab, UF2HIKEY(fp)); 17094 } 17095 fp->uf_args = newargs; 17096 fp->uf_lines = newlines; 17097 #ifdef FEAT_PROFILE 17098 fp->uf_tml_count = NULL; 17099 fp->uf_tml_total = NULL; 17100 fp->uf_tml_self = NULL; 17101 fp->uf_profiling = FALSE; 17102 if (prof_def_func()) 17103 func_do_profile(fp); 17104 #endif 17105 fp->uf_varargs = varargs; 17106 fp->uf_flags = flags; 17107 fp->uf_calls = 0; 17108 fp->uf_script_ID = current_SID; 17109 goto ret_free; 17110 17111 erret: 17112 ga_clear_strings(&newargs); 17113 ga_clear_strings(&newlines); 17114 ret_free: 17115 vim_free(skip_until); 17116 vim_free(fudi.fd_newkey); 17117 vim_free(name); 17118 did_emsg |= saved_did_emsg; 17119 } 17120 17121 /* 17122 * Get a function name, translating "<SID>" and "<SNR>". 17123 * Also handles a Funcref in a List or Dictionary. 17124 * Returns the function name in allocated memory, or NULL for failure. 17125 * flags: 17126 * TFN_INT: internal function name OK 17127 * TFN_QUIET: be quiet 17128 * Advances "pp" to just after the function name (if no error). 17129 */ 17130 static char_u * 17131 trans_function_name(pp, skip, flags, fdp) 17132 char_u **pp; 17133 int skip; /* only find the end, don't evaluate */ 17134 int flags; 17135 funcdict_T *fdp; /* return: info about dictionary used */ 17136 { 17137 char_u *name = NULL; 17138 char_u *start; 17139 char_u *end; 17140 int lead; 17141 char_u sid_buf[20]; 17142 int len; 17143 lval_T lv; 17144 17145 if (fdp != NULL) 17146 vim_memset(fdp, 0, sizeof(funcdict_T)); 17147 start = *pp; 17148 17149 /* Check for hard coded <SNR>: already translated function ID (from a user 17150 * command). */ 17151 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17152 && (*pp)[2] == (int)KE_SNR) 17153 { 17154 *pp += 3; 17155 len = get_id_len(pp) + 3; 17156 return vim_strnsave(start, len); 17157 } 17158 17159 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17160 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17161 lead = eval_fname_script(start); 17162 if (lead > 2) 17163 start += lead; 17164 17165 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17166 lead > 2 ? 0 : FNE_CHECK_START); 17167 if (end == start) 17168 { 17169 if (!skip) 17170 EMSG(_("E129: Function name required")); 17171 goto theend; 17172 } 17173 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17174 { 17175 /* 17176 * Report an invalid expression in braces, unless the expression 17177 * evaluation has been cancelled due to an aborting error, an 17178 * interrupt, or an exception. 17179 */ 17180 if (!aborting()) 17181 { 17182 if (end != NULL) 17183 EMSG2(_(e_invarg2), start); 17184 } 17185 else 17186 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17187 goto theend; 17188 } 17189 17190 if (lv.ll_tv != NULL) 17191 { 17192 if (fdp != NULL) 17193 { 17194 fdp->fd_dict = lv.ll_dict; 17195 fdp->fd_newkey = lv.ll_newkey; 17196 lv.ll_newkey = NULL; 17197 fdp->fd_di = lv.ll_di; 17198 } 17199 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17200 { 17201 name = vim_strsave(lv.ll_tv->vval.v_string); 17202 *pp = end; 17203 } 17204 else 17205 { 17206 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17207 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17208 EMSG(_(e_funcref)); 17209 else 17210 *pp = end; 17211 name = NULL; 17212 } 17213 goto theend; 17214 } 17215 17216 if (lv.ll_name == NULL) 17217 { 17218 /* Error found, but continue after the function name. */ 17219 *pp = end; 17220 goto theend; 17221 } 17222 17223 if (lv.ll_exp_name != NULL) 17224 len = STRLEN(lv.ll_exp_name); 17225 else 17226 { 17227 if (lead == 2) /* skip over "s:" */ 17228 lv.ll_name += 2; 17229 len = (int)(end - lv.ll_name); 17230 } 17231 17232 /* 17233 * Copy the function name to allocated memory. 17234 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17235 * Accept <SNR>123_name() outside a script. 17236 */ 17237 if (skip) 17238 lead = 0; /* do nothing */ 17239 else if (lead > 0) 17240 { 17241 lead = 3; 17242 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17243 { 17244 if (current_SID <= 0) 17245 { 17246 EMSG(_(e_usingsid)); 17247 goto theend; 17248 } 17249 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17250 lead += (int)STRLEN(sid_buf); 17251 } 17252 } 17253 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17254 { 17255 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17256 goto theend; 17257 } 17258 name = alloc((unsigned)(len + lead + 1)); 17259 if (name != NULL) 17260 { 17261 if (lead > 0) 17262 { 17263 name[0] = K_SPECIAL; 17264 name[1] = KS_EXTRA; 17265 name[2] = (int)KE_SNR; 17266 if (lead > 3) /* If it's "<SID>" */ 17267 STRCPY(name + 3, sid_buf); 17268 } 17269 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17270 name[len + lead] = NUL; 17271 } 17272 *pp = end; 17273 17274 theend: 17275 clear_lval(&lv); 17276 return name; 17277 } 17278 17279 /* 17280 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17281 * Return 2 if "p" starts with "s:". 17282 * Return 0 otherwise. 17283 */ 17284 static int 17285 eval_fname_script(p) 17286 char_u *p; 17287 { 17288 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17289 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17290 return 5; 17291 if (p[0] == 's' && p[1] == ':') 17292 return 2; 17293 return 0; 17294 } 17295 17296 /* 17297 * Return TRUE if "p" starts with "<SID>" or "s:". 17298 * Only works if eval_fname_script() returned non-zero for "p"! 17299 */ 17300 static int 17301 eval_fname_sid(p) 17302 char_u *p; 17303 { 17304 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17305 } 17306 17307 /* 17308 * List the head of the function: "name(arg1, arg2)". 17309 */ 17310 static void 17311 list_func_head(fp, indent) 17312 ufunc_T *fp; 17313 int indent; 17314 { 17315 int j; 17316 17317 msg_start(); 17318 if (indent) 17319 MSG_PUTS(" "); 17320 MSG_PUTS("function "); 17321 if (fp->uf_name[0] == K_SPECIAL) 17322 { 17323 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17324 msg_puts(fp->uf_name + 3); 17325 } 17326 else 17327 msg_puts(fp->uf_name); 17328 msg_putchar('('); 17329 for (j = 0; j < fp->uf_args.ga_len; ++j) 17330 { 17331 if (j) 17332 MSG_PUTS(", "); 17333 msg_puts(FUNCARG(fp, j)); 17334 } 17335 if (fp->uf_varargs) 17336 { 17337 if (j) 17338 MSG_PUTS(", "); 17339 MSG_PUTS("..."); 17340 } 17341 msg_putchar(')'); 17342 } 17343 17344 /* 17345 * Find a function by name, return pointer to it in ufuncs. 17346 * Return NULL for unknown function. 17347 */ 17348 static ufunc_T * 17349 find_func(name) 17350 char_u *name; 17351 { 17352 hashitem_T *hi; 17353 17354 hi = hash_find(&func_hashtab, name); 17355 if (!HASHITEM_EMPTY(hi)) 17356 return HI2UF(hi); 17357 return NULL; 17358 } 17359 17360 #if defined(EXITFREE) || defined(PROTO) 17361 void 17362 free_all_functions() 17363 { 17364 hashitem_T *hi; 17365 17366 /* Need to start all over every time, because func_free() may change the 17367 * hash table. */ 17368 while (func_hashtab.ht_used > 0) 17369 for (hi = func_hashtab.ht_array; ; ++hi) 17370 if (!HASHITEM_EMPTY(hi)) 17371 { 17372 func_free(HI2UF(hi)); 17373 break; 17374 } 17375 } 17376 #endif 17377 17378 /* 17379 * Return TRUE if a function "name" exists. 17380 */ 17381 static int 17382 function_exists(name) 17383 char_u *name; 17384 { 17385 char_u *p = name; 17386 int n = FALSE; 17387 17388 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17389 if (p != NULL) 17390 { 17391 if (builtin_function(p)) 17392 n = (find_internal_func(p) >= 0); 17393 else 17394 n = (find_func(p) != NULL); 17395 vim_free(p); 17396 } 17397 return n; 17398 } 17399 17400 /* 17401 * Return TRUE if "name" looks like a builtin function name: starts with a 17402 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17403 */ 17404 static int 17405 builtin_function(name) 17406 char_u *name; 17407 { 17408 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17409 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17410 } 17411 17412 #if defined(FEAT_PROFILE) || defined(PROTO) 17413 /* 17414 * Start profiling function "fp". 17415 */ 17416 static void 17417 func_do_profile(fp) 17418 ufunc_T *fp; 17419 { 17420 fp->uf_tm_count = 0; 17421 profile_zero(&fp->uf_tm_self); 17422 profile_zero(&fp->uf_tm_total); 17423 if (fp->uf_tml_count == NULL) 17424 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17425 (sizeof(int) * fp->uf_lines.ga_len)); 17426 if (fp->uf_tml_total == NULL) 17427 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17428 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17429 if (fp->uf_tml_self == NULL) 17430 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17431 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17432 fp->uf_tml_idx = -1; 17433 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17434 || fp->uf_tml_self == NULL) 17435 return; /* out of memory */ 17436 17437 fp->uf_profiling = TRUE; 17438 } 17439 17440 /* 17441 * Dump the profiling results for all functions in file "fd". 17442 */ 17443 void 17444 func_dump_profile(fd) 17445 FILE *fd; 17446 { 17447 hashitem_T *hi; 17448 int todo; 17449 ufunc_T *fp; 17450 int i; 17451 ufunc_T **sorttab; 17452 int st_len = 0; 17453 17454 todo = func_hashtab.ht_used; 17455 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17456 17457 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17458 { 17459 if (!HASHITEM_EMPTY(hi)) 17460 { 17461 --todo; 17462 fp = HI2UF(hi); 17463 if (fp->uf_profiling) 17464 { 17465 if (sorttab != NULL) 17466 sorttab[st_len++] = fp; 17467 17468 if (fp->uf_name[0] == K_SPECIAL) 17469 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17470 else 17471 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17472 if (fp->uf_tm_count == 1) 17473 fprintf(fd, "Called 1 time\n"); 17474 else 17475 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17476 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17477 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17478 fprintf(fd, "\n"); 17479 fprintf(fd, "count total (s) self (s)\n"); 17480 17481 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17482 { 17483 prof_func_line(fd, fp->uf_tml_count[i], 17484 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17485 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17486 } 17487 fprintf(fd, "\n"); 17488 } 17489 } 17490 } 17491 17492 if (sorttab != NULL && st_len > 0) 17493 { 17494 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17495 prof_total_cmp); 17496 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17497 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17498 prof_self_cmp); 17499 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17500 } 17501 } 17502 17503 static void 17504 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17505 FILE *fd; 17506 ufunc_T **sorttab; 17507 int st_len; 17508 char *title; 17509 int prefer_self; /* when equal print only self time */ 17510 { 17511 int i; 17512 ufunc_T *fp; 17513 17514 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17515 fprintf(fd, "count total (s) self (s) function\n"); 17516 for (i = 0; i < 20 && i < st_len; ++i) 17517 { 17518 fp = sorttab[i]; 17519 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17520 prefer_self); 17521 if (fp->uf_name[0] == K_SPECIAL) 17522 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17523 else 17524 fprintf(fd, " %s()\n", fp->uf_name); 17525 } 17526 fprintf(fd, "\n"); 17527 } 17528 17529 /* 17530 * Print the count and times for one function or function line. 17531 */ 17532 static void 17533 prof_func_line(fd, count, total, self, prefer_self) 17534 FILE *fd; 17535 int count; 17536 proftime_T *total; 17537 proftime_T *self; 17538 int prefer_self; /* when equal print only self time */ 17539 { 17540 if (count > 0) 17541 { 17542 fprintf(fd, "%5d ", count); 17543 if (prefer_self && profile_equal(total, self)) 17544 fprintf(fd, " "); 17545 else 17546 fprintf(fd, "%s ", profile_msg(total)); 17547 if (!prefer_self && profile_equal(total, self)) 17548 fprintf(fd, " "); 17549 else 17550 fprintf(fd, "%s ", profile_msg(self)); 17551 } 17552 else 17553 fprintf(fd, " "); 17554 } 17555 17556 /* 17557 * Compare function for total time sorting. 17558 */ 17559 static int 17560 #ifdef __BORLANDC__ 17561 _RTLENTRYF 17562 #endif 17563 prof_total_cmp(s1, s2) 17564 const void *s1; 17565 const void *s2; 17566 { 17567 ufunc_T *p1, *p2; 17568 17569 p1 = *(ufunc_T **)s1; 17570 p2 = *(ufunc_T **)s2; 17571 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 17572 } 17573 17574 /* 17575 * Compare function for self time sorting. 17576 */ 17577 static int 17578 #ifdef __BORLANDC__ 17579 _RTLENTRYF 17580 #endif 17581 prof_self_cmp(s1, s2) 17582 const void *s1; 17583 const void *s2; 17584 { 17585 ufunc_T *p1, *p2; 17586 17587 p1 = *(ufunc_T **)s1; 17588 p2 = *(ufunc_T **)s2; 17589 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 17590 } 17591 17592 #endif 17593 17594 /* The names of packages that once were loaded is remembered. */ 17595 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 17596 17597 /* 17598 * If "name" has a package name try autoloading the script for it. 17599 * Return TRUE if a package was loaded. 17600 */ 17601 static int 17602 script_autoload(name, reload) 17603 char_u *name; 17604 int reload; /* load script again when already loaded */ 17605 { 17606 char_u *p; 17607 char_u *scriptname, *tofree; 17608 int ret = FALSE; 17609 int i; 17610 17611 /* If there is no '#' after name[0] there is no package name. */ 17612 p = vim_strchr(name, AUTOLOAD_CHAR); 17613 if (p == NULL || p == name) 17614 return FALSE; 17615 17616 tofree = scriptname = autoload_name(name); 17617 17618 /* Find the name in the list of previously loaded package names. Skip 17619 * "autoload/", it's always the same. */ 17620 for (i = 0; i < ga_loaded.ga_len; ++i) 17621 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 17622 break; 17623 if (!reload && i < ga_loaded.ga_len) 17624 ret = FALSE; /* was loaded already */ 17625 else 17626 { 17627 /* Remember the name if it wasn't loaded already. */ 17628 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 17629 { 17630 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 17631 tofree = NULL; 17632 } 17633 17634 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 17635 if (cmd_runtime(scriptname, FALSE) == OK) 17636 ret = TRUE; 17637 } 17638 17639 vim_free(tofree); 17640 return ret; 17641 } 17642 17643 /* 17644 * Return the autoload script name for a function or variable name. 17645 * Returns NULL when out of memory. 17646 */ 17647 static char_u * 17648 autoload_name(name) 17649 char_u *name; 17650 { 17651 char_u *p; 17652 char_u *scriptname; 17653 17654 /* Get the script file name: replace '#' with '/', append ".vim". */ 17655 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 17656 if (scriptname == NULL) 17657 return FALSE; 17658 STRCPY(scriptname, "autoload/"); 17659 STRCAT(scriptname, name); 17660 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 17661 STRCAT(scriptname, ".vim"); 17662 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 17663 *p = '/'; 17664 return scriptname; 17665 } 17666 17667 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 17668 17669 /* 17670 * Function given to ExpandGeneric() to obtain the list of user defined 17671 * function names. 17672 */ 17673 char_u * 17674 get_user_func_name(xp, idx) 17675 expand_T *xp; 17676 int idx; 17677 { 17678 static long_u done; 17679 static hashitem_T *hi; 17680 ufunc_T *fp; 17681 17682 if (idx == 0) 17683 { 17684 done = 0; 17685 hi = func_hashtab.ht_array; 17686 } 17687 if (done < func_hashtab.ht_used) 17688 { 17689 if (done++ > 0) 17690 ++hi; 17691 while (HASHITEM_EMPTY(hi)) 17692 ++hi; 17693 fp = HI2UF(hi); 17694 17695 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 17696 return fp->uf_name; /* prevents overflow */ 17697 17698 cat_func_name(IObuff, fp); 17699 if (xp->xp_context != EXPAND_USER_FUNC) 17700 { 17701 STRCAT(IObuff, "("); 17702 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 17703 STRCAT(IObuff, ")"); 17704 } 17705 return IObuff; 17706 } 17707 return NULL; 17708 } 17709 17710 #endif /* FEAT_CMDL_COMPL */ 17711 17712 /* 17713 * Copy the function name of "fp" to buffer "buf". 17714 * "buf" must be able to hold the function name plus three bytes. 17715 * Takes care of script-local function names. 17716 */ 17717 static void 17718 cat_func_name(buf, fp) 17719 char_u *buf; 17720 ufunc_T *fp; 17721 { 17722 if (fp->uf_name[0] == K_SPECIAL) 17723 { 17724 STRCPY(buf, "<SNR>"); 17725 STRCAT(buf, fp->uf_name + 3); 17726 } 17727 else 17728 STRCPY(buf, fp->uf_name); 17729 } 17730 17731 /* 17732 * ":delfunction {name}" 17733 */ 17734 void 17735 ex_delfunction(eap) 17736 exarg_T *eap; 17737 { 17738 ufunc_T *fp = NULL; 17739 char_u *p; 17740 char_u *name; 17741 funcdict_T fudi; 17742 17743 p = eap->arg; 17744 name = trans_function_name(&p, eap->skip, 0, &fudi); 17745 vim_free(fudi.fd_newkey); 17746 if (name == NULL) 17747 { 17748 if (fudi.fd_dict != NULL && !eap->skip) 17749 EMSG(_(e_funcref)); 17750 return; 17751 } 17752 if (!ends_excmd(*skipwhite(p))) 17753 { 17754 vim_free(name); 17755 EMSG(_(e_trailing)); 17756 return; 17757 } 17758 eap->nextcmd = check_nextcmd(p); 17759 if (eap->nextcmd != NULL) 17760 *p = NUL; 17761 17762 if (!eap->skip) 17763 fp = find_func(name); 17764 vim_free(name); 17765 17766 if (!eap->skip) 17767 { 17768 if (fp == NULL) 17769 { 17770 EMSG2(_(e_nofunc), eap->arg); 17771 return; 17772 } 17773 if (fp->uf_calls > 0) 17774 { 17775 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 17776 return; 17777 } 17778 17779 if (fudi.fd_dict != NULL) 17780 { 17781 /* Delete the dict item that refers to the function, it will 17782 * invoke func_unref() and possibly delete the function. */ 17783 dictitem_remove(fudi.fd_dict, fudi.fd_di); 17784 } 17785 else 17786 func_free(fp); 17787 } 17788 } 17789 17790 /* 17791 * Free a function and remove it from the list of functions. 17792 */ 17793 static void 17794 func_free(fp) 17795 ufunc_T *fp; 17796 { 17797 hashitem_T *hi; 17798 17799 /* clear this function */ 17800 ga_clear_strings(&(fp->uf_args)); 17801 ga_clear_strings(&(fp->uf_lines)); 17802 #ifdef FEAT_PROFILE 17803 vim_free(fp->uf_tml_count); 17804 vim_free(fp->uf_tml_total); 17805 vim_free(fp->uf_tml_self); 17806 #endif 17807 17808 /* remove the function from the function hashtable */ 17809 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 17810 if (HASHITEM_EMPTY(hi)) 17811 EMSG2(_(e_intern2), "func_free()"); 17812 else 17813 hash_remove(&func_hashtab, hi); 17814 17815 vim_free(fp); 17816 } 17817 17818 /* 17819 * Unreference a Function: decrement the reference count and free it when it 17820 * becomes zero. Only for numbered functions. 17821 */ 17822 static void 17823 func_unref(name) 17824 char_u *name; 17825 { 17826 ufunc_T *fp; 17827 17828 if (name != NULL && isdigit(*name)) 17829 { 17830 fp = find_func(name); 17831 if (fp == NULL) 17832 EMSG2(_(e_intern2), "func_unref()"); 17833 else if (--fp->uf_refcount <= 0) 17834 { 17835 /* Only delete it when it's not being used. Otherwise it's done 17836 * when "uf_calls" becomes zero. */ 17837 if (fp->uf_calls == 0) 17838 func_free(fp); 17839 } 17840 } 17841 } 17842 17843 /* 17844 * Count a reference to a Function. 17845 */ 17846 static void 17847 func_ref(name) 17848 char_u *name; 17849 { 17850 ufunc_T *fp; 17851 17852 if (name != NULL && isdigit(*name)) 17853 { 17854 fp = find_func(name); 17855 if (fp == NULL) 17856 EMSG2(_(e_intern2), "func_ref()"); 17857 else 17858 ++fp->uf_refcount; 17859 } 17860 } 17861 17862 /* 17863 * Call a user function. 17864 */ 17865 static void 17866 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 17867 ufunc_T *fp; /* pointer to function */ 17868 int argcount; /* nr of args */ 17869 typval_T *argvars; /* arguments */ 17870 typval_T *rettv; /* return value */ 17871 linenr_T firstline; /* first line of range */ 17872 linenr_T lastline; /* last line of range */ 17873 dict_T *selfdict; /* Dictionary for "self" */ 17874 { 17875 char_u *save_sourcing_name; 17876 linenr_T save_sourcing_lnum; 17877 scid_T save_current_SID; 17878 funccall_T fc; 17879 int save_did_emsg; 17880 static int depth = 0; 17881 dictitem_T *v; 17882 int fixvar_idx = 0; /* index in fixvar[] */ 17883 int i; 17884 int ai; 17885 char_u numbuf[NUMBUFLEN]; 17886 char_u *name; 17887 #ifdef FEAT_PROFILE 17888 proftime_T wait_start; 17889 #endif 17890 17891 /* If depth of calling is getting too high, don't execute the function */ 17892 if (depth >= p_mfd) 17893 { 17894 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 17895 rettv->v_type = VAR_NUMBER; 17896 rettv->vval.v_number = -1; 17897 return; 17898 } 17899 ++depth; 17900 17901 line_breakcheck(); /* check for CTRL-C hit */ 17902 17903 fc.caller = current_funccal; 17904 current_funccal = &fc; 17905 fc.func = fp; 17906 fc.rettv = rettv; 17907 rettv->vval.v_number = 0; 17908 fc.linenr = 0; 17909 fc.returned = FALSE; 17910 fc.level = ex_nesting_level; 17911 /* Check if this function has a breakpoint. */ 17912 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 17913 fc.dbg_tick = debug_tick; 17914 17915 /* 17916 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 17917 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 17918 * each argument variable and saves a lot of time. 17919 */ 17920 /* 17921 * Init l: variables. 17922 */ 17923 init_var_dict(&fc.l_vars, &fc.l_vars_var); 17924 if (selfdict != NULL) 17925 { 17926 /* Set l:self to "selfdict". */ 17927 v = &fc.fixvar[fixvar_idx++].var; 17928 STRCPY(v->di_key, "self"); 17929 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 17930 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 17931 v->di_tv.v_type = VAR_DICT; 17932 v->di_tv.v_lock = 0; 17933 v->di_tv.vval.v_dict = selfdict; 17934 ++selfdict->dv_refcount; 17935 } 17936 17937 /* 17938 * Init a: variables. 17939 * Set a:0 to "argcount". 17940 * Set a:000 to a list with room for the "..." arguments. 17941 */ 17942 init_var_dict(&fc.l_avars, &fc.l_avars_var); 17943 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 17944 (varnumber_T)(argcount - fp->uf_args.ga_len)); 17945 v = &fc.fixvar[fixvar_idx++].var; 17946 STRCPY(v->di_key, "000"); 17947 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 17948 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 17949 v->di_tv.v_type = VAR_LIST; 17950 v->di_tv.v_lock = VAR_FIXED; 17951 v->di_tv.vval.v_list = &fc.l_varlist; 17952 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 17953 fc.l_varlist.lv_refcount = 99999; 17954 17955 /* 17956 * Set a:firstline to "firstline" and a:lastline to "lastline". 17957 * Set a:name to named arguments. 17958 * Set a:N to the "..." arguments. 17959 */ 17960 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 17961 (varnumber_T)firstline); 17962 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 17963 (varnumber_T)lastline); 17964 for (i = 0; i < argcount; ++i) 17965 { 17966 ai = i - fp->uf_args.ga_len; 17967 if (ai < 0) 17968 /* named argument a:name */ 17969 name = FUNCARG(fp, i); 17970 else 17971 { 17972 /* "..." argument a:1, a:2, etc. */ 17973 sprintf((char *)numbuf, "%d", ai + 1); 17974 name = numbuf; 17975 } 17976 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 17977 { 17978 v = &fc.fixvar[fixvar_idx++].var; 17979 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 17980 } 17981 else 17982 { 17983 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 17984 + STRLEN(name))); 17985 if (v == NULL) 17986 break; 17987 v->di_flags = DI_FLAGS_RO; 17988 } 17989 STRCPY(v->di_key, name); 17990 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 17991 17992 /* Note: the values are copied directly to avoid alloc/free. 17993 * "argvars" must have VAR_FIXED for v_lock. */ 17994 v->di_tv = argvars[i]; 17995 v->di_tv.v_lock = VAR_FIXED; 17996 17997 if (ai >= 0 && ai < MAX_FUNC_ARGS) 17998 { 17999 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18000 fc.l_listitems[ai].li_tv = argvars[i]; 18001 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18002 } 18003 } 18004 18005 /* Don't redraw while executing the function. */ 18006 ++RedrawingDisabled; 18007 save_sourcing_name = sourcing_name; 18008 save_sourcing_lnum = sourcing_lnum; 18009 sourcing_lnum = 1; 18010 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18011 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18012 if (sourcing_name != NULL) 18013 { 18014 if (save_sourcing_name != NULL 18015 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18016 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18017 else 18018 STRCPY(sourcing_name, "function "); 18019 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18020 18021 if (p_verbose >= 12) 18022 { 18023 ++no_wait_return; 18024 verbose_enter_scroll(); 18025 18026 smsg((char_u *)_("calling %s"), sourcing_name); 18027 if (p_verbose >= 14) 18028 { 18029 char_u buf[MSG_BUF_LEN]; 18030 char_u numbuf[NUMBUFLEN]; 18031 char_u *tofree; 18032 18033 msg_puts((char_u *)"("); 18034 for (i = 0; i < argcount; ++i) 18035 { 18036 if (i > 0) 18037 msg_puts((char_u *)", "); 18038 if (argvars[i].v_type == VAR_NUMBER) 18039 msg_outnum((long)argvars[i].vval.v_number); 18040 else 18041 { 18042 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18043 buf, MSG_BUF_CLEN); 18044 msg_puts(buf); 18045 vim_free(tofree); 18046 } 18047 } 18048 msg_puts((char_u *)")"); 18049 } 18050 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18051 18052 verbose_leave_scroll(); 18053 --no_wait_return; 18054 } 18055 } 18056 #ifdef FEAT_PROFILE 18057 if (do_profiling) 18058 { 18059 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18060 func_do_profile(fp); 18061 if (fp->uf_profiling 18062 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18063 { 18064 ++fp->uf_tm_count; 18065 profile_start(&fp->uf_tm_start); 18066 profile_zero(&fp->uf_tm_children); 18067 } 18068 script_prof_save(&wait_start); 18069 } 18070 #endif 18071 18072 save_current_SID = current_SID; 18073 current_SID = fp->uf_script_ID; 18074 save_did_emsg = did_emsg; 18075 did_emsg = FALSE; 18076 18077 /* call do_cmdline() to execute the lines */ 18078 do_cmdline(NULL, get_func_line, (void *)&fc, 18079 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18080 18081 --RedrawingDisabled; 18082 18083 /* when the function was aborted because of an error, return -1 */ 18084 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18085 { 18086 clear_tv(rettv); 18087 rettv->v_type = VAR_NUMBER; 18088 rettv->vval.v_number = -1; 18089 } 18090 18091 #ifdef FEAT_PROFILE 18092 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18093 { 18094 profile_end(&fp->uf_tm_start); 18095 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18096 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18097 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18098 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18099 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18100 { 18101 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18102 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18103 } 18104 } 18105 #endif 18106 18107 /* when being verbose, mention the return value */ 18108 if (p_verbose >= 12) 18109 { 18110 ++no_wait_return; 18111 verbose_enter_scroll(); 18112 18113 if (aborting()) 18114 smsg((char_u *)_("%s aborted"), sourcing_name); 18115 else if (fc.rettv->v_type == VAR_NUMBER) 18116 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18117 (long)fc.rettv->vval.v_number); 18118 else 18119 { 18120 char_u buf[MSG_BUF_LEN]; 18121 char_u numbuf[NUMBUFLEN]; 18122 char_u *tofree; 18123 18124 /* The value may be very long. Skip the middle part, so that we 18125 * have some idea how it starts and ends. smsg() would always 18126 * truncate it at the end. */ 18127 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18128 buf, MSG_BUF_CLEN); 18129 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18130 vim_free(tofree); 18131 } 18132 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18133 18134 verbose_leave_scroll(); 18135 --no_wait_return; 18136 } 18137 18138 vim_free(sourcing_name); 18139 sourcing_name = save_sourcing_name; 18140 sourcing_lnum = save_sourcing_lnum; 18141 current_SID = save_current_SID; 18142 #ifdef FEAT_PROFILE 18143 if (do_profiling) 18144 script_prof_restore(&wait_start); 18145 #endif 18146 18147 if (p_verbose >= 12 && sourcing_name != NULL) 18148 { 18149 ++no_wait_return; 18150 verbose_enter_scroll(); 18151 18152 smsg((char_u *)_("continuing in %s"), sourcing_name); 18153 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18154 18155 verbose_leave_scroll(); 18156 --no_wait_return; 18157 } 18158 18159 did_emsg |= save_did_emsg; 18160 current_funccal = fc.caller; 18161 18162 /* The a: variables typevals were not alloced, only free the allocated 18163 * variables. */ 18164 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18165 18166 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18167 --depth; 18168 } 18169 18170 /* 18171 * Add a number variable "name" to dict "dp" with value "nr". 18172 */ 18173 static void 18174 add_nr_var(dp, v, name, nr) 18175 dict_T *dp; 18176 dictitem_T *v; 18177 char *name; 18178 varnumber_T nr; 18179 { 18180 STRCPY(v->di_key, name); 18181 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18182 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18183 v->di_tv.v_type = VAR_NUMBER; 18184 v->di_tv.v_lock = VAR_FIXED; 18185 v->di_tv.vval.v_number = nr; 18186 } 18187 18188 /* 18189 * ":return [expr]" 18190 */ 18191 void 18192 ex_return(eap) 18193 exarg_T *eap; 18194 { 18195 char_u *arg = eap->arg; 18196 typval_T rettv; 18197 int returning = FALSE; 18198 18199 if (current_funccal == NULL) 18200 { 18201 EMSG(_("E133: :return not inside a function")); 18202 return; 18203 } 18204 18205 if (eap->skip) 18206 ++emsg_skip; 18207 18208 eap->nextcmd = NULL; 18209 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18210 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18211 { 18212 if (!eap->skip) 18213 returning = do_return(eap, FALSE, TRUE, &rettv); 18214 else 18215 clear_tv(&rettv); 18216 } 18217 /* It's safer to return also on error. */ 18218 else if (!eap->skip) 18219 { 18220 /* 18221 * Return unless the expression evaluation has been cancelled due to an 18222 * aborting error, an interrupt, or an exception. 18223 */ 18224 if (!aborting()) 18225 returning = do_return(eap, FALSE, TRUE, NULL); 18226 } 18227 18228 /* When skipping or the return gets pending, advance to the next command 18229 * in this line (!returning). Otherwise, ignore the rest of the line. 18230 * Following lines will be ignored by get_func_line(). */ 18231 if (returning) 18232 eap->nextcmd = NULL; 18233 else if (eap->nextcmd == NULL) /* no argument */ 18234 eap->nextcmd = check_nextcmd(arg); 18235 18236 if (eap->skip) 18237 --emsg_skip; 18238 } 18239 18240 /* 18241 * Return from a function. Possibly makes the return pending. Also called 18242 * for a pending return at the ":endtry" or after returning from an extra 18243 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18244 * when called due to a ":return" command. "rettv" may point to a typval_T 18245 * with the return rettv. Returns TRUE when the return can be carried out, 18246 * FALSE when the return gets pending. 18247 */ 18248 int 18249 do_return(eap, reanimate, is_cmd, rettv) 18250 exarg_T *eap; 18251 int reanimate; 18252 int is_cmd; 18253 void *rettv; 18254 { 18255 int idx; 18256 struct condstack *cstack = eap->cstack; 18257 18258 if (reanimate) 18259 /* Undo the return. */ 18260 current_funccal->returned = FALSE; 18261 18262 /* 18263 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18264 * not in its finally clause (which then is to be executed next) is found. 18265 * In this case, make the ":return" pending for execution at the ":endtry". 18266 * Otherwise, return normally. 18267 */ 18268 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18269 if (idx >= 0) 18270 { 18271 cstack->cs_pending[idx] = CSTP_RETURN; 18272 18273 if (!is_cmd && !reanimate) 18274 /* A pending return again gets pending. "rettv" points to an 18275 * allocated variable with the rettv of the original ":return"'s 18276 * argument if present or is NULL else. */ 18277 cstack->cs_rettv[idx] = rettv; 18278 else 18279 { 18280 /* When undoing a return in order to make it pending, get the stored 18281 * return rettv. */ 18282 if (reanimate) 18283 rettv = current_funccal->rettv; 18284 18285 if (rettv != NULL) 18286 { 18287 /* Store the value of the pending return. */ 18288 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18289 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18290 else 18291 EMSG(_(e_outofmem)); 18292 } 18293 else 18294 cstack->cs_rettv[idx] = NULL; 18295 18296 if (reanimate) 18297 { 18298 /* The pending return value could be overwritten by a ":return" 18299 * without argument in a finally clause; reset the default 18300 * return value. */ 18301 current_funccal->rettv->v_type = VAR_NUMBER; 18302 current_funccal->rettv->vval.v_number = 0; 18303 } 18304 } 18305 report_make_pending(CSTP_RETURN, rettv); 18306 } 18307 else 18308 { 18309 current_funccal->returned = TRUE; 18310 18311 /* If the return is carried out now, store the return value. For 18312 * a return immediately after reanimation, the value is already 18313 * there. */ 18314 if (!reanimate && rettv != NULL) 18315 { 18316 clear_tv(current_funccal->rettv); 18317 *current_funccal->rettv = *(typval_T *)rettv; 18318 if (!is_cmd) 18319 vim_free(rettv); 18320 } 18321 } 18322 18323 return idx < 0; 18324 } 18325 18326 /* 18327 * Free the variable with a pending return value. 18328 */ 18329 void 18330 discard_pending_return(rettv) 18331 void *rettv; 18332 { 18333 free_tv((typval_T *)rettv); 18334 } 18335 18336 /* 18337 * Generate a return command for producing the value of "rettv". The result 18338 * is an allocated string. Used by report_pending() for verbose messages. 18339 */ 18340 char_u * 18341 get_return_cmd(rettv) 18342 void *rettv; 18343 { 18344 char_u *s = NULL; 18345 char_u *tofree = NULL; 18346 char_u numbuf[NUMBUFLEN]; 18347 18348 if (rettv != NULL) 18349 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18350 if (s == NULL) 18351 s = (char_u *)""; 18352 18353 STRCPY(IObuff, ":return "); 18354 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18355 if (STRLEN(s) + 8 >= IOSIZE) 18356 STRCPY(IObuff + IOSIZE - 4, "..."); 18357 vim_free(tofree); 18358 return vim_strsave(IObuff); 18359 } 18360 18361 /* 18362 * Get next function line. 18363 * Called by do_cmdline() to get the next line. 18364 * Returns allocated string, or NULL for end of function. 18365 */ 18366 /* ARGSUSED */ 18367 char_u * 18368 get_func_line(c, cookie, indent) 18369 int c; /* not used */ 18370 void *cookie; 18371 int indent; /* not used */ 18372 { 18373 funccall_T *fcp = (funccall_T *)cookie; 18374 ufunc_T *fp = fcp->func; 18375 char_u *retval; 18376 garray_T *gap; /* growarray with function lines */ 18377 18378 /* If breakpoints have been added/deleted need to check for it. */ 18379 if (fcp->dbg_tick != debug_tick) 18380 { 18381 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18382 sourcing_lnum); 18383 fcp->dbg_tick = debug_tick; 18384 } 18385 #ifdef FEAT_PROFILE 18386 if (do_profiling) 18387 func_line_end(cookie); 18388 #endif 18389 18390 gap = &fp->uf_lines; 18391 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18392 retval = NULL; 18393 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18394 retval = NULL; 18395 else 18396 { 18397 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18398 sourcing_lnum = fcp->linenr; 18399 #ifdef FEAT_PROFILE 18400 if (do_profiling) 18401 func_line_start(cookie); 18402 #endif 18403 } 18404 18405 /* Did we encounter a breakpoint? */ 18406 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18407 { 18408 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18409 /* Find next breakpoint. */ 18410 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18411 sourcing_lnum); 18412 fcp->dbg_tick = debug_tick; 18413 } 18414 18415 return retval; 18416 } 18417 18418 #if defined(FEAT_PROFILE) || defined(PROTO) 18419 /* 18420 * Called when starting to read a function line. 18421 * "sourcing_lnum" must be correct! 18422 * When skipping lines it may not actually be executed, but we won't find out 18423 * until later and we need to store the time now. 18424 */ 18425 void 18426 func_line_start(cookie) 18427 void *cookie; 18428 { 18429 funccall_T *fcp = (funccall_T *)cookie; 18430 ufunc_T *fp = fcp->func; 18431 18432 if (fp->uf_profiling && sourcing_lnum >= 1 18433 && sourcing_lnum <= fp->uf_lines.ga_len) 18434 { 18435 fp->uf_tml_idx = sourcing_lnum - 1; 18436 fp->uf_tml_execed = FALSE; 18437 profile_start(&fp->uf_tml_start); 18438 profile_zero(&fp->uf_tml_children); 18439 profile_get_wait(&fp->uf_tml_wait); 18440 } 18441 } 18442 18443 /* 18444 * Called when actually executing a function line. 18445 */ 18446 void 18447 func_line_exec(cookie) 18448 void *cookie; 18449 { 18450 funccall_T *fcp = (funccall_T *)cookie; 18451 ufunc_T *fp = fcp->func; 18452 18453 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18454 fp->uf_tml_execed = TRUE; 18455 } 18456 18457 /* 18458 * Called when done with a function line. 18459 */ 18460 void 18461 func_line_end(cookie) 18462 void *cookie; 18463 { 18464 funccall_T *fcp = (funccall_T *)cookie; 18465 ufunc_T *fp = fcp->func; 18466 18467 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18468 { 18469 if (fp->uf_tml_execed) 18470 { 18471 ++fp->uf_tml_count[fp->uf_tml_idx]; 18472 profile_end(&fp->uf_tml_start); 18473 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18474 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18475 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18476 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18477 } 18478 fp->uf_tml_idx = -1; 18479 } 18480 } 18481 #endif 18482 18483 /* 18484 * Return TRUE if the currently active function should be ended, because a 18485 * return was encountered or an error occured. Used inside a ":while". 18486 */ 18487 int 18488 func_has_ended(cookie) 18489 void *cookie; 18490 { 18491 funccall_T *fcp = (funccall_T *)cookie; 18492 18493 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18494 * an error inside a try conditional. */ 18495 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18496 || fcp->returned); 18497 } 18498 18499 /* 18500 * return TRUE if cookie indicates a function which "abort"s on errors. 18501 */ 18502 int 18503 func_has_abort(cookie) 18504 void *cookie; 18505 { 18506 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18507 } 18508 18509 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18510 typedef enum 18511 { 18512 VAR_FLAVOUR_DEFAULT, 18513 VAR_FLAVOUR_SESSION, 18514 VAR_FLAVOUR_VIMINFO 18515 } var_flavour_T; 18516 18517 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18518 18519 static var_flavour_T 18520 var_flavour(varname) 18521 char_u *varname; 18522 { 18523 char_u *p = varname; 18524 18525 if (ASCII_ISUPPER(*p)) 18526 { 18527 while (*(++p)) 18528 if (ASCII_ISLOWER(*p)) 18529 return VAR_FLAVOUR_SESSION; 18530 return VAR_FLAVOUR_VIMINFO; 18531 } 18532 else 18533 return VAR_FLAVOUR_DEFAULT; 18534 } 18535 #endif 18536 18537 #if defined(FEAT_VIMINFO) || defined(PROTO) 18538 /* 18539 * Restore global vars that start with a capital from the viminfo file 18540 */ 18541 int 18542 read_viminfo_varlist(virp, writing) 18543 vir_T *virp; 18544 int writing; 18545 { 18546 char_u *tab; 18547 int is_string = FALSE; 18548 typval_T tv; 18549 18550 if (!writing && (find_viminfo_parameter('!') != NULL)) 18551 { 18552 tab = vim_strchr(virp->vir_line + 1, '\t'); 18553 if (tab != NULL) 18554 { 18555 *tab++ = '\0'; /* isolate the variable name */ 18556 if (*tab == 'S') /* string var */ 18557 is_string = TRUE; 18558 18559 tab = vim_strchr(tab, '\t'); 18560 if (tab != NULL) 18561 { 18562 if (is_string) 18563 { 18564 tv.v_type = VAR_STRING; 18565 tv.vval.v_string = viminfo_readstring(virp, 18566 (int)(tab - virp->vir_line + 1), TRUE); 18567 } 18568 else 18569 { 18570 tv.v_type = VAR_NUMBER; 18571 tv.vval.v_number = atol((char *)tab + 1); 18572 } 18573 set_var(virp->vir_line + 1, &tv, FALSE); 18574 if (is_string) 18575 vim_free(tv.vval.v_string); 18576 } 18577 } 18578 } 18579 18580 return viminfo_readline(virp); 18581 } 18582 18583 /* 18584 * Write global vars that start with a capital to the viminfo file 18585 */ 18586 void 18587 write_viminfo_varlist(fp) 18588 FILE *fp; 18589 { 18590 hashitem_T *hi; 18591 dictitem_T *this_var; 18592 int todo; 18593 char *s; 18594 char_u *p; 18595 char_u *tofree; 18596 char_u numbuf[NUMBUFLEN]; 18597 18598 if (find_viminfo_parameter('!') == NULL) 18599 return; 18600 18601 fprintf(fp, _("\n# global variables:\n")); 18602 18603 todo = globvarht.ht_used; 18604 for (hi = globvarht.ht_array; todo > 0; ++hi) 18605 { 18606 if (!HASHITEM_EMPTY(hi)) 18607 { 18608 --todo; 18609 this_var = HI2DI(hi); 18610 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 18611 { 18612 switch (this_var->di_tv.v_type) 18613 { 18614 case VAR_STRING: s = "STR"; break; 18615 case VAR_NUMBER: s = "NUM"; break; 18616 default: continue; 18617 } 18618 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 18619 p = echo_string(&this_var->di_tv, &tofree, numbuf); 18620 if (p != NULL) 18621 viminfo_writestring(fp, p); 18622 vim_free(tofree); 18623 } 18624 } 18625 } 18626 } 18627 #endif 18628 18629 #if defined(FEAT_SESSION) || defined(PROTO) 18630 int 18631 store_session_globals(fd) 18632 FILE *fd; 18633 { 18634 hashitem_T *hi; 18635 dictitem_T *this_var; 18636 int todo; 18637 char_u *p, *t; 18638 18639 todo = globvarht.ht_used; 18640 for (hi = globvarht.ht_array; todo > 0; ++hi) 18641 { 18642 if (!HASHITEM_EMPTY(hi)) 18643 { 18644 --todo; 18645 this_var = HI2DI(hi); 18646 if ((this_var->di_tv.v_type == VAR_NUMBER 18647 || this_var->di_tv.v_type == VAR_STRING) 18648 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 18649 { 18650 /* Escape special characters with a backslash. Turn a LF and 18651 * CR into \n and \r. */ 18652 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 18653 (char_u *)"\\\"\n\r"); 18654 if (p == NULL) /* out of memory */ 18655 break; 18656 for (t = p; *t != NUL; ++t) 18657 if (*t == '\n') 18658 *t = 'n'; 18659 else if (*t == '\r') 18660 *t = 'r'; 18661 if ((fprintf(fd, "let %s = %c%s%c", 18662 this_var->di_key, 18663 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18664 : ' ', 18665 p, 18666 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18667 : ' ') < 0) 18668 || put_eol(fd) == FAIL) 18669 { 18670 vim_free(p); 18671 return FAIL; 18672 } 18673 vim_free(p); 18674 } 18675 } 18676 } 18677 return OK; 18678 } 18679 #endif 18680 18681 #endif /* FEAT_EVAL */ 18682 18683 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 18684 18685 18686 #ifdef WIN3264 18687 /* 18688 * Functions for ":8" filename modifier: get 8.3 version of a filename. 18689 */ 18690 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18691 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 18692 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18693 18694 /* 18695 * Get the short pathname of a file. 18696 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 18697 */ 18698 static int 18699 get_short_pathname(fnamep, bufp, fnamelen) 18700 char_u **fnamep; 18701 char_u **bufp; 18702 int *fnamelen; 18703 { 18704 int l,len; 18705 char_u *newbuf; 18706 18707 len = *fnamelen; 18708 18709 l = GetShortPathName(*fnamep, *fnamep, len); 18710 if (l > len - 1) 18711 { 18712 /* If that doesn't work (not enough space), then save the string 18713 * and try again with a new buffer big enough 18714 */ 18715 newbuf = vim_strnsave(*fnamep, l); 18716 if (newbuf == NULL) 18717 return 0; 18718 18719 vim_free(*bufp); 18720 *fnamep = *bufp = newbuf; 18721 18722 l = GetShortPathName(*fnamep,*fnamep,l+1); 18723 18724 /* Really should always succeed, as the buffer is big enough */ 18725 } 18726 18727 *fnamelen = l; 18728 return 1; 18729 } 18730 18731 /* 18732 * Create a short path name. Returns the length of the buffer it needs. 18733 * Doesn't copy over the end of the buffer passed in. 18734 */ 18735 static int 18736 shortpath_for_invalid_fname(fname, bufp, fnamelen) 18737 char_u **fname; 18738 char_u **bufp; 18739 int *fnamelen; 18740 { 18741 char_u *s, *p, *pbuf2, *pbuf3; 18742 char_u ch; 18743 int len, len2, plen, slen; 18744 18745 /* Make a copy */ 18746 len2 = *fnamelen; 18747 pbuf2 = vim_strnsave(*fname, len2); 18748 pbuf3 = NULL; 18749 18750 s = pbuf2 + len2 - 1; /* Find the end */ 18751 slen = 1; 18752 plen = len2; 18753 18754 if (after_pathsep(pbuf2, s + 1)) 18755 { 18756 --s; 18757 ++slen; 18758 --plen; 18759 } 18760 18761 do 18762 { 18763 /* Go back one path-seperator */ 18764 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 18765 { 18766 --s; 18767 ++slen; 18768 --plen; 18769 } 18770 if (s <= pbuf2) 18771 break; 18772 18773 /* Remeber the character that is about to be blatted */ 18774 ch = *s; 18775 *s = 0; /* get_short_pathname requires a null-terminated string */ 18776 18777 /* Try it in situ */ 18778 p = pbuf2; 18779 if (!get_short_pathname(&p, &pbuf3, &plen)) 18780 { 18781 vim_free(pbuf2); 18782 return -1; 18783 } 18784 *s = ch; /* Preserve the string */ 18785 } while (plen == 0); 18786 18787 if (plen > 0) 18788 { 18789 /* Remeber the length of the new string. */ 18790 *fnamelen = len = plen + slen; 18791 vim_free(*bufp); 18792 if (len > len2) 18793 { 18794 /* If there's not enough space in the currently allocated string, 18795 * then copy it to a buffer big enough. 18796 */ 18797 *fname= *bufp = vim_strnsave(p, len); 18798 if (*fname == NULL) 18799 return -1; 18800 } 18801 else 18802 { 18803 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 18804 *fname = *bufp = pbuf2; 18805 if (p != pbuf2) 18806 strncpy(*fname, p, plen); 18807 pbuf2 = NULL; 18808 } 18809 /* Concat the next bit */ 18810 strncpy(*fname + plen, s, slen); 18811 (*fname)[len] = '\0'; 18812 } 18813 vim_free(pbuf3); 18814 vim_free(pbuf2); 18815 return 0; 18816 } 18817 18818 /* 18819 * Get a pathname for a partial path. 18820 */ 18821 static int 18822 shortpath_for_partial(fnamep, bufp, fnamelen) 18823 char_u **fnamep; 18824 char_u **bufp; 18825 int *fnamelen; 18826 { 18827 int sepcount, len, tflen; 18828 char_u *p; 18829 char_u *pbuf, *tfname; 18830 int hasTilde; 18831 18832 /* Count up the path seperators from the RHS.. so we know which part 18833 * of the path to return. 18834 */ 18835 sepcount = 0; 18836 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 18837 if (vim_ispathsep(*p)) 18838 ++sepcount; 18839 18840 /* Need full path first (use expand_env() to remove a "~/") */ 18841 hasTilde = (**fnamep == '~'); 18842 if (hasTilde) 18843 pbuf = tfname = expand_env_save(*fnamep); 18844 else 18845 pbuf = tfname = FullName_save(*fnamep, FALSE); 18846 18847 len = tflen = STRLEN(tfname); 18848 18849 if (!get_short_pathname(&tfname, &pbuf, &len)) 18850 return -1; 18851 18852 if (len == 0) 18853 { 18854 /* Don't have a valid filename, so shorten the rest of the 18855 * path if we can. This CAN give us invalid 8.3 filenames, but 18856 * there's not a lot of point in guessing what it might be. 18857 */ 18858 len = tflen; 18859 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 18860 return -1; 18861 } 18862 18863 /* Count the paths backward to find the beginning of the desired string. */ 18864 for (p = tfname + len - 1; p >= tfname; --p) 18865 { 18866 #ifdef FEAT_MBYTE 18867 if (has_mbyte) 18868 p -= mb_head_off(tfname, p); 18869 #endif 18870 if (vim_ispathsep(*p)) 18871 { 18872 if (sepcount == 0 || (hasTilde && sepcount == 1)) 18873 break; 18874 else 18875 sepcount --; 18876 } 18877 } 18878 if (hasTilde) 18879 { 18880 --p; 18881 if (p >= tfname) 18882 *p = '~'; 18883 else 18884 return -1; 18885 } 18886 else 18887 ++p; 18888 18889 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 18890 vim_free(*bufp); 18891 *fnamelen = (int)STRLEN(p); 18892 *bufp = pbuf; 18893 *fnamep = p; 18894 18895 return 0; 18896 } 18897 #endif /* WIN3264 */ 18898 18899 /* 18900 * Adjust a filename, according to a string of modifiers. 18901 * *fnamep must be NUL terminated when called. When returning, the length is 18902 * determined by *fnamelen. 18903 * Returns valid flags. 18904 * When there is an error, *fnamep is set to NULL. 18905 */ 18906 int 18907 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 18908 char_u *src; /* string with modifiers */ 18909 int *usedlen; /* characters after src that are used */ 18910 char_u **fnamep; /* file name so far */ 18911 char_u **bufp; /* buffer for allocated file name or NULL */ 18912 int *fnamelen; /* length of fnamep */ 18913 { 18914 int valid = 0; 18915 char_u *tail; 18916 char_u *s, *p, *pbuf; 18917 char_u dirname[MAXPATHL]; 18918 int c; 18919 int has_fullname = 0; 18920 #ifdef WIN3264 18921 int has_shortname = 0; 18922 #endif 18923 18924 repeat: 18925 /* ":p" - full path/file_name */ 18926 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 18927 { 18928 has_fullname = 1; 18929 18930 valid |= VALID_PATH; 18931 *usedlen += 2; 18932 18933 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 18934 if ((*fnamep)[0] == '~' 18935 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 18936 && ((*fnamep)[1] == '/' 18937 # ifdef BACKSLASH_IN_FILENAME 18938 || (*fnamep)[1] == '\\' 18939 # endif 18940 || (*fnamep)[1] == NUL) 18941 18942 #endif 18943 ) 18944 { 18945 *fnamep = expand_env_save(*fnamep); 18946 vim_free(*bufp); /* free any allocated file name */ 18947 *bufp = *fnamep; 18948 if (*fnamep == NULL) 18949 return -1; 18950 } 18951 18952 /* When "/." or "/.." is used: force expansion to get rid of it. */ 18953 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 18954 { 18955 if (vim_ispathsep(*p) 18956 && p[1] == '.' 18957 && (p[2] == NUL 18958 || vim_ispathsep(p[2]) 18959 || (p[2] == '.' 18960 && (p[3] == NUL || vim_ispathsep(p[3]))))) 18961 break; 18962 } 18963 18964 /* FullName_save() is slow, don't use it when not needed. */ 18965 if (*p != NUL || !vim_isAbsName(*fnamep)) 18966 { 18967 *fnamep = FullName_save(*fnamep, *p != NUL); 18968 vim_free(*bufp); /* free any allocated file name */ 18969 *bufp = *fnamep; 18970 if (*fnamep == NULL) 18971 return -1; 18972 } 18973 18974 /* Append a path separator to a directory. */ 18975 if (mch_isdir(*fnamep)) 18976 { 18977 /* Make room for one or two extra characters. */ 18978 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 18979 vim_free(*bufp); /* free any allocated file name */ 18980 *bufp = *fnamep; 18981 if (*fnamep == NULL) 18982 return -1; 18983 add_pathsep(*fnamep); 18984 } 18985 } 18986 18987 /* ":." - path relative to the current directory */ 18988 /* ":~" - path relative to the home directory */ 18989 /* ":8" - shortname path - postponed till after */ 18990 while (src[*usedlen] == ':' 18991 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 18992 { 18993 *usedlen += 2; 18994 if (c == '8') 18995 { 18996 #ifdef WIN3264 18997 has_shortname = 1; /* Postpone this. */ 18998 #endif 18999 continue; 19000 } 19001 pbuf = NULL; 19002 /* Need full path first (use expand_env() to remove a "~/") */ 19003 if (!has_fullname) 19004 { 19005 if (c == '.' && **fnamep == '~') 19006 p = pbuf = expand_env_save(*fnamep); 19007 else 19008 p = pbuf = FullName_save(*fnamep, FALSE); 19009 } 19010 else 19011 p = *fnamep; 19012 19013 has_fullname = 0; 19014 19015 if (p != NULL) 19016 { 19017 if (c == '.') 19018 { 19019 mch_dirname(dirname, MAXPATHL); 19020 s = shorten_fname(p, dirname); 19021 if (s != NULL) 19022 { 19023 *fnamep = s; 19024 if (pbuf != NULL) 19025 { 19026 vim_free(*bufp); /* free any allocated file name */ 19027 *bufp = pbuf; 19028 pbuf = NULL; 19029 } 19030 } 19031 } 19032 else 19033 { 19034 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19035 /* Only replace it when it starts with '~' */ 19036 if (*dirname == '~') 19037 { 19038 s = vim_strsave(dirname); 19039 if (s != NULL) 19040 { 19041 *fnamep = s; 19042 vim_free(*bufp); 19043 *bufp = s; 19044 } 19045 } 19046 } 19047 vim_free(pbuf); 19048 } 19049 } 19050 19051 tail = gettail(*fnamep); 19052 *fnamelen = (int)STRLEN(*fnamep); 19053 19054 /* ":h" - head, remove "/file_name", can be repeated */ 19055 /* Don't remove the first "/" or "c:\" */ 19056 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19057 { 19058 valid |= VALID_HEAD; 19059 *usedlen += 2; 19060 s = get_past_head(*fnamep); 19061 while (tail > s && after_pathsep(s, tail)) 19062 --tail; 19063 *fnamelen = (int)(tail - *fnamep); 19064 #ifdef VMS 19065 if (*fnamelen > 0) 19066 *fnamelen += 1; /* the path separator is part of the path */ 19067 #endif 19068 while (tail > s && !after_pathsep(s, tail)) 19069 mb_ptr_back(*fnamep, tail); 19070 } 19071 19072 /* ":8" - shortname */ 19073 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19074 { 19075 *usedlen += 2; 19076 #ifdef WIN3264 19077 has_shortname = 1; 19078 #endif 19079 } 19080 19081 #ifdef WIN3264 19082 /* Check shortname after we have done 'heads' and before we do 'tails' 19083 */ 19084 if (has_shortname) 19085 { 19086 pbuf = NULL; 19087 /* Copy the string if it is shortened by :h */ 19088 if (*fnamelen < (int)STRLEN(*fnamep)) 19089 { 19090 p = vim_strnsave(*fnamep, *fnamelen); 19091 if (p == 0) 19092 return -1; 19093 vim_free(*bufp); 19094 *bufp = *fnamep = p; 19095 } 19096 19097 /* Split into two implementations - makes it easier. First is where 19098 * there isn't a full name already, second is where there is. 19099 */ 19100 if (!has_fullname && !vim_isAbsName(*fnamep)) 19101 { 19102 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19103 return -1; 19104 } 19105 else 19106 { 19107 int l; 19108 19109 /* Simple case, already have the full-name 19110 * Nearly always shorter, so try first time. */ 19111 l = *fnamelen; 19112 if (!get_short_pathname(fnamep, bufp, &l)) 19113 return -1; 19114 19115 if (l == 0) 19116 { 19117 /* Couldn't find the filename.. search the paths. 19118 */ 19119 l = *fnamelen; 19120 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19121 return -1; 19122 } 19123 *fnamelen = l; 19124 } 19125 } 19126 #endif /* WIN3264 */ 19127 19128 /* ":t" - tail, just the basename */ 19129 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19130 { 19131 *usedlen += 2; 19132 *fnamelen -= (int)(tail - *fnamep); 19133 *fnamep = tail; 19134 } 19135 19136 /* ":e" - extension, can be repeated */ 19137 /* ":r" - root, without extension, can be repeated */ 19138 while (src[*usedlen] == ':' 19139 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19140 { 19141 /* find a '.' in the tail: 19142 * - for second :e: before the current fname 19143 * - otherwise: The last '.' 19144 */ 19145 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19146 s = *fnamep - 2; 19147 else 19148 s = *fnamep + *fnamelen - 1; 19149 for ( ; s > tail; --s) 19150 if (s[0] == '.') 19151 break; 19152 if (src[*usedlen + 1] == 'e') /* :e */ 19153 { 19154 if (s > tail) 19155 { 19156 *fnamelen += (int)(*fnamep - (s + 1)); 19157 *fnamep = s + 1; 19158 #ifdef VMS 19159 /* cut version from the extension */ 19160 s = *fnamep + *fnamelen - 1; 19161 for ( ; s > *fnamep; --s) 19162 if (s[0] == ';') 19163 break; 19164 if (s > *fnamep) 19165 *fnamelen = s - *fnamep; 19166 #endif 19167 } 19168 else if (*fnamep <= tail) 19169 *fnamelen = 0; 19170 } 19171 else /* :r */ 19172 { 19173 if (s > tail) /* remove one extension */ 19174 *fnamelen = (int)(s - *fnamep); 19175 } 19176 *usedlen += 2; 19177 } 19178 19179 /* ":s?pat?foo?" - substitute */ 19180 /* ":gs?pat?foo?" - global substitute */ 19181 if (src[*usedlen] == ':' 19182 && (src[*usedlen + 1] == 's' 19183 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19184 { 19185 char_u *str; 19186 char_u *pat; 19187 char_u *sub; 19188 int sep; 19189 char_u *flags; 19190 int didit = FALSE; 19191 19192 flags = (char_u *)""; 19193 s = src + *usedlen + 2; 19194 if (src[*usedlen + 1] == 'g') 19195 { 19196 flags = (char_u *)"g"; 19197 ++s; 19198 } 19199 19200 sep = *s++; 19201 if (sep) 19202 { 19203 /* find end of pattern */ 19204 p = vim_strchr(s, sep); 19205 if (p != NULL) 19206 { 19207 pat = vim_strnsave(s, (int)(p - s)); 19208 if (pat != NULL) 19209 { 19210 s = p + 1; 19211 /* find end of substitution */ 19212 p = vim_strchr(s, sep); 19213 if (p != NULL) 19214 { 19215 sub = vim_strnsave(s, (int)(p - s)); 19216 str = vim_strnsave(*fnamep, *fnamelen); 19217 if (sub != NULL && str != NULL) 19218 { 19219 *usedlen = (int)(p + 1 - src); 19220 s = do_string_sub(str, pat, sub, flags); 19221 if (s != NULL) 19222 { 19223 *fnamep = s; 19224 *fnamelen = (int)STRLEN(s); 19225 vim_free(*bufp); 19226 *bufp = s; 19227 didit = TRUE; 19228 } 19229 } 19230 vim_free(sub); 19231 vim_free(str); 19232 } 19233 vim_free(pat); 19234 } 19235 } 19236 /* after using ":s", repeat all the modifiers */ 19237 if (didit) 19238 goto repeat; 19239 } 19240 } 19241 19242 return valid; 19243 } 19244 19245 /* 19246 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19247 * "flags" can be "g" to do a global substitute. 19248 * Returns an allocated string, NULL for error. 19249 */ 19250 char_u * 19251 do_string_sub(str, pat, sub, flags) 19252 char_u *str; 19253 char_u *pat; 19254 char_u *sub; 19255 char_u *flags; 19256 { 19257 int sublen; 19258 regmatch_T regmatch; 19259 int i; 19260 int do_all; 19261 char_u *tail; 19262 garray_T ga; 19263 char_u *ret; 19264 char_u *save_cpo; 19265 19266 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19267 save_cpo = p_cpo; 19268 p_cpo = (char_u *)""; 19269 19270 ga_init2(&ga, 1, 200); 19271 19272 do_all = (flags[0] == 'g'); 19273 19274 regmatch.rm_ic = p_ic; 19275 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19276 if (regmatch.regprog != NULL) 19277 { 19278 tail = str; 19279 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19280 { 19281 /* 19282 * Get some space for a temporary buffer to do the substitution 19283 * into. It will contain: 19284 * - The text up to where the match is. 19285 * - The substituted text. 19286 * - The text after the match. 19287 */ 19288 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19289 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19290 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19291 { 19292 ga_clear(&ga); 19293 break; 19294 } 19295 19296 /* copy the text up to where the match is */ 19297 i = (int)(regmatch.startp[0] - tail); 19298 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19299 /* add the substituted text */ 19300 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19301 + ga.ga_len + i, TRUE, TRUE, FALSE); 19302 ga.ga_len += i + sublen - 1; 19303 /* avoid getting stuck on a match with an empty string */ 19304 if (tail == regmatch.endp[0]) 19305 { 19306 if (*tail == NUL) 19307 break; 19308 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19309 ++ga.ga_len; 19310 } 19311 else 19312 { 19313 tail = regmatch.endp[0]; 19314 if (*tail == NUL) 19315 break; 19316 } 19317 if (!do_all) 19318 break; 19319 } 19320 19321 if (ga.ga_data != NULL) 19322 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19323 19324 vim_free(regmatch.regprog); 19325 } 19326 19327 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19328 ga_clear(&ga); 19329 p_cpo = save_cpo; 19330 19331 return ret; 19332 } 19333 19334 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19335